static void request_pin(const char *prompt_msg, char *pin) { int i, rc; if (opt_pin) { rc = securid_pin_format_ok(opt_pin); if (rc == ERR_BAD_LEN) warn("warning: bad --pin argument length, ignoring\n"); else if (rc == ERR_GENERAL) warn("warning: --pin argument is not numeric, ignoring\n"); else { strncpy(pin, opt_pin, BUFLEN); return; } } for (i = 0; ; i++) { prompt(prompt_msg); read_user_input(pin, BUFLEN, 1); rc = securid_pin_format_ok(pin); if (rc == ERR_NONE) break; if (i == 2) die("error: invalid PIN\n"); if (rc == ERR_BAD_LEN) warn("PIN must be %d-%d digits. Use '0000' for no PIN.\n", MIN_PIN, MAX_PIN); else warn("PIN can only contain digits.\n"); } }
static int decode_rc_token(struct stoken_cfg *cfg, struct securid_token *t) { int rc = securid_decode_token(cfg->rc_token, t); if (rc != ERR_NONE) { warn("rcfile: token data is garbled, ignoring\n"); return rc; } if (cfg->rc_pin) { if (t->flags & FL_PASSPROT) t->enc_pin_str = xstrdup(cfg->rc_pin); else { if (securid_pin_format_ok(cfg->rc_pin) == ERR_NONE) strncpy(t->pin, cfg->rc_pin, MAX_PIN + 1); else warn("rcfile: invalid PIN format\n"); } } return ERR_NONE; }
static int request_credentials(struct securid_token *t) { int rc, pass_required = 0, pin_required = 0; if (securid_pass_required(t)) { pass_required = 1; if (opt_password) { rc = securid_decrypt_seed(t, opt_password, NULL); if (rc == ERR_DECRYPT_FAILED) warn("warning: --password parameter is incorrect\n"); else if (rc != ERR_NONE) error_dialog("Token decrypt error", stoken_errstr[rc]); else pass_required = 0; } } else { rc = securid_decrypt_seed(t, opt_password, NULL); if (rc != ERR_NONE) error_dialog("Token decrypt error", stoken_errstr[rc]); } while (pass_required) { const char *pass = do_password_dialog(UIDIR "/password-dialog.ui"); if (!pass) return ERR_MISSING_PASSWORD; rc = securid_decrypt_seed(t, pass, NULL); if (rc == ERR_NONE) { if (t->enc_pin_str) { rc = securid_decrypt_pin(t->enc_pin_str, pass, t->pin); if (rc != ERR_NONE) error_dialog("PIN decrypt error", stoken_errstr[rc]); } pass_required = 0; } else if (rc == ERR_DECRYPT_FAILED) warning_dialog(NULL, "Bad password", "Please enter the correct password for this seed."); else error_dialog("Token decrypt error", stoken_errstr[rc]); } if (securid_pin_required(t)) { pin_required = 1; if (opt_pin) { if (securid_pin_format_ok(opt_pin) == ERR_NONE) { xstrncpy(t->pin, opt_pin, MAX_PIN + 1); pin_required = 0; } else warn("warning: --pin argument is invalid\n"); } else if (strlen(t->pin) || t->enc_pin_str) pin_required = 0; } while (pin_required) { const char *pin = do_password_dialog(UIDIR "/pin-dialog.ui"); if (!pin) { skipped_pin = 1; xstrncpy(t->pin, "0000", MAX_PIN + 1); break; } if (securid_pin_format_ok(pin) != ERR_NONE) { warning_dialog(NULL, "Bad PIN", "Please enter 4-8 digits, or click Skip for no PIN."); } else { xstrncpy(t->pin, pin, MAX_PIN + 1); break; } } return ERR_NONE; }
int main(int argc, char **argv) { char *cmd = parse_cmdline(argc, argv, NOT_GUI); int rc; char buf[BUFLEN]; struct securid_token *t; rc = common_init(cmd); if (rc != ERR_NONE) die("can't initialize: %s\n", stoken_errstr[rc]); t = current_token; if (!t) die("error: no token present. Use 'stoken import' to add one.\n"); terminal_init(); if (!strcmp(cmd, "tokencode")) { int days_left = securid_check_exp(t, adjusted_time()); if (days_left < 0 && !opt_force) die("error: token has expired; use --force to override\n"); unlock_token(t, 1, NULL); securid_compute_tokencode(t, adjusted_time(), buf); puts(buf); if (days_left < 14 && !opt_force) warn("warning: token expires in %d day%s\n", days_left, days_left == 1 ? "" : "s"); } else if (!strcmp(cmd, "import")) { char *pass; unlock_token(t, 0, &pass); if (!opt_keep_password) { pass = xmalloc(BUFLEN); request_new_pass(pass); } t->is_smartphone = 0; securid_encode_token(t, pass, opt_new_devid, buf); rc = write_token_and_pin(buf, NULL, pass); if (rc != ERR_NONE) die("rcfile: error writing new token: %s\n", stoken_errstr[rc]); } else if (!strcmp(cmd, "export")) { char *pass; unlock_token(t, 0, &pass); if (opt_new_password) pass = opt_new_password; else if (!opt_keep_password) pass = NULL; t->is_smartphone = opt_iphone || opt_android; securid_encode_token(t, pass, opt_new_devid, buf); print_formatted(buf); } else if (!strcmp(cmd, "show")) { unlock_token(t, 0, NULL); securid_token_info(t, &print_token_info_line); } else if (!strcmp(cmd, "setpin")) { char *pass = NULL, pin[BUFLEN], confirm_pin[BUFLEN]; int len; if (opt_file || opt_token) die("error: setpin only operates on the rcfile token\n"); unlock_token(t, 0, &pass); if (opt_new_pin) { if (securid_pin_format_ok(opt_new_pin) != ERR_NONE) die("error: invalid --new-pin format\n"); strncpy(pin, opt_new_pin, BUFLEN); len = strlen(pin); } else { prompt("Enter new PIN: "); len = read_user_input(pin, BUFLEN, 1); if (len > 0 && securid_pin_format_ok(pin) != ERR_NONE) die("error: PIN must be 4-8 digits\n"); prompt("Confirm new PIN: "); read_user_input(confirm_pin, BUFLEN, 1); if (strcmp(pin, confirm_pin) != 0) die("error: PINs do not match\n"); } securid_encode_token(t, pass, NULL, buf); rc = write_token_and_pin(buf, len ? pin : NULL, pass); free(pass); if (rc != ERR_NONE) die("error: can't set PIN: %s\n", stoken_errstr[rc]); } else if (!strcmp(cmd, "setpass")) { char pass[BUFLEN]; unlock_token(t, 0, NULL); request_new_pass(pass); securid_encode_token(t, pass, NULL, buf); /* just print to stdout if it didn't come from the rcfile */ if (opt_file || opt_token) print_formatted(buf); else { rc = write_token_and_pin(buf, strlen(t->pin) ? t->pin : NULL, strlen(pass) ? pass : NULL); if (rc != ERR_NONE) die("error: can't set password: %s\n", stoken_errstr[rc]); } } else die("error: invalid command '%s'\n", cmd); return 0; }
static int do_password_dialog(struct securid_token *t) { GtkWidget *dialog; GtkWidget *pass_entry = NULL, *pin_entry = NULL; gint resp; int rc, pass_required = 0, pin_required = 0; if (securid_pass_required(t)) { pass_required = 1; if (opt_password) { rc = securid_decrypt_seed(t, opt_password, NULL); if (rc == ERR_DECRYPT_FAILED) warn("warning: --password parameter is incorrect\n"); else if (rc != ERR_NONE) error_dialog("Token decrypt error", stoken_errstr[rc]); else pass_required = 0; } } else { rc = securid_decrypt_seed(t, opt_password, NULL); if (rc != ERR_NONE) error_dialog("Token decrypt error", stoken_errstr[rc]); } if (securid_pin_required(t)) { pin_required = 1; if (opt_pin) { if (securid_pin_format_ok(opt_pin) == ERR_NONE) { xstrncpy(t->pin, opt_pin, MAX_PIN + 1); pin_required = 0; } else warn("warning: --pin argument is invalid\n"); } else if (strlen(t->pin) || t->enc_pin_str) pin_required = 0; } if (!pin_required && !pass_required) return ERR_NONE; if (pass_required) pass_entry = gtk_entry_new(); if (pin_required) pin_entry = gtk_entry_new(); create_password_dialog(&dialog, pass_entry, pin_entry); while (1) { const char *pass = NULL, *pin = NULL; resp = gtk_dialog_run(GTK_DIALOG(dialog)); if (resp != GTK_RESPONSE_ACCEPT) { gtk_widget_destroy(dialog); return 1; } if (pass_required) { pass = gtk_entry_get_text(GTK_ENTRY(pass_entry)); rc = securid_decrypt_seed(current_token, pass, NULL); if (rc == ERR_DECRYPT_FAILED) { warning_dialog(dialog, "Bad password", "Please enter the correct password for this seed."); continue; } else if (rc != ERR_NONE) error_dialog("Token decrypt error", stoken_errstr[rc]); } if (t->enc_pin_str) { rc = securid_decrypt_pin(t->enc_pin_str, pass, t->pin); if (rc != ERR_NONE) error_dialog("PIN decrypt error", stoken_errstr[rc]); } if (pin_required) { pin = gtk_entry_get_text(GTK_ENTRY(pin_entry)); if (securid_pin_format_ok(pin) != ERR_NONE) { warning_dialog(dialog, "Bad PIN", "Please enter 4-8 digits, or '0000' to skip."); continue; } xstrncpy(t->pin, pin, MAX_PIN + 1); } break; } gtk_widget_destroy(dialog); return ERR_NONE; }