Add SIGHUP signal handling to wssshc for configuration reload

- Implement SIGHUP signal handler that triggers configuration reload
- Add reload_configuration() function to reload services config and password
- Reload password from config files when SIGHUP is received
- Reload services configuration from service files
- Update connect_to_server() to accept services parameters for reload functionality
- Add proper cleanup for services in main function

This allows wssshc to reload its configuration without restarting:
- Services configuration from /etc/wsssh.d/ directory
- Password from config files
- All changes take effect immediately without service interruption
parent 821af834
...@@ -47,6 +47,7 @@ int global_debug = 0; ...@@ -47,6 +47,7 @@ int global_debug = 0;
time_t start_time = 0; time_t start_time = 0;
volatile sig_atomic_t sigint_count = 0; volatile sig_atomic_t sigint_count = 0;
volatile sig_atomic_t graceful_shutdown = 0; volatile sig_atomic_t graceful_shutdown = 0;
volatile sig_atomic_t reload_config = 0;
void sigint_handler(int sig __attribute__((unused))) { void sigint_handler(int sig __attribute__((unused))) {
sigint_count++; sigint_count++;
...@@ -61,6 +62,12 @@ void sigint_handler(int sig __attribute__((unused))) { ...@@ -61,6 +62,12 @@ void sigint_handler(int sig __attribute__((unused))) {
} }
} }
void sighup_handler(int sig __attribute__((unused))) {
fprintf(stderr, "\nReceived SIGHUP, reloading configuration...\n");
fflush(stderr);
reload_config = 1;
}
void print_status() { void print_status() {
if (global_debug) return; if (global_debug) return;
...@@ -339,6 +346,54 @@ service_config_t *find_service(service_config_t **services, int num_services, co ...@@ -339,6 +346,54 @@ service_config_t *find_service(service_config_t **services, int num_services, co
return NULL; return NULL;
} }
// Reload configuration (services and password)
void reload_configuration(wssshc_config_t *config, service_config_t ***services, int *num_services) {
fprintf(stderr, "Reloading configuration...\n");
// Reload password from config files
wssshc_config_t temp_config = *config; // Copy current config
load_config(&temp_config); // Reload from files
// Update password if it changed
if (temp_config.password && (!config->password || strcmp(temp_config.password, config->password) != 0)) {
fprintf(stderr, "Password updated from configuration\n");
if (config->password) free(config->password);
config->password = temp_config.password;
temp_config.password = NULL; // Don't free it
}
// Reload services configuration
if (config->services_path) {
// Free existing services
if (*services) {
free_services_config(*services, *num_services);
*services = NULL;
*num_services = 0;
}
// Reload services
*services = load_services_config(config->services_path, num_services);
if (*services) {
fprintf(stderr, "Reloaded %d service configurations\n", *num_services);
} else {
fprintf(stderr, "No service configurations found\n");
}
}
// Free temporary config fields that weren't used
if (temp_config.wssshd_server) free(temp_config.wssshd_server);
if (temp_config.ssh_host) free(temp_config.ssh_host);
if (temp_config.tunnel_host) free(temp_config.tunnel_host);
if (temp_config.client_id) free(temp_config.client_id);
if (temp_config.tunnel) free(temp_config.tunnel);
if (temp_config.tunnel_control) free(temp_config.tunnel_control);
if (temp_config.wssshd_private_ip) free(temp_config.wssshd_private_ip);
if (temp_config.services_path) free(temp_config.services_path);
if (temp_config.default_service) free(temp_config.default_service);
fprintf(stderr, "Configuration reload complete\n");
}
// Execute a command before tunnel connection // Execute a command before tunnel connection
int execute_service_command(const char *command, int debug) { int execute_service_command(const char *command, int debug) {
...@@ -519,7 +574,7 @@ int parse_args(int argc, char *argv[], wssshc_config_t *config) { ...@@ -519,7 +574,7 @@ int parse_args(int argc, char *argv[], wssshc_config_t *config) {
int connect_to_server(const wssshc_config_t *config) { int connect_to_server(const wssshc_config_t *config, service_config_t ***services, int *num_services) {
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
struct hostent *he; struct hostent *he;
int sock; int sock;
...@@ -1322,22 +1377,14 @@ int connect_to_server(const wssshc_config_t *config) { ...@@ -1322,22 +1377,14 @@ int connect_to_server(const wssshc_config_t *config) {
} else { } else {
printf("[EVENT] New tunnel request: %s\n", id_start); printf("[EVENT] New tunnel request: %s\n", id_start);
} }
// Load services if not already loaded (this should be done once at startup) // Services are now loaded in main function
static service_config_t **services = NULL;
static int num_services = 0;
if (!services && config->services_path) {
services = load_services_config(config->services_path, &num_services);
if (config->debug && services) {
printf("[DEBUG] Loaded %d service configurations from %s\n", num_services, config->services_path);
}
}
// Find service configuration // Find service configuration
service_config_t *service = NULL; service_config_t *service = NULL;
const char *requested_service = service_name[0] ? service_name : config->default_service; const char *requested_service = service_name[0] ? service_name : config->default_service;
if (requested_service && services) { if (requested_service && *services) {
service = find_service(services, num_services, requested_service); service = find_service(*services, *num_services, requested_service);
} }
if (service) { if (service) {
...@@ -1520,8 +1567,9 @@ int main(int argc, char *argv[]) { ...@@ -1520,8 +1567,9 @@ int main(int argc, char *argv[]) {
pthread_mutex_init(&tunnel_mutex, NULL); pthread_mutex_init(&tunnel_mutex, NULL);
// Set up signal handler for SIGINT // Set up signal handlers
signal(SIGINT, sigint_handler); signal(SIGINT, sigint_handler);
signal(SIGHUP, sighup_handler);
// Load configuration files first (system and user configs) // Load configuration files first (system and user configs)
load_config(&config); load_config(&config);
...@@ -1591,6 +1639,16 @@ int main(int argc, char *argv[]) { ...@@ -1591,6 +1639,16 @@ int main(int argc, char *argv[]) {
global_debug = config.debug; global_debug = config.debug;
start_time = time(NULL); start_time = time(NULL);
// Load services configuration
service_config_t **services = NULL;
int num_services = 0;
if (config.services_path) {
services = load_services_config(config.services_path, &num_services);
if (config.debug && services) {
printf("[DEBUG] Loaded %d service configurations from %s\n", num_services, config.services_path);
}
}
// Print configured options // Print configured options
printf("WSSSH Client starting...\n"); printf("WSSSH Client starting...\n");
printf("Configuration:\n"); printf("Configuration:\n");
...@@ -1613,6 +1671,12 @@ int main(int argc, char *argv[]) { ...@@ -1613,6 +1671,12 @@ int main(int argc, char *argv[]) {
break; break;
} }
// Check for configuration reload
if (reload_config) {
reload_config = 0; // Reset flag
reload_configuration(&config, &services, &num_services);
}
// Print status every 60 seconds // Print status every 60 seconds
time_t current_time = time(NULL); time_t current_time = time(NULL);
if (current_time - last_status_time >= 60) { if (current_time - last_status_time >= 60) {
...@@ -1620,7 +1684,7 @@ int main(int argc, char *argv[]) { ...@@ -1620,7 +1684,7 @@ int main(int argc, char *argv[]) {
last_status_time = current_time; last_status_time = current_time;
} }
int result = connect_to_server(&config); int result = connect_to_server(&config, &services, &num_services);
if (result == 1) { if (result == 1) {
// Error condition - use short retry interval for immediate reconnection // Error condition - use short retry interval for immediate reconnection
if (config.debug) { if (config.debug) {
...@@ -1643,6 +1707,9 @@ int main(int argc, char *argv[]) { ...@@ -1643,6 +1707,9 @@ int main(int argc, char *argv[]) {
} }
// Cleanup // Cleanup
if (services) {
free_services_config(services, num_services);
}
free(config.wssshd_server); free(config.wssshd_server);
free(config.ssh_host); free(config.ssh_host);
free(config.client_id); free(config.client_id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment