tomcat-11: fix mediator version and license
[oi-userland.git] / components / network / hpn-ssh / patches / 0019-PubKeyPlugin-support.patch
blob425d4ac0d985f001fcaa15800a66f5f7c8ac2cf3
1 This adds the PubKeyPlugin directive and associated code from
2 SunSSH, allowing an in-process shared library to be called
3 into to check public keys for authentication.
5 --- hpn-ssh-hpn-18.4.2/auth2-pubkey.c.orig
6 +++ hpn-ssh-hpn-18.4.2/auth2-pubkey.c
7 @@ -23,6 +23,11 @@
8 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
9 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11 +/*
12 + * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
13 + * Copyright 2015 Joyent, Inc.
14 + * Use is subject to license terms.
15 + */
17 #include "includes.h"
19 @@ -41,11 +46,13 @@
20 #include <time.h>
21 #include <unistd.h>
22 #include <limits.h>
23 +#include <dlfcn.h>
25 #include "xmalloc.h"
26 #include "ssh.h"
27 #include "ssh2.h"
28 #include "packet.h"
29 +#include "digest.h"
30 #include "kex.h"
31 #include "sshbuf.h"
32 #include "log.h"
33 @@ -84,6 +91,15 @@
34 return ret;
37 +static const char *RSA_SYM_NAME = "sshd_user_rsa_key_allowed";
38 +static const char *ECDSA_SYM_NAME = "sshd_user_ecdsa_key_allowed";
39 +typedef int (*RSA_SYM)(struct passwd *, RSA *, const char *);
40 +typedef int (*ECDSA_SYM)(struct passwd *, EC_KEY *, const char *);
42 +static const char *UNIV_SYM_NAME = "sshd_user_key_allowed";
43 +typedef int (*UNIV_SYM)(struct passwd *, const char *,
44 + const u_char *, size_t);
46 static int
47 userauth_pubkey(struct ssh *ssh, const char *method)
49 @@ -745,6 +761,124 @@
50 return found_key;
53 +/**
54 + * Checks whether or not access is allowed based on a plugin specified
55 + * in sshd_config (PubKeyPlugin).
56 + *
57 + * Note that this expects a symbol in the loaded library that takes
58 + * the current user (pwd entry), the current RSA key and it's fingerprint.
59 + * The symbol is expected to return 1 on success and 0 on failure.
60 + *
61 + * While we could optimize this code to dlopen once in the process' lifetime,
62 + * sshd is already a slow beast, so this is really not a concern.
63 + * The overhead is basically a rounding error compared to everything else, and
64 + * it keeps this code minimally invasive.
65 + */
66 +static int
67 +user_key_allowed_from_plugin(struct passwd *pw, struct sshkey *key)
69 + RSA_SYM rsa_sym = NULL;
70 + ECDSA_SYM ecdsa_sym = NULL;
71 + UNIV_SYM univ_sym = NULL;
72 + char *fp = NULL;
73 + char *argfp = NULL;
74 + void *handle = NULL;
75 + int success = 0;
77 + if (options.pubkey_plugin == NULL || pw == NULL || key == NULL ||
78 + (key->type != KEY_RSA &&
79 + key->type != KEY_DSA && key->type != KEY_ECDSA))
80 + return success;
82 + handle = dlopen(options.pubkey_plugin, RTLD_NOW);
83 + if (handle == NULL) {
84 + debug("Unable to open library %s: %s", options.pubkey_plugin,
85 + dlerror());
86 + goto out;
87 + }
89 + /*
90 + * If we have the new-style universal symbol for checking keys, use
91 + * that instead of the old-style per-key-type symbols.
92 + */
93 + univ_sym = (UNIV_SYM)dlsym(handle, UNIV_SYM_NAME);
94 + if (univ_sym != NULL) {
95 + u_char *blob;
96 + const char *type = sshkey_type(key);
97 + size_t len = 0;
98 + if (sshkey_to_blob(key, &blob, &len) != 0) {
99 + debug("failed to convert key to rfc4253 format");
100 + goto out;
102 + debug("Invoking %s from %s", UNIV_SYM_NAME,
103 + options.pubkey_plugin);
104 + success = (*univ_sym)(pw, type, blob, len);
105 + debug("pubkeyplugin returned: %d", success);
106 + goto out;
109 + /* Otherwise, continue with the old-style fingerprint symbols. */
110 + fp = sshkey_fingerprint(key, SSH_DIGEST_MD5, SSH_FP_HEX);
111 + if (fp == NULL) {
112 + debug("failed to generate fingerprint");
113 + goto out;
115 + if (strncmp(fp, "MD5:", 4) != 0) {
116 + debug("fingerprint not in MD5:hex format");
117 + goto out;
119 + /* give the plugin the string without leading MD5: */
120 + argfp = fp + 4;
122 + switch (key->type) {
123 + case KEY_RSA:
124 + rsa_sym = (RSA_SYM)dlsym(handle, RSA_SYM_NAME);
125 + if (rsa_sym == NULL) {
126 + debug("Unable to resolve symbol %s: %s", RSA_SYM_NAME,
127 + dlerror());
128 + goto out;
130 + debug2("Invoking %s from %s", RSA_SYM_NAME,
131 + options.pubkey_plugin);
132 + success = (*rsa_sym)(pw, key->rsa, argfp);
133 + break;
134 + case KEY_ECDSA:
135 + ecdsa_sym = (ECDSA_SYM)dlsym(handle, ECDSA_SYM_NAME);
136 + if (ecdsa_sym == NULL) {
137 + debug("Unable to resolve symbol %s: %s", ECDSA_SYM_NAME,
138 + dlerror());
139 + goto out;
141 + debug2("Invoking %s from %s", ECDSA_SYM_NAME,
142 + options.pubkey_plugin);
143 + success = (*ecdsa_sym)(pw, key->ecdsa, argfp);
144 + break;
145 + default:
146 + debug2("user_key_plugins only support RSA and ECDSA keys");
149 + debug("pubkeyplugin returned: %d", success);
151 +out:
152 + if (handle != NULL) {
153 + dlclose(handle);
154 + ecdsa_sym = NULL;
155 + rsa_sym = NULL;
156 + univ_sym = NULL;
157 + handle = NULL;
160 + if (success)
161 + verbose("Found matching %s key: %s", sshkey_type(key), fp);
163 + if (fp != NULL) {
164 + free(fp);
165 + fp = NULL;
168 + return success;
172 * Check whether key authenticates and authorises the user.
174 @@ -796,6 +930,10 @@
175 sshauthopt_free(opts);
176 opts = NULL;
178 + success = user_key_allowed_from_plugin(pw, key);
179 + if (success > 0)
180 + goto out;
182 if ((success = user_key_command_allowed2(pw, key, remote_ip,
183 remote_host, conn_id, rdomain, &opts)) != 0)
184 goto out;
185 --- hpn-ssh-hpn-18.4.2/servconf.c.orig
186 +++ hpn-ssh-hpn-18.4.2/servconf.c
187 @@ -214,6 +214,7 @@
189 options->pam_service_per_authmethod = 1;
190 #endif
191 + options->pubkey_plugin = NULL;
194 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
195 @@ -573,6 +574,7 @@
196 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
197 sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
198 sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
199 + sPubKeyPlugin,
200 sDeprecated, sIgnore, sUnsupported
201 } ServerOpCodes;
203 @@ -743,6 +745,7 @@
204 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
205 { "rdomain", sRDomain, SSHCFG_ALL },
206 { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
207 + { "pubkeyplugin", sPubKeyPlugin, SSHCFG_ALL },
208 { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
209 { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
210 { "channeltimeout", sChannelTimeout, SSHCFG_ALL },
211 @@ -2705,6 +2708,18 @@
213 break;
215 + case sPubKeyPlugin:
216 + /*
217 + * Can't use parse_filename, as we need to support plain
218 + * names which dlopen will find on our lib path.
219 + */
220 + arg = strdelim(&str);
221 + if (!arg || *arg == '\0')
222 + fatal("%s line %d: missing file name.",
223 + filename, linenum);
224 + options->pubkey_plugin = xstrdup(arg);
225 + break;
227 case sDeprecated:
228 case sIgnore:
229 case sUnsupported:
230 --- hpn-ssh-hpn-18.4.2/servconf.h.orig
231 +++ hpn-ssh-hpn-18.4.2/servconf.h
232 @@ -239,6 +239,7 @@
234 int fingerprint_hash;
235 int expose_userauth_info;
236 + char *pubkey_plugin;
237 u_int64_t timing_secret;
238 char *sk_provider;
239 int required_rsa_size; /* minimum size of RSA keys */