Bugzilla – Attachment 2522 Details for
Bug 2081
extend the parameters to the AuthorizedKeysCommand
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Reworked patch enabling optional %-expanded arguments
0001-Extend-AuthorizedKeysCommand-with-expanded-arguments.patch (text/plain), 9.27 KB, created by
Sami Hartikainen
on 2014-12-29 21:44:24 AEDT
(
hide
)
Description:
Reworked patch enabling optional %-expanded arguments
Filename:
MIME Type:
Creator:
Sami Hartikainen
Created:
2014-12-29 21:44:24 AEDT
Size:
9.27 KB
patch
obsolete
>From 4bccce65551034ff35e39c2a0c4ee10d4fb252a6 Mon Sep 17 00:00:00 2001 >From: Sami Hartikainen <sami.hartikainen@teleste.com> >Date: Fri, 19 Sep 2014 18:39:05 +0300 >Subject: [PATCH] Extend AuthorizedKeysCommand with %-expanded arguments > >Implements #2081 as per comment 13 [1] by enabling the use of >%u, %h, %t, %f and %k arguments; if none provided, works as before >and passes the username to be authorized as the only argument to >the AuthorizedKeysCommand program. > > [1] https://bugzilla.mindrot.org/show_bug.cgi?id=2081#c13 > >As a side-effect any number of (non-expanded) parameters may >be passed to the AuthorizedKeysCommand program. >--- > auth2-pubkey.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++--------- > key.h | 1 + > sshd_config.5 | 9 ++++++- > sshkey.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > sshkey.h | 2 ++ > 5 files changed, 150 insertions(+), 13 deletions(-) > >diff --git a/auth2-pubkey.c b/auth2-pubkey.c >index 2b04862..c3bb27e 100644 >--- a/auth2-pubkey.c >+++ b/auth2-pubkey.c >@@ -518,9 +518,13 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > int ok, found_key = 0; > struct passwd *pw; > struct stat st; >- int status, devnull, p[2], i; >+ int status, devnull, p[2], i, argc; > pid_t pid; > char *username, errmsg[512]; >+ char *cp, *command = NULL, **argv = NULL; >+ char *authorized_keys_command_path; >+ char *key_fp = NULL, *keytext = NULL; >+ size_t keytextlen; > > if (options.authorized_keys_command == NULL || > options.authorized_keys_command[0] != '/') >@@ -544,12 +548,49 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > > temporarily_use_uid(pw); > >- if (stat(options.authorized_keys_command, &st) < 0) { >+ if (strstr(options.authorized_keys_command, "%f") != NULL) { >+ key_fp = key_fingerprint(key, options.fingerprint_hash, >+ SSH_FP_DEFAULT); >+ if (key_fp == NULL) { >+ error("AuthorizedKeysCommand %%f parameter expansion failed"); >+ goto out; >+ } >+ } >+ if (strstr(options.authorized_keys_command, "%k") != NULL) { >+ if (key_to_base64(key, &keytext, &keytextlen) != 0) { >+ error("AuthorizedKeysCommand %%k parameter expansion failed"); >+ goto out; >+ } >+ } >+ command = cp = percent_expand(options.authorized_keys_command, >+ "u", user_pw->pw_name, "h", user_pw->pw_dir, "t", key_ssh_name(key), >+ "f", key_fp == NULL ? "" : key_fp, >+ "k", keytext == NULL ? "" : keytext, (char *)NULL); >+ i = 0; >+ argc = 10; >+ while (cp != NULL) { >+ if (argv == NULL || i == argc - 1) { >+ argc *= 2; >+ argv = xrealloc(argv, argc, sizeof(argv[0])); >+ } >+ argv[i++] = strdelim(&cp); >+ argv[i] = NULL; >+ debug3("AuthorizedKeysCommand argv[%d]: %s", >+ i - 1, argv[i - 1]); >+ } >+ if (argv[1] == NULL) { >+ argv[1] = user_pw->pw_name; >+ argv[2] = NULL; >+ debug3("AuthorizedKeysCommand argv[1]: %s", argv[1]); >+ } >+ authorized_keys_command_path = argv[0]; >+ >+ if (stat(authorized_keys_command_path, &st) < 0) { > error("Could not stat AuthorizedKeysCommand \"%s\": %s", >- options.authorized_keys_command, strerror(errno)); >+ authorized_keys_command_path, strerror(errno)); > goto out; > } >- if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0, >+ if (auth_secure_path(authorized_keys_command_path, &st, NULL, 0, > errmsg, sizeof(errmsg)) != 0) { > error("Unsafe AuthorizedKeysCommand: %s", errmsg); > goto out; >@@ -560,8 +601,8 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > goto out; > } > >- debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"", >- options.authorized_keys_command, user_pw->pw_name, pw->pw_name); >+ debug3("Running AuthorizedKeysCommand: \"%s ...\" as \"%s\"", >+ authorized_keys_command_path, pw->pw_name); > > /* > * Don't want to call this in the child, where it can fatal() and >@@ -574,6 +615,12 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > error("%s: fork: %s", __func__, strerror(errno)); > close(p[0]); > close(p[1]); >+ free(argv); >+ free(command); >+ if (keytext != NULL) >+ free(keytext); >+ if (key_fp != NULL) >+ free(key_fp); > return 0; > case 0: /* child */ > for (i = 0; i < NSIG; i++) >@@ -609,11 +656,10 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > _exit(1); > } > >- execl(options.authorized_keys_command, >- options.authorized_keys_command, user_pw->pw_name, NULL); >+ execv(authorized_keys_command_path, argv); > > error("AuthorizedKeysCommand %s exec failed: %s", >- options.authorized_keys_command, strerror(errno)); >+ authorized_keys_command_path, strerror(errno)); > _exit(127); > default: /* parent */ > break; >@@ -631,7 +677,7 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > ; > goto out; > } >- ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); >+ ok = check_authkeys_file(f, authorized_keys_command_path, key, pw); > fclose(f); > > while (waitpid(pid, &status, 0) == -1) { >@@ -642,15 +688,23 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) > } > if (WIFSIGNALED(status)) { > error("AuthorizedKeysCommand %s exited on signal %d", >- options.authorized_keys_command, WTERMSIG(status)); >+ authorized_keys_command_path, WTERMSIG(status)); > goto out; > } else if (WEXITSTATUS(status) != 0) { > error("AuthorizedKeysCommand %s returned status %d", >- options.authorized_keys_command, WEXITSTATUS(status)); >+ authorized_keys_command_path, WEXITSTATUS(status)); > goto out; > } > found_key = ok; > out: >+ if (argv != NULL) >+ free(argv); >+ if (command != NULL) >+ free(command); >+ if (keytext != NULL) >+ free(keytext); >+ if (key_fp != NULL) >+ free(key_fp); > restore_uid(); > return found_key; > } >diff --git a/key.h b/key.h >index de78657..ab3a8d7 100644 >--- a/key.h >+++ b/key.h >@@ -61,6 +61,7 @@ typedef struct sshkey Key; > #define key_dump_ec_point sshkey_dump_ec_point > #define key_dump_ec_key sshkey_dump_ec_key > #define key_fingerprint sshkey_fingerprint >+#define key_to_base64 sshkey_to_base64 > #endif > > void key_add_private(Key *); >diff --git a/sshd_config.5 b/sshd_config.5 >index cec2a02..4202815 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -232,7 +232,14 @@ of a single authentication method is sufficient. > Specifies a program to be used to look up the user's public keys. > The program must be owned by root and not writable by group or others. > It will be invoked with a single argument of the username >-being authenticated, and should produce on standard output zero or >+being authenticated, unless any of the following tokens, which are >+expanded at runtime, are provided: %% is replaced by a literal '%', >+%u is replaced by the username being authenticated, %h is replaced >+by the home directory of the user being authenticated, %t is replaced >+with the key type offered for authentication, %f is replaced with the >+fingerprint of the key, and %k is replaced with the key being offered >+for authentication. >+The program should produce on standard output zero or > more lines of authorized_keys output (see AUTHORIZED_KEYS in > .Xr sshd 8 ) . > If a key supplied by AuthorizedKeysCommand does not successfully authenticate >diff --git a/sshkey.c b/sshkey.c >index 9b37c9a..bbf5290 100644 >--- a/sshkey.c >+++ b/sshkey.c >@@ -1463,6 +1463,79 @@ sshkey_write(const struct sshkey *key, FILE *f) > return ret; > } > >+int >+sshkey_to_base64(const struct sshkey *key, char **blobp, size_t *lenp) >+{ >+ int ret = SSH_ERR_INTERNAL_ERROR; >+ struct sshbuf *b = NULL, *bb = NULL; >+ char *uu = NULL; >+ size_t len; >+ >+ if (lenp != NULL) >+ *lenp = 0; >+ if (blobp != NULL) >+ *blobp = NULL; >+ >+ if (sshkey_is_cert(key)) { >+ if (key->cert == NULL) >+ return SSH_ERR_EXPECTED_CERT; >+ if (sshbuf_len(key->cert->certblob) == 0) >+ return SSH_ERR_KEY_LACKS_CERTBLOB; >+ } >+ if ((b = sshbuf_new()) == NULL) >+ return SSH_ERR_ALLOC_FAIL; >+ switch (key->type) { >+#ifdef WITH_OPENSSL >+ case KEY_DSA: >+ case KEY_DSA_CERT_V00: >+ case KEY_DSA_CERT: >+ case KEY_ECDSA: >+ case KEY_ECDSA_CERT: >+ case KEY_RSA: >+ case KEY_RSA_CERT_V00: >+ case KEY_RSA_CERT: >+#endif /* WITH_OPENSSL */ >+ case KEY_ED25519: >+ case KEY_ED25519_CERT: >+ if ((bb = sshbuf_new()) == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ if ((ret = sshkey_to_blob_buf(key, bb)) != 0) >+ goto out; >+ if ((uu = sshbuf_dtob64(bb)) == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0) >+ goto out; >+ break; >+ default: >+ ret = SSH_ERR_KEY_TYPE_UNKNOWN; >+ goto out; >+ } >+ len = sshbuf_len(b); >+ if (lenp != NULL) >+ *lenp = len; >+ if (blobp != NULL) { >+ if ((*blobp = malloc(len + 1)) == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ memset(*blobp, 0, len + 1); >+ memcpy(*blobp, sshbuf_ptr(b), len); >+ } >+ ret = 0; >+ out: >+ if (b != NULL) >+ sshbuf_free(b); >+ if (bb != NULL) >+ sshbuf_free(bb); >+ if (uu != NULL) >+ free(uu); >+ return ret; >+} >+ > const char * > sshkey_cert_type(const struct sshkey *k) > { >diff --git a/sshkey.h b/sshkey.h >index 4554b09..2f97bd0 100644 >--- a/sshkey.h >+++ b/sshkey.h >@@ -165,6 +165,8 @@ int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); > int sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *); > int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); > >+int sshkey_to_base64(const struct sshkey *, char **, size_t *); >+ > int sshkey_sign(const struct sshkey *, u_char **, size_t *, > const u_char *, size_t, u_int); > int sshkey_verify(const struct sshkey *, const u_char *, size_t, >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2081
:
2412
|
2416
|
2417
|
2438
|
2477
|
2478
|
2479
|
2522
|
2544
|
2545
|
2546
|
2549
|
2556
|
2557