diff options
author | Colin Watson <cjwatson@debian.org> | 2013-09-14 23:42:11 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2013-09-14 23:42:11 +0100 |
commit | 327155e6824b3ee13837bdde04e4eb47e147ff46 (patch) | |
tree | 8f8743122403c7a2e6ed919156711fb1520c657f /ssh.c | |
parent | 0334ce32304e9ba2a10ee5ca49ca6e8ff3ba6cf4 (diff) | |
parent | 74e339b8f8936bc0d985e053a076d0c9b5e9ea51 (diff) |
* New upstream release (http://www.openssh.com/txt/release-6.3).
- sftp(1): add support for resuming partial downloads using the "reget"
command and on the sftp commandline or on the "get" commandline using
the "-a" (append) option (closes: #158590).
- ssh(1): add an "IgnoreUnknown" configuration option to selectively
suppress errors arising from unknown configuration directives (closes:
#436052).
- sftp(1): update progressmeter when data is acknowledged, not when it's
sent (partially addresses #708372).
- ssh(1): do not fatally exit when attempting to cleanup multiplexing-
created channels that are incompletely opened (closes: #651357).
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 101 |
1 files changed, 67 insertions, 34 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.373 2013/02/22 22:09:01 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.381 2013/07/25 00:29:10 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 |
@@ -197,9 +197,9 @@ usage(void) | |||
197 | { | 197 | { |
198 | fprintf(stderr, | 198 | fprintf(stderr, |
199 | "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" | 199 | "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" |
200 | " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" | 200 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" |
201 | " [-I pkcs11] [-i identity_file]\n" | 201 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" |
202 | " [-L [bind_address:]port:host:hostport]\n" | 202 | " [-L [bind_address:]port:host:hostport] [-Q protocol_feature]\n" |
203 | " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" | 203 | " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" |
204 | " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" | 204 | " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" |
205 | " [-W host:port] [-w local_tun[:remote_tun]]\n" | 205 | " [-W host:port] [-w local_tun[:remote_tun]]\n" |
@@ -226,7 +226,7 @@ tilde_expand_paths(char **paths, u_int num_paths) | |||
226 | 226 | ||
227 | for (i = 0; i < num_paths; i++) { | 227 | for (i = 0; i < num_paths; i++) { |
228 | cp = tilde_expand_filename(paths[i], original_real_uid); | 228 | cp = tilde_expand_filename(paths[i], original_real_uid); |
229 | xfree(paths[i]); | 229 | free(paths[i]); |
230 | paths[i] = cp; | 230 | paths[i] = cp; |
231 | } | 231 | } |
232 | } | 232 | } |
@@ -238,7 +238,7 @@ int | |||
238 | main(int ac, char **av) | 238 | main(int ac, char **av) |
239 | { | 239 | { |
240 | int i, r, opt, exit_status, use_syslog; | 240 | int i, r, opt, exit_status, use_syslog; |
241 | char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg; | 241 | char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile; |
242 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 242 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
243 | struct stat st; | 243 | struct stat st; |
244 | struct passwd *pw; | 244 | struct passwd *pw; |
@@ -299,7 +299,7 @@ main(int ac, char **av) | |||
299 | /* Get user data. */ | 299 | /* Get user data. */ |
300 | pw = getpwuid(original_real_uid); | 300 | pw = getpwuid(original_real_uid); |
301 | if (!pw) { | 301 | if (!pw) { |
302 | logit("You don't exist, go away!"); | 302 | logit("No user exists for uid %lu", (u_long)original_real_uid); |
303 | exit(255); | 303 | exit(255); |
304 | } | 304 | } |
305 | /* Take a copy of the returned structure. */ | 305 | /* Take a copy of the returned structure. */ |
@@ -322,11 +322,12 @@ main(int ac, char **av) | |||
322 | /* Parse command-line arguments. */ | 322 | /* Parse command-line arguments. */ |
323 | host = NULL; | 323 | host = NULL; |
324 | use_syslog = 0; | 324 | use_syslog = 0; |
325 | logfile = NULL; | ||
325 | argv0 = av[0]; | 326 | argv0 = av[0]; |
326 | 327 | ||
327 | again: | 328 | again: |
328 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" | 329 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" |
329 | "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { | 330 | "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { |
330 | switch (opt) { | 331 | switch (opt) { |
331 | case '1': | 332 | case '1': |
332 | options.protocol = SSH_PROTO_1; | 333 | options.protocol = SSH_PROTO_1; |
@@ -356,6 +357,9 @@ main(int ac, char **av) | |||
356 | case 'y': | 357 | case 'y': |
357 | use_syslog = 1; | 358 | use_syslog = 1; |
358 | break; | 359 | break; |
360 | case 'E': | ||
361 | logfile = xstrdup(optarg); | ||
362 | break; | ||
359 | case 'Y': | 363 | case 'Y': |
360 | options.forward_x11 = 1; | 364 | options.forward_x11 = 1; |
361 | options.forward_x11_trusted = 1; | 365 | options.forward_x11_trusted = 1; |
@@ -385,6 +389,22 @@ main(int ac, char **av) | |||
385 | case 'P': /* deprecated */ | 389 | case 'P': /* deprecated */ |
386 | options.use_privileged_port = 0; | 390 | options.use_privileged_port = 0; |
387 | break; | 391 | break; |
392 | case 'Q': /* deprecated */ | ||
393 | cp = NULL; | ||
394 | if (strcasecmp(optarg, "cipher") == 0) | ||
395 | cp = cipher_alg_list(); | ||
396 | else if (strcasecmp(optarg, "mac") == 0) | ||
397 | cp = mac_alg_list(); | ||
398 | else if (strcasecmp(optarg, "kex") == 0) | ||
399 | cp = kex_alg_list(); | ||
400 | else if (strcasecmp(optarg, "key") == 0) | ||
401 | cp = key_alg_list(); | ||
402 | if (cp == NULL) | ||
403 | fatal("Unsupported query \"%s\"", optarg); | ||
404 | printf("%s\n", cp); | ||
405 | free(cp); | ||
406 | exit(0); | ||
407 | break; | ||
388 | case 'a': | 408 | case 'a': |
389 | options.forward_agent = 0; | 409 | options.forward_agent = 0; |
390 | break; | 410 | break; |
@@ -427,9 +447,8 @@ main(int ac, char **av) | |||
427 | } else { | 447 | } else { |
428 | if (options.log_level < SYSLOG_LEVEL_DEBUG3) | 448 | if (options.log_level < SYSLOG_LEVEL_DEBUG3) |
429 | options.log_level++; | 449 | options.log_level++; |
430 | break; | ||
431 | } | 450 | } |
432 | /* FALLTHROUGH */ | 451 | break; |
433 | case 'V': | 452 | case 'V': |
434 | fprintf(stderr, "%s, %s\n", | 453 | fprintf(stderr, "%s, %s\n", |
435 | SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); | 454 | SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); |
@@ -454,7 +473,7 @@ main(int ac, char **av) | |||
454 | if (parse_forward(&fwd, optarg, 1, 0)) { | 473 | if (parse_forward(&fwd, optarg, 1, 0)) { |
455 | stdio_forward_host = fwd.listen_host; | 474 | stdio_forward_host = fwd.listen_host; |
456 | stdio_forward_port = fwd.listen_port; | 475 | stdio_forward_port = fwd.listen_port; |
457 | xfree(fwd.connect_host); | 476 | free(fwd.connect_host); |
458 | } else { | 477 | } else { |
459 | fprintf(stderr, | 478 | fprintf(stderr, |
460 | "Bad stdio forwarding specification '%s'\n", | 479 | "Bad stdio forwarding specification '%s'\n", |
@@ -582,7 +601,7 @@ main(int ac, char **av) | |||
582 | line, "command-line", 0, &dummy, SSHCONF_USERCONF) | 601 | line, "command-line", 0, &dummy, SSHCONF_USERCONF) |
583 | != 0) | 602 | != 0) |
584 | exit(255); | 603 | exit(255); |
585 | xfree(line); | 604 | free(line); |
586 | break; | 605 | break; |
587 | case 's': | 606 | case 's': |
588 | subsystem_flag = 1; | 607 | subsystem_flag = 1; |
@@ -663,18 +682,28 @@ main(int ac, char **av) | |||
663 | 682 | ||
664 | /* | 683 | /* |
665 | * Initialize "log" output. Since we are the client all output | 684 | * Initialize "log" output. Since we are the client all output |
666 | * actually goes to stderr. | 685 | * goes to stderr unless otherwise specified by -y or -E. |
667 | */ | 686 | */ |
687 | if (use_syslog && logfile != NULL) | ||
688 | fatal("Can't specify both -y and -E"); | ||
689 | if (logfile != NULL) { | ||
690 | log_redirect_stderr_to(logfile); | ||
691 | free(logfile); | ||
692 | } | ||
668 | log_init(argv0, | 693 | log_init(argv0, |
669 | options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, | 694 | options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, |
670 | SYSLOG_FACILITY_USER, !use_syslog); | 695 | SYSLOG_FACILITY_USER, !use_syslog); |
671 | 696 | ||
697 | if (debug_flag) | ||
698 | logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); | ||
699 | |||
672 | /* | 700 | /* |
673 | * Read per-user configuration file. Ignore the system wide config | 701 | * Read per-user configuration file. Ignore the system wide config |
674 | * file if the user specifies a config file on the command line. | 702 | * file if the user specifies a config file on the command line. |
675 | */ | 703 | */ |
676 | if (config != NULL) { | 704 | if (config != NULL) { |
677 | if (!read_config_file(config, host, &options, SSHCONF_USERCONF)) | 705 | if (strcasecmp(config, "none") != 0 && |
706 | !read_config_file(config, host, &options, SSHCONF_USERCONF)) | ||
678 | fatal("Can't open user config file %.100s: " | 707 | fatal("Can't open user config file %.100s: " |
679 | "%.100s", config, strerror(errno)); | 708 | "%.100s", config, strerror(errno)); |
680 | } else { | 709 | } else { |
@@ -749,7 +778,7 @@ main(int ac, char **av) | |||
749 | "p", portstr, "u", pw->pw_name, "L", shorthost, | 778 | "p", portstr, "u", pw->pw_name, "L", shorthost, |
750 | (char *)NULL); | 779 | (char *)NULL); |
751 | debug3("expanded LocalCommand: %s", options.local_command); | 780 | debug3("expanded LocalCommand: %s", options.local_command); |
752 | xfree(cp); | 781 | free(cp); |
753 | } | 782 | } |
754 | 783 | ||
755 | /* force lowercase for hostkey matching */ | 784 | /* force lowercase for hostkey matching */ |
@@ -761,24 +790,24 @@ main(int ac, char **av) | |||
761 | 790 | ||
762 | if (options.proxy_command != NULL && | 791 | if (options.proxy_command != NULL && |
763 | strcmp(options.proxy_command, "none") == 0) { | 792 | strcmp(options.proxy_command, "none") == 0) { |
764 | xfree(options.proxy_command); | 793 | free(options.proxy_command); |
765 | options.proxy_command = NULL; | 794 | options.proxy_command = NULL; |
766 | } | 795 | } |
767 | if (options.control_path != NULL && | 796 | if (options.control_path != NULL && |
768 | strcmp(options.control_path, "none") == 0) { | 797 | strcmp(options.control_path, "none") == 0) { |
769 | xfree(options.control_path); | 798 | free(options.control_path); |
770 | options.control_path = NULL; | 799 | options.control_path = NULL; |
771 | } | 800 | } |
772 | 801 | ||
773 | if (options.control_path != NULL) { | 802 | if (options.control_path != NULL) { |
774 | cp = tilde_expand_filename(options.control_path, | 803 | cp = tilde_expand_filename(options.control_path, |
775 | original_real_uid); | 804 | original_real_uid); |
776 | xfree(options.control_path); | 805 | free(options.control_path); |
777 | options.control_path = percent_expand(cp, "h", host, | 806 | options.control_path = percent_expand(cp, "h", host, |
778 | "l", thishost, "n", host_arg, "r", options.user, | 807 | "l", thishost, "n", host_arg, "r", options.user, |
779 | "p", portstr, "u", pw->pw_name, "L", shorthost, | 808 | "p", portstr, "u", pw->pw_name, "L", shorthost, |
780 | (char *)NULL); | 809 | (char *)NULL); |
781 | xfree(cp); | 810 | free(cp); |
782 | } | 811 | } |
783 | if (muxclient_command != 0 && options.control_path == NULL) | 812 | if (muxclient_command != 0 && options.control_path == NULL) |
784 | fatal("No ControlPath specified for \"-O\" command"); | 813 | fatal("No ControlPath specified for \"-O\" command"); |
@@ -929,13 +958,11 @@ main(int ac, char **av) | |||
929 | sensitive_data.keys[i] = NULL; | 958 | sensitive_data.keys[i] = NULL; |
930 | } | 959 | } |
931 | } | 960 | } |
932 | xfree(sensitive_data.keys); | 961 | free(sensitive_data.keys); |
933 | } | 962 | } |
934 | for (i = 0; i < options.num_identity_files; i++) { | 963 | for (i = 0; i < options.num_identity_files; i++) { |
935 | if (options.identity_files[i]) { | 964 | free(options.identity_files[i]); |
936 | xfree(options.identity_files[i]); | 965 | options.identity_files[i] = NULL; |
937 | options.identity_files[i] = NULL; | ||
938 | } | ||
939 | if (options.identity_keys[i]) { | 966 | if (options.identity_keys[i]) { |
940 | key_free(options.identity_keys[i]); | 967 | key_free(options.identity_keys[i]); |
941 | options.identity_keys[i] = NULL; | 968 | options.identity_keys[i] = NULL; |
@@ -995,6 +1022,7 @@ control_persist_detach(void) | |||
995 | if (devnull > STDERR_FILENO) | 1022 | if (devnull > STDERR_FILENO) |
996 | close(devnull); | 1023 | close(devnull); |
997 | } | 1024 | } |
1025 | daemon(1, 1); | ||
998 | setproctitle("%s [mux]", options.control_path); | 1026 | setproctitle("%s [mux]", options.control_path); |
999 | } | 1027 | } |
1000 | 1028 | ||
@@ -1453,6 +1481,11 @@ ssh_session2(void) | |||
1453 | 1481 | ||
1454 | if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) | 1482 | if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) |
1455 | id = ssh_session2_open(); | 1483 | id = ssh_session2_open(); |
1484 | else { | ||
1485 | packet_set_interactive( | ||
1486 | options.control_master == SSHCTL_MASTER_NO, | ||
1487 | options.ip_qos_interactive, options.ip_qos_bulk); | ||
1488 | } | ||
1456 | 1489 | ||
1457 | /* If we don't expect to open a new session, then disallow it */ | 1490 | /* If we don't expect to open a new session, then disallow it */ |
1458 | if (options.control_master == SSHCTL_MASTER_NO && | 1491 | if (options.control_master == SSHCTL_MASTER_NO && |
@@ -1525,7 +1558,7 @@ load_public_identity_files(void) | |||
1525 | xstrdup(options.pkcs11_provider); /* XXX */ | 1558 | xstrdup(options.pkcs11_provider); /* XXX */ |
1526 | n_ids++; | 1559 | n_ids++; |
1527 | } | 1560 | } |
1528 | xfree(keys); | 1561 | free(keys); |
1529 | } | 1562 | } |
1530 | #endif /* ENABLE_PKCS11 */ | 1563 | #endif /* ENABLE_PKCS11 */ |
1531 | if ((pw = getpwuid(original_real_uid)) == NULL) | 1564 | if ((pw = getpwuid(original_real_uid)) == NULL) |
@@ -1538,7 +1571,7 @@ load_public_identity_files(void) | |||
1538 | for (i = 0; i < options.num_identity_files; i++) { | 1571 | for (i = 0; i < options.num_identity_files; i++) { |
1539 | if (n_ids >= SSH_MAX_IDENTITY_FILES || | 1572 | if (n_ids >= SSH_MAX_IDENTITY_FILES || |
1540 | strcasecmp(options.identity_files[i], "none") == 0) { | 1573 | strcasecmp(options.identity_files[i], "none") == 0) { |
1541 | xfree(options.identity_files[i]); | 1574 | free(options.identity_files[i]); |
1542 | continue; | 1575 | continue; |
1543 | } | 1576 | } |
1544 | cp = tilde_expand_filename(options.identity_files[i], | 1577 | cp = tilde_expand_filename(options.identity_files[i], |
@@ -1546,7 +1579,7 @@ load_public_identity_files(void) | |||
1546 | filename = percent_expand(cp, "d", pwdir, | 1579 | filename = percent_expand(cp, "d", pwdir, |
1547 | "u", pwname, "l", thishost, "h", host, | 1580 | "u", pwname, "l", thishost, "h", host, |
1548 | "r", options.user, (char *)NULL); | 1581 | "r", options.user, (char *)NULL); |
1549 | xfree(cp); | 1582 | free(cp); |
1550 | public = key_load_public(filename, NULL); | 1583 | public = key_load_public(filename, NULL); |
1551 | debug("identity file %s type %d", filename, | 1584 | debug("identity file %s type %d", filename, |
1552 | public ? public->type : -1); | 1585 | public ? public->type : -1); |
@@ -1558,15 +1591,15 @@ load_public_identity_files(void) | |||
1558 | logit("Public key %s blacklisted (see " | 1591 | logit("Public key %s blacklisted (see " |
1559 | "ssh-vulnkey(1)); refusing to send it", | 1592 | "ssh-vulnkey(1)); refusing to send it", |
1560 | fp); | 1593 | fp); |
1561 | xfree(fp); | 1594 | free(fp); |
1562 | if (!options.use_blacklisted_keys) { | 1595 | if (!options.use_blacklisted_keys) { |
1563 | key_free(public); | 1596 | key_free(public); |
1564 | xfree(filename); | 1597 | free(filename); |
1565 | filename = NULL; | 1598 | filename = NULL; |
1566 | public = NULL; | 1599 | public = NULL; |
1567 | } | 1600 | } |
1568 | } | 1601 | } |
1569 | xfree(options.identity_files[i]); | 1602 | free(options.identity_files[i]); |
1570 | identity_files[n_ids] = filename; | 1603 | identity_files[n_ids] = filename; |
1571 | identity_keys[n_ids] = public; | 1604 | identity_keys[n_ids] = public; |
1572 | 1605 | ||
@@ -1579,14 +1612,14 @@ load_public_identity_files(void) | |||
1579 | debug("identity file %s type %d", cp, | 1612 | debug("identity file %s type %d", cp, |
1580 | public ? public->type : -1); | 1613 | public ? public->type : -1); |
1581 | if (public == NULL) { | 1614 | if (public == NULL) { |
1582 | xfree(cp); | 1615 | free(cp); |
1583 | continue; | 1616 | continue; |
1584 | } | 1617 | } |
1585 | if (!key_is_cert(public)) { | 1618 | if (!key_is_cert(public)) { |
1586 | debug("%s: key %s type %s is not a certificate", | 1619 | debug("%s: key %s type %s is not a certificate", |
1587 | __func__, cp, key_type(public)); | 1620 | __func__, cp, key_type(public)); |
1588 | key_free(public); | 1621 | key_free(public); |
1589 | xfree(cp); | 1622 | free(cp); |
1590 | continue; | 1623 | continue; |
1591 | } | 1624 | } |
1592 | identity_keys[n_ids] = public; | 1625 | identity_keys[n_ids] = public; |
@@ -1599,9 +1632,9 @@ load_public_identity_files(void) | |||
1599 | memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); | 1632 | memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); |
1600 | 1633 | ||
1601 | bzero(pwname, strlen(pwname)); | 1634 | bzero(pwname, strlen(pwname)); |
1602 | xfree(pwname); | 1635 | free(pwname); |
1603 | bzero(pwdir, strlen(pwdir)); | 1636 | bzero(pwdir, strlen(pwdir)); |
1604 | xfree(pwdir); | 1637 | free(pwdir); |
1605 | } | 1638 | } |
1606 | 1639 | ||
1607 | static void | 1640 | static void |