Mailing List Archive

[RFC PATCH 4/4] pam-ssh-agent: Add authenticating the SSH agent
The two key sets, agent and auth, are compared. The matching keys are
used to challenge the agent in signing some random data. The first
positive proof immediately ends the verification with a success.

Tests verify the correct behavior with different auth files. A full
round with all the supported key types is also performed.

Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>

---
pam-ssh-agent.c | 33 ++++++++++++++++++++++++++++++++-
regress/pam-ssh-agent.sh | 23 +++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)

Index: b/pam-ssh-agent.c
===================================================================
--- a/pam-ssh-agent.c
+++ b/pam-ssh-agent.c
@@ -38,6 +38,7 @@
#include "authfile.h"
#include "authfd.h"
#include "ssherr.h"
+#include "sshkey.h"
#include "ssh.h"

static int pam_debug;
@@ -95,6 +96,36 @@ out:
return r;
}

+static int
+challenge_agent(int agent_fd, const struct sshkey *agent_key, const struct sshkey *auth_key)
+{
+ u_char *sig = NULL;
+ size_t slen = 0;
+ char data[1024];
+ int ret;
+
+ arc4random_buf(data, sizeof(data));
+ ret = ssh_agent_sign(agent_fd, agent_key, &sig, &slen, data, sizeof(data), NULL, 0) ||
+ sshkey_verify(auth_key, sig, slen, data, sizeof(data), NULL, 0, NULL);
+
+ if (sig != NULL)
+ free(sig);
+ return !ret;
+}
+
+static int
+authenticate_agent(int agent_fd, const struct ssh_identitylist *agent_ids,
+ const struct ssh_identitylist *auth_ids)
+{
+ unsigned i, j;
+ for (i=0; i!=agent_ids->nkeys; i++)
+ for (j=0; j!=auth_ids->nkeys; j++)
+ if (sshkey_equal(agent_ids->keys[i], auth_ids->keys[j]))
+ if (challenge_agent(agent_fd, agent_ids->keys[i], auth_ids->keys[j]))
+ return PAM_SUCCESS;
+ return PAM_AUTH_ERR;
+}
+
int
pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
@@ -161,7 +192,7 @@ pam_sm_authenticate(pam_handle_t *pamh,
syslog(LOG_DEBUG, " %d) %s", i, agent_ids->comments[i]);
}

- ret = PAM_SUCCESS;
+ ret = authenticate_agent(agent_fd, agent_ids, auth_ids);

out:
if (agent_fd != -1)
Index: b/regress/pam-ssh-agent.sh
===================================================================
--- a/regress/pam-ssh-agent.sh
+++ b/regress/pam-ssh-agent.sh
@@ -20,7 +20,9 @@ PAM_AUTHINFO_UNAVAIL=9
. $OBJ/keytype_gen.sh

first_kt=`echo $ktypes | cut -d" " -f1`
+second_kt=`echo $ktypes | cut -d" " -f2`
AUTH_FILE=$OBJ/key.$first_kt.pub
+AUTH_FILE2=$OBJ/key.$second_kt.pub

pam_agent_test()
{
@@ -73,6 +75,27 @@ expect=$PAM_SUCCESS pam_agent_
trace "authenticate agent (non-debug)"
expect=$PAM_SUCCESS pam_agent_test file=$AUTH_FILE

+trace "change of auth file (debug)"
+expect=$PAM_AUTH_ERR pam_agent_test file=$AUTH_FILE2 debug
+
+trace "change of auth file (non-debug)"
+expect=$PAM_AUTH_ERR pam_agent_test file=$AUTH_FILE2
+
+for kt in $ktypes; do
+ trace "load key $kt into the agent"
+ ${SSHADD} -q $OBJ/key.$kt
+ r=$?
+ if [ $r -ne 0 ]; then
+ fatal "could not add the key: exit code $r"
+ fi
+
+ trace "authenticate agent with $kt (debug)"
+ expect=$PAM_SUCCESS pam_agent_test file=$OBJ/key.$kt.pub debug
+
+ trace "authenticate agent with $kt (non-debug)"
+ expect=$PAM_SUCCESS pam_agent_test file=$OBJ/key.$kt.pub
+done
+
trace "kill agent"
${SSHAGENT} -k > /dev/null


_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev