--- pam_tcb/support.c.orig 2010-01-17 12:22:29.000000000 +0100 +++ pam_tcb/support.c 2010-02-12 10:47:37.000000000 +0100 @@ -466,6 +466,44 @@ return retval; } +static unsigned char _crypt_itoa64[64 + 1] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *crypt_gensalt_ra(const char *prefix, unsigned long count, + const char *entropy, int entropy_size) +{ + if (count != 0) + return NULL; + if (entropy_size < 3) + return NULL; + char* salt = malloc(strlen(prefix) + entropy_size/3*4 + 1); + if (!salt) + return NULL; + char *sp = stpcpy(salt, prefix); + int i; + for (i = 0; entropy_size >= 3 * (i + 1); i++) { + unsigned long value = + ((unsigned long)(unsigned char)entropy[3 * i]) | + ((unsigned long)(unsigned char)entropy[3 * i + 1] << 8) | + ((unsigned long)(unsigned char)entropy[3 * i + 2] << 16); + *sp++ = _crypt_itoa64[value & 0x3f]; + *sp++ = _crypt_itoa64[(value >> 6) & 0x3f]; + *sp++ = _crypt_itoa64[(value >> 12) & 0x3f]; + *sp++ = _crypt_itoa64[(value >> 18) & 0x3f]; + } + *sp = '\0'; + return salt; +} + +static char *crypt_ra(const char *key, const char *salt, + void **data, int *size) +{ + *size = sizeof(struct crypt_data); + if (!(*data = calloc(1, *size))) + return NULL; + return crypt_r(key, salt, *data); +} + static int check_crypt(pam_handle_t *pamh, const char *pass, const char *stored_hash) { @@ -1019,28 +1057,16 @@ if (!parse_opt(pamh, *argv, the_cmdline_opts)) return 0; param = get_optval("prefix=", the_cmdline_opts); - pam_unix_param.crypt_prefix = param ?: "$2a$"; + pam_unix_param.crypt_prefix = param ?: "$6$"; param = get_optval("helper=", the_cmdline_opts); pam_unix_param.helper = param ?: CHKPWD_HELPER; param = get_optval("count=", the_cmdline_opts); if (param) { - char *end; - /* - * SUSv2 says: - * Because 0 and ULONG_MAX are returned on error and - * are also valid returns on success, an application - * wishing to check for error situations should set - * errno to 0, then call strtoul(), then check errno. - */ - errno = 0; - pam_unix_param.count = strtoul(param, &end, 10); - if (errno || !*param || *end) { - pam_syslog(pamh, LOG_ERR, - "Invalid count= argument: %s", param); - return 0; - } + pam_syslog(pamh, LOG_ERR, + "count= parameter is not supported without Openwall libcrypt extensions"); + return 0; } else pam_unix_param.count = 0;