the problem frequently occurs on the client side: admin need to configure
stunnel for multiple users.
every user has own key, certificate, own permissions on file system (for
log-files, etc)

this patch allow to write flexible config.

some examples:
cert = %USERPROFILE%\.config\my.pem (windows)
cert = ${HOME}/.config/my.pem (other)

output = %APPDATA%\stunnel.log (windows)
output = ${HOME}/stunnel.log (other)

CAfile = %ALLUSERSPROFILE%\ourCAbundle.crt (windows)
CAfile = /etc/ssl/certs/ourCAbundle.crt (other, not using variables)

"secure" :) random port example:
...
[srv1]
accept = 127.0.0.1:%SRV1_PORT% (windows)
accept = 127.0.0.1:${SRV1_PORT} (other)
...
start stunnel (batch-file or shell-script):
set SRV1_PORT=%RANDOM% (windows)

limitations:
1. don't support unicode on windows (localized usernames, files, etc)
2. only ${NAME} syntax supported on *nix (not $NAME).
--- stunnel-5.32/src/options.c.orig	2016-05-03 22:35:03.000000000 +0400
+++ stunnel-5.32/src/options.c	2016-05-23 15:21:14.059958210 +0400
@@ -329,10 +329,59 @@
     return 0;
 }
 
+#ifndef USE_WIN32
+unsigned int ExpandEnvironmentStringsA(const char *lpSrc, char *lpDst, size_t nSize) {
+    const char *from;
+    char *to;
+    const char *begin;
+    const char *end;
+    char *name;
+    const char *value;
+    size_t len;
+
+    from = lpSrc;
+    to = lpDst;
+    while ((begin = strchr(from, '$'))) {
+        len = (size_t)(begin - from);
+        if (*(begin + 1) == '{' && (end = strchr(begin, '}')) ) {
+            if ((size_t)(to - lpDst) + len >= nSize) return 0;
+            strncpy(to, from, len);
+            to += len;
+            len = (size_t)(end - begin - 2);
+            name = strndup(begin + 2, len);
+            value = getenv(name);
+            free(name);
+            if (value) {
+                len = strlen(value);
+                if ((size_t)(to - lpDst) + len >= nSize) return 0;
+                strncpy(to, value, len);
+            } else {
+                len = (size_t)(end - begin + 1);
+                if ((size_t)(to - lpDst) + len >= nSize) return 0;
+                strncpy(to, begin, len);
+            }
+        } else {
+            len++; /* +$ itself */
+            if ((size_t)(to - lpDst) + len >= nSize) return 0;
+            strncpy(to, from, len);
+            end = from + len - 1;
+        }
+        to += len;
+        from = end + 1;
+    }
+    len = strlen(from); /* rest of string */
+    if ((size_t)(to - lpDst) + len >= nSize) return 0;
+    strncpy(to, from, len);
+    to[len] = '\0';
+    return strlen(lpDst);
+}
+#endif
+
 NOEXPORT int options_file(char *path, CONF_TYPE type, SERVICE_OPTIONS **section) {
     DISK_FILE *df;
     char line_text[CONFLINELEN], *errstr;
     char config_line[CONFLINELEN], *config_opt, *config_arg;
+    char env_expanded[CONFLINELEN];
     int i, line_number=0;
 #ifndef USE_WIN32
     int fd;
@@ -429,6 +478,16 @@
             continue;
         }
 
+        if(config_arg) {
+            if(ExpandEnvironmentStringsA(config_arg, env_expanded, sizeof(env_expanded))) {
+                config_arg=env_expanded;
+            } else {
+                s_log(LOG_ERR, "%s:%d: Failed to expand environment variables \"%s\"",
+                    path, line_number, config_arg);
+                return 1;
+            }
+        }
+
         errstr=option_not_found;
         /* try global options first (e.g. for 'debug') */
         if(!new_service_options.next)
_______________________________________________
stunnel-users mailing list
stunnel-users@stunnel.org
https://www.stunnel.org/cgi-bin/mailman/listinfo/stunnel-users

Reply via email to