def create_config(self, cfg, resinfo): """Create FreeRADIUS configuration files. Freeradius is always started and thus no start/nostart magic is needed. """ net_cfg = cfg.getS(ns.networkConfig, rdf.Type(ns.NetworkConfig)) ppp_cfg = cfg.getS(ns.pppConfig, rdf.Type(ns.PppConfig)) ppp_auth = ppp_cfg.getS(ns.pppAuthentication, rdf.Type(ns.PppAuthentication)) ppp_comp = ppp_cfg.getS(ns.pppCompression, rdf.Type(ns.PppCompression)) l2tp_cfg = cfg.getS(ns.l2tpConfig, rdf.Type(ns.L2tpConfig)) radius_public_ip = resinfo.public_interface.address.getAddress().toString() nas_ip = radius_public_ip radius_private_ip = None if resinfo.private_interface is not None: radius_private_ip = resinfo.private_interface.address.getAddress().toString() nas_ip = radius_private_ip # NB: this secret does no good for us and may be static client_config = textwrap.dedent("""\ # autogenerated file, do not edit client 127.0.0.1 { secret = notasecret shortname = localhost nastype = other } """ % {'nas_ip':nas_ip}) dictionary_config = textwrap.dedent("""\ # autogenerated file, do not edit $INCLUDE /usr/share/freeradius/dictionary """) # XXX: may need changes in the future retry_delay = 5 retry_count = 3 proxy_config = textwrap.dedent("""\ # autogenerated file, do not edit proxy server { synchronous = no retry_delay = %(retry_delay)d retry_count = %(retry_count)d dead_time = 120 default_fallback = yes post_proxy_authorize = no } realm LOCAL { type = radius authhost = LOCAL accthost = LOCAL } """ % {'retry_delay':retry_delay, 'retry_count':retry_count}) # NB: no way to do failover with DEFAULT or NULL realms, use a # bogus realm instead using_proxy, nas_id, servers = self._get_radius_parameters(cfg) for addr, port, secret in servers: if addr is not None and port is not None and secret is not None: proxy_config += textwrap.dedent("""\ realm default.realm.invalid { type = radius authhost = %(addr)s:%(port)s secret = "%(secret)s" nostrip } """ % {'addr':str(addr), 'port':str(port), 'secret':str(secret)}) # XXX: log_file below *does not work*, it causes a non-fatal startup error # can it be removed? we're using syslog anyway # XXX: may need changing in the future max_reqtime = 30 radiusd_config = textwrap.dedent("""\ # autogenerated file, do not edit prefix = /usr exec_prefix = /usr sysconfdir = /etc localstatedir = /var sbindir = ${exec_prefix}/sbin logdir = syslog raddbdir = %(raddbdir)s radacctdir = ${logdir}/radacct confdir = ${raddbdir} run_dir = %(run_dir)s log_file = ${logdir}/radius.log libdir = /usr/lib/freeradius pidfile = ${run_dir}/freeradius.pid user = freerad group = freerad max_request_time = %(max_reqtime)d delete_blocked_requests = yes cleanup_delay = 5 max_requests = 512 """ % {'raddbdir':constants.FREERADIUS_CONFIG_DIR, 'run_dir':constants.FREERADIUS_RUNPATH, 'max_reqtime':max_reqtime}) # NB: bind only to localhost radiusd_config += textwrap.dedent("""\ listen { ipaddr = 127.0.0.1 port = 1812 type = auth } """) radiusd_config += textwrap.dedent("""\ hostname_lookups = no allow_core_dumps = no regular_expressions = yes extended_expressions = yes log_stripped_names = no log_auth = no log_auth_badpass = no log_auth_goodpass = no usercollide = no lower_user = no lower_pass = no nospace_user = no nospace_pass = no checkrad = ${sbindir}/checkrad security { max_attributes = 200 reject_delay = 1 status_server = no } proxy_requests = yes $INCLUDE ${confdir}/proxy.conf $INCLUDE ${confdir}/clients.conf thread pool { start_servers = 3 max_servers = 16 min_spare_servers = 2 max_spare_servers = 3 max_requests_per_server = 0 } modules { pap { auto_header = yes } chap { authtype = CHAP } pam { pam_auth = radiusd } mschap { } realm suffix { format = suffix delimiter = "@" ignore_default = no ignore_null = no } preprocess { huntgroups = ${confdir}/huntgroups hints = ${confdir}/hints with_ascend_hack = no ascend_channels_per_line = 23 with_ntdomain_hack = no with_specialix_jetstream_hack = no with_cisco_vsa_hack = no } files { usersfile = ${confdir}/users acctusersfile = ${confdir}/acct_users preproxy_usersfile = ${confdir}/preproxy_users compat = no } detail { detailfile = ${radacctdir}/%{Client-IP-Address}/detail-%Y%m%d detailperm = 0600 suppress { User-Password } } acct_unique { key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port" } expr { } digest { } exec { wait = yes input_pairs = request } } instantiate { exec expr } authorize { preprocess chap mschap suffix files pap } authenticate { Auth-Type PAP { pap } Auth-Type CHAP { chap } Auth-Type MS-CHAP { mschap } } session { } post-auth { } pre-proxy { files } post-proxy { } """) preproxy_config = textwrap.dedent("""\ # autogenerated file, do not edit DEFAULT NAS-IP-Address := "%(nas_ip)s", NAS-Port-Type := 5""" % {'nas_ip':nas_ip}) if nas_id is not None: preproxy_config += textwrap.dedent("""\ , NAS-Identifier := "%(nas_id)s" """ % {'nas_id':nas_id}) else: preproxy_config += '\n\n' self.configs = [ {'file': constants.FREERADIUS_ACCT_USERS, 'cont': ''}, # Not used {'file': constants.FREERADIUS_ATTRS, 'cont': ''}, # Not used {'file': constants.FREERADIUS_CLIENTS, 'cont': ''}, # Deprecated {'file': constants.FREERADIUS_CLIENTS_CONF, 'cont': client_config}, {'file': constants.FREERADIUS_DICTIONARY, 'cont': dictionary_config}, {'file': constants.FREERADIUS_EAP_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_EXPERIMENTAL_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_HINTS, 'cont': ''}, # Not used {'file': constants.FREERADIUS_HUNTGROUPS, 'cont': ''}, # Not used {'file': constants.FREERADIUS_LDAP_ATTRMAP, 'cont': ''}, # Not used {'file': constants.FREERADIUS_MSSQL_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_NASLIST, 'cont': ''}, # Deprecated {'file': constants.FREERADIUS_NASPASSWD, 'cont': ''}, # Not used {'file': constants.FREERADIUS_ORACLESQL_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_OTP_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_POSTGRESQL_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_PREPROXY_USERS, 'cont': preproxy_config}, {'file': constants.FREERADIUS_PROXY_CONF, 'cont': proxy_config}, {'file': constants.FREERADIUS_RADIUSD_CONF, 'cont': radiusd_config}, {'file': constants.FREERADIUS_REALMS, 'cont': ''}, # Deprecated {'file': constants.FREERADIUS_SNMP_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_SQL_CONF, 'cont': ''}, # Not used {'file': constants.FREERADIUS_SQLIPPOOL_CONF, 'cont': ''}, # Not used ] self.configs.append(self._create_users_file(cfg, resinfo, using_proxy))
def _do_mgmt_identify_args(self): root = self.rdf_root licinfo = self.rdf_root.getS(ns_ui.licenseInfo, rdf.Type(ns_ui.LicenseInfo)) uiconfig = self.rdf_root.getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) args = {} try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.licenseKey) and ui_root.getS( ns_ui.licenseKey, rdf.String) != '': args['licenseKey'] = ui_root.getS(ns_ui.licenseKey, rdf.String) elif ui_root.hasS(ns_ui.testLicenseKey) and ui_root.getS( ns_ui.testLicenseKey, rdf.String) != '': args['licenseKey'] = ui_root.getS(ns_ui.testLicenseKey, rdf.String) else: raise Exception('no configured license') except: args['licenseKey'] = '' # anonymous try: t = helpers.get_boot_uuid() if t is None: args['bootUuid'] = '' else: args['bootUuid'] = t except: args['bootUuid'] = '' try: t = helpers.get_installation_uuid() if t is None: args['installationUuid'] = '' else: args['installationUuid'] = t except: args['installationUuid'] = '' try: t = helpers.get_cookie_uuid() if t is None: args['cookieUuid'] = '' else: args['cookieUuid'] = t except: args['cookieUuid'] = '' args['address'] = '0.0.0.0' # overridden by managementconnection args['port'] = 0 # overridden by managementconnection try: args['softwareVersion'] = helpers.get_product_version() except: args['softwareVersion'] = '' args['softwareBuildInfo'] = '' # XXX args['hardwareType'] = '' # XXX args['hardwareInfo'] = '' # XXX try: if self.force_update: args['automaticUpdates'] = True else: args['automaticUpdates'] = uiconfig.getS( ns_ui.automaticUpdates, rdf.Boolean) except: args['automaticUpdates'] = True try: args['isLiveCd'] = helpers.is_live_cd() except: args['isLiveCd'] = False return args
def _update_public_private_ifaces(self, now, ifaces, pub_di, priv_di, first_time): def _update_iface(di, st): orxtime = st.getS(ns.rxLastChange, rdf.Datetime) nrxtime = now st.setS(ns.rxLastChange, rdf.Datetime, nrxtime) otxtime = st.getS(ns.txLastChange, rdf.Datetime) ntxtime = now st.setS(ns.txLastChange, rdf.Datetime, ntxtime) orxbytes = st.getS(ns.rxBytesCounter, rdf.Integer) nrxbytes = di.rxbytes nrxbytes = _wrap_check(orxbytes, nrxbytes) # handle 4GiB wrap st.setS(ns.rxBytesCounter, rdf.Integer, nrxbytes) otxbytes = st.getS(ns.txBytesCounter, rdf.Integer) ntxbytes = di.txbytes ntxbytes = _wrap_check(otxbytes, ntxbytes) # handle 4GiB wrap st.setS(ns.txBytesCounter, rdf.Integer, ntxbytes) orxpackets = st.getS(ns.rxPacketsCounter, rdf.Integer) nrxpackets = di.rxpackets st.setS(ns.rxPacketsCounter, rdf.Integer, nrxpackets) otxpackets = st.getS(ns.txPacketsCounter, rdf.Integer) ntxpackets = di.txpackets st.setS(ns.txPacketsCounter, rdf.Integer, ntxpackets) if first_time: st.setS(ns.rxRateCurrent, rdf.Float, 0.0) st.setS(ns.rxRateMaximum, rdf.Float, 0.0) st.setS(ns.txRateCurrent, rdf.Float, 0.0) st.setS(ns.txRateMaximum, rdf.Float, 0.0) else: rx_time = nrxtime - orxtime rx_secs = float(rx_time.seconds) + float( rx_time.microseconds / 1000000.0) if rx_secs > 0.0: rx_rate = float(nrxbytes - orxbytes) / rx_secs else: rx_rate = 0.0 if rx_rate > st.getS(ns.rxRateMaximum, rdf.Float): st.setS(ns.rxRateMaximum, rdf.Float, rx_rate) st.setS(ns.rxRateCurrent, rdf.Float, rx_rate) tx_time = ntxtime - otxtime tx_secs = float(tx_time.seconds) + float( tx_time.microseconds / 1000000.0) if tx_secs > 0.0: tx_rate = float(ntxbytes - otxbytes) / tx_secs else: tx_rate = 0.0 if tx_rate > st.getS(ns.txRateMaximum, rdf.Float): st.setS(ns.txRateMaximum, rdf.Float, tx_rate) st.setS(ns.txRateCurrent, rdf.Float, tx_rate) # NB: link and IP info are updated on every round; this benefits # very little but also costs very little... # update link info st.setS(ns.mtu, rdf.Integer, di.mtu) st.setS(ns.macAddress, rdf.String, di.mac) # update ip level info iface = ifaces.get_interface_by_name(di.devname) addrsub = iface.get_current_ipv4_address_info() if addrsub is None: _log.info('could not get address of interface %s, ignoring' % di.devname) else: st.setS(ns.ipAddress, rdf.IPv4AddressSubnet, addrsub) if pub_di is not None: pub_if_st = helpers.get_status().getS( ns.publicInterface, rdf.Type(ns.NetworkInterface)) _update_iface(pub_di, pub_if_st) if priv_di is not None: priv_if_st = helpers.get_status().getS( ns.privateInterface, rdf.Type(ns.NetworkInterface)) _update_iface(priv_di, priv_if_st)
def start_client_connection(self, identifier, myip, gwip, username, password): l2tp_cfg = helpers.get_db_root().getS(ns.l2tpDeviceConfig, rdf.Type(ns.L2tpDeviceConfig)) ppp_cfg = l2tp_cfg.getS(ns.pppConfig, rdf.Type(ns.PppConfig)) debug = helpers.get_debug(l2tp_cfg) def _run_config(config, failmsg, successmsg): rv, out, err = 1, '', '' lock = helpers.acquire_openl2tpconfig_lock() if lock is None: raise Exception('failed to acquire openl2tp config lock') try: [rv, out, err] = run_command([constants.CMD_OPENL2TPCONFIG], stdin=str(config)) except: pass helpers.release_openl2tpconfig_lock(lock) if rv != 0: self._log.error('%s: %s, %s, %s' % (str(failmsg), str(rv), str(out), str(err))) raise Exception(str(failmsg)) else: self._log.debug('%s: %s, %s, %s' % (str(successmsg), str(rv), str(out), str(err))) return rv, out, err our_port = 1702 # NB: yes, 1702; we differentiate client and site-to-site connections based on local port peer_port = 1701 ppp_profile_name = 'ppp-prof-%s' % identifier tunnel_profile_name = 'tunnel-prof-%s' % identifier session_profile_name = 'session-prof-%s' % identifier peer_profile_name = 'peer-prof-%s' % identifier tunnel_name = 'tunnel-%s' % identifier session_name = 'session-%s' % identifier # we allow openl2tp to select these and "snoop" them from stdout tunnel_id = None session_id = None # ppp profile trace_flags = '0' if debug: trace_flags = '2047' config = 'ppp profile create profile_name=%s\n' % ppp_profile_name # XXX: take MRU and MTU like normal config? # XXX: should we have separate lcp echo etc settings for site-to-site? mtu = ppp_cfg.getS(ns.pppMtu, rdf.Integer) mru = mtu lcp_echo_interval = 0 lcp_echo_failure = 0 if ppp_cfg.hasS(ns.pppLcpEchoInterval): lcp_echo_interval = ppp_cfg.getS(ns.pppLcpEchoInterval, rdf.Timedelta).seconds lcp_echo_failure = ppp_cfg.getS(ns.pppLcpEchoFailure, rdf.Integer) for i in [ ['default_route', 'no'], ['multilink', 'no'], ['use_radius', 'no'], ['idle_timeout', '0'], # no limit ['mtu', str(mtu)], ['mru', str(mru)], ['lcp_echo_interval', str(lcp_echo_interval)], ['lcp_echo_failure_count', str(lcp_echo_failure)], ['max_connect_time', '0'], # no limit ['max_failure_count', '10'], ['trace_flags', trace_flags] ]: config += 'ppp profile modify profile_name=%s %s=%s\n' % (ppp_profile_name, i[0], i[1]) # Note: all auth options must be on one line config += 'ppp profile modify profile_name=%s req_none=yes auth_pap=yes auth_chap=yes auth_mschapv1=no auth_mschapv2=no auth_eap=no req_pap=no req_chap=no req_mschapv1=no req_mschapv2=no req_eap=no\n' % ppp_profile_name # no encryption config += 'ppp profile modify profile_name=%s mppe=no\n' % ppp_profile_name # Note: all compression options must be on one line # Request deflate or bsdcomp compression. config += 'ppp profile modify profile_name=%s comp_mppc=no comp_accomp=yes comp_pcomp=no comp_bsdcomp=no comp_deflate=yes comp_predictor=no comp_vj=no comp_ccomp_vj=no comp_ask_deflate=yes comp_ask_bsdcomp=no\n' % ppp_profile_name # tunnel profile config += 'tunnel profile create profile_name=%s\n' % tunnel_profile_name trace_flags = '0' if debug: trace_flags = '2047' # XXX: 1460 is hardcoded here, like in normal l2tp connections for i in [ ['our_udp_port', str(our_port)], ['peer_udp_port', str(peer_port)], ['mtu', '1460'], ['hello_timeout', '60'], ['retry_timeout', '3'], ['idle_timeout', '0'], ['rx_window_size', '4'], ['tx_window_size', '10'], ['max_retries', '5'], ['framing_caps', 'any'], ['bearer_caps', 'any'], ['trace_flags', trace_flags] ]: config += 'tunnel profile modify profile_name=%s %s=%s\n' % (tunnel_profile_name, i[0], i[1]) # session profile config += 'session profile create profile_name=%s\n' % session_profile_name trace_flags = '0' if debug: trace_flags = '2047' for i in [ ['sequencing_required', 'no'], ['use_sequence_numbers', 'no'], ['trace_flags', trace_flags] ]: config += 'session profile modify profile_name=%s %s=%s\n' % (session_profile_name, i[0], i[1]) # peer profile config += 'peer profile create profile_name=%s\n' % peer_profile_name # XXX: 'lac_lns', 'netmask' # 'peer_port' has no effect for some reason for i in [ ['peer_ipaddr', gwip.toString()], ['peer_port', str(peer_port)], # XXX: dup from above ['ppp_profile_name', ppp_profile_name], ['session_profile_name', session_profile_name], ['tunnel_profile_name', tunnel_profile_name] ]: config += 'peer profile modify profile_name=%s %s=%s\n' % (peer_profile_name, i[0], i[1]) config += '\nquit\n' # create profiles self._log.debug('openl2tp config:\n%s' % config) rv, stdout, stderr = _run_config(config, 'failed to create client-mode profiles', 'create client-mode profiles ok') # create tunnel - this triggers openl2tp # # NOTE: 'interface_name' would make life easier, but is not currently # supported by Openl2tp. # # XXX: 'persist', 'interface_name' config = 'tunnel create tunnel_name=%s' % tunnel_name # NB: all on one line here for i in [ ['src_ipaddr', myip.toString()], ['our_udp_port', str(our_port)], # XXX: dup from above ['peer_udp_port', str(peer_port)], # XXX: dup from above ['dest_ipaddr', gwip.toString()], ['peer_profile_name', peer_profile_name], ['profile_name', tunnel_profile_name], ['session_profile_name', session_profile_name], ['tunnel_name', tunnel_name], ### ['tunnel_id', tunnel_id], # XXX: for some reason can't be used, fetched below! ['use_udp_checksums', 'yes'] ]: # XXX: probably doesn't do anything now config += ' %s=%s' % (i[0], i[1]) config += '\nquit\n' # activate tunnel self._log.debug('openl2tp config for tunnel:\n%s' % config) rv, stdout, stderr = _run_config(config, 'failed to create client-mode tunnel', 'create client-mode tunnel ok') for l in stderr.split('\n'): m = _re_openl2tp_created_tunnel.match(l) if m is not None: if tunnel_id is not None: self._log.warning('second tunnel id (%s), old one was %s; ignoring' % (m.group(1), tunnel_id)) else: tunnel_id = m.group(1) self._log.debug('figured out tunnel id %s' % tunnel_id) if tunnel_id is None: raise Exception('could not figure tunnel id of new site-to-site tunnel (username %s) [rv: %s, out: %s, err: %s]' % (username, rv, stdout, stderr)) config = 'session create session_name=%s' % session_name for i in [ ['tunnel_name', tunnel_name], ['tunnel_id', tunnel_id], ### ['session_id', session_id], # XXX: for some reason can't be used, fetched below! ['profile_name', session_profile_name], ['ppp_profile_name', ppp_profile_name], ['user_name', username], ['user_password', password] ]: config += ' %s=%s' % (i[0], i[1]) config += '\nquit\n' # activate session self._log.debug('openl2tp config for session:\n%s' % config) rv, stdout, stderr = _run_config(config, 'failed to create client-mode session', 'create client-mode session ok') for l in stderr.split('\n'): m = _re_openl2tp_created_session.match(l) if m is not None: if session_id is not None: self._log.warning('second session id (%s), old one was %s; ignoring' % (m.group(2), session_id)) else: tun = m.group(1) if tun != tunnel_id: self._log.warning('tunnel id differs from earlier (earlier %s, found %s), ignoring' % (tunnel_id, tun)) else: session_id = m.group(2) self._log.debug('figured out session id %s' % session_id) if session_id is None: raise Exception('could not figure session id of new site-to-site tunnel (username %s) [rv: %s, out: %s, err: %s]' % (username, rv, stdout, stderr)) self._log.info('created new tunnel and session (%s/%s) for site-to-site client (username %s)' % (tunnel_id, session_id, username))
def create_config(self, cfg, res_info): """Create OpenL2tp configuration file as string.""" # This is for get_args() to later pick up self.ip_address = res_info.public_interface.address.getAddress().toString() (pub_if, pub_if_name), (priv_if, priv_if_name) = helpers.get_ifaces(cfg) net_cfg = cfg.getS(ns.networkConfig, rdf.Type(ns.NetworkConfig)) ppp_cfg = cfg.getS(ns.pppConfig, rdf.Type(ns.PppConfig)) ppp_auth = ppp_cfg.getS(ns.pppAuthentication, rdf.Type(ns.PppAuthentication)) ppp_comp = ppp_cfg.getS(ns.pppCompression, rdf.Type(ns.PppCompression)) l2tp_cfg = cfg.getS(ns.l2tpConfig, rdf.Type(ns.L2tpConfig)) # XXX: (do we need a patch for these?) # - noipx, crtscts, lock: are not used by openl2tp # Note: # - noipdefault, nodetach, local: always passed to pppd by openl2tp # Note: The receive port is not changeable and no point in # setting the local port because of the one-udp-port -patch. # Note: could set the openl2tp local sending port which would # disable the ephemeral port use, but this is not required while # we use the one-socket patch. self.debug_on = helpers.get_debug(cfg) # XXX: it seems like openl2tp has *ppp* profile trace flags # all enabled by default and others (tunnel, session, system) not.. # there could be other debug flags, too, which would affect f.ex # openl2tp and pluto ppp_subnet = ppp_cfg.getS(ns.pppSubnet, rdf.IPv4Subnet) if ppp_subnet.getCidr() > 30: raise Exception('PPP subnet does not contain enough usable addresses') local_ip = ppp_subnet.getLastUsableAddress() # Note: hostname is not settable, but openl2tp derives it from # system hostname. # Note: vendor_name is not settable (and not used for anything more # than testing code) in openl2tp # Note: tunnelrws option does not exist in openl2tp # but could set the tx/rx window sizes # Note: not settable through openl2tp. # this has effect only when connect or pty options are used # in pppd config and thus is not required here. # connect_delay = '5000' # Note: openl2tp always uses lenght bit, so "length bit = yes" # or similar is not required in config. # PPP profile params = {} params['prefix'] = 'ppp profile modify profile_name=default' params['idle_timeout'] = '0' if ppp_cfg.hasS(ns.pppIdleTimeout): # short timeouts (less than 10 seconds, say) are not sane, but we # assume the user interface checks for sanity params['idle_timeout'] = str(ppp_cfg.getS(ns.pppIdleTimeout, rdf.Timedelta).seconds) # truncate self._log.warning('idle timeout specified, not robust with many clients') params['mtu'] = str(ppp_cfg.getS(ns.pppMtu, rdf.Integer)) params['mru'] = params['mtu'] params['local_ipaddr'] = local_ip.toString() # XXX: if no echo failure specified, then the tunnels may never die. # - tunnels have hello_interval but it only controls of the # frequency of the sent HELLO messages # - tunnels have idle timeout, but it has meaning only when all the # sessions for tunnel have died out # - sessions themselves do not die unless pppd terminates because # they have no timeout.. # Note: be careful with PPP options -> delete or empty config files! # - some options in the /etc/ppp/options file have priority over # command-line options # - openl2tp options are always command-line options # - this may lead to strange behaviour if there are old config # files still hanging around.. params['lcp_echo_interval'] = '0' params['lcp_echo_failure'] = '0' if ppp_cfg.hasS(ns.pppLcpEchoInterval): params['lcp_echo_interval'] = str(ppp_cfg.getS(ns.pppLcpEchoInterval, rdf.Timedelta).seconds) params['lcp_echo_failure'] = str(ppp_cfg.getS(ns.pppLcpEchoFailure, rdf.Integer)) params['auth_pap'] = 'no' if ppp_auth.hasS(ns.pppPap) and ppp_auth.getS(ns.pppPap, rdf.Boolean): params['auth_pap'] = 'yes' params['auth_chap'] = 'no' if ppp_auth.hasS(ns.pppChap) and ppp_auth.getS(ns.pppChap, rdf.Boolean): params['auth_chap'] = 'yes' # MSCHAPv1 had problems with pppd RADIUS support params['auth_mschapv1'] = 'no' if ppp_auth.hasS(ns.pppMschap) and ppp_auth.getS(ns.pppMschap, rdf.Boolean): self._log.warn('auth mschapv1 enabled in config but not supported, ignoring') params['auth_mschapv2'] = 'no' if ppp_auth.hasS(ns.pppMschapV2) and ppp_auth.getS(ns.pppMschapV2, rdf.Boolean): params['auth_mschapv2'] = 'yes' params['auth_eap'] = 'no' if ppp_auth.hasS(ns.pppEap) and ppp_auth.getS(ns.pppEap, rdf.Boolean): self._log.warn('eap enabled in config but not supported, ignoring') # compression options params['comp_mppc'] = 'no' if ppp_comp.hasS(ns.pppMppc) and ppp_comp.getS(ns.pppMppc, rdf.Boolean): params['comp_mppc'] = 'yes' params['comp_mppe'] = 'no' if ppp_comp.hasS(ns.pppMppe) and ppp_comp.getS(ns.pppMppe, rdf.Boolean): params['comp_mppe'] = 'yes' params['comp_accomp'] = 'no' if ppp_comp.hasS(ns.pppAccomp) and ppp_comp.getS(ns.pppAccomp, rdf.Boolean): params['comp_accomp'] = 'yes' params['comp_pcomp'] = 'no' if ppp_comp.hasS(ns.pppPcomp) and ppp_comp.getS(ns.pppPcomp, rdf.Boolean): params['comp_pcomp'] = 'yes' params['comp_bsdcomp'] = 'no' if ppp_comp.hasS(ns.pppBsdcomp) and ppp_comp.getS(ns.pppBsdcomp, rdf.Boolean): params['comp_bsdcomp'] = 'yes' params['comp_deflate'] = 'no' if ppp_comp.hasS(ns.pppDeflate) and ppp_comp.getS(ns.pppDeflate, rdf.Boolean): params['comp_deflate'] = 'yes' params['comp_predictor1'] = 'no' if ppp_comp.hasS(ns.pppPredictor1) and ppp_comp.getS(ns.pppPredictor1, rdf.Boolean): params['comp_predictor1'] = 'yes' params['comp_vj'] = 'no' if ppp_comp.hasS(ns.pppVj) and ppp_comp.getS(ns.pppVj, rdf.Boolean): params['comp_vj'] = 'yes' params['comp_ccomp_vj'] = 'no' if ppp_comp.hasS(ns.pppCcompVj) and ppp_comp.getS(ns.pppCcompVj, rdf.Boolean): params['comp_ccomp_vj'] = 'yes' # sanity checks if params['comp_pcomp'] == 'yes': self._log.warning('pcomp enabled - this breaks in mppc: disabling') params['comp_pcomp'] = 'no' if params['comp_mppe'] == 'yes': self._log.warning('mppe enabled - not handled by protocol: disabling') params['comp_mppe'] = 'no' # dns servers params['dns_ipaddr_pri'] = '0' params['dns_ipaddr_sec'] = '0' dns_list = res_info.ppp_dns_servers if len(dns_list) > 0: params['dns_ipaddr_pri'] = dns_list[0].address.toString() if len(dns_list) > 1: params['dns_ipaddr_sec'] = dns_list[1].address.toString() # wins servers params['wins_ipaddr_pri'] = '0' params['wins_ipaddr_sec'] = '0' wins_list = res_info.ppp_wins_servers if len(wins_list) > 0: params['wins_ipaddr_pri'] = wins_list[0].address.toString() if len(wins_list) > 1: params['wins_ipaddr_sec'] = wins_list[1].address.toString() # XXX: check and set sensible values, these are defaults params['max_connect_time'] = '0' params['max_failure_count'] = '10' # NB: This is actually not set, because it causes problems in Openl2tp # (boolean argument doesn't work correctly; it will actually be set!) params['default_route'] = 'no' params['multilink'] = 'no' # NB: always use only radius, also local users are from the local radius server params['use_radius'] = 'yes' # Force radius plugin to use proper config file of radiusclient-ng params['radius_hint'] = constants.RADIUSCLIENT_CONFIG # Note: there seems to be quite real disagreement between # openl2tp configration interface and actual used/set configuration # values in openl2tpd: # - dns1=0 seems to work in configuration client, but actually it # sets the IP address as 0.0.0.0 in pppd config # - the zero IP:s do not seem to have any effect because pppd is # resilient. # - etc.. if self.debug_on: params['trace_flags'] = '2047' # Full trace else: params['trace_flags'] = '0' ppp_conf = textwrap.dedent("""\ %(prefix)s ip_pool_name=clientpool %(prefix)s default_route=%(default_route)s %(prefix)s multilink=%(multilink)s %(prefix)s use_radius=%(use_radius)s %(prefix)s radius_hint=%(radius_hint)s %(prefix)s idle_timeout=%(idle_timeout)s %(prefix)s mtu=%(mtu)s %(prefix)s mru=%(mru)s %(prefix)s local_ipaddr=%(local_ipaddr)s %(prefix)s lcp_echo_interval=%(lcp_echo_interval)s %(prefix)s lcp_echo_failure_count=%(lcp_echo_failure)s # Note: all auth options must be on one line %(prefix)s \ req_none=no \ auth_pap=no \ auth_chap=no \ auth_mschapv1=no \ auth_mschapv2=no \ auth_eap=no \ req_pap=%(auth_pap)s \ req_chap=%(auth_chap)s \ req_mschapv1=%(auth_mschapv1)s \ req_mschapv2=%(auth_mschapv2)s \ req_eap=%(auth_eap)s %(prefix)s \ mppe=%(comp_mppe)s %(prefix)s \ comp_mppc=%(comp_mppc)s \ comp_accomp=%(comp_accomp)s \ comp_pcomp=%(comp_pcomp)s \ comp_bsdcomp=%(comp_bsdcomp)s \ comp_deflate=%(comp_deflate)s \ comp_predictor1=%(comp_predictor1)s \ comp_vj=%(comp_vj)s \ comp_ccomp_vj=%(comp_ccomp_vj)s %(prefix)s dns_ipaddr_pri=%(dns_ipaddr_pri)s %(prefix)s dns_ipaddr_sec=%(dns_ipaddr_sec)s %(prefix)s wins_ipaddr_pri=%(wins_ipaddr_pri)s %(prefix)s wins_ipaddr_sec=%(wins_ipaddr_sec)s %(prefix)s max_connect_time=%(max_connect_time)s %(prefix)s max_failure_count=%(max_failure_count)s %(prefix)s trace_flags=%(trace_flags)s """) % params # Tunnel profile params = {} params['prefix'] = 'tunnel profile modify profile_name=default' # Default responder port params['our_port'] = '1701' # XXX: better values, these are defaults. # NB: this works ok in practice, and no need to change if no problems seen. params['mtu'] = '1460' # This might affect socket behaviour or the pppol2tp kernel module.. # XXX: this is default in openl2tp code # do we need to configure this? params['hello_timeout'] = '60' params['retry_timeout'] = '1' # Note: must set this to some value other than zero to prevent # tunnels from hanging when all connections (sessions) are dead params['idle_timeout'] = '1800' # 30 minutes params['rx_window_size'] = '4' params['tx_window_size']= '10' params['max_retries'] = '5' # XXX: better values, these are defaults # possible: none,digital,analog,any params['framing_caps'] = 'any' params['bearer_caps'] = 'any' if self.debug_on: params['trace_flags'] = '2047' # Full trace else: params['trace_flags'] = '0' tunnel_conf = textwrap.dedent("""\ %(prefix)s our_udp_port=%(our_port)s %(prefix)s mtu=%(mtu)s %(prefix)s hello_timeout=%(hello_timeout)s %(prefix)s retry_timeout=%(retry_timeout)s %(prefix)s idle_timeout=%(idle_timeout)s %(prefix)s rx_window_size=%(rx_window_size)s %(prefix)s tx_window_size=%(tx_window_size)s %(prefix)s max_retries=%(max_retries)s %(prefix)s framing_caps=%(framing_caps)s %(prefix)s bearer_caps=%(bearer_caps)s %(prefix)s trace_flags=%(trace_flags)s """) % params # Session profile params = {} params['prefix'] = 'session profile modify profile_name=default' # XXX: should we use sequence numbers for data? maybe not. # ppp will receive the packets anyway. reordering might matter # for control packets, but that should not happen anyway. params['sequencing_required'] = 'no' params['use_sequence_numbers'] = 'no' if self.debug_on: params['trace_flags'] = '2047' # Full trace else: params['trace_flags'] = '0' session_conf = textwrap.dedent("""\ %(prefix)s sequencing_required=%(sequencing_required)s %(prefix)s use_sequence_numbers=%(use_sequence_numbers)s %(prefix)s trace_flags=%(trace_flags)s """) % params # Peer profile # Note: no trace flags available for peer profile.. duh. params = {} params['prefix'] = 'peer profile modify profile_name=default' peer_conf = textwrap.dedent("""\ """) % params self.configs = [{'file': constants.OPENL2TP_CONF, 'cont': ppp_conf + tunnel_conf + session_conf + peer_conf}]
def save_network_data(self, ctx, form, data): def _save_ip_address(rdf_node, fda): if fda['ip_address_selection'] == 'dhcp': rdf_node.setS(ns_ui.address, rdf.Type(ns_ui.DhcpAddress)) elif fda['ip_address_selection'] == 'static': static_node = rdf_node.setS(ns_ui.address, rdf.Type(ns_ui.StaticAddress)) static_node.setS(ns_ui.ipAddress, rdf.IPv4Address, fda['ip_address']) static_node.setS(ns_ui.subnetMask, rdf.IPv4Address, fda['subnet_mask']) else: raise uidatahelpers.FormDataError( 'ip_address_selection is neither dhcp nor static') def _save_client_traffic(rdf_node, fda): client_nat = False client_proxy = False if fda['client_traffic'] == 'nat': client_nat = True elif fda['client_traffic'] == 'proxyarp': client_proxy = True rdf_node.setS(ns_ui.clientConnectionNat, rdf.Boolean, client_nat) rdf_node.setS(ns_ui.clientConnectionProxyArp, rdf.Boolean, client_proxy) fda = formalutils.FormDataAccessor(form, [], ctx) ui_root = helpers.get_new_ui_config() # Interface count ic_root = ui_root.setS(ns_ui.internetConnection, rdf.Type(ns_ui.NetworkConnection)) if fda['ifcount_group.interface_count'] == 'oneif': ui_root.removeNodes(ns_ui.privateNetworkConnection) pn_root = None elif fda['ifcount_group.interface_count'] == 'twoif': pn_root = ui_root.setS(ns_ui.privateNetworkConnection, rdf.Type(ns_ui.NetworkConnection)) else: raise uidatahelpers.FormDataError( 'interface_count is neither oneif nor twoif.') # Internet connection ic_fda = fda.descend('ic_group') ic_root.setS(ns_ui.interface, rdf.String, ic_fda['if']) _save_ip_address(ic_root, ic_fda) uidatahelpers.save_optional_field_to_rdf(ic_root, ns_ui.defaultGateway, rdf.IPv4Address, ic_fda, 'default_gateway') ic_root.setS(ns_ui.mtu, rdf.Integer, int(ic_fda['mtu'])) uidatahelpers.save_optional_field_to_rdf(ic_root, ns_ui.vpnUplink, rdf.Float, ic_fda, 'uplink') _save_client_traffic(ic_root, ic_fda) # Private network connection, fill if exists. if not (pn_root is None): pn_fda = fda.descend('pn_group') pn_root.setS(ns_ui.interface, rdf.String, pn_fda['if']) _save_ip_address(pn_root, pn_fda) uidatahelpers.save_optional_field_to_rdf(pn_root, ns_ui.defaultGateway, rdf.IPv4Address, pn_fda, 'default_gateway') _save_client_traffic(pn_root, pn_fda) # DNS Servers dns_fda = fda.descend('dns_group') if dns_fda['dns_selection'] == 'use_dhcp_ic': dns_root = ui_root.setS(ns_ui.dnsServers, rdf.Type(ns_ui.InternetConnectionDhcp)) elif dns_fda['dns_selection'] == 'use_dhcp_pn': dns_root = ui_root.setS( ns_ui.dnsServers, rdf.Type(ns_ui.PrivateNetworkConnectionDhcp)) elif dns_fda['dns_selection'] == 'set_manually': dns_root = ui_root.setS(ns_ui.dnsServers, rdf.Type(ns_ui.SetDnsServers)) # XXX: dns_1 is not really optional here; we should not save dns_2 if we don't have dns_1, it makes no sense uidatahelpers.save_optional_field_to_rdf(dns_root, ns_ui.primaryDns, rdf.IPv4Address, dns_fda, 'dns_1') uidatahelpers.save_optional_field_to_rdf(dns_root, ns_ui.secondaryDns, rdf.IPv4Address, dns_fda, 'dns_2') # Dyndns ddns_fda = fda.descend('ddns_group') if uidatahelpers.has_form_value(ddns_fda, 'ddns_provider') and \ (ddns_fda['ddns_provider'] != 'none'): ddns_root = ui_root.setS(ns_ui.dynDnsServer, rdf.Type(ns_ui.DynDnsServer)) ddns_root.setS(ns_ui.dynDnsProvider, rdf.String, ddns_fda['ddns_provider']) ddns_root.setS(ns_ui.dynDnsUsername, rdf.String, ddns_fda['ddns_username']) ddns_root.setS(ns_ui.dynDnsPassword, rdf.String, ddns_fda['ddns_password']) ddns_root.setS(ns_ui.dynDnsHostname, rdf.String, ddns_fda['ddns_hostname']) tmp = ddns_fda['ddns_address_type'] if tmp == 'interface': ddns_root.setS(ns_ui.dynDnsAddress, rdf.String, '') elif tmp == 'natted': ddns_root.setS(ns_ui.dynDnsAddress, rdf.String, 'natted') elif tmp == 'static': if (ddns_fda.has_key('ddns_address')) and \ (ddns_fda['ddns_address'] is not None) and \ (ddns_fda['ddns_address'] != ''): ddns_root.setS(ns_ui.dynDnsAddress, rdf.String, ddns_fda['ddns_address']) else: ddns_root.setS(ns_ui.dynDnsAddress, rdf.String, '') else: ui_root.removeNodes(ns_ui.dynDnsServer)
def fill_network_config(self, form, ctx, fda): def _fill_address_to_form(rdf_node, fda): if (rdf_node.getS(ns_ui.address).hasType(ns_ui.DhcpAddress)): fda['ip_address_selection'] = 'dhcp' elif (rdf_node.getS(ns_ui.address).hasType(ns_ui.StaticAddress)): fda['ip_address_selection'] = 'static' fda['ip_address'] = rdf_node.getS(ns_ui.address).getS( ns_ui.ipAddress, rdf.IPv4Address) fda['subnet_mask'] = rdf_node.getS(ns_ui.address).getS( ns_ui.subnetMask, rdf.IPv4Address) else: raise uidatahelpers.RdfDataError( 'ns_ui.address is not dhcp or static') def _fill_client_traffic_to_form(rdf_node, fda): if rdf_node.getS(ns_ui.clientConnectionNat, rdf.Boolean): fda['client_traffic'] = 'nat' elif rdf_node.getS(ns_ui.clientConnectionProxyArp, rdf.Boolean): fda['client_traffic'] = 'proxyarp' else: fda['client_traffic'] = 'none' root = helpers.get_ui_config() # interface count (ifcount_group) ifc_fda = fda.descend('ifcount_group') if root.hasS(ns_ui.privateNetworkConnection): ifc_fda['interface_count'] = 'twoif' pn_root = root.getS(ns_ui.privateNetworkConnection, rdf.Type(ns_ui.NetworkConnection)) else: ifc_fda['interface_count'] = 'oneif' pn_root = None # internet connection (ic_group) ic_root = root.getS(ns_ui.internetConnection, rdf.Type(ns_ui.NetworkConnection)) ic_fda = fda.descend('ic_group') ic_fda['if'] = ic_root.getS(ns_ui.interface, rdf.String) _fill_address_to_form(ic_root, ic_fda) uidatahelpers.fill_optional_field_to_form(ic_root, ns_ui.defaultGateway, rdf.IPv4Address, ic_fda, 'default_gateway') ic_fda['mtu'] = ic_root.getS(ns_ui.mtu, rdf.Integer) uidatahelpers.fill_optional_field_to_form(ic_root, ns_ui.vpnUplink, rdf.Float, ic_fda, 'uplink') _fill_client_traffic_to_form(ic_root, ic_fda) # private network connection (pn_group) if not (pn_root is None): pn_fda = fda.descend('pn_group') pn_fda['if'] = pn_root.getS(ns_ui.interface, rdf.String) _fill_address_to_form(pn_root, pn_fda) uidatahelpers.fill_optional_field_to_form(pn_root, ns_ui.defaultGateway, rdf.IPv4Address, pn_fda, 'default_gateway') _fill_client_traffic_to_form(pn_root, pn_fda) # dns servers (dns_group) dns_root = root.getS(ns_ui.dnsServers) dns_fda = fda.descend('dns_group') if dns_root.hasType(ns_ui.InternetConnectionDhcp): dns_fda['dns_selection'] = 'use_dhcp_ic' elif dns_root.hasType(ns_ui.PrivateNetworkConnectionDhcp): dns_fda['dns_selection'] = 'use_dhcp_pn' elif dns_root.hasType(ns_ui.SetDnsServers): dns_fda['dns_selection'] = 'set_manually' dns_exists = False if dns_root.hasS(ns_ui.primaryDns): dns_exists = True dns_fda['dns_1'] = dns_root.getS(ns_ui.primaryDns, rdf.IPv4Address) if dns_root.hasS(ns_ui.secondaryDns): dns_exists = True dns_fda['dns_2'] = dns_root.getS(ns_ui.secondaryDns, rdf.IPv4Address) if not (dns_exists): _log.warning('no dns servers when filling form data') else: raise uidatahelpers.RdfDataError( 'Unknown DNS server information selection') # dynamic dns (ddns_group) ddns_fda = fda.descend('ddns_group') if root.hasS(ns_ui.dynDnsServer): ddns_root = root.getS(ns_ui.dynDnsServer, rdf.Type(ns_ui.DynDnsServer)) ddns_fda['ddns_provider'] = ddns_root.getS(ns_ui.dynDnsProvider, rdf.String) ddns_fda['ddns_username'] = ddns_root.getS(ns_ui.dynDnsUsername, rdf.String) ddns_fda['ddns_password'] = ddns_root.getS(ns_ui.dynDnsPassword, rdf.String) ddns_fda['ddns_hostname'] = ddns_root.getS(ns_ui.dynDnsHostname, rdf.String) if ddns_root.hasS(ns_ui.dynDnsAddress): tmp = ddns_root.getS(ns_ui.dynDnsAddress, rdf.String) if tmp == '': ddns_fda['ddns_address_type'] = 'interface' ddns_fda['ddns_address'] = '' elif tmp == 'natted': ddns_fda['ddns_address_type'] = 'natted' ddns_fda['ddns_address'] = '' else: ddns_fda['ddns_address_type'] = 'static' ddns_fda['ddns_address'] = tmp else: ddns_fda['ddns_address_type'] = 'interface' ddns_fda['ddns_address'] = '' else: ddns_fda['ddns_provider'] = 'none'
def renderHTTP(self, ctx): request = inevow.IRequest(ctx) # read unpatched exe f = None exedata = '' try: f = open(self.autoconfig_exe_filename, 'rb') exedata = f.read() finally: if f is not None: f.close() f = None # figure parameters server_address_in_uri = None try: server_address_in_uri = str(request.getRequestHostname()) except: _log.exception('cannot figure out server_address_in_uri') server_ip = None try: server_ip = self._get_server_ip_for_win2k(ctx) except: _log.exception('cannot figure out server_ip') server_address = None if self.force_server_address_to_ip: server_address = server_ip else: server_address = server_address_in_uri if (server_address_in_uri is None) or (server_address_in_uri == ''): raise Exception('server_address_in_uri missing, failing') if (server_address is None) or (server_address == ''): raise Exception('server_address missing, failing') if self.include_win2k_regdata and ((server_ip is None) or (server_ip == '')): raise Exception('server_ip is needed and missing, failing') preshared_key = '' try: psk_seq = helpers.get_ui_config().getS(ns_ui.preSharedKeys, rdf.Seq(rdf.Type(ns_ui.PreSharedKey))) preshared_key = str(psk_seq[0].getS(ns_ui.preSharedKey, rdf.String)) except: _log.exception('cannot figure out preshared_key') username = '' try: tmp = self.get_logged_in_username() if tmp is not None: username = str(tmp) except: _log.exception('cannot figure out username') # Profile name, always uses address in URI, even if server address itself forced to IP profile_prefix = 'VPNease' try: if os.path.exists(constants.AUTOCONFIG_PROFILE_PREFIX_FILE): profile_prefix = helpers.read_and_strip_file(constants.AUTOCONFIG_PROFILE_PREFIX_FILE) except: _log.exception('failed when checking for alternative profile name') profile_name = '%s (%s)' % (profile_prefix, server_address_in_uri) # Server behind port forward server_portfw = False try: global_st = helpers.get_global_status() if global_st.hasS(ns.behindNat): if global_st.getS(ns.behindNat, rdf.Boolean): server_portfw = True else: server_portfw = False else: # assume worst - reboot *MAY* be required server_portfw = True # markerfile for debugging if helpers.check_marker_file(constants.FORCE_NATTREBOOT_MARKERFILE): _log.warning('force nat-t reboot marker file exists, pretending server is behind port forward') server_portfw = True except: _log.exception('cannot determine whether server is behind port forward, may be OK') # Windows 2000 registry-based IPsec policy + prohibitIpsec win2k_ipsec_policy_registry_file = '' try: if self.include_win2k_regdata: # Registry data is HEX encoded UTF-16; HEX encoding is used to avoid problems # with the parameters.cpp mechanism (null termination). The resulting data is # large, around 50 kilobytes (!). # Always uses server IP for IPsec policy, because that's what Windows 2000 IPsec wants t = self._get_win2k_reg_file(server_ip, preshared_key) t = self._encode_windows_reg_file(t) # UTF-16 win2k_ipsec_policy_registry_file = t.encode('hex') # hex-encoded UTF-16 except: _log.exception('cannot create win2k registry file') # Fill paramdict and return paramdict = {} paramdict['operation'] = 'configure_profile' paramdict['profile_name'] = profile_name paramdict['desktop_shortcut_name'] = '%s.LNK' % profile_name # xxx: for now the same paramdict['server_address'] = server_address paramdict['preshared_key'] = preshared_key paramdict['username'] = username paramdict['ppp_compression_enabled'] = '1' paramdict['default_route_enabled'] = '1' paramdict['create_desktop_shortcut'] = '1' paramdict['open_profile_after_creation'] = '1' if server_portfw: paramdict['server_behind_port_forward'] = '1' else: paramdict['server_behind_port_forward'] = '0' if self.include_win2k_regdata: paramdict['win2k_registry_file'] = win2k_ipsec_policy_registry_file return uihelpers.RewritingBinaryResource(exedata, paramdict)
def _update_snmp(): """Update SNMP data.""" from codebay.l2tpserver import licensemanager from codebay.l2tpserver import helpers from codebay.l2tpserver.webui import uihelpers now = datetime.datetime.utcnow() st = helpers.get_status() global_st = helpers.get_global_status() license_info = helpers.get_license_info() def _timeticks(td): return int(helpers.timedelta_to_seconds(td) * 100.0) def _timestamp(dt): return datatypes.encode_datetime_to_iso8601_subset(dt) def _get_management_conn(): # XXX: not the best place for this if global_st.hasS(ns.managementServerConnection): if global_st.getS(ns.managementServerConnection, rdf.Boolean): return 1 return 0 vals = {} lm = licensemanager.LicenseMonitor() usr_count, usr_limit, usr_limit_leeway, s2s_count, s2s_limit, s2s_limit_leeway = None, None, None, None, None, None try: usr_count, usr_limit, usr_limit_leeway, s2s_count, s2s_limit, s2s_limit_leeway = lm.count_both_users() except: _log.exception('cannot get ppp counts for snmp') # XXX: this sharing of status code is quite unclean; see uihelpers.get_status_and_substatus() for suggestions health_errors = 0 try: status_class, status_text, substatus_class, substatus_text, status_ok = uihelpers.get_status_and_substatus() if status_ok: health_errors = 0 else: health_errors = 1 except: _log.exception('cannot determine health errors') for k, l in [ ('vpneaseHealthCheckErrors', lambda: health_errors), ('vpneaseUserCount', lambda: usr_count), ('vpneaseSiteToSiteCount', lambda: s2s_count), ('vpneaseLastMaintenanceReboot', lambda: _timestamp(helpers.read_datetime_marker_file(constants.LAST_AUTOMATIC_REBOOT_MARKER_FILE))), ('vpneaseNextMaintenanceReboot', lambda: _timestamp(uihelpers.compute_periodic_reboot_time())), ('vpneaseLastSoftwareUpdate', lambda: _timestamp(helpers.read_datetime_marker_file(constants.LAST_SUCCESSFUL_UPDATE_MARKER_FILE))), ('vpneaseSoftwareVersion', lambda: helpers.get_product_version(cache=True, filecache=True)), ('vpneaseCpuUsage', lambda: int(global_st.getS(ns.cpuUsage, rdf.Float))), ('vpneaseMemoryUsage', lambda: int(global_st.getS(ns.memoryUsage, rdf.Float))), ('vpneaseVirtualMemoryUsage', lambda: int(global_st.getS(ns.swapUsage, rdf.Float))), ('vpneaseServiceUptime', lambda: _timeticks(now - st.getS(ns.startTime, rdf.Datetime))), ('vpneaseHostUptime', lambda: _timeticks(datetime.timedelta(0, helpers.get_uptime(), 0))), ('vpneasePublicAddress', lambda: st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getAddress().toString()), ('vpneasePublicSubnet', lambda: st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getMask().toString()), ('vpneasePublicMac', lambda: st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface)).getS(ns.macAddress, rdf.String)), ('vpneasePrivateAddress', lambda: st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getAddress().toString()), ('vpneasePrivateSubnet', lambda: st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getMask().toString()), ('vpneasePrivateMac', lambda: st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface)).getS(ns.macAddress, rdf.String)), ('vpneaseLicenseKey', lambda: license_info.getS(ns_ui.licenseKey, rdf.String)), ('vpneaseLicenseString', lambda: license_info.getS(ns_ui.licenseString, rdf.String)), ('vpneaseLicenseUserLimit', lambda: usr_limit), ('vpneaseLicenseSiteToSiteLimit', lambda: s2s_limit), ('vpneaseMaintenanceReboots', lambda: global_st.getS(ns.periodicReboots, rdf.Integer)), ('vpneaseWatchdogReboots', lambda: global_st.getS(ns.watchdogReboots, rdf.Integer)), ('vpneaseLicenseServerConnection', _get_management_conn), ]: try: val = l() if val is not None: vals[k] = val except: # these are expected in several cases, so don't spew too much log about them # XXX: it would be better if the checkers would figure these out for themselves # (when a value is expected and when not) _log.info('failed to get snmp value for key %s' % k) #_log.exception('failed to get snmp value for key %s' % k) keys = vals.keys() keys.sort() res = '' for k in keys: res += '%s=%s\n' % (k, vals[k]) # to ASCII, escaping any non-ASCII chars with XML escapes res = res.encode('US-ASCII', 'xmlcharrefreplace') f = None try: f = open(constants.SNMP_DATA_FILE, 'wb') f.write(res) finally: if f: f.close() f = None
def _validate(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, ['s2s_connections'], ctx) # Get some useful stuff for validation ui_root = helpers.get_ui_config() pub_iface, pub_addr_subnet = None, None if ui_root.hasS(ns_ui.internetConnection): pub_iface = ui_root.getS(ns_ui.internetConnection, rdf.Type(ns_ui.NetworkConnection)) pub_addr = pub_iface.getS(ns_ui.address) if pub_addr.hasType(ns_ui.StaticAddress): pub_addr_subnet = datatypes.IPv4AddressSubnet.fromStrings( pub_addr.getS(ns_ui.ipAddress, rdf.IPv4Address).toString(), pub_addr.getS(ns_ui.subnetMask, rdf.IPv4Address).toString()) priv_iface, priv_addr_subnet = None, None if ui_root.hasS(ns_ui.privateNetworkConnection): priv_iface = ui_root.getS(ns_ui.privateNetworkConnection, rdf.Type(ns_ui.NetworkConnection)) priv_addr = priv_iface.getS(ns_ui.address) if priv_addr.hasType(ns_ui.StaticAddress): priv_addr_subnet = datatypes.IPv4AddressSubnet.fromStrings( priv_addr.getS(ns_ui.ipAddress, rdf.IPv4Address).toString(), priv_addr.getS(ns_ui.subnetMask, rdf.IPv4Address).toString()) ppp_subnet = None if ui_root.hasS(ns_ui.clientSubnet): ppp_subnet = ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) # Validate individual site-to-site connections idx = 0 conns = [] while True: fda_conn = fda.descend(str(idx)) if len(fda_conn.keys()) == 0: break conns.append(fda_conn) idx += 1 remote_access_usernames = [] if ui_root.hasS(ns_ui.users): for user in ui_root.getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User))): if user.hasS(ns_ui.username): remote_access_usernames.append( user.getS(ns_ui.username, rdf.String)) s2s_server_usernames_found = [] for fda_conn_index, fda_conn in enumerate(conns): if fda_conn.has_key('s2s_username'): if not uihelpers.check_ppp_username_characters( fda_conn['s2s_username']): fda_conn.add_error('s2s_username', 'Invalid characters') elif len(fda_conn['s2s_username'] ) > constants.MAX_USERNAME_LENGTH: fda_conn.add_error('s2s_username', 'Username too long') if fda_conn.has_key('s2s_password'): if not uihelpers.check_ppp_password_characters( fda_conn['s2s_password']): fda_conn.add_error('s2s_password', 'Invalid characters') elif len(fda_conn['s2s_password'] ) > constants.MAX_PASSWORD_LENGTH: fda_conn.add_error('s2s_password', 'Password too long') if fda_conn.has_key('s2s_mode'): mode = fda_conn['s2s_mode'] if mode == 'client': # psk and server address are mandatory for client if not fda_conn.has_key('s2s_psk') or fda_conn[ 's2s_psk'] == '' or fda_conn['s2s_psk'] is None: fda_conn.add_error('s2s_psk', 'Required for initiator') else: if not uihelpers.check_preshared_key_characters( fda_conn['s2s_psk']): fda_conn.add_error('s2s_psk', 'Invalid characters') if not fda_conn.has_key('s2s_server') or fda_conn[ 's2s_server'] == '' or fda_conn[ 's2s_server'] is None: fda_conn.add_error('s2s_server', 'Required for initiator') else: if not uihelpers.check_dns_name_characters( fda_conn['s2s_server']): fda_conn.add_error('s2s_server', 'Invalid characters') else: # server # must not have duplicate server-mode names; client mode names may be duplicates if fda_conn.has_key('s2s_username'): username = fda_conn['s2s_username'] if username in s2s_server_usernames_found: fda_conn.add_error( 's2s_username', 'Duplicate username for server mode connection' ) elif username in remote_access_usernames: fda_conn.add_error( 's2s_username', 'Duplicate username for server mode connection (already a user with that name)' ) else: s2s_server_usernames_found.append( fda_conn['s2s_username']) # check subnets if fda_conn.has_key('s2s_subnets'): subnets = fda_conn['s2s_subnets'] # check that list doesn't contain overlap inside itself overlap_inside_list = False for i in xrange(len(subnets)): for j in xrange(len(subnets)): if i != j: if subnets[i].overlapsWithSubnet(subnets[j]): overlap_inside_list = True if overlap_inside_list: fda_conn.add_warning('s2s_subnets', 'Subnets in list overlap') # check that no element of list overlaps with any other subnet of any other site-to-site connection overlap_with_other = False for subnet in subnets: for other_conn_index, other_conn in enumerate(conns): if other_conn.has_key( 's2s_subnets' ) and other_conn_index != fda_conn_index: for other_subnet in other_conn['s2s_subnets']: if subnet.overlapsWithSubnet(other_subnet): overlap_with_other = True if overlap_with_other: fda_conn.add_warning( 's2s_subnets', 'Remote subnet(s) overlap with other connections') # check overlap against public interface if pub_addr_subnet is not None: if subnet.overlapsWithSubnet(pub_addr_subnet.getSubnet()): fda_conn.add_warning( 's2s_subnets', 'Remote subnet(s) overlap with Internet connection subnet' ) # check overlap against private interface if priv_addr_subnet is not None: if subnet.overlapsWithSubnet(priv_addr_subnet.getSubnet()): fda_conn.add_warning( 's2s_subnets', 'Remote subnet(s) overlap with private network connection subnet' ) # check overlap against ppp subnet if ppp_subnet is not None: if subnet.overlapsWithSubnet(ppp_subnet): fda_conn.add_warning( 's2s_subnets', 'Remote subnet(s) overlap with client subnet')