mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-10 18:28:10 +09:00
config: Avoid infinite recursion when using Include
Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
@@ -189,18 +189,29 @@ ssh_bind_config_parse_line(ssh_bind bind,
|
|||||||
const char *line,
|
const char *line,
|
||||||
unsigned int count,
|
unsigned int count,
|
||||||
uint32_t *parser_flags,
|
uint32_t *parser_flags,
|
||||||
uint8_t *seen);
|
uint8_t *seen,
|
||||||
|
unsigned int depth);
|
||||||
|
|
||||||
static void local_parse_file(ssh_bind bind,
|
#define LIBSSH_BIND_CONF_MAX_DEPTH 16
|
||||||
const char *filename,
|
static void
|
||||||
uint32_t *parser_flags,
|
local_parse_file(ssh_bind bind,
|
||||||
uint8_t *seen)
|
const char *filename,
|
||||||
|
uint32_t *parser_flags,
|
||||||
|
uint8_t *seen,
|
||||||
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char line[MAX_LINE_SIZE] = {0};
|
char line[MAX_LINE_SIZE] = {0};
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (depth > LIBSSH_BIND_CONF_MAX_DEPTH) {
|
||||||
|
ssh_set_error(bind, SSH_FATAL,
|
||||||
|
"ERROR - Too many levels of configuration includes "
|
||||||
|
"when processing file '%s'", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
f = fopen(filename, "r");
|
f = fopen(filename, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
||||||
@@ -213,7 +224,7 @@ static void local_parse_file(ssh_bind bind,
|
|||||||
|
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
count++;
|
count++;
|
||||||
rv = ssh_bind_config_parse_line(bind, line, count, parser_flags, seen);
|
rv = ssh_bind_config_parse_line(bind, line, count, parser_flags, seen, depth);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return;
|
return;
|
||||||
@@ -228,7 +239,8 @@ static void local_parse_file(ssh_bind bind,
|
|||||||
static void local_parse_glob(ssh_bind bind,
|
static void local_parse_glob(ssh_bind bind,
|
||||||
const char *fileglob,
|
const char *fileglob,
|
||||||
uint32_t *parser_flags,
|
uint32_t *parser_flags,
|
||||||
uint8_t *seen)
|
uint8_t *seen,
|
||||||
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
glob_t globbuf = {
|
glob_t globbuf = {
|
||||||
.gl_flags = 0,
|
.gl_flags = 0,
|
||||||
@@ -248,7 +260,7 @@ static void local_parse_glob(ssh_bind bind,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < globbuf.gl_pathc; i++) {
|
for (i = 0; i < globbuf.gl_pathc; i++) {
|
||||||
local_parse_file(bind, globbuf.gl_pathv[i], parser_flags, seen);
|
local_parse_file(bind, globbuf.gl_pathv[i], parser_flags, seen, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
globfree(&globbuf);
|
globfree(&globbuf);
|
||||||
@@ -274,7 +286,8 @@ ssh_bind_config_parse_line(ssh_bind bind,
|
|||||||
const char *line,
|
const char *line,
|
||||||
unsigned int count,
|
unsigned int count,
|
||||||
uint32_t *parser_flags,
|
uint32_t *parser_flags,
|
||||||
uint8_t *seen)
|
uint8_t *seen,
|
||||||
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
enum ssh_bind_config_opcode_e opcode;
|
enum ssh_bind_config_opcode_e opcode;
|
||||||
const char *p = NULL;
|
const char *p = NULL;
|
||||||
@@ -333,9 +346,9 @@ ssh_bind_config_parse_line(ssh_bind bind,
|
|||||||
p = ssh_config_get_str_tok(&s, NULL);
|
p = ssh_config_get_str_tok(&s, NULL);
|
||||||
if (p && (*parser_flags & PARSING)) {
|
if (p && (*parser_flags & PARSING)) {
|
||||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||||
local_parse_glob(bind, p, parser_flags, seen);
|
local_parse_glob(bind, p, parser_flags, seen, depth + 1);
|
||||||
#else
|
#else
|
||||||
local_parse_file(bind, p, parser_flags, seen);
|
local_parse_file(bind, p, parser_flags, seen, depth + 1);
|
||||||
#endif /* HAVE_GLOB */
|
#endif /* HAVE_GLOB */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -628,7 +641,7 @@ int ssh_bind_config_parse_file(ssh_bind bind, const char *filename)
|
|||||||
parser_flags = PARSING;
|
parser_flags = PARSING;
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
count++;
|
count++;
|
||||||
rv = ssh_bind_config_parse_line(bind, line, count, &parser_flags, seen);
|
rv = ssh_bind_config_parse_line(bind, line, count, &parser_flags, seen, 0);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
31
src/config.c
31
src/config.c
@@ -191,7 +191,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);
|
unsigned int count, int *parsing, unsigned int depth);
|
||||||
|
|
||||||
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;
|
||||||
@@ -205,16 +205,25 @@ static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
|
|||||||
return SOC_UNKNOWN;
|
return SOC_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LIBSSH_CONF_MAX_DEPTH 16
|
||||||
static void
|
static void
|
||||||
local_parse_file(ssh_session session,
|
local_parse_file(ssh_session session,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
int *parsing)
|
int *parsing,
|
||||||
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char line[MAX_LINE_SIZE] = {0};
|
char line[MAX_LINE_SIZE] = {0};
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (depth > LIBSSH_CONF_MAX_DEPTH) {
|
||||||
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"ERROR - Too many levels of configuration includes "
|
||||||
|
"when processing file '%s'", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
f = fopen(filename, "r");
|
f = fopen(filename, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
||||||
@@ -225,7 +234,7 @@ local_parse_file(ssh_session session,
|
|||||||
SSH_LOG(SSH_LOG_PACKET, "Reading additional configuration data from %s", filename);
|
SSH_LOG(SSH_LOG_PACKET, "Reading additional configuration data from %s", filename);
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
count++;
|
count++;
|
||||||
rv = ssh_config_parse_line(session, line, count, parsing);
|
rv = ssh_config_parse_line(session, line, count, parsing, depth);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return;
|
return;
|
||||||
@@ -239,7 +248,8 @@ local_parse_file(ssh_session session,
|
|||||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||||
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,
|
||||||
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
glob_t globbuf = {
|
glob_t globbuf = {
|
||||||
.gl_flags = 0,
|
.gl_flags = 0,
|
||||||
@@ -259,7 +269,7 @@ static void local_parse_glob(ssh_session session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < globbuf.gl_pathc; i++) {
|
for (i = 0; i < globbuf.gl_pathc; i++) {
|
||||||
local_parse_file(session, globbuf.gl_pathv[i], parsing);
|
local_parse_file(session, globbuf.gl_pathv[i], parsing, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
globfree(&globbuf);
|
globfree(&globbuf);
|
||||||
@@ -513,7 +523,8 @@ static int
|
|||||||
ssh_config_parse_line(ssh_session session,
|
ssh_config_parse_line(ssh_session session,
|
||||||
const char *line,
|
const char *line,
|
||||||
unsigned int count,
|
unsigned int count,
|
||||||
int *parsing)
|
int *parsing,
|
||||||
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
enum ssh_config_opcode_e opcode;
|
enum ssh_config_opcode_e opcode;
|
||||||
const char *p = NULL, *p2 = NULL;
|
const char *p = NULL, *p2 = NULL;
|
||||||
@@ -573,9 +584,9 @@ ssh_config_parse_line(ssh_session session,
|
|||||||
p = ssh_config_get_str_tok(&s, NULL);
|
p = ssh_config_get_str_tok(&s, NULL);
|
||||||
if (p && *parsing) {
|
if (p && *parsing) {
|
||||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||||
local_parse_glob(session, p, parsing);
|
local_parse_glob(session, p, parsing, depth + 1);
|
||||||
#else
|
#else
|
||||||
local_parse_file(session, p, parsing);
|
local_parse_file(session, p, parsing, depth + 1);
|
||||||
#endif /* HAVE_GLOB */
|
#endif /* HAVE_GLOB */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1163,7 +1174,7 @@ int ssh_config_parse_file(ssh_session session, const char *filename)
|
|||||||
parsing = 1;
|
parsing = 1;
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
count++;
|
count++;
|
||||||
rv = ssh_config_parse_line(session, line, count, &parsing);
|
rv = ssh_config_parse_line(session, line, count, &parsing, 0);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1215,7 +1226,7 @@ int ssh_config_parse_string(ssh_session session, const char *input)
|
|||||||
memcpy(line, line_start, line_len);
|
memcpy(line, line_start, line_len);
|
||||||
line[line_len] = '\0';
|
line[line_len] = '\0';
|
||||||
SSH_LOG(SSH_LOG_DEBUG, "Line %u: %s", line_num, line);
|
SSH_LOG(SSH_LOG_DEBUG, "Line %u: %s", line_num, line);
|
||||||
rv = ssh_config_parse_line(session, line, line_num, &parsing);
|
rv = ssh_config_parse_line(session, line, line_num, &parsing, 0);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user