]> jfr.im git - solanum.git/blame - extensions/m_mkpasswd.c
msg: remove last vestiges of the fakelag system. charybdis has never supported fakelag.
[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
f924ea40 39DECLARE_MODULE_AV1(mkpasswd, NULL, NULL, mkpasswd_clist, NULL, NULL, "$Revision$");
212380e3
AC
40
41
06c3a319 42/* m_mkpasswd - mkpasswd message handler
f924ea40
EM
43 * parv[1] = password
44 * parv[2] = type
45 */
212380e3 46static int
760bafda 47m_mkpasswd(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
212380e3
AC
48{
49 static time_t last_used = 0;
f924ea40 50 char *salt;
e69375f3 51 const char *crypted;
f924ea40
EM
52 const char *hashtype;
53 const char hashdefault[] = "SHA512";
54
55 if(EmptyString(parv[1]))
56 {
57 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD");
58 return 0;
59 }
60
61 if(parc < 3)
62 hashtype = hashdefault;
63 else
64 hashtype = parv[2];
212380e3 65
954012d3 66 if((last_used + ConfigFileEntry.pace_wait) > rb_current_time())
212380e3
AC
67 {
68 /* safe enough to give this on a local connect only */
3dfaa671 69 sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "MKPASSWD");
212380e3
AC
70 return 0;
71 }
72 else
954012d3 73 last_used = rb_current_time();
212380e3 74
f924ea40
EM
75 if(!irccmp(hashtype, "SHA256"))
76 salt = make_sha256_salt(16);
77 else if(!irccmp(hashtype, "SHA512"))
78 salt = make_sha512_salt(16);
79 else if(!irccmp(hashtype, "MD5"))
80 salt = make_md5_salt(8);
81 else
212380e3 82 {
f924ea40
EM
83 sendto_one_notice(source_p,
84 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
85 return 0;
212380e3
AC
86 }
87
e69375f3
JT
88 crypted = rb_crypt(parv[1], salt);
89 sendto_one_notice(source_p, ":Hash [%s] for %s: %s", hashtype, parv[1], crypted ? crypted : "???");
212380e3
AC
90 return 0;
91}
92
06c3a319 93/* mo_mkpasswd - mkpasswd message handler
f924ea40
EM
94 * parv[1] = password
95 * parv[2] = type
96 */
212380e3 97static int
760bafda 98mo_mkpasswd(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
212380e3 99{
f924ea40 100 char *salt;
e69375f3 101 const char *crypted;
f924ea40
EM
102 const char *hashtype;
103 const char hashdefault[] = "SHA512";
212380e3 104
f924ea40 105 if(EmptyString(parv[1]))
212380e3 106 {
f924ea40
EM
107 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD");
108 return 0;
212380e3
AC
109 }
110
f924ea40
EM
111 if(parc < 3)
112 hashtype = hashdefault;
113 else
114 hashtype = parv[2];
115
116 if(!irccmp(hashtype, "SHA256"))
117 salt = make_sha256_salt(16);
118 else if(!irccmp(hashtype, "SHA512"))
119 salt = make_sha512_salt(16);
120 else if(!irccmp(hashtype, "MD5"))
121 salt = make_md5_salt(8);
212380e3 122 else
f924ea40
EM
123 {
124 sendto_one_notice(source_p,
125 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
126 return 0;
127 }
212380e3 128
e69375f3
JT
129 crypted = rb_crypt(parv[1], salt);
130 sendto_one_notice(source_p, ":Hash [%s] for %s: %s", hashtype, parv[1], crypted ? crypted : "???");
212380e3
AC
131 return 0;
132}
133
f924ea40
EM
134char *
135make_md5_salt(int length)
212380e3 136{
f924ea40
EM
137 static char salt[21];
138 if(length > 16)
139 {
140 printf("MD5 salt length too long\n");
141 exit(0);
142 }
143 salt[0] = '$';
144 salt[1] = '1';
145 salt[2] = '$';
146 generate_random_salt(&salt[3], length);
147 salt[length + 3] = '$';
148 salt[length + 4] = '\0';
212380e3
AC
149 return salt;
150}
151
f924ea40
EM
152char *
153make_sha256_salt(int length)
212380e3 154{
f924ea40
EM
155 static char salt[21];
156 if(length > 16)
157 {
158 printf("SHA256 salt length too long\n");
159 exit(0);
160 }
212380e3 161 salt[0] = '$';
f924ea40 162 salt[1] = '5';
212380e3 163 salt[2] = '$';
f924ea40
EM
164 generate_random_salt(&salt[3], length);
165 salt[length + 3] = '$';
166 salt[length + 4] = '\0';
212380e3
AC
167 return salt;
168}
f924ea40
EM
169
170char *
171make_sha512_salt(int length)
172{
173 static char salt[21];
174 if(length > 16)
175 {
176 printf("SHA512 salt length too long\n");
177 exit(0);
178 }
179 salt[0] = '$';
180 salt[1] = '6';
181 salt[2] = '$';
182 generate_random_salt(&salt[3], length);
183 salt[length + 3] = '$';
184 salt[length + 4] = '\0';
185 return salt;
186}
187
188char *
189generate_poor_salt(char *salt, int length)
190{
191 int i;
192 srand(time(NULL));
193 for(i = 0; i < length; i++)
194 {
195 salt[i] = saltChars[rand() % 64];
196 }
197 return (salt);
198}
199
200char *
201generate_random_salt(char *salt, int length)
202{
203 char *buf;
204 int fd, i;
205 if((fd = open("/dev/random", O_RDONLY)) < 0)
206 {
207 return (generate_poor_salt(salt, length));
208 }
209 buf = calloc(1, length);
210 if(read(fd, buf, length) != length)
211 {
212 free(buf);
f9960c02 213 close(fd);
f924ea40
EM
214 return (generate_poor_salt(salt, length));
215 }
216
217 for(i = 0; i < length; i++)
218 {
219 salt[i] = saltChars[abs(buf[i]) % 64];
220 }
221 free(buf);
f9960c02 222 close(fd);
f924ea40
EM
223 return (salt);
224}