pam_ssh alternative?

yggdrasil

Well-Known Member
Servus zusammen,

angespornt von Michael W. Lucas Vortrag zu PAM wollte ich mich mal wieder etwas in die Materie einarbeiten. Vor allem wollte ich den ssh-agent direkt in PAM starten lassen (das tut wunderbar) und meine privaten Schlüssel entschlüsseln (das tut leider nicht). Nach etwas wälzen der recht kurz geratenen manpage und benutzen des debug-Arguments zu pam-ssh stellt sich heraus, daß das OpenPAMs pam-ssh leider nur 4 private Schlüssel erkennt: idendity, id_rsa, id_dsa, id_ecdsa. Die LinuxPAM-Version liest einfach alle Schlüssel in einem Unterverzeichnis von ~/.ssh ein, was doch deutlich flexibler ist (und ec25519 unterstützt).
Daher meine Frage an euch: hat schonmal jemand mit OpenPAMs pam_ssh gearbeitet und es dazu gebracht, andere Schlüssel als die in der Liste zu entschlüsseln. Oder kennt jemand eine Möglichkeit, LinuxPAMs pam_ssh unter FreeBSD einzusetzen? Oder eine andere Alternative (den Agenten per .xsession zu starten und mit ssh-askpass das Schlüsselpassword abzufragen kenn ich schon, davon will ich ja gerade weg).

Besten Danke!
 
Interessanter Hinweis... ich werde mal
anfangen mich in die code-base des
pam(8) Modulen einzuarbeiten...

... vielleicht ist es notwendig die
bestehende Code-base des Modulen,
um die bennanten fn'en (Callbacks)
zu erweitern, da pam(8) bzw. die
Funktionalitaet (bspw. das Verarbeiten
von Token) per Callbacks ueber den
Softwarecontext abgebildet wird.

Also mich interessierts (jetzt)!
 
Nun... nach dem "groben" Ueberfliegen des pam_ssh(8) Modulen,
Code:
...

extern char **environ;

struct pam_ssh_key {
    Key *key;
     char    *comment;
};

static const char *pam_ssh_prompt = "SSH passphrase: ";
static const char *pam_ssh_have_keys = "pam_ssh_have_keys";

static const char *pam_ssh_keyfiles[] = {
    ".ssh/identity",    /* SSH1 RSA key */
    ".ssh/id_rsa",      /* SSH2 RSA key */
    ".ssh/id_dsa",      /* SSH2 DSA key */
    ".ssh/id_ecdsa",    /* SSH2 ECDSA key */
    NULL
};

static const char *pam_ssh_agent = "/usr/bin/ssh-agent";
static char *const pam_ssh_agent_argv[] = { "ssh_agent", "-s", NULL };
static char *const pam_ssh_agent_envp[] = { NULL };

...
erscheint das Modifizieren dieses Modulen, bzgl. "gewuenschter" Funktionalitaet, sich moeglicherweise als realistisches Unterfangen zu gestalten.
 
Letzendlich agiert dieses Modulen bspw. (mitunter) als "Proxy-pattern"...
Code:
...

/*
 * Attempts to load a private key from the specified file in the specified
 * directory, using the specified passphrase.  If successful, returns a
 * struct pam_ssh_key containing the key and its comment.
 */
static struct pam_ssh_key *
pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase,
    int nullok)
{
    struct pam_ssh_key *psk;
    char fn[PATH_MAX];
    char *comment;
    Key *key;

    if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn))
        return (NULL);
    comment = NULL;
    /*
     * If the key is unencrypted, OpenSSL ignores the passphrase, so
     * it will seem like the user typed in the right one.  This allows
     * a user to circumvent nullok by providing a dummy passphrase.
     * Verify that the key really *is* encrypted by trying to load it
     * with an empty passphrase, and if the key is not encrypted,
     * accept only an empty passphrase.
     */
    key = key_load_private(fn, "", &comment);
    if (key != NULL && !(*passphrase == '\0' && nullok)) {
        key_free(key);
        return (NULL);
    }
    if (key == NULL)
        key = key_load_private(fn, passphrase, &comment);
    if (key == NULL) {
        openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn);
        return (NULL);
    }

    openpam_log(PAM_LOG_DEBUG, "loaded '%s' from %s", comment, fn);
    if ((psk = malloc(sizeof(*psk))) == NULL) {
        key_free(key);
        free(comment);
        return (NULL);
    }
    psk->key = key;
    psk->comment = comment;
    return (psk);
}

...

Fazit: es bedarf keiner "Alternative" zu dem verwendeten pam_ssh(8) Modulen, sondern der als
Code:
...

static const char *pam_ssh_keyfiles[] = {
    ".ssh/identity",    /* SSH1 RSA key */
    ".ssh/id_rsa",      /* SSH2 RSA key */
    ".ssh/id_dsa",      /* SSH2 DSA key */
    ".ssh/id_ecdsa",    /* SSH2 ECDSA key */
    NULL
};

...
definierte Vektor sollte im Rahmen der angestrebten Problemloesung (moeglicherweise) um fehlende Artefakte erweitert werden. Ich selbst habe diesen Loesungsansatz noch nicht getestet, da ich momentan dieses Modulen bzgl. interner Struktur (und Skalierbarkeit) analysiere.
 
Zurück
Oben