Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Nov 2011 22:12:46 +0100
From:      =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To:        Guy Helmer <guy.helmer@palisadesystems.com>
Cc:        freebsd-security@freebsd.org
Subject:   Re: Possible pam_ssh bug?
Message-ID:  <86ty65qecx.fsf@ds4.des.no>
In-Reply-To: <98001F9B-0B96-4D17-9EAE-08B12A1C1C75@palisadesystems.com> (Guy Helmer's message of "Tue, 15 Nov 2011 10:39:31 -0600")
References:  <98001F9B-0B96-4D17-9EAE-08B12A1C1C75@palisadesystems.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
Guy Helmer <guy.helmer@palisadesystems.com> writes:
> I have a shell user who is able to login to his accounts via sshd on
> FreeBSD 8.2 using any password. The user had a .ssh/id_rsa and
> .ssh/id_rsa.pub key pair without a password but nullok was not
> specified, so I think this should be considered a bug.

It turns out that this goes all the way to OpenSSL, which ignores the
passphrase if the key is not encrypted.  The only solution I can think
of - more of a workaround, really - is to first try to load the key with
an empty passphrase, and skip the key if that worked.  See the attached
(untested) patch.

A more advanced patch would load all keys but require at least one of
them to have a passphrase.

DES
-- 
Dag-Erling Smørgrav - des@des.no


[-- Attachment #2 --]
Index: lib/libpam/modules/pam_ssh/pam_ssh.c
===================================================================
--- lib/libpam/modules/pam_ssh/pam_ssh.c	(revision 227125)
+++ lib/libpam/modules/pam_ssh/pam_ssh.c	(working copy)
@@ -93,7 +93,8 @@
  * 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)
+pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase,
+    int nullok)
 {
 	struct pam_ssh_key *psk;
 	char fn[PATH_MAX];
@@ -103,6 +104,21 @@
 	if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn))
 		return (NULL);
 	comment = NULL;
+	if (!nullok) {
+		/*
+		 * 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.
+		 */
+		key = key_load_private(fn, "", &comment);
+		if (key != NULL) {
+			key_free(key);
+			return (NULL);
+		}
+	}
 	key = key_load_private(fn, passphrase, &comment);
 	if (key == NULL) {
 		openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn);
@@ -180,7 +196,7 @@
 
 	/* try to load keys from all keyfiles we know of */
 	for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) {
-		psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase);
+		psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase, nullok);
 		if (psk != NULL) {
 			pam_set_data(pamh, *kfn, psk, pam_ssh_free_key);
 			++nkeys;
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86ty65qecx.fsf>