diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 600 |
1 files changed, 64 insertions, 536 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.470 2016/05/24 04:43:45 dtucker Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.480 2016/12/09 03:04:29 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -87,7 +87,6 @@ | |||
87 | 87 | ||
88 | #include "xmalloc.h" | 88 | #include "xmalloc.h" |
89 | #include "ssh.h" | 89 | #include "ssh.h" |
90 | #include "ssh1.h" | ||
91 | #include "ssh2.h" | 90 | #include "ssh2.h" |
92 | #include "rsa.h" | 91 | #include "rsa.h" |
93 | #include "sshpty.h" | 92 | #include "sshpty.h" |
@@ -115,7 +114,6 @@ | |||
115 | #include "dispatch.h" | 114 | #include "dispatch.h" |
116 | #include "channels.h" | 115 | #include "channels.h" |
117 | #include "session.h" | 116 | #include "session.h" |
118 | #include "monitor_mm.h" | ||
119 | #include "monitor.h" | 117 | #include "monitor.h" |
120 | #ifdef GSSAPI | 118 | #ifdef GSSAPI |
121 | #include "ssh-gss.h" | 119 | #include "ssh-gss.h" |
@@ -125,10 +123,6 @@ | |||
125 | #include "version.h" | 123 | #include "version.h" |
126 | #include "ssherr.h" | 124 | #include "ssherr.h" |
127 | 125 | ||
128 | #ifndef O_NOCTTY | ||
129 | #define O_NOCTTY 0 | ||
130 | #endif | ||
131 | |||
132 | /* Re-exec fds */ | 126 | /* Re-exec fds */ |
133 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | 127 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
134 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | 128 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) |
@@ -201,22 +195,12 @@ int have_agent = 0; | |||
201 | * not very useful. Currently, memory locking is not implemented. | 195 | * not very useful. Currently, memory locking is not implemented. |
202 | */ | 196 | */ |
203 | struct { | 197 | struct { |
204 | Key *server_key; /* ephemeral server key */ | ||
205 | Key *ssh1_host_key; /* ssh1 host key */ | ||
206 | Key **host_keys; /* all private host keys */ | 198 | Key **host_keys; /* all private host keys */ |
207 | Key **host_pubkeys; /* all public host keys */ | 199 | Key **host_pubkeys; /* all public host keys */ |
208 | Key **host_certificates; /* all public host certificates */ | 200 | Key **host_certificates; /* all public host certificates */ |
209 | int have_ssh1_key; | ||
210 | int have_ssh2_key; | 201 | int have_ssh2_key; |
211 | u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; | ||
212 | } sensitive_data; | 202 | } sensitive_data; |
213 | 203 | ||
214 | /* | ||
215 | * Flag indicating whether the RSA server key needs to be regenerated. | ||
216 | * Is set in the SIGALRM handler and cleared when the key is regenerated. | ||
217 | */ | ||
218 | static volatile sig_atomic_t key_do_regen = 0; | ||
219 | |||
220 | /* This is set to true when a signal is received. */ | 204 | /* This is set to true when a signal is received. */ |
221 | static volatile sig_atomic_t received_sighup = 0; | 205 | static volatile sig_atomic_t received_sighup = 0; |
222 | static volatile sig_atomic_t received_sigterm = 0; | 206 | static volatile sig_atomic_t received_sigterm = 0; |
@@ -255,10 +239,6 @@ struct passwd *privsep_pw = NULL; | |||
255 | /* Prototypes for various functions defined later in this file. */ | 239 | /* Prototypes for various functions defined later in this file. */ |
256 | void destroy_sensitive_data(void); | 240 | void destroy_sensitive_data(void); |
257 | void demote_sensitive_data(void); | 241 | void demote_sensitive_data(void); |
258 | |||
259 | #ifdef WITH_SSH1 | ||
260 | static void do_ssh1_kex(void); | ||
261 | #endif | ||
262 | static void do_ssh2_kex(void); | 242 | static void do_ssh2_kex(void); |
263 | 243 | ||
264 | /* | 244 | /* |
@@ -310,6 +290,8 @@ static void | |||
310 | sighup_restart(void) | 290 | sighup_restart(void) |
311 | { | 291 | { |
312 | logit("Received SIGHUP; restarting."); | 292 | logit("Received SIGHUP; restarting."); |
293 | if (options.pid_file != NULL) | ||
294 | unlink(options.pid_file); | ||
313 | platform_pre_restart(); | 295 | platform_pre_restart(); |
314 | close_listen_socks(); | 296 | close_listen_socks(); |
315 | close_startup_pipes(); | 297 | close_startup_pipes(); |
@@ -375,64 +357,17 @@ grace_alarm_handler(int sig) | |||
375 | ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); | 357 | ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); |
376 | } | 358 | } |
377 | 359 | ||
378 | /* | ||
379 | * Signal handler for the key regeneration alarm. Note that this | ||
380 | * alarm only occurs in the daemon waiting for connections, and it does not | ||
381 | * do anything with the private key or random state before forking. | ||
382 | * Thus there should be no concurrency control/asynchronous execution | ||
383 | * problems. | ||
384 | */ | ||
385 | static void | ||
386 | generate_ephemeral_server_key(void) | ||
387 | { | ||
388 | verbose("Generating %s%d bit RSA key.", | ||
389 | sensitive_data.server_key ? "new " : "", options.server_key_bits); | ||
390 | if (sensitive_data.server_key != NULL) | ||
391 | key_free(sensitive_data.server_key); | ||
392 | sensitive_data.server_key = key_generate(KEY_RSA1, | ||
393 | options.server_key_bits); | ||
394 | verbose("RSA key generation complete."); | ||
395 | |||
396 | arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); | ||
397 | } | ||
398 | |||
399 | /*ARGSUSED*/ | ||
400 | static void | ||
401 | key_regeneration_alarm(int sig) | ||
402 | { | ||
403 | int save_errno = errno; | ||
404 | |||
405 | signal(SIGALRM, SIG_DFL); | ||
406 | errno = save_errno; | ||
407 | key_do_regen = 1; | ||
408 | } | ||
409 | |||
410 | static void | 360 | static void |
411 | sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | 361 | sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) |
412 | { | 362 | { |
413 | u_int i; | 363 | u_int i; |
414 | int mismatch; | ||
415 | int remote_major, remote_minor; | 364 | int remote_major, remote_minor; |
416 | int major, minor; | ||
417 | char *s, *newline = "\n"; | 365 | char *s, *newline = "\n"; |
418 | char buf[256]; /* Must not be larger than remote_version. */ | 366 | char buf[256]; /* Must not be larger than remote_version. */ |
419 | char remote_version[256]; /* Must be at least as big as buf. */ | 367 | char remote_version[256]; /* Must be at least as big as buf. */ |
420 | 368 | ||
421 | if ((options.protocol & SSH_PROTO_1) && | ||
422 | (options.protocol & SSH_PROTO_2)) { | ||
423 | major = PROTOCOL_MAJOR_1; | ||
424 | minor = 99; | ||
425 | } else if (options.protocol & SSH_PROTO_2) { | ||
426 | major = PROTOCOL_MAJOR_2; | ||
427 | minor = PROTOCOL_MINOR_2; | ||
428 | newline = "\r\n"; | ||
429 | } else { | ||
430 | major = PROTOCOL_MAJOR_1; | ||
431 | minor = PROTOCOL_MINOR_1; | ||
432 | } | ||
433 | |||
434 | xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", | 369 | xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", |
435 | major, minor, SSH_VERSION, | 370 | PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, |
436 | *options.version_addendum == '\0' ? "" : " ", | 371 | *options.version_addendum == '\0' ? "" : " ", |
437 | options.version_addendum, newline); | 372 | options.version_addendum, newline); |
438 | 373 | ||
@@ -511,42 +446,13 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | |||
511 | "refusing connection", remote_version); | 446 | "refusing connection", remote_version); |
512 | } | 447 | } |
513 | 448 | ||
514 | mismatch = 0; | ||
515 | switch (remote_major) { | ||
516 | case 1: | ||
517 | if (remote_minor == 99) { | ||
518 | if (options.protocol & SSH_PROTO_2) | ||
519 | enable_compat20(); | ||
520 | else | ||
521 | mismatch = 1; | ||
522 | break; | ||
523 | } | ||
524 | if (!(options.protocol & SSH_PROTO_1)) { | ||
525 | mismatch = 1; | ||
526 | break; | ||
527 | } | ||
528 | if (remote_minor < 3) { | ||
529 | packet_disconnect("Your ssh version is too old and " | ||
530 | "is no longer supported. Please install a newer version."); | ||
531 | } else if (remote_minor == 3) { | ||
532 | /* note that this disables agent-forwarding */ | ||
533 | enable_compat13(); | ||
534 | } | ||
535 | break; | ||
536 | case 2: | ||
537 | if (options.protocol & SSH_PROTO_2) { | ||
538 | enable_compat20(); | ||
539 | break; | ||
540 | } | ||
541 | /* FALLTHROUGH */ | ||
542 | default: | ||
543 | mismatch = 1; | ||
544 | break; | ||
545 | } | ||
546 | chop(server_version_string); | 449 | chop(server_version_string); |
547 | debug("Local version string %.200s", server_version_string); | 450 | debug("Local version string %.200s", server_version_string); |
548 | 451 | ||
549 | if (mismatch) { | 452 | if (remote_major == 2 || |
453 | (remote_major == 1 && remote_minor == 99)) { | ||
454 | enable_compat20(); | ||
455 | } else { | ||
550 | s = "Protocol major versions differ.\n"; | 456 | s = "Protocol major versions differ.\n"; |
551 | (void) atomicio(vwrite, sock_out, s, strlen(s)); | 457 | (void) atomicio(vwrite, sock_out, s, strlen(s)); |
552 | close(sock_in); | 458 | close(sock_in); |
@@ -565,10 +471,6 @@ destroy_sensitive_data(void) | |||
565 | { | 471 | { |
566 | int i; | 472 | int i; |
567 | 473 | ||
568 | if (sensitive_data.server_key) { | ||
569 | key_free(sensitive_data.server_key); | ||
570 | sensitive_data.server_key = NULL; | ||
571 | } | ||
572 | for (i = 0; i < options.num_host_key_files; i++) { | 474 | for (i = 0; i < options.num_host_key_files; i++) { |
573 | if (sensitive_data.host_keys[i]) { | 475 | if (sensitive_data.host_keys[i]) { |
574 | key_free(sensitive_data.host_keys[i]); | 476 | key_free(sensitive_data.host_keys[i]); |
@@ -579,8 +481,6 @@ destroy_sensitive_data(void) | |||
579 | sensitive_data.host_certificates[i] = NULL; | 481 | sensitive_data.host_certificates[i] = NULL; |
580 | } | 482 | } |
581 | } | 483 | } |
582 | sensitive_data.ssh1_host_key = NULL; | ||
583 | explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); | ||
584 | } | 484 | } |
585 | 485 | ||
586 | /* Demote private to public keys for network child */ | 486 | /* Demote private to public keys for network child */ |
@@ -590,30 +490,40 @@ demote_sensitive_data(void) | |||
590 | Key *tmp; | 490 | Key *tmp; |
591 | int i; | 491 | int i; |
592 | 492 | ||
593 | if (sensitive_data.server_key) { | ||
594 | tmp = key_demote(sensitive_data.server_key); | ||
595 | key_free(sensitive_data.server_key); | ||
596 | sensitive_data.server_key = tmp; | ||
597 | } | ||
598 | |||
599 | for (i = 0; i < options.num_host_key_files; i++) { | 493 | for (i = 0; i < options.num_host_key_files; i++) { |
600 | if (sensitive_data.host_keys[i]) { | 494 | if (sensitive_data.host_keys[i]) { |
601 | tmp = key_demote(sensitive_data.host_keys[i]); | 495 | tmp = key_demote(sensitive_data.host_keys[i]); |
602 | key_free(sensitive_data.host_keys[i]); | 496 | key_free(sensitive_data.host_keys[i]); |
603 | sensitive_data.host_keys[i] = tmp; | 497 | sensitive_data.host_keys[i] = tmp; |
604 | if (tmp->type == KEY_RSA1) | ||
605 | sensitive_data.ssh1_host_key = tmp; | ||
606 | } | 498 | } |
607 | /* Certs do not need demotion */ | 499 | /* Certs do not need demotion */ |
608 | } | 500 | } |
501 | } | ||
502 | |||
503 | static void | ||
504 | reseed_prngs(void) | ||
505 | { | ||
506 | u_int32_t rnd[256]; | ||
609 | 507 | ||
610 | /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ | 508 | #ifdef WITH_OPENSSL |
509 | RAND_poll(); | ||
510 | #endif | ||
511 | arc4random_stir(); /* noop on recent arc4random() implementations */ | ||
512 | arc4random_buf(rnd, sizeof(rnd)); /* let arc4random notice PID change */ | ||
513 | |||
514 | #ifdef WITH_OPENSSL | ||
515 | RAND_seed(rnd, sizeof(rnd)); | ||
516 | /* give libcrypto a chance to notice the PID change */ | ||
517 | if ((RAND_bytes((u_char *)rnd, 1)) != 1) | ||
518 | fatal("%s: RAND_bytes failed", __func__); | ||
519 | #endif | ||
520 | |||
521 | explicit_bzero(rnd, sizeof(rnd)); | ||
611 | } | 522 | } |
612 | 523 | ||
613 | static void | 524 | static void |
614 | privsep_preauth_child(void) | 525 | privsep_preauth_child(void) |
615 | { | 526 | { |
616 | u_int32_t rnd[256]; | ||
617 | gid_t gidset[1]; | 527 | gid_t gidset[1]; |
618 | 528 | ||
619 | /* Enable challenge-response authentication for privilege separation */ | 529 | /* Enable challenge-response authentication for privilege separation */ |
@@ -625,14 +535,7 @@ privsep_preauth_child(void) | |||
625 | ssh_gssapi_prepare_supported_oids(); | 535 | ssh_gssapi_prepare_supported_oids(); |
626 | #endif | 536 | #endif |
627 | 537 | ||
628 | arc4random_stir(); | 538 | reseed_prngs(); |
629 | arc4random_buf(rnd, sizeof(rnd)); | ||
630 | #ifdef WITH_OPENSSL | ||
631 | RAND_seed(rnd, sizeof(rnd)); | ||
632 | if ((RAND_bytes((u_char *)rnd, 1)) != 1) | ||
633 | fatal("%s: RAND_bytes failed", __func__); | ||
634 | #endif | ||
635 | explicit_bzero(rnd, sizeof(rnd)); | ||
636 | 539 | ||
637 | /* Demote the private keys to public keys. */ | 540 | /* Demote the private keys to public keys. */ |
638 | demote_sensitive_data(); | 541 | demote_sensitive_data(); |
@@ -689,9 +592,6 @@ privsep_preauth(Authctxt *authctxt) | |||
689 | ssh_sandbox_parent_preauth(box, pid); | 592 | ssh_sandbox_parent_preauth(box, pid); |
690 | monitor_child_preauth(authctxt, pmonitor); | 593 | monitor_child_preauth(authctxt, pmonitor); |
691 | 594 | ||
692 | /* Sync memory */ | ||
693 | monitor_sync(pmonitor); | ||
694 | |||
695 | /* Wait for the child's exit status */ | 595 | /* Wait for the child's exit status */ |
696 | while (waitpid(pid, &status, 0) < 0) { | 596 | while (waitpid(pid, &status, 0) < 0) { |
697 | if (errno == EINTR) | 597 | if (errno == EINTR) |
@@ -731,12 +631,10 @@ privsep_preauth(Authctxt *authctxt) | |||
731 | static void | 631 | static void |
732 | privsep_postauth(Authctxt *authctxt) | 632 | privsep_postauth(Authctxt *authctxt) |
733 | { | 633 | { |
734 | u_int32_t rnd[256]; | ||
735 | |||
736 | #ifdef DISABLE_FD_PASSING | 634 | #ifdef DISABLE_FD_PASSING |
737 | if (1) { | 635 | if (1) { |
738 | #else | 636 | #else |
739 | if (authctxt->pw->pw_uid == 0 || options.use_login) { | 637 | if (authctxt->pw->pw_uid == 0) { |
740 | #endif | 638 | #endif |
741 | /* File descriptor passing is broken or root login */ | 639 | /* File descriptor passing is broken or root login */ |
742 | use_privsep = 0; | 640 | use_privsep = 0; |
@@ -766,14 +664,7 @@ privsep_postauth(Authctxt *authctxt) | |||
766 | /* Demote the private keys to public keys. */ | 664 | /* Demote the private keys to public keys. */ |
767 | demote_sensitive_data(); | 665 | demote_sensitive_data(); |
768 | 666 | ||
769 | arc4random_stir(); | 667 | reseed_prngs(); |
770 | arc4random_buf(rnd, sizeof(rnd)); | ||
771 | #ifdef WITH_OPENSSL | ||
772 | RAND_seed(rnd, sizeof(rnd)); | ||
773 | if ((RAND_bytes((u_char *)rnd, 1)) != 1) | ||
774 | fatal("%s: RAND_bytes failed", __func__); | ||
775 | #endif | ||
776 | explicit_bzero(rnd, sizeof(rnd)); | ||
777 | 668 | ||
778 | /* Drop privileges */ | 669 | /* Drop privileges */ |
779 | do_setusercontext(authctxt->pw); | 670 | do_setusercontext(authctxt->pw); |
@@ -803,7 +694,7 @@ list_hostkey_types(void) | |||
803 | key = sensitive_data.host_keys[i]; | 694 | key = sensitive_data.host_keys[i]; |
804 | if (key == NULL) | 695 | if (key == NULL) |
805 | key = sensitive_data.host_pubkeys[i]; | 696 | key = sensitive_data.host_pubkeys[i]; |
806 | if (key == NULL || key->type == KEY_RSA1) | 697 | if (key == NULL) |
807 | continue; | 698 | continue; |
808 | /* Check that the key is accepted in HostkeyAlgorithms */ | 699 | /* Check that the key is accepted in HostkeyAlgorithms */ |
809 | if (match_pattern_list(sshkey_ssh_name(key), | 700 | if (match_pattern_list(sshkey_ssh_name(key), |
@@ -952,7 +843,7 @@ notify_hostkeys(struct ssh *ssh) | |||
952 | for (i = nkeys = 0; i < options.num_host_key_files; i++) { | 843 | for (i = nkeys = 0; i < options.num_host_key_files; i++) { |
953 | key = get_hostkey_public_by_index(i, ssh); | 844 | key = get_hostkey_public_by_index(i, ssh); |
954 | if (key == NULL || key->type == KEY_UNSPEC || | 845 | if (key == NULL || key->type == KEY_UNSPEC || |
955 | key->type == KEY_RSA1 || sshkey_is_cert(key)) | 846 | sshkey_is_cert(key)) |
956 | continue; | 847 | continue; |
957 | fp = sshkey_fingerprint(key, options.fingerprint_hash, | 848 | fp = sshkey_fingerprint(key, options.fingerprint_hash, |
958 | SSH_FP_DEFAULT); | 849 | SSH_FP_DEFAULT); |
@@ -1018,10 +909,9 @@ usage(void) | |||
1018 | #endif | 909 | #endif |
1019 | ); | 910 | ); |
1020 | fprintf(stderr, | 911 | fprintf(stderr, |
1021 | "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" | 912 | "usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n" |
1022 | " [-E log_file] [-f config_file] [-g login_grace_time]\n" | 913 | " [-E log_file] [-f config_file] [-g login_grace_time]\n" |
1023 | " [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n" | 914 | " [-h host_key_file] [-o option] [-p port] [-u len]\n" |
1024 | " [-u len]\n" | ||
1025 | ); | 915 | ); |
1026 | exit(1); | 916 | exit(1); |
1027 | } | 917 | } |
@@ -1038,13 +928,6 @@ send_rexec_state(int fd, struct sshbuf *conf) | |||
1038 | /* | 928 | /* |
1039 | * Protocol from reexec master to child: | 929 | * Protocol from reexec master to child: |
1040 | * string configuration | 930 | * string configuration |
1041 | * u_int ephemeral_key_follows | ||
1042 | * bignum e (only if ephemeral_key_follows == 1) | ||
1043 | * bignum n " | ||
1044 | * bignum d " | ||
1045 | * bignum iqmp " | ||
1046 | * bignum p " | ||
1047 | * bignum q " | ||
1048 | * string rngseed (only if OpenSSL is not self-seeded) | 931 | * string rngseed (only if OpenSSL is not self-seeded) |
1049 | */ | 932 | */ |
1050 | if ((m = sshbuf_new()) == NULL) | 933 | if ((m = sshbuf_new()) == NULL) |
@@ -1052,28 +935,6 @@ send_rexec_state(int fd, struct sshbuf *conf) | |||
1052 | if ((r = sshbuf_put_stringb(m, conf)) != 0) | 935 | if ((r = sshbuf_put_stringb(m, conf)) != 0) |
1053 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 936 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1054 | 937 | ||
1055 | #ifdef WITH_SSH1 | ||
1056 | if (sensitive_data.server_key != NULL && | ||
1057 | sensitive_data.server_key->type == KEY_RSA1) { | ||
1058 | if ((r = sshbuf_put_u32(m, 1)) != 0 || | ||
1059 | (r = sshbuf_put_bignum1(m, | ||
1060 | sensitive_data.server_key->rsa->e)) != 0 || | ||
1061 | (r = sshbuf_put_bignum1(m, | ||
1062 | sensitive_data.server_key->rsa->n)) != 0 || | ||
1063 | (r = sshbuf_put_bignum1(m, | ||
1064 | sensitive_data.server_key->rsa->d)) != 0 || | ||
1065 | (r = sshbuf_put_bignum1(m, | ||
1066 | sensitive_data.server_key->rsa->iqmp)) != 0 || | ||
1067 | (r = sshbuf_put_bignum1(m, | ||
1068 | sensitive_data.server_key->rsa->p)) != 0 || | ||
1069 | (r = sshbuf_put_bignum1(m, | ||
1070 | sensitive_data.server_key->rsa->q)) != 0) | ||
1071 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1072 | } else | ||
1073 | #endif | ||
1074 | if ((r = sshbuf_put_u32(m, 1)) != 0) | ||
1075 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1076 | |||
1077 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) | 938 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |
1078 | rexec_send_rng_seed(m); | 939 | rexec_send_rng_seed(m); |
1079 | #endif | 940 | #endif |
@@ -1107,24 +968,6 @@ recv_rexec_state(int fd, Buffer *conf) | |||
1107 | buffer_append(conf, cp, len); | 968 | buffer_append(conf, cp, len); |
1108 | free(cp); | 969 | free(cp); |
1109 | 970 | ||
1110 | if (buffer_get_int(&m)) { | ||
1111 | #ifdef WITH_SSH1 | ||
1112 | if (sensitive_data.server_key != NULL) | ||
1113 | key_free(sensitive_data.server_key); | ||
1114 | sensitive_data.server_key = key_new_private(KEY_RSA1); | ||
1115 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); | ||
1116 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); | ||
1117 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); | ||
1118 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); | ||
1119 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); | ||
1120 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); | ||
1121 | if (rsa_generate_additional_parameters( | ||
1122 | sensitive_data.server_key->rsa) != 0) | ||
1123 | fatal("%s: rsa_generate_additional_parameters " | ||
1124 | "error", __func__); | ||
1125 | #endif | ||
1126 | } | ||
1127 | |||
1128 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) | 971 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |
1129 | rexec_recv_rng_seed(&m); | 972 | rexec_recv_rng_seed(&m); |
1130 | #endif | 973 | #endif |
@@ -1248,7 +1091,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1248 | { | 1091 | { |
1249 | fd_set *fdset; | 1092 | fd_set *fdset; |
1250 | int i, j, ret, maxfd; | 1093 | int i, j, ret, maxfd; |
1251 | int key_used = 0, startups = 0; | 1094 | int startups = 0; |
1252 | int startup_p[2] = { -1 , -1 }; | 1095 | int startup_p[2] = { -1 , -1 }; |
1253 | struct sockaddr_storage from; | 1096 | struct sockaddr_storage from; |
1254 | socklen_t fromlen; | 1097 | socklen_t fromlen; |
@@ -1295,11 +1138,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1295 | unlink(options.pid_file); | 1138 | unlink(options.pid_file); |
1296 | exit(received_sigterm == SIGTERM ? 0 : 255); | 1139 | exit(received_sigterm == SIGTERM ? 0 : 255); |
1297 | } | 1140 | } |
1298 | if (key_used && key_do_regen) { | ||
1299 | generate_ephemeral_server_key(); | ||
1300 | key_used = 0; | ||
1301 | key_do_regen = 0; | ||
1302 | } | ||
1303 | if (ret < 0) | 1141 | if (ret < 0) |
1304 | continue; | 1142 | continue; |
1305 | 1143 | ||
@@ -1336,7 +1174,15 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1336 | continue; | 1174 | continue; |
1337 | } | 1175 | } |
1338 | if (drop_connection(startups) == 1) { | 1176 | if (drop_connection(startups) == 1) { |
1339 | debug("drop connection #%d", startups); | 1177 | char *laddr = get_local_ipaddr(*newsock); |
1178 | char *raddr = get_peer_ipaddr(*newsock); | ||
1179 | |||
1180 | verbose("drop connection #%d from [%s]:%d " | ||
1181 | "on [%s]:%d past MaxStartups", startups, | ||
1182 | raddr, get_peer_port(*newsock), | ||
1183 | laddr, get_local_port(*newsock)); | ||
1184 | free(laddr); | ||
1185 | free(raddr); | ||
1340 | close(*newsock); | 1186 | close(*newsock); |
1341 | continue; | 1187 | continue; |
1342 | } | 1188 | } |
@@ -1434,19 +1280,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1434 | close(config_s[0]); | 1280 | close(config_s[0]); |
1435 | close(config_s[1]); | 1281 | close(config_s[1]); |
1436 | } | 1282 | } |
1437 | |||
1438 | /* | ||
1439 | * Mark that the key has been used (it | ||
1440 | * was "given" to the child). | ||
1441 | */ | ||
1442 | if ((options.protocol & SSH_PROTO_1) && | ||
1443 | key_used == 0) { | ||
1444 | /* Schedule server key regeneration alarm. */ | ||
1445 | signal(SIGALRM, key_regeneration_alarm); | ||
1446 | alarm(options.key_regeneration_time); | ||
1447 | key_used = 1; | ||
1448 | } | ||
1449 | |||
1450 | close(*newsock); | 1283 | close(*newsock); |
1451 | 1284 | ||
1452 | /* | 1285 | /* |
@@ -1486,8 +1319,8 @@ check_ip_options(struct ssh *ssh) | |||
1486 | #ifdef IP_OPTIONS | 1319 | #ifdef IP_OPTIONS |
1487 | int sock_in = ssh_packet_get_connection_in(ssh); | 1320 | int sock_in = ssh_packet_get_connection_in(ssh); |
1488 | struct sockaddr_storage from; | 1321 | struct sockaddr_storage from; |
1489 | socklen_t option_size, i, fromlen = sizeof(from); | ||
1490 | u_char opts[200]; | 1322 | u_char opts[200]; |
1323 | socklen_t i, option_size = sizeof(opts), fromlen = sizeof(from); | ||
1491 | char text[sizeof(opts) * 3 + 1]; | 1324 | char text[sizeof(opts) * 3 + 1]; |
1492 | 1325 | ||
1493 | memset(&from, 0, sizeof(from)); | 1326 | memset(&from, 0, sizeof(from)); |
@@ -1520,7 +1353,7 @@ main(int ac, char **av) | |||
1520 | struct ssh *ssh = NULL; | 1353 | struct ssh *ssh = NULL; |
1521 | extern char *optarg; | 1354 | extern char *optarg; |
1522 | extern int optind; | 1355 | extern int optind; |
1523 | int r, opt, i, j, on = 1; | 1356 | int r, opt, i, j, on = 1, already_daemon; |
1524 | int sock_in = -1, sock_out = -1, newsock = -1; | 1357 | int sock_in = -1, sock_out = -1, newsock = -1; |
1525 | const char *remote_ip; | 1358 | const char *remote_ip; |
1526 | int remote_port; | 1359 | int remote_port; |
@@ -1619,8 +1452,7 @@ main(int ac, char **av) | |||
1619 | options.log_level = SYSLOG_LEVEL_QUIET; | 1452 | options.log_level = SYSLOG_LEVEL_QUIET; |
1620 | break; | 1453 | break; |
1621 | case 'b': | 1454 | case 'b': |
1622 | options.server_key_bits = (int)strtonum(optarg, 256, | 1455 | /* protocol 1, ignored */ |
1623 | 32768, NULL); | ||
1624 | break; | 1456 | break; |
1625 | case 'p': | 1457 | case 'p': |
1626 | options.ports_from_cmdline = 1; | 1458 | options.ports_from_cmdline = 1; |
@@ -1641,10 +1473,7 @@ main(int ac, char **av) | |||
1641 | } | 1473 | } |
1642 | break; | 1474 | break; |
1643 | case 'k': | 1475 | case 'k': |
1644 | if ((options.key_regeneration_time = convtime(optarg)) == -1) { | 1476 | /* protocol 1, ignored */ |
1645 | fprintf(stderr, "Invalid key regeneration interval.\n"); | ||
1646 | exit(1); | ||
1647 | } | ||
1648 | break; | 1477 | break; |
1649 | case 'h': | 1478 | case 'h': |
1650 | if (options.num_host_key_files >= MAX_HOSTKEYS) { | 1479 | if (options.num_host_key_files >= MAX_HOSTKEYS) { |
@@ -1726,9 +1555,6 @@ main(int ac, char **av) | |||
1726 | drop_cray_privs(); | 1555 | drop_cray_privs(); |
1727 | #endif | 1556 | #endif |
1728 | 1557 | ||
1729 | sensitive_data.server_key = NULL; | ||
1730 | sensitive_data.ssh1_host_key = NULL; | ||
1731 | sensitive_data.have_ssh1_key = 0; | ||
1732 | sensitive_data.have_ssh2_key = 0; | 1558 | sensitive_data.have_ssh2_key = 0; |
1733 | 1559 | ||
1734 | /* | 1560 | /* |
@@ -1781,9 +1607,6 @@ main(int ac, char **av) | |||
1781 | * and warns for trivial misconfigurations that could break login. | 1607 | * and warns for trivial misconfigurations that could break login. |
1782 | */ | 1608 | */ |
1783 | if (options.num_auth_methods != 0) { | 1609 | if (options.num_auth_methods != 0) { |
1784 | if ((options.protocol & SSH_PROTO_1)) | ||
1785 | fatal("AuthenticationMethods is not supported with " | ||
1786 | "SSH protocol 1"); | ||
1787 | for (n = 0; n < options.num_auth_methods; n++) { | 1610 | for (n = 0; n < options.num_auth_methods; n++) { |
1788 | if (auth2_methods_valid(options.auth_methods[n], | 1611 | if (auth2_methods_valid(options.auth_methods[n], |
1789 | 1) == 0) | 1612 | 1) == 0) |
@@ -1852,8 +1675,7 @@ main(int ac, char **av) | |||
1852 | sensitive_data.host_keys[i] = key; | 1675 | sensitive_data.host_keys[i] = key; |
1853 | sensitive_data.host_pubkeys[i] = pubkey; | 1676 | sensitive_data.host_pubkeys[i] = pubkey; |
1854 | 1677 | ||
1855 | if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && | 1678 | if (key == NULL && pubkey != NULL && have_agent) { |
1856 | have_agent) { | ||
1857 | debug("will rely on agent for hostkey %s", | 1679 | debug("will rely on agent for hostkey %s", |
1858 | options.host_key_files[i]); | 1680 | options.host_key_files[i]); |
1859 | keytype = pubkey->type; | 1681 | keytype = pubkey->type; |
@@ -1868,10 +1690,6 @@ main(int ac, char **av) | |||
1868 | } | 1690 | } |
1869 | 1691 | ||
1870 | switch (keytype) { | 1692 | switch (keytype) { |
1871 | case KEY_RSA1: | ||
1872 | sensitive_data.ssh1_host_key = key; | ||
1873 | sensitive_data.have_ssh1_key = 1; | ||
1874 | break; | ||
1875 | case KEY_RSA: | 1693 | case KEY_RSA: |
1876 | case KEY_DSA: | 1694 | case KEY_DSA: |
1877 | case KEY_ECDSA: | 1695 | case KEY_ECDSA: |
@@ -1884,19 +1702,10 @@ main(int ac, char **av) | |||
1884 | SSH_FP_DEFAULT)) == NULL) | 1702 | SSH_FP_DEFAULT)) == NULL) |
1885 | fatal("sshkey_fingerprint failed"); | 1703 | fatal("sshkey_fingerprint failed"); |
1886 | debug("%s host key #%d: %s %s", | 1704 | debug("%s host key #%d: %s %s", |
1887 | key ? "private" : "agent", i, keytype == KEY_RSA1 ? | 1705 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); |
1888 | sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); | ||
1889 | free(fp); | 1706 | free(fp); |
1890 | } | 1707 | } |
1891 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { | 1708 | if (!sensitive_data.have_ssh2_key) { |
1892 | logit("Disabling protocol version 1. Could not load host key"); | ||
1893 | options.protocol &= ~SSH_PROTO_1; | ||
1894 | } | ||
1895 | if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { | ||
1896 | logit("Disabling protocol version 2. Could not load host key"); | ||
1897 | options.protocol &= ~SSH_PROTO_2; | ||
1898 | } | ||
1899 | if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { | ||
1900 | logit("sshd: no hostkeys available -- exiting."); | 1709 | logit("sshd: no hostkeys available -- exiting."); |
1901 | exit(1); | 1710 | exit(1); |
1902 | } | 1711 | } |
@@ -1944,33 +1753,6 @@ main(int ac, char **av) | |||
1944 | key_type(key)); | 1753 | key_type(key)); |
1945 | } | 1754 | } |
1946 | 1755 | ||
1947 | #ifdef WITH_SSH1 | ||
1948 | /* Check certain values for sanity. */ | ||
1949 | if (options.protocol & SSH_PROTO_1) { | ||
1950 | if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE || | ||
1951 | options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { | ||
1952 | fprintf(stderr, "Bad server key size.\n"); | ||
1953 | exit(1); | ||
1954 | } | ||
1955 | /* | ||
1956 | * Check that server and host key lengths differ sufficiently. This | ||
1957 | * is necessary to make double encryption work with rsaref. Oh, I | ||
1958 | * hate software patents. I dont know if this can go? Niels | ||
1959 | */ | ||
1960 | if (options.server_key_bits > | ||
1961 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - | ||
1962 | SSH_KEY_BITS_RESERVED && options.server_key_bits < | ||
1963 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + | ||
1964 | SSH_KEY_BITS_RESERVED) { | ||
1965 | options.server_key_bits = | ||
1966 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + | ||
1967 | SSH_KEY_BITS_RESERVED; | ||
1968 | debug("Forcing server key to %d bits to make it differ from host key.", | ||
1969 | options.server_key_bits); | ||
1970 | } | ||
1971 | } | ||
1972 | #endif | ||
1973 | |||
1974 | if (use_privsep) { | 1756 | if (use_privsep) { |
1975 | struct stat st; | 1757 | struct stat st; |
1976 | 1758 | ||
@@ -2030,25 +1812,17 @@ main(int ac, char **av) | |||
2030 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1812 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
2031 | 1813 | ||
2032 | /* | 1814 | /* |
2033 | * If not in debugging mode, and not started from inetd, disconnect | 1815 | * If not in debugging mode, not started from inetd and not already |
2034 | * from the controlling terminal, and fork. The original process | 1816 | * daemonized (eg re-exec via SIGHUP), disconnect from the controlling |
2035 | * exits. | 1817 | * terminal, and fork. The original process exits. |
2036 | */ | 1818 | */ |
2037 | if (!(debug_flag || inetd_flag || no_daemon_flag)) { | 1819 | already_daemon = daemonized(); |
2038 | #ifdef TIOCNOTTY | 1820 | if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) { |
2039 | int fd; | 1821 | |
2040 | #endif /* TIOCNOTTY */ | ||
2041 | if (daemon(0, 0) < 0) | 1822 | if (daemon(0, 0) < 0) |
2042 | fatal("daemon() failed: %.200s", strerror(errno)); | 1823 | fatal("daemon() failed: %.200s", strerror(errno)); |
2043 | 1824 | ||
2044 | /* Disconnect from the controlling tty. */ | 1825 | disconnect_controlling_tty(); |
2045 | #ifdef TIOCNOTTY | ||
2046 | fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); | ||
2047 | if (fd >= 0) { | ||
2048 | (void) ioctl(fd, TIOCNOTTY, NULL); | ||
2049 | close(fd); | ||
2050 | } | ||
2051 | #endif /* TIOCNOTTY */ | ||
2052 | } | 1826 | } |
2053 | /* Reinitialize the log (because of the fork above). */ | 1827 | /* Reinitialize the log (because of the fork above). */ |
2054 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1828 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
@@ -2068,9 +1842,6 @@ main(int ac, char **av) | |||
2068 | platform_pre_listen(); | 1842 | platform_pre_listen(); |
2069 | server_listen(); | 1843 | server_listen(); |
2070 | 1844 | ||
2071 | if (options.protocol & SSH_PROTO_1) | ||
2072 | generate_ephemeral_server_key(); | ||
2073 | |||
2074 | signal(SIGHUP, sighup_handler); | 1845 | signal(SIGHUP, sighup_handler); |
2075 | signal(SIGCHLD, main_sigchld_handler); | 1846 | signal(SIGCHLD, main_sigchld_handler); |
2076 | signal(SIGTERM, sigterm_handler); | 1847 | signal(SIGTERM, sigterm_handler); |
@@ -2220,11 +1991,6 @@ main(int ac, char **av) | |||
2220 | alarm(options.login_grace_time); | 1991 | alarm(options.login_grace_time); |
2221 | 1992 | ||
2222 | sshd_exchange_identification(ssh, sock_in, sock_out); | 1993 | sshd_exchange_identification(ssh, sock_in, sock_out); |
2223 | |||
2224 | /* In inetd mode, generate ephemeral key only for proto 1 connections */ | ||
2225 | if (!compat20 && inetd_flag && sensitive_data.server_key == NULL) | ||
2226 | generate_ephemeral_server_key(); | ||
2227 | |||
2228 | packet_set_nonblocking(); | 1994 | packet_set_nonblocking(); |
2229 | 1995 | ||
2230 | /* allocate authentication context */ | 1996 | /* allocate authentication context */ |
@@ -2242,7 +2008,7 @@ main(int ac, char **av) | |||
2242 | if (use_privsep) { | 2008 | if (use_privsep) { |
2243 | if (privsep_preauth(authctxt) == 1) | 2009 | if (privsep_preauth(authctxt) == 1) |
2244 | goto authenticated; | 2010 | goto authenticated; |
2245 | } else if (compat20 && have_agent) { | 2011 | } else if (have_agent) { |
2246 | if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { | 2012 | if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { |
2247 | error("Unable to get agent socket: %s", ssh_err(r)); | 2013 | error("Unable to get agent socket: %s", ssh_err(r)); |
2248 | have_agent = 0; | 2014 | have_agent = 0; |
@@ -2251,17 +2017,9 @@ main(int ac, char **av) | |||
2251 | 2017 | ||
2252 | /* perform the key exchange */ | 2018 | /* perform the key exchange */ |
2253 | /* authenticate user and start session */ | 2019 | /* authenticate user and start session */ |
2254 | if (compat20) { | 2020 | do_ssh2_kex(); |
2255 | do_ssh2_kex(); | 2021 | do_authentication2(authctxt); |
2256 | do_authentication2(authctxt); | 2022 | |
2257 | } else { | ||
2258 | #ifdef WITH_SSH1 | ||
2259 | do_ssh1_kex(); | ||
2260 | do_authentication(authctxt); | ||
2261 | #else | ||
2262 | fatal("ssh1 not supported"); | ||
2263 | #endif | ||
2264 | } | ||
2265 | /* | 2023 | /* |
2266 | * If we use privilege separation, the unprivileged child transfers | 2024 | * If we use privilege separation, the unprivileged child transfers |
2267 | * the current keystate and exits | 2025 | * the current keystate and exits |
@@ -2309,16 +2067,13 @@ main(int ac, char **av) | |||
2309 | if (use_privsep) { | 2067 | if (use_privsep) { |
2310 | privsep_postauth(authctxt); | 2068 | privsep_postauth(authctxt); |
2311 | /* the monitor process [priv] will not return */ | 2069 | /* the monitor process [priv] will not return */ |
2312 | if (!compat20) | ||
2313 | destroy_sensitive_data(); | ||
2314 | } | 2070 | } |
2315 | 2071 | ||
2316 | packet_set_timeout(options.client_alive_interval, | 2072 | packet_set_timeout(options.client_alive_interval, |
2317 | options.client_alive_count_max); | 2073 | options.client_alive_count_max); |
2318 | 2074 | ||
2319 | /* Try to send all our hostkeys to the client */ | 2075 | /* Try to send all our hostkeys to the client */ |
2320 | if (compat20) | 2076 | notify_hostkeys(active_state); |
2321 | notify_hostkeys(active_state); | ||
2322 | 2077 | ||
2323 | /* Start session. */ | 2078 | /* Start session. */ |
2324 | do_authenticated(authctxt); | 2079 | do_authenticated(authctxt); |
@@ -2347,229 +2102,6 @@ main(int ac, char **av) | |||
2347 | exit(0); | 2102 | exit(0); |
2348 | } | 2103 | } |
2349 | 2104 | ||
2350 | #ifdef WITH_SSH1 | ||
2351 | /* | ||
2352 | * Decrypt session_key_int using our private server key and private host key | ||
2353 | * (key with larger modulus first). | ||
2354 | */ | ||
2355 | int | ||
2356 | ssh1_session_key(BIGNUM *session_key_int) | ||
2357 | { | ||
2358 | struct ssh *ssh = active_state; /* XXX */ | ||
2359 | int rsafail = 0; | ||
2360 | |||
2361 | if (BN_cmp(sensitive_data.server_key->rsa->n, | ||
2362 | sensitive_data.ssh1_host_key->rsa->n) > 0) { | ||
2363 | /* Server key has bigger modulus. */ | ||
2364 | if (BN_num_bits(sensitive_data.server_key->rsa->n) < | ||
2365 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + | ||
2366 | SSH_KEY_BITS_RESERVED) { | ||
2367 | fatal("do_connection: %s port %d: " | ||
2368 | "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", | ||
2369 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
2370 | BN_num_bits(sensitive_data.server_key->rsa->n), | ||
2371 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), | ||
2372 | SSH_KEY_BITS_RESERVED); | ||
2373 | } | ||
2374 | if (rsa_private_decrypt(session_key_int, session_key_int, | ||
2375 | sensitive_data.server_key->rsa) != 0) | ||
2376 | rsafail++; | ||
2377 | if (rsa_private_decrypt(session_key_int, session_key_int, | ||
2378 | sensitive_data.ssh1_host_key->rsa) != 0) | ||
2379 | rsafail++; | ||
2380 | } else { | ||
2381 | /* Host key has bigger modulus (or they are equal). */ | ||
2382 | if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < | ||
2383 | BN_num_bits(sensitive_data.server_key->rsa->n) + | ||
2384 | SSH_KEY_BITS_RESERVED) { | ||
2385 | fatal("do_connection: %s port %d: " | ||
2386 | "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", | ||
2387 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
2388 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), | ||
2389 | BN_num_bits(sensitive_data.server_key->rsa->n), | ||
2390 | SSH_KEY_BITS_RESERVED); | ||
2391 | } | ||
2392 | if (rsa_private_decrypt(session_key_int, session_key_int, | ||
2393 | sensitive_data.ssh1_host_key->rsa) != 0) | ||
2394 | rsafail++; | ||
2395 | if (rsa_private_decrypt(session_key_int, session_key_int, | ||
2396 | sensitive_data.server_key->rsa) != 0) | ||
2397 | rsafail++; | ||
2398 | } | ||
2399 | return (rsafail); | ||
2400 | } | ||
2401 | |||
2402 | /* | ||
2403 | * SSH1 key exchange | ||
2404 | */ | ||
2405 | static void | ||
2406 | do_ssh1_kex(void) | ||
2407 | { | ||
2408 | struct ssh *ssh = active_state; /* XXX */ | ||
2409 | int i, len; | ||
2410 | int rsafail = 0; | ||
2411 | BIGNUM *session_key_int, *fake_key_int, *real_key_int; | ||
2412 | u_char session_key[SSH_SESSION_KEY_LENGTH]; | ||
2413 | u_char fake_key_bytes[4096 / 8]; | ||
2414 | size_t fake_key_len; | ||
2415 | u_char cookie[8]; | ||
2416 | u_int cipher_type, auth_mask, protocol_flags; | ||
2417 | |||
2418 | /* | ||
2419 | * Generate check bytes that the client must send back in the user | ||
2420 | * packet in order for it to be accepted; this is used to defy ip | ||
2421 | * spoofing attacks. Note that this only works against somebody | ||
2422 | * doing IP spoofing from a remote machine; any machine on the local | ||
2423 | * network can still see outgoing packets and catch the random | ||
2424 | * cookie. This only affects rhosts authentication, and this is one | ||
2425 | * of the reasons why it is inherently insecure. | ||
2426 | */ | ||
2427 | arc4random_buf(cookie, sizeof(cookie)); | ||
2428 | |||
2429 | /* | ||
2430 | * Send our public key. We include in the packet 64 bits of random | ||
2431 | * data that must be matched in the reply in order to prevent IP | ||
2432 | * spoofing. | ||
2433 | */ | ||
2434 | packet_start(SSH_SMSG_PUBLIC_KEY); | ||
2435 | for (i = 0; i < 8; i++) | ||
2436 | packet_put_char(cookie[i]); | ||
2437 | |||
2438 | /* Store our public server RSA key. */ | ||
2439 | packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); | ||
2440 | packet_put_bignum(sensitive_data.server_key->rsa->e); | ||
2441 | packet_put_bignum(sensitive_data.server_key->rsa->n); | ||
2442 | |||
2443 | /* Store our public host RSA key. */ | ||
2444 | packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); | ||
2445 | packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); | ||
2446 | packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); | ||
2447 | |||
2448 | /* Put protocol flags. */ | ||
2449 | packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); | ||
2450 | |||
2451 | /* Declare which ciphers we support. */ | ||
2452 | packet_put_int(cipher_mask_ssh1(0)); | ||
2453 | |||
2454 | /* Declare supported authentication types. */ | ||
2455 | auth_mask = 0; | ||
2456 | if (options.rhosts_rsa_authentication) | ||
2457 | auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; | ||
2458 | if (options.rsa_authentication) | ||
2459 | auth_mask |= 1 << SSH_AUTH_RSA; | ||
2460 | if (options.challenge_response_authentication == 1) | ||
2461 | auth_mask |= 1 << SSH_AUTH_TIS; | ||
2462 | if (options.password_authentication) | ||
2463 | auth_mask |= 1 << SSH_AUTH_PASSWORD; | ||
2464 | packet_put_int(auth_mask); | ||
2465 | |||
2466 | /* Send the packet and wait for it to be sent. */ | ||
2467 | packet_send(); | ||
2468 | packet_write_wait(); | ||
2469 | |||
2470 | debug("Sent %d bit server key and %d bit host key.", | ||
2471 | BN_num_bits(sensitive_data.server_key->rsa->n), | ||
2472 | BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); | ||
2473 | |||
2474 | /* Read clients reply (cipher type and session key). */ | ||
2475 | packet_read_expect(SSH_CMSG_SESSION_KEY); | ||
2476 | |||
2477 | /* Get cipher type and check whether we accept this. */ | ||
2478 | cipher_type = packet_get_char(); | ||
2479 | |||
2480 | if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) | ||
2481 | packet_disconnect("Warning: client selects unsupported cipher."); | ||
2482 | |||
2483 | /* Get check bytes from the packet. These must match those we | ||
2484 | sent earlier with the public key packet. */ | ||
2485 | for (i = 0; i < 8; i++) | ||
2486 | if (cookie[i] != packet_get_char()) | ||
2487 | packet_disconnect("IP Spoofing check bytes do not match."); | ||
2488 | |||
2489 | debug("Encryption type: %.200s", cipher_name(cipher_type)); | ||
2490 | |||
2491 | /* Get the encrypted integer. */ | ||
2492 | if ((real_key_int = BN_new()) == NULL) | ||
2493 | fatal("do_ssh1_kex: BN_new failed"); | ||
2494 | packet_get_bignum(real_key_int); | ||
2495 | |||
2496 | protocol_flags = packet_get_int(); | ||
2497 | packet_set_protocol_flags(protocol_flags); | ||
2498 | packet_check_eom(); | ||
2499 | |||
2500 | /* Setup a fake key in case RSA decryption fails */ | ||
2501 | if ((fake_key_int = BN_new()) == NULL) | ||
2502 | fatal("do_ssh1_kex: BN_new failed"); | ||
2503 | fake_key_len = BN_num_bytes(real_key_int); | ||
2504 | if (fake_key_len > sizeof(fake_key_bytes)) | ||
2505 | fake_key_len = sizeof(fake_key_bytes); | ||
2506 | arc4random_buf(fake_key_bytes, fake_key_len); | ||
2507 | if (BN_bin2bn(fake_key_bytes, fake_key_len, fake_key_int) == NULL) | ||
2508 | fatal("do_ssh1_kex: BN_bin2bn failed"); | ||
2509 | |||
2510 | /* Decrypt real_key_int using host/server keys */ | ||
2511 | rsafail = PRIVSEP(ssh1_session_key(real_key_int)); | ||
2512 | /* If decryption failed, use the fake key. Else, the real key. */ | ||
2513 | if (rsafail) | ||
2514 | session_key_int = fake_key_int; | ||
2515 | else | ||
2516 | session_key_int = real_key_int; | ||
2517 | |||
2518 | /* | ||
2519 | * Extract session key from the decrypted integer. The key is in the | ||
2520 | * least significant 256 bits of the integer; the first byte of the | ||
2521 | * key is in the highest bits. | ||
2522 | */ | ||
2523 | (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); | ||
2524 | len = BN_num_bytes(session_key_int); | ||
2525 | if (len < 0 || (u_int)len > sizeof(session_key)) { | ||
2526 | error("%s: bad session key len from %s port %d: " | ||
2527 | "session_key_int %d > sizeof(session_key) %lu", __func__, | ||
2528 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
2529 | len, (u_long)sizeof(session_key)); | ||
2530 | rsafail++; | ||
2531 | } else { | ||
2532 | explicit_bzero(session_key, sizeof(session_key)); | ||
2533 | BN_bn2bin(session_key_int, | ||
2534 | session_key + sizeof(session_key) - len); | ||
2535 | |||
2536 | derive_ssh1_session_id( | ||
2537 | sensitive_data.ssh1_host_key->rsa->n, | ||
2538 | sensitive_data.server_key->rsa->n, | ||
2539 | cookie, session_id); | ||
2540 | /* | ||
2541 | * Xor the first 16 bytes of the session key with the | ||
2542 | * session id. | ||
2543 | */ | ||
2544 | for (i = 0; i < 16; i++) | ||
2545 | session_key[i] ^= session_id[i]; | ||
2546 | } | ||
2547 | |||
2548 | /* Destroy the private and public keys. No longer. */ | ||
2549 | destroy_sensitive_data(); | ||
2550 | |||
2551 | if (use_privsep) | ||
2552 | mm_ssh1_session_id(session_id); | ||
2553 | |||
2554 | /* Destroy the decrypted integer. It is no longer needed. */ | ||
2555 | BN_clear_free(real_key_int); | ||
2556 | BN_clear_free(fake_key_int); | ||
2557 | |||
2558 | /* Set the session key. From this on all communications will be encrypted. */ | ||
2559 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); | ||
2560 | |||
2561 | /* Destroy our copy of the session key. It is no longer needed. */ | ||
2562 | explicit_bzero(session_key, sizeof(session_key)); | ||
2563 | |||
2564 | debug("Received session key; encryption turned on."); | ||
2565 | |||
2566 | /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ | ||
2567 | packet_start(SSH_SMSG_SUCCESS); | ||
2568 | packet_send(); | ||
2569 | packet_write_wait(); | ||
2570 | } | ||
2571 | #endif | ||
2572 | |||
2573 | int | 2105 | int |
2574 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, | 2106 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, |
2575 | const u_char *data, size_t dlen, const char *alg, u_int flag) | 2107 | const u_char *data, size_t dlen, const char *alg, u_int flag) |
@@ -2618,10 +2150,6 @@ do_ssh2_kex(void) | |||
2618 | if (options.compression == COMP_NONE) { | 2150 | if (options.compression == COMP_NONE) { |
2619 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = | 2151 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = |
2620 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; | 2152 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; |
2621 | } else if (options.compression == COMP_DELAYED) { | ||
2622 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = | ||
2623 | myproposal[PROPOSAL_COMP_ALGS_STOC] = | ||
2624 | "none,zlib@openssh.com"; | ||
2625 | } | 2153 | } |
2626 | 2154 | ||
2627 | if (options.rekey_limit || options.rekey_interval) | 2155 | if (options.rekey_limit || options.rekey_interval) |