[RFC PATCH 4/4] pam-ssh-agent: Add authenticating the SSH agent
Domenico Andreoli
cavokz at gmail.com
Tue Jul 21 11:06:17 AEST 2020
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 at 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
More information about the openssh-unix-dev
mailing list