Mailing List Archive

[RFC PATCH 2/4] pam-ssh-agent: Add reading of one auth key from file
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@linux.com>

---
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@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev