mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 09:54:25 +09:00
cmake: Add option WITH_HERMETIC_USR
Add a cmake option to enable hermetic-usr, i.e., use of config files in /usr/. If turned on, GLOBAL_*_CONFIG is prepended with /usr/ and defined as USR_GLOBAL_*_CONFIG. Config lookup follows this path GLOBAL_*_CONFIG -> USR_GLOBAL_*_CONFIG. Introduce a ssh_config_parse primitive. This avoids convoluted checks for file presence (without modifing the behaviour of ssh_config_parse_file) and allows marking whether the config is global at the call site. Signed-off-by: Lucas Mulling <lucas.mulling@suse.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
committed by
Jakub Jelen
parent
6b83aa9a40
commit
3372c2ad78
@@ -249,9 +249,15 @@ message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
|
|||||||
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
|
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
|
||||||
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
|
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
|
||||||
message(STATUS "Release is final: ${WITH_FINAL}")
|
message(STATUS "Release is final: ${WITH_FINAL}")
|
||||||
|
if (WITH_HERMETIC_USR)
|
||||||
|
message(STATUS "User global client config: ${USR_GLOBAL_CLIENT_CONFIG}")
|
||||||
|
endif ()
|
||||||
message(STATUS "Global client config: ${GLOBAL_CLIENT_CONFIG}")
|
message(STATUS "Global client config: ${GLOBAL_CLIENT_CONFIG}")
|
||||||
if (WITH_SERVER)
|
if (WITH_SERVER)
|
||||||
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
|
if (WITH_HERMETIC_USR)
|
||||||
|
message(STATUS "User global bind config: ${USR_GLOBAL_BIND_CONFIG}")
|
||||||
|
endif ()
|
||||||
|
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "********************************************")
|
message(STATUS "********************************************")
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ option(WITH_INSECURE_NONE "Enable insecure none cipher and MAC algorithms (not s
|
|||||||
option(WITH_EXEC "Enable libssh to execute arbitrary commands from configuration files or options (match exec, proxy commands and OpenSSH-based proxy-jumps)." ON)
|
option(WITH_EXEC "Enable libssh to execute arbitrary commands from configuration files or options (match exec, proxy commands and OpenSSH-based proxy-jumps)." ON)
|
||||||
option(FUZZ_TESTING "Build with fuzzer for the server and client (automatically enables none cipher!)" OFF)
|
option(FUZZ_TESTING "Build with fuzzer for the server and client (automatically enables none cipher!)" OFF)
|
||||||
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
|
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
|
||||||
|
option(WITH_HERMETIC_USR "Build with support for hermetic /usr/" OFF)
|
||||||
|
|
||||||
if (WITH_ZLIB)
|
if (WITH_ZLIB)
|
||||||
set(WITH_LIBZ ON)
|
set(WITH_LIBZ ON)
|
||||||
@@ -59,6 +60,11 @@ if (NOT GLOBAL_CLIENT_CONFIG)
|
|||||||
set(GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config")
|
set(GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config")
|
||||||
endif (NOT GLOBAL_CLIENT_CONFIG)
|
endif (NOT GLOBAL_CLIENT_CONFIG)
|
||||||
|
|
||||||
|
if (WITH_HERMETIC_USR)
|
||||||
|
set(USR_GLOBAL_BIND_CONFIG "/usr${GLOBAL_BIND_CONFIG}")
|
||||||
|
set(USR_GLOBAL_CLIENT_CONFIG "/usr${GLOBAL_CLIENT_CONFIG}")
|
||||||
|
endif (WITH_HERMETIC_USR)
|
||||||
|
|
||||||
if (FUZZ_TESTING)
|
if (FUZZ_TESTING)
|
||||||
set(WITH_INSECURE_NONE ON)
|
set(WITH_INSECURE_NONE ON)
|
||||||
endif (FUZZ_TESTING)
|
endif (FUZZ_TESTING)
|
||||||
|
|||||||
@@ -9,9 +9,11 @@
|
|||||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||||
|
|
||||||
/* Global bind configuration file path */
|
/* Global bind configuration file path */
|
||||||
|
#cmakedefine USR_GLOBAL_BIND_CONFIG "${USR_GLOBAL_BIND_CONFIG}"
|
||||||
#cmakedefine GLOBAL_BIND_CONFIG "${GLOBAL_BIND_CONFIG}"
|
#cmakedefine GLOBAL_BIND_CONFIG "${GLOBAL_BIND_CONFIG}"
|
||||||
|
|
||||||
/* Global client configuration file path */
|
/* Global client configuration file path */
|
||||||
|
#cmakedefine USR_GLOBAL_CLIENT_CONFIG "${USR_GLOBAL_CLIENT_CONFIG}"
|
||||||
#cmakedefine GLOBAL_CLIENT_CONFIG "${GLOBAL_CLIENT_CONFIG}"
|
#cmakedefine GLOBAL_CLIENT_CONFIG "${GLOBAL_CLIENT_CONFIG}"
|
||||||
|
|
||||||
/************************** HEADER FILES *************************/
|
/************************** HEADER FILES *************************/
|
||||||
|
|||||||
@@ -49,9 +49,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef int mode_t;
|
typedef int mode_t;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int ssh_config_parse(ssh_session session, FILE *fp, bool global);
|
||||||
int ssh_config_parse_file(ssh_session session, const char *filename);
|
int ssh_config_parse_file(ssh_session session, const char *filename);
|
||||||
int ssh_config_parse_string(ssh_session session, const char *input);
|
int ssh_config_parse_string(ssh_session session, const char *input);
|
||||||
int ssh_options_set_algo(ssh_session session,
|
int ssh_options_set_algo(ssh_session session,
|
||||||
|
|||||||
56
src/config.c
56
src/config.c
@@ -1449,6 +1449,32 @@ ssh_config_parse_line(ssh_session session,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @brief Parse configuration from a file pointer
|
||||||
|
*
|
||||||
|
* @params[in] session The ssh session
|
||||||
|
* @params[in] fp A valid file pointer
|
||||||
|
* @params[in] global Whether the config is global or not
|
||||||
|
*
|
||||||
|
* @returns 0 on successful parsing the configuration file, -1 on error
|
||||||
|
*/
|
||||||
|
int ssh_config_parse(ssh_session session, FILE *fp, bool global)
|
||||||
|
{
|
||||||
|
char line[MAX_LINE_SIZE] = {0};
|
||||||
|
unsigned int count = 0;
|
||||||
|
int parsing, rv;
|
||||||
|
|
||||||
|
parsing = 1;
|
||||||
|
while (fgets(line, sizeof(line), fp)) {
|
||||||
|
count++;
|
||||||
|
rv = ssh_config_parse_line(session, line, count, &parsing, 0, global);
|
||||||
|
if (rv < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* @brief Parse configuration file and set the options to the given session
|
/* @brief Parse configuration file and set the options to the given session
|
||||||
*
|
*
|
||||||
* @params[in] session The ssh session
|
* @params[in] session The ssh session
|
||||||
@@ -1458,36 +1484,32 @@ ssh_config_parse_line(ssh_session session,
|
|||||||
*/
|
*/
|
||||||
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};
|
FILE *fp;
|
||||||
unsigned int count = 0;
|
int rv;
|
||||||
FILE *f;
|
|
||||||
int parsing, rv;
|
|
||||||
bool global = 0;
|
bool global = 0;
|
||||||
|
|
||||||
f = fopen(filename, "r");
|
fp = fopen(filename, "r");
|
||||||
if (f == NULL) {
|
if (fp == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = strcmp(filename, GLOBAL_CLIENT_CONFIG);
|
rv = strcmp(filename, GLOBAL_CLIENT_CONFIG);
|
||||||
|
#ifdef USR_GLOBAL_CLIENT_CONFIG
|
||||||
|
if (rv != 0) {
|
||||||
|
rv = strcmp(filename, USR_GLOBAL_CLIENT_CONFIG);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
global = true;
|
global = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
|
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
|
||||||
|
|
||||||
parsing = 1;
|
rv = ssh_config_parse(session, fp, global);
|
||||||
while (fgets(line, sizeof(line), f)) {
|
|
||||||
count++;
|
|
||||||
rv = ssh_config_parse_line(session, line, count, &parsing, 0, global);
|
|
||||||
if (rv < 0) {
|
|
||||||
fclose(f);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
fclose(fp);
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @brief Parse configuration string and set the options to the given session
|
/* @brief Parse configuration string and set the options to the given session
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#else
|
#else
|
||||||
@@ -1814,6 +1815,8 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv)
|
|||||||
*
|
*
|
||||||
* @param filename The options file to use, if NULL the default
|
* @param filename The options file to use, if NULL the default
|
||||||
* ~/.ssh/config and /etc/ssh/ssh_config will be used.
|
* ~/.ssh/config and /etc/ssh/ssh_config will be used.
|
||||||
|
* If complied with support for hermetic-usr,
|
||||||
|
* /usr/etc/ssh/ssh_config will be used last.
|
||||||
*
|
*
|
||||||
* @return 0 on success, < 0 on error.
|
* @return 0 on success, < 0 on error.
|
||||||
*
|
*
|
||||||
@@ -1821,48 +1824,63 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv)
|
|||||||
*/
|
*/
|
||||||
int ssh_options_parse_config(ssh_session session, const char *filename)
|
int ssh_options_parse_config(ssh_session session, const char *filename)
|
||||||
{
|
{
|
||||||
char *expanded_filename;
|
char *expanded_filename;
|
||||||
int r;
|
int r;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (session->opts.host == NULL) {
|
if (session->opts.host == NULL) {
|
||||||
ssh_set_error_invalid(session);
|
ssh_set_error_invalid(session);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->opts.sshdir == NULL) {
|
if (session->opts.sshdir == NULL) {
|
||||||
r = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL);
|
r = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set default filename */
|
/* set default filename */
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
expanded_filename = ssh_path_expand_escape(session, "%d/config");
|
expanded_filename = ssh_path_expand_escape(session, "%d/config");
|
||||||
} else {
|
} else {
|
||||||
expanded_filename = ssh_path_expand_escape(session, filename);
|
expanded_filename = ssh_path_expand_escape(session, filename);
|
||||||
}
|
}
|
||||||
if (expanded_filename == NULL) {
|
if (expanded_filename == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = ssh_config_parse_file(session, expanded_filename);
|
r = ssh_config_parse_file(session, expanded_filename);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
r = ssh_config_parse_file(session, GLOBAL_CLIENT_CONFIG);
|
if ((fp = fopen(GLOBAL_CLIENT_CONFIG, "r")) != NULL) {
|
||||||
}
|
filename = GLOBAL_CLIENT_CONFIG;
|
||||||
|
#ifdef USR_GLOBAL_CLIENT_CONFIG
|
||||||
|
} else if ((fp = fopen(USR_GLOBAL_CLIENT_CONFIG, "r")) != NULL) {
|
||||||
|
filename = USR_GLOBAL_CLIENT_CONFIG;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Do not process the default configuration as part of connection again */
|
if (fp) {
|
||||||
session->opts.config_processed = true;
|
SSH_LOG(SSH_LOG_PACKET,
|
||||||
|
"Reading configuration data from %s",
|
||||||
|
filename);
|
||||||
|
r = ssh_config_parse(session, fp, true);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do not process the default configuration as part of connection again */
|
||||||
|
session->opts.config_processed = true;
|
||||||
out:
|
out:
|
||||||
free(expanded_filename);
|
free(expanded_filename);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_options_apply(ssh_session session)
|
int ssh_options_apply(ssh_session session)
|
||||||
@@ -2706,7 +2724,13 @@ int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename)
|
|||||||
/* If the global default configuration hasn't been processed yet, process it
|
/* If the global default configuration hasn't been processed yet, process it
|
||||||
* before the provided configuration. */
|
* before the provided configuration. */
|
||||||
if (!(sshbind->config_processed)) {
|
if (!(sshbind->config_processed)) {
|
||||||
rc = ssh_bind_config_parse_file(sshbind, GLOBAL_BIND_CONFIG);
|
if (access(GLOBAL_BIND_CONFIG, F_OK) == 0) {
|
||||||
|
rc = ssh_bind_config_parse_file(sshbind, GLOBAL_BIND_CONFIG);
|
||||||
|
#ifdef USR_GLOBAL_BIND_CONFIG
|
||||||
|
} else {
|
||||||
|
rc = ssh_bind_config_parse_file(sshbind, USR_GLOBAL_BIND_CONFIG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user