summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-15 12:14:12 +1100
committerDamien Miller <djm@mindrot.org>2013-10-15 12:14:12 +1100
commite9fc72edd6c313b670558cd5219601c38a949b67 (patch)
tree32ed93978e93622d5829a55cbc0479e00b1161bf
parent194fd904d8597a274b93e075b2047afdf5a175d4 (diff)
- djm@cvs.openbsd.org 2013/10/14 23:28:23
[canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] refactor client config code a little: add multistate option partsing to readconf.c, similar to servconf.c's existing code. move checking of options that accept "none" as an argument to readconf.c add a lowercase() function and use it instead of explicit tolower() in loops part of a larger diff that was ok markus@
-rw-r--r--ChangeLog9
-rw-r--r--canohost.c13
-rw-r--r--misc.c10
-rw-r--r--misc.h4
-rw-r--r--readconf.c199
-rw-r--r--sftp-server.c25
-rw-r--r--ssh.c28
7 files changed, 149 insertions, 139 deletions
diff --git a/ChangeLog b/ChangeLog
index 2b0ca0b8d..91a6b6497 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,6 +37,15 @@
37 [readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5] 37 [readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5]
38 add a "Match" keyword to ssh_config that allows matching on hostname, 38 add a "Match" keyword to ssh_config that allows matching on hostname,
39 user and result of arbitrary commands. "nice work" markus@ 39 user and result of arbitrary commands. "nice work" markus@
40 - djm@cvs.openbsd.org 2013/10/14 23:28:23
41 [canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c]
42 refactor client config code a little:
43 add multistate option partsing to readconf.c, similar to servconf.c's
44 existing code.
45 move checking of options that accept "none" as an argument to readconf.c
46 add a lowercase() function and use it instead of explicit tolower() in
47 loops
48 part of a larger diff that was ok markus@
40 49
4120131010 5020131010
42 - (dtucker) OpenBSD CVS Sync 51 - (dtucker) OpenBSD CVS Sync
diff --git a/canohost.c b/canohost.c
index 69e8e6f6d..a8eeb0e35 100644
--- a/canohost.c
+++ b/canohost.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: canohost.c,v 1.67 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: canohost.c,v 1.68 2013/10/14 23:28:22 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
@@ -48,7 +48,6 @@ static char *
48get_remote_hostname(int sock, int use_dns) 48get_remote_hostname(int sock, int use_dns)
49{ 49{
50 struct sockaddr_storage from; 50 struct sockaddr_storage from;
51 int i;
52 socklen_t fromlen; 51 socklen_t fromlen;
53 struct addrinfo hints, *ai, *aitop; 52 struct addrinfo hints, *ai, *aitop;
54 char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; 53 char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
@@ -99,13 +98,9 @@ get_remote_hostname(int sock, int use_dns)
99 return xstrdup(ntop); 98 return xstrdup(ntop);
100 } 99 }
101 100
102 /* 101 /* Names are stores in lowercase. */
103 * Convert it to all lowercase (which is expected by the rest 102 lowercase(name);
104 * of this software). 103
105 */
106 for (i = 0; name[i]; i++)
107 if (isupper(name[i]))
108 name[i] = (char)tolower(name[i]);
109 /* 104 /*
110 * Map it back to an IP address and check that the given 105 * Map it back to an IP address and check that the given
111 * address actually is an address of this host. This is 106 * address actually is an address of this host. This is
diff --git a/misc.c b/misc.c
index c3c809943..e4c8c3238 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.91 2013/07/12 00:43:50 djm Exp $ */ 1/* $OpenBSD: misc.c,v 1.92 2013/10/14 23:28:23 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -43,6 +43,7 @@
43#include <netinet/ip.h> 43#include <netinet/ip.h>
44#include <netinet/tcp.h> 44#include <netinet/tcp.h>
45 45
46#include <ctype.h>
46#include <errno.h> 47#include <errno.h>
47#include <fcntl.h> 48#include <fcntl.h>
48#include <netdb.h> 49#include <netdb.h>
@@ -1017,6 +1018,13 @@ iptos2str(int iptos)
1017 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 1018 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
1018 return iptos_str; 1019 return iptos_str;
1019} 1020}
1021
1022void
1023lowercase(char *s)
1024{
1025 for (; *s; s++)
1026 *s = tolower((u_char)*s);
1027}
1020void 1028void
1021sock_set_v6only(int s) 1029sock_set_v6only(int s)
1022{ 1030{
diff --git a/misc.h b/misc.h
index fceb30655..d4df619cd 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.h,v 1.49 2013/06/01 13:15:52 dtucker Exp $ */ 1/* $OpenBSD: misc.h,v 1.50 2013/10/14 23:28:23 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -36,6 +36,8 @@ void sanitise_stdfd(void);
36void ms_subtract_diff(struct timeval *, int *); 36void ms_subtract_diff(struct timeval *, int *);
37void ms_to_timeval(struct timeval *, int); 37void ms_to_timeval(struct timeval *, int);
38time_t monotime(void); 38time_t monotime(void);
39void lowercase(char *s);
40
39void sock_set_v6only(int); 41void sock_set_v6only(int);
40 42
41struct passwd *pwcopy(struct passwd *); 43struct passwd *pwcopy(struct passwd *);
diff --git a/readconf.c b/readconf.c
index f7b912ef6..9340effd0 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.206 2013/10/14 22:22:02 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.207 2013/10/14 23:28:23 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
@@ -555,6 +555,61 @@ parse_token(const char *cp, const char *filename, int linenum,
555 return oBadOption; 555 return oBadOption;
556} 556}
557 557
558/* Multistate option parsing */
559struct multistate {
560 char *key;
561 int value;
562};
563static const struct multistate multistate_flag[] = {
564 { "true", 1 },
565 { "false", 0 },
566 { "yes", 1 },
567 { "no", 0 },
568 { NULL, -1 }
569};
570static const struct multistate multistate_yesnoask[] = {
571 { "true", 1 },
572 { "false", 0 },
573 { "yes", 1 },
574 { "no", 0 },
575 { "ask", 2 },
576 { NULL, -1 }
577};
578static const struct multistate multistate_addressfamily[] = {
579 { "inet", AF_INET },
580 { "inet6", AF_INET6 },
581 { "any", AF_UNSPEC },
582 { NULL, -1 }
583};
584static const struct multistate multistate_controlmaster[] = {
585 { "true", SSHCTL_MASTER_YES },
586 { "yes", SSHCTL_MASTER_YES },
587 { "false", SSHCTL_MASTER_NO },
588 { "no", SSHCTL_MASTER_NO },
589 { "auto", SSHCTL_MASTER_AUTO },
590 { "ask", SSHCTL_MASTER_ASK },
591 { "autoask", SSHCTL_MASTER_AUTO_ASK },
592 { NULL, -1 }
593};
594static const struct multistate multistate_tunnel[] = {
595 { "ethernet", SSH_TUNMODE_ETHERNET },
596 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
597 { "true", SSH_TUNMODE_DEFAULT },
598 { "yes", SSH_TUNMODE_DEFAULT },
599 { "false", SSH_TUNMODE_NO },
600 { "no", SSH_TUNMODE_NO },
601 { NULL, -1 }
602};
603static const struct multistate multistate_requesttty[] = {
604 { "true", REQUEST_TTY_YES },
605 { "yes", REQUEST_TTY_YES },
606 { "false", REQUEST_TTY_NO },
607 { "no", REQUEST_TTY_NO },
608 { "force", REQUEST_TTY_FORCE },
609 { "auto", REQUEST_TTY_AUTO },
610 { NULL, -1 }
611};
612
558/* 613/*
559 * Processes a single option line as used in the configuration files. This 614 * Processes a single option line as used in the configuration files. This
560 * only sets those values that have not already been set. 615 * only sets those values that have not already been set.
@@ -572,6 +627,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
572 long long val64; 627 long long val64;
573 size_t len; 628 size_t len;
574 Forward fwd; 629 Forward fwd;
630 const struct multistate *multistate_ptr;
575 631
576 if (activep == NULL) { /* We are processing a command line directive */ 632 if (activep == NULL) { /* We are processing a command line directive */
577 cmdline = 1; 633 cmdline = 1;
@@ -595,8 +651,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
595 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 651 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
596 return 0; 652 return 0;
597 /* Match lowercase keyword */ 653 /* Match lowercase keyword */
598 for (i = 0; i < strlen(keyword); i++) 654 lowercase(keyword);
599 keyword[i] = tolower(keyword[i]);
600 655
601 opcode = parse_token(keyword, filename, linenum, 656 opcode = parse_token(keyword, filename, linenum,
602 options->ignored_unknown); 657 options->ignored_unknown);
@@ -626,17 +681,23 @@ parse_time:
626 681
627 case oForwardAgent: 682 case oForwardAgent:
628 intptr = &options->forward_agent; 683 intptr = &options->forward_agent;
629parse_flag: 684 parse_flag:
685 multistate_ptr = multistate_flag;
686 parse_multistate:
630 arg = strdelim(&s); 687 arg = strdelim(&s);
631 if (!arg || *arg == '\0') 688 if (!arg || *arg == '\0')
632 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 689 fatal("%s line %d: missing argument.",
633 value = 0; /* To avoid compiler warning... */ 690 filename, linenum);
634 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 691 value = -1;
635 value = 1; 692 for (i = 0; multistate_ptr[i].key != NULL; i++) {
636 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 693 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
637 value = 0; 694 value = multistate_ptr[i].value;
638 else 695 break;
639 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 696 }
697 }
698 if (value == -1)
699 fatal("%s line %d: unsupported option \"%s\".",
700 filename, linenum, arg);
640 if (*activep && *intptr == -1) 701 if (*activep && *intptr == -1)
641 *intptr = value; 702 *intptr = value;
642 break; 703 break;
@@ -719,27 +780,13 @@ parse_flag:
719 780
720 case oVerifyHostKeyDNS: 781 case oVerifyHostKeyDNS:
721 intptr = &options->verify_host_key_dns; 782 intptr = &options->verify_host_key_dns;
722 goto parse_yesnoask; 783 multistate_ptr = multistate_yesnoask;
784 goto parse_multistate;
723 785
724 case oStrictHostKeyChecking: 786 case oStrictHostKeyChecking:
725 intptr = &options->strict_host_key_checking; 787 intptr = &options->strict_host_key_checking;
726parse_yesnoask: 788 multistate_ptr = multistate_yesnoask;
727 arg = strdelim(&s); 789 goto parse_multistate;
728 if (!arg || *arg == '\0')
729 fatal("%.200s line %d: Missing yes/no/ask argument.",
730 filename, linenum);
731 value = 0; /* To avoid compiler warning... */
732 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
733 value = 1;
734 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
735 value = 0;
736 else if (strcmp(arg, "ask") == 0)
737 value = 2;
738 else
739 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
740 if (*activep && *intptr == -1)
741 *intptr = value;
742 break;
743 790
744 case oCompression: 791 case oCompression:
745 intptr = &options->compression; 792 intptr = &options->compression;
@@ -1080,22 +1127,9 @@ parse_int:
1080 break; 1127 break;
1081 1128
1082 case oAddressFamily: 1129 case oAddressFamily:
1083 arg = strdelim(&s);
1084 if (!arg || *arg == '\0')
1085 fatal("%s line %d: missing address family.",
1086 filename, linenum);
1087 intptr = &options->address_family; 1130 intptr = &options->address_family;
1088 if (strcasecmp(arg, "inet") == 0) 1131 multistate_ptr = multistate_addressfamily;
1089 value = AF_INET; 1132 goto parse_multistate;
1090 else if (strcasecmp(arg, "inet6") == 0)
1091 value = AF_INET6;
1092 else if (strcasecmp(arg, "any") == 0)
1093 value = AF_UNSPEC;
1094 else
1095 fatal("Unsupported AddressFamily \"%s\"", arg);
1096 if (*activep && *intptr == -1)
1097 *intptr = value;
1098 break;
1099 1133
1100 case oEnableSSHKeysign: 1134 case oEnableSSHKeysign:
1101 intptr = &options->enable_ssh_keysign; 1135 intptr = &options->enable_ssh_keysign;
@@ -1134,27 +1168,8 @@ parse_int:
1134 1168
1135 case oControlMaster: 1169 case oControlMaster:
1136 intptr = &options->control_master; 1170 intptr = &options->control_master;
1137 arg = strdelim(&s); 1171 multistate_ptr = multistate_controlmaster;
1138 if (!arg || *arg == '\0') 1172 goto parse_multistate;
1139 fatal("%.200s line %d: Missing ControlMaster argument.",
1140 filename, linenum);
1141 value = 0; /* To avoid compiler warning... */
1142 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1143 value = SSHCTL_MASTER_YES;
1144 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1145 value = SSHCTL_MASTER_NO;
1146 else if (strcmp(arg, "auto") == 0)
1147 value = SSHCTL_MASTER_AUTO;
1148 else if (strcmp(arg, "ask") == 0)
1149 value = SSHCTL_MASTER_ASK;
1150 else if (strcmp(arg, "autoask") == 0)
1151 value = SSHCTL_MASTER_AUTO_ASK;
1152 else
1153 fatal("%.200s line %d: Bad ControlMaster argument.",
1154 filename, linenum);
1155 if (*activep && *intptr == -1)
1156 *intptr = value;
1157 break;
1158 1173
1159 case oControlPersist: 1174 case oControlPersist:
1160 /* no/false/yes/true, or a time spec */ 1175 /* no/false/yes/true, or a time spec */
@@ -1186,25 +1201,8 @@ parse_int:
1186 1201
1187 case oTunnel: 1202 case oTunnel:
1188 intptr = &options->tun_open; 1203 intptr = &options->tun_open;
1189 arg = strdelim(&s); 1204 multistate_ptr = multistate_tunnel;
1190 if (!arg || *arg == '\0') 1205 goto parse_multistate;
1191 fatal("%s line %d: Missing yes/point-to-point/"
1192 "ethernet/no argument.", filename, linenum);
1193 value = 0; /* silence compiler */
1194 if (strcasecmp(arg, "ethernet") == 0)
1195 value = SSH_TUNMODE_ETHERNET;
1196 else if (strcasecmp(arg, "point-to-point") == 0)
1197 value = SSH_TUNMODE_POINTOPOINT;
1198 else if (strcasecmp(arg, "yes") == 0)
1199 value = SSH_TUNMODE_DEFAULT;
1200 else if (strcasecmp(arg, "no") == 0)
1201 value = SSH_TUNMODE_NO;
1202 else
1203 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1204 "no argument: %s", filename, linenum, arg);
1205 if (*activep)
1206 *intptr = value;
1207 break;
1208 1206
1209 case oTunnelDevice: 1207 case oTunnelDevice:
1210 arg = strdelim(&s); 1208 arg = strdelim(&s);
@@ -1253,24 +1251,9 @@ parse_int:
1253 goto parse_flag; 1251 goto parse_flag;
1254 1252
1255 case oRequestTTY: 1253 case oRequestTTY:
1256 arg = strdelim(&s);
1257 if (!arg || *arg == '\0')
1258 fatal("%s line %d: missing argument.",
1259 filename, linenum);
1260 intptr = &options->request_tty; 1254 intptr = &options->request_tty;
1261 if (strcasecmp(arg, "yes") == 0) 1255 multistate_ptr = multistate_requesttty;
1262 value = REQUEST_TTY_YES; 1256 goto parse_multistate;
1263 else if (strcasecmp(arg, "no") == 0)
1264 value = REQUEST_TTY_NO;
1265 else if (strcasecmp(arg, "force") == 0)
1266 value = REQUEST_TTY_FORCE;
1267 else if (strcasecmp(arg, "auto") == 0)
1268 value = REQUEST_TTY_AUTO;
1269 else
1270 fatal("Unsupported RequestTTY \"%s\"", arg);
1271 if (*activep && *intptr == -1)
1272 *intptr = value;
1273 break;
1274 1257
1275 case oIgnoreUnknown: 1258 case oIgnoreUnknown:
1276 charptr = &options->ignored_unknown; 1259 charptr = &options->ignored_unknown;
@@ -1596,8 +1579,16 @@ fill_default_options(Options * options)
1596 options->request_tty = REQUEST_TTY_AUTO; 1579 options->request_tty = REQUEST_TTY_AUTO;
1597 if (options->proxy_use_fdpass == -1) 1580 if (options->proxy_use_fdpass == -1)
1598 options->proxy_use_fdpass = 0; 1581 options->proxy_use_fdpass = 0;
1599 /* options->local_command should not be set by default */ 1582#define CLEAR_ON_NONE(v) \
1600 /* options->proxy_command should not be set by default */ 1583 do { \
1584 if (v != NULL && strcasecmp(v, "none") == 0) { \
1585 free(v); \
1586 v = NULL; \
1587 } \
1588 } while(0)
1589 CLEAR_ON_NONE(options->local_command);
1590 CLEAR_ON_NONE(options->proxy_command);
1591 CLEAR_ON_NONE(options->control_path);
1601 /* options->user will be set in the main program if appropriate */ 1592 /* options->user will be set in the main program if appropriate */
1602 /* options->hostname will be set in the main program if appropriate */ 1593 /* options->hostname will be set in the main program if appropriate */
1603 /* options->host_key_alias should not be set by default */ 1594 /* options->host_key_alias should not be set by default */
diff --git a/sftp-server.c b/sftp-server.c
index b62bd3510..3056c454e 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-server.c,v 1.100 2013/10/14 14:18:56 jmc Exp $ */ 1/* $OpenBSD: sftp-server.c,v 1.101 2013/10/14 23:28:23 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
4 * 4 *
@@ -230,6 +230,8 @@ flags_from_portable(int pflags)
230 } else if (pflags & SSH2_FXF_WRITE) { 230 } else if (pflags & SSH2_FXF_WRITE) {
231 flags = O_WRONLY; 231 flags = O_WRONLY;
232 } 232 }
233 if (pflags & SSH2_FXF_APPEND)
234 flags |= O_APPEND;
233 if (pflags & SSH2_FXF_CREAT) 235 if (pflags & SSH2_FXF_CREAT)
234 flags |= O_CREAT; 236 flags |= O_CREAT;
235 if (pflags & SSH2_FXF_TRUNC) 237 if (pflags & SSH2_FXF_TRUNC)
@@ -256,6 +258,8 @@ string_from_portable(int pflags)
256 PAPPEND("READ") 258 PAPPEND("READ")
257 if (pflags & SSH2_FXF_WRITE) 259 if (pflags & SSH2_FXF_WRITE)
258 PAPPEND("WRITE") 260 PAPPEND("WRITE")
261 if (pflags & SSH2_FXF_APPEND)
262 PAPPEND("APPEND")
259 if (pflags & SSH2_FXF_CREAT) 263 if (pflags & SSH2_FXF_CREAT)
260 PAPPEND("CREATE") 264 PAPPEND("CREATE")
261 if (pflags & SSH2_FXF_TRUNC) 265 if (pflags & SSH2_FXF_TRUNC)
@@ -279,6 +283,7 @@ struct Handle {
279 int use; 283 int use;
280 DIR *dirp; 284 DIR *dirp;
281 int fd; 285 int fd;
286 int flags;
282 char *name; 287 char *name;
283 u_int64_t bytes_read, bytes_write; 288 u_int64_t bytes_read, bytes_write;
284 int next_unused; 289 int next_unused;
@@ -302,7 +307,7 @@ static void handle_unused(int i)
302} 307}
303 308
304static int 309static int
305handle_new(int use, const char *name, int fd, DIR *dirp) 310handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
306{ 311{
307 int i; 312 int i;
308 313
@@ -320,6 +325,7 @@ handle_new(int use, const char *name, int fd, DIR *dirp)
320 handles[i].use = use; 325 handles[i].use = use;
321 handles[i].dirp = dirp; 326 handles[i].dirp = dirp;
322 handles[i].fd = fd; 327 handles[i].fd = fd;
328 handles[i].flags = flags;
323 handles[i].name = xstrdup(name); 329 handles[i].name = xstrdup(name);
324 handles[i].bytes_read = handles[i].bytes_write = 0; 330 handles[i].bytes_read = handles[i].bytes_write = 0;
325 331
@@ -382,6 +388,14 @@ handle_to_fd(int handle)
382 return -1; 388 return -1;
383} 389}
384 390
391static int
392handle_to_flags(int handle)
393{
394 if (handle_is_ok(handle, HANDLE_FILE))
395 return handles[handle].flags;
396 return 0;
397}
398
385static void 399static void
386handle_update_read(int handle, ssize_t bytes) 400handle_update_read(int handle, ssize_t bytes)
387{ 401{
@@ -668,7 +682,7 @@ process_open(u_int32_t id)
668 if (fd < 0) { 682 if (fd < 0) {
669 status = errno_to_portable(errno); 683 status = errno_to_portable(errno);
670 } else { 684 } else {
671 handle = handle_new(HANDLE_FILE, name, fd, NULL); 685 handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
672 if (handle < 0) { 686 if (handle < 0) {
673 close(fd); 687 close(fd);
674 } else { 688 } else {
@@ -754,7 +768,8 @@ process_write(u_int32_t id)
754 if (fd < 0) 768 if (fd < 0)
755 status = SSH2_FX_FAILURE; 769 status = SSH2_FX_FAILURE;
756 else { 770 else {
757 if (lseek(fd, off, SEEK_SET) < 0) { 771 if (!(handle_to_flags(handle) & O_APPEND) &&
772 lseek(fd, off, SEEK_SET) < 0) {
758 status = errno_to_portable(errno); 773 status = errno_to_portable(errno);
759 error("process_write: seek failed"); 774 error("process_write: seek failed");
760 } else { 775 } else {
@@ -971,7 +986,7 @@ process_opendir(u_int32_t id)
971 if (dirp == NULL) { 986 if (dirp == NULL) {
972 status = errno_to_portable(errno); 987 status = errno_to_portable(errno);
973 } else { 988 } else {
974 handle = handle_new(HANDLE_DIR, path, 0, dirp); 989 handle = handle_new(HANDLE_DIR, path, 0, 0, dirp);
975 if (handle < 0) { 990 if (handle < 0) {
976 closedir(dirp); 991 closedir(dirp);
977 } else { 992 } else {
diff --git a/ssh.c b/ssh.c
index 13f384a92..5aa5dcc89 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.382 2013/10/14 22:22:04 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.383 2013/10/14 23:28:23 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
@@ -723,6 +723,14 @@ main(int ac, char **av)
723 723
724 channel_set_af(options.address_family); 724 channel_set_af(options.address_family);
725 725
726 /* Tidy and check options */
727 if (options.host_key_alias != NULL)
728 lowercase(options.host_key_alias);
729 if (options.proxy_command != NULL &&
730 strcmp(options.proxy_command, "-") == 0 &&
731 options.proxy_use_fdpass)
732 fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
733
726 /* reinit */ 734 /* reinit */
727 log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); 735 log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
728 736
@@ -779,24 +787,6 @@ main(int ac, char **av)
779 free(cp); 787 free(cp);
780 } 788 }
781 789
782 /* force lowercase for hostkey matching */
783 if (options.host_key_alias != NULL) {
784 for (p = options.host_key_alias; *p; p++)
785 if (isupper(*p))
786 *p = (char)tolower(*p);
787 }
788
789 if (options.proxy_command != NULL &&
790 strcmp(options.proxy_command, "none") == 0) {
791 free(options.proxy_command);
792 options.proxy_command = NULL;
793 }
794 if (options.control_path != NULL &&
795 strcmp(options.control_path, "none") == 0) {
796 free(options.control_path);
797 options.control_path = NULL;
798 }
799
800 if (options.control_path != NULL) { 790 if (options.control_path != NULL) {
801 cp = tilde_expand_filename(options.control_path, 791 cp = tilde_expand_filename(options.control_path,
802 original_real_uid); 792 original_real_uid);