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