|
|
- #!/bin/sh /etc/rc.common
- # Copyright (C) 2006-2008 OpenWrt.org
- # Copyright (C) 2019 Jeffery To
-
- START=90
- USE_PROCD=1
-
- PID_FILE="/var/run/stunnel/stunnel.pid"
- CONF_FILE="/var/etc/stunnel.conf"
- BIN="/usr/bin/stunnel"
- CONF_FILE_CREATED=
- HAVE_ALT_CONF_FILE=
- SERVICE_SECTION_FOUND=
-
- validate_globals_section() {
- uci_load_validate stunnel globals "$1" "$2" \
- 'alt_config_file:file' \
- \
- 'compression:or("deflate","zlib")' \
- 'EGD:string' \
- 'engine:string' \
- 'engineCtrl:string' \
- 'engineDefault:list(or("ALL","CIPHERS","DH","DIGESTS","DSA","ECDH","ECDSA","PKEY","PKEY_ASN1","PKEY_CRYPTO","RAND","RSA"))' \
- 'log:or("append","overwrite")' \
- 'output:string' \
- 'RNDbytes:uinteger' \
- 'RNDfile:string' \
- 'RNDoverwrite:bool' \
- 'setgid:or(string,uinteger)' \
- 'setuid:or(string,uinteger)' \
- 'syslog:bool' \
- ;
- }
-
- validate_service_section() {
- uci_load_validate stunnel service "$1" "$2" \
- 'enabled:bool:1' \
- \
- 'setgid:or(string,uinteger)' \
- 'setuid:or(string,uinteger)' \
- ;
- }
-
- validate_service_options() {
- uci_load_validate stunnel "$1" "$2" "$3" \
- 'accept_host:host' \
- 'accept_port:port' \
- 'CAfile:string' \
- 'CApath:string' \
- 'cert:string' \
- 'checkEmail:list(string)' \
- 'checkHost:list(host)' \
- 'checkIP:list(ipaddr)' \
- 'ciphers:list(string)' \
- 'ciphersuites:list(string)' \
- 'client:bool' \
- 'config:list(string)' \
- 'connect:list(string)' \
- 'CRLfile:string' \
- 'CRLpath:string' \
- 'curves:list(string)' \
- 'debug:or(range(0,7),string)' \
- 'delay:bool' \
- 'engineId:string' \
- 'engineNum:and(uinteger,min(1))' \
- 'exec:string' \
- 'execArgs:string' \
- 'failover:or("prio","rr")' \
- 'ident:string' \
- 'include:directory' \
- 'key:string' \
- 'local:host' \
- 'logId:or("process","sequential","thread","unique")' \
- 'OCSP:string' \
- 'OCSPaia:bool' \
- 'OCSPflag:list(or("NOCASIGN","NOCERTS","NOCHAIN","NOCHECKS","NODELEGATED","NOEXPLICIT","NOINTERN","NOSIGS","NOTIME","NOVERIFY","RESPID_KEY","TRUSTOTHER"))' \
- 'OCSPnonce:bool' \
- 'options:list(string) ' \
- 'protocol:or("cifs","connect","imap","nntp","pgsql","pop3","proxy","smtp","socks")' \
- 'protocolAuthentication:or("basic","login","ntlm","plain")' \
- 'protocolDomain:hostname' \
- 'protocolHost_host:host' \
- 'protocolHost_port:port' \
- 'protocolPassword:string' \
- 'protocolUsername:string' \
- 'PSKidentity:string' \
- 'PSKsecrets:string' \
- 'pty:bool' \
- 'redirect_host:host' \
- 'redirect_port:port' \
- 'renegotiation:bool' \
- 'requireCert:bool' \
- 'reset:bool' \
- 'retry:bool' \
- 'service:string' \
- 'sessionCacheSize:uinteger' \
- 'sessionCacheTimeout:uinteger' \
- 'sessiond_host:host' \
- 'sessiond_port:port' \
- 'sni:list(string)' \
- 'socket:list(string)' \
- 'sslVersion:or("all","SSLv2","SSLv3","TLSv1","TLSv1.1","TLSv1.2")' \
- 'stack:uinteger' \
- 'ticketKeySecret:string' \
- 'ticketMacSecret:string' \
- 'TIMEOUTbusy:uinteger' \
- 'TIMEOUTclose:uinteger' \
- 'TIMEOUTconnect:uinteger' \
- 'TIMEOUTidle:uinteger' \
- 'transparent:or("both","destination","none","source")' \
- 'verifyChain:bool' \
- 'verifyPeer:bool' \
- ;
- }
-
- validate_globals_section_service_options() {
- validate_service_options globals "$@"
- }
-
- validate_service_section_service_options() {
- validate_service_options service "$@"
- }
-
- print_options() {
- local _opt
- local _value
- for _opt in "$@"; do
- eval "_value=\$$_opt"
- [ -z "$_value" ] || echo "$_opt = $_value" >> "$CONF_FILE"
- done
- }
-
- print_bool_options() {
- local _opt
- local _bool
- local _value
- for _opt in "$@"; do
- eval "_bool=\$$_opt"
- [ -z "$_bool" ] || {
- _value=no
- [ "$_bool" != 1 ] || _value=yes
- echo "$_opt = $_value" >> "$CONF_FILE"
- }
- done
- }
-
- print_lists_map() {
- local _opt
- local _values
- local _value
- for _opt in "$@"; do
- eval "_values=\$$_opt"
- for _value in $_values; do
- echo "$_opt = $_value" >> "$CONF_FILE"
- done
- done
- }
-
- print_lists_reduce() {
- local _delim="$1"
- local _opt
- local _value
- local _values
- local _v
- shift
- for _opt in "$@"; do
- _value=
- eval "_values=\$$_opt"
- for _v in $_values; do
- _value=$_value$_delim$_v
- done
- _value=${_value#$_delim}
- [ -z "$_value" ] || echo "$_opt = $_value" >> "$CONF_FILE"
- done
- }
-
- print_host_port() {
- local _opt
- local _host
- local _port
- for _opt in "$@"; do
- eval "_host=\${${_opt}_host}"
- eval "_port=\${${_opt}_port}"
- [ -z "$_host" ] || [ -z "$_port" ] || echo "$_opt = $_host:$_port" >> "$CONF_FILE"
- done
- }
-
- print_optional_host_port() {
- local _opt
- local _host
- local _port
- local _value
- for _opt in "$@"; do
- eval "_host=\${${_opt}_host}"
- eval "_port=\${${_opt}_port}"
- [ -z "$_port" ] || {
- _value=$_port
- [ -z "$_host" ] || _value=$_host:$_port
- echo "$_opt = $_value" >> "$CONF_FILE"
- }
- done
- }
-
- print_global_options() {
- print_options \
- compression \
- EGD \
- engine \
- engineCtrl \
- log \
- output \
- RNDbytes \
- RNDfile \
- RNDoverwrite \
- ;
-
- print_bool_options \
- syslog \
- ;
-
- print_lists_reduce , \
- engineDefault \
- ;
- }
-
- print_service_options() {
- [ "$2" = 0 ] || {
- echo "validation failed"
- return 1
- }
-
- print_options \
- CAfile \
- CApath \
- cert \
- CRLfile \
- CRLpath \
- debug \
- logId \
- engineId \
- engineNum \
- exec \
- execArgs \
- failover \
- ident \
- include \
- key \
- local \
- OCSP \
- protocol \
- protocolAuthentication \
- protocolDomain \
- protocolPassword \
- protocolUsername \
- PSKidentity \
- PSKsecrets \
- service \
- sessionCacheSize \
- sessionCacheTimeout \
- setgid \
- setuid \
- sslVersion \
- stack \
- ticketKeySecret \
- ticketMacSecret \
- TIMEOUTbusy \
- TIMEOUTclose \
- TIMEOUTconnect \
- TIMEOUTidle \
- transparent \
- ;
-
- print_bool_options \
- client \
- delay \
- OCSPaia \
- OCSPnonce \
- pty \
- renegotiation \
- requireCert \
- reset \
- retry \
- verifyChain \
- verifyPeer \
- ;
-
- print_lists_map \
- checkEmail \
- checkHost \
- checkIP \
- config \
- connect \
- OCSPflag \
- options \
- sni \
- socket \
- ;
-
- print_lists_reduce : \
- ciphers \
- curves \
- ciphersuites \
- ;
-
- print_host_port \
- protocolHost \
- sessiond \
- ;
-
- print_optional_host_port \
- accept \
- redirect \
- ;
- }
-
- create_conf_file() {
- [ -n "$CONF_FILE_CREATED" ] || {
- mkdir -p "$(dirname "$CONF_FILE")"
- echo "; STunnel configuration file generated by uci" > "$CONF_FILE"
- echo "; Written $(date +'%c')" >> "$CONF_FILE"
- echo >> "$CONF_FILE"
- echo "foreground = quiet" >> "$CONF_FILE"
- echo "pid = $PID_FILE" >> "$CONF_FILE"
- CONF_FILE_CREATED=1
- }
- }
-
- global_defs() {
- local pid_dir
-
- [ "$2" = 0 ] || {
- echo "validation failed"
- return 1
- }
-
- # If the first globals section has alt_config_file, don't process any more globals
- [ -z "$HAVE_ALT_CONF_FILE" ] || return 0
-
- # If "alt_config_file" specified in the first globals section, use that instead
- [ -z "$alt_config_file" ] || [ -n "$CONF_FILE_CREATED" ] || {
- # Symlink "alt_config_file" since it's a bit easier and safer
- ln -s "$alt_config_file" "$CONF_FILE"
- # Set section found to start service, user hopefully knows what they are doing
- SERVICE_SECTION_FOUND=1
- CONF_FILE_CREATED=1
- HAVE_ALT_CONF_FILE=1
- return 0
- }
-
- pid_dir="$(dirname "$PID_FILE")"
- mkdir -p "$pid_dir"
- [ -z "$setuid" ] || chown "$setuid" "$pid_dir"
- [ -z "$setgid" ] || chown ":$setgid" "$pid_dir"
-
- create_conf_file
- print_global_options
- validate_service_options globals "$1" print_service_options
- }
-
- service_section() {
- [ "$2" = 0 ] || {
- echo "validation failed"
- return 1
- }
-
- [ "$enabled" = 1 ] || return 0
-
- SERVICE_SECTION_FOUND=1
- echo >> "$CONF_FILE"
- echo "[$1]" >> "$CONF_FILE"
-
- validate_service_options service "$1" print_service_options
- }
-
- service_triggers() {
- procd_add_reload_trigger stunnel
-
- procd_open_validate
- validate_globals_section "$@"
- validate_globals_section_service_options "$@"
- validate_service_section "$@"
- validate_service_section_service_options "$@"
- procd_close_validate
- }
-
- start_service() {
- rm -f "$CONF_FILE"
- config_load stunnel
-
- config_foreach validate_globals_section globals global_defs
-
- [ -n "$HAVE_ALT_CONF_FILE" ] || {
- create_conf_file
- config_foreach validate_service_section service service_section
- }
-
- [ -n "$SERVICE_SECTION_FOUND" ] || {
- logger -t stunnel -p daemon.info "No uci service section enabled or found!"
- return 1
- }
-
- procd_open_instance
- procd_set_param command "$BIN"
- procd_append_param command "$CONF_FILE"
- procd_set_param respawn
- procd_set_param file "$CONF_FILE"
- procd_close_instance
- }
|