示例#1
0
int main() {
	uint8_t index;
	uint8_t menulen;
	uint8_t button_pressed = UINT8_MAX - 1;
	uint16_t i;
	uint8_t pass_len;

	//Since we are waiting indefinitely for input from keyboard,
	//the watchdog is not applicable anymore
	//wdt_enable(WDTO_1S); // enable 1s watchdog timer

	init();

	for (i = 0; i < sizeof(keyboard_report); i++) // clear report initially
		((uchar *) &keyboard_report)[i] = 0;

	usbDeviceDisconnect(); // enforce re-enumeration
	for (i = 0; i < 250; i++) { // wait 500 ms
		//wdt_reset();
		_delay_ms(2);
	}
	usbDeviceConnect();

	// Enable interrupts after re-enumeration
	sei();

	//Enable this to reinitialize passwords/EEPROM
	//eeprom_write_byte(0,0);

	pass_no = read_passwords(&passwords);

	index = 0;
	mode = MODE_MENU;
	menulen = MENU_LENGTH;

	while (1) {
		//wdt_reset();
		// keep the watchdog happy
		usbPoll();

		//Only display stuff if a button was pressed
		//(most likely something changed on the screen)
		if (button_pressed != UINT8_MAX) {
			lcd_clrscr();
			if (mode == MODE_MENU) {
				strcpy_P(stringBuffer,
						(PGM_P) pgm_read_word(&(menu_items[index])));
				lcd_puts(stringBuffer);
			} else {
				lcd_puts(passwords[index]);
			}
		}

		button_pressed = poll_buttons();

		switch (button_pressed) {
		case MENU:
			//Get back to the main menu
			mode = MODE_MENU;
			index = 0;
			menulen = MENU_LENGTH;

			toggle_led(PB0);
			break;

		case CYCLE:
			//Prepare next item for display
			if (index < menulen - 1) {
				lcd_clrscr();
				index++;
			} else {
				index = 0;
			}
			toggle_led(PB0);
			break;

		case SELECT:
			if (mode == MODE_MENU) {
				//We can add password directly from the MENU mode (main menu)
				if (index == MODE_ADD) {

					uint8_t pass_len;

					pass_len = input_password();

					if (pass_len > 0) {
						stringBuffer[pass_len] = '\0';

						passwords = realloc(passwords,
								(pass_no + 1) * sizeof(char*));
						passwords[pass_no] = malloc(pass_len * sizeof(char));
						strcpy(passwords[pass_no], stringBuffer);
						pass_no++;
						menulen = pass_no;
						write_passwords(pass_no, passwords);
					}
					//Get back to the MENU mode (main menu)
					mode = MODE_MENU;
					menulen = MENU_LENGTH;
					toggle_led(PB0);
				} else {
					//Enter the corresponding mode
					mode = index;
					index = 0;
					menulen = pass_no;
				}
			} else {
				//in SEND, REMOVE or CHANGE mode
				if (index < menulen) {
					switch (mode) {
					case MODE_SEND:
						//Send password to the PC
						strcpy(stringBuffer, passwords[index]);
						messagePtr = 0;
						messageState = STATE_SEND;
						//Stay in the SEND mode displaying the same password
						break;

					case MODE_REMOVE:
						//Remove password
						free(passwords[index]);
						for (i = index; i < pass_no - 1; i++) {
							passwords[i] = passwords[i + 1];
						}
						pass_no--;
						passwords = realloc(passwords, pass_no * sizeof(char*));
						write_passwords(pass_no, passwords);
						//Stay in the REMOVE mode, but display the first password
						index = 0;
						menulen = pass_no;
						break;

					case MODE_CHANGE:
						pass_len = input_password();

						if (pass_len > 0) {
							stringBuffer[pass_len] = '\0';

							passwords[index] = realloc(passwords[index],
									pass_len);
							strcpy(passwords[index], stringBuffer);
							write_passwords(pass_no, passwords);
						}
						//Stay in the CHANGE mode, but display the first password
						index = 0;
						toggle_led(PB0);
						break;
					}
				}

			}
			break;
		}
		// characters are sent when messageState == STATE_SEND
		if (usbInterruptIsReady() && messageState == STATE_SEND) {
			messageState = buildReport();
			usbSetInterrupt((void *) &keyboard_report, sizeof(keyboard_report));
		}
	}

	return 0;
}
示例#2
0
static int
set_password(const char *forwho, const char *shadow, const char *remember)
{
    struct passwd *pwd = NULL;
    int retval;
    char pass[MAXPASS + 1];
    char towhat[MAXPASS + 1];
    int npass = 0;
    /* we don't care about number format errors because the helper
       should be called internally only */
    int doshadow = atoi(shadow);
    int nremember = atoi(remember);
    char *passwords[] = { pass, towhat };

    /* read the password from stdin (a pipe from the pam_unix module) */

    npass = read_passwords(STDIN_FILENO, 2, passwords);

    if (npass != 2) {	/* is it a valid password? */
      if (npass == 1) {
        helper_log_err(LOG_DEBUG, "no new password supplied");
	memset(pass, '\0', MAXPASS);
      } else {
        helper_log_err(LOG_DEBUG, "no valid passwords supplied");
      }
      return PAM_AUTHTOK_ERR;
    }

    if (lock_pwdf() != PAM_SUCCESS)
	return PAM_AUTHTOK_LOCK_BUSY;

    pwd = getpwnam(forwho);

    if (pwd == NULL) {
        retval = PAM_USER_UNKNOWN;
        goto done;
    }

    /* If real caller uid is not root we must verify that
       received old pass agrees with the current one.
       We always allow change from null pass. */
    if (getuid()) {
	retval = helper_verify_password(forwho, pass, 1);
	if (retval != PAM_SUCCESS) {
	    goto done;
	}
    }

    /* first, save old password */
    if (save_old_password(forwho, pass, nremember)) {
	retval = PAM_AUTHTOK_ERR;
	goto done;
    }

    if (doshadow || is_pwd_shadowed(pwd)) {
	retval = unix_update_shadow(forwho, towhat);
	if (retval == PAM_SUCCESS)
	    if (!is_pwd_shadowed(pwd))
		retval = unix_update_passwd(forwho, "x");
    } else {
	retval = unix_update_passwd(forwho, towhat);
    }

done:
    memset(pass, '\0', MAXPASS);
    memset(towhat, '\0', MAXPASS);

    unlock_pwdf();

    if (retval == PAM_SUCCESS) {
	return PAM_SUCCESS;
    } else {
	return PAM_AUTHTOK_ERR;
    }
}
示例#3
0
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;
    }
}