1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-03 13:31:11 +03:00

config: Preserve the seen array among invocations

This follows the OpenSSH behavior of parsing subseqent configuration
files, while applying only the first option.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Jakub Jelen
2018-10-30 12:49:22 +01:00
committed by Andreas Schneider
parent 4a95a35bc6
commit de7405f1c7
3 changed files with 25 additions and 6 deletions

View File

@@ -220,6 +220,7 @@ struct ssh_session_struct {
int flags; int flags;
int nodelay; int nodelay;
bool config_processed; bool config_processed;
uint8_t *options_seen;
} opts; } opts;
/* counters */ /* counters */
ssh_counter socket_counter; ssh_counter socket_counter;

View File

@@ -213,7 +213,7 @@ static struct ssh_config_match_keyword_table_s ssh_config_match_keyword_table[]
}; };
static int ssh_config_parse_line(ssh_session session, const char *line, static int ssh_config_parse_line(ssh_session session, const char *line,
unsigned int count, int *parsing, int seen[]); unsigned int count, int *parsing, uint8_t *seen);
static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) { static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
int i; int i;
@@ -323,7 +323,9 @@ static int ssh_config_get_yesno(char **str, int notfound) {
return notfound; return notfound;
} }
static void local_parse_file(ssh_session session, const char *filename, int *parsing, int seen[]) { static void local_parse_file(ssh_session session, const char *filename,
int *parsing, uint8_t *seen)
{
FILE *f; FILE *f;
char line[MAX_LINE_SIZE] = {0}; char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0; unsigned int count = 0;
@@ -351,7 +353,7 @@ static void local_parse_file(ssh_session session, const char *filename, int *par
static void local_parse_glob(ssh_session session, static void local_parse_glob(ssh_session session,
const char *fileglob, const char *fileglob,
int *parsing, int *parsing,
int seen[]) uint8_t *seen)
{ {
glob_t globbuf = { glob_t globbuf = {
.gl_flags = 0, .gl_flags = 0,
@@ -413,7 +415,8 @@ ssh_config_match(char *value, const char *pattern, bool negate)
} }
static int ssh_config_parse_line(ssh_session session, const char *line, static int ssh_config_parse_line(ssh_session session, const char *line,
unsigned int count, int *parsing, int seen[]) { unsigned int count, int *parsing, uint8_t *seen)
{
enum ssh_config_opcode_e opcode; enum ssh_config_opcode_e opcode;
const char *p; const char *p;
char *s, *x; char *s, *x;
@@ -450,6 +453,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
opcode != SOC_MATCH && opcode != SOC_MATCH &&
opcode != SOC_INCLUDE && opcode != SOC_INCLUDE &&
opcode > SOC_UNSUPPORTED) { /* Ignore all unknown types here */ opcode > SOC_UNSUPPORTED) { /* Ignore all unknown types here */
/* Skip all the options that were already applied */
if (seen[opcode] != 0) { if (seen[opcode] != 0) {
SAFE_FREE(x); SAFE_FREE(x);
return 0; return 0;
@@ -822,12 +826,13 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
} }
/* ssh_config_parse_file */ /* ssh_config_parse_file */
int ssh_config_parse_file(ssh_session session, const char *filename) { int ssh_config_parse_file(ssh_session session, const char *filename)
{
char line[MAX_LINE_SIZE] = {0}; char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0; unsigned int count = 0;
FILE *f; FILE *f;
int parsing; int parsing;
int seen[SOC_END - SOC_UNSUPPORTED] = {0}; uint8_t *seen = NULL;
if ((f = fopen(filename, "r")) == NULL) { if ((f = fopen(filename, "r")) == NULL) {
return 0; return 0;
@@ -835,6 +840,18 @@ int ssh_config_parse_file(ssh_session session, const char *filename) {
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename); SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
/* Preserve the seen array among invocations throughout the session */
if (session->opts.options_seen == NULL) {
seen = calloc(SOC_END - SOC_UNSUPPORTED, sizeof(uint8_t));
if (seen == NULL) {
ssh_set_error_oom(session);
return -1;
}
session->opts.options_seen = seen;
} else {
seen = session->opts.options_seen;
}
parsing = 1; parsing = 1;
while (fgets(line, sizeof(line), f)) { while (fgets(line, sizeof(line), f)) {
count++; count++;

View File

@@ -283,6 +283,7 @@ void ssh_free(ssh_session session) {
SAFE_FREE(session->opts.gss_server_identity); SAFE_FREE(session->opts.gss_server_identity);
SAFE_FREE(session->opts.gss_client_identity); SAFE_FREE(session->opts.gss_client_identity);
SAFE_FREE(session->opts.pubkey_accepted_types); SAFE_FREE(session->opts.pubkey_accepted_types);
SAFE_FREE(session->opts.options_seen);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
if (session->opts.wanted_methods[i]) { if (session->opts.wanted_methods[i]) {