[RFC PATCH 2/4] pam-ssh-agent: Add reading of one auth key from file

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



The module needs to read authorized ssh keys from file. Tests validate
the file name and content.

This first implementation reads only one key, support for multiple keys
would be added later.

Fancy ways to obtain auth keys need to be implemented in separate
modules and keys would be shared via PAM environment (to be implemented).

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

---
 pam-ssh-agent.c          |   64 +++++++++++++++++++++++++++++++++++++++++++++++
 regress/pam-ssh-agent.sh |   24 +++++++++++++++---
 2 files changed, 84 insertions(+), 4 deletions(-)

Index: b/pam-ssh-agent.c
===================================================================
--- a/pam-ssh-agent.c
+++ b/pam-ssh-agent.c
@@ -35,7 +35,12 @@
 #include <pam/pam_modules.h>
 #endif
 
+#include "authfile.h"
+#include "authfd.h"
+#include "ssherr.h"
+
 static int pam_debug;
+static const char *auth_file;
 
 static int
 parse_args(int argc, const char **argv)
@@ -45,6 +50,14 @@ parse_args(int argc, const char **argv)
 	for (i=0; i!=argc; i++) {
 		if (!strcmp(argv[i], "debug")) {
 			pam_debug = 1;
+		} else if (!strncmp(argv[i], "file=", 5)) {
+			if (argv[i][5] == '\0')
+				continue;
+			auth_file = argv[i] + 5;
+			if (auth_file[0] != '/') {
+				syslog(LOG_ERR, "auth file error: Path is not absolute: %s", auth_file);
+				invalid++;
+			}
 		} else {
 			syslog(LOG_ERR, "invalid argument: %s", argv[i]);
 			invalid++;
@@ -54,9 +67,37 @@ parse_args(int argc, const char **argv)
 	return invalid;
 }
 
+static int
+ssh_read_identitylist(const char *filename, struct ssh_identitylist **idlp)
+{
+	struct ssh_identitylist *idl = NULL;
+	int r;
+
+	if ((idl = calloc(1, sizeof(*idl))) == NULL ||
+	    (idl->keys = calloc(1, sizeof(*idl->keys))) == NULL ||
+	    (idl->comments = calloc(1, sizeof(*idl->comments))) == NULL) {
+		r = SSH_ERR_ALLOC_FAIL;
+		goto out;
+	}
+
+	r = sshkey_load_public(filename, &idl->keys[0], &idl->comments[0]);
+	if (r)
+		goto out;
+
+	idl->nkeys = 1;
+	*idlp = idl;
+	idl = NULL;
+
+out:
+	if (idl != NULL)
+		ssh_free_identitylist(idl);
+	return r;
+}
+
 int
 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
 {
+	struct ssh_identitylist *auth_ids = NULL;
 	int ret;
 
 	openlog("pam_ssh_agent_auth", 0, LOG_AUTHPRIV);
@@ -70,11 +111,34 @@ pam_sm_authenticate(pam_handle_t *pamh,
 		const char *user = "(unknown)";
 		pam_get_user(pamh, &user, NULL);
 		syslog(LOG_DEBUG, "USER: %s", user);
+		syslog(LOG_DEBUG, "FILE: %s", auth_file ? auth_file : "(null)");
+	}
+
+	if (auth_file == NULL) {
+		syslog(LOG_ERR, "auth file error: file= is not specified");
+		ret = PAM_SERVICE_ERR;
+		goto out;
+	}
+
+	ret = ssh_read_identitylist(auth_file, &auth_ids);
+	if (ret) {
+		syslog(LOG_ERR, "auth file error: %s: %s", ssh_err(ret), auth_file);
+		ret = PAM_AUTHINFO_UNAVAIL;
+		goto out;
+	}
+
+	if (pam_debug) {
+		unsigned i;
+		syslog(LOG_DEBUG, "auth file has %u key(s):", (unsigned) auth_ids->nkeys);
+		for (i=0; i!=auth_ids->nkeys; i++)
+			syslog(LOG_DEBUG, "  %d) %s", i, auth_ids->comments[i]);
 	}
 
 	ret = PAM_SUCCESS;
 
 out:
+	if (auth_ids != NULL)
+		ssh_free_identitylist(auth_ids);
 	if (pam_debug)
 		syslog(LOG_DEBUG, "result: %s", pam_strerror(pamh, ret));
 	closelog();
Index: b/regress/pam-ssh-agent.sh
===================================================================
--- a/regress/pam-ssh-agent.sh
+++ b/regress/pam-ssh-agent.sh
@@ -14,9 +14,13 @@ export PAM_WRAPPER_SERVICE_DIR=$OBJ/pam-
 
 PAM_SUCCESS=0
 PAM_SERVICE_ERR=3
+PAM_AUTHINFO_UNAVAIL=9
 
 . $OBJ/keytype_gen.sh
 
+first_kt=`echo $ktypes | cut -d" " -f1`
+AUTH_FILE=$OBJ/key.$first_kt.pub
+
 pam_agent_test()
 {
 	rm -rf $PAM_WRAPPER_SERVICE_DIR
@@ -36,8 +40,20 @@ EOF
 trace "invalid arguments"
 expect=$PAM_SERVICE_ERR       pam_agent_test invalid arguments
 
-trace "debug argument"
-expect=$PAM_SUCCESS           pam_agent_test debug
-
 trace "without arguments"
-expect=$PAM_SUCCESS           pam_agent_test
+expect=$PAM_SERVICE_ERR       pam_agent_test # file= is required
+
+trace "with non-absolute auth file path"
+expect=$PAM_SERVICE_ERR       pam_agent_test file=nonabsolute.$$
+
+trace "with non-existent auth file"
+expect=$PAM_AUTHINFO_UNAVAIL  pam_agent_test file=/nonexistent.$$
+
+trace "with empty auth file"
+expect=$PAM_AUTHINFO_UNAVAIL  pam_agent_test file=/dev/null
+
+trace "authenticate agent (debug)"
+expect=$PAM_SUCCESS           pam_agent_test file=$AUTH_FILE debug
+
+trace "authenticate agent (non-debug)"
+expect=$PAM_SUCCESS           pam_agent_test file=$AUTH_FILE

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



[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux