/* * Authorize authenticated OTP_ID for login as USERNAME using * AUTHFILE. Return 0 on failures, otherwise success. */ static int authorize_user_token (struct cfg *cfg, const char *username, const char *otp_id) { int retval; if (cfg->auth_file) { /* Administrator had configured the file and specified is name as an argument for this module. */ retval = check_user_token (cfg, cfg->auth_file, username, otp_id); } else { char *userfile = NULL; /* Getting file from user home directory ..... i.e. ~/.yubico/authorized_yubikeys */ if (! get_user_cfgfile_path (NULL, "authorized_yubikeys", username, &userfile)) return 0; retval = check_user_token (cfg, userfile, username, otp_id); free (userfile); } return retval; #undef USERFILE }
/* * Authorize authenticated OTP_ID for login as USERNAME using * AUTHFILE. Return 0 on failures, otherwise success. */ static int authorize_user_token (struct cfg *cfg, const char *username, const char *otp_id, pam_handle_t *pamh) { int retval; if (cfg->auth_file) { /* Administrator had configured the file and specified is name 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); } else { char *userfile = NULL; struct passwd *p; p = getpwnam (username); if (p == NULL) { DBG (("getpwnam: %s", strerror(errno))); return 0; } /* Getting file from user home directory ..... i.e. ~/.yubico/authorized_yubikeys */ if (! get_user_cfgfile_path (NULL, "authorized_yubikeys", username, &userfile)) { D (("Failed figuring out per-user cfgfile")); return 0; } DBG (("Dropping privileges")); if (drop_privileges(p, pamh) < 0) { D (("could not drop privileges")); return 0; } retval = check_user_token (cfg, userfile, username, otp_id); if (restore_privileges(pamh) < 0) { DBG (("could not restore privileges")); return 0; } free (userfile); } return retval; }
static void test_check_user_token(void) { char file[] = "/tmp/pamtest.XXXXXX"; int fd = mkstemp(file); FILE *handle; int ret; assert(fd != -1); handle = fdopen(fd, "w"); fprintf(handle, "foobar:hhhvhvhdhbid:hnhbhnhbhnhb:\n"); fprintf(handle, "kaka:hdhrhbhjhvhu:hihbhdhrhbhj\n"); fprintf(handle, "bar:hnhbhnhbhnhb\n"); fclose(handle); ret = check_user_token(file, "foobar", "hhhvhvhdhbid", 1); assert(ret == 1); ret = check_user_token(file, "foobar", "hnhbhnhbhnhb", 1); assert(ret == 1); ret = check_user_token(file, "foobar", "hnhbhnhbhnhc", 1); assert(ret == -1); ret = check_user_token(file, "kaka", "hihbhdhrhbhj", 1); assert(ret == 1); ret = check_user_token(file, "bar", "hnhbhnhbhnhb", 1); assert(ret == 1); ret = check_user_token(file, "foo", "hdhrhbhjhvhu", 1); assert(ret == -2); remove(file); }
static void test_check_user_token(void) { char file[] = "/tmp/pamtest.XXXXXX"; int fd = mkstemp(file); FILE *handle; int ret; assert(fd != -1); handle = fdopen(fd, "w"); fprintf(handle, "# This is a comment containing foobar:foobar\n"); fprintf(handle, "foobar:hhhvhvhdhbid:hnhbhnhbhnhb:\n"); fprintf(handle, "# This is a comment in the middle\n"); fprintf(handle, "kaka:hdhrhbhjhvhu:hihbhdhrhbhj\n"); fprintf(handle, "# foo2 is a user showing up twice in the file\n"); fprintf(handle, "foo2:vvvvvvvvvvvv\n"); fprintf(handle, "bar:hnhbhnhbhnhb\n"); fprintf(handle, "foo2:cccccccccccc\n"); fclose(handle); ret = check_user_token(file, "foobar", "hhhvhvhdhbid", 1); assert(ret == 1); ret = check_user_token(file, "foobar", "hnhbhnhbhnhb", 1); assert(ret == 1); ret = check_user_token(file, "foobar", "hnhbhnhbhnhc", 1); assert(ret == -1); ret = check_user_token(file, "kaka", "hihbhdhrhbhj", 1); assert(ret == 1); ret = check_user_token(file, "bar", "hnhbhnhbhnhb", 1); assert(ret == 1); ret = check_user_token(file, "foo", "hdhrhbhjhvhu", 1); assert(ret == -2); ret = check_user_token(file, "foo2", "cccccccccccc", 1); assert(ret == 1); ret = check_user_token(file, "foo2", "vvvvvvvvvvvv", 1); assert(ret == 1); ret = check_user_token(file, "foo2", "vvvvvvvvvvcc", 1); assert(ret == -1); remove(file); }