1
0
mirror of https://github.com/Yubico/yubico-pam.git synced 2024-11-29 00:24:11 +01:00

Make length of public ID part of tokens configurable.

Now that we support setting URL, not all public ID's can be expected
to be six bytes (the length used in the YubiCloud validation service).

Unfortunately we can't support OTPs of different lengths at once,
because there is code supporting users entering their (other)
password followed by the OTP from the YubiKey.

Patch by fraser.scott@gmail.com in
http://code.google.com/p/yubico-pam/issues/detail?id=19
This commit is contained in:
Fredrik Thulin 2011-02-28 17:09:08 +01:00
parent bdfa3891e2
commit 336f794b42

View File

@ -81,8 +81,9 @@
#include <sys/types.h>
#include <pwd.h>
#define TOKEN_LEN 44
#define TOKEN_ID_LEN 12
#define TOKEN_OTP_LEN 32
#define MAX_TOKEN_ID_LEN 16
#define DEFAULT_TOKEN_ID_LEN 12
/*
* This function will look for users name with valid user token id. It
@ -346,6 +347,7 @@ struct cfg
char *ldapdn;
char *user_attr;
char *yubi_attr;
int token_id_length;
};
static void
@ -368,6 +370,7 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg)
cfg->ldapdn = NULL;
cfg->user_attr = NULL;
cfg->yubi_attr = NULL;
cfg->token_id_length = DEFAULT_TOKEN_ID_LEN;
for (i = 0; i < argc; i++)
{
@ -401,6 +404,8 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg)
cfg->user_attr = (char *) argv[i] + 10;
if (strncmp (argv[i], "yubi_attr=", 10) == 0)
cfg->yubi_attr = (char *) argv[i] + 10;
if (strncmp (argv[i], "token_id_length=", 17) == 0)
sscanf (argv[i], "token_id_length=%d", &cfg->token_id_length);
}
if (cfg->debug)
@ -424,6 +429,7 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg)
D (("yubi_attr=%s", cfg->yubi_attr ? cfg->yubi_attr : "(null)"));
D (("url=%s", cfg->url ? cfg->url : "(null)"));
D (("capath=%s", cfg->capath ? cfg->capath : "(null)"));
D (("token_id_length=%d", cfg->token_id_length));
}
}
@ -436,9 +442,10 @@ pam_sm_authenticate (pam_handle_t * pamh,
int retval, rc;
const char *user = NULL;
const char *password = NULL;
char otp[TOKEN_LEN + 1] = { 0 };
char otp_id[TOKEN_ID_LEN + 1] = { 0 };
char otp[MAX_TOKEN_ID_LEN + TOKEN_OTP_LEN + 1] = { 0 };
char otp_id[MAX_TOKEN_ID_LEN + 1] = { 0 };
int password_len = 0;
int skip_bytes = 0;
int valid_token = 0;
struct pam_conv *conv;
struct pam_message *pmsg[1], msg[1];
@ -554,24 +561,33 @@ pam_sm_authenticate (pam_handle_t * pamh,
}
password_len = strlen (password);
if (password_len < TOKEN_LEN)
if (password_len < TOKEN_OTP_LEN)
{
DBG (("OTP too short: %s", password));
retval = PAM_AUTH_ERR;
goto done;
}
strncpy (otp, password + (password_len - TOKEN_LEN), TOKEN_LEN);
strncpy (otp_id, password + (password_len - TOKEN_LEN), TOKEN_ID_LEN);
/* In case the input was systempassword+YubiKeyOTP, we want to skip over
"systempassword" when copying the token_id and OTP to separate buffers */
skip_bytes = password_len - (cfg.token_id_length + TOKEN_OTP_LEN);
DBG (("Skipping first %i bytes. Length is %i, token_id set to %i and token OTP always %i.",
skip_bytes, password_len, cfg.token_id_length, TOKEN_OTP_LEN));
/* Copy full YubiKey output (public ID + OTP) into otp */
strncpy (otp, password + skip_bytes, sizeof (otp) - 1);
/* Copy only public ID into otp_id. Destination buffer is zeroed. */
strncpy (otp_id, password + skip_bytes, cfg.token_id_length);
DBG (("OTP: %s ID: %s ", otp, otp_id));
/* user entered their system password followed by generated OTP? */
if (password_len > TOKEN_LEN)
if (password_len > TOKEN_OTP_LEN + cfg.token_id_length)
{
char *onlypasswd = strdup (password);
onlypasswd[password_len - TOKEN_LEN] = '\0';
onlypasswd[password_len - (TOKEN_OTP_LEN + cfg.token_id_length)] = '\0';
DBG (("Password: %s ", onlypasswd));