summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c97
1 files changed, 65 insertions, 32 deletions
diff --git a/ssh.c b/ssh.c
index 5ec89f2cc..87233bc91 100644
--- a/ssh.c
+++ b/ssh.c
@@ -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
238main(int ac, char **av) 238main(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,11 +1579,11 @@ 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);
1553 xfree(options.identity_files[i]); 1586 free(options.identity_files[i]);
1554 identity_files[n_ids] = filename; 1587 identity_files[n_ids] = filename;
1555 identity_keys[n_ids] = public; 1588 identity_keys[n_ids] = public;
1556 1589
@@ -1563,14 +1596,14 @@ load_public_identity_files(void)
1563 debug("identity file %s type %d", cp, 1596 debug("identity file %s type %d", cp,
1564 public ? public->type : -1); 1597 public ? public->type : -1);
1565 if (public == NULL) { 1598 if (public == NULL) {
1566 xfree(cp); 1599 free(cp);
1567 continue; 1600 continue;
1568 } 1601 }
1569 if (!key_is_cert(public)) { 1602 if (!key_is_cert(public)) {
1570 debug("%s: key %s type %s is not a certificate", 1603 debug("%s: key %s type %s is not a certificate",
1571 __func__, cp, key_type(public)); 1604 __func__, cp, key_type(public));
1572 key_free(public); 1605 key_free(public);
1573 xfree(cp); 1606 free(cp);
1574 continue; 1607 continue;
1575 } 1608 }
1576 identity_keys[n_ids] = public; 1609 identity_keys[n_ids] = public;
@@ -1583,9 +1616,9 @@ load_public_identity_files(void)
1583 memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); 1616 memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
1584 1617
1585 bzero(pwname, strlen(pwname)); 1618 bzero(pwname, strlen(pwname));
1586 xfree(pwname); 1619 free(pwname);
1587 bzero(pwdir, strlen(pwdir)); 1620 bzero(pwdir, strlen(pwdir));
1588 xfree(pwdir); 1621 free(pwdir);
1589} 1622}
1590 1623
1591static void 1624static void