int main(int argc, char **argv) { char buffer[0x1000] = { 0 }; char user[0x100], pwd[0x100], cookie[0x100] = { 0 }; (void)(argc); (void)(argv); if ( !getenv("REQUEST_METHOD") || strcmp(getenv("REQUEST_METHOD"), "POST") || !fread(buffer, 1, sizeof(buffer) - 1, stdin) ) login_page(NULL); chomp(buffer); if (parse_request(buffer, user, sizeof(user), pwd, sizeof(pwd))) login_page("Missing username or password"); if (!match_user("db/members.csv", user, pwd)) login_page("Incorrect username or password"); if (set_cookie("db/loggedin.csv", user, cookie, sizeof(cookie))) login_page("Internal error, please try again"); catalog_page(user, cookie); return 0; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { #ifdef HAVE_LOGIN_CAP extern login_cap_t *lc; int match_name, match_ip; char *cap_hlist, *hp; #endif struct ssh *ssh = active_state; /* XXX */ struct stat st; const char *hostname = NULL, *ipaddr = NULL; int r; u_int i; /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef HAVE_LOGIN_CAP hostname = auth_get_canonical_hostname(ssh, options.use_dns); ipaddr = ssh_remote_ipaddr(ssh); lc = login_getclass(pw->pw_class); /* * Check the deny list. */ cap_hlist = login_getcapstr(lc, "host.deny", NULL, NULL); if (cap_hlist != NULL) { hp = strtok(cap_hlist, ","); while (hp != NULL) { match_name = match_hostname(hostname, hp); match_ip = match_hostname(ipaddr, hp); /* * Only a positive match here causes a "deny". */ if (match_name > 0 || match_ip > 0) { free(cap_hlist); login_close(lc); return 0; } hp = strtok(NULL, ","); } free(cap_hlist); } /* * Check the allow list. If the allow list exists, and the * remote host is not in it, the user is implicitly denied. */ cap_hlist = login_getcapstr(lc, "host.allow", NULL, NULL); if (cap_hlist != NULL) { hp = strtok(cap_hlist, ","); if (hp == NULL) { /* Just in case there's an empty string... */ free(cap_hlist); login_close(lc); return 0; } while (hp != NULL) { match_name = match_hostname(hostname, hp); match_ip = match_hostname(ipaddr, hp); /* * Negative match causes an immediate "deny". * Positive match causes us to break out * of the loop (allowing a fallthrough). */ if (match_name < 0 || match_ip < 0) { free(cap_hlist); login_close(lc); return 0; } if (match_name > 0 || match_ip > 0) break; hp = strtok(NULL, ","); } free(cap_hlist); if (hp == NULL) { login_close(lc); return 0; } } login_close(lc); #endif #ifdef USE_PAM if (!options.use_pam) { #endif /* * password/account expiration. */ if (pw->pw_change || pw->pw_expire) { struct timeval tv; (void)gettimeofday(&tv, (struct timezone *)NULL); if (pw->pw_expire) { if (tv.tv_sec >= pw->pw_expire) { logit("User %.100s not allowed because account has expired", pw->pw_name); return 0; /* expired */ } } #ifdef _PASSWORD_CHGNOW if (pw->pw_change == _PASSWORD_CHGNOW) { logit("User %.100s not allowed because password needs to be changed", pw->pw_name); return 0; /* can't force password change (yet) */ } #endif if (pw->pw_change) { if (tv.tv_sec >= pw->pw_change) { logit("User %.100s not allowed because password has expired", pw->pw_name); return 0; /* expired */ } } } #ifdef USE_PAM } #endif /* * Deny if shell does not exist or is not executable unless we * are chrooting. */ /* * XXX Should check to see if it is executable by the * XXX requesting user. --thorpej */ if (options.chroot_directory == NULL || strcasecmp(options.chroot_directory, "none") == 0) { char *shell = xstrdup((pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s " "does not exist", pw->pw_name, shell); free(shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s " "is not executable", pw->pw_name, shell); free(shell); return 0; } free(shell); } /* * XXX Consider nuking {Allow,Deny}{Users,Groups}. We have the * XXX login_cap(3) mechanism which covers all other types of * XXX logins, too. */ if (options.num_deny_users > 0 || options.num_allow_users > 0 || options.num_deny_groups > 0 || options.num_allow_groups > 0) { hostname = auth_get_canonical_hostname(ssh, options.use_dns); ipaddr = ssh_remote_ipaddr(ssh); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) { r = match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i]); if (r < 0) { fatal("Invalid DenyUsers pattern \"%.100s\"", options.deny_users[i]); } else if (r != 0) { logit("User %.100s from %.100s not allowed " "because listed in DenyUsers", pw->pw_name, hostname); return 0; } } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) { r = match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i]); if (r < 0) { fatal("Invalid AllowUsers pattern \"%.100s\"", options.allow_users[i]); } else if (r == 1) break; } /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s from %.100s not allowed because " "not listed in AllowUsers", pw->pw_name, hostname); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s from %.100s not allowed because " "not in any group", pw->pw_name, hostname); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because a group is listed in DenyGroups", pw->pw_name, hostname); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because none of user's groups are listed " "in AllowGroups", pw->pw_name, hostname); return 0; } ga_free(); } /* We found no reason not to let this user try to log on... */ return 1; }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { int i, rv; const char *user = NULL; char *password; unsigned int slot_num = 0; int is_a_screen_saver = 0; struct configuration_st *configuration; int pkcs11_pam_fail = PAM_AUTHINFO_UNAVAIL; pkcs11_handle_t *ph; cert_object_t *chosen_cert = NULL; cert_object_t **cert_list; int ncert; unsigned char random_value[128]; unsigned char *signature; unsigned long signature_length; /* enough space to hold an issuer DN */ char env_temp[256] = ""; char **issuer, **serial; const char *login_token_name = NULL; pam_prompt(pamh, PAM_TEXT_INFO , NULL, _("Smartcard authentication starts")); /* first of all check whether debugging should be enabled */ for (i = 0; i < argc; i++) if (strcmp("debug", argv[i]) == 0) { set_debug_level(1); } /* call configure routines */ configuration = pk_configure(argc,argv); if (!configuration ) { ERR("Error setting configuration parameters"); return PAM_AUTHINFO_UNAVAIL; } /* Either slot_description or slot_num, but not both, needs to be used */ if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) { ERR("Error setting configuration parameters"); return PAM_AUTHINFO_UNAVAIL; } /* fail if we are using a remote server * local login: DISPLAY=:0 * XDMCP login: DISPLAY=host:0 */ { char *display = getenv("DISPLAY"); if (display) { if (strncmp(display, "localhost:", 10) != 0 && (display[0] != ':') && (display[0] != '\0')) { ERR1("Remote login (from %s) is not (yet) supported", display); pam_syslog(pamh, LOG_ERR, "Remote login (from %s) is not (yet) supported", display); return PAM_AUTHINFO_UNAVAIL; } } } #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, "/usr/share/locale"); textdomain(PACKAGE); #endif /* init openssl */ rv = crypto_init(&configuration->policy); if (rv != 0) { ERR("Failed to initialize crypto"); if (!configuration->quiet) pam_syslog(pamh,LOG_ERR, "Failed to initialize crypto"); return PAM_AUTHINFO_UNAVAIL; } /* * card_only means: * 1) always get the userid from the certificate. * 2) don't prompt for the user name if the card is present. * 3) if the token is present, then we must use the cardAuth mechanism. * * wait_for_card means: * 1) nothing if card_only isn't set * 2) if logged in, block in pam conversation until the token used for login * is inserted * 3) if not logged in, block until a token that could be used for logging in * is inserted * right now, logged in means PKC11_LOGIN_TOKEN_NAME is set, * but we could something else later (like set some per-user state in * a pam session module keyed off uid) */ if (configuration->card_only) { char *service; if (configuration->screen_savers) { DBG("Is it a screen saver?"); pam_get_item(pamh, PAM_SERVICE, &service); for (i=0; configuration->screen_savers[i]; i++) { if (strcmp(configuration->screen_savers[i], service) == 0) { is_a_screen_saver = 1; break; } } } pkcs11_pam_fail = PAM_CRED_INSUFFICIENT; /* look to see if username is already set */ pam_get_item(pamh, PAM_USER, &user); if (user) { DBG1("explicit username = [%s]", user); } } else { rv = pam_get_item(pamh, PAM_USER, &user); if (rv != PAM_SUCCESS || user == NULL || user[0] == '\0') { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Please insert your %s or enter your username."), _(configuration->token_type)); /* get user name */ rv = pam_get_user(pamh, &user, NULL); if (rv != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "pam_get_user() failed %s", pam_strerror(pamh, rv)); return PAM_USER_UNKNOWN; } } DBG1("username = [%s]", user); } login_token_name = getenv("PKCS11_LOGIN_TOKEN_NAME"); /* if we are using a screen saver, and we didn't log in using the smart card * drop to the next pam module. */ if (is_a_screen_saver && !login_token_name) { return PAM_IGNORE; } /* load pkcs #11 module */ DBG("loading pkcs #11 module..."); rv = load_pkcs11_module(configuration->pkcs11_modulepath, &ph); if (rv != 0) { ERR2("load_pkcs11_module() failed loading %s: %s", configuration->pkcs11_modulepath, get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "load_pkcs11_module() failed loading %s: %s", configuration->pkcs11_modulepath, get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2302: PKCS#11 module failed loading")); sleep(configuration->err_display_time); } return PAM_AUTHINFO_UNAVAIL; } /* initialise pkcs #11 module */ DBG("initialising pkcs #11 module..."); rv = init_pkcs11_module(ph,configuration->support_threads); if (rv != 0) { release_pkcs11_module(ph); ERR1("init_pkcs11_module() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "init_pkcs11_module() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2304: PKCS#11 module could not be initialized")); sleep(configuration->err_display_time); } return PAM_AUTHINFO_UNAVAIL; } /* open pkcs #11 session */ if (configuration->slot_description != NULL) { rv = find_slot_by_slotlabel_and_tokenlabel(ph, configuration->slot_description, login_token_name, &slot_num); } else if (configuration->slot_num != -1) { rv = find_slot_by_number_and_label(ph, configuration->slot_num, login_token_name, &slot_num); } if (rv != 0) { ERR("no suitable token available"); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "no suitable token available"); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2306: No suitable token available")); sleep(configuration->err_display_time); } if (!configuration->card_only) { release_pkcs11_module(ph); return PAM_AUTHINFO_UNAVAIL; } /* we must have a smart card, either because we've configured it as such, * or because we used one to log in */ if (login_token_name || configuration->wait_for_card) { if (login_token_name) { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Please insert your smart card called \"%.32s\"."), login_token_name); } else { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Please insert your smart card.")); } if (configuration->slot_description != NULL) { rv = wait_for_token_by_slotlabel(ph, configuration->slot_description, login_token_name, &slot_num); } else if (configuration->slot_num != -1) { rv = wait_for_token(ph, configuration->slot_num, login_token_name, &slot_num); } if (rv != 0) { release_pkcs11_module(ph); return pkcs11_pam_fail; } } else if (user) { if (!configuration->quiet) { pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2308: No smartcard found")); sleep(configuration->err_display_time); } /* we have a user and no smart card, go to the next pam module */ release_pkcs11_module(ph); return PAM_AUTHINFO_UNAVAIL; } else { /* we haven't prompted for the user yet, get the user and see if * the smart card has been inserted in the mean time */ pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Please insert your %s or enter your username."), _(configuration->token_type)); rv = pam_get_user(pamh, &user, NULL); /* check one last time for the smart card before bouncing to the next * module */ if (configuration->slot_description != NULL) { rv = find_slot_by_slotlabel(ph, configuration->slot_description, &slot_num); } else if (configuration->slot_num != -1) { rv = find_slot_by_number(ph, configuration->slot_num, &slot_num); } if (rv != 0) { /* user gave us a user id and no smart card go to next module */ if (!configuration->quiet) { pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2310: No smartcard found")); sleep(configuration->err_display_time); } release_pkcs11_module(ph); return PAM_AUTHINFO_UNAVAIL; } } } else { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("%s found."), _(configuration->token_type)); } rv = open_pkcs11_session(ph, slot_num); if (rv != 0) { ERR1("open_pkcs11_session() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "open_pkcs11_session() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2312: open PKCS#11 session failed")); sleep(configuration->err_display_time); } release_pkcs11_module(ph); return pkcs11_pam_fail; } rv = get_slot_login_required(ph); if (rv == -1) { ERR1("get_slot_login_required() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "get_slot_login_required() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2314: Slot login failed")); sleep(configuration->err_display_time); } release_pkcs11_module(ph); return pkcs11_pam_fail; } else if (rv) { /* get password */ pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Welcome %.32s!"), get_slot_tokenlabel(ph)); /* no CKF_PROTECTED_AUTHENTICATION_PATH */ rv = get_slot_protected_authentication_path(ph); if ((-1 == rv) || (0 == rv)) { char password_prompt[128]; snprintf(password_prompt, sizeof(password_prompt), _("%s PIN: "), _(configuration->token_type)); if (configuration->use_first_pass) { rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0); } else if (configuration->try_first_pass) { rv = pam_get_pwd(pamh, &password, password_prompt, PAM_AUTHTOK, PAM_AUTHTOK); } else { rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK); } if (rv != PAM_SUCCESS) { if (!configuration->quiet) { pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2316: password could not be read")); sleep(configuration->err_display_time); } release_pkcs11_module(ph); pam_syslog(pamh, LOG_ERR, "pam_get_pwd() failed: %s", pam_strerror(pamh, rv)); return pkcs11_pam_fail; } #ifdef DEBUG_SHOW_PASSWORD DBG1("password = [%s]", password); #endif /* check password length */ if (!configuration->nullok && strlen(password) == 0) { release_pkcs11_module(ph); memset(password, 0, strlen(password)); free(password); pam_syslog(pamh, LOG_ERR, "password length is zero but the 'nullok' argument was not defined."); if (!configuration->quiet) { pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2318: Empty smartcard PIN not allowed.")); sleep(configuration->err_display_time); } return PAM_AUTH_ERR; } } else { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Enter your %s PIN on the pinpad"), _(configuration->token_type)); /* use pin pad */ password = NULL; } /* call pkcs#11 login to ensure that the user is the real owner of the card * we need to do thise before get_certificate_list because some tokens * can not read their certificates until the token is authenticated */ rv = pkcs11_login(ph, password); /* erase and free in-memory password data asap */ if (password) { memset(password, 0, strlen(password)); free(password); } if (rv != 0) { ERR1("open_pkcs11_login() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "open_pkcs11_login() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2320: Wrong smartcard PIN")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } } cert_list = get_certificate_list(ph, &ncert); if (rv<0) { ERR1("get_certificate_list() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "get_certificate_list() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2322: No certificate found")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } /* load mapper modules */ load_mappers(configuration->ctx); /* find a valid and matching certificates */ for (i = 0; i < ncert; i++) { X509 *x509 = (X509 *)get_X509_certificate(cert_list[i]); if (!x509 ) continue; /* sanity check */ DBG1("verifying the certificate #%d", i + 1); if (!configuration->quiet) { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("verifying certificate")); } /* verify certificate (date, signature, CRL, ...) */ rv = verify_certificate(x509,&configuration->policy); if (rv < 0) { ERR1("verify_certificate() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "verify_certificate() failed: %s", get_error()); switch (rv) { case -2: // X509_V_ERR_CERT_HAS_EXPIRED: pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2324: Certificate has expired")); break; case -3: // X509_V_ERR_CERT_NOT_YET_VALID: pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2326: Certificate not yet valid")); break; case -4: // X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2328: Certificate signature invalid")); break; default: pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2330: Certificate invalid")); break; } sleep(configuration->err_display_time); } continue; /* try next certificate */ } else if (rv != 1) { ERR1("verify_certificate() failed: %s", get_error()); continue; /* try next certificate */ } /* CA and CRL verified, now check/find user */ if ( is_spaced_str(user) ) { /* if provided user is null or empty extract and set user name from certificate */ DBG("Empty login: try to deduce from certificate"); user=find_user(x509); if (!user) { ERR2("find_user() failed: %s on cert #%d", get_error(),i+1); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "find_user() failed: %s on cert #%d",get_error(),i+1); continue; /* try on next certificate */ } else { DBG1("certificate is valid and matches user %s",user); /* try to set up PAM user entry with evaluated value */ rv = pam_set_item(pamh, PAM_USER,(const void *)user); if (rv != PAM_SUCCESS) { ERR1("pam_set_item() failed %s", pam_strerror(pamh, rv)); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "pam_set_item() failed %s", pam_strerror(pamh, rv)); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2332: setting PAM userentry failed")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } chosen_cert = cert_list[i]; break; /* end loop, as find user success */ } } else { /* User provided: check whether the certificate matches the user */ rv = match_user(x509, user); if (rv < 0) { /* match error; abort and return */ ERR1("match_user() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "match_user() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2334: No matching user")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } else if (rv == 0) { /* match didn't success */ DBG("certificate is valid but does not match the user"); continue; /* try next certificate */ } else { /* match success */ DBG("certificate is valid and matches the user"); chosen_cert = cert_list[i]; break; } } /* if is_spaced string */ } /* for (i=0; i<ncerts; i++) */ /* now myCert points to our found certificate or null if no user found */ if (!chosen_cert) { ERR("no valid certificate which meets all requirements found"); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "no valid certificate which meets all requirements found"); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2336: No matching certificate found")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } /* if signature check is enforced, generate random data, sign and verify */ if (configuration->policy.signature_policy) { pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Checking signature")); #ifdef notdef rv = get_private_key(ph); if (rv != 0) { ERR1("get_private_key() failed: %s", get_error()); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "get_private_key() failed: %s", get_error()); goto auth_failed_nopw; } #endif /* read random value */ rv = get_random_value(random_value, sizeof(random_value)); if (rv != 0) { ERR1("get_random_value() failed: %s", get_error()); if (!configuration->quiet){ pam_syslog(pamh, LOG_ERR, "get_random_value() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2338: Getting random value failed")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } /* sign random value */ signature = NULL; rv = sign_value(ph, chosen_cert, random_value, sizeof(random_value), &signature, &signature_length); if (rv != 0) { ERR1("sign_value() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "sign_value() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2340: Signing failed")); sleep(configuration->err_display_time); } goto auth_failed_nopw; } /* verify the signature */ DBG("verifying signature..."); rv = verify_signature((X509 *)get_X509_certificate(chosen_cert), random_value, sizeof(random_value), signature, signature_length); if (signature != NULL) { free(signature); } if (rv != 0) { close_pkcs11_session(ph); release_pkcs11_module(ph); ERR1("verify_signature() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "verify_signature() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2342: Verifying signature failed")); sleep(configuration->err_display_time); } return PAM_AUTH_ERR; } } else { DBG("Skipping signature check"); } /* * fill in the environment variables. */ snprintf(env_temp, sizeof(env_temp) - 1, "PKCS11_LOGIN_TOKEN_NAME=%.*s", (int)((sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME=")), get_slot_tokenlabel(ph)); rv = pam_putenv(pamh, env_temp); if (rv != PAM_SUCCESS) { ERR1("could not put token name in environment: %s", pam_strerror(pamh, rv)); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "could not put token name in environment: %s", pam_strerror(pamh, rv)); } issuer = cert_info((X509 *)get_X509_certificate(chosen_cert), CERT_ISSUER, ALGORITHM_NULL); if (issuer) { snprintf(env_temp, sizeof(env_temp) - 1, "PKCS11_LOGIN_CERT_ISSUER=%.*s", (int)((sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_CERT_ISSUER=")), issuer[0]); rv = pam_putenv(pamh, env_temp); } else { ERR("couldn't get certificate issuer."); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "couldn't get certificate issuer."); } if (rv != PAM_SUCCESS) { ERR1("could not put cert issuer in environment: %s", pam_strerror(pamh, rv)); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "could not put cert issuer in environment: %s", pam_strerror(pamh, rv)); } serial = cert_info((X509 *)get_X509_certificate(chosen_cert), CERT_SERIAL, ALGORITHM_NULL); if (serial) { snprintf(env_temp, sizeof(env_temp) - 1, "PKCS11_LOGIN_CERT_SERIAL=%.*s", (int)((sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_CERT_SERIAL=")), serial[0]); rv = pam_putenv(pamh, env_temp); } else { ERR("couldn't get certificate serial number."); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "couldn't get certificate serial number."); } if (rv != PAM_SUCCESS) { ERR1("could not put cert serial in environment: %s", pam_strerror(pamh, rv)); if (!configuration->quiet) pam_syslog(pamh, LOG_ERR, "could not put cert serial in environment: %s", pam_strerror(pamh, rv)); } /* unload mapper modules */ unload_mappers(); /* close pkcs #11 session */ rv = close_pkcs11_session(ph); if (rv != 0) { release_pkcs11_module(ph); ERR1("close_pkcs11_session() failed: %s", get_error()); if (!configuration->quiet) { pam_syslog(pamh, LOG_ERR, "close_pkcs11_module() failed: %s", get_error()); pam_prompt(pamh, PAM_ERROR_MSG , NULL, ("Error 2344: Closing PKCS#11 session failed")); sleep(configuration->err_display_time); } return pkcs11_pam_fail; } /* release pkcs #11 module */ DBG("releasing pkcs #11 module..."); release_pkcs11_module(ph); DBG("authentication succeeded"); return PAM_SUCCESS; /* quick and dirty fail exit point */ memset(password, 0, strlen(password)); free(password); /* erase and free in-memory password data */ auth_failed_nopw: unload_mappers(); close_pkcs11_session(ph); release_pkcs11_module(ph); return pkcs11_pam_fail; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; u_int i; #ifdef USE_SHADOW struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef USE_SHADOW if (!options.use_pam) spw = getspnam(pw->pw_name); #ifdef HAS_SHADOW_EXPIRE if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) return 0; #endif /* HAS_SHADOW_EXPIRE */ #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ passwd = pw->pw_passwd; #ifdef USE_SHADOW if (spw != NULL) #ifdef USE_LIBIAF passwd = get_iaf_password(pw); #else passwd = spw->sp_pwdp; #endif /* USE_LIBIAF */ #endif /* check for locked account */ if (!options.use_pam && passwd && *passwd) { int locked = 0; #ifdef LOCKED_PASSWD_STRING if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, strlen(LOCKED_PASSWD_PREFIX)) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_SUBSTR if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif #ifdef USE_LIBIAF free((void *) passwd); #endif /* USE_LIBIAF */ if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); return 0; } } /* * Deny if shell does not exist or is not executable unless we * are chrooting. */ if (options.chroot_directory == NULL || strcasecmp(options.chroot_directory, "none") == 0) { char *shell = xstrdup((pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s " "does not exist", pw->pw_name, shell); xfree(shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s " "is not executable", pw->pw_name, shell); xfree(shell); return 0; } xfree(shell); } if (options.num_deny_users > 0 || options.num_allow_users > 0 || options.num_deny_groups > 0 || options.num_allow_groups > 0) { hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { logit("User %.100s from %.100s not allowed " "because listed in DenyUsers", pw->pw_name, hostname); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s from %.100s not allowed because " "not listed in AllowUsers", pw->pw_name, hostname); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s from %.100s not allowed because " "not in any group", pw->pw_name, hostname); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because a group is listed in DenyGroups", pw->pw_name, hostname); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s from %.100s not allowed " "because none of user's groups are listed " "in AllowGroups", pw->pw_name, hostname); return 0; } ga_free(); } #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER if (!sys_auth_allowed_user(pw, &loginmsg)) return 0; #endif /* We found no reason not to let this user try to log on... */ return 1; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; char *shell; int i; #ifdef USE_SHADOW struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef USE_SHADOW if (!options.use_pam) spw = getspnam(pw->pw_name); #ifdef HAS_SHADOW_EXPIRE if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) return 0; #endif /* HAS_SHADOW_EXPIRE */ #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ #ifdef USE_SHADOW if (spw != NULL) passwd = spw->sp_pwdp; #else passwd = pw->pw_passwd; #endif /* check for locked account */ if (!options.use_pam && passwd && *passwd) { int locked = 0; #ifdef LOCKED_PASSWD_STRING if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, strlen(LOCKED_PASSWD_PREFIX)) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_SUBSTR if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); return 0; } } /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s is not executable", pw->pw_name, shell); return 0; } if (options.num_deny_users > 0 || options.num_allow_users > 0) { hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { logit("User %.100s not allowed because listed in DenyUsers", pw->pw_name); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s not allowed because not listed in AllowUsers", pw->pw_name); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s not allowed because not in any group", pw->pw_name); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s not allowed because a group is listed in DenyGroups", pw->pw_name); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s not allowed because none of user's groups are listed in AllowGroups", pw->pw_name); return 0; } ga_free(); } #ifdef WITH_AIXAUTHENTICATE /* * Don't check loginrestrictions() for root account (use * PermitRootLogin to control logins via ssh), or if running as * non-root user (since loginrestrictions will always fail). */ if ((pw->pw_uid != 0) && (geteuid() == 0)) { char *msg; if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) { int loginrestrict_errno = errno; if (msg && *msg) { buffer_append(&loginmsg, msg, strlen(msg)); aix_remove_embedded_newlines(msg); logit("Login restricted for %s: %.100s", pw->pw_name, msg); } /* Don't fail if /etc/nologin set */ if (!(loginrestrict_errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0)) return 0; } } #endif /* WITH_AIXAUTHENTICATE */ /* We found no reason not to let this user try to log on... */ return 1; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL; char *shell; int i; #ifdef WITH_AIXAUTHENTICATE char *loginmsg; #endif /* WITH_AIXAUTHENTICATE */ #if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) struct spwd *spw; /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #define DAY (24L * 60 * 60) /* 1 day in seconds */ spw = getspnam(pw->pw_name); if (spw != NULL) { time_t today = time(NULL) / DAY; debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" " sp_max %d", (int)today, (int)spw->sp_expire, (int)spw->sp_lstchg, (int)spw->sp_max); /* * We assume account and password expiration occurs the * day after the day specified. */ if (spw->sp_expire != -1 && today > spw->sp_expire) { log("Account %.100s has expired", pw->pw_name); return 0; } if (spw->sp_lstchg == 0) { log("User %.100s password has expired (root forced)", pw->pw_name); return 0; } if (spw->sp_max != -1 && today > spw->sp_lstchg + spw->sp_max) { log("User %.100s password has expired (password aged)", pw->pw_name); return 0; } } #else /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #endif /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { log("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { log("User %.100s not allowed because shell %.100s is not executable", pw->pw_name, shell); return 0; } if (options.num_deny_users > 0 || options.num_allow_users > 0) { hostname = get_canonical_hostname(options.verify_reverse_mapping); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { log("User %.100s not allowed because listed in DenyUsers", pw->pw_name); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { log("User %.100s not allowed because not listed in AllowUsers", pw->pw_name); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { log("User %.100s not allowed because not in any group", pw->pw_name); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); log("User %.100s not allowed because a group is listed in DenyGroups", pw->pw_name); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); log("User %.100s not allowed because none of user's groups are listed in AllowGroups", pw->pw_name); return 0; } ga_free(); } #ifdef WITH_AIXAUTHENTICATE if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { if (loginmsg && *loginmsg) { /* Remove embedded newlines (if any) */ char *p; for (p = loginmsg; *p; p++) { if (*p == '\n') *p = ' '; } /* Remove trailing newline */ *--p = '\0'; log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); } return 0; } #endif /* WITH_AIXAUTHENTICATE */ /* We found no reason not to let this user try to log on... */ return 1; }
int main() { //register_user("ezhuang", "john1990", "test"); //register_user("hahaha","dadada","test"); //register_user("ddd","poo","test"); //match_user("ezhuang", "john1990", "test"); //match_user("hahaha","dadada","test"); //match_user("ezhuang", "john1990", "test"); //delete_user("hahaha","dadada","test"); printf("Available commands:\n(1) register_user\n(2) delete_user\n(3) is_user_valid\n(4) match_user\n(5) change_user_password\n(6) quit\n\n\n"); unsigned char command[1024]; int operation_status ; while(1) { printf("enter a command: "); scanf("%s",command) ; // printf("\n") ; operation_status = OKAY ; if(!strcmp(command,"register_user")) { printf("username: "******"%s",username) ; printf("password: "******"%s",password) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = register_user(username,password,pFile) ; } else if(!strcmp(command,"delete_user")) { printf("username: "******"%s",username) ; printf("password: "******"%s",password) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = delete_user(username,password, pFile) ; } else if(!strcmp(command,"is_user_valid")) { printf("username: "******"%s",username) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = is_user_valid(username,pFile) ; } else if(!strcmp(command,"match_user")) { printf("username: "******"%s",username) ; printf("password: "******"%s",password) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = match_user(username,password,pFile) ; } else if(!strcmp(command,"change_user_password")) { printf("username: "******"%s",username) ; printf("current password: "******"%s",password) ; printf("new password: "******"%s",npassword) ; printf("password file name: "); unsigned char pFile[1024] ; scanf("%s",pFile); operation_status = change_user_password(username,password,npassword, pFile) ; } else if(!strcmp(command,"quit")) { printf("INFO: Got the quit command\n"); printf("Program terminating\n"); break; } else { printf("ERROR: Unknown command %s\n",command); printf("INFO: Ignoring command\n") ; } if(operation_status == ERROR) printf("Operation %s failed\n",command) ; } return 0; }
static int report_job(papi_job_t job, int show_rank, int verbose) { papi_attribute_t **attrs = papiJobGetAttributeList(job); time_t clock = 0; char date[24]; char request[26]; char *user = "******"; int32_t size = 0; int32_t jstate = 0; char *destination = "unknown"; int32_t id = -1; (void) papiAttributeListGetString(attrs, NULL, "job-originating-user-name", &user); if ((users != NULL) && (match_user(user, users) < 0)) return (0); (void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size); size *= 1024; /* for the approximate byte size */ (void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size); (void) time(&clock); (void) papiAttributeListGetInteger(attrs, NULL, "time-at-creation", (int32_t *)&clock); (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock)); (void) papiAttributeListGetString(attrs, NULL, "job-printer-uri", &destination); (void) papiAttributeListGetString(attrs, NULL, "printer-name", &destination); (void) papiAttributeListGetInteger(attrs, NULL, "job-id", &id); snprintf(request, sizeof (request), "%s-%d", destination, id); if (show_rank != 0) { int32_t rank = -1; (void) papiAttributeListGetInteger(attrs, NULL, "number-of-intervening-jobs", &rank); rank++; printf("%3d %-21s %-14s %7ld %s", rank, request, user, size, date); } else printf("%-23s %-14s %7ld %s", request, user, size, date); (void) papiAttributeListGetInteger(attrs, NULL, "job-state", &jstate); if (jstate == 0x04) printf(gettext(", being held")); else if (jstate == 0x07) printf(gettext(", cancelled")); else if (jstate == 0x09) printf(gettext(", complete")); if (verbose == 1) { (void) papiAttributeListGetString(attrs, NULL, "output-device-assigned", &destination); printf("\n\t assigned %s", destination); } else if (verbose > 1) { printf("\n"); papiAttributeListPrint(stdout, attrs, "\t"); } printf("\n"); return (0); }