From dd2d7d7738a2719de692b0d3df54201f7d58df53 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 15 Oct 2024 06:55:39 -0400 Subject: [PATCH 1/8] multi-tun support for windows --- lib/ziti-tunnel/include/ziti/ziti_tunnel.h | 1 + programs/ziti-edge-tunnel/CMakeLists.txt | 2 +- programs/ziti-edge-tunnel/config-utils.c | 37 +- .../ziti-edge-tunnel/include/config-utils.h | 26 - .../include/instance-config.h | 11 +- .../include/{identity-utils.h => instance.h} | 5 + .../ziti-edge-tunnel/include/model/dtos.h | 4 +- .../include/windows/windows-scripts.h | 12 +- programs/ziti-edge-tunnel/instance-config.c | 90 +-- programs/ziti-edge-tunnel/instance.c | 48 +- .../netif_driver/windows/tun.c | 2 +- .../netif_driver/windows/tun.h | 2 +- programs/ziti-edge-tunnel/windows-scripts.c | 78 ++- programs/ziti-edge-tunnel/windows-service.c | 6 +- programs/ziti-edge-tunnel/windows/log_utils.c | 8 - programs/ziti-edge-tunnel/ziti-edge-tunnel.c | 626 +++++++++++++----- 16 files changed, 635 insertions(+), 323 deletions(-) delete mode 100644 programs/ziti-edge-tunnel/include/config-utils.h rename programs/ziti-edge-tunnel/include/{identity-utils.h => instance.h} (93%) diff --git a/lib/ziti-tunnel/include/ziti/ziti_tunnel.h b/lib/ziti-tunnel/include/ziti/ziti_tunnel.h index 3de80dcb..e5a6c29c 100644 --- a/lib/ziti-tunnel/include/ziti/ziti_tunnel.h +++ b/lib/ziti-tunnel/include/ziti/ziti_tunnel.h @@ -201,6 +201,7 @@ extern void ziti_tunnel_set_log_level(int lvl); typedef void (*ziti_tunnel_async_fn)(uv_loop_t *loop, void *ctx); extern void ziti_tunnel_async_send(tunneler_context tctx, ziti_tunnel_async_fn f, void *arg); +size_t find_other_zets(model_list* ipcs, const char* base, const char* prefix); #define TNL_IP_MEM_POOL(XX, ...) \ XX(name, model_string, none, Name, __VA_ARGS__) \ diff --git a/programs/ziti-edge-tunnel/CMakeLists.txt b/programs/ziti-edge-tunnel/CMakeLists.txt index fe2c0512..31f97d78 100644 --- a/programs/ziti-edge-tunnel/CMakeLists.txt +++ b/programs/ziti-edge-tunnel/CMakeLists.txt @@ -23,7 +23,7 @@ set(ZITI_INSTANCE_COMMON include/model/events.h include/model/dtos.h instance.c - include/identity-utils.h + include/instance.h config-utils.c include/config-utils.h instance-config.c diff --git a/programs/ziti-edge-tunnel/config-utils.c b/programs/ziti-edge-tunnel/config-utils.c index 97abf355..5d98747c 100644 --- a/programs/ziti-edge-tunnel/config-utils.c +++ b/programs/ziti-edge-tunnel/config-utils.c @@ -22,13 +22,19 @@ #include #endif -const char* app_data = "APPDATA"; +#if _WIN32 +#define realpath(rel, abs) _fullpath(abs, rel, FILENAME_MAX) +#endif + static char* identifier_path = NULL; -char* get_system_config_path() { - char* config_path = malloc(FILENAME_MAX * sizeof(char)); +char* get_system_config_path(const char* base_dir) { + char actual_base_path[FILENAME_MAX]; + realpath(base_dir, actual_base_path); + + char* config_path = calloc(FILENAME_MAX, sizeof(char) + 1); #if _WIN32 - snprintf(config_path, FILENAME_MAX, "%s\\NetFoundry", getenv(app_data)); + snprintf(config_path, FILENAME_MAX, "%s%cNetFoundry", actual_base_path, PATH_SEP); #elif __linux__ snprintf(config_path, FILENAME_MAX, "/var/lib/ziti"); #else @@ -37,7 +43,7 @@ char* get_system_config_path() { return config_path; } -char* get_identifier_path() { +const char* get_identifier_path() { return identifier_path; } @@ -47,24 +53,3 @@ void set_identifier_path(char* id_path) { } } -char* get_config_file_name(char* config_path) { - if (config_path != NULL) { - char* config_file_name = calloc(FILENAME_MAX, sizeof(char)); - snprintf(config_file_name, FILENAME_MAX, "%s/config.json", config_path); - return config_file_name; - } else { - return "config.json"; - } - -} - -char* get_backup_config_file_name(char* config_path) { - if (config_path != NULL) { - char* bkp_config_file_name = calloc(FILENAME_MAX, sizeof(char)); - snprintf(bkp_config_file_name, FILENAME_MAX, "%s/config.json.backup", config_path); - return bkp_config_file_name; - } else { - return "config.json.backup"; - } -} - diff --git a/programs/ziti-edge-tunnel/include/config-utils.h b/programs/ziti-edge-tunnel/include/config-utils.h deleted file mode 100644 index 9cccd1e1..00000000 --- a/programs/ziti-edge-tunnel/include/config-utils.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright 2019-2021 NetFoundry Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -#ifndef ZITI_TUNNEL_SDK_C_CONFIG_UTILS_H -#define ZITI_TUNNEL_SDK_C_CONFIG_UTILS_H - -char* get_system_config_path(); -void set_identifier_path(char* id_dir); -char* get_identifier_path(); -char* get_config_file_name(char* config_path); -char* get_backup_config_file_name(char* config_path); - -#endif //ZITI_TUNNEL_SDK_C_CONFIG_UTILS_H diff --git a/programs/ziti-edge-tunnel/include/instance-config.h b/programs/ziti-edge-tunnel/include/instance-config.h index f752e9ed..e914eba1 100644 --- a/programs/ziti-edge-tunnel/include/instance-config.h +++ b/programs/ziti-edge-tunnel/include/instance-config.h @@ -16,10 +16,19 @@ #ifndef ZITI_TUNNEL_SDK_C_INSTANCE_CONFIG_H #define ZITI_TUNNEL_SDK_C_INSTANCE_CONFIG_H +#include +#include + +#define DEFAULT_STATE_FILE_NAME "config.json" + +char* get_system_config_path(const char* base_path); +void set_identifier_path(char* id_dir); +const char* get_identifier_path(); bool load_tunnel_status_from_file(uv_loop_t *ziti_loop); bool save_tunnel_status_to_file(); -void initialize_instance_config(); +void initialize_instance_config(const char* config_dir); void cleanup_instance_config(); +char* get_config_file_name(); #endif //ZITI_TUNNEL_SDK_C_INSTANCE_CONFIG_H diff --git a/programs/ziti-edge-tunnel/include/identity-utils.h b/programs/ziti-edge-tunnel/include/instance.h similarity index 93% rename from programs/ziti-edge-tunnel/include/identity-utils.h rename to programs/ziti-edge-tunnel/include/instance.h index 8e6ad390..e8b9ed70 100644 --- a/programs/ziti-edge-tunnel/include/identity-utils.h +++ b/programs/ziti-edge-tunnel/include/instance.h @@ -82,6 +82,11 @@ int get_api_page_size(); tunnel_identity_array get_tunnel_identities_for_metrics(); +void normalize_identifier(char *str); + +void set_config_dir(const char *path); +void set_tun_name(const char *name); +char* get_zet_instance_id(const char* discriminator); #ifdef __cplusplus } diff --git a/programs/ziti-edge-tunnel/include/model/dtos.h b/programs/ziti-edge-tunnel/include/model/dtos.h index 4762636d..ac42ad1a 100644 --- a/programs/ziti-edge-tunnel/include/model/dtos.h +++ b/programs/ziti-edge-tunnel/include/model/dtos.h @@ -103,7 +103,9 @@ XX(ServiceVersion, service_version, ptr, ServiceVersion, __VA_ARGS__) \ XX(TunIpv4, model_string, none, TunIpv4, __VA_ARGS__) \ XX(TunPrefixLength, model_number, none, TunIpv4Mask, __VA_ARGS__) \ XX(AddDns, model_bool, none, AddDns, __VA_ARGS__) \ -XX(ApiPageSize, model_number, none, ApiPageSize, __VA_ARGS__) +XX(ApiPageSize, model_number, none, ApiPageSize, __VA_ARGS__) \ +XX(TunName, model_string, none, TunName, __VA_ARGS__)\ +XX(ConfigDir, model_string, none, ConfigDir, __VA_ARGS__) #define IP_INFO(XX, ...) \ XX(Ip, model_string, none, Ip, __VA_ARGS__) \ diff --git a/programs/ziti-edge-tunnel/include/windows/windows-scripts.h b/programs/ziti-edge-tunnel/include/windows/windows-scripts.h index 5454e4ca..00256e8c 100644 --- a/programs/ziti-edge-tunnel/include/windows/windows-scripts.h +++ b/programs/ziti-edge-tunnel/include/windows/windows-scripts.h @@ -28,11 +28,13 @@ #include "ziti/model_support.h" -void add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip); -void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames); -void remove_all_nrpt_rules(); -bool is_nrpt_policies_effective(const char* tns_ip); -void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip); +bool is_nrpt_policies_effective(const char* tns_ip, char* zet_id); + +void add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip, const char* discriminator); +void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* discriminator); +void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip, const char* discriminator); +void remove_all_nrpt_rules(char* zet_id, bool exact); + void update_interface_metric(uv_loop_t *ziti_loop, wchar_t* tun_name, int metric); void update_symlink(uv_loop_t *symlink_loop, char* symlink, char* filename); diff --git a/programs/ziti-edge-tunnel/instance-config.c b/programs/ziti-edge-tunnel/instance-config.c index be22a0dc..85d88305 100644 --- a/programs/ziti-edge-tunnel/instance-config.c +++ b/programs/ziti-edge-tunnel/instance-config.c @@ -14,13 +14,17 @@ limitations under the License. */ +#include "instance-config.h" #include #include -#include #include -#include "identity-utils.h" +#include "instance.h" #include +#if _WIN32 +#define realpath(rel, abs) _fullpath(abs, rel, MAX_PATH) +#endif + // to store the whole tunnel status data #define MIN_BUFFER_LEN 512 @@ -28,7 +32,21 @@ static uv_sem_t sem; static unsigned int sem_value = 1; static int sem_initialized = -1; -void initialize_instance_config() { +static char* config_dir = NULL; +static bool config_saving_enabled = true; + +/// +/// \param path represents the location of the configuration to be used +void initialize_instance_config(const char* path) { + if (!path) { + //indicates this was started with -i (not -I). Operations should not do anything in this case + return; + } + + char actual_config_dir[FILENAME_MAX]; + realpath(path, actual_config_dir); + + config_dir = strdup(actual_config_dir); //save the location of the config dir sem_initialized = uv_sem_init(&sem, sem_value); if (sem_initialized < 0) { ZITI_LOG(WARN, "Could not initialize lock for the config, config file may not be updated"); @@ -66,74 +84,62 @@ bool load_config_from_file(char* config_file_name) { } bool load_tunnel_status_from_file(uv_loop_t* ziti_loop) { - char* config_path = get_system_config_path(); - uv_fs_t fs; - int check = uv_fs_mkdir(ziti_loop, &fs, config_path, 0755, NULL); + int check = uv_fs_mkdir(ziti_loop, &fs, config_dir, 0755, NULL); if (check == 0) { - ZITI_LOG(TRACE, "config path is created at %s", config_path); + ZITI_LOG(TRACE, "config path is created at %s", config_dir); } else if (check == UV_EEXIST) { - ZITI_LOG(TRACE, "config path exists at %s", config_path); + ZITI_LOG(TRACE, "config path exists at %s", config_dir); } else { - ZITI_LOG(ERROR, "error creating %s: %s", config_path, uv_strerror(check)); + ZITI_LOG(ERROR, "error creating %s: %s", config_dir, uv_strerror(check)); return false; } bool loaded = false; - char* config_file_name = get_config_file_name(config_path); - char* bkp_config_file_name = get_backup_config_file_name(config_path); + char* config_file_name = get_config_file_name(); ZITI_LOG(INFO,"Loading config file from %s", config_file_name); // try to load tunnel status from config file loaded = load_config_from_file(config_file_name); - // try to load tunnel status from backup config file + // not able to load the tunnel status if (!loaded) { - loaded = load_config_from_file(bkp_config_file_name); + ZITI_LOG(WARN, "Config file %s cannot be read, does not exist, or is invalid. a new config file will be written if possible.", config_file_name); } - // not able to load the tunnel status from both the config and backup files - if (!loaded) { - ZITI_LOG(WARN, "Config files %s and the backup file cannot be read or they do not exist, will create a new config file or the old one will be overwritten", config_file_name); - } + set_config_dir(config_dir); free(config_file_name); - free(bkp_config_file_name); - free(config_path); return loaded; } bool save_tunnel_status_to_file() { + if(!config_saving_enabled) { + ZITI_LOG(DEBUG, "config_saving_enabled is false. not saving config"); + return true; + } + if(!config_dir) { + // no base_dir indicates using -i not -I + ZITI_LOG(DEBUG, "skipping save_tunnel_status_to_file. config_dir is not set"); + return true; + } size_t json_len; char* tunnel_status = get_tunnel_config(&json_len); bool saved = false; if (json_len > 0) { - char* config_path = get_system_config_path(); - - char* config_file_name = get_config_file_name(config_path); - char* bkp_config_file_name = get_backup_config_file_name(config_path); + char* config_path = get_system_config_path(config_dir); + char* config_file_name = get_config_file_name(); if (sem_initialized == 0) { uv_sem_wait(&sem); } else { ZITI_LOG(ZITI_WTF, "Could not save the config file [%s] due to semaphore lock not initialized error.", config_file_name); free(config_file_name); - free(bkp_config_file_name); free(config_path); free(tunnel_status); return saved; } - //copy config to backup file - int rem = remove(bkp_config_file_name); - if (rem == 0) { - ZITI_LOG(DEBUG, "Deleted backup config file %s", bkp_config_file_name); - } - if (rename(config_file_name, bkp_config_file_name) == 0) { - ZITI_LOG(DEBUG, "Copied config file to backup config file %s", bkp_config_file_name); - } else { - ZITI_LOG(ERROR, "Could not copy config file [%s] to backup config file, the config might not exists at the moment", config_file_name); - } // write tunnel status to the config file FILE* config = fopen(config_file_name, "w"); @@ -152,14 +158,11 @@ bool save_tunnel_status_to_file() { } saved = true; fclose(config); - ZITI_LOG(DEBUG, "Saved current tunnel status into Config file %s", config_file_name); + ZITI_LOG(INFO, "Saved current tunnel status into Config file %s", config_file_name); } uv_sem_post(&sem); - - ZITI_LOG(TRACE, "Cleaning up resources used for the backup of tunnel config file %s", config_file_name); free(config_file_name); - free(bkp_config_file_name); free(config_path); } free(tunnel_status); @@ -176,4 +179,15 @@ void cleanup_instance_config() { } else { ZITI_LOG(ZITI_WTF, "Could not clean instance config. The semaphore is not initialized."); } +} + +char* get_config_file_name() { + if (config_dir != NULL) { + char* config_file_name = calloc(FILENAME_MAX, sizeof(char)); + snprintf(config_file_name, FILENAME_MAX, "%s%c%s", config_dir, PATH_SEP, DEFAULT_STATE_FILE_NAME); + normalize_identifier(config_file_name); + return config_file_name; + } else { + return DEFAULT_STATE_FILE_NAME; + } } \ No newline at end of file diff --git a/programs/ziti-edge-tunnel/instance.c b/programs/ziti-edge-tunnel/instance.c index 1ea7dbeb..b3689c1c 100644 --- a/programs/ziti-edge-tunnel/instance.c +++ b/programs/ziti-edge-tunnel/instance.c @@ -17,10 +17,10 @@ #include "model/dtos.h" #include #include -#include #include "lwip/ip_addr.h" #include "ziti/ziti_tunnel.h" -#include "identity-utils.h" +#include "instance.h" +#include "instance-config.h" #define MIN_API_PAGESIZE 10 #define DEFAULT_API_PAGESIZE 25 @@ -52,7 +52,9 @@ tunnel_identity *create_or_get_tunnel_identity(const char* identifier, const cha return id; } else { tunnel_identity *tnl_id = calloc(1, sizeof(struct tunnel_identity_s)); - tnl_id->Identifier = strdup(identifier); + char* dup_identifier = strdup(identifier); + normalize_identifier(dup_identifier); + tnl_id->Identifier = dup_identifier; if (filename != NULL) { char* extension = strstr(filename, ".json"); @@ -557,9 +559,10 @@ void normalize_identifier(char *str) { if (*str == find) { *str = replace; } + *str = (char)tolower((unsigned char)*str); // Convert to lowercase } #else - return; // nothing to normalize at this time + // nothing to normalize at this time #endif remove_duplicate_path_separators(init_pos, PATH_SEP); } @@ -581,7 +584,14 @@ void set_identifier_from_identities() { if (tnl_id->Identifier != NULL) { // set this field to false during initialization normalize_identifier((char*)tnl_id->Identifier); - model_map_set(&tnl_identity_map, tnl_id->Identifier, tnl_id); + // verify the identity file is still there before adding to the map + + struct stat buffer; + if (stat(tnl_id->Identifier, &buffer) == 0) { + model_map_set(&tnl_identity_map, tnl_id->Identifier, tnl_id); + } else { + ZITI_LOG(WARN, "identity was in config, but file no longer exists. identifier=%s", tnl_id->Identifier); + } } //on startup - set mfa needed to false to correctly reflect tunnel status. After the identity is loaded these //are set to true __if necessary__ @@ -596,7 +606,6 @@ void initialize_tunnel_status() { tnl_status.StartTime.tv_sec = (long)now.tv_sec; tnl_status.StartTime.tv_usec = now.tv_usec; tnl_status.ApiPageSize = DEFAULT_API_PAGESIZE; - } bool load_tunnel_status(const char* config_data) { @@ -882,6 +891,33 @@ int get_api_page_size() { return tnl_status.ApiPageSize; } +void set_config_dir(const char *path) { + tnl_status.ConfigDir = strdup(path); +} + +void set_tun_name(const char *name) { + tnl_status.TunName = strdup(name); +} + +char* get_zet_instance_id(const char* discriminator) { + char empty_delim[] = ""; + char delim[] = "."; + + char *delim_to_use = empty_delim; + if (discriminator != NULL) { + delim_to_use = delim; + } else { + discriminator = empty_delim; // can't use NULL so use the empty delim + } + + size_t prefix_len = strlen(DEFAULT_EXECUTABLE_NAME); + size_t discrim_len = strlen(discriminator); + size_t delim_len = strlen(delim_to_use); + + char *zet_instance_id = calloc(prefix_len + delim_len + discrim_len + 1, sizeof(char)); + sprintf(zet_instance_id, "%s%s%s", DEFAULT_EXECUTABLE_NAME, delim_to_use, discriminator); + return zet_instance_id; +} // ************** TUNNEL BROADCAST MESSAGES IMPL_MODEL(tunnel_identity, TUNNEL_IDENTITY) IMPL_MODEL(tunnel_config, TUNNEL_CONFIG) diff --git a/programs/ziti-edge-tunnel/netif_driver/windows/tun.c b/programs/ziti-edge-tunnel/netif_driver/windows/tun.c index 99f7bea9..5817a7ab 100644 --- a/programs/ziti-edge-tunnel/netif_driver/windows/tun.c +++ b/programs/ziti-edge-tunnel/netif_driver/windows/tun.c @@ -539,7 +539,7 @@ int set_dns(netif_handle tun, uint32_t dns_ip) { return rc; } -wchar_t* get_tun_name(netif_handle tun) { +const wchar_t* get_tun_name(netif_handle tun) { return tun->name; } diff --git a/programs/ziti-edge-tunnel/netif_driver/windows/tun.h b/programs/ziti-edge-tunnel/netif_driver/windows/tun.h index fa0be68e..fd90be61 100644 --- a/programs/ziti-edge-tunnel/netif_driver/windows/tun.h +++ b/programs/ziti-edge-tunnel/netif_driver/windows/tun.h @@ -25,6 +25,6 @@ extern netif_driver tun_open(struct uv_loop_s *loop, uint32_t tun_ip, const char extern int set_dns(netif_handle tun, uint32_t dns_ip); -extern wchar_t* get_tun_name(netif_handle tun); +extern const wchar_t* get_tun_name(netif_handle tun); #endif //ZITI_TUNNEL_SDK_C_TUN_H diff --git a/programs/ziti-edge-tunnel/windows-scripts.c b/programs/ziti-edge-tunnel/windows-scripts.c index e4741bb6..ce7ceb93 100644 --- a/programs/ziti-edge-tunnel/windows-scripts.c +++ b/programs/ziti-edge-tunnel/windows-scripts.c @@ -18,12 +18,12 @@ #include #include "ziti/ziti_tunnel.h" #include "windows/windows-scripts.h" +#include "instance.h" #define MAX_BUCKET_SIZE 512 #define MIN_BUFFER_LEN 512 static char* const namespace_template = "%s@{n='%s';}"; -static char* const exe_name = "ziti-edge-tunnel"; struct hostname_s { char *hostname; @@ -34,7 +34,7 @@ typedef LIST_HEAD(hostname_list_s, hostname_s) hostname_list_t; static void exit_cb(uv_process_t* process, int64_t exit_status, int term_signal) { - ZITI_LOG(TRACE, "Process exited with status %d, signal %d", exit_status, term_signal); + ZITI_LOG(TRACE, "Process exited with status %lld, signal %d", exit_status, term_signal); uv_close((uv_handle_t*)process, (uv_close_cb) free); } @@ -107,7 +107,7 @@ const char *normalize_hostname(char *hostname) { return hostname; } -void chunked_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, char* tun_ip) { +void chunked_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, const char* tun_ip, const char* zet_instance) { char script[MAX_POWERSHELL_SCRIPT_LEN] = { 0 }; size_t buf_len = snprintf(script, MAX_POWERSHELL_SCRIPT_LEN, "$Namespaces = @("); if (!is_buffer_available(buf_len, MAX_POWERSHELL_SCRIPT_LEN, script)) { @@ -144,7 +144,7 @@ void chunked_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, ch return; } copied += buf_len; - buf_len = snprintf(script + copied, (MAX_POWERSHELL_SCRIPT_LEN - copied), "$Rule = @{Namespace=${ns}; NameServers=@('%s'); Comment='Added by %s'; DisplayName='%s:'+${ns}; }\n", tun_ip, exe_name, exe_name); + buf_len = snprintf(script + copied, (MAX_POWERSHELL_SCRIPT_LEN - copied), "$Rule = @{Namespace=${ns}; NameServers=@('%s'); Comment='Added by %s'; DisplayName='%s:'+${ns}; }\n", tun_ip, zet_instance, zet_instance); if (!is_buffer_available(buf_len, (MAX_POWERSHELL_SCRIPT_LEN - copied), script)) { return; } @@ -173,13 +173,13 @@ void chunked_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, ch const char* args[] = {"powershell", "-Command", script, NULL}; bool result = exec_process(ziti_loop, args[0], args); if (!result) { - ZITI_LOG(WARN, "Add domains NRPT script: %d(err=%d)", result, GetLastError()); + ZITI_LOG(WARN, "Add domains NRPT script: %d(err=%lu)", result, GetLastError()); } else { ZITI_LOG(DEBUG, "Added domains using NRPT script"); } } -void add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip) { +void add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip, const char* zet_id) { ZITI_LOG(VERBOSE, "Add nrpt rules"); if (hostnames == NULL || model_map_size(hostnames) == 0) { @@ -194,7 +194,7 @@ void add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ while(it != NULL) { const char* hostname = model_map_it_key(it); if (current_size > MAX_BUCKET_SIZE || rule_size > MAX_POWERSHELL_SCRIPT_LEN) { - chunked_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip); + chunked_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip, zet_id); rule_size = MIN_BUFFER_LEN; current_size = 0; } @@ -207,11 +207,11 @@ void add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ it = model_map_it_remove(it); } if (current_size > 0) { - chunked_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip); + chunked_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip, zet_id); } } -void chunked_remove_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames) { +void chunked_remove_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, const char* discriminator) { char script[MAX_POWERSHELL_SCRIPT_LEN] = { 0 }; size_t buf_len = snprintf(script, MAX_POWERSHELL_SCRIPT_LEN, "$toRemove = @(\n"); if (!is_buffer_available(buf_len, MAX_POWERSHELL_SCRIPT_LEN, script)) { @@ -264,13 +264,13 @@ void chunked_remove_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames) const char* args[] = {"powershell", "-Command", script, NULL}; bool result = exec_process(ziti_loop, args[0], args); if (!result) { - ZITI_LOG(WARN, "Remove domains NRPT script: %d(err=%d)", result, GetLastError()); + ZITI_LOG(WARN, "Remove domains NRPT script: %d(err=%lu)", result, GetLastError()); } else { ZITI_LOG(DEBUG, "Removed domains using NRPT script"); } } -void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames) { +void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* discriminator) { ZITI_LOG(VERBOSE, "Remove nrpt rules"); if (hostnames == NULL || model_map_size(hostnames) == 0) { @@ -285,7 +285,7 @@ void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames) { while(it != NULL) { const char* hostname = model_map_it_key(it); if (current_size > MAX_BUCKET_SIZE || rule_size > MAX_POWERSHELL_SCRIPT_LEN) { - chunked_remove_nrpt_rules(nrpt_loop, &host_names_list); + chunked_remove_nrpt_rules(nrpt_loop, &host_names_list, discriminator); rule_size = MIN_BUFFER_LEN; current_size = 0; } @@ -298,25 +298,41 @@ void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames) { it = model_map_it_remove(it); } if (current_size > 0) { - chunked_remove_nrpt_rules(nrpt_loop, &host_names_list); + chunked_remove_nrpt_rules(nrpt_loop, &host_names_list, discriminator); } } -void remove_all_nrpt_rules() { +char* get_nrpt_comment(char* zet_id, bool exact) { + size_t tot_chars = 40 + strlen(zet_id); + char* nrpt_filter = calloc(tot_chars+1, sizeof(char)); + if(exact) { + snprintf(nrpt_filter, tot_chars, "$_.Comment -eq 'Added by %s'", zet_id); + } else { + snprintf(nrpt_filter, tot_chars, "$_.Comment.StartsWith('Added by %s')", zet_id); + } + return nrpt_filter; +} + +void remove_all_nrpt_rules(char* zet_id, bool exact) { char remove_cmd[MAX_POWERSHELL_COMMAND_LEN]; - size_t buf_len = sprintf(remove_cmd, "powershell -Command \"Get-DnsClientNrptRule | Where { $_.Comment.StartsWith('Added by %s') } | Remove-DnsClientNrptRule -ErrorAction SilentlyContinue -Force\"", exe_name); + + char* nrpt_filter = get_nrpt_comment(zet_id, exact); + ZITI_LOG(INFO, "removing NRPT rules matching filter: %s", nrpt_filter); + size_t buf_len = snprintf(remove_cmd, MAX_POWERSHELL_COMMAND_LEN, "powershell -Command \"Get-DnsClientNrptRule | Where { %s } | Remove-DnsClientNrptRule -ErrorAction SilentlyContinue -Force\"", nrpt_filter); + free(nrpt_filter); + ZITI_LOG(TRACE, "Removing all nrpt rules. total script size: %zd", buf_len); ZITI_LOG(DEBUG, "Executing Remove all nrpt rules: '%s'", remove_cmd); int rc = system(remove_cmd); if (rc != 0) { - ZITI_LOG(WARN, "Remove all NRPT script: %d(err=%d)", rc, GetLastError()); + ZITI_LOG(WARN, "Remove all NRPT script: %d(err=%lu)", rc, GetLastError()); } else { ZITI_LOG(DEBUG, "Removed all nrpt rules"); } } -void chunked_remove_and_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, const char* dns_ip) { +void chunked_remove_and_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *hostnames, const char* dns_ip, const char* zet_id) { char script[MAX_POWERSHELL_SCRIPT_LEN] = { 0 }; size_t buf_len = snprintf(script, MAX_POWERSHELL_SCRIPT_LEN, "$toRemoveAndAdd = @(\n"); if (!is_buffer_available(buf_len, MAX_POWERSHELL_SCRIPT_LEN, script)) { @@ -355,7 +371,7 @@ void chunked_remove_and_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *ho return; } copied += buf_len; - buf_len = snprintf(script + copied, (MAX_POWERSHELL_SCRIPT_LEN - copied), "$Rule = @{Namespace=${nsToAdd}; NameServers=@('%s'); Comment='Added by %s'; DisplayName='%s:'+${ns}; }\n", dns_ip, exe_name, exe_name); + buf_len = snprintf(script + copied, (MAX_POWERSHELL_SCRIPT_LEN - copied), "$Rule = @{Namespace=${nsToAdd}; NameServers=@('%s'); Comment='Added by %s'; DisplayName='%s:'+${ns}; }\n", dns_ip, zet_id, zet_id); if (!is_buffer_available(buf_len, (MAX_POWERSHELL_SCRIPT_LEN - copied), script)) { return; } @@ -384,13 +400,13 @@ void chunked_remove_and_add_nrpt_rules(uv_loop_t *ziti_loop, hostname_list_t *ho const char* args[] = {"powershell", "-Command", script, NULL}; bool result = exec_process(ziti_loop, args[0], args); if (!result) { - ZITI_LOG(WARN, "Remove and add domains NRPT script: %d(err=%d)", result, GetLastError()); + ZITI_LOG(WARN, "Remove and add domains NRPT script: %d(err=%lu)", result, GetLastError()); } else { ZITI_LOG(DEBUG, "Removed and added domains using NRPT script"); } } -void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip) { +void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip, const char* zet_id) { ZITI_LOG(VERBOSE, "Remove and add nrpt rules"); if (hostnames == NULL || model_map_size(hostnames) == 0) { @@ -405,7 +421,7 @@ void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const while(it != NULL) { const char* hostname = model_map_it_key(it); if (current_size > MAX_BUCKET_SIZE || rule_size > MAX_POWERSHELL_SCRIPT_LEN) { - chunked_remove_and_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip); + chunked_remove_and_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip, zet_id); rule_size = MIN_BUFFER_LEN; current_size = 0; } @@ -418,7 +434,7 @@ void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const it = model_map_it_remove(it); } if (current_size > 0) { - chunked_remove_and_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip); + chunked_remove_and_add_nrpt_rules(nrpt_loop, &host_names_list, dns_ip, zet_id); } } @@ -430,21 +446,21 @@ void remove_single_nrpt_rule(char* nrpt_rule) { ZITI_LOG(DEBUG, "Executing Remove nrpt rule: %s", remove_cmd); int rc = system(remove_cmd); if (rc != 0) { - ZITI_LOG(WARN, "Delete single NRPT rule: %d(err=%d)", rc, GetLastError()); + ZITI_LOG(WARN, "Delete single NRPT rule: %d(err=%lu)", rc, GetLastError()); } else { ZITI_LOG(DEBUG, "Removed nrpt rules"); } } -bool is_nrpt_policies_effective(const char* tns_ip) { +bool is_nrpt_policies_effective(const char* tns_ip, char* zet_id) { char add_cmd[MAX_POWERSHELL_COMMAND_LEN]; - size_t buf_len = sprintf(add_cmd, "powershell -Command \"Add-DnsClientNrptRule -Namespace '.ziti.test' -NameServers '%s' -Comment 'Added by ziti-edge-tunnel' -DisplayName 'ziti-edge-tunnel:.ziti.test'\"",tns_ip); + size_t buf_len = sprintf(add_cmd, "powershell -Command \"Add-DnsClientNrptRule -Namespace '.ziti.test' -NameServers '%s' -Comment 'Added by %s' -DisplayName '%s:.ziti.test'\"",tns_ip, zet_id, zet_id); ZITI_LOG(TRACE, "add test nrpt rule. total script size: %zd", buf_len); ZITI_LOG(DEBUG, "Executing add test nrpt rule. %s", add_cmd); int rc = system(add_cmd); if (rc != 0) { - ZITI_LOG(WARN, "Add test NRPT rule: %d(err=%d)", rc, GetLastError()); + ZITI_LOG(WARN, "Add test NRPT rule: %d(err=%lu)", rc, GetLastError()); return false; } @@ -494,7 +510,7 @@ void update_interface_metric(uv_loop_t *ziti_loop, wchar_t* tun_name, int metric const char* args[] = {"powershell", "-Command", script, NULL}; bool result = exec_process(ziti_loop, args[0], args); if (!result) { - ZITI_LOG(WARN, "Update Interface metric script: %d(err=%d)", result, GetLastError()); + ZITI_LOG(WARN, "Update Interface metric script: %d(err=%lu)", result, GetLastError()); } else { ZITI_LOG(DEBUG, "Updated Interface metric"); } @@ -502,9 +518,9 @@ void update_interface_metric(uv_loop_t *ziti_loop, wchar_t* tun_name, int metric void update_symlink(uv_loop_t *symlink_loop, char* symlink, char* filename) { char script[MAX_POWERSHELL_SCRIPT_LEN] = { 0 }; - size_t buf_len = sprintf(script, "Get-Item -Path \"%s\" | Remove-Item\n", symlink); + size_t buf_len = sprintf(script, "Get-Item -Path \"%s\" | Remove-Item;", symlink); size_t copied = buf_len; - buf_len = sprintf(script + copied, "New-Item -Itemtype SymbolicLink -Path \"%s\" -Target \"%s\"", symlink, filename); + buf_len = sprintf(script + copied, "New-Item -Itemtype SymbolicLink -Path \"%s\" -Target \"%s\" | Out-Null", symlink, filename); copied += buf_len; ZITI_LOG(TRACE, "Updating symlink using script. total script size: %zd", copied); @@ -517,8 +533,8 @@ void update_symlink(uv_loop_t *symlink_loop, char* symlink, char* filename) { char* args[] = {"powershell", "-Command", script, NULL}; bool result = exec_process(symlink_loop, args[0], args); if (!result) { - ZITI_LOG(WARN, "Update symlink script: %d(err=%d)", result, GetLastError()); + ZITI_LOG(WARN, "Update symlink script: %d(err=%lu)", result, GetLastError()); } else { ZITI_LOG(DEBUG, "Updated symlink script"); } -} +} \ No newline at end of file diff --git a/programs/ziti-edge-tunnel/windows-service.c b/programs/ziti-edge-tunnel/windows-service.c index 6546e980..8ee66232 100644 --- a/programs/ziti-edge-tunnel/windows-service.c +++ b/programs/ziti-edge-tunnel/windows-service.c @@ -16,11 +16,10 @@ limitations under the License. #include #include -#include - #include #include #include +#include #pragma comment(lib, "advapi32.lib") @@ -160,8 +159,9 @@ VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ); // Perform service-specific initialization and work. - char* config_dir = get_system_config_path(); + char* config_dir = get_system_config_path(getenv("APPDATA")); scm_service_init(config_dir); + free(config_dir); SvcInit( dwArgc, lpszArgv ); } diff --git a/programs/ziti-edge-tunnel/windows/log_utils.c b/programs/ziti-edge-tunnel/windows/log_utils.c index 83796130..4be95fda 100644 --- a/programs/ziti-edge-tunnel/windows/log_utils.c +++ b/programs/ziti-edge-tunnel/windows/log_utils.c @@ -93,14 +93,6 @@ static char* get_log_path() { snprintf(log_path, FILENAME_MAX, "%slogs%cservice", process_dir, PATH_SEP); } mkdir_p(log_path); - - struct stat info; - if (stat(log_path, &info) != 0) { - fprintf(stderr,"\nlogging cannot proceed. the path could not be created: %s!\n", log_path); - } else { - fprintf(stderr,"\nlogs enabled at: %s\n", log_path); - } - return log_path; } diff --git a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c index 0a3f53a1..b03e0971 100644 --- a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c +++ b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c @@ -25,9 +25,8 @@ #include #include #include "model/events.h" -#include "identity-utils.h" +#include "instance.h" #include "instance-config.h" -#include #include #if __APPLE__ && __MACH__ @@ -42,6 +41,7 @@ #include "windows/windows-scripts.h" #define setenv(n,v,o) do {if(o || getenv(n) == NULL) _putenv_s(n,v); } while(0) + #endif #ifndef MAXIPCCOMMANDLEN @@ -62,6 +62,13 @@ #define S_IWUSR _S_IWRITE #endif +#if _WIN32 +#define LAST_CHAR_IPC_CMD "\n" +#define realpath(rel, abs) _fullpath(abs, rel, MAX_PATH) +#else +#define LAST_CHAR_IPC_CMD "\0" +#endif + //functions for logging on windows bool log_init(uv_loop_t *); void ziti_log_writer(int , const char *, const char *, size_t); @@ -80,13 +87,11 @@ static void stop_tunnel_and_cleanup(); static bool is_host_only(); static void run_tunneler_loop(uv_loop_t* ziti_loop); static tunneler_context initialize_tunneler(netif_driver tun, uv_loop_t* ziti_loop); +static struct json_object* send_message_to_tunnel(char* message, char* ipc); -#if _WIN32 -static void move_config_from_previous_windows_backup(uv_loop_t *loop); -#define LAST_CHAR_IPC_CMD '\n' -#else -#define LAST_CHAR_IPC_CMD '\0' -#endif +static tunnel_command cmd = { + .show_result = true, // consistent with old behaviour +}; struct ipc_cmd_s { char *cmd_data; @@ -135,6 +140,7 @@ static char *configured_cidr = NULL; static char *configured_log_level = NULL; static char *configured_proxy = NULL; static char *config_dir = NULL; +static char *ipc_discriminator = NULL; static uv_pipe_t cmd_server; static uv_pipe_t event_server; @@ -155,16 +161,20 @@ static uv_cond_t stop_cond; IMPL_ENUM(event, EVENT_ACTIONS) #if _WIN32 -static char sockfile[] = "\\\\.\\pipe\\ziti-edge-tunnel.sock"; -static char eventsockfile[] = "\\\\.\\pipe\\ziti-edge-tunnel-event.sock"; +static char SOCKET_PATH[] = "\\\\.\\pipe\\"; +static char sockfilebase[] = "ziti-edge-tunnel.sock"; +static char eventsockfilebase[] = "ziti-edge-tunnel-event.sock"; #elif __unix__ || unix || ( __APPLE__ && __MACH__ ) #include #include -#define SOCKET_PATH "/tmp/.ziti" -static char sockfile[] = SOCKET_PATH "/ziti-edge-tunnel.sock"; -static char eventsockfile[] = SOCKET_PATH "/ziti-edge-tunnel-event.sock"; +static char SOCKET_PATH[] = "/tmp/.ziti/"; +static char sockfilebase[] = "ziti-edge-tunnel.sock"; +static char eventsockfilebase[] = "ziti-edge-tunnel-event.sock"; #endif +static char* sockfile; +static char* eventsockfile; + static int sizeof_event_clients_list() { struct event_conn_s *event_client; int size = 0; @@ -266,7 +276,7 @@ static void on_command_resp(const tunnel_result* result, void *ctx) { } if (model_map_size(&hostnamesToRemove) > 0) { - remove_nrpt_rules(global_loop_ref, &hostnamesToRemove); + remove_nrpt_rules(global_loop_ref, &hostnamesToRemove, ipc_discriminator); } } } else { @@ -305,7 +315,7 @@ static void on_command_resp(const tunnel_result* result, void *ctx) { if (uv_is_active((const uv_handle_t *) ctx)) { uv_buf_t buf; - size_t data_len = json_len + strlen("\n") + 1; + size_t data_len = json_len + strlen(LAST_CHAR_IPC_CMD) + 1; buf.base = calloc(data_len, sizeof(char)); snprintf(buf.base, data_len, "%s\n", json); buf.len = strlen(buf.base); @@ -390,6 +400,7 @@ static bool process_tunnel_commands(const tunnel_command *tnl_cmd, command_cb cb .code = IPC_ERROR, }; bool cmd_accepted = false; + bool save_config = true; switch (tnl_cmd->command) { case TunnelCommand_SetLogLevel: { cmd_accepted = true; @@ -489,6 +500,7 @@ static bool process_tunnel_commands(const tunnel_command *tnl_cmd, command_cb cb } case TunnelCommand_Status: { cmd_accepted = true; + save_config = false; // no need to save the file tunnel_status* status = get_tunnel_status(); result.success = true; result.code = IPC_SUCCESS; @@ -561,9 +573,9 @@ static bool process_tunnel_commands(const tunnel_command *tnl_cmd, command_cb cb add_id_req->identifier = strdup(new_identifier); add_id_req->identifier_file_name = strdup(new_identifier_name); add_id_req->jwt_content = strdup(tunnel_add_identity_cmd.jwtContent); - add_id_req->use_keychain = tunnel_add_identity_cmd.useKeychain; - + add_id_req->use_keychain = true; enroll_ziti_async(global_loop_ref, add_id_req); + free_tunnel_add_identity(&tunnel_add_identity_cmd); return true; } @@ -614,7 +626,11 @@ static bool process_tunnel_commands(const tunnel_command *tnl_cmd, command_cb cb cb(&result, ctx); if (result.success) { // should be the last line in this function as it calls the mutex/lock - save_tunnel_status_to_file(); + if(save_config) { + save_tunnel_status_to_file(); + } else { + + } } if (result.data) { free(result.data); @@ -702,26 +718,26 @@ static void on_cmd_client(uv_stream_t *s, int status) { ZITI_LOG(DEBUG,"Received IPC client connection request, count: %d", ++current_ipc_channels); } -static int start_cmd_socket(uv_loop_t *l) { +static int start_cmd_socket(uv_loop_t *l, const char* ipc) { if (uv_is_active((const uv_handle_t *) &cmd_server)) { return 0; } uv_fs_t fs; - uv_fs_unlink(l, &fs, sockfile, NULL); + uv_fs_unlink(l, &fs, ipc, NULL); #define CHECK_UV(op) do{ \ int uv_rc = (op); \ if (uv_rc != 0) { \ - ZITI_LOG(WARN, "failed to open IPC socket op=[%s] err=%d[%s]", #op, uv_rc, uv_strerror(uv_rc));\ + ZITI_LOG(WARN, "failed to open IPC socket path=[%s] op=[%s] err=%d[%s]", ipc, #op, uv_rc, uv_strerror(uv_rc));\ goto uv_err; \ } \ } while(0) CHECK_UV(uv_pipe_init(l, &cmd_server, 0)); - CHECK_UV(uv_pipe_bind(&cmd_server, sockfile)); + CHECK_UV(uv_pipe_bind(&cmd_server, ipc)); CHECK_UV(uv_pipe_chmod(&cmd_server, UV_WRITABLE | UV_READABLE)); uv_unref((uv_handle_t *) &cmd_server); @@ -822,17 +838,17 @@ static void send_events_message(const void *message, to_json_fn to_json_f, bool free(json); } -static int start_event_socket(uv_loop_t *l) { +static int start_event_socket(uv_loop_t *l, const char* ipc) { if (uv_is_active((const uv_handle_t *) &event_server)) { return 0; } uv_fs_t fs; - uv_fs_unlink(l, &fs, eventsockfile, NULL); + uv_fs_unlink(l, &fs, ipc, NULL); CHECK_UV(uv_pipe_init(l, &event_server, 0)); - CHECK_UV(uv_pipe_bind(&event_server, eventsockfile)); + CHECK_UV(uv_pipe_bind(&event_server, ipc)); CHECK_UV(uv_pipe_chmod(&event_server, UV_WRITABLE | UV_READABLE)); uv_unref((uv_handle_t *) &event_server); @@ -1102,36 +1118,39 @@ static void load_identities(uv_work_t *wr) { uv_dirent_t file; while (uv_fs_scandir_next(&fs, &file) == 0) { - ZITI_LOG(TRACE, "processing file: %s %d", file.name, rc); + char* file_as_identifier = malloc(MAXPATHLEN); + snprintf(file_as_identifier, MAXPATHLEN, "%s%c%s", config_dir, PATH_SEP, file.name); + normalize_identifier(file_as_identifier); + ZITI_LOG(TRACE, "processing file: %s %d", file_as_identifier, rc); if(file.type != UV_DIRENT_FILE) { - ZITI_LOG(DEBUG, "skipping file in config dir as it's not the proper type. type: %d. file: %s", file.type, file.name); - continue; + ZITI_LOG(DEBUG, "skipping file in config dir as it's not the proper type. type: %d. file: %s", file.type, file_as_identifier); + goto exit_loop; } - - if (strcasecmp(file.name, get_config_file_name(NULL)) == 0) { - ZITI_LOG(DEBUG, "skipping the configuration file: %s", file.name); - continue; - } else if(strcasecmp(file.name, get_backup_config_file_name(NULL)) == 0 ) { - ZITI_LOG(DEBUG, "skipping the backup configuration file: %s", file.name); - continue; + char* cfg_file_name = get_config_file_name(); + normalize_identifier(cfg_file_name); + if (strcasecmp(file_as_identifier, cfg_file_name) == 0) { + ZITI_LOG(DEBUG, "skipping the configuration file: %s", file_as_identifier); + goto exit_loop; } + free(cfg_file_name); - const char* ext = get_filename_ext(file.name); + const char* ext = get_filename_ext(file_as_identifier); // ignore back up files if (strcasecmp(ext, ".bak") == 0 || strcasecmp(ext, ".original") == 0 || strcasecmp(ext, "json") != 0) { - ZITI_LOG(DEBUG, "skipping backup file: %s", file.name); - continue; + ZITI_LOG(DEBUG, "skipping backup file: %s", file_as_identifier); + goto exit_loop; } - ZITI_LOG(INFO, "loading identity file: %s", file.name); + ZITI_LOG(INFO, "loading identity file: %s", file_as_identifier); if (file.type == UV_DIRENT_FILE) { struct cfg_instance_s *inst = calloc(1, sizeof(struct cfg_instance_s)); - inst->cfg = malloc(MAXPATHLEN); - snprintf(inst->cfg, MAXPATHLEN, "%s%c%s", config_dir, PATH_SEP, file.name); - create_or_get_tunnel_identity(inst->cfg, file.name); + inst->cfg = strdup(file_as_identifier); + create_or_get_tunnel_identity(inst->cfg, file_as_identifier); LIST_INSERT_HEAD(&load_list, inst, _next); } + exit_loop: + free(file_as_identifier); } } } @@ -1152,6 +1171,8 @@ static void load_identities_complete(uv_work_t * wr, int status) { struct cfg_instance_s *inst = LIST_FIRST(&load_list); LIST_REMOVE(inst, _next); + normalize_identifier(inst->cfg); + if (config_dir == NULL) { create_or_get_tunnel_identity(inst->cfg, inst->cfg); } @@ -1336,13 +1357,15 @@ static void on_event(const base_event *ev) { } if (id->Active && model_map_size(&hostnamesToEdit) > 0 && !is_host_only()) { - remove_and_add_nrpt_rules(global_loop_ref, &hostnamesToEdit, get_dns_ip()); + remove_and_add_nrpt_rules(global_loop_ref, &hostnamesToEdit, get_dns_ip(), ipc_discriminator); } if (id->Active && model_map_size(&hostnamesToAdd) > 0 && !is_host_only()) { - add_nrpt_rules(global_loop_ref, &hostnamesToAdd, get_dns_ip()); + char* zet_id = get_zet_instance_id(ipc_discriminator); + add_nrpt_rules(global_loop_ref, &hostnamesToAdd, get_dns_ip(), zet_id); + free(zet_id); } if (model_map_size(&hostnamesToRemove) > 0 && !is_host_only()) { - remove_nrpt_rules(global_loop_ref, &hostnamesToRemove); + remove_nrpt_rules(global_loop_ref, &hostnamesToRemove, ipc_discriminator); } #endif @@ -1517,7 +1540,7 @@ static void on_event(const base_event *ev) { } } -static char* normalize_host(char* hostname) { +static char* normalize_host(const char* hostname) { size_t len = strlen(hostname); char* hostname_new = calloc(len+2, sizeof(char)); // add . in the beginning of the hostname @@ -1556,9 +1579,18 @@ static int run_tunnel(uv_loop_t *ziti_loop, uint32_t tun_ip, uint32_t dns_ip, co ZITI_LOG(ERROR, "failed to open network interface: %s", tun_error); return 1; } + const wchar_t* tun_name = get_tun_name(tun->handle); + size_t tun_name_len = wcslen(tun_name); + char* name = calloc(tun_name_len, sizeof(char) + 1); + wcstombs(name, tun_name, tun_name_len + 1); + set_tun_name(name); + free(name); #if _WIN32 - bool nrpt_effective = is_nrpt_policies_effective(get_dns_ip()); + + char* zet_id = get_zet_instance_id(ipc_discriminator); + bool nrpt_effective = is_nrpt_policies_effective(get_dns_ip(), zet_id); + free(zet_id); if (!nrpt_effective || get_add_dns_flag()) { if (get_add_dns_flag()) { ZITI_LOG(INFO, "DNS is enabled for the TUN interface, because apply Dns flag in the config file is true"); @@ -1568,10 +1600,10 @@ static int run_tunnel(uv_loop_t *ziti_loop, uint32_t tun_ip, uint32_t dns_ip, co } set_dns(tun->handle, dns_ip); ZITI_LOG(INFO, "Setting interface metric to 5"); - update_interface_metric(ziti_loop, get_tun_name(tun->handle), 5); + update_interface_metric(ziti_loop, tun_name, 5); } else { ZITI_LOG(INFO, "Setting interface metric to 255"); - update_interface_metric(ziti_loop, get_tun_name(tun->handle), 255); + update_interface_metric(ziti_loop, tun_name, 255); } #endif @@ -1732,8 +1764,8 @@ static void run_tunneler_loop(uv_loop_t* ziti_loop) { int rc0 = 0, rc1; rc0 = rc1 = make_socket_path(ziti_loop); if (rc0 == 0) { - rc0 = start_cmd_socket(ziti_loop); - rc1 = start_event_socket(ziti_loop); + rc0 = start_cmd_socket(ziti_loop, sockfile); + rc1 = start_event_socket(ziti_loop, eventsockfile); } if (rc0 < 0 || rc1 < 0) { @@ -1803,7 +1835,7 @@ static void usage(int argc, char *argv[]) { return; } char *help_args[] = { - "ziti-edge-tunnel", + DEFAULT_EXECUTABLE_NAME, argv[0], "-h" }; @@ -1818,6 +1850,7 @@ static struct option run_options[] = { { "dns-ip-range", required_argument, NULL, 'd'}, { "dns-upstream", required_argument, NULL, 'u'}, { "proxy", required_argument, NULL, 'x' }, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; static struct option run_host_options[] = { @@ -1884,17 +1917,20 @@ static int run_opts(int argc, char *argv[]) { optind = 0; bool identity_provided = false; - while ((c = getopt_long(argc, argv, "i:I:v:r:d:u:x:", + while ((c = getopt_long(argc, argv, "i:I:v:r:d:u:x:p:P:", run_options, &option_index)) != -1) { switch (c) { case 'i': { struct cfg_instance_s *inst = calloc(1, sizeof(struct cfg_instance_s)); + normalize_identifier(optarg); inst->cfg = strdup(optarg); + create_or_get_tunnel_identity(inst->cfg, inst->cfg); LIST_INSERT_HEAD(&load_list, inst, _next); identity_provided = true; break; } case 'I': + normalize_identifier(optarg); config_dir = optarg; identity_provided = true; break; @@ -1915,6 +1951,9 @@ static int run_opts(int argc, char *argv[]) { case 'x': configured_proxy = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -1936,12 +1975,13 @@ static int run_host_opts(int argc, char *argv[]) { optind = 0; bool identity_provided = false; - while ((c = getopt_long(argc, argv, "i:I:v:r:x:", + while ((c = getopt_long(argc, argv, "i:I:v:r:x:P:", run_host_options, &option_index)) != -1) { switch (c) { case 'i': { struct cfg_instance_s *inst = calloc(1, sizeof(struct cfg_instance_s)); inst->cfg = strdup(optarg); + create_or_get_tunnel_identity(inst->cfg, inst->cfg); LIST_INSERT_HEAD(&load_list, inst, _next); identity_provided = true; break; @@ -1961,6 +2001,9 @@ static int run_host_opts(int argc, char *argv[]) { case 'x': configured_proxy = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -1998,12 +2041,87 @@ static void interrupt_handler(int sig) { } #endif +size_t find_other_zets(model_list* ipcs, const char* ipc_base, const char* ipc_prefix) { + uv_fs_t fs; + int rc = uv_fs_scandir(uv_default_loop(), &fs, SOCKET_PATH, 0, NULL); + if (rc < 0) { + ZITI_LOG(ERROR, "failed to scan dir[%s]: %d/%s", ipc_base, rc, uv_strerror(rc)); + return 0; + } + uv_dirent_t file; + while (uv_fs_scandir_next(&fs, &file) == 0) { + size_t len = strlen(ipc_prefix); + if(strncmp(file.name, ipc_prefix, len) == 0) { + model_list_append(ipcs, strdup(file.name)); + } + } + return model_list_size(ipcs); +} + +static bool same_dir(const char* path1, const char* path2) { + char resolved_path1[PATH_MAX]; + char resolved_path2[PATH_MAX]; + + if (realpath(path1, resolved_path1) == NULL) { + ZITI_LOG(ERROR, "error resolving path1"); + return 0; + } + + if (realpath(path2, resolved_path2) == NULL) { + ZITI_LOG(ERROR, "error resolving path2"); + return 0; + } + + return strcmp(resolved_path1, resolved_path2) == 0; +} + +static void configure_ipc(bool automatic_ipc_discriminator) { + if(ipc_discriminator == NULL && automatic_ipc_discriminator) { + int pid = getpid(); + ipc_discriminator = calloc(10, sizeof(char)); + snprintf(ipc_discriminator, 10, "%d", pid); + } + + size_t socket_path_len = strlen(SOCKET_PATH); + size_t ipc_discriminator_len = 0; + if (ipc_discriminator != NULL) { + ipc_discriminator_len = strlen(ipc_discriminator); + } + size_t sockfilebase_len = strlen(sockfilebase); + size_t eventsockfilebase_len = strlen(eventsockfilebase); + + sockfile = calloc(socket_path_len + sockfilebase_len + ipc_discriminator_len + 1, sizeof(char)); + eventsockfile = calloc(socket_path_len + eventsockfilebase_len + ipc_discriminator_len + 1, sizeof(char)); + + model_list ipc_list = {0}; + size_t count = find_other_zets(&ipc_list, SOCKET_PATH, sockfilebase); + if(count > 0 && ipc_discriminator != NULL) { + ZITI_LOG(INFO, "multiple ziti-edge-tunnels are running. %zu found. applying ipc discriminator", count); + char *f; + model_list_iter it = model_list_iterator(&ipc_list); + int idx = 0; + while (it) { + f = model_list_it_element(it); + it = model_list_it_remove(it); + ZITI_LOG(INFO, "zet [%d] IPC found at: %s%c%s", idx++, SOCKET_PATH, PATH_SEP, f); + } + + sprintf(sockfile, "%s%s.%s", SOCKET_PATH, sockfilebase, ipc_discriminator); + sprintf(eventsockfile, "%s%s.%s", SOCKET_PATH, eventsockfilebase, ipc_discriminator); + } else { + ZITI_LOG(INFO, "using default paths for IPC. resetting ipc_discriminator from %s to NULL", ipc_discriminator); + ipc_discriminator = NULL; // reset back to NULL + sprintf(sockfile, "%s%s", SOCKET_PATH, sockfilebase); + sprintf(eventsockfile, "%s%s", SOCKET_PATH, eventsockfilebase); + } + ZITI_LOG(INFO, "ipc command path: %s", sockfile); + ZITI_LOG(INFO, "ipc events path: %s", eventsockfile); +} + static void run(int argc, char *argv[]) { uv_cond_init(&stop_cond); uv_mutex_init(&stop_mutex); - initialize_instance_config(); - //set log level in precedence: command line flag (-v/--verbose) -> env var (ZITI_LOG) -> config file int log_level = get_log_level(configured_log_level); log_writer log_fn = NULL; @@ -2012,15 +2130,70 @@ static void run(int argc, char *argv[]) { // initialize log function here. level will be set further down log_init(global_loop_ref); log_fn = ziti_log_writer; - remove_all_nrpt_rules(); - signal(SIGINT, interrupt_handler); #endif ziti_log_init(global_loop_ref, log_level, log_fn); + configure_ipc(true); + + initialize_instance_config(config_dir); + + model_list ipc_list = {0}; + size_t other_zets = find_other_zets(&ipc_list, SOCKET_PATH, sockfilebase); + // generate tunnel status instance and save active state and start time if (config_dir != NULL) { + // xx disable config save here + if (other_zets > 0) { + model_list_iter it = model_list_iterator(&ipc_list); + int idx = 0; + char *f; + while (it) { + f = model_list_it_element(it); + it = model_list_it_remove(it); + ZITI_LOG(INFO, "zet [%d] IPC found at: %s%c%s", idx++, SOCKET_PATH, PATH_SEP, f); + char *ipc = calloc(100, sizeof(char)); + sprintf(ipc, "%s%c%s", SOCKET_PATH, PATH_SEP, f); + cmd.command = TunnelCommand_Status; + char *json = tunnel_command_to_json(&cmd, MODEL_JSON_COMPACT, NULL); + + struct json_object *result = send_message_to_tunnel(json, ipc); + struct json_object *ts_obj; + if (!json_object_object_get_ex(result, "Data", &ts_obj)) { + ZITI_LOG(WARN, "unable to extract response from %s", ipc); + goto end_while; + } + + const char *data = json_object_to_json_string_ext(ts_obj, JSON_C_TO_STRING_PRETTY); + size_t dlen = strlen(data); + + tunnel_status s = {0}; + int r = parse_tunnel_status(&s, data, dlen); + if (r < 0) { + ZITI_LOG(WARN, "unable to parse tunnel_status response from %s", ipc); + goto end_while; + } + + if (same_dir(s.ConfigDir, config_dir)) { + ZITI_LOG(ERROR, "another running ziti-edge-tunnel is configured to use the same config dir."); + ZITI_LOG(ERROR, "running ziti-eddge-tunnel has TunName: %s", s.TunName); + ZITI_LOG(ERROR, "running ziti-eddge-tunnel has ipc=%s", ipc); + ZITI_LOG(ERROR, "exiting"); + ZITI_LOG(ERROR, "==========================================================================="); + exit(-1); + } + + end_while: + free_tunnel_status(&s); + free(ipc); + free_tunnel_command(&cmd); + free(json); + if (result) { + json_object_put(result); + } + } + } set_identifier_path(config_dir); load_tunnel_status_from_file(global_loop_ref); } @@ -2070,6 +2243,11 @@ static void run(int argc, char *argv[]) { set_service_version(); #if _WIN32 + if (other_zets == 0) { + remove_all_nrpt_rules(DEFAULT_EXECUTABLE_NAME, false); //remove all rules starting with ziti-edge-tunnel + } else { + ZITI_LOG(INFO, "not removing existing rules on startup [%zu] other %s instances running", other_zets, DEFAULT_EXECUTABLE_NAME); + } uv_timeval64_t dump_time; uv_gettimeofday(&dump_time); char time_str[32]; @@ -2084,7 +2262,6 @@ static void run(int argc, char *argv[]) { ZITI_LOG(INFO," - initialized at : %s (local time), %s (UTC)", time_val, time_str); ZITI_LOG(INFO," - log file location: %s", get_log_file_name()); ZITI_LOG(INFO,"============================================================================"); - move_config_from_previous_windows_backup(global_loop_ref); ZITI_LOG(DEBUG, "granting se_debug privilege to current process to allow access to privileged processes during posture checks"); //ensure this process has the necessary access token to get the full path of privileged processes @@ -2125,12 +2302,15 @@ static int version_opts(int argc, char *argv[]) { int c, option_index, errors = 0; optind = 0; - while ((c = getopt_long(argc, argv, "v", + while ((c = getopt_long(argc, argv, "v:P:", version_options, &option_index)) != -1) { switch (c) { case 'v': verbose_version = 1; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2176,12 +2356,13 @@ static int parse_enroll_opts(int argc, char *argv[]) { { "cert", required_argument, NULL, 'c'}, { "name", required_argument, NULL, 'n'}, { "proxy", required_argument, NULL, 'x' }, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; const char *proxy_arg = NULL; optind = 0; - while ((c = getopt_long(argc, argv, "j:i:Kk:c:n:x:", + while ((c = getopt_long(argc, argv, "j:i:Kk:c:n:x:P:", opts, &option_index)) != -1) { switch (c) { case 'j': @@ -2221,6 +2402,9 @@ static int parse_enroll_opts(int argc, char *argv[]) { case 'x': proxy_arg = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2342,14 +2526,11 @@ static void enroll(int argc, char *argv[]) { } } -static tunnel_command cmd = { - .show_result = true, // consistent with old behaviour -}; - static int dump_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, {"dump_path", required_argument, NULL, 'p'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2357,7 +2538,7 @@ static int dump_opts(int argc, char *argv[]) { tunnel_ziti_dump *dump_options = calloc(1, sizeof(tunnel_ziti_dump)); cmd.command = TunnelCommand_ZitiDump; - while ((c = getopt_long(argc, argv, "i:p:", + while ((c = getopt_long(argc, argv, "i:p:d:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2366,6 +2547,9 @@ static int dump_opts(int argc, char *argv[]) { case 'p': dump_options->dump_path = realpath(optarg, NULL); break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2389,6 +2573,7 @@ static int dump_opts(int argc, char *argv[]) { static int ip_dump_opts(int argc, char *argv[]) { static struct option opts[] = { {"dump_path", required_argument, NULL, 'p'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2421,16 +2606,16 @@ static int ip_dump_opts(int argc, char *argv[]) { return optind; } -static int send_message_to_tunnel(char* message, bool show_result) { +static struct json_object* send_message_to_tunnel(char* message, char* ipc) { #if _WIN32 - HANDLE cmd_soc = CreateFileA(sockfile, + HANDLE cmd_soc = CreateFileA(ipc, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (cmd_soc == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); - fprintf(stderr, "failed to connect to pipe: %lu", err); + fprintf(stderr, "failed to connect to pipe: %lu - pipe %s", err, ipc); exit(1); } #else @@ -2441,7 +2626,7 @@ static int send_message_to_tunnel(char* message, bool show_result) { .sun_len = sizeof(addr), #endif }; - strncpy(addr.sun_path, sockfile, sizeof(addr.sun_path)); + strncpy(addr.sun_path, ipc, sizeof(addr.sun_path)); if (connect(cmd_soc, (const struct sockaddr *) &addr, sizeof(addr))) { perror("cmd socket connect"); @@ -2468,12 +2653,16 @@ static int send_message_to_tunnel(char* message, bool show_result) { count += c; } + DWORD c; + if (!WriteFile(cmd_soc, LAST_CHAR_IPC_CMD, 1, &c, NULL)) { + fprintf(stderr, "failed to write to pipe: %lu", GetLastError()); + exit(1); + } struct json_tokener *parser = json_tokener_new(); char buf[8*1024]; struct json_object *json = NULL; while(json == NULL) { #if _WIN32 - DWORD c; if (!ReadFile(cmd_soc, buf, sizeof(buf), &c, NULL)) { fprintf(stderr, "failed to read from pipe: %lu", GetLastError()); exit(1); @@ -2496,42 +2685,54 @@ static int send_message_to_tunnel(char* message, bool show_result) { } } - if (show_result) { - printf("%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - } - int code = json_object_get_boolean(json_object_object_get(json, "Success")) ? - 0 : json_object_get_int(json_object_object_get(json, "Code")); - json_object_put(json); json_tokener_free(parser); - return code; + return json; } static void send_message_to_tunnel_fn(int argc, char *argv[]) { + int log_level = get_log_level(configured_log_level); + log_writer log_fn = ziti_log_writer; + log_init(uv_default_loop()); + + configure_ipc(false); char* json = tunnel_command_to_json(&cmd, MODEL_JSON_COMPACT, NULL); - int result = send_message_to_tunnel(json, cmd.show_result); + struct json_object *jsonobj = send_message_to_tunnel(json, sockfile); + + printf("%s\n", json_object_to_json_string_ext(jsonobj, JSON_C_TO_STRING_PRETTY)); + int code = json_object_get_boolean(json_object_object_get(jsonobj, "Success")) ? + 0 : json_object_get_int(json_object_object_get(jsonobj, "Code")); free_tunnel_command(&cmd); free(json); - exit(result); + if(jsonobj) { + json_object_put(jsonobj); + exit(0); + } else { + exit(-1); + } } // reusable parsing of a single required `-i` option static char* get_identity_opt(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; char *id = NULL; - while ((c = getopt_long(argc, argv, "i:", + while ((c = getopt_long(argc, argv, "i:P:", opts, &option_index)) != -1) { switch (c) { case 'i': id = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { - fprintf(stderr, "Unknown option '%c'\n", c); - errors++; + // not an error -- fprintf(stderr, "Unknown option '%c'\n", c); + //errors++; break; } } @@ -2547,9 +2748,34 @@ static char* get_identity_opt(int argc, char *argv[]) { static int ext_auth_opts(int argc, char *argv[]) { tunnel_identity_id id = { - .identifier = (char*)get_identity_opt(argc, argv), + }; + optind = 0; + static struct option opts[] = { + {"identity", required_argument, NULL, 'i'}, + { "verbose", required_argument, NULL, 'v'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, + }; + int c, option_index, errors = 0; + while ((c = getopt_long(argc, argv, "i:p:v:P:", opts, &option_index)) != -1) { + switch (c) { + case 'i': + id.identifier = optarg; + break; + case 'v': + configured_log_level = optarg; + break; + case 'P': + ipc_discriminator = optarg; + break; + default: { + fprintf(stderr, "Unknown option '%c'\n", c); + errors++; + break; + } + } + } cmd.command = TunnelCommands.ExternalAuth; cmd.data = tunnel_identity_id_to_json(&id, MODEL_JSON_COMPACT, NULL); return optind; @@ -2558,7 +2784,8 @@ static int ext_auth_opts(int argc, char *argv[]) { static int on_off_identity_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, - {"onoff", required_argument, NULL, 'o'} + {"onoff", required_argument, NULL, 'o'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2566,7 +2793,7 @@ static int on_off_identity_opts(int argc, char *argv[]) { tunnel_on_off_identity on_off_identity_options = {0}; cmd.command = TunnelCommand_IdentityOnOff; - while ((c = getopt_long(argc, argv, "i:o:", + while ((c = getopt_long(argc, argv, "i:o:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2580,6 +2807,9 @@ static int on_off_identity_opts(int argc, char *argv[]) { } break; } + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2628,6 +2858,7 @@ static int verify_mfa_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, {"authcode", required_argument, NULL, 'c'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2635,7 +2866,7 @@ static int verify_mfa_opts(int argc, char *argv[]) { tunnel_verify_mfa *verify_mfa_options = calloc(1, sizeof(tunnel_verify_mfa)); cmd.command = TunnelCommand_VerifyMFA; - while ((c = getopt_long(argc, argv, "i:c:", + while ((c = getopt_long(argc, argv, "i:c:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2644,6 +2875,9 @@ static int verify_mfa_opts(int argc, char *argv[]) { case 'c': verify_mfa_options->code = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2665,6 +2899,7 @@ static int remove_mfa_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, {"authcode", required_argument, NULL, 'c'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2672,7 +2907,7 @@ static int remove_mfa_opts(int argc, char *argv[]) { tunnel_remove_mfa *remove_mfa_options = calloc(1, sizeof(tunnel_remove_mfa)); cmd.command = TunnelCommand_RemoveMFA; - while ((c = getopt_long(argc, argv, "i:c:", + while ((c = getopt_long(argc, argv, "i:c:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2681,6 +2916,9 @@ static int remove_mfa_opts(int argc, char *argv[]) { case 'c': remove_mfa_options->code = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2702,6 +2940,7 @@ static int submit_mfa_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, {"authcode", required_argument, NULL, 'c'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2709,7 +2948,7 @@ static int submit_mfa_opts(int argc, char *argv[]) { tunnel_submit_mfa *submit_mfa_options = calloc(1, sizeof(tunnel_submit_mfa)); cmd.command = TunnelCommand_SubmitMFA; - while ((c = getopt_long(argc, argv, "i:c:", + while ((c = getopt_long(argc, argv, "i:c:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2718,6 +2957,9 @@ static int submit_mfa_opts(int argc, char *argv[]) { case 'c': submit_mfa_options->code = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2739,6 +2981,7 @@ static int generate_mfa_codes_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, {"authcode", required_argument, NULL, 'c'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2746,7 +2989,7 @@ static int generate_mfa_codes_opts(int argc, char *argv[]) { tunnel_generate_mfa_codes *mfa_codes_options = calloc(1, sizeof(tunnel_generate_mfa_codes)); cmd.command = TunnelCommand_GenerateMFACodes; - while ((c = getopt_long(argc, argv, "i:c:", + while ((c = getopt_long(argc, argv, "i:c:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2755,6 +2998,9 @@ static int generate_mfa_codes_opts(int argc, char *argv[]) { case 'c': mfa_codes_options->code = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2776,6 +3022,7 @@ static int get_mfa_codes_opts(int argc, char *argv[]) { static struct option opts[] = { {"identity", required_argument, NULL, 'i'}, {"authcode", required_argument, NULL, 'c'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2783,7 +3030,7 @@ static int get_mfa_codes_opts(int argc, char *argv[]) { tunnel_get_mfa_codes *get_mfa_codes_options = calloc(1, sizeof(tunnel_get_mfa_codes)); cmd.command = TunnelCommand_GetMFACodes; - while ((c = getopt_long(argc, argv, "i:c:", + while ((c = getopt_long(argc, argv, "i:c:P:", opts, &option_index)) != -1) { switch (c) { case 'i': @@ -2792,6 +3039,9 @@ static int get_mfa_codes_opts(int argc, char *argv[]) { case 'c': get_mfa_codes_options->code = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2812,17 +3062,21 @@ static int get_mfa_codes_opts(int argc, char *argv[]) { static int set_log_level_opts(int argc, char *argv[]) { static struct option opts[] = { {"loglevel", required_argument, NULL, 'l'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; tunnel_set_log_level log_level_options = {0}; - while ((c = getopt_long(argc, argv, "l:", + while ((c = getopt_long(argc, argv, "l:P:", opts, &option_index)) != -1) { switch (c) { case 'l': log_level_options.loglevel = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2851,6 +3105,7 @@ static int update_tun_ip_opts(int argc, char *argv[]) { {"tunip", required_argument, NULL, 't'}, {"prefixlength", required_argument, NULL, 'p'}, {"addDNS", required_argument, NULL, 'd'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2895,6 +3150,7 @@ static int endpoint_status_change_opts(int argc, char *argv[]) { static struct option opts[] = { {"wake", optional_argument, NULL, 'w'}, {"unlock", optional_argument, NULL, 'u'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -2902,7 +3158,7 @@ static int endpoint_status_change_opts(int argc, char *argv[]) { tunnel_status_change *tunnel_status_change_opts = calloc(1, sizeof(tunnel_status_change)); cmd.command = TunnelCommand_StatusChange; - while ((c = getopt_long(argc, argv, "w:u:", + while ((c = getopt_long(argc, argv, "w:u:P:", opts, &option_index)) != -1) { switch (c) { case 'w': @@ -2919,6 +3175,9 @@ static int endpoint_status_change_opts(int argc, char *argv[]) { tunnel_status_change_opts->unlocked = false; } break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -2967,13 +3226,16 @@ static int svc_opts(int argc, char *argv[]) { int c, option_index, errors = 0; optind = 0; - while ((c = getopt_long(argc, argv, "o:", + while ((c = getopt_long(argc, argv, "o:P:", svc_opts, &option_index)) != -1) { switch (c) { case 'o': { tunnel_service_control_options->operation = optarg; break; } + case 'P': + ipc_discriminator = optarg; + break; default: { ZITI_LOG(ERROR, "Unknown option '%c'", c); errors++; @@ -2992,10 +3254,31 @@ static int svc_opts(int argc, char *argv[]) { #endif static int get_status_opts(int argc, char *argv[]) { + static struct option opts[] = { + { "ipc-discriminator", required_argument, NULL, 'P' }, + { "verbose", required_argument, NULL, 'v'}, + }; + int c, option_index, errors = 0; optind = 0; cmd.command = TunnelCommand_Status; + while ((c = getopt_long(argc, argv, "P:v:", + opts, &option_index)) != -1) { + switch (c) { + case 'P': + ipc_discriminator = optarg; + break; + case 'v': + configured_log_level = optarg; + break; + default: { + ZITI_LOG(ERROR, "Unknown option '%c'", c); + errors++; + break; + } + } + } return optind; } @@ -3017,6 +3300,7 @@ static int add_identity_opts(int argc, char *argv[]) { {"use-keychain", no_argument, NULL, 'K' }, {"identity", required_argument, NULL, 'i'}, {"jwt", required_argument, NULL, 'j'}, + { "ipc-discriminator", required_argument, NULL, 'P' }, }; int c, option_index, errors = 0; optind = 0; @@ -3024,7 +3308,7 @@ static int add_identity_opts(int argc, char *argv[]) { tunnel_add_identity *tunnel_add_identity_opt = calloc(1, sizeof(tunnel_add_identity)); cmd.command = TunnelCommand_AddIdentity; - while ((c = getopt_long(argc, argv, "Ki:j:", + while ((c = getopt_long(argc, argv, "Ki:j:P:", opts, &option_index)) != -1) { switch (c) { case 'K': @@ -3036,6 +3320,9 @@ static int add_identity_opts(int argc, char *argv[]) { case 'j': tunnel_add_identity_opt->jwtContent = optarg; break; + case 'P': + ipc_discriminator = optarg; + break; default: { fprintf(stderr, "Unknown option '%c'\n", c); errors++; @@ -3053,84 +3340,119 @@ static int add_identity_opts(int argc, char *argv[]) { return optind; } + static CommandLine enroll_cmd = make_command("enroll", "enroll Ziti identity", - "-j|--jwt -i|--identity [-k|--key [-c|--cert ]] [-n|--name ]", + "-j|--jwt -i|--identity [-k|--key [-c|--cert ]] [-n|--name ]\n", "\t-j|--jwt\tenrollment token file\n" "\t-x|--proxy type://[username[:password]@]hostname_or_ip:port\tproxy to use when connecting to OpenZiti controller. 'http' is currently the only supported type.\n" "\t-i|--identity\toutput identity file\n" "\t-K|--use-keychain\tuse keychain to generate/store private key\n" "\t-k|--key\tprivate key for enrollment\n" "\t-c|--cert\tcertificate for enrollment\n" - "\t-n|--name\tidentity name\n", + "\t-n|--name\tidentity name\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", parse_enroll_opts, enroll); static CommandLine run_cmd = make_command("run", "run Ziti tunnel (required superuser access)", "-i [-r N] [-v N] [-d|--dns-ip-range N.N.N.N/n]", "\t-i|--identity \trun with provided identity file (required)\n" "\t-I|--identity-dir \tload identities from provided directory\n" "\t-x|--proxy type://[username[:password]@]hostname_or_ip:port\tproxy to use when" - " connecting to OpenZiti controller and edge routers. 'http' is currently the only supported type." + " connecting to OpenZiti controller and edge routers. 'http' is currently the only supported type.\n" "\t-v|--verbose N\tset log level, higher level -- more verbose (default 3)\n" "\t-r|--refresh N\tset service polling interval in seconds (default 10)\n" "\t-d|--dns-ip-range \tspecify CIDR block in which service DNS names" - " are assigned in N.N.N.N/n format (default " DEFAULT_DNS_CIDR ")\n", + " are assigned in N.N.N.N/n format (default " DEFAULT_DNS_CIDR ")\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", run_opts, run); static CommandLine run_host_cmd = make_command("run-host", "run Ziti tunnel to host services", "-i [-r N] [-v N]", "\t-i|--identity \trun with provided identity file (required)\n" "\t-I|--identity-dir \tload identities from provided directory\n" "\t-x|--proxy type://[username[:password]@]hostname_or_ip:port\tproxy to use when" - " connecting to OpenZiti controller and edge routers" + " connecting to OpenZiti controller and edge routers\n" "\t-v|--verbose N\tset log level, higher level -- more verbose (default 3)\n" - "\t-r|--refresh N\tset service polling interval in seconds (default 10)\n", + "\t-r|--refresh N\tset service polling interval in seconds (default 10)\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", run_host_opts, run); static CommandLine dump_cmd = make_command("dump", "dump the identities information", "[-i ] [-p ]", "\t-i|--identity\tdump identity info\n" - "\t-p|--dump_path\tdump into path\n", dump_opts, send_message_to_tunnel_fn); + "\t-p|--dump_path\tdump into path\n" + "\t-d|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + dump_opts, send_message_to_tunnel_fn); static CommandLine ip_dump_cmd = make_command("ip_dump", "dump ip stack information", "[-p ]", - "\t-p|--dump_path\tdump into path\n", ip_dump_opts, send_message_to_tunnel_fn); + "\t-p|--dump_path\tdump into path\n" + "\t-d|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + ip_dump_opts, send_message_to_tunnel_fn); static CommandLine on_off_id_cmd = make_command("on_off_identity", "enable/disable the identities information", "-i -o t|f", "\t-i|--identity\tidentity info that needs to be enabled/disabled\n" - "\t-o|--onoff\t't' or 'f' to enable or disable the identity\n", on_off_identity_opts, send_message_to_tunnel_fn); + "\t-o|--onoff\t't' or 'f' to enable or disable the identity\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + on_off_identity_opts, send_message_to_tunnel_fn); static CommandLine enable_id_cmd = make_command("enable", "enable the identities information", "[-i ]", - "\t-i|--identity\tidentity info that needs to be enabled\n", enable_identity_opts, send_message_to_tunnel_fn); + "\t-i|--identity\tidentity info that needs to be enabled\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + enable_identity_opts, send_message_to_tunnel_fn); static CommandLine enable_mfa_cmd = make_command("enable_mfa", "Enable MFA function fetches the totp url from the controller", "[-i ]", - "\t-i|--identity\tidentity info for enabling mfa\n", enable_mfa_opts, send_message_to_tunnel_fn); + "\t-i|--identity\tidentity info for enabling mfa\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + enable_mfa_opts, send_message_to_tunnel_fn); static CommandLine verify_mfa_cmd = make_command("verify_mfa", "Verify the mfa login using the auth code while enabling mfa", "[-i ] [-c ]", "\t-i|--identity\tidentity info to verify mfa login\n" - "\t-c|--authcode\tauth code to verify mfa login\n", verify_mfa_opts, send_message_to_tunnel_fn); + "\t-c|--authcode\tauth code to verify mfa login\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + verify_mfa_opts, send_message_to_tunnel_fn); static CommandLine remove_mfa_cmd = make_command("remove_mfa", "Removes MFA registration from the controller", "[-i ] [-c ]", "\t-i|--identity\tidentity info for removing mfa\n" - "\t-c|--authcode\tauth code to verify mfa login\n", remove_mfa_opts, send_message_to_tunnel_fn); + "\t-c|--authcode\tauth code to verify mfa login\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + remove_mfa_opts, send_message_to_tunnel_fn); static CommandLine submit_mfa_cmd = make_command("submit_mfa", "Submit MFA code to authenticate to the controller", "[-i ] [-c ]", "\t-i|--identity\tidentity info for submitting mfa\n" - "\t-c|--authcode\tauth code to authenticate mfa login\n", submit_mfa_opts, send_message_to_tunnel_fn); + "\t-c|--authcode\tauth code to authenticate mfa login\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + submit_mfa_opts, send_message_to_tunnel_fn); static CommandLine generate_mfa_codes_cmd = make_command("generate_mfa_codes", "Generate MFA codes", "[-i ] [-c ]", "\t-i|--identity\tidentity info for generating mfa codes\n" - "\t-c|--authcode\tauth code to authenticate the request for generating mfa codes\n", generate_mfa_codes_opts, send_message_to_tunnel_fn); + "\t-c|--authcode\tauth code to authenticate the request for generating mfa codes\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + generate_mfa_codes_opts, send_message_to_tunnel_fn); static CommandLine get_mfa_codes_cmd = make_command("get_mfa_codes", "Get MFA codes", "[-i ] [-c ]", "\t-i|--identity\tidentity info for fetching mfa codes\n" "\t-c|--authcode\tauth code to authenticate the request for fetching mfa codes\n", get_mfa_codes_opts, send_message_to_tunnel_fn); -static CommandLine get_status_cmd = make_command("tunnel_status", "Get Tunnel Status", "", "", get_status_opts, send_message_to_tunnel_fn); +static CommandLine get_status_cmd = make_command("tunnel_status", "Get Tunnel Status", "", "" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + get_status_opts, send_message_to_tunnel_fn); static CommandLine delete_id_cmd = make_command("delete", "delete the identities information", "[-i ]", - "\t-i|--identity\tidentity info that needs to be deleted\n", delete_identity_opts, send_message_to_tunnel_fn); + "\t-i|--identity\tidentity info that needs to be deleted\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + delete_identity_opts, send_message_to_tunnel_fn); static CommandLine add_id_cmd = make_command("add", "enroll and load the identity", "-j -i ", "\t-K|--use-keychain\tuse keychain to generate/store private key\n" "\t-j|--jwt\tenrollment token content\n" - "\t-i|--identity\toutput identity .json file (relative to \"-I\" config directory)\n", - add_identity_opts, send_message_to_tunnel_fn); + "\t-i|--identity\toutput identity .json file (relative to \"-I\" config directory)\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + add_identity_opts, send_message_to_tunnel_fn); static CommandLine set_log_level_cmd = make_command("set_log_level", "Set log level of the tunneler", "-l ", - "\t-l|--loglevel\tlog level of the tunneler\n", set_log_level_opts, send_message_to_tunnel_fn); + "\t-l|--loglevel\tlog level of the tunneler\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + set_log_level_opts, send_message_to_tunnel_fn); static CommandLine update_tun_ip_cmd = make_command("update_tun_ip", "Update tun ip of the tunneler", "[-t ] [-p ] [-d ]", "\t-t|--tunip\ttun ipv4 of the tunneler\n" "\t-p|--prefixlength\ttun ipv4 prefix length of the tunneler\n" - "\t-d|--addDNS\tAdd Dns to the tunneler\n", update_tun_ip_opts, send_message_to_tunnel_fn); + "\t-d|--addDNS\tAdd Dns to the tunneler\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + update_tun_ip_opts, send_message_to_tunnel_fn); static CommandLine ep_status_change_cmd = make_command("endpoint_sts_change", "send endpoint status change message to the tunneler", "[-w ] [-u ]", "\t-w|--wake\twake the tunneler\n" - "\t-u|--unlock\tunlock the tunneler\n", endpoint_status_change_opts, send_message_to_tunnel_fn); + "\t-u|--unlock\tunlock the tunneler\n" + "\t-P|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", + endpoint_status_change_opts, send_message_to_tunnel_fn); static CommandLine ext_auth_login = make_command( "ext-jwt-login", "login with ext JWT signer", "-i ", - "\t-i|--identity\tidentity to authenticate\n", + "\t-i|--identity\tidentity to authenticate\n" + "\t-v|--verbose N\tset log level, higher level -- more verbose (default 3)\n" + "\t-p|--ipc-discriminator\ta discriminator to apply to the IPC sockets\n", ext_auth_opts, send_message_to_tunnel_fn); #if _WIN32 @@ -3228,7 +3550,7 @@ void scm_service_run(const char *name) { void stop_tunnel_and_cleanup() { ZITI_LOG(INFO, "Control request to stop tunnel service received..."); - ZITI_LOG(INFO,"notifying any clients of impending shutdown"); + ZITI_LOG(INFO, "notifying any clients of impending shutdown"); send_tunnel_status("shutdown"); // ziti dump to log file / stdout @@ -3236,8 +3558,16 @@ void stop_tunnel_and_cleanup() { tnl_cmd->command = TunnelCommand_ZitiDump; send_tunnel_command_inline(tnl_cmd, NULL); - ZITI_LOG(INFO,"removing nrpt rules"); - remove_all_nrpt_rules(); + model_list ipc_list = {0}; + size_t other_zets = find_other_zets(&ipc_list, SOCKET_PATH, sockfilebase); + char* zet_id = get_zet_instance_id(ipc_discriminator); + if(other_zets > 1) { + ZITI_LOG(INFO, "removing nrpt rules"); + remove_all_nrpt_rules(zet_id, true); + } else { + remove_all_nrpt_rules(DEFAULT_EXECUTABLE_NAME, false); // no other tunnelers, clean all rules + } + free(zet_id); ZITI_LOG(INFO,"cleaning instance config "); cleanup_instance_config(); @@ -3265,60 +3595,6 @@ void scm_service_stop() { uv_cond_wait(&stop_cond, &stop_mutex); uv_mutex_unlock(&stop_mutex); } - -static void move_config_from_previous_windows_backup(uv_loop_t *loop) { - char *backup_folders[] = { - "Windows.~BT\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry", - "Windows.old\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry", - NULL - }; - - char* system_drive = getenv("SystemDrive"); - - for (int i =0; backup_folders[i]; i++) { - char* config_dir_bkp = calloc(FILENAME_MAX, sizeof(char)); - sprintf(config_dir_bkp, "%s\\%s", system_drive, backup_folders[i]); - uv_fs_t fs; - int rc = uv_fs_access(loop, &fs, config_dir_bkp, 0, NULL); - if (rc < 0) { - uv_fs_req_cleanup(&fs); - continue; - } - rc = uv_fs_scandir(loop, &fs, config_dir_bkp, 0, NULL); - if (rc < 0) { - ZITI_LOG(ERROR, "failed to scan dir[%s]: %d/%s", config_dir_bkp, rc, uv_strerror(rc)); - uv_fs_req_cleanup(&fs); - continue; - } else if (rc == 0) { - uv_fs_req_cleanup(&fs); - continue; - } - ZITI_LOG(TRACE, "scan dir %s, file count: %d", config_dir_bkp, rc); - - uv_dirent_t file; - while (uv_fs_scandir_next(&fs, &file) == 0) { - if (file.type == UV_DIRENT_FILE) { - char old_file[FILENAME_MAX]; - snprintf(old_file, FILENAME_MAX, "%s\\%s", config_dir_bkp, file.name); - char new_file[FILENAME_MAX]; - snprintf(new_file, FILENAME_MAX, "%s\\%s", config_dir, file.name); - uv_fs_t fs_cpy; - rc = uv_fs_copyfile(loop, &fs_cpy, old_file, new_file, 0, NULL); - if (rc == 0) { - ZITI_LOG(INFO, "Restored old identity from the backup path - %s to new path - %s", old_file , new_file); - ZITI_LOG(INFO, "Removing old identity from the backup path - %s", old_file); - remove(old_file); - } else { - ZITI_LOG(ERROR, "failed to copy backup identity file[%s]: %d/%s", old_file, rc, uv_strerror(rc)); - } - uv_fs_req_cleanup(&fs_cpy); - } - } - free(config_dir_bkp); - config_dir_bkp = NULL; - uv_fs_req_cleanup(&fs); - } -} #endif static bool is_host_only() { From 4ea6f2baace18d0cacd972479b0ad80a57b08816 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:26:14 -0400 Subject: [PATCH 2/8] refinements from review --- programs/ziti-edge-tunnel/CMakeLists.txt | 1 - programs/ziti-edge-tunnel/instance-config.c | 2 +- programs/ziti-edge-tunnel/instance.c | 4 ++-- programs/ziti-edge-tunnel/windows-scripts.c | 17 ++++++++++++----- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/programs/ziti-edge-tunnel/CMakeLists.txt b/programs/ziti-edge-tunnel/CMakeLists.txt index 31f97d78..2ddb228a 100644 --- a/programs/ziti-edge-tunnel/CMakeLists.txt +++ b/programs/ziti-edge-tunnel/CMakeLists.txt @@ -25,7 +25,6 @@ set(ZITI_INSTANCE_COMMON instance.c include/instance.h config-utils.c - include/config-utils.h instance-config.c include/instance-config.h ) diff --git a/programs/ziti-edge-tunnel/instance-config.c b/programs/ziti-edge-tunnel/instance-config.c index 85d88305..9f7a0091 100644 --- a/programs/ziti-edge-tunnel/instance-config.c +++ b/programs/ziti-edge-tunnel/instance-config.c @@ -158,7 +158,7 @@ bool save_tunnel_status_to_file() { } saved = true; fclose(config); - ZITI_LOG(INFO, "Saved current tunnel status into Config file %s", config_file_name); + ZITI_LOG(DEBUG, "Saved current tunnel status into Config file %s", config_file_name); } uv_sem_post(&sem); diff --git a/programs/ziti-edge-tunnel/instance.c b/programs/ziti-edge-tunnel/instance.c index b3689c1c..f9b488a9 100644 --- a/programs/ziti-edge-tunnel/instance.c +++ b/programs/ziti-edge-tunnel/instance.c @@ -559,7 +559,7 @@ void normalize_identifier(char *str) { if (*str == find) { *str = replace; } - *str = (char)tolower((unsigned char)*str); // Convert to lowercase + *str = (char)tolower((unsigned char)*str); // Convert to lowercase when on windows } #else // nothing to normalize at this time @@ -584,7 +584,7 @@ void set_identifier_from_identities() { if (tnl_id->Identifier != NULL) { // set this field to false during initialization normalize_identifier((char*)tnl_id->Identifier); - // verify the identity file is still there before adding to the map + // verify the identity file is still there before adding to the map. This handles the case when the fle is removed manually struct stat buffer; if (stat(tnl_id->Identifier, &buffer) == 0) { diff --git a/programs/ziti-edge-tunnel/windows-scripts.c b/programs/ziti-edge-tunnel/windows-scripts.c index ce7ceb93..21e1b0f6 100644 --- a/programs/ziti-edge-tunnel/windows-scripts.c +++ b/programs/ziti-edge-tunnel/windows-scripts.c @@ -303,13 +303,20 @@ void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* d } char* get_nrpt_comment(char* zet_id, bool exact) { - size_t tot_chars = 40 + strlen(zet_id); - char* nrpt_filter = calloc(tot_chars+1, sizeof(char)); - if(exact) { - snprintf(nrpt_filter, tot_chars, "$_.Comment -eq 'Added by %s'", zet_id); + char *nrpt_filter; + char *name; + char *format; + if (exact) { + name = zet_id; + format = "$_.Comment -eq 'Added by %s'"; } else { - snprintf(nrpt_filter, tot_chars, "$_.Comment.StartsWith('Added by %s')", zet_id); + // remove any rules starting with the common prefix + name = DEFAULT_EXECUTABLE_NAME; + format = "$_.Comment.StartsWith('Added by %s')"; } + size_t tot_chars = strlen(format) + strlen(name); + nrpt_filter = calloc(tot_chars + 1, sizeof(char)); + snprintf(nrpt_filter, tot_chars, format, name); return nrpt_filter; } From f2d5361d1021552e644a826ca8a7b7169a80423c Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:22:28 -0400 Subject: [PATCH 3/8] move the define to the proper file and fix typo --- lib/ziti-tunnel/include/ziti/ziti_tunnel.h | 2 ++ programs/ziti-edge-tunnel/instance.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/ziti-tunnel/include/ziti/ziti_tunnel.h b/lib/ziti-tunnel/include/ziti/ziti_tunnel.h index e5a6c29c..f3dd7f99 100644 --- a/lib/ziti-tunnel/include/ziti/ziti_tunnel.h +++ b/lib/ziti-tunnel/include/ziti/ziti_tunnel.h @@ -43,6 +43,8 @@ extern "C" { #define MAXPATHLEN PATH_MAX #endif +#define DEFAULT_EXECUTABLE_NAME "ziti-edge-tunnel" + /** keys used in app_data model map */ extern const char *DST_PROTO_KEY; // "dst_protocol" extern const char *DST_IP_KEY; // "dst_ip" diff --git a/programs/ziti-edge-tunnel/instance.c b/programs/ziti-edge-tunnel/instance.c index f9b488a9..e6734f95 100644 --- a/programs/ziti-edge-tunnel/instance.c +++ b/programs/ziti-edge-tunnel/instance.c @@ -584,7 +584,7 @@ void set_identifier_from_identities() { if (tnl_id->Identifier != NULL) { // set this field to false during initialization normalize_identifier((char*)tnl_id->Identifier); - // verify the identity file is still there before adding to the map. This handles the case when the fle is removed manually + // verify the identity file is still there before adding to the map. This handles the case when the file is removed manually struct stat buffer; if (stat(tnl_id->Identifier, &buffer) == 0) { From 7d018439414d74a21d1440d1c799cdb51778ea41 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:31:53 -0400 Subject: [PATCH 4/8] more rearranging --- programs/ziti-edge-tunnel/ziti-edge-tunnel.c | 26 ++++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c index b03e0971..247104be 100644 --- a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c +++ b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c @@ -31,17 +31,24 @@ #if __APPLE__ && __MACH__ #include "netif_driver/darwin/utun.h" +#define LAST_CHAR_IPC_CMD "\0" #elif __linux__ #include "netif_driver/linux/tun.h" +#define LAST_CHAR_IPC_CMD "\0" #elif _WIN32 #include #include #include "netif_driver/windows/tun.h" #include "windows/windows-service.h" #include "windows/windows-scripts.h" - +#define LAST_CHAR_IPC_CMD "\n" +#define realpath(rel, abs) _fullpath(abs, rel, MAX_PATH) #define setenv(n,v,o) do {if(o || getenv(n) == NULL) _putenv_s(n,v); } while(0) - +//functions for logging on windows +bool log_init(uv_loop_t *); +void ziti_log_writer(int , const char *, const char *, size_t); +char* get_log_file_name(); +#include #endif #ifndef MAXIPCCOMMANDLEN @@ -54,6 +61,7 @@ #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 254 +#endif #ifndef S_IRUSR #define S_IRUSR _S_IREAD @@ -62,20 +70,6 @@ #define S_IWUSR _S_IWRITE #endif -#if _WIN32 -#define LAST_CHAR_IPC_CMD "\n" -#define realpath(rel, abs) _fullpath(abs, rel, MAX_PATH) -#else -#define LAST_CHAR_IPC_CMD "\0" -#endif - -//functions for logging on windows -bool log_init(uv_loop_t *); -void ziti_log_writer(int , const char *, const char *, size_t); -char* get_log_file_name(); -#include -#endif - static int dns_miss_status = DNS_REFUSE; typedef char * (*to_json_fn)(const void * msg, int flags, size_t *len); From f9d83c8376144b8856645b86f4e52b273bd541bf Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:25:17 -0400 Subject: [PATCH 5/8] getting things to compile on all operating systems --- .../include/windows/windows-scripts.h | 2 +- .../ziti-edge-tunnel/netif_driver/darwin/utun.c | 4 ++++ .../ziti-edge-tunnel/netif_driver/darwin/utun.h | 1 + .../ziti-edge-tunnel/netif_driver/linux/tun.c | 4 ++++ .../ziti-edge-tunnel/netif_driver/linux/tun.h | 1 + programs/ziti-edge-tunnel/windows-scripts.c | 2 +- programs/ziti-edge-tunnel/ziti-edge-tunnel.c | 17 ++++++++++------- 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/programs/ziti-edge-tunnel/include/windows/windows-scripts.h b/programs/ziti-edge-tunnel/include/windows/windows-scripts.h index 00256e8c..0e629cfe 100644 --- a/programs/ziti-edge-tunnel/include/windows/windows-scripts.h +++ b/programs/ziti-edge-tunnel/include/windows/windows-scripts.h @@ -35,7 +35,7 @@ void remove_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* d void remove_and_add_nrpt_rules(uv_loop_t *nrpt_loop, model_map *hostnames, const char* dns_ip, const char* discriminator); void remove_all_nrpt_rules(char* zet_id, bool exact); -void update_interface_metric(uv_loop_t *ziti_loop, wchar_t* tun_name, int metric); +void update_interface_metric(uv_loop_t *ziti_loop, const wchar_t* tun_name, int metric); void update_symlink(uv_loop_t *symlink_loop, char* symlink, char* filename); #endif //ZITI_TUNNEL_SDK_C_WINDOWS_SCRIPTS_H diff --git a/programs/ziti-edge-tunnel/netif_driver/darwin/utun.c b/programs/ziti-edge-tunnel/netif_driver/darwin/utun.c index 5b9ecff7..2ebc5f48 100644 --- a/programs/ziti-edge-tunnel/netif_driver/darwin/utun.c +++ b/programs/ziti-edge-tunnel/netif_driver/darwin/utun.c @@ -283,4 +283,8 @@ netif_driver utun_open(char *error, size_t error_len, const char *cidr) { } } return driver; +} + +const char* get_tun_name(netif_handle tun) { + return tun->name; } \ No newline at end of file diff --git a/programs/ziti-edge-tunnel/netif_driver/darwin/utun.h b/programs/ziti-edge-tunnel/netif_driver/darwin/utun.h index 31ead368..bb3569d6 100644 --- a/programs/ziti-edge-tunnel/netif_driver/darwin/utun.h +++ b/programs/ziti-edge-tunnel/netif_driver/darwin/utun.h @@ -27,4 +27,5 @@ struct netif_handle_s { extern netif_driver utun_open(char *error, size_t error_len, const char *cidr); +extern const char* get_tun_name(netif_handle tun); #endif //ZITI_TUNNELER_SDK_UTUN_H diff --git a/programs/ziti-edge-tunnel/netif_driver/linux/tun.c b/programs/ziti-edge-tunnel/netif_driver/linux/tun.c index 78ce061e..228f5465 100644 --- a/programs/ziti-edge-tunnel/netif_driver/linux/tun.c +++ b/programs/ziti-edge-tunnel/netif_driver/linux/tun.c @@ -492,3 +492,7 @@ netif_driver tun_open(uv_loop_t *loop, uint32_t tun_ip, uint32_t dns_ip, const c return driver; } + +const char* get_tun_name(netif_handle tun) { + return tun->name; +} \ No newline at end of file diff --git a/programs/ziti-edge-tunnel/netif_driver/linux/tun.h b/programs/ziti-edge-tunnel/netif_driver/linux/tun.h index 73c83cd8..fb9b0f43 100644 --- a/programs/ziti-edge-tunnel/netif_driver/linux/tun.h +++ b/programs/ziti-edge-tunnel/netif_driver/linux/tun.h @@ -30,4 +30,5 @@ struct netif_handle_s { extern netif_driver tun_open(struct uv_loop_s *loop, uint32_t tun_ip, uint32_t dns_ip, const char *cidr, char *error, size_t error_len); +extern const char* get_tun_name(netif_handle tun); #endif //ZITI_TUNNELER_SDK_TUN_H diff --git a/programs/ziti-edge-tunnel/windows-scripts.c b/programs/ziti-edge-tunnel/windows-scripts.c index 21e1b0f6..04cf030e 100644 --- a/programs/ziti-edge-tunnel/windows-scripts.c +++ b/programs/ziti-edge-tunnel/windows-scripts.c @@ -500,7 +500,7 @@ bool is_nrpt_policies_effective(const char* tns_ip, char* zet_id) { } } -void update_interface_metric(uv_loop_t *ziti_loop, wchar_t* tun_name, int metric) { +void update_interface_metric(uv_loop_t *ziti_loop, const wchar_t* tun_name, int metric) { char script[MAX_POWERSHELL_SCRIPT_LEN] = { 0 }; size_t buf_len = sprintf(script, "$i=Get-NetIPInterface | Where -FilterScript {$_.InterfaceAlias -Eq \"%ls\"}; ", tun_name); size_t copied = buf_len; diff --git a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c index 247104be..3d1e7aa9 100644 --- a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c +++ b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c @@ -1573,15 +1573,15 @@ static int run_tunnel(uv_loop_t *ziti_loop, uint32_t tun_ip, uint32_t dns_ip, co ZITI_LOG(ERROR, "failed to open network interface: %s", tun_error); return 1; } + +#if _WIN32 const wchar_t* tun_name = get_tun_name(tun->handle); size_t tun_name_len = wcslen(tun_name); char* name = calloc(tun_name_len, sizeof(char) + 1); wcstombs(name, tun_name, tun_name_len + 1); - set_tun_name(name); + set_tun_name(name); //sets the tunnel status, tun name... free(name); -#if _WIN32 - char* zet_id = get_zet_instance_id(ipc_discriminator); bool nrpt_effective = is_nrpt_policies_effective(get_dns_ip(), zet_id); free(zet_id); @@ -1599,6 +1599,9 @@ static int run_tunnel(uv_loop_t *ziti_loop, uint32_t tun_ip, uint32_t dns_ip, co ZITI_LOG(INFO, "Setting interface metric to 255"); update_interface_metric(ziti_loop, tun_name, 255); } +#else + const char* name = get_tun_name(tun->handle); + set_tun_name(name); //sets the tunnel status, tun name... #endif tunneler = initialize_tunneler(tun, ziti_loop); @@ -2647,11 +2650,15 @@ static struct json_object* send_message_to_tunnel(char* message, char* ipc) { count += c; } +#if _WIN32 DWORD c; if (!WriteFile(cmd_soc, LAST_CHAR_IPC_CMD, 1, &c, NULL)) { fprintf(stderr, "failed to write to pipe: %lu", GetLastError()); exit(1); } +#else + //empty on purpose +#endif struct json_tokener *parser = json_tokener_new(); char buf[8*1024]; struct json_object *json = NULL; @@ -2685,10 +2692,6 @@ static struct json_object* send_message_to_tunnel(char* message, char* ipc) { } static void send_message_to_tunnel_fn(int argc, char *argv[]) { - int log_level = get_log_level(configured_log_level); - log_writer log_fn = ziti_log_writer; - log_init(uv_default_loop()); - configure_ipc(false); char* json = tunnel_command_to_json(&cmd, MODEL_JSON_COMPACT, NULL); struct json_object *jsonobj = send_message_to_tunnel(json, sockfile); From d253fea5e43a5c5a15ed40fa8ba242e18ef32a12 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:05:55 -0400 Subject: [PATCH 6/8] add limits.h --- programs/ziti-edge-tunnel/ziti-edge-tunnel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c index 3d1e7aa9..39d94203 100644 --- a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c +++ b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c @@ -28,6 +28,7 @@ #include "instance.h" #include "instance-config.h" #include +#include #if __APPLE__ && __MACH__ #include "netif_driver/darwin/utun.h" From befd2b06ae25978d9a095ed2bd1ea393656d5995 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:28:42 -0400 Subject: [PATCH 7/8] use FILENAME_MAX --- programs/ziti-edge-tunnel/ziti-edge-tunnel.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c index 39d94203..25692995 100644 --- a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c +++ b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c @@ -28,7 +28,6 @@ #include "instance.h" #include "instance-config.h" #include -#include #if __APPLE__ && __MACH__ #include "netif_driver/darwin/utun.h" @@ -2057,8 +2056,8 @@ size_t find_other_zets(model_list* ipcs, const char* ipc_base, const char* ipc_p } static bool same_dir(const char* path1, const char* path2) { - char resolved_path1[PATH_MAX]; - char resolved_path2[PATH_MAX]; + char resolved_path1[FILENAME_MAX]; + char resolved_path2[FILENAME_MAX]; if (realpath(path1, resolved_path1) == NULL) { ZITI_LOG(ERROR, "error resolving path1"); @@ -2339,9 +2338,6 @@ static ziti_enroll_opts enroll_opts; static char* config_file; #if _WIN32 -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif #define realpath(rel, abs) _fullpath(abs, rel, PATH_MAX) #endif From aca03dbfd9f01cb165bf01cc2f9e1f15adb8be89 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:59:29 -0400 Subject: [PATCH 8/8] missed a spot --- programs/ziti-edge-tunnel/ziti-edge-tunnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c index 25692995..6596eaa7 100644 --- a/programs/ziti-edge-tunnel/ziti-edge-tunnel.c +++ b/programs/ziti-edge-tunnel/ziti-edge-tunnel.c @@ -2338,7 +2338,7 @@ static ziti_enroll_opts enroll_opts; static char* config_file; #if _WIN32 -#define realpath(rel, abs) _fullpath(abs, rel, PATH_MAX) +#define realpath(rel, abs) _fullpath(abs, rel, FILENAME_MAX) #endif static int parse_enroll_opts(int argc, char *argv[]) {