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