diff --git a/gb.crypt/src/c_crypt.c b/gb.crypt/src/c_crypt.c index bc627bfa2..d333af387 100644 --- a/gb.crypt/src/c_crypt.c +++ b/gb.crypt/src/c_crypt.c @@ -36,54 +36,75 @@ #include "c_crypt.h" #include "main.h" +enum { USE_DES, USE_MD5, USE_SHA256, USE_SHA512 }; -static char *do_crypt(const char *passwd, const char *prefix, bool use_md5) +static char *do_crypt(const char *passwd, const char *prefix, int mode) { static char key_table[65] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz./"; static bool init = FALSE; - + int i, n; - char key[16]; + char key[18]; char *result; - char errormsg[35]; + char errormsg[64]; + + switch(mode) + { + case USE_MD5: + strcpy(key, "$1$"); + n = 8; + break; + case USE_SHA256: + strcpy(key, "$5$"); + n = 13; + break; + case USE_SHA512: + strcpy(key, "$6$"); + n = 13; + break; + case USE_DES: + default: + n = 2; + } if (prefix) { - n = use_md5 ? 8 : 2; if (strlen(prefix) != n) - { - snprintf(errormsg, 35, "size must be %d characters long", n); + { + snprintf(errormsg, sizeof(errormsg), "must be %d characters long", n); goto __BAD_PREFIX; } - + for (i = 0; i < n; i++) { if (strchr(key_table, prefix[i]) == NULL) { - snprintf(errormsg, 35, "character '%c' not allowed" , prefix[i]); + snprintf(errormsg, sizeof(errormsg), "character '%c' is not allowed" , prefix[i]); goto __BAD_PREFIX; } } - - if (use_md5) - { - strcpy(key, "$1$"); - strcat(key, prefix); - } - else + + if (mode == USE_DES) strcpy(key, prefix); + else + strcat(key, prefix); } else - { + { if (!init) { srandom((unsigned int)time(NULL)); init = TRUE; } - - if (use_md5) + + if (mode == USE_DES) + { + for (i = 0; i < 2; i++) + key[i] = key_table[(int)((random() / (RAND_MAX + 1.0)) * sizeof(key_table))]; + key[2] = 0; + } + else if (mode == USE_MD5) { - strcpy(key, "$1$"); for (i = 0; i < 8; i++) key[i + 3] = key_table[(int)((random() / (RAND_MAX + 1.0)) * sizeof(key_table))]; key[11] = '$'; @@ -91,61 +112,78 @@ static char *do_crypt(const char *passwd, const char *prefix, bool use_md5) } else { - for (i = 0; i < 2; i++) - key[i] = key_table[(int)((random() / (RAND_MAX + 1.0)) * sizeof(key_table))]; - key[2] = 0; + for (i = 0; i < 13; i++) + key[i + 3] = key_table[(int)((random() / (RAND_MAX + 1.0)) * sizeof(key_table))]; + key[16] = '$'; + key[17] = 0; } } - + result = crypt(passwd, key); - + if (!result && errno == ENOSYS) GB.Error("Crypting is not supported on this system"); - + return result; - + __BAD_PREFIX: GB.Error("Bad prefix, &1",errormsg); return NULL; } - static bool check_crypt(const char *passwd, const char *crypted) { char *result = crypt(passwd, crypted); - + if (!result && errno == ENOSYS) GB.Error("Crypting is not supported on this system"); - + if (!result) return TRUE; else return strcmp(result, crypted) != 0; } +BEGIN_METHOD(CCRYPT_call_des, GB_STRING password; GB_STRING key) + + char *result; + + result = do_crypt(GB.ToZeroString(ARG(password)), MISSING(key) ? NULL : GB.ToZeroString(ARG(key)), USE_DES); + if (result) + GB.ReturnNewZeroString(result); + +END_METHOD BEGIN_METHOD(CCRYPT_call_md5, GB_STRING password; GB_STRING key) char *result; - result = do_crypt(GB.ToZeroString(ARG(password)), MISSING(key) ? NULL : GB.ToZeroString(ARG(key)), TRUE); + result = do_crypt(GB.ToZeroString(ARG(password)), MISSING(key) ? NULL : GB.ToZeroString(ARG(key)), USE_MD5); if (result) GB.ReturnNewZeroString(result); END_METHOD - -BEGIN_METHOD(CCRYPT_call_des, GB_STRING password; GB_STRING key) +BEGIN_METHOD(CCRYPT_call_sha256, GB_STRING password; GB_STRING key) char *result; - result = do_crypt(GB.ToZeroString(ARG(password)), MISSING(key) ? NULL : GB.ToZeroString(ARG(key)), FALSE); + result = do_crypt(GB.ToZeroString(ARG(password)), MISSING(key) ? NULL : GB.ToZeroString(ARG(key)), USE_SHA256); if (result) GB.ReturnNewZeroString(result); END_METHOD +BEGIN_METHOD(CCRYPT_call_sha512, GB_STRING password; GB_STRING key) + + char *result; + + result = do_crypt(GB.ToZeroString(ARG(password)), MISSING(key) ? NULL : GB.ToZeroString(ARG(key)), USE_SHA512); + if (result) + GB.ReturnNewZeroString(result); + +END_METHOD BEGIN_METHOD(CCRYPT_check, GB_STRING password; GB_STRING crypt) @@ -153,16 +191,16 @@ BEGIN_METHOD(CCRYPT_check, GB_STRING password; GB_STRING crypt) END_METHOD - GB_DESC CCryptDesc[] = { GB_DECLARE("Crypt", 0), GB_VIRTUAL_CLASS(), - + GB_STATIC_METHOD("_call", "s", CCRYPT_call_md5, "(Password)s[(Prefix)s]"), GB_STATIC_METHOD("Check", "b", CCRYPT_check, "(Password)s(Crypt)s"), - GB_STATIC_METHOD("MD5", "s", CCRYPT_call_md5, "(Password)s[(Prefix)s]"), GB_STATIC_METHOD("DES", "s", CCRYPT_call_des, "(Password)s[(Prefix)s]"), + GB_STATIC_METHOD("MD5", "s", CCRYPT_call_md5, "(Password)s[(Prefix)s]"), + GB_STATIC_METHOD("SHA256", "s", CCRYPT_call_sha256, "(Password)s[(Prefix)s]"), + GB_STATIC_METHOD("SHA512", "s", CCRYPT_call_sha512, "(Password)s[(Prefix)s]"), GB_END_DECLARE }; -