00001
00015 #include "services.h"
00016 #include <time.h>
00017 #include <ctype.h>
00018 #include <string.h>
00019
00020 #include "hash/md5.h"
00021 #include "hash/md5pw.h"
00022
00023 #ifndef __cplusplus
00024
00025 typedef unsigned char bool;
00026 #endif
00027
00028
00029
00042 unsigned char *toBase64(const unsigned char *stream, size_t left)
00043 {
00044 #define X_OUTPUT_MAP_SZ 64
00045 const unsigned char mutations[] =
00046 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
00047 "0123456789+/";
00048 unsigned int j, k, s_sz = 0, acc;
00049 unsigned char temp[3], out[4];
00050 char *s = NULL, *p;
00051
00052 j = acc = 0;
00053
00054
00055
00056
00057 s_sz = (((left * 8) / 24) * 4) +
00058 ((((left * 8) % 24)) ? 3 : 0) +
00059 2;
00060
00061
00062 p = s = (char *)oalloc(s_sz + 1);
00063
00064 for ( ; left ; )
00065 {
00066 while ( left > 0 && j < 3 ) {
00067 temp[j++] = *stream;
00068 left--;
00069 stream++;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 out[0] = (temp[0] >> 2);
00091
00092
00093
00094
00095 {
00096 if (j < 3) {
00097 temp[2] = 0;
00098 if (j < 2)
00099 temp[1] = 0;
00100 }
00101
00102 out[1] = ((temp[0] & 0x03) << 4) |
00103 (temp[1] >> 4);
00104
00105
00106
00107
00108 out[2] = ( (temp[1] & 0x0f) << 2 ) |
00109 ( temp[2] >> 6 );
00110
00111
00112 out[3] = (temp[2] & 0x3f);
00113 }
00114
00115 for(k = 0; k < 4; k++) {
00116 if ( k <= j ) {
00117 assert(out[k] < X_OUTPUT_MAP_SZ);
00118 *p++ = mutations[out[k]];
00119 }
00120 else *p++ = '=';
00121 if (--s_sz < 1)
00122 assert(s_sz >= 1);
00123 }
00124
00125 j = 0;
00126 }
00127
00128 *p++ = '\0';
00129
00130 #undef X_OUTPUT_MAP_SZ 64
00131 return (unsigned char *)s;
00132 }
00133
00144 unsigned char *fromBase64(const char *cStr, int *len)
00145 {
00146 #define X_OUTPUT_MAP_SZ 64
00147 const unsigned char mutations[] =
00148 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
00149 "0123456789+/";
00150 static unsigned char decode_table[255] = {};
00151 static int pFlag = 0;
00152 int i, j, k, s_sz = 0, hitz = 0;
00153 unsigned char temp[4], out[4], c;
00154 unsigned char *s = NULL, *p;
00155 size_t left = strlen(cStr);
00156
00157
00158 if (pFlag == 0)
00159 {
00160 pFlag = 1;
00161
00162 for(j = 0; j < 127; j++)
00163 decode_table[j] = '\0';
00164
00165 for(j = 0; j < 64; j++) {
00166 for(i = 0; i < 127; i++) {
00167 if (i == mutations[j]) {
00168 decode_table[i] = j;
00169 break;
00170 }
00171 }
00172 }
00173 pFlag = 1;
00174 }
00175
00176
00177
00178
00179 s_sz = 3 + (int) ((left / 4.0) * 3);
00180
00181 p = s = (unsigned char *)oalloc(s_sz + 1 + 10);
00182
00183 for ( ; left > 0 ; )
00184 {
00185 j = 0;
00186 hitz = 0;
00187
00188 while(j < 4 && left > 0) {
00189 c = *(cStr++);
00190 if ((unsigned char)temp[j] < sizeof(decode_table))
00191 c = decode_table[(unsigned char)c];
00192 else { c = '\0'; hitz = 1; }
00193
00194 if (hitz == 0) {
00195 temp[j] = c;
00196 j++;
00197 }
00198 left--;
00199 }
00200 for(k = j; k < 4; k++)
00201 temp[k] = 0;
00202
00203
00204
00205
00206
00207 out[0] = (temp[0] << 2) | ((temp[1] >> 4) & 0x03);
00208 out[1] = (temp[1] << 4) | ((temp[2] >> 2));
00209 out[2] = (temp[2] << 6) | temp[3];
00210
00211 if (s_sz > 0) {
00212 *(p++) = out[0];
00213 s_sz--;
00214 }
00215
00216 if (s_sz > 0) {
00217 *(p++) = out[1];
00218 s_sz--;
00219 }
00220
00221 if (j >= 4) {
00222 (*(p++)) = out[2];
00223 s_sz--;
00224 }
00225
00226 if (s_sz <= 0) {
00227 assert(s_sz > 0);
00228 }
00229 }
00230
00231 if (len)
00232 (*len) = (size_t)(p - s);
00233
00234 *p++ = '\0';
00235
00236 return (unsigned char *)s;
00237 #undef X_OUTPUT_MAP_SZ
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 static char *ExpressAsHighIntBase(u_int32_t value)
00248 {
00249 static char result[256];
00250 char *x_output_map[] = {
00251 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
00252 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
00253 "-", "_", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/",
00254 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
00255 "N", "$", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
00256
00257 "*", "+", "=", "\\", "&", "^", "#", "@", "!", "{",
00258 "(", "[" "?", "'", "\"", "]", ")", ")", ",", ".",
00259 "<", ">", "%", "`", "|", "`", ""
00260 };
00261 #define X_OUTPUT_MAP_SZ 88
00262 #define X_BASE_ENCODING ULONG_MAX
00263 int i = 0, x = 99;
00264 u_int32_t rem;
00265
00266 for(i = 0; i < 100; i++)
00267 result[i] = '\0';
00268
00269 while(value > 0) {
00270 rem = (value % X_BASE_ENCODING);
00271 value = (int) value / X_BASE_ENCODING;
00272 if ((rem >= X_BASE_ENCODING))
00273 break;
00274 result[x--] = *x_output_map[((unsigned char)rem) % X_OUTPUT_MAP_SZ];
00275 if (x < 0 || value < 1)
00276 break;
00277 }
00278
00279 if (x < 99)
00280 for(i = 0; !result[i]; i++) ;
00281 else i = 0;
00282
00283 return (result + i);
00284 #undef X_OUTPUT_MAP_SZ
00285 #undef X_BASE_ENCODING
00286 }
00287
00298 const char *GetAuthChKey(const char *email, const char *password,
00299 time_t timereg, u_int32_t code_arg)
00300 {
00301 u_char digest[16];
00302 static char tresult[256];
00303 struct MD5Context ctx;
00304 uint32 buf[PASSLEN+8];
00305 uint32 md5buf[16];
00306
00307 int cnt = 0, o = 0;
00308
00309 int i, j, k, l;
00310
00311 i = l = 0;
00312 memset(buf, 0, sizeof(buf));
00313
00314 buf[l++] = (timereg & 65280UL) | (timereg & 4278190080UL);
00315 buf[l++] = (timereg & 255UL) | (timereg & 16711680UL);
00316 buf[l++] = (code_arg & 255UL) | (code_arg & 65280UL);
00317 buf[l++] = 0x7f0a528;
00318 buf[l++] = 0x3011f3f;
00319
00320 for(i = 0; password[i] && i <= PASSLEN; i++)
00321 buf[l++] = password[i];
00322 buf[l++] = 0x0;
00323
00324 for(i = 0; i < l; i++) {
00325 buf[i] ^= (code_arg & 4278190080UL);
00326 buf[i] ^= (code_arg & 16711680UL);
00327 }
00328
00329 buf[l++] = 0x162a34b;
00330
00331 MD5Init(&ctx);
00332
00333 for(j = 0 ;; j += 16 ) {
00334 if (j >= l)
00335 break;
00336 k = 0;
00337
00338 for(i = j; i < j+16; i++) {
00339 if (i >= l) {
00340 do {
00341 md5buf[j+i] = k ^ ((code_arg & 255) << 1);
00342 } while(++i < 16);
00343 break;
00344 }
00345 md5buf[j+i] = buf[i];
00346 buf[i] = 0;
00347 }
00348 MD5Transform(ctx.buf, md5buf);
00349 }
00350
00351 MD5Update(&ctx, (unsigned const char *)email, strlen(email));
00352 MD5Final(digest, &ctx);
00353 MD5Init(&ctx);
00354 memset(buf, 0, sizeof(buf));
00355
00356 *tresult = '\0';
00357 memset(tresult, 0, 255);
00358 for(cnt = 0; cnt < 16; ++cnt)
00359 o += sprintf(tresult+o, "%s", ExpressAsHighIntBase(digest[cnt]));
00360 return tresult;
00361 }
00362
00363
00364
00365
00366
00367 static int pwd_too_simple(const char *newp)
00368 {
00369 int count_digit = 0, count_upper = 0;
00370 int count_lower = 0, count_misc = 0;
00371 int req_len;
00372 int i;
00373
00374 for (i = 0;newp[i];i++) {
00375 if (isupper (newp[i]))
00376 count_upper++;
00377 else if (isdigit (newp[i]))
00378 count_digit++;
00379 else if (islower (newp[i]))
00380 count_lower++;
00381 else
00382 count_misc++;
00383 }
00384
00385 req_len = 7;
00386 if (count_digit > 0) --req_len;
00387 if (count_upper > 0) --req_len;
00388 if (count_lower) --req_len;
00389 if (count_misc) --req_len;
00390
00391 if (req_len <= i)
00392 return 0;
00393
00394 return 1;
00395 }
00396
00397
00398
00399 int mpwd_too_simple(char *epwd, RegNickList *nick)
00400 {
00401 char pwd[MAXBUF];
00402
00403 if (!epwd || !nick)
00404 return 1;
00405 strncpy(pwd, epwd, MIN(MAXBUF, 80));
00406 pwd[MAXBUF - 1] = '\0';
00407
00408 #ifdef CRACKLIB_DICTPATH
00409 if (nick)
00410 {
00411 char *msg;
00412 if ((msg = (char *) FascistCheck(pwd, CRACKLIB_DICTPATH))) {
00413 sSend(":%s NOTICE %s :That password you specified not safe because %s.", NickServ, nick->nick);
00414 return 1;
00415 }
00416 }
00417
00418
00419
00420
00421 #else
00422 if (nick && (pwd_too_simple(pwd))) {
00423 sSend(":%s NOTICE %s :That password is too short, try again.", NickServ, nick->nick);
00424 return 1;
00425 }
00426
00427 #endif
00428 return 0;
00429 }
00430
00440 const char *PrintPass(u_char pI[], char enc)
00441 {
00442 static char buf[256];
00443
00444 if (enc == '$' || enc == '+') {
00445 u_char *p = toBase64(pI, 16);
00446 if (!p)
00447 abort();
00448 strncpy(buf, (char *)p, sizeof(buf));
00449 buf[sizeof(buf) - 1] = '\0';
00450 FREE(p);
00451 return buf;
00452 }
00453 else
00454 return (char *)pI;
00455 }
00456
00464 int isPasswordAcceptable(const char* password, char* reason)
00465 {
00466 if (!password || !*password) {
00467 strcpy(reason, "Blank passwords are not allowed.");
00468 return 0;
00469 }
00470
00471 if (isMD5Key(password)) {
00472 strcpy(reason, "Try using a password that doesn't start with MD5(.");
00473 return 0;
00474 }
00475
00476 if (password[0] == '$' && password[1] == '_') {
00477 strcpy(reason, "Try using a password that doesn't start with $_.");
00478 return 0;
00479 }
00480 return 1;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512