GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Passworteingabe am Terminal ausblenden

Ohne getch sich darauf zu verlassen und das veraltete getpass zu vermeiden , ist der empfohlene Ansatz, Terminal ECHO über termios zu deaktivieren verwenden. Nach ein paar Suchen nach einer vorgefertigten flexiblen Passwortroutine war ich überrascht, dass nur sehr wenige für die eigenständige Verwendung mit C geeignet waren. Anstatt einfach getch neu zu codieren mit termios c_lflag Optionen, etwas allgemeinerer Ansatz erfordert nur ein paar Ergänzungen. Über das Ersetzen von getch hinaus Jede Routine sollte eine bestimmte maximale Länge erzwingen, um einen Überlauf zu verhindern, abschneiden, wenn der Benutzer versucht, über das Maximum hinaus einzugeben, und warnen, wenn auf irgendeine Weise abgeschnitten wird.

Unten erlauben die Zusätze das Lesen von jedem FILE * Eingabestrom, begrenzt die Länge auf eine bestimmte Länge, bietet minimale Bearbeitungsmöglichkeiten (Rücktaste) bei der Eingabe, ermöglicht die Angabe oder vollständige Deaktivierung der Zeichenmaske und gibt schließlich die Länge des eingegebenen Passworts zurück. Eine Warnung wurde hinzugefügt, wenn das eingegebene Passwort auf die maximale oder angegebene Länge gekürzt wurde.

Hoffentlich wird es anderen mit dieser Frage, die nach einer ähnlichen Lösung suchen, nützlich sein:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>

#define MAXPW 32

/* read a string from fp into pw masking keypress with mask char.
getpasswd will read upto sz - 1 chars into pw, null-terminating
the resulting string. On success, the number of characters in
pw are returned, -1 otherwise.
*/
ssize_t getpasswd (char **pw, size_t sz, int mask, FILE *fp)
{
    if (!pw || !sz || !fp) return -1;       /* validate input   */
#ifdef MAXPW
    if (sz > MAXPW) sz = MAXPW;
#endif

    if (*pw == NULL) {              /* reallocate if no address */
        void *tmp = realloc (*pw, sz * sizeof **pw);
        if (!tmp)
            return -1;
        memset (tmp, 0, sz);    /* initialize memory to 0   */
        *pw =  (char*) tmp;
    }

    size_t idx = 0;         /* index, number of chars in read   */
    int c = 0;

    struct termios old_kbd_mode;    /* orig keyboard settings   */
    struct termios new_kbd_mode;

    if (tcgetattr (0, &old_kbd_mode)) { /* save orig settings   */
        fprintf (stderr, "%s() error: tcgetattr failed.\n", __func__);
        return -1;
    }   /* copy old to new */
    memcpy (&new_kbd_mode, &old_kbd_mode, sizeof(struct termios));

    new_kbd_mode.c_lflag &= ~(ICANON | ECHO);  /* new kbd flags */
    new_kbd_mode.c_cc[VTIME] = 0;
    new_kbd_mode.c_cc[VMIN] = 1;
    if (tcsetattr (0, TCSANOW, &new_kbd_mode)) {
        fprintf (stderr, "%s() error: tcsetattr failed.\n", __func__);
        return -1;
    }

    /* read chars from fp, mask if valid char specified */
    while (((c = fgetc (fp)) != '\n' && c != EOF && idx < sz - 1) ||
            (idx == sz - 1 && c == 127))
    {
        if (c != 127) {
            if (31 < mask && mask < 127)    /* valid ascii char */
                fputc (mask, stdout);
            (*pw)[idx++] = c;
        }
        else if (idx > 0) {         /* handle backspace (del)   */
            if (31 < mask && mask < 127) {
                fputc (0x8, stdout);
                fputc (' ', stdout);
                fputc (0x8, stdout);
            }
            (*pw)[--idx] = 0;
        }
    }
    (*pw)[idx] = 0; /* null-terminate   */

    /* reset original keyboard  */
    if (tcsetattr (0, TCSANOW, &old_kbd_mode)) {
        fprintf (stderr, "%s() error: tcsetattr failed.\n", __func__);
        return -1;
    }

    if (idx == sz - 1 && c != '\n') /* warn if pw truncated */
        fprintf (stderr, " (%s() warning: truncated at %zu chars.)\n",
                __func__, sz - 1);

    return idx; /* number of chars in passwd    */
}

Ein einfaches Programm, das die Verwendung zeigt, wäre wie folgt. Wenn Sie ein statisches Array von Zeichen zum Speichern des Passworts verwenden, stellen Sie einfach sicher, dass ein Zeiger an die Funktion übergeben wird.

int main (void ) {

    char pw[MAXPW] = {0};
    char *p = pw;
    FILE *fp = stdin;
    ssize_t nchr = 0;

    printf ( "\n Enter password: ");
    nchr = getpasswd (&p, MAXPW, '*', fp);
    printf ("\n you entered   : %s  (%zu chars)\n", p, nchr);

    printf ( "\n Enter password: ");
    nchr = getpasswd (&p, MAXPW, 0, fp);
    printf ("\n you entered   : %s  (%zu chars)\n\n", p, nchr);

    return 0;
}

Beispielausgabe

$ ./bin/getpasswd2

 Enter password: ******
 you entered   : 123456  (6 chars)

 Enter password:
 you entered   : abcdef  (6 chars)

In der Linux-Welt erfolgt die Maskierung normalerweise nicht mit Sternchen, normalerweise wird das Echo einfach ausgeschaltet und das Terminal zeigt Leerzeichen an, z. wenn Sie su verwenden oder in ein virtuelles Terminal einloggen etc.

Es gibt eine Bibliotheksfunktion zum Abrufen von Passwörtern, die das Passwort nicht mit Sternchen maskiert, sondern das Echo des Passworts an das Terminal deaktiviert. Ich zog dies aus einem Linux-Buch, das ich habe. Ich glaube, es ist Teil des Posix-Standards

#include <unistd.h>
char *getpass(const char *prompt);

/*Returns pointer to statically allocated input password string
on success, or NULL on error*/

Die getpass()-Funktion deaktiviert zunächst das Echoing und die gesamte Verarbeitung von Terminal-Sonderzeichen (wie etwa das Interrupt-Zeichen, normalerweise Strg-C).

Dann gibt es den String aus, auf den prompt zeigt, und liest eine Eingabezeile, wobei es den auf Null endenden Eingabestring mit entferntem Zeilenumbruch als Funktionsergebnis zurückgibt.

Eine Google-Suche nach getpass() enthält einen Verweis auf die GNU-Implementierung (sollte in den meisten Linux-Distributionen enthalten sein) und einigen Beispielcode für die Implementierung Ihres eigenen Codes, falls erforderlich

http://www.gnu.org/s/hello/manual/libc/getpass.html

Ihr Beispiel zum Selberrollen:

#include <termios.h>
#include <stdio.h>

ssize_t
my_getpass (char **lineptr, size_t *n, FILE *stream)
{
    struct termios old, new;
    int nread;

    /* Turn echoing off and fail if we can't. */
    if (tcgetattr (fileno (stream), &old) != 0)
        return -1;
    new = old;
    new.c_lflag &= ~ECHO;
    if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
        return -1;

    /* Read the password. */
    nread = getline (lineptr, n, stream);

    /* Restore terminal. */
    (void) tcsetattr (fileno (stream), TCSAFLUSH, &old);

    return nread;
}

Bei Bedarf können Sie dies als Grundlage verwenden, indem Sie es so ändern, dass Sternchen angezeigt werden.


Linux
  1. Wie verstecke ich die Terminalausgabe beim Ausführen eines Befehls?

  2. | Im Terminalkommando?

  3. Ubuntu-Terminal

  4. Ausblenden von Benutzereingaben auf dem Terminal im Linux-Skript

  5. Löschen Sie den Terminalverlauf in Linux

Verwalten Sie Ihre Passwörter im Linux-Terminal

So zeigen Sie Sternchen an, wenn Sie das Passwort im Terminal eingeben

So machen Sie Passwort-Sternchen im Ubuntu-Terminal sichtbar

So finden Sie ein gespeichertes WLAN-Passwort in Linux Mint mithilfe der GUI oder des Terminals

Clearing-Terminal

Ubuntu Server:Meine Eingabe im Terminal wird nicht angezeigt