From: Matthew Newton Date: Fri, 28 Sep 2012 16:51:58 +0000 (+0100) Subject: start tidy of rlm_pap - move crypt to separate function X-Git-Tag: release_3_0_0_beta1~1669 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f192b94a3b88c1dbbe7c8ab17c1548d32e8cec40;p=thirdparty%2Ffreeradius-server.git start tidy of rlm_pap - move crypt to separate function --- diff --git a/src/modules/rlm_pap/rlm_pap.c b/src/modules/rlm_pap/rlm_pap.c index 2078ffbf629..c1b5f9150a3 100644 --- a/src/modules/rlm_pap/rlm_pap.c +++ b/src/modules/rlm_pap/rlm_pap.c @@ -46,6 +46,8 @@ RCSID("$Id$") #define PAP_MAX_ENC 9 +static int pap_auth_crypt(REQUEST *, VALUE_PAIR *, char *); + /* * Define a structure for our module configuration. * @@ -478,7 +480,6 @@ static int pap_authorize(void *instance, REQUEST *request) */ static int pap_authenticate(void *instance, REQUEST *request) { - rlm_pap_t *inst = instance; VALUE_PAIR *vp; VALUE_PAIR *module_fmsg_vp; char module_fmsg[MAX_STRING_LEN]; @@ -488,6 +489,10 @@ static int pap_authenticate(void *instance, REQUEST *request) char charbuf[128]; uint8_t buff[MAX_STRING_LEN]; char buff2[MAX_STRING_LEN + 50]; + int rc = RLM_MODULE_INVALID; + + /* Shut the compiler up */ + instance = instance; if (!request->password || (request->password->attribute != PW_USER_PASSWORD)) { @@ -512,274 +517,283 @@ static int pap_authenticate(void *instance, REQUEST *request) * First, auto-detect passwords, by attribute in the * config items. */ - for (vp = request->config_items; vp != NULL; vp = vp->next) { - switch (vp->attribute) { - case PW_USER_PASSWORD: /* deprecated */ - case PW_CLEARTEXT_PASSWORD: /* preferred */ - goto do_clear; + for (vp = request->config_items; vp != NULL; vp = vp->next) { + switch (vp->attribute) { + case PW_USER_PASSWORD: /* deprecated */ + case PW_CLEARTEXT_PASSWORD: /* preferred */ + goto do_clear; - case PW_CRYPT_PASSWORD: - goto do_crypt; + case PW_CRYPT_PASSWORD: + rc = pap_auth_crypt(request, vp, module_fmsg); + break; - case PW_MD5_PASSWORD: - goto do_md5; + case PW_MD5_PASSWORD: + goto do_md5; - case PW_SHA_PASSWORD: - goto do_sha; + case PW_SHA_PASSWORD: + goto do_sha; - case PW_NT_PASSWORD: - goto do_nt; + case PW_NT_PASSWORD: + goto do_nt; - case PW_LM_PASSWORD: - goto do_lm; + case PW_LM_PASSWORD: + goto do_lm; - case PW_SMD5_PASSWORD: - goto do_smd5; + case PW_SMD5_PASSWORD: + goto do_smd5; - case PW_SSHA_PASSWORD: - goto do_ssha; + case PW_SSHA_PASSWORD: + goto do_ssha; - case PW_NS_MTA_MD5_PASSWORD: - goto do_ns_mta_md5; + case PW_NS_MTA_MD5_PASSWORD: + goto do_ns_mta_md5; - default: - break; /* ignore it */ + default: + break; + } + if (rc != RLM_MODULE_INVALID) { + if (rc == RLM_MODULE_REJECT) { +make_msg: + RDEBUG("Passwords don't match"); + RDEBUG("return message '%s'", module_fmsg); + module_fmsg_vp = pairmake("Module-Failure-Message", + module_fmsg, T_OP_EQ); + pairadd(&request->packet->vps, module_fmsg_vp); + return RLM_MODULE_REJECT; } - } - RDEBUG("No password configured for the user. Cannot do authentication"); - return RLM_MODULE_FAIL; + return rc; + } + } + RDEBUG("No password configured for the user. Cannot do authentication"); + return RLM_MODULE_FAIL; /* * Now that we've decided what to do, go do it. */ - do_clear: - if (vp->attribute == PW_USER_PASSWORD) { - RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - RDEBUG("!!! Please update your configuration so that the \"known good\" !!!"); - RDEBUG("!!! clear text password is in Cleartext-Password, and not in User-Password. !!!"); - RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - } - RDEBUG("Using clear text password \"%s\"", - vp->vp_strvalue); - if ((vp->length != request->password->length) || - (rad_digest_cmp(vp->vp_octets, - request->password->vp_octets, - vp->length) != 0)) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: CLEAR TEXT password check failed"); - goto make_msg; - } - done: - RDEBUG("User authenticated successfully"); - return RLM_MODULE_OK; - - do_crypt: - RDEBUG("Using CRYPT password \"%s\"", - vp->vp_strvalue); - if (fr_crypt_check(request->password->vp_strvalue, - vp->vp_strvalue) != 0) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: CRYPT password check failed"); - goto make_msg; - } - goto done; +do_clear: + if (vp->attribute == PW_USER_PASSWORD) { + RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + RDEBUG("!!! Please update your configuration so that the \"known good\" !!!"); + RDEBUG("!!! clear text password is in Cleartext-Password, and not in User-Password. !!!"); + RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } + RDEBUG("Using clear text password \"%s\"", + vp->vp_strvalue); + if ((vp->length != request->password->length) || + (rad_digest_cmp(vp->vp_octets, + request->password->vp_octets, + vp->length) != 0)) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: CLEAR TEXT password check failed"); + goto make_msg; + } +done: + RDEBUG("User authenticated successfully"); + return RLM_MODULE_OK; + +do_md5: + RDEBUG("Using MD5 encryption."); + + normify(request, vp, 16); + if (vp->length != 16) { + RDEBUG("Configured MD5 password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured MD5 password has incorrect length"); + goto make_msg; + } - do_md5: - RDEBUG("Using MD5 encryption."); + fr_MD5Init(&md5_context); + fr_MD5Update(&md5_context, request->password->vp_octets, + request->password->length); + fr_MD5Final(binbuf, &md5_context); + if (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: MD5 password check failed"); + goto make_msg; + } + goto done; - normify(request, vp, 16); - if (vp->length != 16) { - RDEBUG("Configured MD5 password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured MD5 password has incorrect length"); - goto make_msg; - } +do_smd5: + RDEBUG("Using SMD5 encryption."); - fr_MD5Init(&md5_context); - fr_MD5Update(&md5_context, request->password->vp_octets, - request->password->length); - fr_MD5Final(binbuf, &md5_context); - if (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: MD5 password check failed"); - goto make_msg; - } - goto done; + normify(request, vp, 16); + if (vp->length <= 16) { + RDEBUG("Configured SMD5 password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SMD5 password has incorrect length"); + goto make_msg; + } - do_smd5: - RDEBUG("Using SMD5 encryption."); + fr_MD5Init(&md5_context); + fr_MD5Update(&md5_context, request->password->vp_octets, + request->password->length); + fr_MD5Update(&md5_context, &vp->vp_octets[16], vp->length - 16); + fr_MD5Final(binbuf, &md5_context); - normify(request, vp, 16); - if (vp->length <= 16) { - RDEBUG("Configured SMD5 password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SMD5 password has incorrect length"); - goto make_msg; - } + /* + * Compare only the MD5 hash results, not the salt. + */ + if (rad_digest_cmp(binbuf, vp->vp_octets, 16) != 0) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SMD5 password check failed"); + goto make_msg; + } + goto done; - fr_MD5Init(&md5_context); - fr_MD5Update(&md5_context, request->password->vp_octets, - request->password->length); - fr_MD5Update(&md5_context, &vp->vp_octets[16], vp->length - 16); - fr_MD5Final(binbuf, &md5_context); +do_sha: + RDEBUG("Using SHA1 encryption."); - /* - * Compare only the MD5 hash results, not the salt. - */ - if (rad_digest_cmp(binbuf, vp->vp_octets, 16) != 0) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SMD5 password check failed"); - goto make_msg; - } - goto done; + normify(request, vp, 20); + if (vp->length != 20) { + RDEBUG("Configured SHA1 password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SHA1 password has incorrect length"); + goto make_msg; + } - do_sha: - RDEBUG("Using SHA1 encryption."); + fr_SHA1Init(&sha1_context); + fr_SHA1Update(&sha1_context, request->password->vp_octets, + request->password->length); + fr_SHA1Final(binbuf,&sha1_context); + if (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SHA1 password check failed"); + goto make_msg; + } + goto done; - normify(request, vp, 20); - if (vp->length != 20) { - RDEBUG("Configured SHA1 password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SHA1 password has incorrect length"); - goto make_msg; - } +do_ssha: + RDEBUG("Using SSHA encryption."); - fr_SHA1Init(&sha1_context); - fr_SHA1Update(&sha1_context, request->password->vp_octets, - request->password->length); - fr_SHA1Final(binbuf,&sha1_context); - if (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SHA1 password check failed"); - goto make_msg; - } - goto done; + normify(request, vp, 20); + if (vp->length <= 20) { + RDEBUG("Configured SSHA password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SHA password has incorrect length"); + goto make_msg; + } - do_ssha: - RDEBUG("Using SSHA encryption."); - normify(request, vp, 20); - if (vp->length <= 20) { - RDEBUG("Configured SSHA password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SHA password has incorrect length"); - goto make_msg; - } + fr_SHA1Init(&sha1_context); + fr_SHA1Update(&sha1_context, request->password->vp_octets, + request->password->length); + fr_SHA1Update(&sha1_context, &vp->vp_octets[20], vp->length - 20); + fr_SHA1Final(binbuf,&sha1_context); + if (rad_digest_cmp(binbuf, vp->vp_octets, 20) != 0) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SSHA password check failed"); + goto make_msg; + } + goto done; +do_nt: + RDEBUG("Using NT encryption."); - fr_SHA1Init(&sha1_context); - fr_SHA1Update(&sha1_context, request->password->vp_octets, - request->password->length); - fr_SHA1Update(&sha1_context, &vp->vp_octets[20], vp->length - 20); - fr_SHA1Final(binbuf,&sha1_context); - if (rad_digest_cmp(binbuf, vp->vp_octets, 20) != 0) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SSHA password check failed"); - goto make_msg; - } - goto done; + normify(request, vp, 16); + if (vp->length != 16) { + RDEBUG("Configured NT-Password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NT-Password has incorrect length"); + goto make_msg; + } - do_nt: - RDEBUG("Using NT encryption."); - normify(request, vp, 16); - if (vp->length != 16) { - RDEBUG("Configured NT-Password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NT-Password has incorrect length"); - goto make_msg; - } + strlcpy(buff2, "%{mschap:NT-Hash %{User-Password}}", sizeof(buff2)); + if (!radius_xlat(charbuf, sizeof(charbuf),buff2,request,NULL)){ + RDEBUG("mschap xlat failed"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: mschap xlat failed"); + goto make_msg; + } + if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) || + (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: NT password check failed"); + goto make_msg; + } + goto done; +do_lm: + RDEBUG("Using LM encryption."); - strlcpy(buff2, "%{mschap:NT-Hash %{User-Password}}", sizeof(buff2)); - if (!radius_xlat(charbuf, sizeof(charbuf),buff2,request,NULL)){ - RDEBUG("mschap xlat failed"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: mschap xlat failed"); - goto make_msg; - } - if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) || - (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: NT password check failed"); - goto make_msg; - } - goto done; + normify(request, vp, 16); + if (vp->length != 16) { + RDEBUG("Configured LM-Password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured LM-Password has incorrect length"); + goto make_msg; + } + strlcpy(buff2, "%{mschap:LM-Hash %{User-Password}}", sizeof(buff2)); + if (!radius_xlat(charbuf,sizeof(charbuf),buff2,request,NULL)){ + RDEBUG("mschap xlat failed"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: mschap xlat failed"); + goto make_msg; + } + if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) || + (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: LM password check failed"); + goto make_msg; + } + goto done; - do_lm: - RDEBUG("Using LM encryption."); +do_ns_mta_md5: + RDEBUG("Using NT-MTA-MD5 password"); - normify(request, vp, 16); - if (vp->length != 16) { - RDEBUG("Configured LM-Password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured LM-Password has incorrect length"); - goto make_msg; - } - strlcpy(buff2, "%{mschap:LM-Hash %{User-Password}}", sizeof(buff2)); - if (!radius_xlat(charbuf,sizeof(charbuf),buff2,request,NULL)){ - RDEBUG("mschap xlat failed"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: mschap xlat failed"); - goto make_msg; - } - if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) || - (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: LM password check failed"); - make_msg: - RDEBUG("Passwords don't match"); - module_fmsg_vp = pairmake("Module-Failure-Message", - module_fmsg, T_OP_EQ); - pairadd(&request->packet->vps, module_fmsg_vp); - return RLM_MODULE_REJECT; - } - goto done; + if (vp->length != 64) { + RDEBUG("Configured NS-MTA-MD5-Password has incorrect length"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NS-MTA-MD5-Password has incorrect length"); + goto make_msg; + } - do_ns_mta_md5: - RDEBUG("Using NT-MTA-MD5 password"); + /* + * Sanity check the value of NS-MTA-MD5-Password + */ + if (fr_hex2bin(vp->vp_strvalue, binbuf, 32) != 16) { + RDEBUG("Configured NS-MTA-MD5-Password has invalid value"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NS-MTA-MD5-Password has invalid value"); + goto make_msg; + } - if (vp->length != 64) { - RDEBUG("Configured NS-MTA-MD5-Password has incorrect length"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NS-MTA-MD5-Password has incorrect length"); - goto make_msg; - } + /* + * Ensure we don't have buffer overflows. + * + * This really: sizeof(buff) - 2 - 2*32 - strlen(passwd) + */ + if (strlen(request->password->vp_strvalue) >= (sizeof(buff) - 2 - 2 * 32)) { + RDEBUG("Configured password is too long"); + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: password is too long"); + goto make_msg; + } - /* - * Sanity check the value of NS-MTA-MD5-Password - */ - if (fr_hex2bin(vp->vp_strvalue, binbuf, 32) != 16) { - RDEBUG("Configured NS-MTA-MD5-Password has invalid value"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NS-MTA-MD5-Password has invalid value"); - goto make_msg; - } + /* + * Set up the algorithm. + */ + { + char *p = buff2; - /* - * Ensure we don't have buffer overflows. - * - * This really: sizeof(buff) - 2 - 2*32 - strlen(passwd) - */ - if (strlen(request->password->vp_strvalue) >= (sizeof(buff) - 2 - 2 * 32)) { - RDEBUG("Configured password is too long"); - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: password is too long"); - goto make_msg; - } + memcpy(p, &vp->vp_octets[32], 32); + p += 32; + *(p++) = 89; + strcpy(p, request->password->vp_strvalue); + p += strlen(p); + *(p++) = 247; + memcpy(p, &vp->vp_octets[32], 32); + p += 32; - /* - * Set up the algorithm. - */ - { - char *p = buff2; - - memcpy(p, &vp->vp_octets[32], 32); - p += 32; - *(p++) = 89; - strcpy(p, request->password->vp_strvalue); - p += strlen(p); - *(p++) = 247; - memcpy(p, &vp->vp_octets[32], 32); - p += 32; - - fr_MD5Init(&md5_context); - fr_MD5Update(&md5_context, (uint8_t *) buff2, - p - buff2); - fr_MD5Final(buff, &md5_context); - } - if (rad_digest_cmp(binbuf, buff, 16) != 0) { - snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: NS-MTA-MD5 password check failed"); - goto make_msg; - } - goto done; + fr_MD5Init(&md5_context); + fr_MD5Update(&md5_context, (uint8_t *) buff2, + p - buff2); + fr_MD5Final(buff, &md5_context); + } + if (rad_digest_cmp(binbuf, buff, 16) != 0) { + snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: NS-MTA-MD5 password check failed"); + goto make_msg; + } + goto done; } +static int pap_auth_crypt(REQUEST *request, VALUE_PAIR *vp, char *fmsg) +{ + RDEBUG("Using CRYPT password \"%s\"", vp->vp_strvalue); + if (fr_crypt_check(request->password->vp_strvalue, + vp->vp_strvalue) != 0) { + snprintf(fmsg,sizeof(char[MAX_STRING_LEN]),"rlm_pap: CRYPT password check failed"); + return RLM_MODULE_REJECT; + } + return RLM_MODULE_OK; +} + /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'.