diff options
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | sshconnect1.c | 774 |
2 files changed, 1 insertions, 775 deletions
diff --git a/Makefile.in b/Makefile.in index f6625734a..a7a6239c0 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -95,7 +95,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ | |||
95 | platform-pledge.o platform-tracing.o | 95 | platform-pledge.o platform-tracing.o |
96 | 96 | ||
97 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ | 97 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ |
98 | sshconnect.o sshconnect1.o sshconnect2.o mux.o | 98 | sshconnect.o sshconnect2.o mux.o |
99 | 99 | ||
100 | SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ | 100 | SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ |
101 | audit.o audit-bsm.o audit-linux.o platform.o \ | 101 | audit.o audit-bsm.o audit-linux.o platform.o \ |
diff --git a/sshconnect1.c b/sshconnect1.c deleted file mode 100644 index dc00b4cd0..000000000 --- a/sshconnect1.c +++ /dev/null | |||
@@ -1,774 +0,0 @@ | |||
1 | /* $OpenBSD: sshconnect1.c,v 1.80 2017/03/10 03:53:11 dtucker Exp $ */ | ||
2 | /* | ||
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | ||
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
5 | * All rights reserved | ||
6 | * Code to connect to a remote host, and to perform the client side of the | ||
7 | * login (authentication) dialog. | ||
8 | * | ||
9 | * As far as I am concerned, the code I have written for this software | ||
10 | * can be used freely for any purpose. Any derived versions of this | ||
11 | * software must be clearly marked as such, and if the derived work is | ||
12 | * incompatible with the protocol description in the RFC file, it must be | ||
13 | * called by a name other than "ssh" or "Secure Shell". | ||
14 | */ | ||
15 | |||
16 | #include "includes.h" | ||
17 | |||
18 | #ifdef WITH_SSH1 | ||
19 | |||
20 | #include <sys/types.h> | ||
21 | #include <sys/socket.h> | ||
22 | |||
23 | #include <openssl/bn.h> | ||
24 | |||
25 | #include <errno.h> | ||
26 | #include <stdarg.h> | ||
27 | #include <stdio.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <string.h> | ||
30 | #include <signal.h> | ||
31 | #include <pwd.h> | ||
32 | |||
33 | #include "xmalloc.h" | ||
34 | #include "ssh.h" | ||
35 | #include "ssh1.h" | ||
36 | #include "rsa.h" | ||
37 | #include "buffer.h" | ||
38 | #include "packet.h" | ||
39 | #include "key.h" | ||
40 | #include "cipher.h" | ||
41 | #include "kex.h" | ||
42 | #include "uidswap.h" | ||
43 | #include "log.h" | ||
44 | #include "misc.h" | ||
45 | #include "readconf.h" | ||
46 | #include "authfd.h" | ||
47 | #include "sshconnect.h" | ||
48 | #include "authfile.h" | ||
49 | #include "canohost.h" | ||
50 | #include "hostfile.h" | ||
51 | #include "auth.h" | ||
52 | #include "digest.h" | ||
53 | #include "ssherr.h" | ||
54 | |||
55 | /* Session id for the current session. */ | ||
56 | u_char session_id[16]; | ||
57 | u_int supported_authentications = 0; | ||
58 | |||
59 | extern Options options; | ||
60 | extern char *__progname; | ||
61 | |||
62 | /* | ||
63 | * Checks if the user has an authentication agent, and if so, tries to | ||
64 | * authenticate using the agent. | ||
65 | */ | ||
66 | static int | ||
67 | try_agent_authentication(void) | ||
68 | { | ||
69 | int r, type, agent_fd, ret = 0; | ||
70 | u_char response[16]; | ||
71 | size_t i; | ||
72 | BIGNUM *challenge; | ||
73 | struct ssh_identitylist *idlist = NULL; | ||
74 | |||
75 | /* Get connection to the agent. */ | ||
76 | if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { | ||
77 | if (r != SSH_ERR_AGENT_NOT_PRESENT) | ||
78 | debug("%s: ssh_get_authentication_socket: %s", | ||
79 | __func__, ssh_err(r)); | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | if ((challenge = BN_new()) == NULL) | ||
84 | fatal("try_agent_authentication: BN_new failed"); | ||
85 | |||
86 | /* Loop through identities served by the agent. */ | ||
87 | if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) { | ||
88 | if (r != SSH_ERR_AGENT_NO_IDENTITIES) | ||
89 | debug("%s: ssh_fetch_identitylist: %s", | ||
90 | __func__, ssh_err(r)); | ||
91 | goto out; | ||
92 | } | ||
93 | for (i = 0; i < idlist->nkeys; i++) { | ||
94 | /* Try this identity. */ | ||
95 | debug("Trying RSA authentication via agent with '%.100s'", | ||
96 | idlist->comments[i]); | ||
97 | |||
98 | /* Tell the server that we are willing to authenticate using this key. */ | ||
99 | packet_start(SSH_CMSG_AUTH_RSA); | ||
100 | packet_put_bignum(idlist->keys[i]->rsa->n); | ||
101 | packet_send(); | ||
102 | packet_write_wait(); | ||
103 | |||
104 | /* Wait for server's response. */ | ||
105 | type = packet_read(); | ||
106 | |||
107 | /* The server sends failure if it doesn't like our key or | ||
108 | does not support RSA authentication. */ | ||
109 | if (type == SSH_SMSG_FAILURE) { | ||
110 | debug("Server refused our key."); | ||
111 | continue; | ||
112 | } | ||
113 | /* Otherwise it should have sent a challenge. */ | ||
114 | if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) | ||
115 | packet_disconnect("Protocol error during RSA authentication: %d", | ||
116 | type); | ||
117 | |||
118 | packet_get_bignum(challenge); | ||
119 | packet_check_eom(); | ||
120 | |||
121 | debug("Received RSA challenge from server."); | ||
122 | |||
123 | /* Ask the agent to decrypt the challenge. */ | ||
124 | if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i], | ||
125 | challenge, session_id, response)) != 0) { | ||
126 | /* | ||
127 | * The agent failed to authenticate this identifier | ||
128 | * although it advertised it supports this. Just | ||
129 | * return a wrong value. | ||
130 | */ | ||
131 | logit("Authentication agent failed to decrypt " | ||
132 | "challenge: %s", ssh_err(r)); | ||
133 | explicit_bzero(response, sizeof(response)); | ||
134 | } | ||
135 | debug("Sending response to RSA challenge."); | ||
136 | |||
137 | /* Send the decrypted challenge back to the server. */ | ||
138 | packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); | ||
139 | for (i = 0; i < 16; i++) | ||
140 | packet_put_char(response[i]); | ||
141 | packet_send(); | ||
142 | packet_write_wait(); | ||
143 | |||
144 | /* Wait for response from the server. */ | ||
145 | type = packet_read(); | ||
146 | |||
147 | /* | ||
148 | * The server returns success if it accepted the | ||
149 | * authentication. | ||
150 | */ | ||
151 | if (type == SSH_SMSG_SUCCESS) { | ||
152 | debug("RSA authentication accepted by server."); | ||
153 | ret = 1; | ||
154 | break; | ||
155 | } else if (type != SSH_SMSG_FAILURE) | ||
156 | packet_disconnect("Protocol error waiting RSA auth " | ||
157 | "response: %d", type); | ||
158 | } | ||
159 | if (ret != 1) | ||
160 | debug("RSA authentication using agent refused."); | ||
161 | out: | ||
162 | ssh_free_identitylist(idlist); | ||
163 | ssh_close_authentication_socket(agent_fd); | ||
164 | BN_clear_free(challenge); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Computes the proper response to a RSA challenge, and sends the response to | ||
170 | * the server. | ||
171 | */ | ||
172 | static void | ||
173 | respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) | ||
174 | { | ||
175 | u_char buf[32], response[16]; | ||
176 | struct ssh_digest_ctx *md; | ||
177 | int i, len; | ||
178 | |||
179 | /* Decrypt the challenge using the private key. */ | ||
180 | /* XXX think about Bleichenbacher, too */ | ||
181 | if (rsa_private_decrypt(challenge, challenge, prv) != 0) | ||
182 | packet_disconnect( | ||
183 | "respond_to_rsa_challenge: rsa_private_decrypt failed"); | ||
184 | |||
185 | /* Compute the response. */ | ||
186 | /* The response is MD5 of decrypted challenge plus session id. */ | ||
187 | len = BN_num_bytes(challenge); | ||
188 | if (len <= 0 || (u_int)len > sizeof(buf)) | ||
189 | packet_disconnect( | ||
190 | "respond_to_rsa_challenge: bad challenge length %d", len); | ||
191 | |||
192 | memset(buf, 0, sizeof(buf)); | ||
193 | BN_bn2bin(challenge, buf + sizeof(buf) - len); | ||
194 | if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || | ||
195 | ssh_digest_update(md, buf, 32) < 0 || | ||
196 | ssh_digest_update(md, session_id, 16) < 0 || | ||
197 | ssh_digest_final(md, response, sizeof(response)) < 0) | ||
198 | fatal("%s: md5 failed", __func__); | ||
199 | ssh_digest_free(md); | ||
200 | |||
201 | debug("Sending response to host key RSA challenge."); | ||
202 | |||
203 | /* Send the response back to the server. */ | ||
204 | packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); | ||
205 | for (i = 0; i < 16; i++) | ||
206 | packet_put_char(response[i]); | ||
207 | packet_send(); | ||
208 | packet_write_wait(); | ||
209 | |||
210 | explicit_bzero(buf, sizeof(buf)); | ||
211 | explicit_bzero(response, sizeof(response)); | ||
212 | explicit_bzero(&md, sizeof(md)); | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * Checks if the user has authentication file, and if so, tries to authenticate | ||
217 | * the user using it. | ||
218 | */ | ||
219 | static int | ||
220 | try_rsa_authentication(int idx) | ||
221 | { | ||
222 | BIGNUM *challenge; | ||
223 | Key *public, *private; | ||
224 | char buf[300], *passphrase = NULL, *comment, *authfile; | ||
225 | int i, perm_ok = 1, type, quit; | ||
226 | |||
227 | public = options.identity_keys[idx]; | ||
228 | authfile = options.identity_files[idx]; | ||
229 | comment = xstrdup(authfile); | ||
230 | |||
231 | debug("Trying RSA authentication with key '%.100s'", comment); | ||
232 | |||
233 | /* Tell the server that we are willing to authenticate using this key. */ | ||
234 | packet_start(SSH_CMSG_AUTH_RSA); | ||
235 | packet_put_bignum(public->rsa->n); | ||
236 | packet_send(); | ||
237 | packet_write_wait(); | ||
238 | |||
239 | /* Wait for server's response. */ | ||
240 | type = packet_read(); | ||
241 | |||
242 | /* | ||
243 | * The server responds with failure if it doesn't like our key or | ||
244 | * doesn't support RSA authentication. | ||
245 | */ | ||
246 | if (type == SSH_SMSG_FAILURE) { | ||
247 | debug("Server refused our key."); | ||
248 | free(comment); | ||
249 | return 0; | ||
250 | } | ||
251 | /* Otherwise, the server should respond with a challenge. */ | ||
252 | if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) | ||
253 | packet_disconnect("Protocol error during RSA authentication: %d", type); | ||
254 | |||
255 | /* Get the challenge from the packet. */ | ||
256 | if ((challenge = BN_new()) == NULL) | ||
257 | fatal("try_rsa_authentication: BN_new failed"); | ||
258 | packet_get_bignum(challenge); | ||
259 | packet_check_eom(); | ||
260 | |||
261 | debug("Received RSA challenge from server."); | ||
262 | |||
263 | /* | ||
264 | * If the key is not stored in external hardware, we have to | ||
265 | * load the private key. Try first with empty passphrase; if it | ||
266 | * fails, ask for a passphrase. | ||
267 | */ | ||
268 | if (public->flags & SSHKEY_FLAG_EXT) | ||
269 | private = public; | ||
270 | else | ||
271 | private = key_load_private_type(KEY_RSA1, authfile, "", NULL, | ||
272 | &perm_ok); | ||
273 | if (private == NULL && !options.batch_mode && perm_ok) { | ||
274 | snprintf(buf, sizeof(buf), | ||
275 | "Enter passphrase for RSA key '%.100s': ", comment); | ||
276 | for (i = 0; i < options.number_of_password_prompts; i++) { | ||
277 | passphrase = read_passphrase(buf, 0); | ||
278 | if (strcmp(passphrase, "") != 0) { | ||
279 | private = key_load_private_type(KEY_RSA1, | ||
280 | authfile, passphrase, NULL, NULL); | ||
281 | quit = 0; | ||
282 | } else { | ||
283 | debug2("no passphrase given, try next key"); | ||
284 | quit = 1; | ||
285 | } | ||
286 | if (private != NULL || quit) | ||
287 | break; | ||
288 | debug2("bad passphrase given, try again..."); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if (private != NULL) | ||
293 | maybe_add_key_to_agent(authfile, private, comment, passphrase); | ||
294 | |||
295 | if (passphrase != NULL) { | ||
296 | explicit_bzero(passphrase, strlen(passphrase)); | ||
297 | free(passphrase); | ||
298 | } | ||
299 | |||
300 | /* We no longer need the comment. */ | ||
301 | free(comment); | ||
302 | |||
303 | if (private == NULL) { | ||
304 | if (!options.batch_mode && perm_ok) | ||
305 | error("Bad passphrase."); | ||
306 | |||
307 | /* Send a dummy response packet to avoid protocol error. */ | ||
308 | packet_start(SSH_CMSG_AUTH_RSA_RESPONSE); | ||
309 | for (i = 0; i < 16; i++) | ||
310 | packet_put_char(0); | ||
311 | packet_send(); | ||
312 | packet_write_wait(); | ||
313 | |||
314 | /* Expect the server to reject it... */ | ||
315 | packet_read_expect(SSH_SMSG_FAILURE); | ||
316 | BN_clear_free(challenge); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | /* Compute and send a response to the challenge. */ | ||
321 | respond_to_rsa_challenge(challenge, private->rsa); | ||
322 | |||
323 | /* Destroy the private key unless it in external hardware. */ | ||
324 | if (!(private->flags & SSHKEY_FLAG_EXT)) | ||
325 | key_free(private); | ||
326 | |||
327 | /* We no longer need the challenge. */ | ||
328 | BN_clear_free(challenge); | ||
329 | |||
330 | /* Wait for response from the server. */ | ||
331 | type = packet_read(); | ||
332 | if (type == SSH_SMSG_SUCCESS) { | ||
333 | debug("RSA authentication accepted by server."); | ||
334 | return 1; | ||
335 | } | ||
336 | if (type != SSH_SMSG_FAILURE) | ||
337 | packet_disconnect("Protocol error waiting RSA auth response: %d", type); | ||
338 | debug("RSA authentication refused."); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv | ||
344 | * authentication and RSA host authentication. | ||
345 | */ | ||
346 | static int | ||
347 | try_rhosts_rsa_authentication(const char *local_user, Key * host_key) | ||
348 | { | ||
349 | int type; | ||
350 | BIGNUM *challenge; | ||
351 | |||
352 | debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); | ||
353 | |||
354 | /* Tell the server that we are willing to authenticate using this key. */ | ||
355 | packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); | ||
356 | packet_put_cstring(local_user); | ||
357 | packet_put_int(BN_num_bits(host_key->rsa->n)); | ||
358 | packet_put_bignum(host_key->rsa->e); | ||
359 | packet_put_bignum(host_key->rsa->n); | ||
360 | packet_send(); | ||
361 | packet_write_wait(); | ||
362 | |||
363 | /* Wait for server's response. */ | ||
364 | type = packet_read(); | ||
365 | |||
366 | /* The server responds with failure if it doesn't admit our | ||
367 | .rhosts authentication or doesn't know our host key. */ | ||
368 | if (type == SSH_SMSG_FAILURE) { | ||
369 | debug("Server refused our rhosts authentication or host key."); | ||
370 | return 0; | ||
371 | } | ||
372 | /* Otherwise, the server should respond with a challenge. */ | ||
373 | if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) | ||
374 | packet_disconnect("Protocol error during RSA authentication: %d", type); | ||
375 | |||
376 | /* Get the challenge from the packet. */ | ||
377 | if ((challenge = BN_new()) == NULL) | ||
378 | fatal("try_rhosts_rsa_authentication: BN_new failed"); | ||
379 | packet_get_bignum(challenge); | ||
380 | packet_check_eom(); | ||
381 | |||
382 | debug("Received RSA challenge for host key from server."); | ||
383 | |||
384 | /* Compute a response to the challenge. */ | ||
385 | respond_to_rsa_challenge(challenge, host_key->rsa); | ||
386 | |||
387 | /* We no longer need the challenge. */ | ||
388 | BN_clear_free(challenge); | ||
389 | |||
390 | /* Wait for response from the server. */ | ||
391 | type = packet_read(); | ||
392 | if (type == SSH_SMSG_SUCCESS) { | ||
393 | debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server."); | ||
394 | return 1; | ||
395 | } | ||
396 | if (type != SSH_SMSG_FAILURE) | ||
397 | packet_disconnect("Protocol error waiting RSA auth response: %d", type); | ||
398 | debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused."); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * Tries to authenticate with any string-based challenge/response system. | ||
404 | * Note that the client code is not tied to s/key or TIS. | ||
405 | */ | ||
406 | static int | ||
407 | try_challenge_response_authentication(void) | ||
408 | { | ||
409 | int type, i; | ||
410 | u_int clen; | ||
411 | char prompt[1024]; | ||
412 | char *challenge, *response; | ||
413 | |||
414 | debug("Doing challenge response authentication."); | ||
415 | |||
416 | for (i = 0; i < options.number_of_password_prompts; i++) { | ||
417 | /* request a challenge */ | ||
418 | packet_start(SSH_CMSG_AUTH_TIS); | ||
419 | packet_send(); | ||
420 | packet_write_wait(); | ||
421 | |||
422 | type = packet_read(); | ||
423 | if (type != SSH_SMSG_FAILURE && | ||
424 | type != SSH_SMSG_AUTH_TIS_CHALLENGE) { | ||
425 | packet_disconnect("Protocol error: got %d in response " | ||
426 | "to SSH_CMSG_AUTH_TIS", type); | ||
427 | } | ||
428 | if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) { | ||
429 | debug("No challenge."); | ||
430 | return 0; | ||
431 | } | ||
432 | challenge = packet_get_string(&clen); | ||
433 | packet_check_eom(); | ||
434 | snprintf(prompt, sizeof prompt, "%s%s", challenge, | ||
435 | strchr(challenge, '\n') ? "" : "\nResponse: "); | ||
436 | free(challenge); | ||
437 | if (i != 0) | ||
438 | error("Permission denied, please try again."); | ||
439 | if (options.cipher == SSH_CIPHER_NONE) | ||
440 | logit("WARNING: Encryption is disabled! " | ||
441 | "Response will be transmitted in clear text."); | ||
442 | response = read_passphrase(prompt, 0); | ||
443 | if (strcmp(response, "") == 0) { | ||
444 | free(response); | ||
445 | break; | ||
446 | } | ||
447 | packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); | ||
448 | ssh_put_password(response); | ||
449 | explicit_bzero(response, strlen(response)); | ||
450 | free(response); | ||
451 | packet_send(); | ||
452 | packet_write_wait(); | ||
453 | type = packet_read(); | ||
454 | if (type == SSH_SMSG_SUCCESS) | ||
455 | return 1; | ||
456 | if (type != SSH_SMSG_FAILURE) | ||
457 | packet_disconnect("Protocol error: got %d in response " | ||
458 | "to SSH_CMSG_AUTH_TIS_RESPONSE", type); | ||
459 | } | ||
460 | /* failure */ | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Tries to authenticate with plain passwd authentication. | ||
466 | */ | ||
467 | static int | ||
468 | try_password_authentication(char *prompt) | ||
469 | { | ||
470 | int type, i; | ||
471 | char *password; | ||
472 | |||
473 | debug("Doing password authentication."); | ||
474 | if (options.cipher == SSH_CIPHER_NONE) | ||
475 | logit("WARNING: Encryption is disabled! Password will be transmitted in clear text."); | ||
476 | for (i = 0; i < options.number_of_password_prompts; i++) { | ||
477 | if (i != 0) | ||
478 | error("Permission denied, please try again."); | ||
479 | password = read_passphrase(prompt, 0); | ||
480 | packet_start(SSH_CMSG_AUTH_PASSWORD); | ||
481 | ssh_put_password(password); | ||
482 | explicit_bzero(password, strlen(password)); | ||
483 | free(password); | ||
484 | packet_send(); | ||
485 | packet_write_wait(); | ||
486 | |||
487 | type = packet_read(); | ||
488 | if (type == SSH_SMSG_SUCCESS) | ||
489 | return 1; | ||
490 | if (type != SSH_SMSG_FAILURE) | ||
491 | packet_disconnect("Protocol error: got %d in response to passwd auth", type); | ||
492 | } | ||
493 | /* failure */ | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * SSH1 key exchange | ||
499 | */ | ||
500 | void | ||
501 | ssh_kex(char *host, struct sockaddr *hostaddr) | ||
502 | { | ||
503 | int i; | ||
504 | BIGNUM *key; | ||
505 | Key *host_key, *server_key; | ||
506 | int bits, rbits; | ||
507 | int ssh_cipher_default = SSH_CIPHER_3DES; | ||
508 | u_char session_key[SSH_SESSION_KEY_LENGTH]; | ||
509 | u_char cookie[8]; | ||
510 | u_int supported_ciphers; | ||
511 | u_int server_flags, client_flags; | ||
512 | |||
513 | debug("Waiting for server public key."); | ||
514 | |||
515 | /* Wait for a public key packet from the server. */ | ||
516 | packet_read_expect(SSH_SMSG_PUBLIC_KEY); | ||
517 | |||
518 | /* Get cookie from the packet. */ | ||
519 | for (i = 0; i < 8; i++) | ||
520 | cookie[i] = packet_get_char(); | ||
521 | |||
522 | /* Get the public key. */ | ||
523 | if ((server_key = key_new(KEY_RSA1)) == NULL) | ||
524 | fatal("%s: key_new(KEY_RSA1) failed", __func__); | ||
525 | bits = packet_get_int(); | ||
526 | packet_get_bignum(server_key->rsa->e); | ||
527 | packet_get_bignum(server_key->rsa->n); | ||
528 | |||
529 | rbits = BN_num_bits(server_key->rsa->n); | ||
530 | if (bits != rbits) { | ||
531 | logit("Warning: Server lies about size of server public key: " | ||
532 | "actual size is %d bits vs. announced %d.", rbits, bits); | ||
533 | logit("Warning: This may be due to an old implementation of ssh."); | ||
534 | } | ||
535 | /* Get the host key. */ | ||
536 | if ((host_key = key_new(KEY_RSA1)) == NULL) | ||
537 | fatal("%s: key_new(KEY_RSA1) failed", __func__); | ||
538 | bits = packet_get_int(); | ||
539 | packet_get_bignum(host_key->rsa->e); | ||
540 | packet_get_bignum(host_key->rsa->n); | ||
541 | |||
542 | rbits = BN_num_bits(host_key->rsa->n); | ||
543 | if (bits != rbits) { | ||
544 | logit("Warning: Server lies about size of server host key: " | ||
545 | "actual size is %d bits vs. announced %d.", rbits, bits); | ||
546 | logit("Warning: This may be due to an old implementation of ssh."); | ||
547 | } | ||
548 | |||
549 | /* Get protocol flags. */ | ||
550 | server_flags = packet_get_int(); | ||
551 | packet_set_protocol_flags(server_flags); | ||
552 | |||
553 | supported_ciphers = packet_get_int(); | ||
554 | supported_authentications = packet_get_int(); | ||
555 | packet_check_eom(); | ||
556 | |||
557 | debug("Received server public key (%d bits) and host key (%d bits).", | ||
558 | BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); | ||
559 | |||
560 | if (verify_host_key(host, hostaddr, host_key) == -1) | ||
561 | fatal("Host key verification failed."); | ||
562 | |||
563 | client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; | ||
564 | |||
565 | derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); | ||
566 | |||
567 | /* | ||
568 | * Generate an encryption key for the session. The key is a 256 bit | ||
569 | * random number, interpreted as a 32-byte key, with the least | ||
570 | * significant 8 bits being the first byte of the key. | ||
571 | */ | ||
572 | arc4random_buf(session_key, sizeof(session_key)); | ||
573 | |||
574 | /* | ||
575 | * According to the protocol spec, the first byte of the session key | ||
576 | * is the highest byte of the integer. The session key is xored with | ||
577 | * the first 16 bytes of the session id. | ||
578 | */ | ||
579 | if ((key = BN_new()) == NULL) | ||
580 | fatal("ssh_kex: BN_new failed"); | ||
581 | if (BN_set_word(key, 0) == 0) | ||
582 | fatal("ssh_kex: BN_set_word failed"); | ||
583 | for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { | ||
584 | if (BN_lshift(key, key, 8) == 0) | ||
585 | fatal("ssh_kex: BN_lshift failed"); | ||
586 | if (i < 16) { | ||
587 | if (BN_add_word(key, session_key[i] ^ session_id[i]) | ||
588 | == 0) | ||
589 | fatal("ssh_kex: BN_add_word failed"); | ||
590 | } else { | ||
591 | if (BN_add_word(key, session_key[i]) == 0) | ||
592 | fatal("ssh_kex: BN_add_word failed"); | ||
593 | } | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Encrypt the integer using the public key and host key of the | ||
598 | * server (key with smaller modulus first). | ||
599 | */ | ||
600 | if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { | ||
601 | /* Public key has smaller modulus. */ | ||
602 | if (BN_num_bits(host_key->rsa->n) < | ||
603 | BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { | ||
604 | fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " | ||
605 | "SSH_KEY_BITS_RESERVED %d", | ||
606 | BN_num_bits(host_key->rsa->n), | ||
607 | BN_num_bits(server_key->rsa->n), | ||
608 | SSH_KEY_BITS_RESERVED); | ||
609 | } | ||
610 | if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || | ||
611 | rsa_public_encrypt(key, key, host_key->rsa) != 0) | ||
612 | fatal("%s: rsa_public_encrypt failed", __func__); | ||
613 | } else { | ||
614 | /* Host key has smaller modulus (or they are equal). */ | ||
615 | if (BN_num_bits(server_key->rsa->n) < | ||
616 | BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { | ||
617 | fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " | ||
618 | "SSH_KEY_BITS_RESERVED %d", | ||
619 | BN_num_bits(server_key->rsa->n), | ||
620 | BN_num_bits(host_key->rsa->n), | ||
621 | SSH_KEY_BITS_RESERVED); | ||
622 | } | ||
623 | if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || | ||
624 | rsa_public_encrypt(key, key, server_key->rsa) != 0) | ||
625 | fatal("%s: rsa_public_encrypt failed", __func__); | ||
626 | } | ||
627 | |||
628 | /* Destroy the public keys since we no longer need them. */ | ||
629 | key_free(server_key); | ||
630 | key_free(host_key); | ||
631 | |||
632 | if (options.cipher == SSH_CIPHER_NOT_SET) { | ||
633 | if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default)) | ||
634 | options.cipher = ssh_cipher_default; | ||
635 | } else if (options.cipher == SSH_CIPHER_INVALID || | ||
636 | !(cipher_mask_ssh1(1) & (1 << options.cipher))) { | ||
637 | logit("No valid SSH1 cipher, using %.100s instead.", | ||
638 | cipher_name(ssh_cipher_default)); | ||
639 | options.cipher = ssh_cipher_default; | ||
640 | } | ||
641 | /* Check that the selected cipher is supported. */ | ||
642 | if (!(supported_ciphers & (1 << options.cipher))) | ||
643 | fatal("Selected cipher type %.100s not supported by server.", | ||
644 | cipher_name(options.cipher)); | ||
645 | |||
646 | debug("Encryption type: %.100s", cipher_name(options.cipher)); | ||
647 | |||
648 | /* Send the encrypted session key to the server. */ | ||
649 | packet_start(SSH_CMSG_SESSION_KEY); | ||
650 | packet_put_char(options.cipher); | ||
651 | |||
652 | /* Send the cookie back to the server. */ | ||
653 | for (i = 0; i < 8; i++) | ||
654 | packet_put_char(cookie[i]); | ||
655 | |||
656 | /* Send and destroy the encrypted encryption key integer. */ | ||
657 | packet_put_bignum(key); | ||
658 | BN_clear_free(key); | ||
659 | |||
660 | /* Send protocol flags. */ | ||
661 | packet_put_int(client_flags); | ||
662 | |||
663 | /* Send the packet now. */ | ||
664 | packet_send(); | ||
665 | packet_write_wait(); | ||
666 | |||
667 | debug("Sent encrypted session key."); | ||
668 | |||
669 | /* Set the encryption key. */ | ||
670 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); | ||
671 | |||
672 | /* | ||
673 | * We will no longer need the session key here. | ||
674 | * Destroy any extra copies. | ||
675 | */ | ||
676 | explicit_bzero(session_key, sizeof(session_key)); | ||
677 | |||
678 | /* | ||
679 | * Expect a success message from the server. Note that this message | ||
680 | * will be received in encrypted form. | ||
681 | */ | ||
682 | packet_read_expect(SSH_SMSG_SUCCESS); | ||
683 | |||
684 | debug("Received encrypted confirmation."); | ||
685 | } | ||
686 | |||
687 | /* | ||
688 | * Authenticate user | ||
689 | */ | ||
690 | void | ||
691 | ssh_userauth1(const char *local_user, const char *server_user, char *host, | ||
692 | Sensitive *sensitive) | ||
693 | { | ||
694 | int i, type; | ||
695 | |||
696 | if (supported_authentications == 0) | ||
697 | fatal("ssh_userauth1: server supports no auth methods"); | ||
698 | |||
699 | /* Send the name of the user to log in as on the server. */ | ||
700 | packet_start(SSH_CMSG_USER); | ||
701 | packet_put_cstring(server_user); | ||
702 | packet_send(); | ||
703 | packet_write_wait(); | ||
704 | |||
705 | /* | ||
706 | * The server should respond with success if no authentication is | ||
707 | * needed (the user has no password). Otherwise the server responds | ||
708 | * with failure. | ||
709 | */ | ||
710 | type = packet_read(); | ||
711 | |||
712 | /* check whether the connection was accepted without authentication. */ | ||
713 | if (type == SSH_SMSG_SUCCESS) | ||
714 | goto success; | ||
715 | if (type != SSH_SMSG_FAILURE) | ||
716 | packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type); | ||
717 | |||
718 | /* | ||
719 | * Try .rhosts or /etc/hosts.equiv authentication with RSA host | ||
720 | * authentication. | ||
721 | */ | ||
722 | if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && | ||
723 | options.rhosts_rsa_authentication) { | ||
724 | for (i = 0; i < sensitive->nkeys; i++) { | ||
725 | if (sensitive->keys[i] != NULL && | ||
726 | sensitive->keys[i]->type == KEY_RSA1 && | ||
727 | try_rhosts_rsa_authentication(local_user, | ||
728 | sensitive->keys[i])) | ||
729 | goto success; | ||
730 | } | ||
731 | } | ||
732 | /* Try RSA authentication if the server supports it. */ | ||
733 | if ((supported_authentications & (1 << SSH_AUTH_RSA)) && | ||
734 | options.rsa_authentication) { | ||
735 | /* | ||
736 | * Try RSA authentication using the authentication agent. The | ||
737 | * agent is tried first because no passphrase is needed for | ||
738 | * it, whereas identity files may require passphrases. | ||
739 | */ | ||
740 | if (try_agent_authentication()) | ||
741 | goto success; | ||
742 | |||
743 | /* Try RSA authentication for each identity. */ | ||
744 | for (i = 0; i < options.num_identity_files; i++) | ||
745 | if (options.identity_keys[i] != NULL && | ||
746 | options.identity_keys[i]->type == KEY_RSA1 && | ||
747 | try_rsa_authentication(i)) | ||
748 | goto success; | ||
749 | } | ||
750 | /* Try challenge response authentication if the server supports it. */ | ||
751 | if ((supported_authentications & (1 << SSH_AUTH_TIS)) && | ||
752 | options.challenge_response_authentication && !options.batch_mode) { | ||
753 | if (try_challenge_response_authentication()) | ||
754 | goto success; | ||
755 | } | ||
756 | /* Try password authentication if the server supports it. */ | ||
757 | if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && | ||
758 | options.password_authentication && !options.batch_mode) { | ||
759 | char prompt[80]; | ||
760 | |||
761 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", | ||
762 | server_user, host); | ||
763 | if (try_password_authentication(prompt)) | ||
764 | goto success; | ||
765 | } | ||
766 | /* All authentication methods have failed. Exit with an error message. */ | ||
767 | fatal("Permission denied."); | ||
768 | /* NOTREACHED */ | ||
769 | |||
770 | success: | ||
771 | return; /* need statement after label */ | ||
772 | } | ||
773 | |||
774 | #endif /* WITH_SSH1 */ | ||