#include "../../include/md5.h"
#include "../../include/sha1.h"
-#include "rlm_pap.h"
-
/*
* Define a structure for our module configuration.
*
return RLM_MODULE_UPDATED;
}
-
-/*
- * Authenticate the user via one of any well-known password.
- */
-static rlm_rcode_t pap_authenticate(void *instance, REQUEST *request)
-{
- VALUE_PAIR *vp;
- VALUE_PAIR *module_fmsg_vp;
- char module_fmsg[MAX_STRING_LEN];
- rlm_rcode_t rc = RLM_MODULE_INVALID;
- int (*auth_func)(REQUEST *, VALUE_PAIR *, char *) = NULL;
-
- /* Shut the compiler up */
- instance = instance;
-
- if (!request->password ||
- (request->password->da->attr != PW_USER_PASSWORD)) {
- RDEBUGE("You set 'Auth-Type = PAP' for a request that does not contain a User-Password attribute!");
- return RLM_MODULE_INVALID;
- }
-
- /*
- * The user MUST supply a non-zero-length password.
- */
- if (request->password->length == 0) {
- snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: empty password supplied");
- module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
- pairadd(&request->packet->vps, module_fmsg_vp);
- return RLM_MODULE_INVALID;
- }
-
- RDEBUG("login attempt with password \"%s\"", request->password->vp_strvalue);
-
- /*
- * Auto-detect passwords, by attribute in the
- * config items, to find out which authentication
- * function to call.
- */
- for (vp = request->config_items; vp != NULL; vp = vp->next) {
- if (!vp->da->vendor) switch (vp->da->attr) {
- case PW_CLEARTEXT_PASSWORD:
- auth_func = &pap_auth_clear;
- break;
-
- case PW_CRYPT_PASSWORD:
- auth_func = &pap_auth_crypt;
- break;
-
- case PW_MD5_PASSWORD:
- auth_func = &pap_auth_md5;
- break;
-
- case PW_SMD5_PASSWORD:
- auth_func = &pap_auth_smd5;
- break;
-
- case PW_SHA_PASSWORD:
- auth_func = &pap_auth_sha;
- break;
-
- case PW_SSHA_PASSWORD:
- auth_func = &pap_auth_ssha;
- break;
-
- case PW_NT_PASSWORD:
- auth_func = &pap_auth_nt;
- break;
-
- case PW_LM_PASSWORD:
- auth_func = &pap_auth_lm;
- break;
-
- case PW_NS_MTA_MD5_PASSWORD:
- auth_func = &pap_auth_ns_mta_md5;
- break;
-
- default:
- break;
- }
-
- if (auth_func != NULL) break;
- }
-
- /*
- * No attribute was found that looked like a password to match.
- */
- if (auth_func == NULL) {
- RDEBUG("No password configured for the user. Cannot do authentication");
- return RLM_MODULE_FAIL;
- }
-
- /*
- * Authenticate, and return.
- */
- rc = auth_func(request, vp, module_fmsg);
-
- if (rc == RLM_MODULE_REJECT) {
- RDEBUG("Passwords don't match");
- module_fmsg_vp = pairmake("Module-Failure-Message",
- module_fmsg, T_OP_EQ);
- pairadd(&request->packet->vps, module_fmsg_vp);
- }
-
- if (rc == RLM_MODULE_OK) {
- RDEBUG("User authenticated successfully");
- }
-
- return rc;
-}
-
-
/*
* PAP authentication functions
*/
-static int pap_auth_clear(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_clear(REQUEST *request, VALUE_PAIR *vp)
{
RDEBUG("Using clear text password \"%s\"", vp->vp_strvalue);
(rad_digest_cmp(vp->vp_octets,
request->password->vp_octets,
vp->length) != 0)) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: CLEAR TEXT password check failed");
+ RDEBUGE("CLEAR TEXT password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
-static int pap_auth_crypt(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_crypt(REQUEST *request, VALUE_PAIR *vp)
{
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");
+ RDEBUGE("CRYPT password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
-static int pap_auth_md5(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_md5(REQUEST *request, VALUE_PAIR *vp)
{
FR_MD5_CTX md5_context;
uint8_t binbuf[128];
normify(request, vp, 16);
if (vp->length != 16) {
- RDEBUG("Configured MD5 password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured MD5 password has incorrect length");
+ RDEBUGE("Configured MD5 password has incorrect length");
return RLM_MODULE_REJECT;
}
fr_MD5Final(binbuf, &md5_context);
if (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: MD5 password check failed");
+ RDEBUGE("MD5 password check failed");
return RLM_MODULE_REJECT;
}
}
-static int pap_auth_smd5(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_smd5(REQUEST *request, VALUE_PAIR *vp)
{
FR_MD5_CTX md5_context;
uint8_t binbuf[128];
normify(request, vp, 16);
if (vp->length <= 16) {
- RDEBUG("Configured SMD5 password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured SMD5 password has incorrect length");
+ RDEBUGE("Configured SMD5 password has incorrect length");
return RLM_MODULE_REJECT;
}
* Compare only the MD5 hash results, not the salt.
*/
if (rad_digest_cmp(binbuf, vp->vp_octets, 16) != 0) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: SMD5 password check failed");
+ RDEBUGE("SMD5 password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
-static int pap_auth_sha(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_sha(REQUEST *request, VALUE_PAIR *vp)
{
fr_SHA1_CTX sha1_context;
uint8_t binbuf[128];
normify(request, vp, 20);
if (vp->length != 20) {
- RDEBUG("Configured SHA1 password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured SHA1 password has incorrect length");
+ RDEBUGE("SHA1 password has incorrect length");
return RLM_MODULE_REJECT;
}
fr_SHA1Final(binbuf,&sha1_context);
if (rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: SHA1 password check failed");
+ RDEBUGE("SHA1 password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
-static int pap_auth_ssha(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_ssha(REQUEST *request, VALUE_PAIR *vp)
{
fr_SHA1_CTX sha1_context;
uint8_t binbuf[128];
normify(request, vp, 20);
if (vp->length <= 20) {
- RDEBUG("Configured SSHA password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured SHA password has incorrect length");
+ RDEBUGE("SSHA password has incorrect length");
return RLM_MODULE_REJECT;
}
fr_SHA1Final(binbuf,&sha1_context);
if (rad_digest_cmp(binbuf, vp->vp_octets, 20) != 0) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: SSHA password check failed");
+ RDEBUGE("SSHA password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
-static int pap_auth_nt(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_nt(REQUEST *request, VALUE_PAIR *vp)
{
uint8_t binbuf[128];
char charbuf[128];
normify(request, vp, 16);
if (vp->length != 16) {
- RDEBUG("Configured NT-Password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured NT-Password has incorrect length");
+ RDEBUGE("Configured NT-Password has incorrect length");
return RLM_MODULE_REJECT;
}
strlcpy(buff2, "%{mschap:NT-Hash %{User-Password}}", sizeof(buff2));
if (!radius_xlat(charbuf, sizeof(charbuf),buff2,request,NULL,NULL)){
- RDEBUG("mschap xlat failed");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: mschap xlat failed");
+ RDEBUGE("mschap xlat failed");
return RLM_MODULE_REJECT;
}
if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) ||
(rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: NT password check failed");
+ RDEBUGE("NT password check failed");
return RLM_MODULE_REJECT;
}
}
-static int pap_auth_lm(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_lm(REQUEST *request, VALUE_PAIR *vp)
{
uint8_t binbuf[128];
char charbuf[128];
normify(request, vp, 16);
if (vp->length != 16) {
- RDEBUG("Configured LM-Password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured LM-Password has incorrect length");
+ RDEBUGE("Configure LM-Password has incorrect length");
return RLM_MODULE_REJECT;
}
strlcpy(buff2, "%{mschap:LM-Hash %{User-Password}}", sizeof(buff2));
if (!radius_xlat(charbuf,sizeof(charbuf),buff2,request,NULL,NULL)){
- RDEBUG("mschap xlat failed");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: mschap xlat failed");
+ RDEBUGE("mschap xlat failed");
return RLM_MODULE_REJECT;
}
if ((fr_hex2bin(charbuf, binbuf, 16) != vp->length) ||
(rad_digest_cmp(binbuf, vp->vp_octets, vp->length) != 0)) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: LM password check failed");
+ RDEBUGE("LM password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
-static int pap_auth_ns_mta_md5(REQUEST *request, VALUE_PAIR *vp, char *fmsg)
+static int pap_auth_ns_mta_md5(REQUEST *request, VALUE_PAIR *vp)
{
FR_MD5_CTX md5_context;
uint8_t binbuf[128];
RDEBUG("Using NT-MTA-MD5 password");
if (vp->length != 64) {
- RDEBUG("Configured NS-MTA-MD5-Password has incorrect length");
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured NS-MTA-MD5-Password has incorrect length");
+ RDEBUGE("Configured NS-MTA-MD5-Password has incorrect length");
return RLM_MODULE_REJECT;
}
* 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(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: Configured NS-MTA-MD5-Password has invalid value");
+ RDEBUGE("Configured NS-MTA-MD5-Password has invalid value");
return RLM_MODULE_REJECT;
}
* 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(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: password is too long");
+ RDEBUGE("Configured password is too long");
return RLM_MODULE_REJECT;
}
}
if (rad_digest_cmp(binbuf, buff, 16) != 0) {
- snprintf(fmsg, sizeof(char[MAX_STRING_LEN]),
- "rlm_pap: NS-MTA-MD5 password check failed");
+ RDEBUGE("NS-MTA-MD5 password check failed");
return RLM_MODULE_REJECT;
}
return RLM_MODULE_OK;
}
+
+/*
+ * Authenticate the user via one of any well-known password.
+ */
+static rlm_rcode_t pap_authenticate(void *instance, REQUEST *request)
+{
+ VALUE_PAIR *vp;
+ rlm_rcode_t rc = RLM_MODULE_INVALID;
+ int (*auth_func)(REQUEST *, VALUE_PAIR *) = NULL;
+
+ /* Shut the compiler up */
+ instance = instance;
+
+ if (!request->password ||
+ (request->password->da->attr != PW_USER_PASSWORD)) {
+ RDEBUGE("You set 'Auth-Type = PAP' for a request that does not contain a User-Password attribute!");
+ return RLM_MODULE_INVALID;
+ }
+
+ /*
+ * The user MUST supply a non-zero-length password.
+ */
+ if (request->password->length == 0) {
+ RDEBUGE("Password must not be empty");
+ return RLM_MODULE_INVALID;
+ }
+
+ RDEBUG("login attempt with password \"%s\"", request->password->vp_strvalue);
+
+ /*
+ * Auto-detect passwords, by attribute in the
+ * config items, to find out which authentication
+ * function to call.
+ */
+ for (vp = request->config_items; vp != NULL; vp = vp->next) {
+ if (!vp->da->vendor) switch (vp->da->attr) {
+ case PW_CLEARTEXT_PASSWORD:
+ auth_func = &pap_auth_clear;
+ break;
+
+ case PW_CRYPT_PASSWORD:
+ auth_func = &pap_auth_crypt;
+ break;
+
+ case PW_MD5_PASSWORD:
+ auth_func = &pap_auth_md5;
+ break;
+
+ case PW_SMD5_PASSWORD:
+ auth_func = &pap_auth_smd5;
+ break;
+
+ case PW_SHA_PASSWORD:
+ auth_func = &pap_auth_sha;
+ break;
+
+ case PW_SSHA_PASSWORD:
+ auth_func = &pap_auth_ssha;
+ break;
+
+ case PW_NT_PASSWORD:
+ auth_func = &pap_auth_nt;
+ break;
+
+ case PW_LM_PASSWORD:
+ auth_func = &pap_auth_lm;
+ break;
+
+ case PW_NS_MTA_MD5_PASSWORD:
+ auth_func = &pap_auth_ns_mta_md5;
+ break;
+
+ default:
+ break;
+ }
+
+ if (auth_func != NULL) break;
+ }
+
+ /*
+ * No attribute was found that looked like a password to match.
+ */
+ if (auth_func == NULL) {
+ RDEBUG("No password configured for the user. Cannot do authentication");
+ return RLM_MODULE_FAIL;
+ }
+
+ /*
+ * Authenticate, and return.
+ */
+ rc = auth_func(request, vp);
+
+ if (rc == RLM_MODULE_REJECT) {
+ RDEBUG("Passwords don't match");
+ }
+
+ if (rc == RLM_MODULE_OK) {
+ RDEBUG("User authenticated successfully");
+ }
+
+ return rc;
+}
+
+
/*
* The module name should be the only globally exported symbol.
* That is, everything else should be 'static'.