- 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@
This commit is contained in:
parent
194fd904d8
commit
e9fc72edd6
|
@ -37,6 +37,15 @@
|
||||||
[readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5]
|
[readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5]
|
||||||
add a "Match" keyword to ssh_config that allows matching on hostname,
|
add a "Match" keyword to ssh_config that allows matching on hostname,
|
||||||
user and result of arbitrary commands. "nice work" markus@
|
user and result of arbitrary commands. "nice work" markus@
|
||||||
|
- 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@
|
||||||
|
|
||||||
20131010
|
20131010
|
||||||
- (dtucker) OpenBSD CVS Sync
|
- (dtucker) OpenBSD CVS Sync
|
||||||
|
|
13
canohost.c
13
canohost.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: canohost.c,v 1.67 2013/05/17 00:13:13 djm Exp $ */
|
/* $OpenBSD: canohost.c,v 1.68 2013/10/14 23:28:22 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -48,7 +48,6 @@ static char *
|
||||||
get_remote_hostname(int sock, int use_dns)
|
get_remote_hostname(int sock, int use_dns)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage from;
|
struct sockaddr_storage from;
|
||||||
int i;
|
|
||||||
socklen_t fromlen;
|
socklen_t fromlen;
|
||||||
struct addrinfo hints, *ai, *aitop;
|
struct addrinfo hints, *ai, *aitop;
|
||||||
char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
|
char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
|
||||||
|
@ -99,13 +98,9 @@ get_remote_hostname(int sock, int use_dns)
|
||||||
return xstrdup(ntop);
|
return xstrdup(ntop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Names are stores in lowercase. */
|
||||||
* Convert it to all lowercase (which is expected by the rest
|
lowercase(name);
|
||||||
* of this software).
|
|
||||||
*/
|
|
||||||
for (i = 0; name[i]; i++)
|
|
||||||
if (isupper(name[i]))
|
|
||||||
name[i] = (char)tolower(name[i]);
|
|
||||||
/*
|
/*
|
||||||
* Map it back to an IP address and check that the given
|
* Map it back to an IP address and check that the given
|
||||||
* address actually is an address of this host. This is
|
* address actually is an address of this host. This is
|
||||||
|
|
10
misc.c
10
misc.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: misc.c,v 1.91 2013/07/12 00:43:50 djm Exp $ */
|
/* $OpenBSD: misc.c,v 1.92 2013/10/14 23:28:23 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
||||||
|
@ -43,6 +43,7 @@
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
@ -1017,6 +1018,13 @@ iptos2str(int iptos)
|
||||||
snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
|
snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
|
||||||
return iptos_str;
|
return iptos_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lowercase(char *s)
|
||||||
|
{
|
||||||
|
for (; *s; s++)
|
||||||
|
*s = tolower((u_char)*s);
|
||||||
|
}
|
||||||
void
|
void
|
||||||
sock_set_v6only(int s)
|
sock_set_v6only(int s)
|
||||||
{
|
{
|
||||||
|
|
4
misc.h
4
misc.h
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: misc.h,v 1.49 2013/06/01 13:15:52 dtucker Exp $ */
|
/* $OpenBSD: misc.h,v 1.50 2013/10/14 23:28:23 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
|
@ -36,6 +36,8 @@ void sanitise_stdfd(void);
|
||||||
void ms_subtract_diff(struct timeval *, int *);
|
void ms_subtract_diff(struct timeval *, int *);
|
||||||
void ms_to_timeval(struct timeval *, int);
|
void ms_to_timeval(struct timeval *, int);
|
||||||
time_t monotime(void);
|
time_t monotime(void);
|
||||||
|
void lowercase(char *s);
|
||||||
|
|
||||||
void sock_set_v6only(int);
|
void sock_set_v6only(int);
|
||||||
|
|
||||||
struct passwd *pwcopy(struct passwd *);
|
struct passwd *pwcopy(struct passwd *);
|
||||||
|
|
199
readconf.c
199
readconf.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: readconf.c,v 1.206 2013/10/14 22:22:02 djm Exp $ */
|
/* $OpenBSD: readconf.c,v 1.207 2013/10/14 23:28:23 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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,
|
||||||
return oBadOption;
|
return oBadOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Multistate option parsing */
|
||||||
|
struct multistate {
|
||||||
|
char *key;
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
static const struct multistate multistate_flag[] = {
|
||||||
|
{ "true", 1 },
|
||||||
|
{ "false", 0 },
|
||||||
|
{ "yes", 1 },
|
||||||
|
{ "no", 0 },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
static const struct multistate multistate_yesnoask[] = {
|
||||||
|
{ "true", 1 },
|
||||||
|
{ "false", 0 },
|
||||||
|
{ "yes", 1 },
|
||||||
|
{ "no", 0 },
|
||||||
|
{ "ask", 2 },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
static const struct multistate multistate_addressfamily[] = {
|
||||||
|
{ "inet", AF_INET },
|
||||||
|
{ "inet6", AF_INET6 },
|
||||||
|
{ "any", AF_UNSPEC },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
static const struct multistate multistate_controlmaster[] = {
|
||||||
|
{ "true", SSHCTL_MASTER_YES },
|
||||||
|
{ "yes", SSHCTL_MASTER_YES },
|
||||||
|
{ "false", SSHCTL_MASTER_NO },
|
||||||
|
{ "no", SSHCTL_MASTER_NO },
|
||||||
|
{ "auto", SSHCTL_MASTER_AUTO },
|
||||||
|
{ "ask", SSHCTL_MASTER_ASK },
|
||||||
|
{ "autoask", SSHCTL_MASTER_AUTO_ASK },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
static const struct multistate multistate_tunnel[] = {
|
||||||
|
{ "ethernet", SSH_TUNMODE_ETHERNET },
|
||||||
|
{ "point-to-point", SSH_TUNMODE_POINTOPOINT },
|
||||||
|
{ "true", SSH_TUNMODE_DEFAULT },
|
||||||
|
{ "yes", SSH_TUNMODE_DEFAULT },
|
||||||
|
{ "false", SSH_TUNMODE_NO },
|
||||||
|
{ "no", SSH_TUNMODE_NO },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
static const struct multistate multistate_requesttty[] = {
|
||||||
|
{ "true", REQUEST_TTY_YES },
|
||||||
|
{ "yes", REQUEST_TTY_YES },
|
||||||
|
{ "false", REQUEST_TTY_NO },
|
||||||
|
{ "no", REQUEST_TTY_NO },
|
||||||
|
{ "force", REQUEST_TTY_FORCE },
|
||||||
|
{ "auto", REQUEST_TTY_AUTO },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Processes a single option line as used in the configuration files. This
|
* Processes a single option line as used in the configuration files. This
|
||||||
* only sets those values that have not already been set.
|
* 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,
|
||||||
long long val64;
|
long long val64;
|
||||||
size_t len;
|
size_t len;
|
||||||
Forward fwd;
|
Forward fwd;
|
||||||
|
const struct multistate *multistate_ptr;
|
||||||
|
|
||||||
if (activep == NULL) { /* We are processing a command line directive */
|
if (activep == NULL) { /* We are processing a command line directive */
|
||||||
cmdline = 1;
|
cmdline = 1;
|
||||||
|
@ -595,8 +651,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
|
||||||
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
|
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
|
||||||
return 0;
|
return 0;
|
||||||
/* Match lowercase keyword */
|
/* Match lowercase keyword */
|
||||||
for (i = 0; i < strlen(keyword); i++)
|
lowercase(keyword);
|
||||||
keyword[i] = tolower(keyword[i]);
|
|
||||||
|
|
||||||
opcode = parse_token(keyword, filename, linenum,
|
opcode = parse_token(keyword, filename, linenum,
|
||||||
options->ignored_unknown);
|
options->ignored_unknown);
|
||||||
|
@ -626,17 +681,23 @@ parse_time:
|
||||||
|
|
||||||
case oForwardAgent:
|
case oForwardAgent:
|
||||||
intptr = &options->forward_agent;
|
intptr = &options->forward_agent;
|
||||||
parse_flag:
|
parse_flag:
|
||||||
|
multistate_ptr = multistate_flag;
|
||||||
|
parse_multistate:
|
||||||
arg = strdelim(&s);
|
arg = strdelim(&s);
|
||||||
if (!arg || *arg == '\0')
|
if (!arg || *arg == '\0')
|
||||||
fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
|
fatal("%s line %d: missing argument.",
|
||||||
value = 0; /* To avoid compiler warning... */
|
filename, linenum);
|
||||||
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
|
value = -1;
|
||||||
value = 1;
|
for (i = 0; multistate_ptr[i].key != NULL; i++) {
|
||||||
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
|
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
|
||||||
value = 0;
|
value = multistate_ptr[i].value;
|
||||||
else
|
break;
|
||||||
fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
|
}
|
||||||
|
}
|
||||||
|
if (value == -1)
|
||||||
|
fatal("%s line %d: unsupported option \"%s\".",
|
||||||
|
filename, linenum, arg);
|
||||||
if (*activep && *intptr == -1)
|
if (*activep && *intptr == -1)
|
||||||
*intptr = value;
|
*intptr = value;
|
||||||
break;
|
break;
|
||||||
|
@ -719,27 +780,13 @@ parse_flag:
|
||||||
|
|
||||||
case oVerifyHostKeyDNS:
|
case oVerifyHostKeyDNS:
|
||||||
intptr = &options->verify_host_key_dns;
|
intptr = &options->verify_host_key_dns;
|
||||||
goto parse_yesnoask;
|
multistate_ptr = multistate_yesnoask;
|
||||||
|
goto parse_multistate;
|
||||||
|
|
||||||
case oStrictHostKeyChecking:
|
case oStrictHostKeyChecking:
|
||||||
intptr = &options->strict_host_key_checking;
|
intptr = &options->strict_host_key_checking;
|
||||||
parse_yesnoask:
|
multistate_ptr = multistate_yesnoask;
|
||||||
arg = strdelim(&s);
|
goto parse_multistate;
|
||||||
if (!arg || *arg == '\0')
|
|
||||||
fatal("%.200s line %d: Missing yes/no/ask argument.",
|
|
||||||
filename, linenum);
|
|
||||||
value = 0; /* To avoid compiler warning... */
|
|
||||||
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
|
|
||||||
value = 1;
|
|
||||||
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
|
|
||||||
value = 0;
|
|
||||||
else if (strcmp(arg, "ask") == 0)
|
|
||||||
value = 2;
|
|
||||||
else
|
|
||||||
fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
|
|
||||||
if (*activep && *intptr == -1)
|
|
||||||
*intptr = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case oCompression:
|
case oCompression:
|
||||||
intptr = &options->compression;
|
intptr = &options->compression;
|
||||||
|
@ -1080,22 +1127,9 @@ parse_int:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case oAddressFamily:
|
case oAddressFamily:
|
||||||
arg = strdelim(&s);
|
|
||||||
if (!arg || *arg == '\0')
|
|
||||||
fatal("%s line %d: missing address family.",
|
|
||||||
filename, linenum);
|
|
||||||
intptr = &options->address_family;
|
intptr = &options->address_family;
|
||||||
if (strcasecmp(arg, "inet") == 0)
|
multistate_ptr = multistate_addressfamily;
|
||||||
value = AF_INET;
|
goto parse_multistate;
|
||||||
else if (strcasecmp(arg, "inet6") == 0)
|
|
||||||
value = AF_INET6;
|
|
||||||
else if (strcasecmp(arg, "any") == 0)
|
|
||||||
value = AF_UNSPEC;
|
|
||||||
else
|
|
||||||
fatal("Unsupported AddressFamily \"%s\"", arg);
|
|
||||||
if (*activep && *intptr == -1)
|
|
||||||
*intptr = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case oEnableSSHKeysign:
|
case oEnableSSHKeysign:
|
||||||
intptr = &options->enable_ssh_keysign;
|
intptr = &options->enable_ssh_keysign;
|
||||||
|
@ -1134,27 +1168,8 @@ parse_int:
|
||||||
|
|
||||||
case oControlMaster:
|
case oControlMaster:
|
||||||
intptr = &options->control_master;
|
intptr = &options->control_master;
|
||||||
arg = strdelim(&s);
|
multistate_ptr = multistate_controlmaster;
|
||||||
if (!arg || *arg == '\0')
|
goto parse_multistate;
|
||||||
fatal("%.200s line %d: Missing ControlMaster argument.",
|
|
||||||
filename, linenum);
|
|
||||||
value = 0; /* To avoid compiler warning... */
|
|
||||||
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
|
|
||||||
value = SSHCTL_MASTER_YES;
|
|
||||||
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
|
|
||||||
value = SSHCTL_MASTER_NO;
|
|
||||||
else if (strcmp(arg, "auto") == 0)
|
|
||||||
value = SSHCTL_MASTER_AUTO;
|
|
||||||
else if (strcmp(arg, "ask") == 0)
|
|
||||||
value = SSHCTL_MASTER_ASK;
|
|
||||||
else if (strcmp(arg, "autoask") == 0)
|
|
||||||
value = SSHCTL_MASTER_AUTO_ASK;
|
|
||||||
else
|
|
||||||
fatal("%.200s line %d: Bad ControlMaster argument.",
|
|
||||||
filename, linenum);
|
|
||||||
if (*activep && *intptr == -1)
|
|
||||||
*intptr = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case oControlPersist:
|
case oControlPersist:
|
||||||
/* no/false/yes/true, or a time spec */
|
/* no/false/yes/true, or a time spec */
|
||||||
|
@ -1186,25 +1201,8 @@ parse_int:
|
||||||
|
|
||||||
case oTunnel:
|
case oTunnel:
|
||||||
intptr = &options->tun_open;
|
intptr = &options->tun_open;
|
||||||
arg = strdelim(&s);
|
multistate_ptr = multistate_tunnel;
|
||||||
if (!arg || *arg == '\0')
|
goto parse_multistate;
|
||||||
fatal("%s line %d: Missing yes/point-to-point/"
|
|
||||||
"ethernet/no argument.", filename, linenum);
|
|
||||||
value = 0; /* silence compiler */
|
|
||||||
if (strcasecmp(arg, "ethernet") == 0)
|
|
||||||
value = SSH_TUNMODE_ETHERNET;
|
|
||||||
else if (strcasecmp(arg, "point-to-point") == 0)
|
|
||||||
value = SSH_TUNMODE_POINTOPOINT;
|
|
||||||
else if (strcasecmp(arg, "yes") == 0)
|
|
||||||
value = SSH_TUNMODE_DEFAULT;
|
|
||||||
else if (strcasecmp(arg, "no") == 0)
|
|
||||||
value = SSH_TUNMODE_NO;
|
|
||||||
else
|
|
||||||
fatal("%s line %d: Bad yes/point-to-point/ethernet/"
|
|
||||||
"no argument: %s", filename, linenum, arg);
|
|
||||||
if (*activep)
|
|
||||||
*intptr = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case oTunnelDevice:
|
case oTunnelDevice:
|
||||||
arg = strdelim(&s);
|
arg = strdelim(&s);
|
||||||
|
@ -1253,24 +1251,9 @@ parse_int:
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
|
|
||||||
case oRequestTTY:
|
case oRequestTTY:
|
||||||
arg = strdelim(&s);
|
|
||||||
if (!arg || *arg == '\0')
|
|
||||||
fatal("%s line %d: missing argument.",
|
|
||||||
filename, linenum);
|
|
||||||
intptr = &options->request_tty;
|
intptr = &options->request_tty;
|
||||||
if (strcasecmp(arg, "yes") == 0)
|
multistate_ptr = multistate_requesttty;
|
||||||
value = REQUEST_TTY_YES;
|
goto parse_multistate;
|
||||||
else if (strcasecmp(arg, "no") == 0)
|
|
||||||
value = REQUEST_TTY_NO;
|
|
||||||
else if (strcasecmp(arg, "force") == 0)
|
|
||||||
value = REQUEST_TTY_FORCE;
|
|
||||||
else if (strcasecmp(arg, "auto") == 0)
|
|
||||||
value = REQUEST_TTY_AUTO;
|
|
||||||
else
|
|
||||||
fatal("Unsupported RequestTTY \"%s\"", arg);
|
|
||||||
if (*activep && *intptr == -1)
|
|
||||||
*intptr = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case oIgnoreUnknown:
|
case oIgnoreUnknown:
|
||||||
charptr = &options->ignored_unknown;
|
charptr = &options->ignored_unknown;
|
||||||
|
@ -1596,8 +1579,16 @@ fill_default_options(Options * options)
|
||||||
options->request_tty = REQUEST_TTY_AUTO;
|
options->request_tty = REQUEST_TTY_AUTO;
|
||||||
if (options->proxy_use_fdpass == -1)
|
if (options->proxy_use_fdpass == -1)
|
||||||
options->proxy_use_fdpass = 0;
|
options->proxy_use_fdpass = 0;
|
||||||
/* options->local_command should not be set by default */
|
#define CLEAR_ON_NONE(v) \
|
||||||
/* options->proxy_command should not be set by default */
|
do { \
|
||||||
|
if (v != NULL && strcasecmp(v, "none") == 0) { \
|
||||||
|
free(v); \
|
||||||
|
v = NULL; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
CLEAR_ON_NONE(options->local_command);
|
||||||
|
CLEAR_ON_NONE(options->proxy_command);
|
||||||
|
CLEAR_ON_NONE(options->control_path);
|
||||||
/* options->user will be set in the main program if appropriate */
|
/* options->user will be set in the main program if appropriate */
|
||||||
/* options->hostname will be set in the main program if appropriate */
|
/* options->hostname will be set in the main program if appropriate */
|
||||||
/* options->host_key_alias should not be set by default */
|
/* options->host_key_alias should not be set by default */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sftp-server.c,v 1.100 2013/10/14 14:18:56 jmc Exp $ */
|
/* $OpenBSD: sftp-server.c,v 1.101 2013/10/14 23:28:23 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -230,6 +230,8 @@ flags_from_portable(int pflags)
|
||||||
} else if (pflags & SSH2_FXF_WRITE) {
|
} else if (pflags & SSH2_FXF_WRITE) {
|
||||||
flags = O_WRONLY;
|
flags = O_WRONLY;
|
||||||
}
|
}
|
||||||
|
if (pflags & SSH2_FXF_APPEND)
|
||||||
|
flags |= O_APPEND;
|
||||||
if (pflags & SSH2_FXF_CREAT)
|
if (pflags & SSH2_FXF_CREAT)
|
||||||
flags |= O_CREAT;
|
flags |= O_CREAT;
|
||||||
if (pflags & SSH2_FXF_TRUNC)
|
if (pflags & SSH2_FXF_TRUNC)
|
||||||
|
@ -256,6 +258,8 @@ string_from_portable(int pflags)
|
||||||
PAPPEND("READ")
|
PAPPEND("READ")
|
||||||
if (pflags & SSH2_FXF_WRITE)
|
if (pflags & SSH2_FXF_WRITE)
|
||||||
PAPPEND("WRITE")
|
PAPPEND("WRITE")
|
||||||
|
if (pflags & SSH2_FXF_APPEND)
|
||||||
|
PAPPEND("APPEND")
|
||||||
if (pflags & SSH2_FXF_CREAT)
|
if (pflags & SSH2_FXF_CREAT)
|
||||||
PAPPEND("CREATE")
|
PAPPEND("CREATE")
|
||||||
if (pflags & SSH2_FXF_TRUNC)
|
if (pflags & SSH2_FXF_TRUNC)
|
||||||
|
@ -279,6 +283,7 @@ struct Handle {
|
||||||
int use;
|
int use;
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
int fd;
|
int fd;
|
||||||
|
int flags;
|
||||||
char *name;
|
char *name;
|
||||||
u_int64_t bytes_read, bytes_write;
|
u_int64_t bytes_read, bytes_write;
|
||||||
int next_unused;
|
int next_unused;
|
||||||
|
@ -302,7 +307,7 @@ static void handle_unused(int i)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handle_new(int use, const char *name, int fd, DIR *dirp)
|
handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -320,6 +325,7 @@ handle_new(int use, const char *name, int fd, DIR *dirp)
|
||||||
handles[i].use = use;
|
handles[i].use = use;
|
||||||
handles[i].dirp = dirp;
|
handles[i].dirp = dirp;
|
||||||
handles[i].fd = fd;
|
handles[i].fd = fd;
|
||||||
|
handles[i].flags = flags;
|
||||||
handles[i].name = xstrdup(name);
|
handles[i].name = xstrdup(name);
|
||||||
handles[i].bytes_read = handles[i].bytes_write = 0;
|
handles[i].bytes_read = handles[i].bytes_write = 0;
|
||||||
|
|
||||||
|
@ -382,6 +388,14 @@ handle_to_fd(int handle)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
handle_to_flags(int handle)
|
||||||
|
{
|
||||||
|
if (handle_is_ok(handle, HANDLE_FILE))
|
||||||
|
return handles[handle].flags;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_update_read(int handle, ssize_t bytes)
|
handle_update_read(int handle, ssize_t bytes)
|
||||||
{
|
{
|
||||||
|
@ -668,7 +682,7 @@ process_open(u_int32_t id)
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
} else {
|
} else {
|
||||||
handle = handle_new(HANDLE_FILE, name, fd, NULL);
|
handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
|
||||||
if (handle < 0) {
|
if (handle < 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
|
@ -754,7 +768,8 @@ process_write(u_int32_t id)
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
status = SSH2_FX_FAILURE;
|
status = SSH2_FX_FAILURE;
|
||||||
else {
|
else {
|
||||||
if (lseek(fd, off, SEEK_SET) < 0) {
|
if (!(handle_to_flags(handle) & O_APPEND) &&
|
||||||
|
lseek(fd, off, SEEK_SET) < 0) {
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
error("process_write: seek failed");
|
error("process_write: seek failed");
|
||||||
} else {
|
} else {
|
||||||
|
@ -971,7 +986,7 @@ process_opendir(u_int32_t id)
|
||||||
if (dirp == NULL) {
|
if (dirp == NULL) {
|
||||||
status = errno_to_portable(errno);
|
status = errno_to_portable(errno);
|
||||||
} else {
|
} else {
|
||||||
handle = handle_new(HANDLE_DIR, path, 0, dirp);
|
handle = handle_new(HANDLE_DIR, path, 0, 0, dirp);
|
||||||
if (handle < 0) {
|
if (handle < 0) {
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
} else {
|
} else {
|
||||||
|
|
28
ssh.c
28
ssh.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ssh.c,v 1.382 2013/10/14 22:22:04 djm Exp $ */
|
/* $OpenBSD: ssh.c,v 1.383 2013/10/14 23:28:23 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -723,6 +723,14 @@ main(int ac, char **av)
|
||||||
|
|
||||||
channel_set_af(options.address_family);
|
channel_set_af(options.address_family);
|
||||||
|
|
||||||
|
/* Tidy and check options */
|
||||||
|
if (options.host_key_alias != NULL)
|
||||||
|
lowercase(options.host_key_alias);
|
||||||
|
if (options.proxy_command != NULL &&
|
||||||
|
strcmp(options.proxy_command, "-") == 0 &&
|
||||||
|
options.proxy_use_fdpass)
|
||||||
|
fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
|
||||||
|
|
||||||
/* reinit */
|
/* reinit */
|
||||||
log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
|
log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
|
||||||
|
|
||||||
|
@ -779,24 +787,6 @@ main(int ac, char **av)
|
||||||
free(cp);
|
free(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* force lowercase for hostkey matching */
|
|
||||||
if (options.host_key_alias != NULL) {
|
|
||||||
for (p = options.host_key_alias; *p; p++)
|
|
||||||
if (isupper(*p))
|
|
||||||
*p = (char)tolower(*p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.proxy_command != NULL &&
|
|
||||||
strcmp(options.proxy_command, "none") == 0) {
|
|
||||||
free(options.proxy_command);
|
|
||||||
options.proxy_command = NULL;
|
|
||||||
}
|
|
||||||
if (options.control_path != NULL &&
|
|
||||||
strcmp(options.control_path, "none") == 0) {
|
|
||||||
free(options.control_path);
|
|
||||||
options.control_path = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.control_path != NULL) {
|
if (options.control_path != NULL) {
|
||||||
cp = tilde_expand_filename(options.control_path,
|
cp = tilde_expand_filename(options.control_path,
|
||||||
original_real_uid);
|
original_real_uid);
|
||||||
|
|
Loading…
Reference in New Issue