// Main int main(int argc, char *argv[]) { char pass[MAXPASS + 1]; int npass; int retval = YK_FAILURE; int debug = 0; int ch; char *user = NULL; /* * Catch or ignore as many signal as possible. */ setup_signals(); /* loop through each command line var and process it */ while((ch = getopt(argc, argv, "d")) != -1) { switch(ch) { case 'd': /* Set debug mode on */ debug = 1; break; } } /* there should be at least one left over argument */ if (optind < argc) { /* grab the first additional argument as the user name */ user = strdup(argv[optind]); } /* * we establish that this program is running with non-tty stdin. * this is to discourage casual use. It does *NOT* prevent an * intruder from repeatadly running this program to determine the * OTP/passcode of the current user (brute force attack, but one for * which the attacker must already have gained access to the user's * account). */ if (isatty(STDIN_FILENO) || user == NULL ) { syslog(LOG_AUTH ,"inappropriate use of Unix helper binary [UID=%d]" ,getuid()); fprintf(stderr ,"This binary is not designed for running in this way\n" "-- the system administrator has been informed\n"); sleep(10); // this should discourage/annoy the user return YK_FAILURE; } /* * Determine what the current user's name is. * On a SELinux enabled system with a strict policy leaving the * existing check prevents shadow password authentication from working. * We must thus skip the check if the real uid is 0. */ if (getuid() != 0) { /* if the caller specifies the username, verify that user matches it */ if (strcmp(user, getuidname(getuid()))) { syslog(LOG_AUTH ,"mismatch of %s|%s", user, getuidname(getuid())); free(user); return YK_FAILURE; } } /* read the OTP/passcode from stdin (a pipe from the pam_yubikey module) */ npass = read(STDIN_FILENO, pass, MAXPASS); if (npass < 0) { /* is it a valid OTP/passcode? */ syslog(LOG_DEBUG, "no OTP/passcode supplied"); } else if (npass >= MAXPASS) { syslog(LOG_DEBUG, "OTP/passcode too long"); } else { pass[npass] = '\0'; /* NUL terminate */ retval = _yubi_verify_otp_passcode(user, pass, debug, 1); } memset(pass, '\0', MAXPASS); /* clear memory of the OTP/passcode */ /* return pass or fail */ if ((retval != YK_SUCCESS) && (retval != YK_PASSCODE)) { if (debug) syslog(LOG_AUTH, "OTP/passcode check failed for user (%s)", user); free(user); return YK_FAILURE; } free(user); return retval; }
int main(int argc, char *argv[]) { const char *program_name; char *service, *user; int fd; uid_t uid; uid = getuid(); /* * Make sure standard file descriptors are connected. */ while ((fd = open("/dev/null", O_RDWR)) <= 2) ; close(fd); /* * Get the program name */ if (argc == 0) program_name = "hawk_chkpwd"; else if ((program_name = strrchr(argv[0], '/')) != NULL) program_name++; else program_name = argv[0]; /* * Catch or ignore as many signal as possible. */ setup_signals(); /* * Check argument list */ if (argc != 3) { _log_err(LOG_NOTICE, "Bad number of arguments (%d)", argc); return UNIX_FAILED; } /* * Get the service name and do some sanity checks on it */ service = argv[1]; if (!sane_pam_service(service)) { _log_err(LOG_ERR, "Illegal service name '%s'", service); return UNIX_FAILED; } /* * Discourage users messing around (fat chance) */ if (isatty(STDIN_FILENO) && uid != 0) { _log_err(LOG_NOTICE, "Inappropriate use of Unix helper binary [UID=%d]", uid); fprintf(stderr, "This binary is not designed for running in this way\n" "-- the system administrator has been informed\n"); sleep(10); /* this should discourage/annoy the user */ return UNIX_FAILED; } /* * determine the caller's user name */ user = getuidname(uid); if (strcmp(user, argv[2])) { /* Discourage use of this program as a * password cracker */ if (uid != 0 && strcmp(user, HACLUSTER)) sleep(5); user = argv[2]; } if (!in_haclient_grp(user)) { _log_err(LOG_NOTICE, "Failed to authenticate user '%s' (not in group '%s')", user, HACLIENT); return UNIX_FAILED; } return _authenticate(service, user); }
int main(int argc, char *argv[]) { char pass[MAXPASS + 1]; char option[8]; int npass, opt; int force_failure = 0; int retval = UNIX_FAILED; char *user; /* * Catch or ignore as many signal as possible. */ setup_signals(); /* * we establish that this program is running with non-tty stdin. * this is to discourage casual use. It does *NOT* prevent an * intruder from repeatadly running this program to determine the * password of the current user (brute force attack, but one for * which the attacker must already have gained access to the user's * account). */ if (isatty(STDIN_FILENO)) { _log_err(LOG_NOTICE ,"inappropriate use of Unix helper binary [UID=%d]" ,getuid()); fprintf(stderr ,"This binary is not designed for running in this way\n" "-- the system administrator has been informed\n"); sleep(10); /* this should discourage/annoy the user */ return UNIX_FAILED; } /* * determine the current user's name is */ user = getuidname(getuid()); if (argc == 2) { /* if the caller specifies the username, verify that user matches it */ if (strcmp(user, argv[1])) { force_failure = 1; } } /* read the nollok/nonull option */ npass = read(STDIN_FILENO, option, 8); if (npass < 0) { _log_err(LOG_DEBUG, "no option supplied"); return UNIX_FAILED; } else { option[7] = '\0'; if (strncmp(option, "nullok", 8) == 0) opt = 1; else opt = 0; } /* read the password from stdin (a pipe from the pam_unix module) */ npass = read(STDIN_FILENO, pass, MAXPASS); if (npass < 0) { /* is it a valid password? */ _log_err(LOG_DEBUG, "no password supplied"); } else if (npass >= MAXPASS) { _log_err(LOG_DEBUG, "password too long"); } else { if (npass == 0) { /* the password is NULL */ retval = _unix_verify_password(user, NULL, opt); } else { /* does pass agree with the official one? */ pass[npass] = '\0'; /* NUL terminate */ retval = _unix_verify_password(user, pass, opt); } } memset(pass, '\0', MAXPASS); /* clear memory of the password */ /* return pass or fail */ if ((retval != UNIX_PASSED) || force_failure) { return UNIX_FAILED; } else { return UNIX_PASSED; } }
int main(int argc, char *argv[]) { char pass[MAXPASS + 1]; char *option; int npass, nullok; int blankpass = 0; int retval = PAM_AUTH_ERR; char *user; char *passwords[] = { pass }; /* * Catch or ignore as many signal as possible. */ setup_signals(); /* * we establish that this program is running with non-tty stdin. * this is to discourage casual use. It does *NOT* prevent an * intruder from repeatadly running this program to determine the * password of the current user (brute force attack, but one for * which the attacker must already have gained access to the user's * account). */ if (isatty(STDIN_FILENO) || argc != 3 ) { helper_log_err(LOG_NOTICE ,"inappropriate use of Unix helper binary [UID=%d]" ,getuid()); #ifdef HAVE_LIBAUDIT _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR); #endif fprintf(stderr ,"This binary is not designed for running in this way\n" "-- the system administrator has been informed\n"); sleep(10); /* this should discourage/annoy the user */ return PAM_SYSTEM_ERR; } /* * Determine what the current user's name is. * We must thus skip the check if the real uid is 0. */ if (getuid() == 0) { user=argv[1]; } else { user = getuidname(getuid()); /* if the caller specifies the username, verify that user matches it */ if (strcmp(user, argv[1])) { user = argv[1]; /* no match -> permanently change to the real user and proceed */ if (setuid(getuid()) != 0) return PAM_AUTH_ERR; } } option=argv[2]; if (strcmp(option, "chkexpiry") == 0) /* Check account information from the shadow file */ return _check_expiry(argv[1]); /* read the nullok/nonull option */ else if (strcmp(option, "nullok") == 0) nullok = 1; else if (strcmp(option, "nonull") == 0) nullok = 0; else { #ifdef HAVE_LIBAUDIT _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR); #endif return PAM_SYSTEM_ERR; } /* read the password from stdin (a pipe from the pam_unix module) */ npass = read_passwords(STDIN_FILENO, 1, passwords); if (npass != 1) { /* is it a valid password? */ helper_log_err(LOG_DEBUG, "no password supplied"); *pass = '******'; } if (*pass == '\0') { blankpass = 1; } retval = helper_verify_password(user, pass, nullok); memset(pass, '\0', MAXPASS); /* clear memory of the password */ /* return pass or fail */ if (retval != PAM_SUCCESS) { if (!nullok || !blankpass) { /* no need to log blank pass test */ #ifdef HAVE_LIBAUDIT if (getuid() != 0) _audit_log(AUDIT_USER_AUTH, user, PAM_AUTH_ERR); #endif helper_log_err(LOG_NOTICE, "password check failed for user (%s)", user); } return PAM_AUTH_ERR; } else { if (getuid() != 0) { #ifdef HAVE_LIBAUDIT return _audit_log(AUDIT_USER_AUTH, user, PAM_SUCCESS); #else return PAM_SUCCESS; #endif } return PAM_SUCCESS; } }