]> jfr.im git - irc/rqf/shadowircd.git/blame - extensions/m_mkpasswd.c
Disallow mIRC italics in channel names when disable_fake_channels
[irc/rqf/shadowircd.git] / extensions / m_mkpasswd.c
CommitLineData
212380e3 1/*
28545c36 2 * m_mkpasswd.c: Encrypts a password online.
212380e3 3 *
212380e3 4 * Based on mkpasswd.c, originally by Nelson Minar (minar@reed.edu)
212380e3 5 * You can use this code in any way as long as these names remain.
6 *
212380e3 7 */
8
212380e3 9#include "stdinc.h"
10#include "client.h"
212380e3 11#include "numeric.h"
212380e3 12#include "s_conf.h"
212380e3 13#include "modules.h"
14
15#include <string.h>
16
212380e3 17static int m_mkpasswd(struct Client *client_p, struct Client *source_p,
18 int parc, const char *parv[]);
19static int mo_mkpasswd(struct Client *client_p, struct Client *source_p,
20 int parc, const char *parv[]);
212380e3 21
28545c36
EJM
22static char *make_md5_salt(int);
23static char *make_sha256_salt(int);
24static char *make_sha512_salt(int);
25static char *generate_random_salt(char *, int);
26static char *generate_poor_salt(char *, int);
212380e3 27
28545c36
EJM
28static char saltChars[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
29 /* 0 .. 63, ascii - 64 */
212380e3 30
31struct Message mkpasswd_msgtab = {
32 "MKPASSWD", 0, 0, 0, MFLG_SLOW,
33 {mg_unreg, {m_mkpasswd, 2}, mg_ignore, mg_ignore, mg_ignore, {mo_mkpasswd, 2}}
34};
35
36mapi_clist_av1 mkpasswd_clist[] = { &mkpasswd_msgtab, NULL };
37
28545c36 38DECLARE_MODULE_AV1(mkpasswd, NULL, NULL, mkpasswd_clist, NULL, NULL, "$Revision$");
212380e3 39
40
28545c36
EJM
41/* m_mkpasswd - mkpasswd message handler
42 * parv[1] = password
43 * parv[2] = type
44 */
212380e3 45static int
46m_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
47{
48 static time_t last_used = 0;
28545c36
EJM
49 char *salt;
50 const char *hashtype;
51 const char hashdefault[] = "SHA512";
52
53 if(EmptyString(parv[1]))
54 {
55 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD");
56 return 0;
57 }
58
59 if(parc < 3)
60 hashtype = hashdefault;
61 else
62 hashtype = parv[2];
212380e3 63
c51d32ba 64 if((last_used + ConfigFileEntry.pace_wait) > rb_current_time())
212380e3 65 {
66 /* safe enough to give this on a local connect only */
8e425f41 67 sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "MKPASSWD");
212380e3 68 return 0;
69 }
70 else
c51d32ba 71 last_used = rb_current_time();
212380e3 72
28545c36
EJM
73 if(!irccmp(hashtype, "SHA256"))
74 salt = make_sha256_salt(16);
75 else if(!irccmp(hashtype, "SHA512"))
76 salt = make_sha512_salt(16);
77 else if(!irccmp(hashtype, "MD5"))
78 salt = make_md5_salt(8);
79 else
212380e3 80 {
28545c36
EJM
81 sendto_one_notice(source_p,
82 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
83 return 0;
212380e3 84 }
85
28545c36 86 sendto_one_notice(source_p, ":Hash [%s] for %s: %s", hashtype, parv[1], rb_crypt(parv[1], salt));
212380e3 87 return 0;
88}
89
28545c36
EJM
90/* mo_mkpasswd - mkpasswd message handler
91 * parv[1] = password
92 * parv[2] = type
93 */
212380e3 94static int
95mo_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
96{
28545c36
EJM
97 char *salt;
98 const char *hashtype;
99 const char hashdefault[] = "SHA512";
212380e3 100
28545c36 101 if(EmptyString(parv[1]))
212380e3 102 {
28545c36
EJM
103 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD");
104 return 0;
212380e3 105 }
106
28545c36
EJM
107 if(parc < 3)
108 hashtype = hashdefault;
109 else
110 hashtype = parv[2];
111
112 if(!irccmp(hashtype, "SHA256"))
113 salt = make_sha256_salt(16);
114 else if(!irccmp(hashtype, "SHA512"))
115 salt = make_sha512_salt(16);
116 else if(!irccmp(hashtype, "MD5"))
117 salt = make_md5_salt(8);
212380e3 118 else
28545c36
EJM
119 {
120 sendto_one_notice(source_p,
121 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
122 return 0;
123 }
212380e3 124
28545c36 125 sendto_one_notice(source_p, ":Hash [%s] for %s: %s", hashtype, parv[1], rb_crypt(parv[1], salt));
212380e3 126 return 0;
127}
128
28545c36
EJM
129char *
130make_md5_salt(int length)
131{
132 static char salt[21];
133 if(length > 16)
134 {
135 printf("MD5 salt length too long\n");
136 exit(0);
137 }
138 salt[0] = '$';
139 salt[1] = '1';
140 salt[2] = '$';
141 generate_random_salt(&salt[3], length);
142 salt[length + 3] = '$';
143 salt[length + 4] = '\0';
144 return salt;
145}
146
147char *
148make_sha256_salt(int length)
212380e3 149{
28545c36
EJM
150 static char salt[21];
151 if(length > 16)
152 {
153 printf("SHA256 salt length too long\n");
154 exit(0);
155 }
156 salt[0] = '$';
157 salt[1] = '5';
158 salt[2] = '$';
159 generate_random_salt(&salt[3], length);
160 salt[length + 3] = '$';
161 salt[length + 4] = '\0';
212380e3 162 return salt;
163}
164
28545c36
EJM
165char *
166make_sha512_salt(int length)
212380e3 167{
28545c36
EJM
168 static char salt[21];
169 if(length > 16)
170 {
171 printf("SHA512 salt length too long\n");
172 exit(0);
173 }
212380e3 174 salt[0] = '$';
28545c36 175 salt[1] = '6';
212380e3 176 salt[2] = '$';
28545c36
EJM
177 generate_random_salt(&salt[3], length);
178 salt[length + 3] = '$';
179 salt[length + 4] = '\0';
212380e3 180 return salt;
181}
28545c36
EJM
182
183char *
184generate_poor_salt(char *salt, int length)
185{
186 int i;
187 srand(time(NULL));
188 for(i = 0; i < length; i++)
189 {
190 salt[i] = saltChars[rand() % 64];
191 }
192 return (salt);
193}
194
195char *
196generate_random_salt(char *salt, int length)
197{
198 char *buf;
199 int fd, i;
200 if((fd = open("/dev/random", O_RDONLY)) < 0)
201 {
202 return (generate_poor_salt(salt, length));
203 }
204 buf = calloc(1, length);
205 if(read(fd, buf, length) != length)
206 {
207 free(buf);
208 return (generate_poor_salt(salt, length));
209 }
210
211 for(i = 0; i < length; i++)
212 {
213 salt[i] = saltChars[abs(buf[i]) % 64];
214 }
215 free(buf);
216 return (salt);
217}