Esempio n. 1
0
 def test_check_badRSAkey(self):
     """A challenge with a bad RSA secret key should return False."""
     secretKeyBad, publicKeyBad = crypto.getRSAKey('test_gimpCaptcha_badRSAkey')
     c = captcha.GimpCaptcha(self.publik, self.sekrit, self.hmacKey,
                             self.cacheDir)
     image, challenge = c.get()
     self.assertEquals(
         c.check(challenge, c.answer, secretKeyBad, c.hmacKey),
         False)
Esempio n. 2
0
    def setUp(self):
        here = os.getcwd()
        self.topDir = here.rstrip("_trial_temp")
        self.cacheDir = os.path.join(self.topDir, "captchas")
        self.badCacheDir = os.path.join(here, "capt")

        # Get keys for testing or create them:
        self.sekrit, self.publik = crypto.getRSAKey("test_gimpCaptcha_RSAkey")
        self.hmacKey = crypto.getKey("test_gimpCaptcha_HMACkey")
Esempio n. 3
0
    def setUp(self):
        here = os.getcwd()
        self.topDir = here.rstrip('_trial_temp')
        self.cacheDir = os.path.join(self.topDir, 'captchas')
        self.badCacheDir = os.path.join(here, 'capt')

        # Get keys for testing or create them:
        self.sekrit, self.publik = crypto.getRSAKey('test_gimpCaptcha_RSAkey')
        self.hmacKey = crypto.getKey('test_gimpCaptcha_HMACkey')
Esempio n. 4
0
 def test_check_badRSAkey(self):
     """A challenge with a bad RSA secret key should return False."""
     secretKeyBad, publicKeyBad = crypto.getRSAKey(
         'test_gimpCaptcha_badRSAkey')
     c = captcha.GimpCaptcha(self.publik, self.sekrit, self.hmacKey,
                             self.cacheDir)
     image, challenge = c.get()
     self.assertEquals(
         c.check(challenge, c.answer, secretKeyBad, c.hmacKey), False)
Esempio n. 5
0
def addWebServer(config, distributor):
    """Set up a web server for HTTP(S)-based bridge distribution.

    :type config: :class:`bridgedb.persistent.Conf`
    :param config: A configuration object from
         :mod:`bridgedb.Main`. Currently, we use these options::
             HTTP_UNENCRYPTED_PORT
             HTTP_UNENCRYPTED_BIND_IP
             HTTP_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_N_BRIDGES_PER_ANSWER
             HTTPS_INCLUDE_FINGERPRINTS
             HTTPS_KEY_FILE
             HTTPS_CERT_FILE
             HTTPS_PORT
             HTTPS_BIND_IP
             HTTPS_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_ROTATION_PERIOD
             RECAPTCHA_ENABLED
             RECAPTCHA_PUB_KEY
             RECAPTCHA_SEC_KEY
             RECAPTCHA_REMOTEIP
             GIMP_CAPTCHA_ENABLED
             GIMP_CAPTCHA_DIR
             GIMP_CAPTCHA_HMAC_KEYFILE
             GIMP_CAPTCHA_RSA_KEYFILE
             SERVER_PUBLIC_FQDN
             CSP_ENABLED
             CSP_REPORT_ONLY
             CSP_INCLUDE_SELF
    :type distributor: :class:`bridgedb.https.distributor.HTTPSDistributor`
    :param distributor: A bridge distributor.
    :raises SystemExit: if the servers cannot be started.
    :rtype: :api:`twisted.web.server.Site`
    :returns: A webserver.
    """
    captcha = None
    fwdHeaders = config.HTTP_USE_IP_FROM_FORWARDED_HEADER
    numBridges = config.HTTPS_N_BRIDGES_PER_ANSWER
    fprInclude = config.HTTPS_INCLUDE_FINGERPRINTS

    logging.info("Starting web servers...")

    setFQDN(config.SERVER_PUBLIC_FQDN)

    index   = IndexResource()
    options = OptionsResource()
    howto   = HowtoResource()
    robots  = static.File(os.path.join(TEMPLATE_DIR, 'robots.txt'))
    assets  = static.File(os.path.join(TEMPLATE_DIR, 'assets/'))
    keys    = static.Data(bytes(strings.BRIDGEDB_OPENPGP_KEY), 'text/plain')
    csp     = CSPResource(enabled=config.CSP_ENABLED,
                          includeSelf=config.CSP_INCLUDE_SELF,
                          reportViolations=config.CSP_REPORT_ONLY,
                          useForwardedHeader=fwdHeaders)

    root = CustomErrorHandlingResource()
    root.putChild('', index)
    root.putChild('robots.txt', robots)
    root.putChild('keys', keys)
    root.putChild('assets', assets)
    root.putChild('options', options)
    root.putChild('howto', howto)
    root.putChild('maintenance', maintenance)
    root.putChild('error', resource500)
    root.putChild(CSPResource.reportURI, csp)

    if config.RECAPTCHA_ENABLED:
        publicKey = config.RECAPTCHA_PUB_KEY
        secretKey = config.RECAPTCHA_SEC_KEY
        captcha = partial(ReCaptchaProtectedResource,
                          remoteIP=config.RECAPTCHA_REMOTEIP)
    elif config.GIMP_CAPTCHA_ENABLED:
        # Get the master HMAC secret key for CAPTCHA challenges, and then
        # create a new HMAC key from it for use on the server.
        captchaKey = crypto.getKey(config.GIMP_CAPTCHA_HMAC_KEYFILE)
        hmacKey = crypto.getHMAC(captchaKey, "Captcha-Key")
        # Load or create our encryption keys:
        secretKey, publicKey = crypto.getRSAKey(config.GIMP_CAPTCHA_RSA_KEYFILE)
        captcha = partial(GimpCaptchaProtectedResource,
                          hmacKey=hmacKey,
                          captchaDir=config.GIMP_CAPTCHA_DIR)

    if config.HTTPS_ROTATION_PERIOD:
        count, period = config.HTTPS_ROTATION_PERIOD.split()
        sched = ScheduledInterval(count, period)
    else:
        sched = Unscheduled()

    bridges = BridgesResource(distributor, sched, numBridges, fwdHeaders,
                              includeFingerprints=fprInclude)
    if captcha:
        # Protect the 'bridges' page with a CAPTCHA, if configured to do so:
        protected = captcha(publicKey=publicKey,
                            secretKey=secretKey,
                            useForwardedHeader=fwdHeaders,
                            protectedResource=bridges)
        root.putChild('bridges', protected)
        logging.info("Protecting resources with %s." % captcha.func.__name__)
    else:
        root.putChild('bridges', bridges)

    site = Site(root)
    site.displayTracebacks = False

    if config.HTTP_UNENCRYPTED_PORT:  # pragma: no cover
        ip = config.HTTP_UNENCRYPTED_BIND_IP or ""
        port = config.HTTP_UNENCRYPTED_PORT or 80
        try:
            reactor.listenTCP(port, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTP server on %s:%d" % (str(ip), int(port)))

    if config.HTTPS_PORT:  # pragma: no cover
        ip = config.HTTPS_BIND_IP or ""
        port = config.HTTPS_PORT or 443
        try:
            from twisted.internet.ssl import DefaultOpenSSLContextFactory
            factory = DefaultOpenSSLContextFactory(config.HTTPS_KEY_FILE,
                                                   config.HTTPS_CERT_FILE)
            reactor.listenSSL(port, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTPS server on %s:%d" % (str(ip), int(port)))

    return site
Esempio n. 6
0
def addWebServer(cfg, dist, sched):
    """Set up a web server for HTTP(S)-based bridge distribution.

    :type cfg: :class:`bridgedb.persistent.Conf`
    :param cfg: A configuration object from
         :mod:`bridgedb.Main`. Currently, we use these options::
             HTTP_UNENCRYPTED_PORT
             HTTP_UNENCRYPTED_BIND_IP
             HTTP_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_N_BRIDGES_PER_ANSWER
             HTTPS_INCLUDE_FINGERPRINTS
             HTTPS_KEY_FILE
             HTTPS_CERT_FILE
             HTTPS_PORT
             HTTPS_BIND_IP
             HTTPS_USE_IP_FROM_FORWARDED_HEADER
             RECAPTCHA_ENABLED
             RECAPTCHA_PUB_KEY
             RECAPTCHA_SEC_KEY
             RECAPTCHA_REMOTEIP
             GIMP_CAPTCHA_ENABLED
             GIMP_CAPTCHA_DIR
             GIMP_CAPTCHA_HMAC_KEYFILE
             GIMP_CAPTCHA_RSA_KEYFILE
    :type dist: :class:`bridgedb.Dist.IPBasedDistributor`
    :param dist: A bridge distributor.
    :type sched: :class:`bridgedb.schedule.ScheduledInterval`
    :param sched: The scheduled interval at which bridge selection, which
        are ultimately displayed on the :class:`WebResourceBridges` page, will
        be shifted.
    :raises SystemExit: if the servers cannot be started.
    :rtype: :api:`twisted.web.server.Site`
    :returns: A webserver.
    """
    captcha = None
    fwdHeaders = cfg.HTTP_USE_IP_FROM_FORWARDED_HEADER
    numBridges = cfg.HTTPS_N_BRIDGES_PER_ANSWER
    fprInclude = cfg.HTTPS_INCLUDE_FINGERPRINTS

    logging.info("Starting web servers...")

    httpdist = resource.Resource()
    httpdist.putChild('', WebRoot())
    httpdist.putChild('robots.txt',
                      static.File(os.path.join(TEMPLATE_DIR, 'robots.txt')))
    httpdist.putChild('keys',
                      static.File(os.path.join(TEMPLATE_DIR, 'bridgedb.asc')))
    httpdist.putChild('assets',
                      static.File(os.path.join(TEMPLATE_DIR, 'assets/')))
    httpdist.putChild('options', WebResourceOptions())
    httpdist.putChild('howto', WebResourceHowto())

    if cfg.RECAPTCHA_ENABLED:
        publicKey = cfg.RECAPTCHA_PUB_KEY
        secretKey = cfg.RECAPTCHA_SEC_KEY
        captcha = partial(ReCaptchaProtectedResource,
                          remoteIP=cfg.RECAPTCHA_REMOTEIP)
    elif cfg.GIMP_CAPTCHA_ENABLED:
        # Get the master HMAC secret key for CAPTCHA challenges, and then
        # create a new HMAC key from it for use on the server.
        captchaKey = crypto.getKey(cfg.GIMP_CAPTCHA_HMAC_KEYFILE)
        hmacKey = crypto.getHMAC(captchaKey, "Captcha-Key")
        # Load or create our encryption keys:
        secretKey, publicKey = crypto.getRSAKey(cfg.GIMP_CAPTCHA_RSA_KEYFILE)
        captcha = partial(GimpCaptchaProtectedResource,
                          hmacKey=hmacKey,
                          captchaDir=cfg.GIMP_CAPTCHA_DIR)

    bridges = WebResourceBridges(dist, sched, numBridges,
                                 fwdHeaders, includeFingerprints=fprInclude)
    if captcha:
        # Protect the 'bridges' page with a CAPTCHA, if configured to do so:
        protected = captcha(publicKey=publicKey,
                            secretKey=secretKey,
                            useForwardedHeader=fwdHeaders,
                            protectedResource=bridges)
        httpdist.putChild('bridges', protected)
        logging.info("Protecting resources with %s." % captcha.func.__name__)
    else:
        httpdist.putChild('bridges', bridges)

    site = server.Site(httpdist)
    site.displayTracebacks = False

    if cfg.HTTP_UNENCRYPTED_PORT:
        ip = cfg.HTTP_UNENCRYPTED_BIND_IP or ""
        port = cfg.HTTP_UNENCRYPTED_PORT or 80
        try:
            reactor.listenTCP(port, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTP server on %s:%d" % (str(ip), int(port)))

    if cfg.HTTPS_PORT:
        ip = cfg.HTTPS_BIND_IP or ""
        port = cfg.HTTPS_PORT or 443
        try:
            from twisted.internet.ssl import DefaultOpenSSLContextFactory
            factory = DefaultOpenSSLContextFactory(cfg.HTTPS_KEY_FILE,
                                                   cfg.HTTPS_CERT_FILE)
            reactor.listenSSL(port, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTPS server on %s:%d" % (str(ip), int(port)))

    return site
Esempio n. 7
0
def addWebServer(cfg, dist):
    """Set up a web server for HTTP(S)-based bridge distribution.

    :type cfg: :class:`bridgedb.persistent.Conf`
    :param cfg: A configuration object from
         :mod:`bridgedb.Main`. Currently, we use these options::
             HTTP_UNENCRYPTED_PORT
             HTTP_UNENCRYPTED_BIND_IP
             HTTP_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_N_BRIDGES_PER_ANSWER
             HTTPS_INCLUDE_FINGERPRINTS
             HTTPS_KEY_FILE
             HTTPS_CERT_FILE
             HTTPS_PORT
             HTTPS_BIND_IP
             HTTPS_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_ROTATION_PERIOD
             RECAPTCHA_ENABLED
             RECAPTCHA_PUB_KEY
             RECAPTCHA_SEC_KEY
             RECAPTCHA_REMOTEIP
             GIMP_CAPTCHA_ENABLED
             GIMP_CAPTCHA_DIR
             GIMP_CAPTCHA_HMAC_KEYFILE
             GIMP_CAPTCHA_RSA_KEYFILE
    :type dist: :class:`bridgedb.Dist.IPBasedDistributor`
    :param dist: A bridge distributor.
    :raises SystemExit: if the servers cannot be started.
    :rtype: :api:`twisted.web.server.Site`
    :returns: A webserver.
    """
    captcha = None
    fwdHeaders = cfg.HTTP_USE_IP_FROM_FORWARDED_HEADER
    numBridges = cfg.HTTPS_N_BRIDGES_PER_ANSWER
    fprInclude = cfg.HTTPS_INCLUDE_FINGERPRINTS

    logging.info("Starting web servers...")

    httpdist = resource.Resource()
    httpdist.putChild('', WebRoot())
    httpdist.putChild('robots.txt',
                      static.File(os.path.join(TEMPLATE_DIR, 'robots.txt')))
    httpdist.putChild('keys',
                      static.File(os.path.join(TEMPLATE_DIR, 'bridgedb.asc')))
    httpdist.putChild('assets',
                      static.File(os.path.join(TEMPLATE_DIR, 'assets/')))
    httpdist.putChild('options', WebResourceOptions())
    httpdist.putChild('howto', WebResourceHowto())

    if cfg.RECAPTCHA_ENABLED:
        publicKey = cfg.RECAPTCHA_PUB_KEY
        secretKey = cfg.RECAPTCHA_SEC_KEY
        captcha = partial(ReCaptchaProtectedResource,
                          remoteIP=cfg.RECAPTCHA_REMOTEIP)
    elif cfg.GIMP_CAPTCHA_ENABLED:
        # Get the master HMAC secret key for CAPTCHA challenges, and then
        # create a new HMAC key from it for use on the server.
        captchaKey = crypto.getKey(cfg.GIMP_CAPTCHA_HMAC_KEYFILE)
        hmacKey = crypto.getHMAC(captchaKey, "Captcha-Key")
        # Load or create our encryption keys:
        secretKey, publicKey = crypto.getRSAKey(cfg.GIMP_CAPTCHA_RSA_KEYFILE)
        captcha = partial(GimpCaptchaProtectedResource,
                          hmacKey=hmacKey,
                          captchaDir=cfg.GIMP_CAPTCHA_DIR)

    if cfg.HTTPS_ROTATION_PERIOD:
        count, period = cfg.HTTPS_ROTATION_PERIOD.split()
        sched = ScheduledInterval(count, period)
    else:
        sched = Unscheduled()

    bridges = WebResourceBridges(dist, sched, numBridges,
                                 fwdHeaders, includeFingerprints=fprInclude)
    if captcha:
        # Protect the 'bridges' page with a CAPTCHA, if configured to do so:
        protected = captcha(publicKey=publicKey,
                            secretKey=secretKey,
                            useForwardedHeader=fwdHeaders,
                            protectedResource=bridges)
        httpdist.putChild('bridges', protected)
        logging.info("Protecting resources with %s." % captcha.func.__name__)
    else:
        httpdist.putChild('bridges', bridges)

    site = server.Site(httpdist)
    site.displayTracebacks = False

    if cfg.HTTP_UNENCRYPTED_PORT:
        ip = cfg.HTTP_UNENCRYPTED_BIND_IP or ""
        port = cfg.HTTP_UNENCRYPTED_PORT or 80
        try:
            reactor.listenTCP(port, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTP server on %s:%d" % (str(ip), int(port)))

    if cfg.HTTPS_PORT:
        ip = cfg.HTTPS_BIND_IP or ""
        port = cfg.HTTPS_PORT or 443
        try:
            from twisted.internet.ssl import DefaultOpenSSLContextFactory
            factory = DefaultOpenSSLContextFactory(cfg.HTTPS_KEY_FILE,
                                                   cfg.HTTPS_CERT_FILE)
            reactor.listenSSL(port, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTPS server on %s:%d" % (str(ip), int(port)))

    return site
Esempio n. 8
0
def addWebServer(cfg, dist, sched):
    """Set up a web server.

    :param cfg: A configuration object from :mod:`bridgedb.Main`. Currently,
         we use these options::
             HTTPS_N_BRIDGES_PER_ANSWER
             HTTP_UNENCRYPTED_PORT
             HTTP_UNENCRYPTED_BIND_IP
             HTTP_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_PORT
             HTTPS_BIND_IP
             HTTPS_USE_IP_FROM_FORWARDED_HEADER
             RECAPTCHA_ENABLED
             RECAPTCHA_PUB_KEY
             RECAPTCHA_PRIV_KEY
             RECAPTCHA_REMOTEIP
             GIMP_CAPTCHA_ENABLED
             GIMP_CAPTCHA_DIR
    :type dist: :class:`bridgedb.Dist.IPBasedDistributor`
    :param dist: A bridge distributor.
    :type sched: :class:`bridgedb.Time.IntervalSchedule`
    :param sched: DOCDOC
    """
    httpdist = resource.Resource()
    httpdist.putChild('', WebRoot())
    httpdist.putChild('robots.txt',
                      static.File(os.path.join(template_root, 'robots.txt')))
    httpdist.putChild('assets',
                      static.File(os.path.join(template_root, 'assets/')))
    httpdist.putChild('options', WebResourceOptions())

    bridgesResource = WebResourceBridges(
        dist, sched, cfg.HTTPS_N_BRIDGES_PER_ANSWER,
        cfg.HTTP_USE_IP_FROM_FORWARDED_HEADER,
        includeFingerprints=cfg.HTTPS_INCLUDE_FINGERPRINTS)

    if cfg.RECAPTCHA_ENABLED:
        protected = ReCaptchaProtectedResource(
                recaptchaPrivKey=cfg.RECAPTCHA_PRIV_KEY,
                recaptchaPubKey=cfg.RECAPTCHA_PUB_KEY,
                remoteip=cfg.RECAPTCHA_REMOTEIP,
                useForwardedHeader=cfg.HTTP_USE_IP_FROM_FORWARDED_HEADER,
                protectedResource=bridgesResource)
        httpdist.putChild('bridges', protected)

    elif cfg.GIMP_CAPTCHA_ENABLED:
        # Get the HMAC secret key for CAPTCHA challenges and create a new key
        # from it for use on the server:
        captchaKey = crypto.getKey(cfg.GIMP_CAPTCHA_HMAC_KEYFILE)
        hmacKey = crypto.getHMAC(captchaKey, "Captcha-Key")

        # Load or create our encryption keys:
        secretKey, publicKey = crypto.getRSAKey(cfg.GIMP_CAPTCHA_RSA_KEYFILE)

        protected = GimpCaptchaProtectedResource(
            secretKey=secretKey,
            publicKey=publicKey,
            hmacKey=hmacKey,
            captchaDir=cfg.GIMP_CAPTCHA_DIR,
            useForwardedHeader=cfg.HTTP_USE_IP_FROM_FORWARDED_HEADER,
            protectedResource=bridgesResource)
        httpdist.putChild('bridges', protected)
    else:
        httpdist.putChild('bridges', bridgesResource)

    site = server.Site(httpdist)

    if cfg.HTTP_UNENCRYPTED_PORT:
        ip = cfg.HTTP_UNENCRYPTED_BIND_IP or ""
        try:
            reactor.listenTCP(cfg.HTTP_UNENCRYPTED_PORT, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)

    if cfg.HTTPS_PORT:
        from twisted.internet.ssl import DefaultOpenSSLContextFactory
        #from OpenSSL.SSL import SSLv3_METHOD
        ip = cfg.HTTPS_BIND_IP or ""
        factory = DefaultOpenSSLContextFactory(cfg.HTTPS_KEY_FILE,
                                               cfg.HTTPS_CERT_FILE)
        try:
            reactor.listenSSL(cfg.HTTPS_PORT, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)

    return site
Esempio n. 9
0
def addWebServer(config, distributor):
    """Set up a web server for HTTP(S)-based bridge distribution.

    :type config: :class:`bridgedb.persistent.Conf`
    :param config: A configuration object from
         :mod:`bridgedb.main`. Currently, we use these options::
             HTTP_UNENCRYPTED_PORT
             HTTP_UNENCRYPTED_BIND_IP
             HTTP_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_N_BRIDGES_PER_ANSWER
             HTTPS_INCLUDE_FINGERPRINTS
             HTTPS_KEY_FILE
             HTTPS_CERT_FILE
             HTTPS_PORT
             HTTPS_BIND_IP
             HTTPS_USE_IP_FROM_FORWARDED_HEADER
             HTTPS_ROTATION_PERIOD
             RECAPTCHA_ENABLED
             RECAPTCHA_PUB_KEY
             RECAPTCHA_SEC_KEY
             RECAPTCHA_REMOTEIP
             GIMP_CAPTCHA_ENABLED
             GIMP_CAPTCHA_DIR
             GIMP_CAPTCHA_HMAC_KEYFILE
             GIMP_CAPTCHA_RSA_KEYFILE
             SERVER_PUBLIC_FQDN
             CSP_ENABLED
             CSP_REPORT_ONLY
             CSP_INCLUDE_SELF
    :type distributor: :class:`bridgedb.distributors.https.distributor.HTTPSDistributor`
    :param distributor: A bridge distributor.
    :raises SystemExit: if the servers cannot be started.
    :rtype: :api:`twisted.web.server.Site`
    :returns: A webserver.
    """
    captcha = None
    fwdHeaders = config.HTTP_USE_IP_FROM_FORWARDED_HEADER
    numBridges = config.HTTPS_N_BRIDGES_PER_ANSWER
    fprInclude = config.HTTPS_INCLUDE_FINGERPRINTS

    logging.info("Starting web servers...")

    setFQDN(config.SERVER_PUBLIC_FQDN)

    index   = IndexResource()
    options = OptionsResource()
    howto   = HowtoResource()
    robots  = static.File(os.path.join(TEMPLATE_DIR, 'robots.txt'))
    assets  = static.File(os.path.join(TEMPLATE_DIR, 'assets/'))
    keys    = static.Data(bytes(strings.BRIDGEDB_OPENPGP_KEY), 'text/plain')
    csp     = CSPResource(enabled=config.CSP_ENABLED,
                          includeSelf=config.CSP_INCLUDE_SELF,
                          reportViolations=config.CSP_REPORT_ONLY,
                          useForwardedHeader=fwdHeaders)

    root = CustomErrorHandlingResource()
    root.putChild('', index)
    root.putChild('robots.txt', robots)
    root.putChild('keys', keys)
    root.putChild('assets', assets)
    root.putChild('options', options)
    root.putChild('howto', howto)
    root.putChild('maintenance', maintenance)
    root.putChild('error', resource500)
    root.putChild(CSPResource.reportURI, csp)

    if config.RECAPTCHA_ENABLED:
        publicKey = config.RECAPTCHA_PUB_KEY
        secretKey = config.RECAPTCHA_SEC_KEY
        captcha = partial(ReCaptchaProtectedResource,
                          remoteIP=config.RECAPTCHA_REMOTEIP)
    elif config.GIMP_CAPTCHA_ENABLED:
        # Get the master HMAC secret key for CAPTCHA challenges, and then
        # create a new HMAC key from it for use on the server.
        captchaKey = crypto.getKey(config.GIMP_CAPTCHA_HMAC_KEYFILE)
        hmacKey = crypto.getHMAC(captchaKey, "Captcha-Key")
        # Load or create our encryption keys:
        secretKey, publicKey = crypto.getRSAKey(config.GIMP_CAPTCHA_RSA_KEYFILE)
        captcha = partial(GimpCaptchaProtectedResource,
                          hmacKey=hmacKey,
                          captchaDir=config.GIMP_CAPTCHA_DIR)

    if config.HTTPS_ROTATION_PERIOD:
        count, period = config.HTTPS_ROTATION_PERIOD.split()
        sched = ScheduledInterval(count, period)
    else:
        sched = Unscheduled()

    bridges = BridgesResource(distributor, sched, numBridges, fwdHeaders,
                              includeFingerprints=fprInclude)
    if captcha:
        # Protect the 'bridges' page with a CAPTCHA, if configured to do so:
        protected = captcha(publicKey=publicKey,
                            secretKey=secretKey,
                            useForwardedHeader=fwdHeaders,
                            protectedResource=bridges)
        root.putChild('bridges', protected)
        logging.info("Protecting resources with %s." % captcha.func.__name__)
    else:
        root.putChild('bridges', bridges)

    site = Site(root)
    site.displayTracebacks = False

    if config.HTTP_UNENCRYPTED_PORT:  # pragma: no cover
        ip = config.HTTP_UNENCRYPTED_BIND_IP or ""
        port = config.HTTP_UNENCRYPTED_PORT or 80
        try:
            reactor.listenTCP(port, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTP server on %s:%d" % (str(ip), int(port)))

    if config.HTTPS_PORT:  # pragma: no cover
        ip = config.HTTPS_BIND_IP or ""
        port = config.HTTPS_PORT or 443
        try:
            from twisted.internet.ssl import DefaultOpenSSLContextFactory
            factory = DefaultOpenSSLContextFactory(config.HTTPS_KEY_FILE,
                                                   config.HTTPS_CERT_FILE)
            reactor.listenSSL(port, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started HTTPS server on %s:%d" % (str(ip), int(port)))

    return site
Esempio n. 10
0
def addMoatServer(config, distributor):
    """Set up a web server for moat bridge distribution.

    :type config: :class:`bridgedb.persistent.Conf`
    :param config: A configuration object from
         :mod:`bridgedb.main`. Currently, we use these options::
             GIMP_CAPTCHA_DIR
             SERVER_PUBLIC_FQDN
             SUPPORTED_TRANSPORTS
             MOAT_DIST
             MOAT_DIST_VIA_MEEK_ONLY
             MOAT_TLS_CERT_FILE
             MOAT_TLS_KEY_FILE
             MOAT_SERVER_PUBLIC_ROOT
             MOAT_HTTPS_IP
             MOAT_HTTPS_PORT
             MOAT_HTTP_IP
             MOAT_HTTP_PORT
             MOAT_BRIDGES_PER_ANSWER
             MOAT_TRANSPORT_PREFERENCE_LIST
             MOAT_USE_IP_FROM_FORWARDED_HEADER
             MOAT_SKIP_LOOPBACK_ADDRESSES
             MOAT_ROTATION_PERIOD
             MOAT_GIMP_CAPTCHA_HMAC_KEYFILE
             MOAT_GIMP_CAPTCHA_RSA_KEYFILE
    :type distributor: :class:`bridgedb.distributors.moat.distributor.MoatDistributor`
    :param distributor: A bridge distributor.
    :raises SystemExit: if the servers cannot be started.
    :rtype: :api:`twisted.web.server.Site`
    :returns: A webserver.
    """
    captcha = None
    fwdHeaders = config.MOAT_USE_IP_FROM_FORWARDED_HEADER
    numBridges = config.MOAT_BRIDGES_PER_ANSWER
    skipLoopback = config.MOAT_SKIP_LOOPBACK_ADDRESSES

    logging.info("Starting moat servers...")

    setFQDN(config.SERVER_PUBLIC_FQDN)
    setRoot(config.MOAT_SERVER_PUBLIC_ROOT)
    setSupportedTransports(config.SUPPORTED_TRANSPORTS)
    setPreferredTransports(config.MOAT_TRANSPORT_PREFERENCE_LIST)

    # Get the master HMAC secret key for CAPTCHA challenges, and then
    # create a new HMAC key from it for use on the server.
    captchaKey = crypto.getKey(config.MOAT_GIMP_CAPTCHA_HMAC_KEYFILE)
    hmacKey = crypto.getHMAC(captchaKey, "Moat-Captcha-Key")
    # Load or create our encryption keys:
    secretKey, publicKey = crypto.getRSAKey(
        config.MOAT_GIMP_CAPTCHA_RSA_KEYFILE)
    sched = Unscheduled()

    if config.MOAT_ROTATION_PERIOD:
        count, period = config.MOAT_ROTATION_PERIOD.split()
        sched = ScheduledInterval(count, period)

    sitePublicDir = getRoot()

    meek = CustomErrorHandlingResource()
    moat = CustomErrorHandlingResource()
    fetch = CaptchaFetchResource(hmacKey, publicKey, secretKey,
                                 config.GIMP_CAPTCHA_DIR, fwdHeaders,
                                 skipLoopback)
    check = CaptchaCheckResource(distributor, sched, numBridges, hmacKey,
                                 publicKey, secretKey, fwdHeaders,
                                 skipLoopback)

    moat.putChild(b"fetch", fetch)
    moat.putChild(b"check", check)
    meek.putChild(b"moat", moat)

    root = CustomErrorHandlingResource()
    root.putChild(b"meek", meek)
    root.putChild(b"moat", moat)

    site = Site(root)
    site.displayTracebacks = False

    if config.MOAT_HTTP_PORT:  # pragma: no cover
        ip = config.MOAT_HTTP_IP or ""
        port = config.MOAT_HTTP_PORT or 80
        try:
            reactor.listenTCP(port, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started Moat HTTP server on %s:%d" %
                     (str(ip), int(port)))

    if config.MOAT_HTTPS_PORT:  # pragma: no cover
        ip = config.MOAT_HTTPS_IP or ""
        port = config.MOAT_HTTPS_PORT or 443
        try:
            from twisted.internet.ssl import DefaultOpenSSLContextFactory
            factory = DefaultOpenSSLContextFactory(config.MOAT_TLS_KEY_FILE,
                                                   config.MOAT_TLS_CERT_FILE)
            reactor.listenSSL(port, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started Moat TLS server on %s:%d" % (str(ip), int(port)))

    return site
Esempio n. 11
0
def addMoatServer(config, distributor):
    """Set up a web server for moat bridge distribution.

    :type config: :class:`bridgedb.persistent.Conf`
    :param config: A configuration object from
         :mod:`bridgedb.main`. Currently, we use these options::
             GIMP_CAPTCHA_DIR
             SERVER_PUBLIC_FQDN
             SUPPORTED_TRANSPORTS
             MOAT_DIST
             MOAT_DIST_VIA_MEEK_ONLY
             MOAT_TLS_CERT_FILE
             MOAT_TLS_KEY_FILE
             MOAT_SERVER_PUBLIC_ROOT
             MOAT_HTTPS_IP
             MOAT_HTTPS_PORT
             MOAT_HTTP_IP
             MOAT_HTTP_PORT
             MOAT_BRIDGES_PER_ANSWER
             MOAT_TRANSPORT_PREFERENCE_LIST
             MOAT_USE_IP_FROM_FORWARDED_HEADER
             MOAT_SKIP_LOOPBACK_ADDRESSES
             MOAT_ROTATION_PERIOD
             MOAT_GIMP_CAPTCHA_HMAC_KEYFILE
             MOAT_GIMP_CAPTCHA_RSA_KEYFILE
    :type distributor: :class:`bridgedb.distributors.moat.distributor.MoatDistributor`
    :param distributor: A bridge distributor.
    :raises SystemExit: if the servers cannot be started.
    :rtype: :api:`twisted.web.server.Site`
    :returns: A webserver.
    """
    captcha = None
    fwdHeaders = config.MOAT_USE_IP_FROM_FORWARDED_HEADER
    numBridges = config.MOAT_BRIDGES_PER_ANSWER
    skipLoopback = config.MOAT_SKIP_LOOPBACK_ADDRESSES

    logging.info("Starting moat servers...")

    setFQDN(config.SERVER_PUBLIC_FQDN)
    setRoot(config.MOAT_SERVER_PUBLIC_ROOT)
    setSupportedTransports(config.SUPPORTED_TRANSPORTS)
    setPreferredTransports(config.MOAT_TRANSPORT_PREFERENCE_LIST)

    # Get the master HMAC secret key for CAPTCHA challenges, and then
    # create a new HMAC key from it for use on the server.
    captchaKey = crypto.getKey(config.MOAT_GIMP_CAPTCHA_HMAC_KEYFILE)
    hmacKey = crypto.getHMAC(captchaKey, "Moat-Captcha-Key")
    # Load or create our encryption keys:
    secretKey, publicKey = crypto.getRSAKey(config.MOAT_GIMP_CAPTCHA_RSA_KEYFILE)
    sched = Unscheduled()

    if config.MOAT_ROTATION_PERIOD:
        count, period = config.MOAT_ROTATION_PERIOD.split()
        sched = ScheduledInterval(count, period)

    sitePublicDir = getRoot()

    meek = CustomErrorHandlingResource()
    moat = CustomErrorHandlingResource()
    fetch = CaptchaFetchResource(hmacKey, publicKey, secretKey,
                                 config.GIMP_CAPTCHA_DIR,
                                 fwdHeaders, skipLoopback)
    check = CaptchaCheckResource(distributor, sched, numBridges,
                                 hmacKey, publicKey, secretKey,
                                 fwdHeaders, skipLoopback)

    moat.putChild("fetch", fetch)
    moat.putChild("check", check)
    meek.putChild("moat", moat)

    root = CustomErrorHandlingResource()
    root.putChild("meek", meek)
    root.putChild("moat", moat)

    site = Site(root)
    site.displayTracebacks = False

    if config.MOAT_HTTP_PORT:  # pragma: no cover
        ip = config.MOAT_HTTP_IP or ""
        port = config.MOAT_HTTP_PORT or 80
        try:
            reactor.listenTCP(port, site, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started Moat HTTP server on %s:%d" % (str(ip), int(port)))

    if config.MOAT_HTTPS_PORT:  # pragma: no cover
        ip = config.MOAT_HTTPS_IP or ""
        port = config.MOAT_HTTPS_PORT or 443
        try:
            from twisted.internet.ssl import DefaultOpenSSLContextFactory
            factory = DefaultOpenSSLContextFactory(config.MOAT_TLS_KEY_FILE,
                                                   config.MOAT_TLS_CERT_FILE)
            reactor.listenSSL(port, site, factory, interface=ip)
        except CannotListenError as error:
            raise SystemExit(error)
        logging.info("Started Moat TLS server on %s:%d" % (str(ip), int(port)))

    return site