From d9780eacd9e61c5062cdabdce21c224de1884583 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Wed, 27 Aug 2014 10:45:42 +0200 Subject: [PATCH] move check_user_token() to util for testability.. --- pam_yubico.c | 82 ++----------------------------------------------- util.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 1 + 3 files changed, 90 insertions(+), 80 deletions(-) diff --git a/pam_yubico.c b/pam_yubico.c index 78abe38..48308bd 100644 --- a/pam_yubico.c +++ b/pam_yubico.c @@ -127,84 +127,6 @@ struct cfg #endif #define DBG(x) if (cfg->debug) { D(x); } -/* - * This function will look for users name with valid user token id. It - * will returns -2 if the user is unknown, -1 if the token do not match the user line, 0 for internal failure and 1 for success. - * - * File format is as follows: - * :: - * : - * - */ -static int -check_user_token (struct cfg *cfg, - const char *authfile, - const char *username, - const char *otp_id) -{ - char buf[1024]; - char *s_user, *s_token; - int retval = 0; - int fd; - struct stat st; - FILE *opwfile; - - fd = open(authfile, O_RDONLY, 0); - if (fd < 0) { - DBG (("Cannot open file: %s (%s)", authfile, strerror(errno))); - return retval; - } - - if (fstat(fd, &st) < 0) { - DBG (("Cannot stat file: %s (%s)", authfile, strerror(errno))); - close(fd); - return retval; - } - - if (!S_ISREG(st.st_mode)) { - DBG (("%s is not a regular file", authfile)); - close(fd); - return retval; - } - - opwfile = fdopen(fd, "r"); - if (opwfile == NULL) { - DBG (("fdopen: %s", strerror(errno))); - close(fd); - return retval; - } - - retval = -2; - while (fgets (buf, 1024, opwfile)) - { - if (buf[strlen (buf) - 1] == '\n') - buf[strlen (buf) - 1] = '\0'; - DBG (("Authorization line: %s", buf)); - s_user = strtok (buf, ":"); - if (s_user && strcmp (username, s_user) == 0) - { - DBG (("Matched user: %s", s_user)); - retval = -1; //We found at least one line for the user - do - { - s_token = strtok (NULL, ":"); - DBG (("Authorization token: %s", s_token)); - if (s_token && strcmp (otp_id, s_token) == 0) - { - DBG (("Match user/token as %s/%s", username, otp_id)); - fclose (opwfile); - return 1; - } - } - while (s_token != NULL); - } - } - - fclose (opwfile); - - return retval; -} - /* * Authorize authenticated OTP_ID for login as USERNAME using * AUTHFILE. Return -2 if the user is unknown, -1 if the OTP_ID does not match, 0 on internal failures, otherwise success. @@ -223,7 +145,7 @@ authorize_user_token (struct cfg *cfg, as an argument for this module. */ DBG (("Using system-wide auth_file %s", cfg->auth_file)); - retval = check_user_token (cfg, cfg->auth_file, username, otp_id); + retval = check_user_token (cfg->auth_file, username, otp_id, cfg->debug); } else { @@ -252,7 +174,7 @@ authorize_user_token (struct cfg *cfg, goto free_out; } - retval = check_user_token (cfg, userfile, username, otp_id); + retval = check_user_token (userfile, username, otp_id, cfg->debug); if(pam_modutil_regain_priv(pamh, &privs)) { DBG (("could not restore privileges")); diff --git a/util.c b/util.c index 92838bc..ecfacf6 100644 --- a/util.c +++ b/util.c @@ -86,6 +86,93 @@ get_user_cfgfile_path(const char *common_path, const char *filename, const char return 1; } + +/* + * This function will look for users name with valid user token id. It + * will returns -2 if the user is unknown, -1 if the token do not match the user line, 0 for internal failure and 1 for success. + * + * File format is as follows: + * :: + * : + * + */ +int +check_user_token (const char *authfile, + const char *username, + const char *otp_id, + int verbose) +{ + char buf[1024]; + char *s_user, *s_token; + int retval = 0; + int fd; + struct stat st; + FILE *opwfile; + + fd = open(authfile, O_RDONLY, 0); + if (fd < 0) { + if(verbose) + D (("Cannot open file: %s (%s)", authfile, strerror(errno))); + return retval; + } + + if (fstat(fd, &st) < 0) { + if(verbose) + D (("Cannot stat file: %s (%s)", authfile, strerror(errno))); + close(fd); + return retval; + } + + if (!S_ISREG(st.st_mode)) { + if(verbose) + D (("%s is not a regular file", authfile)); + close(fd); + return retval; + } + + opwfile = fdopen(fd, "r"); + if (opwfile == NULL) { + if(verbose) + D (("fdopen: %s", strerror(errno))); + close(fd); + return retval; + } + + retval = -2; + while (fgets (buf, 1024, opwfile)) + { + if (buf[strlen (buf) - 1] == '\n') + buf[strlen (buf) - 1] = '\0'; + if(verbose) + D (("Authorization line: %s", buf)); + s_user = strtok (buf, ":"); + if (s_user && strcmp (username, s_user) == 0) + { + if(verbose) + D (("Matched user: %s", s_user)); + retval = -1; //We found at least one line for the user + do + { + s_token = strtok (NULL, ":"); + if(verbose) + D (("Authorization token: %s", s_token)); + if (s_token && strcmp (otp_id, s_token) == 0) + { + if(verbose) + D (("Match user/token as %s/%s", username, otp_id)); + fclose (opwfile); + return 1; + } + } + while (s_token != NULL); + } + } + + fclose (opwfile); + + return retval; +} + #if HAVE_CR /* Fill buf with len bytes of random data */ int generate_random(void *buf, int len) diff --git a/util.h b/util.h index cc3d344..edb81ac 100644 --- a/util.h +++ b/util.h @@ -53,6 +53,7 @@ #endif /* DEBUG_PAM */ int get_user_cfgfile_path(const char *common_path, const char *filename, const char *username, char **fn); +int check_user_token(const char *authfile, const char *username, const char *otp_id, int verbose); #if HAVE_CR #include