Guy Helmer <[email protected]> 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 - [email protected]

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;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to "[email protected]"

Reply via email to