summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/ssh')
-rw-r--r--usr/src/cmd/ssh/Makefile2
-rw-r--r--usr/src/cmd/ssh/include/key.h15
-rw-r--r--usr/src/cmd/ssh/include/servconf.h1
-rw-r--r--usr/src/cmd/ssh/libssh/common/canohost.c35
-rw-r--r--usr/src/cmd/ssh/libssh/common/key.c17
-rw-r--r--usr/src/cmd/ssh/sftp-server/Makefile2
-rw-r--r--usr/src/cmd/ssh/sftp/Makefile2
-rw-r--r--usr/src/cmd/ssh/ssh-add/Makefile2
-rw-r--r--usr/src/cmd/ssh/ssh-agent/Makefile2
-rw-r--r--usr/src/cmd/ssh/ssh-keygen/Makefile2
-rw-r--r--usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c277
-rw-r--r--usr/src/cmd/ssh/ssh-keyscan/Makefile2
-rw-r--r--usr/src/cmd/ssh/ssh-keysign/Makefile2
-rw-r--r--usr/src/cmd/ssh/ssh/Makefile2
-rw-r--r--usr/src/cmd/ssh/sshd/Makefile2
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-pubkey.c109
-rw-r--r--usr/src/cmd/ssh/sshd/servconf.c9
-rw-r--r--usr/src/cmd/ssh/sshd/sshlogin.c3
18 files changed, 380 insertions, 106 deletions
diff --git a/usr/src/cmd/ssh/Makefile b/usr/src/cmd/ssh/Makefile
index a36a9fb762..62f30b3f36 100644
--- a/usr/src/cmd/ssh/Makefile
+++ b/usr/src/cmd/ssh/Makefile
@@ -77,7 +77,7 @@ check: $(CHECKHDRS)
_msg:
$(RM) $(POFILE)
$(TOUCH) $(POFILE)
- $(MAKE) $(POFILE) XGETTEXT=/usr/bin/gxgettext
+ $(MAKE) $(POFILE) XGETTEXT=$(GNUXGETTEXT)
$(CP) $(POFILE) $(MSGFILE)
$(CP) $(MSGFILE) $(MSGDOMAIN)
diff --git a/usr/src/cmd/ssh/include/key.h b/usr/src/cmd/ssh/include/key.h
index 862b2d81d4..ec4993a9c1 100644
--- a/usr/src/cmd/ssh/include/key.h
+++ b/usr/src/cmd/ssh/include/key.h
@@ -39,11 +39,17 @@ extern "C" {
typedef struct Key Key;
enum types {
- KEY_RSA1,
- KEY_RSA,
- KEY_DSA,
+ KEY_RSA1,
+ KEY_RSA,
+ KEY_DSA,
+ KEY_ECDSA,
+ KEY_RSA_CERT,
+ KEY_DSA_CERT,
+ KEY_ECDSA_CERT,
+ KEY_RSA_CERT_V00,
+ KEY_DSA_CERT_V00,
KEY_NULL,
- KEY_UNSPEC
+ KEY_UNSPEC
};
enum fp_type {
SSH_FP_SHA1,
@@ -87,6 +93,7 @@ int key_names_valid2(const char *);
int key_sign(Key *, u_char **, u_int *, u_char *, u_int);
int key_verify(Key *, u_char *, u_int, u_char *, u_int);
+int key_type_plain(int type);
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/ssh/include/servconf.h b/usr/src/cmd/ssh/include/servconf.h
index a66c6415cb..9a32544c2a 100644
--- a/usr/src/cmd/ssh/include/servconf.h
+++ b/usr/src/cmd/ssh/include/servconf.h
@@ -167,6 +167,7 @@ typedef struct {
char *pre_userauth_hook;
char *pam_service_prefix;
char *pam_service_name;
+ char *pubkey_plugin;
} ServerOptions;
diff --git a/usr/src/cmd/ssh/libssh/common/canohost.c b/usr/src/cmd/ssh/libssh/common/canohost.c
index 2d427b9e8d..87aab396cf 100644
--- a/usr/src/cmd/ssh/libssh/common/canohost.c
+++ b/usr/src/cmd/ssh/libssh/common/canohost.c
@@ -73,9 +73,6 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
-#if 0
- log("Could not reverse map address %.100s.", ntop);
-#endif
return xstrdup(ntop);
}
@@ -206,36 +203,6 @@ get_socket_address(int socket, int remote, int flags)
return (xstrdup(result));
}
-#if 0
-static char *
-get_socket_address(int socket, int remote, int flags)
-{
- struct sockaddr_storage addr;
- socklen_t addrlen;
- char ntop[NI_MAXHOST];
-
- /* Get IP address of client. */
- addrlen = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
-
- if (remote) {
- if (getpeername(socket, (struct sockaddr *)&addr, &addrlen)
- < 0)
- return NULL;
- } else {
- if (getsockname(socket, (struct sockaddr *)&addr, &addrlen)
- < 0)
- return NULL;
- }
- /* Get the address in ascii. */
- if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
- NULL, 0, flags) != 0) {
- error("get_socket_ipaddr: getnameinfo %d failed", flags);
- return NULL;
- }
- return xstrdup(ntop);
-}
-#endif
char *
get_peer_ipaddr(int socket)
@@ -388,4 +355,4 @@ inet_ntop_native(int af, const void *src, char *dst, size_t size)
}
return (result);
-}
+}
diff --git a/usr/src/cmd/ssh/libssh/common/key.c b/usr/src/cmd/ssh/libssh/common/key.c
index f648d3b640..8ee2583d93 100644
--- a/usr/src/cmd/ssh/libssh/common/key.c
+++ b/usr/src/cmd/ssh/libssh/common/key.c
@@ -874,3 +874,20 @@ key_demote(Key *k)
return (pk);
}
+
+int
+key_type_plain(int type)
+{
+ switch (type) {
+ case KEY_RSA_CERT_V00:
+ case KEY_RSA_CERT:
+ return KEY_RSA;
+ case KEY_DSA_CERT_V00:
+ case KEY_DSA_CERT:
+ return KEY_DSA;
+ case KEY_ECDSA_CERT:
+ return KEY_ECDSA;
+ default:
+ return type;
+ }
+}
diff --git a/usr/src/cmd/ssh/sftp-server/Makefile b/usr/src/cmd/ssh/sftp-server/Makefile
index c2bdf26c1e..f49dde54ee 100644
--- a/usr/src/cmd/ssh/sftp-server/Makefile
+++ b/usr/src/cmd/ssh/sftp-server/Makefile
@@ -31,7 +31,7 @@ SRCS = $(OBJS:.o=.c)
include ../../Makefile.cmd
include ../Makefile.ssh-common
-LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lcrypto
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto
POFILE_DIR = ..
diff --git a/usr/src/cmd/ssh/sftp/Makefile b/usr/src/cmd/ssh/sftp/Makefile
index 8bd8bb4ac3..f3c0ea7a75 100644
--- a/usr/src/cmd/ssh/sftp/Makefile
+++ b/usr/src/cmd/ssh/sftp/Makefile
@@ -35,7 +35,7 @@ SRCS = $(OBJS:.o=.c)
include ../../Makefile.cmd
include ../Makefile.ssh-common
-LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lcrypto -ltecla
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto -ltecla
POFILE_DIR = ..
diff --git a/usr/src/cmd/ssh/ssh-add/Makefile b/usr/src/cmd/ssh/ssh-add/Makefile
index 1fb132f741..3235839e06 100644
--- a/usr/src/cmd/ssh/ssh-add/Makefile
+++ b/usr/src/cmd/ssh/ssh-add/Makefile
@@ -32,7 +32,7 @@ SRCS = $(OBJS:.o=.c)
include ../../Makefile.cmd
include ../Makefile.ssh-common
-LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lcrypto
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto
POFILE_DIR= ..
diff --git a/usr/src/cmd/ssh/ssh-agent/Makefile b/usr/src/cmd/ssh/ssh-agent/Makefile
index 3d4a366c17..ab2e1eb49d 100644
--- a/usr/src/cmd/ssh/ssh-agent/Makefile
+++ b/usr/src/cmd/ssh/ssh-agent/Makefile
@@ -32,7 +32,7 @@ SRCS = $(OBJS:.o=.c)
include ../../Makefile.cmd
include ../Makefile.ssh-common
-LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lcrypto
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lsunw_crypto
POFILE_DIR= ..
diff --git a/usr/src/cmd/ssh/ssh-keygen/Makefile b/usr/src/cmd/ssh/ssh-keygen/Makefile
index f92c437045..0c90716768 100644
--- a/usr/src/cmd/ssh/ssh-keygen/Makefile
+++ b/usr/src/cmd/ssh/ssh-keygen/Makefile
@@ -32,7 +32,7 @@ SRCS = $(OBJS:.o=.c)
include ../../Makefile.cmd
include ../Makefile.ssh-common
-LDLIBS += $(SSH_COMMON_LDLIBS) -lcrypto -lsocket
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsunw_crypto -lsocket
POFILE_DIR= ..
diff --git a/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c b/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c
index ebad79b0f8..c79e76ae36 100644
--- a/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c
+++ b/usr/src/cmd/ssh/ssh-keygen/ssh-keygen.c
@@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* $OpenBSD: ssh-keygen.c,v 1.160 2007/01/21 01:41:54 stevesk Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.205 2011/01/11 06:13:10 djm Exp $ */
#include "includes.h"
#include <openssl/evp.h>
@@ -76,9 +76,14 @@ char *identity_new_passphrase = NULL;
/* This is set to the new comment if given on the command line. */
char *identity_comment = NULL;
-/* Dump public key file in format used by real and the original SSH 2 */
-int convert_to_ssh2 = 0;
-int convert_from_ssh2 = 0;
+/* Conversion to/from various formats */
+int convert_to = 0;
+int convert_from = 0;
+enum {
+ FMT_RFC4716,
+ FMT_PKCS8,
+ FMT_PEM
+} convert_format = FMT_RFC4716;
int print_public = 0;
char *key_type_name = NULL;
@@ -154,41 +159,105 @@ load_identity(char *filename)
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
static void
-do_convert_to_ssh2(struct passwd *pw)
+do_convert_to_ssh2(struct passwd *pw, Key *k)
{
- Key *k;
u_int len;
u_char *blob;
- struct stat st;
+ char comment[61];
- if (!have_identity)
- ask_filename(pw, gettext("Enter file in which the key is"));
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
+ if (key_to_blob(k, &blob, &len) <= 0) {
+ fprintf(stderr, "key_to_blob failed\n");
exit(1);
}
+ /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
+ snprintf(comment, sizeof(comment),
+ "%u-bit %s, converted by %s@%s from OpenSSH",
+ key_size(k), key_type(k),
+ pw->pw_name, hostname);
+
+ fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
+ fprintf(stdout, "Comment: \"%s\"\n", comment);
+ dump_base64(stdout, blob, len);
+ fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
+ key_free(k);
+ xfree(blob);
+ exit(0);
+}
+
+static void
+do_convert_to_pkcs8(Key *k)
+{
+ switch (key_type_plain(k->type)) {
+ case KEY_RSA:
+ if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
+ fatal("PEM_write_RSA_PUBKEY failed");
+ break;
+ case KEY_DSA:
+ if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
+ fatal("PEM_write_DSA_PUBKEY failed");
+ break;
+ default:
+ fatal("%s: unsupported key type %s", __func__, key_type(k));
+ }
+ exit(0);
+}
+
+static void
+do_convert_to_pem(Key *k)
+{
+ switch (key_type_plain(k->type)) {
+ case KEY_RSA:
+ if (!PEM_write_RSAPublicKey(stdout, k->rsa))
+ fatal("PEM_write_RSAPublicKey failed");
+ break;
+ case KEY_DSA:
+ if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
+ fatal("PEM_write_DSAPublicKey failed");
+ break;
+ default:
+ fatal("%s: unsupported key type %s", __func__, key_type(k));
+ }
+ exit(0);
+}
+
+static void
+do_convert_to(struct passwd *pw)
+{
+ Key *k;
+ struct stat st;
+
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
if ((k = key_load_public(identity_file, NULL)) == NULL) {
if ((k = load_identity(identity_file)) == NULL) {
- fprintf(stderr, gettext("load failed\n"));
+ fprintf(stderr, "load failed\n");
exit(1);
}
}
- if (key_to_blob(k, &blob, &len) <= 0) {
- fprintf(stderr, gettext("key_to_blob failed\n"));
+ if (k->type == KEY_RSA1) {
+ fprintf(stderr, "version 1 keys are not supported\n");
exit(1);
}
- fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
- fprintf(stdout, gettext(
- "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n"),
- key_size(k), key_type(k),
- pw->pw_name, hostname);
- dump_base64(stdout, blob, len);
- fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
- key_free(k);
- xfree(blob);
+
+ switch (convert_format) {
+ case FMT_RFC4716:
+ do_convert_to_ssh2(pw, k);
+ break;
+ case FMT_PKCS8:
+ do_convert_to_pkcs8(k);
+ break;
+ case FMT_PEM:
+ do_convert_to_pem(k);
+ break;
+ default:
+ fatal("%s: unknown key format %d", __func__, convert_format);
+ }
exit(0);
}
+
static void
buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
{
@@ -327,24 +396,16 @@ get_line(FILE *fp, char *line, size_t len)
}
static void
-do_convert_from_ssh2(struct passwd *pw)
+do_convert_from_ssh2(struct passwd *pw, Key **k, int *private)
{
- Key *k;
int blen;
u_int len;
char line[1024];
u_char blob[8096];
char encoded[8096];
- struct stat st;
- int escaped = 0, private = 0, ok;
+ int escaped = 0;
FILE *fp;
- if (!have_identity)
- ask_filename(pw, gettext("Enter file in which the key is"));
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
fp = fopen(identity_file, "r");
if (fp == NULL) {
perror(identity_file);
@@ -357,7 +418,7 @@ do_convert_from_ssh2(struct passwd *pw)
if (strncmp(line, "----", 4) == 0 ||
strstr(line, ": ") != NULL) {
if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
- private = 1;
+ *private = 1;
if (strstr(line, " END ") != NULL) {
break;
}
@@ -382,26 +443,117 @@ do_convert_from_ssh2(struct passwd *pw)
fprintf(stderr, gettext("uudecode failed.\n"));
exit(1);
}
- k = private ?
+ *k = *private ?
do_convert_private_ssh2_from_blob(blob, blen) :
key_from_blob(blob, blen);
- if (k == NULL) {
+ if (*k == NULL) {
fprintf(stderr, gettext("decode blob failed.\n"));
exit(1);
}
- ok = private ?
- (k->type == KEY_DSA ?
- PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
- PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :
- key_write(k, stdout);
+ fclose(fp);
+}
+
+static void
+do_convert_from_pkcs8(Key **k, int *private)
+{
+ EVP_PKEY *pubkey;
+ FILE *fp;
+
+ if ((fp = fopen(identity_file, "r")) == NULL)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+ if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
+ fatal("%s: %s is not a recognised public key format", __func__,
+ identity_file);
+ }
+ fclose(fp);
+ switch (EVP_PKEY_type(pubkey->type)) {
+ case EVP_PKEY_RSA:
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_RSA;
+ (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
+ break;
+ case EVP_PKEY_DSA:
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_DSA;
+ (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
+ break;
+ default:
+ fatal("%s: unsupported pubkey type %d", __func__,
+ EVP_PKEY_type(pubkey->type));
+ }
+ EVP_PKEY_free(pubkey);
+ return;
+}
+
+static void
+do_convert_from_pem(Key **k, int *private)
+{
+ FILE *fp;
+ RSA *rsa;
+
+ if ((fp = fopen(identity_file, "r")) == NULL)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+ if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
+ *k = key_new(KEY_UNSPEC);
+ (*k)->type = KEY_RSA;
+ (*k)->rsa = rsa;
+ fclose(fp);
+ return;
+ }
+ fatal("%s: unrecognised raw private key format", __func__);
+}
+
+static void
+do_convert_from(struct passwd *pw)
+{
+ Key *k = NULL;
+ int private = 0, ok = 0;
+ struct stat st;
+
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0)
+ fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
+
+ switch (convert_format) {
+ case FMT_RFC4716:
+ do_convert_from_ssh2(pw, &k, &private);
+ break;
+ case FMT_PKCS8:
+ do_convert_from_pkcs8(&k, &private);
+ break;
+ case FMT_PEM:
+ do_convert_from_pem(&k, &private);
+ break;
+ default:
+ fatal("%s: unknown key format %d", __func__, convert_format);
+ }
+
+ if (!private)
+ ok = key_write(k, stdout);
+ if (ok)
+ fprintf(stdout, "\n");
+ else {
+ switch (k->type) {
+ case KEY_DSA:
+ ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
+ NULL, 0, NULL, NULL);
+ break;
+ case KEY_RSA:
+ ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
+ NULL, 0, NULL, NULL);
+ break;
+ default:
+ fatal("%s: unsupported key type %s", __func__,
+ key_type(k));
+ }
+ }
+
if (!ok) {
- fprintf(stderr, gettext("key write failed"));
+ fprintf(stderr, "key write failed\n");
exit(1);
}
key_free(k);
- if (!private)
- fprintf(stdout, "\n");
- fclose(fp);
exit(0);
}
@@ -917,12 +1069,13 @@ usage(void)
" -B Show bubblebabble digest of key file.\n"
" -c Change comment in private and public key files.\n"
" -C comment Provide new comment.\n"
- " -e Convert OpenSSH to IETF SECSH key file.\n"
+ " -e Convert OpenSSH to foreign format key file.\n"
" -f filename Filename of the key file.\n"
" -F hostname Find hostname in known hosts file.\n"
" -H Hash names in known_hosts file.\n"
- " -i Convert IETF SECSH to OpenSSH key file.\n"
+ " -i Convert foreign format to OpenSSH key file.\n"
" -l Show fingerprint of key file.\n"
+ " -m key_fmt Conversion format for -e/-i (PEM|PKCS8|RFC4716).\n"
" -N phrase Provide new passphrase.\n"
" -p Change passphrase of private key file.\n"
" -P phrase Provide old passphrase.\n"
@@ -974,7 +1127,7 @@ main(int argc, char **argv)
exit(1);
}
-#define GETOPT_ARGS "BcdeHilpqxXyb:C:f:F:N:P:R:t:"
+#define GETOPT_ARGS "BcdeHilpqxXyb:C:f:F:m:N:P:R:t:"
while ((opt = getopt(argc, argv, GETOPT_ARGS)) != -1) {
switch (opt) {
@@ -1002,6 +1155,22 @@ main(int argc, char **argv)
case 'B':
print_bubblebabble = 1;
break;
+ case 'm':
+ if (strcasecmp(optarg, "RFC4716") == 0 ||
+ strcasecmp(optarg, "ssh2") == 0) {
+ convert_format = FMT_RFC4716;
+ break;
+ }
+ if (strcasecmp(optarg, "PKCS8") == 0) {
+ convert_format = FMT_PKCS8;
+ break;
+ }
+ if (strcasecmp(optarg, "PEM") == 0) {
+ convert_format = FMT_PEM;
+ break;
+ }
+ fatal("Unsupported conversion format \"%s\"", optarg);
+ /*NOTREACHED*/
case 'p':
change_passphrase = 1;
break;
@@ -1027,12 +1196,12 @@ main(int argc, char **argv)
case 'e':
case 'x':
/* export key */
- convert_to_ssh2 = 1;
+ convert_to = 1;
break;
case 'i':
case 'X':
/* import key */
- convert_from_ssh2 = 1;
+ convert_from = 1;
break;
case 'y':
print_public = 1;
@@ -1064,10 +1233,10 @@ main(int argc, char **argv)
do_change_passphrase(pw);
if (change_comment)
do_change_comment(pw);
- if (convert_to_ssh2)
- do_convert_to_ssh2(pw);
- if (convert_from_ssh2)
- do_convert_from_ssh2(pw);
+ if (convert_to)
+ do_convert_to(pw);
+ if (convert_from)
+ do_convert_from(pw);
if (print_public)
do_print_public(pw);
diff --git a/usr/src/cmd/ssh/ssh-keyscan/Makefile b/usr/src/cmd/ssh/ssh-keyscan/Makefile
index 9e2fd17160..90428880a3 100644
--- a/usr/src/cmd/ssh/ssh-keyscan/Makefile
+++ b/usr/src/cmd/ssh/ssh-keyscan/Makefile
@@ -32,7 +32,7 @@ SRCS = $(OBJS:.o=.c)
include ../../Makefile.cmd
include ../Makefile.ssh-common
-LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lnsl -lz -lcrypto
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lnsl -lz -lsunw_crypto
POFILE_DIR= ..
diff --git a/usr/src/cmd/ssh/ssh-keysign/Makefile b/usr/src/cmd/ssh/ssh-keysign/Makefile
index e31ae681a1..649935a050 100644
--- a/usr/src/cmd/ssh/ssh-keysign/Makefile
+++ b/usr/src/cmd/ssh/ssh-keysign/Makefile
@@ -36,7 +36,7 @@ include ../Makefile.ssh-common
FILEMODE= 04555
-LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lnsl -lz -lcrypto
+LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket -lnsl -lz -lsunw_crypto
POFILE_DIR= ..
diff --git a/usr/src/cmd/ssh/ssh/Makefile b/usr/src/cmd/ssh/ssh/Makefile
index 7bdd4f6be5..2d77334497 100644
--- a/usr/src/cmd/ssh/ssh/Makefile
+++ b/usr/src/cmd/ssh/ssh/Makefile
@@ -40,7 +40,7 @@ include ../Makefile.ssh-common
LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket \
-lnsl \
-lz \
- -lcrypto \
+ -lsunw_crypto \
-lgss
POFILE_DIR= ..
diff --git a/usr/src/cmd/ssh/sshd/Makefile b/usr/src/cmd/ssh/sshd/Makefile
index a52e9b1cc8..4c82633347 100644
--- a/usr/src/cmd/ssh/sshd/Makefile
+++ b/usr/src/cmd/ssh/sshd/Makefile
@@ -75,7 +75,7 @@ LDLIBS += $(SSH_COMMON_LDLIBS) -lsocket \
-lpam \
-lbsm \
-lwrap \
- -lcrypto \
+ -lsunw_crypto \
-lgss \
-lcontract
MAPFILES = $(MAPFILE.INT) $(MAPFILE.NGB)
diff --git a/usr/src/cmd/ssh/sshd/auth2-pubkey.c b/usr/src/cmd/ssh/sshd/auth2-pubkey.c
index 658634c195..c1c5f540e4 100644
--- a/usr/src/cmd/ssh/sshd/auth2-pubkey.c
+++ b/usr/src/cmd/ssh/sshd/auth2-pubkey.c
@@ -26,6 +26,8 @@
* Use is subject to license terms.
*/
+#include <dlfcn.h>
+
#include "includes.h"
RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
@@ -54,6 +56,13 @@ extern ServerOptions options;
extern u_char *session_id2;
extern int session_id2_len;
+/* global plugin function requirements */
+static const char *RSA_SYM_NAME = "sshd_user_rsa_key_allowed";
+static const char *DSA_SYM_NAME = "sshd_user_rsa_key_allowed";
+typedef int (*RSA_SYM)(struct passwd *, RSA *, const char *);
+typedef int (*DSA_SYM)(struct passwd *, DSA *, const char *);
+
+
static void
userauth_pubkey(Authctxt *authctxt)
{
@@ -309,7 +318,98 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
return found_key;
}
-/* check whether given key is in .ssh/authorized_keys* */
+/**
+ * Checks whether or not access is allowed based on a plugin specified
+ * in sshd_config (PubKeyPlugin).
+ *
+ * Note that this expects a symbol in the loaded library that takes
+ * the current user (pwd entry), the current RSA key and it's fingerprint.
+ * The symbol is expected to return 1 on success and 0 on failure.
+ *
+ * While we could optimize this code to dlopen once in the process' lifetime,
+ * sshd is already a slow beast, so this is really not a concern.
+ * The overhead is basically a rounding error compared to everything else, and
+ * it keeps this code minimally invasive.
+ */
+static int
+user_key_allowed_from_plugin(struct passwd *pw, Key *key)
+{
+ RSA_SYM rsa_sym = NULL;
+ DSA_SYM dsa_sym = NULL;
+ char *fp = NULL;
+ void *handle = NULL;
+ int success = 0;
+
+ if (options.pubkey_plugin == NULL || pw == NULL || key == NULL ||
+ (key->type != KEY_RSA && key->type != KEY_RSA1 &&
+ key->type != KEY_DSA && key->type != KEY_ECDSA))
+ return success;
+
+ handle = dlopen(options.pubkey_plugin, RTLD_NOW);
+ if ((handle == NULL)) {
+ debug("Unable to open library %s: %s", options.pubkey_plugin,
+ dlerror());
+ goto out;
+ }
+
+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ if (fp == NULL) {
+ debug("failed to generate fingerprint");
+ goto out;
+ }
+
+ switch (key->type) {
+ case KEY_RSA1:
+ case KEY_RSA:
+ rsa_sym = (RSA_SYM)dlsym(handle, RSA_SYM_NAME);
+ if (rsa_sym == NULL) {
+ debug("Unable to resolve symbol %s: %s", RSA_SYM_NAME,
+ dlerror());
+ goto out;
+ }
+ debug2("Invoking %s from %s", RSA_SYM_NAME,
+ options.pubkey_plugin);
+ success = (*rsa_sym)(pw, key->rsa, fp);
+ break;
+ case KEY_DSA:
+ case KEY_ECDSA:
+ dsa_sym = (DSA_SYM)dlsym(handle, RSA_SYM_NAME);
+ if (dsa_sym == NULL) {
+ debug("Unable to resolve symbol %s: %s", DSA_SYM_NAME,
+ dlerror());
+ goto out;
+ }
+ debug2("Invoking %s from %s", DSA_SYM_NAME,
+ options.pubkey_plugin);
+ success = (*dsa_sym)(pw, key->dsa, fp);
+ break;
+ default:
+ debug2("user_key_plugins only support RSA keys");
+ }
+
+ debug("sshd_plugin returned: %d", success);
+
+out:
+ if (handle != NULL) {
+ dlclose(handle);
+ dsa_sym = NULL;
+ rsa_sym = NULL;
+ handle = NULL;
+ }
+
+ if (success)
+ verbose("Found matching %s key: %s", key_type(key), fp);
+
+ if (fp != NULL) {
+ xfree(fp);
+ fp = NULL;
+ }
+
+ return success;
+}
+
+
+/* check whether given key is in .ssh/authorized_keys or a plugin */
int
user_key_allowed(struct passwd *pw, Key *key)
{
@@ -329,6 +429,13 @@ user_key_allowed(struct passwd *pw, Key *key)
file = authorized_keys_file2(pw);
success = user_key_allowed2(pw, key, file);
xfree(file);
+
+ if (success)
+ return success;
+
+ /* try from a plugin */
+ success = user_key_allowed_from_plugin(pw, key);
+
return success;
}
diff --git a/usr/src/cmd/ssh/sshd/servconf.c b/usr/src/cmd/ssh/sshd/servconf.c
index 516466bbc1..16f1dcecf7 100644
--- a/usr/src/cmd/ssh/sshd/servconf.c
+++ b/usr/src/cmd/ssh/sshd/servconf.c
@@ -155,6 +155,7 @@ initialize_server_options(ServerOptions *options)
options->pre_userauth_hook = NULL;
options->pam_service_name = NULL;
options->pam_service_prefix = NULL;
+ options->pubkey_plugin = NULL;
}
#ifdef HAVE_DEFOPEN
@@ -419,13 +420,14 @@ typedef enum {
sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
- sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
+ sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
sMaxAuthTries, sMaxAuthTriesLog, sUsePrivilegeSeparation,
sLookupClientHostnames, sUseOpenSSLEngine, sChrootDirectory,
sPreUserauthHook, sMatch, sPAMServicePrefix, sPAMServiceName,
+ sMaxStartups, sPubKeyPlugin,
sDeprecated
} ServerOpCodes;
@@ -532,6 +534,7 @@ static struct {
{ "match", sMatch, SSHCFG_ALL },
{ "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
{ "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
+ { "pubkeyplugin", sPubKeyPlugin, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -1356,6 +1359,10 @@ parse_flag:
options->pam_service_name = xstrdup(arg);
break;
+ case sPubKeyPlugin:
+ charptr = &options->pubkey_plugin;
+ goto parse_filename;
+
default:
fatal("%s line %d: Missing handler for opcode %s (%d)",
filename, linenum, arg, opcode);
diff --git a/usr/src/cmd/ssh/sshd/sshlogin.c b/usr/src/cmd/ssh/sshd/sshlogin.c
index c21877355c..c2bd3bacb7 100644
--- a/usr/src/cmd/ssh/sshd/sshlogin.c
+++ b/usr/src/cmd/ssh/sshd/sshlogin.c
@@ -101,8 +101,7 @@ record_login(pid_t pid, const char *ttyname, const char *progname,
fatal_cleanup();
}
}
- remote_name_or_ip = get_remote_name_or_ip(utmp_len,
- options.verify_reverse_mapping);
+ remote_name_or_ip = get_remote_ipaddr();
initialized = 1;
}