/* The okay button has been clicked or the enter enter key in the text field. */ static void ok_button_clicked (HWND dlg, pinentry_t pe) { char *s_utf8; wchar_t *w_buffer; size_t w_buffer_size = 255; unsigned int nchar; pe->locale_err = 1; w_buffer = secmem_malloc ((w_buffer_size + 1) * sizeof *w_buffer); if (!w_buffer) return; nchar = GetDlgItemTextW (dlg, IDC_PINENT_TEXT, w_buffer, w_buffer_size); s_utf8 = wchar_to_utf8 (w_buffer, nchar, 1); secmem_free (w_buffer); if (s_utf8) { passphrase_ok = 1; pinentry_setbufferlen (pe, strlen (s_utf8) + 1); if (pe->pin) strcpy (pe->pin, s_utf8); secmem_free (s_utf8); pe->locale_err = 0; pe->result = pe->pin? strlen (pe->pin) : 0; } }
static void button_clicked (GtkWidget *widget, gpointer data) { if (data) { const char *s; /* Okay button or enter used in text field. */ #ifdef ENABLE_ENHANCED /* FIXME: This is not compatible with assuan. We can't just print stuff on stdout. */ if (pinentry->enhanced) printf ("Options: %s\nTimeout: %d\n\n", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (insure)) ? "insure" : "", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (time_out))); #endif s = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (entry)); if (!s) s = ""; passphrase_ok = 1; pinentry_setbufferlen (pinentry, strlen (s) + 1); if (pinentry->pin) strcpy (pinentry->pin, s); } gtk_main_quit (); }
static void button_clicked (GtkWidget *widget, gpointer data) { if (data) { /* Okay button hit or Enter used in the text field. */ const char *s; char *s_utf8; char *s_buffer; if (pinentry->enhanced) { printf("Options: %s\nTimeout: %d\n\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(insure)) ? "insure" : "", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(time_out))); } pinentry->locale_err = 1; s = gtk_secure_entry_get_text (GTK_SECURE_ENTRY(entry)); if (!s) s = ""; s_buffer = secmem_malloc (strlen (s) + 1); if (s_buffer) { strcpy (s_buffer, s); s_utf8 = pinentry_local_to_utf8 (pinentry->lc_ctype, s_buffer, 1); secmem_free (s_buffer); if (s_utf8) { passphrase_ok = 1; pinentry_setbufferlen (pinentry, strlen (s_utf8) + 1); if (pinentry->pin) strcpy (pinentry->pin, s_utf8); secmem_free (s_utf8); pinentry->locale_err = 0; } } } gtk_main_quit (); }
/* * returns the pin length, or -1 on error */ int pe_get_pin( const struct pe_context* ctx ) { jfieldID fid; fid = ( *ctx->env )->GetFieldID ( ctx->env, ctx->pe_struct_class , "pin", "Ljava/lang/String;" ); if ( !fid ) { LOGE ( "pe_get_pin: failed to get pin jfieldID\n" ); return -1; } jstring jpin = ( *ctx->env )->GetObjectField ( ctx->env, ctx->pe_struct, fid ); if ( !jpin ) { LOGE ( "pe_get_pin: jpin is null!!\n" ); return -1; } jsize pin_len = ( *ctx->env )->GetStringUTFLength ( ctx->env, jpin ); const jbyte* pin = ( *ctx->env )->GetStringUTFChars ( ctx->env, jpin, 0 ); if ( pin_len <= 0 ) { LOGE( "pe_get_pin: pin_len <=0 " ); goto pin_error; } pinentry_setbufferlen ( ctx->pe, pin_len + 1 ); if ( !ctx->pe->pin ) { LOGE( "pe_get_pin: error allocating pin buffer" ); goto pin_error; } strncpy ( ctx->pe->pin, pin, pin_len ); ( *ctx->env )->ReleaseStringUTFChars ( ctx->env, jpin, pin ); return pin_len; pin_error: ( *ctx->env )->ReleaseStringUTFChars ( ctx->env, jpin, pin ); return -1; }
static int dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) { struct dialog diag; FILE *ttyfi = NULL; FILE *ttyfo = NULL; SCREEN *screen = 0; int done = 0; char *pin_utf8; int alt = 0; #ifndef HAVE_DOSISH_SYSTEM int no_input = 1; #endif #ifdef HAVE_NCURSESW char *old_ctype = NULL; if (pinentry->lc_ctype) { old_ctype = strdup (setlocale (LC_CTYPE, NULL)); setlocale (LC_CTYPE, pinentry->lc_ctype); } else setlocale (LC_CTYPE, ""); #endif /* Open the desired terminal if necessary. */ if (tty_name) { ttyfi = fopen (tty_name, "r"); if (!ttyfi) { pinentry->specific_err = ASSUAN_ENOENT; return -1; } ttyfo = fopen (tty_name, "w"); if (!ttyfo) { int err = errno; fclose (ttyfi); errno = err; pinentry->specific_err = ASSUAN_ENOENT; return -1; } screen = newterm (tty_type, ttyfo, ttyfi); set_term (screen); } else { if (!init_screen) { if (!(isatty(fileno(stdin)) && isatty(fileno(stdout)))) { errno = ENOTTY; pinentry->specific_err = ASSUAN_ENOTTY; return -1; } init_screen = 1; initscr (); } else clear (); } keypad (stdscr, TRUE); /* Enable keyboard mapping. */ nonl (); /* Tell curses not to do NL->CR/NL on output. */ cbreak (); /* Take input chars one at a time, no wait for \n. */ noecho (); /* Don't echo input - in color. */ if (has_colors ()) { start_color (); #ifdef NCURSES_VERSION use_default_colors (); #endif if (pinentry->color_so == PINENTRY_COLOR_DEFAULT) { pinentry->color_so = PINENTRY_COLOR_RED; pinentry->color_so_bright = 1; } if (COLOR_PAIRS >= 2) { init_pair (1, pinentry_color[pinentry->color_fg], pinentry_color[pinentry->color_bg]); init_pair (2, pinentry_color[pinentry->color_so], pinentry_color[pinentry->color_bg]); bkgd (COLOR_PAIR (1)); attron (COLOR_PAIR (1) | (pinentry->color_fg_bright ? A_BOLD : 0)); } } refresh (); /* Create the dialog. */ if (dialog_create (pinentry, &diag)) { /* Note: pinentry->specific_err has already been set. */ endwin (); if (screen) delscreen (screen); #ifdef HAVE_NCURSESW if (old_ctype) { setlocale (LC_CTYPE, old_ctype); free (old_ctype); } #endif if (ttyfi) fclose (ttyfi); if (ttyfo) fclose (ttyfo); return -2; } dialog_switch_pos (&diag, diag.pinentry->pin ? DIALOG_POS_PIN : DIALOG_POS_OK); #ifndef HAVE_DOSISH_SYSTEM wtimeout (stdscr, 70); #endif do { int c; c = wgetch (stdscr); /* Refresh, accept single keystroke of input. */ #ifndef HAVE_DOSISH_SYSTEM if (timed_out && no_input) { done = -2; break; } #endif switch (c) { case ERR: #ifndef HAVE_DOSISH_SYSTEM continue; #else done = -2; break; #endif case 27: /* Alt was pressed. */ alt = 1; /* Get the next key press. */ continue; case KEY_LEFT: case KEY_UP: switch (diag.pos) { case DIALOG_POS_OK: if (diag.pinentry->pin) dialog_switch_pos (&diag, DIALOG_POS_PIN); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_CANCEL: if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else dialog_switch_pos (&diag, DIALOG_POS_OK); break; default: break; } break; case KEY_RIGHT: case KEY_DOWN: switch (diag.pos) { case DIALOG_POS_PIN: dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_OK: if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; default: break; } break; case '\t': switch (diag.pos) { case DIALOG_POS_PIN: dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_OK: if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_CANCEL: if (diag.pinentry->pin) dialog_switch_pos (&diag, DIALOG_POS_PIN); else dialog_switch_pos (&diag, DIALOG_POS_OK); break; default: break; } break; case '\005': done = -2; break; case '\r': switch (diag.pos) { case DIALOG_POS_PIN: case DIALOG_POS_OK: done = 1; break; case DIALOG_POS_NOTOK: done = -1; break; case DIALOG_POS_CANCEL: done = -2; break; case DIALOG_POS_NONE: break; } break; default: if (diag.pos == DIALOG_POS_PIN) dialog_input (&diag, alt, c); } #ifndef HAVE_DOSISH_SYSTEM no_input = 0; #endif if (c != -1) alt = 0; } while (!done); if (diag.pinentry->pin) /* NUL terminate the passphrase. dialog_run makes sure there is enough space for the terminating NUL byte. */ diag.pinentry->pin[diag.pin_len] = 0; set_cursor_state (1); endwin (); if (screen) delscreen (screen); #ifdef HAVE_NCURSESW if (old_ctype) { setlocale (LC_CTYPE, old_ctype); free (old_ctype); } #endif if (ttyfi) fclose (ttyfi); if (ttyfo) fclose (ttyfo); /* XXX Factor out into dialog_release or something. */ free (diag.ok); if (diag.cancel) free (diag.cancel); if (diag.notok) free (diag.notok); if (pinentry->pin) { pinentry->locale_err = 1; pin_utf8 = pinentry_local_to_utf8 (pinentry->lc_ctype, pinentry->pin, 1); if (pin_utf8) { pinentry_setbufferlen (pinentry, strlen (pin_utf8) + 1); if (pinentry->pin) strcpy (pinentry->pin, pin_utf8); secmem_free (pin_utf8); pinentry->locale_err = 0; } } if (done == -2) pinentry->canceled = 1; if (diag.pinentry->pin) return done < 0 ? -1 : diag.pin_len; else return done < 0 ? 0 : 1; }
/* XXX Assume that field width is at least > 5. */ static void dialog_input (dialog_t diag, int alt, int chr) { int old_loc = diag->pin_loc; assert (diag->pinentry->pin); assert (diag->pos == DIALOG_POS_PIN); if (alt && chr == KEY_BACKSPACE) /* Remap alt-backspace to control-W. */ chr = 'w' - 'a' + 1; switch (chr) { case KEY_BACKSPACE: case 'h' - 'a' + 1: /* control-h. */ if (diag->pin_len > 0) { diag->pin_len--; diag->pin_loc--; if (diag->pin_loc == 0 && diag->pin_len > 0) { diag->pin_loc = diag->pin_size - 5; if (diag->pin_loc > diag->pin_len) diag->pin_loc = diag->pin_len; } } break; case 'l' - 'a' + 1: /* control-l */ /* Refresh the screen. */ endwin (); refresh (); break; case 'u' - 'a' + 1: /* control-u */ /* Erase the whole line. */ if (diag->pin_len > 0) { diag->pin_len = 0; diag->pin_loc = 0; } break; case 'w' - 'a' + 1: /* control-w. */ while (diag->pin_len > 0 && diag->pinentry->pin[diag->pin_len - 1] == ' ') { diag->pin_len --; diag->pin_loc --; if (diag->pin_loc < 0) { diag->pin_loc += diag->pin_size; if (diag->pin_loc > diag->pin_len) diag->pin_loc = diag->pin_len; } } while (diag->pin_len > 0 && diag->pinentry->pin[diag->pin_len - 1] != ' ') { diag->pin_len --; diag->pin_loc --; if (diag->pin_loc < 0) { diag->pin_loc += diag->pin_size; if (diag->pin_loc > diag->pin_len) diag->pin_loc = diag->pin_len; } } break; default: if (chr > 0 && chr < 256 && diag->pin_len < diag->pin_max) { /* Make sure there is enough room for this character and a following NUL byte. */ if (! pinentry_setbufferlen (diag->pinentry, diag->pin_len + 2)) { /* Bail. Here we use a simple approach. It would be better to have a pinentry_bug function. */ assert (!"setbufferlen failed"); abort (); } diag->pinentry->pin[diag->pin_len] = (char) chr; diag->pin_len++; diag->pin_loc++; if (diag->pin_loc == diag->pin_size && diag->pin_len < diag->pin_max) { diag->pin_loc = 5; if (diag->pin_loc < diag->pin_size - (diag->pin_max + 1 - diag->pin_len)) diag->pin_loc = diag->pin_size - (diag->pin_max + 1 - diag->pin_len); } } break; } if (old_loc < diag->pin_loc) { move (diag->pin_y, diag->pin_x + old_loc); while (old_loc++ < diag->pin_loc) addch ('*'); } else if (old_loc > diag->pin_loc) { move (diag->pin_y, diag->pin_x + diag->pin_loc); while (old_loc-- > diag->pin_loc) addch ('_'); } move (diag->pin_y, diag->pin_x + diag->pin_loc); }
static int qt_cmd_handler (pinentry_t pe) { QWidget *parent = 0; /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) parent = new ForeignWidget ((WId) pe->parent_wid); int want_pass = !!pe->pin; const QString ok = pe->ok ? escape_accel( from_utf8( pe->ok ) ) : pe->default_ok ? escape_accel( from_utf8( pe->default_ok ) ) : /* else */ QLatin1String( "&OK" ) ; const QString cancel = pe->cancel ? escape_accel( from_utf8( pe->cancel ) ) : pe->default_cancel ? escape_accel( from_utf8( pe->default_cancel ) ) : /* else */ QLatin1String( "&Cancel" ) ; const QString title = pe->title ? from_utf8( pe->title ) : /* else */ QLatin1String( "pinentry-qt4" ) ; if (want_pass) { PinEntryDialog pinentry (parent, 0, pe->timeout, true, !!pe->quality_bar); pinentry.setPinentryInfo (pe); pinentry.setPrompt (escape_accel (from_utf8 (pe->prompt)) ); pinentry.setDescription (from_utf8 (pe->description)); if ( pe->title ) pinentry.setWindowTitle( from_utf8( pe->title ) ); /* If we reuse the same dialog window. */ pinentry.setPin (secqstring()); pinentry.setOkText (ok); pinentry.setCancelText (cancel); if (pe->error) pinentry.setError (from_utf8 (pe->error)); if (pe->quality_bar) pinentry.setQualityBar (from_utf8 (pe->quality_bar)); if (pe->quality_bar_tt) pinentry.setQualityBarTT (from_utf8 (pe->quality_bar_tt)); bool ret = pinentry.exec (); if (!ret) return -1; const secstring pinUtf8 = toUtf8( pinentry.pin() ); const char *pin = pinUtf8.data(); int len = strlen (pin); if (len >= 0) { pinentry_setbufferlen (pe, len + 1); if (pe->pin) { strcpy (pe->pin, pin); return len; } } return -1; } else { const QString desc = pe->description ? from_utf8 ( pe->description ) : QString(); const QString notok = pe->notok ? escape_accel (from_utf8 ( pe->notok )) : QString(); const QMessageBox::StandardButtons buttons = pe->one_button ? QMessageBox::Ok : pe->notok ? QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel : /* else */ QMessageBox::Ok|QMessageBox::Cancel ; PinentryConfirm box( QMessageBox::Information, pe->timeout, title, desc, buttons, parent ); const struct { QMessageBox::StandardButton button; QString label; } buttonLabels[] = { { QMessageBox::Ok, ok }, { QMessageBox::Yes, ok }, { QMessageBox::No, notok }, { QMessageBox::Cancel, cancel }, }; for ( size_t i = 0 ; i < sizeof buttonLabels / sizeof *buttonLabels ; ++i ) if ( (buttons & buttonLabels[i].button) && !buttonLabels[i].label.isEmpty() ) box.button( buttonLabels[i].button )->setText( buttonLabels[i].label ); box.setIconPixmap( icon() ); if ( !pe->one_button ) box.setDefaultButton( QMessageBox::Cancel ); box.show(); raiseWindow( &box ); const int rc = box.exec(); if ( rc == QMessageBox::Cancel ) pe->canceled = true; return rc == QMessageBox::Ok || rc == QMessageBox::Yes ; } }
static int dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) { struct dialog diag; FILE *ttyfi = NULL; FILE *ttyfo = NULL; SCREEN *screen = 0; int done = 0; char *pin_utf8; /* Open the desired terminal if necessary. */ if (tty_name) { ttyfi = fopen (tty_name, "r"); if (!ttyfi) return -1; ttyfo = fopen (tty_name, "w"); if (!ttyfo) { int err = errno; fclose (ttyfi); errno = err; return -1; } screen = newterm ((char *)tty_type, ttyfo, ttyfi); set_term (screen); } else { if (!init_screen) { init_screen = 1; initscr (); } else clear (); } keypad (stdscr, TRUE); /* Enable keyboard mapping. */ nonl (); /* Tell curses not to do NL->CR/NL on output. */ cbreak (); /* Take input chars one at a time, no wait for \n. */ noecho (); /* Don't echo input - in color. */ if (has_colors ()) { start_color (); use_default_colors (); if (pinentry->color_so == PINENTRY_COLOR_DEFAULT) { pinentry->color_so = PINENTRY_COLOR_RED; pinentry->color_so_bright = 1; } if (COLOR_PAIRS >= 2) { init_pair (1, pinentry_color[pinentry->color_fg], pinentry_color[pinentry->color_bg]); init_pair (2, pinentry_color[pinentry->color_so], pinentry_color[pinentry->color_bg]); bkgd (COLOR_PAIR (1)); attron (COLOR_PAIR (1) | (pinentry->color_fg_bright ? A_BOLD : 0)); } } refresh (); /* XXX */ if (dialog_create (pinentry, &diag)) return -2; dialog_switch_pos (&diag, diag.pin ? DIALOG_POS_PIN : DIALOG_POS_OK); do { int c; c = getch (); /* Refresh, accept single keystroke of input. */ switch (c) { case KEY_LEFT: case KEY_UP: switch (diag.pos) { case DIALOG_POS_OK: if (diag.pin) dialog_switch_pos (&diag, DIALOG_POS_PIN); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_CANCEL: if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else dialog_switch_pos (&diag, DIALOG_POS_OK); break; default: break; } break; case KEY_RIGHT: case KEY_DOWN: switch (diag.pos) { case DIALOG_POS_PIN: dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_OK: if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; default: break; } break; case '\t': switch (diag.pos) { case DIALOG_POS_PIN: dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_OK: if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_CANCEL: if (diag.pin) dialog_switch_pos (&diag, DIALOG_POS_PIN); else dialog_switch_pos (&diag, DIALOG_POS_OK); break; default: break; } break; case '\005': done = -2; break; case '\r': switch (diag.pos) { case DIALOG_POS_PIN: case DIALOG_POS_OK: done = 1; break; case DIALOG_POS_NOTOK: done = -1; break; case DIALOG_POS_CANCEL: done = -2; break; case DIALOG_POS_NONE: break; } break; default: if (diag.pos == DIALOG_POS_PIN) dialog_input (&diag, c); } } while (!done); set_cursor_state (1); endwin (); if (screen) delscreen (screen); if (ttyfi) fclose (ttyfi); if (ttyfo) fclose (ttyfo); /* XXX Factor out into dialog_release or something. */ free (diag.ok); if (diag.cancel) free (diag.cancel); if (diag.notok) free (diag.notok); if (pinentry->pin) { pinentry->locale_err = 1; pin_utf8 = pinentry_local_to_utf8 (pinentry->lc_ctype, pinentry->pin, 1); if (pin_utf8) { pinentry_setbufferlen (pinentry, strlen (pin_utf8) + 1); if (pinentry->pin) strcpy (pinentry->pin, pin_utf8); secmem_free (pin_utf8); pinentry->locale_err = 0; } } if (done == -2) pinentry->canceled = 1; return diag.pin ? (done < 0 ? -1 : diag.pin_len) : (done < 0 ? 0 : 1); }
static int qt_cmd_handler (pinentry_t pe) { QWidget *parent = 0; int want_pass = !!pe->pin; if (want_pass) { /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) parent = new ForeignWidget (pe->parent_wid); PinEntryDialog pinentry (parent, NULL, true, !!pe->quality_bar); pinentry.setPinentryInfo (pe); pinentry.setPrompt (QString::fromUtf8 (pe->prompt)); pinentry.setDescription (QString::fromUtf8 (pe->description)); /* If we reuse the same dialog window. */ #if 0 pinentry.setText (SecQString::null); #endif if (pe->ok) pinentry.setOkText (escape_accel (QString::fromUtf8 (pe->ok))); else if (pe->default_ok) pinentry.setOkText (escape_accel (QString::fromUtf8 (pe->default_ok))); if (pe->cancel) pinentry.setCancelText (escape_accel (QString::fromUtf8 (pe->cancel))); else if (pe->default_cancel) pinentry.setCancelText (escape_accel (QString::fromUtf8 (pe->default_cancel))); if (pe->error) pinentry.setError (QString::fromUtf8 (pe->error)); if (pe->quality_bar) pinentry.setQualityBar (QString::fromUtf8 (pe->quality_bar)); if (pe->quality_bar_tt) pinentry.setQualityBarTT (QString::fromUtf8 (pe->quality_bar_tt)); bool ret = pinentry.exec (); if (!ret) return -1; char *pin = (char *) pinentry.text().utf8(); if (!pin) return -1; int len = strlen (pin); if (len >= 0) { pinentry_setbufferlen (pe, len + 1); if (pe->pin) { strcpy (pe->pin, pin); ::secmem_free (pin); return len; } } ::secmem_free (pin); return -1; } else { QString desc = QString::fromUtf8 (pe->description? pe->description : ""); QString ok = escape_accel (QString::fromUtf8 (pe->ok ? pe->ok : pe->default_ok ? pe->default_ok : "&OK")); QString can = escape_accel (QString::fromUtf8 (pe->cancel ? pe->cancel : pe->default_cancel? pe->default_cancel: "&Cancel")); bool ret; ret = QMessageBox::information (parent, "", desc, ok, can ); return !ret; } }