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]"