diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Makefile.in | 5 | ||||
-rw-r--r-- | authfile.c | 4 | ||||
-rw-r--r-- | authfile.h | 3 | ||||
-rw-r--r-- | pathnames.h | 7 | ||||
-rw-r--r-- | ssh-keysign.8 | 58 | ||||
-rw-r--r-- | ssh-keysign.c | 204 | ||||
-rw-r--r-- | ssh.c | 21 | ||||
-rw-r--r-- | sshconnect.c | 8 | ||||
-rw-r--r-- | sshconnect.h | 15 | ||||
-rw-r--r-- | sshconnect1.c | 12 | ||||
-rw-r--r-- | sshconnect2.c | 95 |
12 files changed, 403 insertions, 36 deletions
@@ -16,6 +16,11 @@ | |||
16 | - deraadt@cvs.openbsd.org 2002/05/22 23:18:25 | 16 | - deraadt@cvs.openbsd.org 2002/05/22 23:18:25 |
17 | [ssh.c sshd.c] | 17 | [ssh.c sshd.c] |
18 | spelling; abishoff@arc.nasa.gov | 18 | spelling; abishoff@arc.nasa.gov |
19 | - markus@cvs.openbsd.org 2002/05/23 19:24:30 | ||
20 | [authfile.c authfile.h pathnames.h ssh.c sshconnect.c sshconnect.h | ||
21 | sshconnect1.c sshconnect2.c ssh-keysign.8 ssh-keysign.c Makefile.in] | ||
22 | add /usr/libexec/ssh-keysign: a setuid helper program for hostbased | ||
23 | authentication in protocol v2 (needs to access the hostkeys). | ||
19 | 24 | ||
20 | 20020604 | 25 | 20020604 |
21 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed | 26 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed |
@@ -700,4 +705,4 @@ | |||
700 | - (stevesk) entropy.c: typo in debug message | 705 | - (stevesk) entropy.c: typo in debug message |
701 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ | 706 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ |
702 | 707 | ||
703 | $Id: ChangeLog,v 1.2148 2002/06/06 19:51:58 mouring Exp $ | 708 | $Id: ChangeLog,v 1.2149 2002/06/06 19:57:33 mouring Exp $ |
diff --git a/Makefile.in b/Makefile.in index e3b145150..ec235f827 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.208 2002/05/13 04:12:05 djm Exp $ | 1 | # $Id: Makefile.in,v 1.209 2002/06/06 19:57:33 mouring Exp $ |
2 | 2 | ||
3 | # uncomment if you run a non bourne compatable shell. Ie. csh | 3 | # uncomment if you run a non bourne compatable shell. Ie. csh |
4 | #SHELL = @SH@ | 4 | #SHELL = @SH@ |
@@ -125,6 +125,9 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o | |||
125 | ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o | 125 | ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o |
126 | $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) | 126 | $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
127 | 127 | ||
128 | ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o | ||
129 | $(LD) -o $@ ssh-keysign.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) | ||
130 | |||
128 | ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o | 131 | ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |
129 | $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) | 132 | $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
130 | 133 | ||
diff --git a/authfile.c b/authfile.c index de8b1022e..6d936de56 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include "includes.h" | 38 | #include "includes.h" |
39 | RCSID("$OpenBSD: authfile.c,v 1.48 2002/02/28 15:46:33 markus Exp $"); | 39 | RCSID("$OpenBSD: authfile.c,v 1.49 2002/05/23 19:24:30 markus Exp $"); |
40 | 40 | ||
41 | #include <openssl/err.h> | 41 | #include <openssl/err.h> |
42 | #include <openssl/evp.h> | 42 | #include <openssl/evp.h> |
@@ -421,7 +421,7 @@ fail: | |||
421 | return NULL; | 421 | return NULL; |
422 | } | 422 | } |
423 | 423 | ||
424 | static Key * | 424 | Key * |
425 | key_load_private_pem(int fd, int type, const char *passphrase, | 425 | key_load_private_pem(int fd, int type, const char *passphrase, |
426 | char **commentp) | 426 | char **commentp) |
427 | { | 427 | { |
diff --git a/authfile.h b/authfile.h index c614ca12c..7f92701ec 100644 --- a/authfile.h +++ b/authfile.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfile.h,v 1.9 2002/03/04 17:27:39 stevesk Exp $ */ | 1 | /* $OpenBSD: authfile.h,v 1.10 2002/05/23 19:24:30 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -20,5 +20,6 @@ Key *key_load_public(const char *, char **); | |||
20 | Key *key_load_public_type(int, const char *, char **); | 20 | Key *key_load_public_type(int, const char *, char **); |
21 | Key *key_load_private(const char *, const char *, char **); | 21 | Key *key_load_private(const char *, const char *, char **); |
22 | Key *key_load_private_type(int, const char *, const char *, char **); | 22 | Key *key_load_private_type(int, const char *, const char *, char **); |
23 | Key *key_load_private_pem(int, int, const char *, char **); | ||
23 | 24 | ||
24 | #endif | 25 | #endif |
diff --git a/pathnames.h b/pathnames.h index 691293c33..89e22c77a 100644 --- a/pathnames.h +++ b/pathnames.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: pathnames.h,v 1.12 2002/03/19 03:03:43 stevesk Exp $ */ | 1 | /* $OpenBSD: pathnames.h,v 1.13 2002/05/23 19:24:30 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -120,6 +120,11 @@ | |||
120 | #define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" | 120 | #define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" |
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | /* Location of ssh-keysign for hostbased authentication */ | ||
124 | #ifndef _PATH_SSH_KEY_SIGN | ||
125 | #define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" | ||
126 | #endif | ||
127 | |||
123 | /* xauth for X11 forwarding */ | 128 | /* xauth for X11 forwarding */ |
124 | #ifndef _PATH_XAUTH | 129 | #ifndef _PATH_XAUTH |
125 | #define _PATH_XAUTH "/usr/X11R6/bin/xauth" | 130 | #define _PATH_XAUTH "/usr/X11R6/bin/xauth" |
diff --git a/ssh-keysign.8 b/ssh-keysign.8 new file mode 100644 index 000000000..fccbd7c27 --- /dev/null +++ b/ssh-keysign.8 | |||
@@ -0,0 +1,58 @@ | |||
1 | .\" $OpenBSD: ssh-keysign.8,v 1.1 2002/05/25 08:16:59 markus Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 2002 Markus Friedl. All rights reserved. | ||
4 | .\" | ||
5 | .\" Redistribution and use in source and binary forms, with or without | ||
6 | .\" modification, are permitted provided that the following conditions | ||
7 | .\" are met: | ||
8 | .\" 1. Redistributions of source code must retain the above copyright | ||
9 | .\" notice, this list of conditions and the following disclaimer. | ||
10 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
11 | .\" notice, this list of conditions and the following disclaimer in the | ||
12 | .\" documentation and/or other materials provided with the distribution. | ||
13 | .\" | ||
14 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
15 | .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
16 | .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
17 | .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
20 | .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
21 | .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | .\" | ||
25 | .Dd May 24, 2002 | ||
26 | .Dt SSH-KEYSIGN 8 | ||
27 | .Os | ||
28 | .Sh NAME | ||
29 | .Nm ssh-keysign | ||
30 | .Nd ssh helper program for hostbased authentication | ||
31 | .Sh SYNOPSIS | ||
32 | .Nm ssh-keysign | ||
33 | .Sh DESCRIPTION | ||
34 | .Nm | ||
35 | is used by | ||
36 | .Xr ssh 1 | ||
37 | to access the local host keys during hostbased authentication with | ||
38 | SSH protocol version 2. | ||
39 | Since the host keys are readable only by root | ||
40 | .Nm | ||
41 | must be setuid root. | ||
42 | .Nm | ||
43 | is not intended to be invoked by the user, but from | ||
44 | .Xr ssh 1 . | ||
45 | See | ||
46 | .Xr ssh 1 | ||
47 | and | ||
48 | .Xr sshd 8 | ||
49 | for more information about hostbased authentication. | ||
50 | .Sh SEE ALSO | ||
51 | .Xr ssh 1 , | ||
52 | .Xr sshd 8 | ||
53 | .Sh AUTHORS | ||
54 | Markus Friedl <markus@openbsd.org> | ||
55 | .Sh HISTORY | ||
56 | .Nm | ||
57 | first appeared in | ||
58 | .Ox 3.2 . | ||
diff --git a/ssh-keysign.c b/ssh-keysign.c new file mode 100644 index 000000000..da630708d --- /dev/null +++ b/ssh-keysign.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2002 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | #include "includes.h" | ||
25 | RCSID("$OpenBSD: ssh-keysign.c,v 1.2 2002/05/31 10:30:33 markus Exp $"); | ||
26 | |||
27 | #include <openssl/evp.h> | ||
28 | |||
29 | #include "log.h" | ||
30 | #include "key.h" | ||
31 | #include "ssh2.h" | ||
32 | #include "misc.h" | ||
33 | #include "xmalloc.h" | ||
34 | #include "buffer.h" | ||
35 | #include "bufaux.h" | ||
36 | #include "authfile.h" | ||
37 | #include "msg.h" | ||
38 | #include "canohost.h" | ||
39 | #include "pathnames.h" | ||
40 | |||
41 | static int | ||
42 | valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, | ||
43 | u_int datalen) | ||
44 | { | ||
45 | Buffer b; | ||
46 | Key *key; | ||
47 | u_char *pkblob; | ||
48 | u_int blen, len; | ||
49 | char *pkalg, *p; | ||
50 | int pktype, fail; | ||
51 | |||
52 | fail = 0; | ||
53 | |||
54 | buffer_init(&b); | ||
55 | buffer_append(&b, data, datalen); | ||
56 | |||
57 | /* session id */ | ||
58 | buffer_skip_string(&b); | ||
59 | if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) | ||
60 | fail++; | ||
61 | |||
62 | /* server user */ | ||
63 | buffer_skip_string(&b); | ||
64 | |||
65 | /* service */ | ||
66 | p = buffer_get_string(&b, NULL); | ||
67 | if (strcmp("ssh-connection", p) != 0) | ||
68 | fail++; | ||
69 | xfree(p); | ||
70 | |||
71 | /* method */ | ||
72 | p = buffer_get_string(&b, NULL); | ||
73 | if (strcmp("hostbased", p) != 0) | ||
74 | fail++; | ||
75 | xfree(p); | ||
76 | |||
77 | /* pubkey */ | ||
78 | pkalg = buffer_get_string(&b, NULL); | ||
79 | pkblob = buffer_get_string(&b, &blen); | ||
80 | |||
81 | pktype = key_type_from_name(pkalg); | ||
82 | if (pktype == KEY_UNSPEC) | ||
83 | fail++; | ||
84 | else if ((key = key_from_blob(pkblob, blen)) == NULL) | ||
85 | fail++; | ||
86 | else if (key->type != pktype) | ||
87 | fail++; | ||
88 | xfree(pkalg); | ||
89 | xfree(pkblob); | ||
90 | |||
91 | /* client host name, handle trailing dot */ | ||
92 | p = buffer_get_string(&b, &len); | ||
93 | debug2("valid_request: check expect chost %s got %s", host, p); | ||
94 | if (strlen(host) != len - 1) | ||
95 | fail++; | ||
96 | else if (p[len - 1] != '.') | ||
97 | fail++; | ||
98 | else if (strncasecmp(host, p, len - 1) != 0) | ||
99 | fail++; | ||
100 | xfree(p); | ||
101 | |||
102 | /* local user */ | ||
103 | p = buffer_get_string(&b, NULL); | ||
104 | |||
105 | if (strcmp(pw->pw_name, p) != 0) | ||
106 | fail++; | ||
107 | xfree(p); | ||
108 | |||
109 | /* end of message */ | ||
110 | if (buffer_len(&b) != 0) | ||
111 | fail++; | ||
112 | |||
113 | debug3("valid_request: fail %d", fail); | ||
114 | |||
115 | if (fail && key != NULL) | ||
116 | key_free(key); | ||
117 | else | ||
118 | *ret = key; | ||
119 | |||
120 | return (fail ? -1 : 0); | ||
121 | } | ||
122 | |||
123 | int | ||
124 | main(int argc, char **argv) | ||
125 | { | ||
126 | Buffer b; | ||
127 | Key *keys[2], *key; | ||
128 | struct passwd *pw; | ||
129 | int key_fd[2], i, found, version = 2, fd; | ||
130 | u_char *signature, *data; | ||
131 | char *host; | ||
132 | u_int slen, dlen; | ||
133 | |||
134 | key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); | ||
135 | key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); | ||
136 | |||
137 | seteuid(getuid()); | ||
138 | setuid(getuid()); | ||
139 | |||
140 | #ifdef DEBUG_SSH_KEYSIGN | ||
141 | log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); | ||
142 | #endif | ||
143 | |||
144 | if (key_fd[0] == -1 && key_fd[1] == -1) | ||
145 | fatal("could not open any host key"); | ||
146 | |||
147 | if ((pw = getpwuid(getuid())) == NULL) | ||
148 | fatal("getpwuid failed"); | ||
149 | pw = pwcopy(pw); | ||
150 | |||
151 | SSLeay_add_all_algorithms(); | ||
152 | |||
153 | found = 0; | ||
154 | for (i = 0; i < 2; i++) { | ||
155 | keys[i] = NULL; | ||
156 | if (key_fd[i] == -1) | ||
157 | continue; | ||
158 | keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC, | ||
159 | NULL, NULL); | ||
160 | close(key_fd[i]); | ||
161 | if (keys[i] != NULL) | ||
162 | found = 1; | ||
163 | } | ||
164 | if (!found) | ||
165 | fatal("no hostkey found"); | ||
166 | |||
167 | buffer_init(&b); | ||
168 | if (msg_recv(STDIN_FILENO, &b) < 0) | ||
169 | fatal("msg_recv failed"); | ||
170 | if (buffer_get_char(&b) != version) | ||
171 | fatal("bad version"); | ||
172 | fd = buffer_get_int(&b); | ||
173 | if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) | ||
174 | fatal("bad fd"); | ||
175 | if ((host = get_local_name(fd)) == NULL) | ||
176 | fatal("cannot get sockname for fd"); | ||
177 | |||
178 | data = buffer_get_string(&b, &dlen); | ||
179 | if (valid_request(pw, host, &key, data, dlen) < 0) | ||
180 | fatal("not a valid request"); | ||
181 | xfree(data); | ||
182 | xfree(host); | ||
183 | |||
184 | found = 0; | ||
185 | for (i = 0; i < 2; i++) { | ||
186 | if (keys[i] != NULL && | ||
187 | key_equal(key, keys[i])) { | ||
188 | found = 1; | ||
189 | break; | ||
190 | } | ||
191 | } | ||
192 | if (!found) | ||
193 | fatal("no matching hostkey found"); | ||
194 | |||
195 | if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) | ||
196 | fatal("key_sign failed"); | ||
197 | |||
198 | /* send reply */ | ||
199 | buffer_clear(&b); | ||
200 | buffer_put_string(&b, signature, slen); | ||
201 | msg_send(STDOUT_FILENO, version, &b); | ||
202 | |||
203 | return (0); | ||
204 | } | ||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.172 2002/05/22 23:18:25 deraadt Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.173 2002/05/23 19:24:30 markus Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -132,10 +132,7 @@ char *host; | |||
132 | struct sockaddr_storage hostaddr; | 132 | struct sockaddr_storage hostaddr; |
133 | 133 | ||
134 | /* Private host keys. */ | 134 | /* Private host keys. */ |
135 | struct { | 135 | Sensitive sensitive_data; |
136 | Key **keys; | ||
137 | int nkeys; | ||
138 | } sensitive_data; | ||
139 | 136 | ||
140 | /* Original real UID. */ | 137 | /* Original real UID. */ |
141 | uid_t original_real_uid; | 138 | uid_t original_real_uid; |
@@ -689,6 +686,7 @@ again: | |||
689 | */ | 686 | */ |
690 | sensitive_data.nkeys = 0; | 687 | sensitive_data.nkeys = 0; |
691 | sensitive_data.keys = NULL; | 688 | sensitive_data.keys = NULL; |
689 | sensitive_data.external_keysign = 0; | ||
692 | if (!cerr && (options.rhosts_rsa_authentication || | 690 | if (!cerr && (options.rhosts_rsa_authentication || |
693 | options.hostbased_authentication)) { | 691 | options.hostbased_authentication)) { |
694 | sensitive_data.nkeys = 3; | 692 | sensitive_data.nkeys = 3; |
@@ -699,6 +697,16 @@ again: | |||
699 | _PATH_HOST_DSA_KEY_FILE, "", NULL); | 697 | _PATH_HOST_DSA_KEY_FILE, "", NULL); |
700 | sensitive_data.keys[2] = key_load_private_type(KEY_RSA, | 698 | sensitive_data.keys[2] = key_load_private_type(KEY_RSA, |
701 | _PATH_HOST_RSA_KEY_FILE, "", NULL); | 699 | _PATH_HOST_RSA_KEY_FILE, "", NULL); |
700 | |||
701 | if (sensitive_data.keys[0] == NULL && | ||
702 | sensitive_data.keys[1] == NULL && | ||
703 | sensitive_data.keys[2] == NULL) { | ||
704 | sensitive_data.keys[1] = key_load_public( | ||
705 | _PATH_HOST_DSA_KEY_FILE, NULL); | ||
706 | sensitive_data.keys[2] = key_load_public( | ||
707 | _PATH_HOST_RSA_KEY_FILE, NULL); | ||
708 | sensitive_data.external_keysign = 1; | ||
709 | } | ||
702 | } | 710 | } |
703 | /* | 711 | /* |
704 | * Get rid of any extra privileges that we may have. We will no | 712 | * Get rid of any extra privileges that we may have. We will no |
@@ -758,8 +766,7 @@ again: | |||
758 | signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ | 766 | signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ |
759 | 767 | ||
760 | /* Log into the remote system. This never returns if the login fails. */ | 768 | /* Log into the remote system. This never returns if the login fails. */ |
761 | ssh_login(sensitive_data.keys, sensitive_data.nkeys, | 769 | ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw); |
762 | host, (struct sockaddr *)&hostaddr, pw); | ||
763 | 770 | ||
764 | /* We no longer need the private host keys. Clear them now. */ | 771 | /* We no longer need the private host keys. Clear them now. */ |
765 | if (sensitive_data.nkeys != 0) { | 772 | if (sensitive_data.nkeys != 0) { |
diff --git a/sshconnect.c b/sshconnect.c index 5bb50e0e9..7af0b9a80 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.119 2002/01/21 15:13:51 markus Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.120 2002/05/23 19:24:30 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -844,7 +844,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
844 | * This function does not require super-user privileges. | 844 | * This function does not require super-user privileges. |
845 | */ | 845 | */ |
846 | void | 846 | void |
847 | ssh_login(Key **keys, int nkeys, const char *orighost, | 847 | ssh_login(Sensitive *sensitive, const char *orighost, |
848 | struct sockaddr *hostaddr, struct passwd *pw) | 848 | struct sockaddr *hostaddr, struct passwd *pw) |
849 | { | 849 | { |
850 | char *host, *cp; | 850 | char *host, *cp; |
@@ -869,10 +869,10 @@ ssh_login(Key **keys, int nkeys, const char *orighost, | |||
869 | /* authenticate user */ | 869 | /* authenticate user */ |
870 | if (compat20) { | 870 | if (compat20) { |
871 | ssh_kex2(host, hostaddr); | 871 | ssh_kex2(host, hostaddr); |
872 | ssh_userauth2(local_user, server_user, host, keys, nkeys); | 872 | ssh_userauth2(local_user, server_user, host, sensitive); |
873 | } else { | 873 | } else { |
874 | ssh_kex(host, hostaddr); | 874 | ssh_kex(host, hostaddr); |
875 | ssh_userauth1(local_user, server_user, host, keys, nkeys); | 875 | ssh_userauth1(local_user, server_user, host, sensitive); |
876 | } | 876 | } |
877 | } | 877 | } |
878 | 878 | ||
diff --git a/sshconnect.h b/sshconnect.h index b475adde0..ad34ee64a 100644 --- a/sshconnect.h +++ b/sshconnect.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.h,v 1.13 2001/10/08 19:05:05 markus Exp $ */ | 1 | /* $OpenBSD: sshconnect.h,v 1.14 2002/05/23 19:24:30 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -26,20 +26,27 @@ | |||
26 | #ifndef SSHCONNECT_H | 26 | #ifndef SSHCONNECT_H |
27 | #define SSHCONNECT_H | 27 | #define SSHCONNECT_H |
28 | 28 | ||
29 | typedef struct Sensitive Sensitive; | ||
30 | struct Sensitive { | ||
31 | Key **keys; | ||
32 | int nkeys; | ||
33 | int external_keysign; | ||
34 | }; | ||
35 | |||
29 | int | 36 | int |
30 | ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, | 37 | ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, |
31 | int, struct passwd *, const char *); | 38 | int, struct passwd *, const char *); |
32 | 39 | ||
33 | void | 40 | void |
34 | ssh_login(Key **, int, const char *, struct sockaddr *, struct passwd *); | 41 | ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *); |
35 | 42 | ||
36 | int verify_host_key(char *, struct sockaddr *, Key *); | 43 | int verify_host_key(char *, struct sockaddr *, Key *); |
37 | 44 | ||
38 | void ssh_kex(char *, struct sockaddr *); | 45 | void ssh_kex(char *, struct sockaddr *); |
39 | void ssh_kex2(char *, struct sockaddr *); | 46 | void ssh_kex2(char *, struct sockaddr *); |
40 | 47 | ||
41 | void ssh_userauth1(const char *, const char *, char *, Key **, int); | 48 | void ssh_userauth1(const char *, const char *, char *, Sensitive *); |
42 | void ssh_userauth2(const char *, const char *, char *, Key **, int); | 49 | void ssh_userauth2(const char *, const char *, char *, Sensitive *); |
43 | 50 | ||
44 | void ssh_put_password(char *); | 51 | void ssh_put_password(char *); |
45 | 52 | ||
diff --git a/sshconnect1.c b/sshconnect1.c index d2024a2b7..e28b7fc72 100644 --- a/sshconnect1.c +++ b/sshconnect1.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect1.c,v 1.50 2002/04/21 16:25:06 stevesk Exp $"); | 16 | RCSID("$OpenBSD: sshconnect1.c,v 1.51 2002/05/23 19:24:30 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | #include <openssl/md5.h> | 19 | #include <openssl/md5.h> |
@@ -1138,7 +1138,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) | |||
1138 | */ | 1138 | */ |
1139 | void | 1139 | void |
1140 | ssh_userauth1(const char *local_user, const char *server_user, char *host, | 1140 | ssh_userauth1(const char *local_user, const char *server_user, char *host, |
1141 | Key **keys, int nkeys) | 1141 | Sensitive *sensitive) |
1142 | { | 1142 | { |
1143 | #ifdef KRB5 | 1143 | #ifdef KRB5 |
1144 | krb5_context context = NULL; | 1144 | krb5_context context = NULL; |
@@ -1224,9 +1224,11 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, | |||
1224 | */ | 1224 | */ |
1225 | if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && | 1225 | if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && |
1226 | options.rhosts_rsa_authentication) { | 1226 | options.rhosts_rsa_authentication) { |
1227 | for (i = 0; i < nkeys; i++) { | 1227 | for (i = 0; i < sensitive->nkeys; i++) { |
1228 | if (keys[i] != NULL && keys[i]->type == KEY_RSA1 && | 1228 | if (sensitive->keys[i] != NULL && |
1229 | try_rhosts_rsa_authentication(local_user, keys[i])) | 1229 | sensitive->keys[i]->type == KEY_RSA1 && |
1230 | try_rhosts_rsa_authentication(local_user, | ||
1231 | sensitive->keys[i])) | ||
1230 | goto success; | 1232 | goto success; |
1231 | } | 1233 | } |
1232 | } | 1234 | } |
diff --git a/sshconnect2.c b/sshconnect2.c index 1ee92ab0d..2736856fa 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: sshconnect2.c,v 1.99 2002/03/26 15:58:46 markus Exp $"); | 26 | RCSID("$OpenBSD: sshconnect2.c,v 1.100 2002/05/23 19:24:30 markus Exp $"); |
27 | 27 | ||
28 | #include "ssh.h" | 28 | #include "ssh.h" |
29 | #include "ssh2.h" | 29 | #include "ssh2.h" |
@@ -45,6 +45,8 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.99 2002/03/26 15:58:46 markus Exp $"); | |||
45 | #include "match.h" | 45 | #include "match.h" |
46 | #include "dispatch.h" | 46 | #include "dispatch.h" |
47 | #include "canohost.h" | 47 | #include "canohost.h" |
48 | #include "msg.h" | ||
49 | #include "pathnames.h" | ||
48 | 50 | ||
49 | /* import */ | 51 | /* import */ |
50 | extern char *client_version_string; | 52 | extern char *client_version_string; |
@@ -154,8 +156,7 @@ struct Authctxt { | |||
154 | int last_key_hint; | 156 | int last_key_hint; |
155 | AuthenticationConnection *agent; | 157 | AuthenticationConnection *agent; |
156 | /* hostbased */ | 158 | /* hostbased */ |
157 | Key **keys; | 159 | Sensitive *sensitive; |
158 | int nkeys; | ||
159 | /* kbd-interactive */ | 160 | /* kbd-interactive */ |
160 | int info_req_seen; | 161 | int info_req_seen; |
161 | }; | 162 | }; |
@@ -215,7 +216,7 @@ Authmethod authmethods[] = { | |||
215 | 216 | ||
216 | void | 217 | void |
217 | ssh_userauth2(const char *local_user, const char *server_user, char *host, | 218 | ssh_userauth2(const char *local_user, const char *server_user, char *host, |
218 | Key **keys, int nkeys) | 219 | Sensitive *sensitive) |
219 | { | 220 | { |
220 | Authctxt authctxt; | 221 | Authctxt authctxt; |
221 | int type; | 222 | int type; |
@@ -255,8 +256,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, | |||
255 | authctxt.success = 0; | 256 | authctxt.success = 0; |
256 | authctxt.method = authmethod_lookup("none"); | 257 | authctxt.method = authmethod_lookup("none"); |
257 | authctxt.authlist = NULL; | 258 | authctxt.authlist = NULL; |
258 | authctxt.keys = keys; | 259 | authctxt.sensitive = sensitive; |
259 | authctxt.nkeys = nkeys; | ||
260 | authctxt.info_req_seen = 0; | 260 | authctxt.info_req_seen = 0; |
261 | if (authctxt.method == NULL) | 261 | if (authctxt.method == NULL) |
262 | fatal("ssh_userauth2: internal error: cannot send userauth none request"); | 262 | fatal("ssh_userauth2: internal error: cannot send userauth none request"); |
@@ -893,6 +893,75 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) | |||
893 | packet_send(); | 893 | packet_send(); |
894 | } | 894 | } |
895 | 895 | ||
896 | static int | ||
897 | ssh_keysign( | ||
898 | Key *key, | ||
899 | u_char **sigp, u_int *lenp, | ||
900 | u_char *data, u_int datalen) | ||
901 | { | ||
902 | Buffer b; | ||
903 | pid_t pid; | ||
904 | int to[2], from[2], status, version = 1; | ||
905 | |||
906 | debug("ssh_keysign called"); | ||
907 | |||
908 | if (fflush(stdout) != 0) | ||
909 | error("ssh_keysign: fflush: %s", strerror(errno)); | ||
910 | if (pipe(to) < 0) { | ||
911 | error("ssh_keysign: pipe: %s", strerror(errno)); | ||
912 | return -1; | ||
913 | } | ||
914 | if (pipe(from) < 0) { | ||
915 | error("ssh_keysign: pipe: %s", strerror(errno)); | ||
916 | return -1; | ||
917 | } | ||
918 | if ((pid = fork()) < 0) { | ||
919 | error("ssh_keysign: fork: %s", strerror(errno)); | ||
920 | return -1; | ||
921 | } | ||
922 | if (pid == 0) { | ||
923 | seteuid(getuid()); | ||
924 | setuid(getuid()); | ||
925 | close(from[0]); | ||
926 | if (dup2(from[1], STDOUT_FILENO) < 0) | ||
927 | fatal("ssh_keysign: dup2: %s", strerror(errno)); | ||
928 | close(to[1]); | ||
929 | if (dup2(to[0], STDIN_FILENO) < 0) | ||
930 | fatal("ssh_keysign: dup2: %s", strerror(errno)); | ||
931 | execlp(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); | ||
932 | fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, | ||
933 | strerror(errno)); | ||
934 | } | ||
935 | close(from[1]); | ||
936 | close(to[0]); | ||
937 | |||
938 | buffer_init(&b); | ||
939 | buffer_put_string(&b, data, datalen); | ||
940 | msg_send(to[1], version, &b); | ||
941 | |||
942 | if (msg_recv(from[0], &b) < 0) { | ||
943 | debug("ssh_keysign: no reply"); | ||
944 | buffer_clear(&b); | ||
945 | return -1; | ||
946 | } | ||
947 | if (buffer_get_char(&b) != version) { | ||
948 | debug("ssh_keysign: bad version"); | ||
949 | buffer_clear(&b); | ||
950 | return -1; | ||
951 | } | ||
952 | *sigp = buffer_get_string(&b, lenp); | ||
953 | buffer_clear(&b); | ||
954 | |||
955 | close(from[0]); | ||
956 | close(to[1]); | ||
957 | |||
958 | while (waitpid(pid, &status, 0) < 0) | ||
959 | if (errno != EINTR) | ||
960 | break; | ||
961 | |||
962 | return 0; | ||
963 | } | ||
964 | |||
896 | /* | 965 | /* |
897 | * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign | 966 | * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign |
898 | * will be setuid-root and the sbit can be removed from /usr/bin/ssh. | 967 | * will be setuid-root and the sbit can be removed from /usr/bin/ssh. |
@@ -901,6 +970,7 @@ int | |||
901 | userauth_hostbased(Authctxt *authctxt) | 970 | userauth_hostbased(Authctxt *authctxt) |
902 | { | 971 | { |
903 | Key *private = NULL; | 972 | Key *private = NULL; |
973 | Sensitive *sensitive = authctxt->sensitive; | ||
904 | Buffer b; | 974 | Buffer b; |
905 | u_char *signature, *blob; | 975 | u_char *signature, *blob; |
906 | char *chost, *pkalg, *p; | 976 | char *chost, *pkalg, *p; |
@@ -909,12 +979,12 @@ userauth_hostbased(Authctxt *authctxt) | |||
909 | int ok, i, len, found = 0; | 979 | int ok, i, len, found = 0; |
910 | 980 | ||
911 | /* check for a useful key */ | 981 | /* check for a useful key */ |
912 | for (i = 0; i < authctxt->nkeys; i++) { | 982 | for (i = 0; i < sensitive->nkeys; i++) { |
913 | private = authctxt->keys[i]; | 983 | private = sensitive->keys[i]; |
914 | if (private && private->type != KEY_RSA1) { | 984 | if (private && private->type != KEY_RSA1) { |
915 | found = 1; | 985 | found = 1; |
916 | /* we take and free the key */ | 986 | /* we take and free the key */ |
917 | authctxt->keys[i] = NULL; | 987 | sensitive->keys[i] = NULL; |
918 | break; | 988 | break; |
919 | } | 989 | } |
920 | } | 990 | } |
@@ -956,7 +1026,12 @@ userauth_hostbased(Authctxt *authctxt) | |||
956 | #ifdef DEBUG_PK | 1026 | #ifdef DEBUG_PK |
957 | buffer_dump(&b); | 1027 | buffer_dump(&b); |
958 | #endif | 1028 | #endif |
959 | ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); | 1029 | if (sensitive->external_keysign) |
1030 | ok = ssh_keysign(private, &signature, &slen, | ||
1031 | buffer_ptr(&b), buffer_len(&b)); | ||
1032 | else | ||
1033 | ok = key_sign(private, &signature, &slen, | ||
1034 | buffer_ptr(&b), buffer_len(&b)); | ||
960 | key_free(private); | 1035 | key_free(private); |
961 | buffer_free(&b); | 1036 | buffer_free(&b); |
962 | if (ok != 0) { | 1037 | if (ok != 0) { |