version 1.328, 2018/04/10 00:10:49 |
version 1.329, 2018/06/06 18:22:41 |
|
|
options->num_accept_env = 0; |
options->num_accept_env = 0; |
options->permit_tun = -1; |
options->permit_tun = -1; |
options->permitted_opens = NULL; |
options->permitted_opens = NULL; |
|
options->permitted_remote_opens = NULL; |
options->adm_forced_command = NULL; |
options->adm_forced_command = NULL; |
options->chroot_directory = NULL; |
options->chroot_directory = NULL; |
options->authorized_keys_command = NULL; |
options->authorized_keys_command = NULL; |
|
|
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
sAcceptEnv, sPermitTunnel, |
sAcceptEnv, sPermitTunnel, |
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory, |
sUsePrivilegeSeparation, sAllowAgentForwarding, |
sUsePrivilegeSeparation, sAllowAgentForwarding, |
sHostCertificate, |
sHostCertificate, |
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
|
|
{ "permituserrc", sPermitUserRC, SSHCFG_ALL }, |
{ "permituserrc", sPermitUserRC, SSHCFG_ALL }, |
{ "match", sMatch, SSHCFG_ALL }, |
{ "match", sMatch, SSHCFG_ALL }, |
{ "permitopen", sPermitOpen, SSHCFG_ALL }, |
{ "permitopen", sPermitOpen, SSHCFG_ALL }, |
|
{ "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL }, |
{ "forcecommand", sForceCommand, SSHCFG_ALL }, |
{ "forcecommand", sForceCommand, SSHCFG_ALL }, |
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, |
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, |
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, |
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, |
|
|
{ -1, NULL } |
{ -1, NULL } |
}; |
}; |
|
|
|
/* Returns an opcode name from its number */ |
|
|
|
static const char * |
|
lookup_opcode_name(ServerOpCodes code) |
|
{ |
|
u_int i; |
|
|
|
for (i = 0; keywords[i].name != NULL; i++) |
|
if (keywords[i].opcode == code) |
|
return(keywords[i].name); |
|
return "UNKNOWN"; |
|
} |
|
|
|
|
/* |
/* |
* Returns the number of the token pointed to by cp or sBadOption. |
* Returns the number of the token pointed to by cp or sBadOption. |
*/ |
*/ |
|
|
} |
} |
|
|
/* |
/* |
* Inform channels layer of permitopen options from configuration. |
* Inform channels layer of permitopen options for a single forwarding |
|
* direction (local/remote). |
*/ |
*/ |
void |
static void |
process_permitopen(struct ssh *ssh, ServerOptions *options) |
process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, |
|
char **opens, u_int num_opens) |
{ |
{ |
u_int i; |
u_int i; |
int port; |
int port; |
char *host, *arg, *oarg; |
char *host, *arg, *oarg; |
|
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; |
|
const char *what = lookup_opcode_name(opcode); |
|
|
channel_clear_adm_permitted_opens(ssh); |
channel_clear_permission(ssh, FORWARD_ADM, where); |
if (options->num_permitted_opens == 0) |
if (num_opens == 0) |
return; /* permit any */ |
return; /* permit any */ |
|
|
/* handle keywords: "any" / "none" */ |
/* handle keywords: "any" / "none" */ |
if (options->num_permitted_opens == 1 && |
if (num_opens == 1 && strcmp(opens[0], "any") == 0) |
strcmp(options->permitted_opens[0], "any") == 0) |
|
return; |
return; |
if (options->num_permitted_opens == 1 && |
if (num_opens == 1 && strcmp(opens[0], "none") == 0) { |
strcmp(options->permitted_opens[0], "none") == 0) { |
channel_disable_admin(ssh, where); |
channel_disable_adm_local_opens(ssh); |
|
return; |
return; |
} |
} |
/* Otherwise treat it as a list of permitted host:port */ |
/* Otherwise treat it as a list of permitted host:port */ |
for (i = 0; i < options->num_permitted_opens; i++) { |
for (i = 0; i < num_opens; i++) { |
oarg = arg = xstrdup(options->permitted_opens[i]); |
oarg = arg = xstrdup(opens[i]); |
host = hpdelim(&arg); |
host = hpdelim(&arg); |
if (host == NULL) |
if (host == NULL) |
fatal("%s: missing host in PermitOpen", __func__); |
fatal("%s: missing host in %s", __func__, what); |
host = cleanhostname(host); |
host = cleanhostname(host); |
if (arg == NULL || ((port = permitopen_port(arg)) < 0)) |
if (arg == NULL || ((port = permitopen_port(arg)) < 0)) |
fatal("%s: bad port number in PermitOpen", __func__); |
fatal("%s: bad port number in %s", __func__, what); |
/* Send it to channels layer */ |
/* Send it to channels layer */ |
channel_add_adm_permitted_opens(ssh, host, port); |
channel_add_permission(ssh, FORWARD_ADM, |
|
where, host, port); |
free(oarg); |
free(oarg); |
} |
} |
} |
} |
|
|
|
/* |
|
* Inform channels layer of permitopen options from configuration. |
|
*/ |
|
void |
|
process_permitopen(struct ssh *ssh, ServerOptions *options) |
|
{ |
|
process_permitopen_list(ssh, sPermitOpen, |
|
options->permitted_opens, options->num_permitted_opens); |
|
process_permitopen_list(ssh, sPermitRemoteOpen, |
|
options->permitted_remote_opens, |
|
options->num_permitted_remote_opens); |
|
} |
|
|
struct connection_info * |
struct connection_info * |
get_connection_info(int populate, int use_dns) |
get_connection_info(int populate, int use_dns) |
{ |
{ |
|
|
const char *filename, int linenum, int *activep, |
const char *filename, int linenum, int *activep, |
struct connection_info *connectinfo) |
struct connection_info *connectinfo) |
{ |
{ |
char *cp, **charptr, *arg, *arg2, *p; |
char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; |
int cmdline = 0, *intptr, value, value2, n, port; |
int cmdline = 0, *intptr, value, value2, n, port; |
SyslogFacility *log_facility_ptr; |
SyslogFacility *log_facility_ptr; |
LogLevel *log_level_ptr; |
LogLevel *log_level_ptr; |
ServerOpCodes opcode; |
ServerOpCodes opcode; |
u_int i, flags = 0; |
u_int i, *uintptr, uvalue, flags = 0; |
size_t len; |
size_t len; |
long long val64; |
long long val64; |
const struct multistate *multistate_ptr; |
const struct multistate *multistate_ptr; |
|
|
*activep = value; |
*activep = value; |
break; |
break; |
|
|
|
case sPermitRemoteOpen: |
case sPermitOpen: |
case sPermitOpen: |
|
if (opcode == sPermitRemoteOpen) { |
|
uintptr = &options->num_permitted_remote_opens; |
|
chararrayptr = &options->permitted_remote_opens; |
|
} else { |
|
uintptr = &options->num_permitted_opens; |
|
chararrayptr = &options->permitted_opens; |
|
} |
arg = strdelim(&cp); |
arg = strdelim(&cp); |
if (!arg || *arg == '\0') |
if (!arg || *arg == '\0') |
fatal("%s line %d: missing PermitOpen specification", |
fatal("%s line %d: missing %s specification", |
filename, linenum); |
filename, linenum, lookup_opcode_name(opcode)); |
value = options->num_permitted_opens; /* modified later */ |
uvalue = *uintptr; /* modified later */ |
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { |
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { |
if (*activep && value == 0) { |
if (*activep && uvalue == 0) { |
options->num_permitted_opens = 1; |
*uintptr = 1; |
options->permitted_opens = xcalloc(1, |
*chararrayptr = xcalloc(1, |
sizeof(*options->permitted_opens)); |
sizeof(**chararrayptr)); |
options->permitted_opens[0] = xstrdup(arg); |
(*chararrayptr)[0] = xstrdup(arg); |
} |
} |
break; |
break; |
} |
} |
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { |
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { |
arg2 = xstrdup(arg); |
arg2 = xstrdup(arg); |
p = hpdelim(&arg); |
p = hpdelim(&arg); |
if (p == NULL) |
/* XXX support bare port number for PermitRemoteOpen */ |
fatal("%s line %d: missing host in PermitOpen", |
if (p == NULL) { |
filename, linenum); |
fatal("%s line %d: missing host in %s", |
|
filename, linenum, |
|
lookup_opcode_name(opcode)); |
|
} |
p = cleanhostname(p); |
p = cleanhostname(p); |
if (arg == NULL || ((port = permitopen_port(arg)) < 0)) |
if (arg == NULL || |
fatal("%s line %d: bad port number in " |
((port = permitopen_port(arg)) < 0)) { |
"PermitOpen", filename, linenum); |
fatal("%s line %d: bad port number in %s", |
if (*activep && value == 0) { |
filename, linenum, |
|
lookup_opcode_name(opcode)); |
|
} |
|
if (*activep && uvalue == 0) { |
array_append(filename, linenum, |
array_append(filename, linenum, |
"PermitOpen", |
lookup_opcode_name(opcode), |
&options->permitted_opens, |
chararrayptr, uintptr, arg2); |
&options->num_permitted_opens, arg2); |
|
} |
} |
free(arg2); |
free(arg2); |
} |
} |
|
|
} |
} |
} |
} |
|
|
static const char * |
|
lookup_opcode_name(ServerOpCodes code) |
|
{ |
|
u_int i; |
|
|
|
for (i = 0; keywords[i].name != NULL; i++) |
|
if (keywords[i].opcode == code) |
|
return(keywords[i].name); |
|
return "UNKNOWN"; |
|
} |
|
|
|
static void |
static void |
dump_cfg_int(ServerOpCodes code, int val) |
dump_cfg_int(ServerOpCodes code, int val) |
{ |
{ |
|
|
else { |
else { |
for (i = 0; i < o->num_permitted_opens; i++) |
for (i = 0; i < o->num_permitted_opens; i++) |
printf(" %s", o->permitted_opens[i]); |
printf(" %s", o->permitted_opens[i]); |
|
} |
|
printf("\n"); |
|
printf("permitremoteopen"); |
|
if (o->num_permitted_remote_opens == 0) |
|
printf(" any"); |
|
else { |
|
for (i = 0; i < o->num_permitted_remote_opens; i++) |
|
printf(" %s", o->permitted_remote_opens[i]); |
} |
} |
printf("\n"); |
printf("\n"); |
} |
} |