Пример #1
0
    def renderHTTP(self, ctx):
        # XXX: refactor this to a helper??
        def _xml_escape(x):
            return helpers.xml_escape(x)

        # XXX: simple base64 encoding does not seem to be enough
        def _base64_encode(x):
            # base64 produces a newline, strip it away; still not correct tho
            return x.encode('base64').strip()

        request = inevow.IRequest(ctx)

        # figure parameters
        server_address = ''
        try:
            server_address = str(request.getRequestHostname())
        except:
            _log.exception('cannot figure out server_address')
            
        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
        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)

        # 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')
            
        #
        #  Notes about OSX plist for networkConnect
        #
        #    * There are settings for PPP redial counts etc.  We don't use them
        #      because we want to minimize risks.
        #
        #    * DisconnectOnXXX settings only seem to work when inside SystemConfig,
        #      not inside UserConfigs.
        #
        #    * SystemConfig -> IPv4 -> OverridePrimary=1 should, based on PPP code,
        #      set 'default route' setting but doesn't seem to work.
        #
        #    * UserConfigs -> IPsec -> ExportedSharedSecret contains the pre-shared
        #      key for IKE in some sort of encrypted format.  The value is base64
        #      encoded but the pre-shared key is processed (encrypted or masked)
        #      prior to base64.  Note that whatever the unknown (and seemingly
        #      undocumented transform is, it has to be reversible because IKE needs
        #      the PSK.
        #
        #    * CCP / MPPC / MPPE are disabled now.  They don't actually work in
        #      Leopard at least.
        #
        
        # create xml plist
        textdata = textwrap.dedent("""\
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
            <plist version="1.0">
                <dict>
                    <key>L2TP</key>
                    <dict>
                        <key>SystemConfig</key>
                        <dict>
                            <key>PPP</key>
                            <dict>
                                <key>DisconnectOnSleep</key>
                                <integer>1</integer>
                                <key>DisconnectOnFastUserSwitch</key>
                                <integer>1</integer>
                                <key>DisconnectOnLogout</key>
                                <integer>1</integer>
                            </dict>
                        </dict>

                        <key>UserConfigs</key>
                        <array>
                            <dict>
                                <key>EAP</key>
                                <dict/>
                                <key>IPSec</key>
                                <dict>
                                    <key>AuthenticationMethod</key>
                                    <string>SharedSecret</string>
                                    <key>LocalIdentifier</key>
                                    <string></string>
                                    <key>LocalIdentifierType</key>
                                    <string>KeyID</string>
                                </dict>
                                <key>PPP</key>
                                <dict>
                                    <key>AuthName</key>
                                    <string>%(username)s</string>
                                    <key>CommRemoteAddress</key>
                                    <string>%(server_address)s</string>
                                    <key>UserDefinedName</key>
                                    <string>%(profile_name)s</string>
                                    <key>CCPEnabled</key>
                                    <integer>%(ccp_enabled)d</integer>
                                    <key>CCPMPPE128Enabled</key>
                                    <integer>%(ccp_mppe40_enabled)d</integer>
                                    <key>CCPMPPE40Enabled</key>
                                    <integer>%(ccp_mppe128_enabled)d</integer>
                                </dict>
                            </dict>
                        </array>
                    </dict>
                </dict>
            </plist>
        """) % {
            'preshared_key_base64': _xml_escape(_base64_encode(preshared_key)),
            'username': _xml_escape(username),
            'server_address': _xml_escape(server_address),
            'profile_name': _xml_escape(profile_name),
            'override_primary': 1, # XXX: force default route
            'ccp_enabled': 0,
            'ccp_mppe40_enabled': 0,
            'ccp_mppe128_enabled': 0,
            }
        
        #
        #  Content-Type is interesting.  If this is served as 'text/xml', Safari
        #  will display the file without offering a save option.  Even if it is
        #  saved, Safari will *refuse* saving the file with '.networkConnect'
        #  extension.
        #
        #  'application/octet-stream' causes Safari to save the file, and use can
        #  double click to run it.
        #

        return uihelpers.UncachedData(textdata, 'application/octet-stream')
Пример #2
0
    def renderHTTP(self, ctx):
        # XXX: refactor this to a helper??
        def _xml_escape(x):
            return helpers.xml_escape(x)

        # XXX: simple base64 encoding does not seem to be enough
        def _base64_encode(x):
            # base64 produces a newline, strip it away; still not correct tho
            return x.encode('base64').strip()

        request = inevow.IRequest(ctx)

        # figure parameters
        server_address = ''
        try:
            server_address = str(request.getRequestHostname())
        except:
            _log.exception('cannot figure out server_address')

        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
        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)

        # 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'
            )

        #
        #  Notes about OSX plist for networkConnect
        #
        #    * There are settings for PPP redial counts etc.  We don't use them
        #      because we want to minimize risks.
        #
        #    * DisconnectOnXXX settings only seem to work when inside SystemConfig,
        #      not inside UserConfigs.
        #
        #    * SystemConfig -> IPv4 -> OverridePrimary=1 should, based on PPP code,
        #      set 'default route' setting but doesn't seem to work.
        #
        #    * UserConfigs -> IPsec -> ExportedSharedSecret contains the pre-shared
        #      key for IKE in some sort of encrypted format.  The value is base64
        #      encoded but the pre-shared key is processed (encrypted or masked)
        #      prior to base64.  Note that whatever the unknown (and seemingly
        #      undocumented transform is, it has to be reversible because IKE needs
        #      the PSK.
        #
        #    * CCP / MPPC / MPPE are disabled now.  They don't actually work in
        #      Leopard at least.
        #

        # create xml plist
        textdata = textwrap.dedent("""\
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
            <plist version="1.0">
                <dict>
                    <key>L2TP</key>
                    <dict>
                        <key>SystemConfig</key>
                        <dict>
                            <key>PPP</key>
                            <dict>
                                <key>DisconnectOnSleep</key>
                                <integer>1</integer>
                                <key>DisconnectOnFastUserSwitch</key>
                                <integer>1</integer>
                                <key>DisconnectOnLogout</key>
                                <integer>1</integer>
                            </dict>
                        </dict>

                        <key>UserConfigs</key>
                        <array>
                            <dict>
                                <key>EAP</key>
                                <dict/>
                                <key>IPSec</key>
                                <dict>
                                    <key>AuthenticationMethod</key>
                                    <string>SharedSecret</string>
                                    <key>LocalIdentifier</key>
                                    <string></string>
                                    <key>LocalIdentifierType</key>
                                    <string>KeyID</string>
                                </dict>
                                <key>PPP</key>
                                <dict>
                                    <key>AuthName</key>
                                    <string>%(username)s</string>
                                    <key>CommRemoteAddress</key>
                                    <string>%(server_address)s</string>
                                    <key>UserDefinedName</key>
                                    <string>%(profile_name)s</string>
                                    <key>CCPEnabled</key>
                                    <integer>%(ccp_enabled)d</integer>
                                    <key>CCPMPPE128Enabled</key>
                                    <integer>%(ccp_mppe40_enabled)d</integer>
                                    <key>CCPMPPE40Enabled</key>
                                    <integer>%(ccp_mppe128_enabled)d</integer>
                                </dict>
                            </dict>
                        </array>
                    </dict>
                </dict>
            </plist>
        """) % {
            'preshared_key_base64': _xml_escape(_base64_encode(preshared_key)),
            'username': _xml_escape(username),
            'server_address': _xml_escape(server_address),
            'profile_name': _xml_escape(profile_name),
            'override_primary': 1,  # XXX: force default route
            'ccp_enabled': 0,
            'ccp_mppe40_enabled': 0,
            'ccp_mppe128_enabled': 0,
        }

        #
        #  Content-Type is interesting.  If this is served as 'text/xml', Safari
        #  will display the file without offering a save option.  Even if it is
        #  saved, Safari will *refuse* saving the file with '.networkConnect'
        #  extension.
        #
        #  'application/octet-stream' causes Safari to save the file, and use can
        #  double click to run it.
        #

        return uihelpers.UncachedData(textdata, 'application/octet-stream')
Пример #3
0
    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)