2 * m_mkpasswd.c: Encrypts a password online.
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.
18 const char mkpasswd_desc
[] = "Hash a password for use in ircd.conf";
20 static void m_mkpasswd(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
,
21 int parc
, const char *parv
[]);
22 static void mo_mkpasswd(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
,
23 int parc
, const char *parv
[]);
25 static char *make_md5_salt(int);
26 static char *make_sha256_salt(int);
27 static char *make_sha512_salt(int);
28 static char *generate_random_salt(char *, int);
29 static char *generate_poor_salt(char *, int);
31 static char saltChars
[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
32 /* 0 .. 63, ascii - 64 */
34 struct Message mkpasswd_msgtab
= {
35 "MKPASSWD", 0, 0, 0, 0,
36 {mg_unreg
, {m_mkpasswd
, 2}, mg_ignore
, mg_ignore
, mg_ignore
, {mo_mkpasswd
, 2}}
39 mapi_clist_av1 mkpasswd_clist
[] = { &mkpasswd_msgtab
, NULL
};
41 DECLARE_MODULE_AV2(mkpasswd
, NULL
, NULL
, mkpasswd_clist
, NULL
, NULL
, NULL
, NULL
, mkpasswd_desc
);
44 /* m_mkpasswd - mkpasswd message handler
49 m_mkpasswd(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
51 static time_t last_used
= 0;
55 const char hashdefault
[] = "SHA512";
57 if(EmptyString(parv
[1]))
59 sendto_one(source_p
, form_str(ERR_NEEDMOREPARAMS
), me
.name
, source_p
->name
, "MKPASSWD");
64 hashtype
= hashdefault
;
68 if((last_used
+ ConfigFileEntry
.pace_wait
) > rb_current_time())
70 /* safe enough to give this on a local connect only */
71 sendto_one(source_p
, form_str(RPL_LOAD2HI
), me
.name
, source_p
->name
, "MKPASSWD");
75 last_used
= rb_current_time();
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);
85 sendto_one_notice(source_p
,
86 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
90 crypted
= rb_crypt(parv
[1], salt
);
91 sendto_one_notice(source_p
, ":Hash [%s] for %s: %s", hashtype
, parv
[1], crypted
? crypted
: "???");
94 /* mo_mkpasswd - mkpasswd message handler
99 mo_mkpasswd(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
103 const char *hashtype
;
104 const char hashdefault
[] = "SHA512";
106 if(EmptyString(parv
[1]))
108 sendto_one(source_p
, form_str(ERR_NEEDMOREPARAMS
), me
.name
, source_p
->name
, "MKPASSWD");
113 hashtype
= hashdefault
;
117 if(!irccmp(hashtype
, "SHA256"))
118 salt
= make_sha256_salt(16);
119 else if(!irccmp(hashtype
, "SHA512"))
120 salt
= make_sha512_salt(16);
121 else if(!irccmp(hashtype
, "MD5"))
122 salt
= make_md5_salt(8);
125 sendto_one_notice(source_p
,
126 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
130 crypted
= rb_crypt(parv
[1], salt
);
131 sendto_one_notice(source_p
, ":Hash [%s] for %s: %s", hashtype
, parv
[1], crypted
? crypted
: "???");
135 make_md5_salt(int length
)
137 static char salt
[21];
140 printf("MD5 salt length too long\n");
146 generate_random_salt(&salt
[3], length
);
147 salt
[length
+ 3] = '$';
148 salt
[length
+ 4] = '\0';
153 make_sha256_salt(int length
)
155 static char salt
[21];
158 printf("SHA256 salt length too long\n");
164 generate_random_salt(&salt
[3], length
);
165 salt
[length
+ 3] = '$';
166 salt
[length
+ 4] = '\0';
171 make_sha512_salt(int length
)
173 static char salt
[21];
176 printf("SHA512 salt length too long\n");
182 generate_random_salt(&salt
[3], length
);
183 salt
[length
+ 3] = '$';
184 salt
[length
+ 4] = '\0';
189 generate_poor_salt(char *salt
, int length
)
193 for(i
= 0; i
< length
; i
++)
195 salt
[i
] = saltChars
[rand() % 64];
201 generate_random_salt(char *salt
, int length
)
205 if((fd
= open("/dev/random", O_RDONLY
)) < 0)
207 return (generate_poor_salt(salt
, length
));
209 buf
= calloc(1, length
);
210 if(read(fd
, buf
, length
) != length
)
214 return (generate_poor_salt(salt
, length
));
217 for(i
= 0; i
< length
; i
++)
219 salt
[i
] = saltChars
[abs(buf
[i
]) % 64];