From 806f912d8bf1af148623bd0d2e14dbdeaa059a6f Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 20 Mar 2020 18:01:29 +0100 Subject: sstp: T2008: adjust config syntax to common style --- src/conf_mode/vpn_sstp.py | 707 ++++++++++++++++++++++++---------------------- 1 file changed, 365 insertions(+), 342 deletions(-) diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index 05bf65fde..362eeddbb 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -14,14 +14,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import os -import re -import subprocess import jinja2 -import socket -import time -import syslog as sl + +from time import sleep +from sys import exit +from subprocess import Popen, PIPE, check_output +from socket import socket, AF_INET, SOCK_STREAM +from copy import deepcopy +from stat import S_IRUSR, S_IWUSR, S_IRGRP +from psutil import pid_exists from vyos.config import Config from vyos import ConfigError @@ -35,28 +37,25 @@ ssl_cert_dir = r'/config/user-data/sstp' # config path creation if not os.path.exists(sstp_cnf_dir): os.makedirs(sstp_cnf_dir) - sl.syslog(sl.LOG_NOTICE, sstp_cnf_dir + " created") if not os.path.exists(ssl_cert_dir): os.makedirs(ssl_cert_dir) - sl.syslog(sl.LOG_NOTICE, ssl_cert_dir + " created") -sstp_config = ''' -### generated by vpn_sstp.py ### +sstp_config = """### generated by vpn_sstp.py ### [modules] log_syslog sstp ippool shaper -{% if authentication['mode'] == 'local' %} +{% if auth_mode == 'local' %} chap-secrets +{% elif auth_mode == 'radius' %} +radius {% endif -%} -{% for proto in authentication['auth_proto'] %} + +{% for proto in auth_proto %} {{proto}} {% endfor %} -{% if authentication['mode'] == 'radius' %} -radius -{% endif %} [core] thread-count={{thread_cnt}} @@ -75,17 +74,15 @@ disable [sstp] verbose=1 accept=ssl -{% if certs %} -ssl-ca-file=/config/user-data/sstp/{{certs['ca']}} -ssl-pemfile=/config/user-data/sstp/{{certs['server-cert']}} -ssl-keyfile=/config/user-data/sstp/{{certs['server-key']}} -{% endif %} +ssl-ca-file=/config/user-data/sstp/{{ ssl_ca }} +ssl-pemfile=/config/user-data/sstp/{{ ssl_cert }} +ssl-keyfile=/config/user-data/sstp/{{ ssl_key }} -{%if ip_pool %} +{% if client_ip_pool %} [ip-pool] -gw-ip-address={{gw}} -{% for sn in ip_pool %} -{{sn}} +gw-ip-address={{ client_gateway }} +{% for subnet in client_ip_pool %} +{{ subnet }} {% endfor %} {% endif %} @@ -96,38 +93,34 @@ dns{{ loop.index }}={{ dns }} {% endfor -%} {% endif %} -{% if authentication['mode'] == 'local' %} +{% if auth_mode == 'local' %} [chap-secrets] chap-secrets=/etc/accel-ppp/sstp/chap-secrets -{% endif %} - -{%- if authentication['mode'] == 'radius' %} +{% elif auth_mode == 'radius' %} [radius] verbose=1 -{% for rsrv in authentication['radius-srv']: %} -server={{rsrv}},{{authentication['radius-srv'][rsrv]['secret']}},\ -req-limit={{authentication['radius-srv'][rsrv]['req-limit']}},\ -fail-time={{authentication['radius-srv'][rsrv]['fail-time']}} +{% for r in radius_server %} +server={{ r.server }},{{ r.secret }},req-limit={{ r.req_limit }},fail-time={{ r.fail_time }} {% endfor -%} -{% if authentication['radiusopt']['acct-timeout'] %} -acct-timeout={{authentication['radiusopt']['acct-timeout']}} + +{% if radius_acct_tmo %} +acct-timeout={{ radius_acct_tmo }} {% endif -%} -{% if authentication['radiusopt']['timeout'] %} -timeout={{authentication['radiusopt']['timeout']}} +{% if radius_timeout %} +timeout={{ radius_timeout }} {% endif -%} -{% if authentication['radiusopt']['max-try'] %} -max-try={{authentication['radiusopt']['max-try']}} +{% if rad_max_try %} +max-try={{ rad_max_try }} {% endif -%} -{% if authentication['radiusopt']['nas-id'] %} -nas-identifier={{authentication['radiusopt']['nas-id']}} +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} {% endif -%} -{% if authentication['radiusopt']['nas-ip'] %} -nas-ip-address={{authentication['radiusopt']['nas-ip']}} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} {% endif -%} -{% if authentication['radiusopt']['dae-srv'] %} -dae-server={{authentication['radiusopt']['dae-srv']['ip-addr']}}:\ -{{authentication['radiusopt']['dae-srv']['port']}},\ -{{authentication['radiusopt']['dae-srv']['secret']}} + +{% if radius_dae %} +dae-server={{ radius_dae.server }}:{{ radius_dae.port }},{{ radius_dae.secret }} {% endif -%} {% endif %} @@ -135,373 +128,403 @@ dae-server={{authentication['radiusopt']['dae-srv']['ip-addr']}}:\ verbose=1 check-ip=1 {% if mtu %} -mtu={{mtu}} +mtu={{ mtu }} {% endif -%} -{% if ppp['mppe'] %} -mppe={{ppp['mppe']}} + +{% if ppp_mppe %} +mppe={{ ppp_mppe }} {% endif -%} -{% if ppp['lcp-echo-interval'] %} -lcp-echo-interval={{ppp['lcp-echo-interval']}} +{% if ppp_echo_interval %} +lcp-echo-interval={{ ppp_echo_interval }} {% endif -%} -{% if ppp['lcp-echo-failure'] %} -lcp-echo-failure={{ppp['lcp-echo-failure']}} +{% if ppp_echo_failure %} +lcp-echo-failure={{ ppp_echo_failure }} {% endif -%} -{% if ppp['lcp-echo-timeout'] %} -lcp-echo-timeout={{ppp['lcp-echo-timeout']}} +{% if ppp_echo_timeout %} +lcp-echo-timeout={{ ppp_echo_timeout }} {% endif %} -{% if authentication['radiusopt']['shaper'] %} +{% if radius_shaper_attr %} [shaper] verbose=1 -attr={{authentication['radiusopt']['shaper']['attr']}} -{% if authentication['radiusopt']['shaper']['vendor'] %} -vendor={{authentication['radiusopt']['shaper']['vendor']}} +attr={{ radius_shaper_attr }} +{% if radius_shaper_vendor %} +vendor={{ radius_shaper_vendor }} {% endif -%} {% endif %} [cli] tcp=127.0.0.1:2005 -''' + +""" # sstp chap secrets -chap_secrets_conf = ''' +chap_secrets_conf = """ # username server password acceptable local IP addresses shaper -{% for user in authentication['local-users'] %} -{% if authentication['local-users'][user]['state'] == 'enabled' %} -{% if (authentication['local-users'][user]['upload']) and (authentication['local-users'][user]['download']) %} -{{user}}\t*\t{{authentication['local-users'][user]['passwd']}}\t{{authentication['local-users'][user]['ip']}}\t\ -{{authentication['local-users'][user]['download']}}/{{authentication['local-users'][user]['upload']}} +{% for user in local_users %} +{% if user.state == 'enabled' %} +{% if user.upload and user.download %} +{{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} {{ user.download }} / {{ user.upload }} {% else %} -{{user}}\t*\t{{authentication['local-users'][user]['passwd']}}\t{{authentication['local-users'][user]['ip']}} +{{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} {% endif %} {% endif %} {% endfor %} -''' -### -# inline helper functions -### -# depending on hw and threads, daemon needs a little to start -# if it takes longer than 100 * 0.5 secs, exception is being raised -# not sure if that's the best way to check it, but it worked so far quite well -### +""" +def subprocess_cmd(command): + p = Popen(command, stdout=PIPE, shell=True) + p.communicate() def chk_con(): cnt = 0 - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s = socket(AF_INET, SOCK_STREAM) while True: try: s.connect(("127.0.0.1", 2005)) s.close() break except ConnectionRefusedError: - time.sleep(0.5) + sleep(0.5) cnt += 1 if cnt == 100: raise("failed to start sstp server") break -# chap_secrets file if auth mode local - - -def write_chap_secrets(c): - tmpl = jinja2.Template(chap_secrets_conf, trim_blocks=True) - chap_secrets_txt = tmpl.render(c) - old_umask = os.umask(0o077) - open(chap_secrets, 'w').write(chap_secrets_txt) - os.umask(old_umask) - sl.syslog(sl.LOG_NOTICE, chap_secrets + ' written') - - -def accel_cmd(cmd=''): +def accel_cmd(cmd): if not cmd: return None + try: - ret = subprocess.check_output( - ['/usr/bin/accel-cmd', '-p', '2005', cmd]).decode().strip() - return ret + ret = check_output(['/usr/bin/accel-cmd', '-p', '2005', cmd]) + return ret.decode().strip() + except: return 1 -# check ig local-ip is in client pool subnet - - -### -# inline helper functions end -### +default_config_data = { + 'local_users' : [], + 'auth_mode' : 'local', + 'auth_proto' : [], + 'radius_server' : [], + 'radius_acct_tmo' : '', + 'radius_max_try' : '', + 'radius_timeout' : '', + 'radius_nas_id' : '', + 'radius_nas_ip' : '', + 'radius_shaper_attr' : '', + 'radius_shaper_vendor': '', + 'radius_dae' : {}, + 'ssl_ca' : '', + 'ssl_cert' : '', + 'ssl_key' : '', + 'client_ip_pool' : [], + 'dnsv4' : [], + 'mtu' : '', + 'ppp_mppe' : '', + 'ppp_echo_failure' : '', + 'ppp_echo_interval' : '', + 'ppp_echo_timeout' : '', + 'thread_cnt' : '' +} def get_config(): + sstp = deepcopy(default_config_data) base_path = ['vpn', 'sstp'] - c = Config() - if not c.exists(base_path): + conf = Config() + if not conf.exists(base_path): return None - c.set_level(base_path) - - config_data = { - 'authentication': { - 'local-users': { - }, - 'mode': 'local', - 'auth_proto': [], - 'radius-srv': {}, - 'radiusopt': {}, - 'dae-srv': {} - }, - 'certs': { - 'ca': None, - 'server-key': None, - 'server-cert': None - }, - 'ip_pool': [], - 'gw': None, - 'dnsv4': [], - 'mtu': None, - 'ppp': {}, - } + conf.set_level(base_path) + cpu = int(os.cpu_count()/2) + if cpu < 1: + cpu = 1 + sstp['thread_cnt'] = cpu + + if conf.exists(['authentication', 'mode']): + sstp['auth_mode'] = conf.return_value(['authentication', 'mode']) + + # # local auth - if c.exists('authentication mode local'): - if c.exists('authentication local-users'): - for usr in c.list_nodes('authentication local-users username'): - config_data['authentication']['local-users'].update( - { - usr: { - 'passwd': None, - 'state': 'enabled', - 'ip': '*', - 'upload': None, - 'download': None - } - } - ) - if c.exists('authentication local-users username ' + usr + ' password'): - config_data['authentication']['local-users'][usr]['passwd'] = c.return_value( - 'authentication local-users username ' + usr + ' password') - if c.exists('authentication local-users username ' + usr + ' disable'): - config_data['authentication']['local-users'][usr]['state'] = 'disable' - if c.exists('authentication local-users username ' + usr + ' static-ip'): - config_data['authentication']['local-users'][usr]['ip'] = c.return_value( - 'authentication local-users username ' + usr + ' static-ip') - if c.exists('authentication local-users username ' + usr + ' rate-limit download'): - config_data['authentication']['local-users'][usr]['download'] = c.return_value( - 'authentication local-users username ' + usr + ' rate-limit download') - if c.exists('authentication local-users username ' + usr + ' rate-limit upload'): - config_data['authentication']['local-users'][usr]['upload'] = c.return_value( - 'authentication local-users username ' + usr + ' rate-limit upload') - - if c.exists('authentication protocols'): - auth_mods = {'pap': 'pap', 'chap': 'auth_chap_md5', - 'mschap': 'auth_mschap_v1', 'mschap-v2': 'auth_mschap_v2'} - for proto in c.return_values('authentication protocols'): - config_data['authentication']['auth_proto'].append( - auth_mods[proto]) - else: - config_data['authentication']['auth_proto'] = ['auth_mschap_v2'] + if conf.exists(['authentication', 'local-users']): + for username in conf.list_nodes(['authentication', 'local-users', 'username']): + user = { + 'name' : username, + 'password' : '', + 'state' : 'enabled', + 'ip' : '*', + 'upload' : None, + 'download' : None + } + + conf.set_level(base_path + ['authentication', 'local-users', 'username', username]) + + if conf.exists(['password']): + user['password'] = conf.return_value(['password']) + + if conf.exists(['disable']): + user['state'] = 'disable' + + if conf.exists(['static-ip']): + user['ip'] = conf.return_value(['static-ip']) + + if conf.exists(['rate-limit', 'download']): + user['download'] = conf.return_value(['rate-limit', 'download']) + + if conf.exists(['rate-limit', 'upload']): + user['upload'] = conf.return_value(['rate-limit', 'upload']) + + sstp['local_users'].append(user) + # # RADIUS auth and settings - if c.exists('authentication mode radius'): - config_data['authentication']['mode'] = c.return_value( - 'authentication mode') - if c.exists('authentication radius-server'): - for rsrv in c.list_nodes('authentication radius-server'): - config_data['authentication']['radius-srv'][rsrv] = {} - if c.exists('authentication radius-server ' + rsrv + ' secret'): - config_data['authentication']['radius-srv'][rsrv]['secret'] = c.return_value( - 'authentication radius-server ' + rsrv + ' secret') - else: - config_data['authentication']['radius-srv'][rsrv]['secret'] = None - if c.exists('authentication radius-server ' + rsrv + ' fail-time'): - config_data['authentication']['radius-srv'][rsrv]['fail-time'] = c.return_value( - 'authentication radius-server ' + rsrv + ' fail-time') - else: - config_data['authentication']['radius-srv'][rsrv]['fail-time'] = 0 - if c.exists('authentication radius-server ' + rsrv + ' req-limit'): - config_data['authentication']['radius-srv'][rsrv]['req-limit'] = c.return_value( - 'authentication radius-server ' + rsrv + ' req-limit') - else: - config_data['authentication']['radius-srv'][rsrv]['req-limit'] = 0 + conf.set_level(base_path) + if conf.exists(['authentication', 'radius-server']): + for server in conf.list_nodes(['authentication', 'radius-server']): + radius = { + 'server' : server, + 'secret' : '', + 'fail_time' : 0, + 'req_limit' : 0 + } + + conf.set_level(base_path + ['authentication', 'radius-server', server]) + + if conf.exists(['secret']): + radius['secret'] = conf.return_value(['secret']) + + if conf.exists(['fail-time']): + radius['fail-time'] = conf.return_value(['fail-time']) + + if conf.exists(['req-limit']): + radius['req_limit'] = conf.return_value(['req-limit']) + + sstp['radius_server'].append(radius) # advanced radius-setting - if c.exists('authentication radius-settings'): - if c.exists('authentication radius-settings acct-timeout'): - config_data['authentication']['radiusopt']['acct-timeout'] = c.return_value( - 'authentication radius-settings acct-timeout') - if c.exists('authentication radius-settings max-try'): - config_data['authentication']['radiusopt']['max-try'] = c.return_value( - 'authentication radius-settings max-try') - if c.exists('authentication radius-settings timeout'): - config_data['authentication']['radiusopt']['timeout'] = c.return_value( - 'authentication radius-settings timeout') - if c.exists('authentication radius-settings nas-identifier'): - config_data['authentication']['radiusopt']['nas-id'] = c.return_value( - 'authentication radius-settings nas-identifier') - if c.exists('authentication radius-settings nas-ip-address'): - config_data['authentication']['radiusopt']['nas-ip'] = c.return_value( - 'authentication radius-settings nas-ip-address') - if c.exists('authentication radius-settings dae-server'): - config_data['authentication']['radiusopt'].update( - { - 'dae-srv': { - 'ip-addr': c.return_value('authentication radius-settings dae-server ip-address'), - 'port': c.return_value('authentication radius-settings dae-server port'), - 'secret': str(c.return_value('authentication radius-settings dae-server secret')) - } - } - ) - if c.exists('authentication radius-settings rate-limit enable'): - if not c.exists('authentication radius-settings rate-limit attribute'): - config_data['authentication']['radiusopt']['shaper'] = { - 'attr': 'Filter-Id'} - else: - config_data['authentication']['radiusopt']['shaper'] = { - 'attr': c.return_value('authentication radius-settings rate-limit attribute') - } - if c.exists('authentication radius-settings rate-limit vendor'): - config_data['authentication']['radiusopt']['shaper']['vendor'] = c.return_value( - 'authentication radius-settings rate-limit vendor') - - if c.exists('sstp-settings ssl-certs ca'): - config_data['certs']['ca'] = c.return_value( - 'sstp-settings ssl-certs ca') - if c.exists('sstp-settings ssl-certs server-cert'): - config_data['certs']['server-cert'] = c.return_value( - 'sstp-settings ssl-certs server-cert') - if c.exists('sstp-settings ssl-certs server-key'): - config_data['certs']['server-key'] = c.return_value( - 'sstp-settings ssl-certs server-key') - - if c.exists('network-settings client-ip-settings subnet'): - config_data['ip_pool'] = c.return_values( - 'network-settings client-ip-settings subnet') - if c.exists('network-settings client-ip-settings gateway-address'): - config_data['gw'] = c.return_value( - 'network-settings client-ip-settings gateway-address') - if c.exists('network-settings name-server'): - config_data['dnsv4'] = c.return_values('network-settings name-server') - if c.exists('network-settings mtu'): - config_data['mtu'] = c.return_value('network-settings mtu') - - # ppp - if c.exists('ppp-settings mppe'): - config_data['ppp']['mppe'] = c.return_value('ppp-settings mppe') - if c.exists('ppp-settings lcp-echo-failure'): - config_data['ppp']['lcp-echo-failure'] = c.return_value( - 'ppp-settings lcp-echo-failure') - if c.exists('ppp-settings lcp-echo-interval'): - config_data['ppp']['lcp-echo-interval'] = c.return_value( - 'ppp-settings lcp-echo-interval') - if c.exists('ppp-settings lcp-echo-timeout'): - config_data['ppp']['lcp-echo-timeout'] = c.return_value( - 'ppp-settings lcp-echo-timeout') - - return config_data - - -def verify(c): - if c == None: + conf.set_level(base_path + ['authentication', 'radius-settings']) + if conf.exists([]): + if conf.exists(['acct-timeout']): + sstp['radius_acct_tmo'] = conf.return_value(['acct-timeout']) + + if conf.exists(['max-try']): + sstp['radius_max_try'] = conf.return_value(['max-try']) + + if conf.exists(['timeout']): + sstp['radius_timeout'] = conf.return_value(['timeout']) + + if conf.exists(['nas-identifier']): + sstp['radius_nas_id'] = conf.return_value(['nas-identifier']) + + if conf.exists(['nas-ip-address']): + sstp['radius_nas_ip'] = conf.return_value(['nas-ip-address']) + + # Dynamic Authorization Extensions (DOA)/ + # Change Of Authentication (COA) + if conf.exists(['dae-server']): + dae = { + 'port' : '', + 'server' : '', + 'secret' : '' + } + + if conf.exists(['ip-address']): + dae['server'] = conf.return_value(['ip-address']) + + if conf.exists(['port']): + dae['port'] = conf.return_value(['port']) + + if conf.exists(['secret']): + dae['secret'] = conf.return_value(['secret']) + + sstp['radius_dae'] = dae + + if conf.exists(['rate-limit', 'enable']): + sstp['radius_shaper_attr'] = 'Filter-Id' + c_attr = ['rate-limit', 'enable', 'attribute'] + if conf.exists(c_attr): + sstp['radius_shaper_attr'] = conf.return_value(c_attr) + + c_vendor = ['rate-limit', 'enable', 'vendor'] + if conf.exists(c_vendor): + sstp['radius_shaper_vendor'] = conf.return_value(c_vendor) + + # + # authentication protocols + conf.set_level(base_path + ['authentication']) + if conf.exists(['protocols']): + auth_mods = { + 'pap': 'auth_pap', + 'chap': 'auth_chap_md5', + 'mschap': 'auth_mschap_v1', + 'mschap-v2': 'auth_mschap_v2' + } + + for proto in conf.return_values(['protocols']): + sstp['auth_proto'].append(auth_mods[proto]) + + else: + sstp['auth_proto'] = ['auth_mschap_v2'] + + # + # read in SSL certs + conf.set_level(base_path + ['sstp-settings', 'ssl-certs']) + if conf.exists(['ca']): + sstp['ssl_ca'] = conf.return_value(['ca']) + + if conf.exists(['server-cert']): + sstp['ssl_cert'] = conf.return_value(['server-cert']) + + if conf.exists(['server-key']): + sstp['ssl_key'] = conf.return_value(['server-key']) + + + # + # read in client ip pool settings + conf.set_level(base_path + ['network-settings', 'client-ip-settings']) + if conf.exists(['subnet']): + sstp['client_ip_pool'] = conf.return_values(['subnet']) + + if conf.exists(['gateway-address']): + sstp['client_gateway'] = conf.return_value(['gateway-address']) + + # + # read in network settings + conf.set_level(base_path + ['network-settings']) + if conf.exists(['name-server']): + sstp['dnsv4'] = conf.return_values(['name-server']) + + if conf.exists(['mtu']): + sstp['mtu'] = conf.return_value(['mtu']) + + # + # read in PPP stuff + conf.set_level(base_path + ['ppp-settings']) + if conf.exists('mppe'): + sstp['ppp_mppe'] = conf.return_value('ppp-settings mppe') + + if conf.exists(['lcp-echo-failure']): + sstp['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure']) + + if conf.exists(['lcp-echo-interval']): + sstp['ppp_echo_interval'] = conf.return_value(['lcp-echo-interval']) + + if conf.exists(['lcp-echo-timeout']): + sstp['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout']) + + return sstp + + +def verify(sstp): + if sstp is None: return None # vertify auth settings - if c['authentication']['mode'] == 'local': - if not c['authentication']['local-users']: - raise ConfigError( - 'sstp-server authentication local-users required') - - for usr in c['authentication']['local-users']: - if not c['authentication']['local-users'][usr]['passwd']: - raise ConfigError('user ' + usr + ' requires a password') + if sstp['auth_mode'] == 'local': + if not sstp['local_users']: + raise ConfigError('sstp-server authentication local-users required') + + for user in sstp['local_users']: + if not user['password']: + raise ConfigError(f"Password required for user {user['name']}") + # if up/download is set, check that both have a value - if c['authentication']['local-users'][usr]['upload']: - if not c['authentication']['local-users'][usr]['download']: - raise ConfigError( - 'user ' + usr + ' requires download speed value') - if c['authentication']['local-users'][usr]['download']: - if not c['authentication']['local-users'][usr]['upload']: - raise ConfigError( - 'user ' + usr + ' requires upload speed value') - - if len(c['dnsv4']) > 2: + if user['upload'] and not user['download']: + raise ConfigError(f"Download speed value required for user {user['name']}") + + if user['download'] and not user['upload']: + raise ConfigError(f"Upload speed value required for user {user['name']}") + + if not sstp['client_ip_pool']: + raise ConfigError("Client IP subnet required") + + if not sstp['client_gateway']: + raise ConfigError("Client gateway IP address required") + + if len(sstp['dnsv4']) > 2: raise ConfigError("Only 2 DNS name-servers can be configured") - if not c['certs']['ca'] or not c['certs']['server-key'] or not c['certs']['server-cert']: - raise ConfigError( - 'service sstp-server sstp-settings ssl-certs needs the ssl certificates set up') - else: - ssl_path = ssl_cert_dir + '/' - if not os.path.exists(ssl_path + c['certs']['ca']): - raise ConfigError('CA {0} doesn\'t exist'.format( - ssl_path + c['certs']['ca'])) - if not os.path.exists(ssl_path + c['certs']['server-cert']): - raise ConfigError('SSL Cert {0} doesn\'t exist'.format( - ssl_path + c['certs']['server-cert'])) - if not os.path.exists(ssl_path + c['certs']['server-cert']): - raise ConfigError('SSL Key {0} doesn\'t exist'.format( - ssl_path + c['certs']['server-key'])) - - if c['authentication']['mode'] == 'radius': - if len(c['authentication']['radius-srv']) == 0: - raise ConfigError( - 'service sstp-server authentication radius-server needs a value') - for rsrv in c['authentication']['radius-srv']: - if c['authentication']['radius-srv'][rsrv]['secret'] == None: - raise ConfigError( - 'service sstp-server authentication radius-server {0} secret requires a value'.format(rsrv)) - - if c['authentication']['mode'] == 'local': - if not c['ip_pool']: - print ( - "WARNING: service sstp-server network-settings client-ip-settings subnet requires a value") - if not c['gw']: - print ( - "WARNING: service sstp-server network-settings client-ip-settings gateway-address requires a value") - - -def generate(c): - if c == None: + if not sstp['ssl_ca'] or not sstp['ssl_cert'] or not sstp['ssl_key']: + raise ConfigError('One or more SSL certificates missing') + + ssl_path = ssl_cert_dir + '/' + if not os.path.exists(ssl_path + sstp['ssl_ca']): + ca = ssl_path + sstp['ssl_ca'] + raise ConfigError(f'CA cert file {ca} does not exist') + + if not os.path.exists(ssl_path + sstp['ssl_cert']): + cert = ssl_path + sstp['ssl_cert'] + raise ConfigError(f'SSL cert file {cert} does not exist') + + if not os.path.exists(ssl_path + sstp['ssl_key']): + key = ssl_path + sstp['ssl_key'] + raise ConfigError(f'SSL key file {key} does not exist') + + if sstp['auth_mode'] == 'radius': + if len(sstp['radius_server']) == 0: + raise ConfigError('RADIUS authentication requires at least one server') + + for radius in sstp['radius_server']: + if not radius['secret']: + raise ConfigError(f"Missing RADIUS secret for server {{ radius['server'] }}") + +def generate(sstp): + if sstp is None: return None # accel-cmd reload doesn't work so any change results in a restart of the daemon - try: - if os.cpu_count() == 1: - c['thread_cnt'] = 1 - else: - c['thread_cnt'] = int(os.cpu_count()/2) - except KeyError: - if os.cpu_count() == 1: - c['thread_cnt'] = 1 - else: - c['thread_cnt'] = int(os.cpu_count()/2) - tmpl = jinja2.Template(sstp_config, trim_blocks=True) - config_text = tmpl.render(c) - open(sstp_conf, 'w').write(config_text) + config_text = tmpl.render(sstp) + with open(sstp_conf, 'w') as f: + f.write(config_text) + + if sstp['local_users']: + tmpl = jinja2.Template(chap_secrets_conf, trim_blocks=True) + config_text = tmpl.render(sstp) + with open(chap_secrets, 'w') as f: + f.write(config_text) + + os.chmod(chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP ) - if c['authentication']['local-users']: - write_chap_secrets(c) + return sstp - return c +def apply(sstp): + pid = 0 + if os.path.isfile(pidfile): + pid = 0 + with open(pidfile, 'r') as f: + pid = int(f.read()) + if sstp is None: + if pid_exists(pid): + cmd = 'start-stop-daemon --stop --quiet' + cmd += ' --pidfile ' + pidfile + subprocess_cmd(cmd) -def apply(c): - if c == None: if os.path.exists(pidfile): - accel_cmd('shutdown hard') - if os.path.exists(pidfile): - os.remove(pidfile) + os.remove(pidfile) + return None - if not os.path.exists(pidfile): - ret = subprocess.call( - ['/usr/sbin/accel-pppd', '-c', sstp_conf, '-p', pidfile, '-d']) - chk_con() - if ret != 0 and os.path.exists(pidfile): + if not pid_exists(pid): + if os.path.exists(pidfile): os.remove(pidfile) - raise ConfigError('accel-pppd failed to start') + + cmd = 'start-stop-daemon --start --quiet' + cmd += ' --pidfile ' + pidfile + cmd += ' --exec /usr/sbin/accel-pppd' + # now pass arguments to accel-pppd binary + cmd += ' --' + cmd += ' -c ' + sstp_conf + cmd += ' -p ' + pidfile + cmd += ' -d' + subprocess_cmd(cmd) + + chk_con() + else: accel_cmd('restart') - sl.syslog(sl.LOG_NOTICE, "reloading config via daemon restart") - if __name__ == '__main__': try: @@ -511,4 +534,4 @@ if __name__ == '__main__': apply(c) except ConfigError as e: print(e) - sys.exit(1) + exit(1) -- cgit v1.2.3