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.
16 static int m_mkpasswd(struct Client
*client_p
, struct Client
*source_p
,
17 int parc
, const char *parv
[]);
18 static int mo_mkpasswd(struct Client
*client_p
, struct Client
*source_p
,
19 int parc
, const char *parv
[]);
21 static char *make_md5_salt(int);
22 static char *make_sha256_salt(int);
23 static char *make_sha512_salt(int);
24 static char *generate_random_salt(char *, int);
25 static char *generate_poor_salt(char *, int);
27 static char saltChars
[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
28 /* 0 .. 63, ascii - 64 */
30 struct Message mkpasswd_msgtab
= {
31 "MKPASSWD", 0, 0, 0, MFLG_SLOW
,
32 {mg_unreg
, {m_mkpasswd
, 2}, mg_ignore
, mg_ignore
, mg_ignore
, {mo_mkpasswd
, 2}}
35 mapi_clist_av1 mkpasswd_clist
[] = { &mkpasswd_msgtab
, NULL
};
37 DECLARE_MODULE_AV1(mkpasswd
, NULL
, NULL
, mkpasswd_clist
, NULL
, NULL
, "$Revision$");
40 /* m_mkpasswd - mkpasswd message handler
45 m_mkpasswd(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
47 static time_t last_used
= 0;
50 const char hashdefault
[] = "SHA512";
52 if(EmptyString(parv
[1]))
54 sendto_one(source_p
, form_str(ERR_NEEDMOREPARAMS
), me
.name
, source_p
->name
, "MKPASSWD");
59 hashtype
= hashdefault
;
63 if((last_used
+ ConfigFileEntry
.pace_wait
) > rb_current_time())
65 /* safe enough to give this on a local connect only */
66 sendto_one(source_p
, form_str(RPL_LOAD2HI
), me
.name
, source_p
->name
, "MKPASSWD");
70 last_used
= rb_current_time();
72 if(!irccmp(hashtype
, "SHA256"))
73 salt
= make_sha256_salt(16);
74 else if(!irccmp(hashtype
, "SHA512"))
75 salt
= make_sha512_salt(16);
76 else if(!irccmp(hashtype
, "MD5"))
77 salt
= make_md5_salt(8);
80 sendto_one_notice(source_p
,
81 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
85 sendto_one_notice(source_p
, ":Hash [%s] for %s: %s", hashtype
, parv
[1], rb_crypt(parv
[1], salt
));
89 /* mo_mkpasswd - mkpasswd message handler
94 mo_mkpasswd(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
98 const char hashdefault
[] = "SHA512";
100 if(EmptyString(parv
[1]))
102 sendto_one(source_p
, form_str(ERR_NEEDMOREPARAMS
), me
.name
, source_p
->name
, "MKPASSWD");
107 hashtype
= hashdefault
;
111 if(!irccmp(hashtype
, "SHA256"))
112 salt
= make_sha256_salt(16);
113 else if(!irccmp(hashtype
, "SHA512"))
114 salt
= make_sha512_salt(16);
115 else if(!irccmp(hashtype
, "MD5"))
116 salt
= make_md5_salt(8);
119 sendto_one_notice(source_p
,
120 ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]");
124 sendto_one_notice(source_p
, ":Hash [%s] for %s: %s", hashtype
, parv
[1], rb_crypt(parv
[1], salt
));
129 make_md5_salt(int length
)
131 static char salt
[21];
134 printf("MD5 salt length too long\n");
140 generate_random_salt(&salt
[3], length
);
141 salt
[length
+ 3] = '$';
142 salt
[length
+ 4] = '\0';
147 make_sha256_salt(int length
)
149 static char salt
[21];
152 printf("SHA256 salt length too long\n");
158 generate_random_salt(&salt
[3], length
);
159 salt
[length
+ 3] = '$';
160 salt
[length
+ 4] = '\0';
165 make_sha512_salt(int length
)
167 static char salt
[21];
170 printf("SHA512 salt length too long\n");
176 generate_random_salt(&salt
[3], length
);
177 salt
[length
+ 3] = '$';
178 salt
[length
+ 4] = '\0';
183 generate_poor_salt(char *salt
, int length
)
187 for(i
= 0; i
< length
; i
++)
189 salt
[i
] = saltChars
[rand() % 64];
195 generate_random_salt(char *salt
, int length
)
199 if((fd
= open("/dev/random", O_RDONLY
)) < 0)
201 return (generate_poor_salt(salt
, length
));
203 buf
= calloc(1, length
);
204 if(read(fd
, buf
, length
) != length
)
207 return (generate_poor_salt(salt
, length
));
210 for(i
= 0; i
< length
; i
++)
212 salt
[i
] = saltChars
[abs(buf
[i
]) % 64];