Пример #1
0
def basic_auth():
    auth = request.authorization
    username = current_app.config['DM_API_ADMIN_USERNAME']
    password = current_app.config['DM_API_ADMIN_PASSWORD']
    if username is None:
        return
    if auth and auth.type == 'basic' and \
            streql.equals(auth.username, username) and streql.equals(auth.password, password):
        return
    return Response(status=401, headers={'WWW-Authenticate': 'Basic realm="DMP Admin"'})
Пример #2
0
def basic_auth():
    auth = request.authorization
    username = current_app.config['DM_API_ADMIN_USERNAME']
    password = current_app.config['DM_API_ADMIN_PASSWORD']
    if username is None:
        return
    if auth and auth.type == 'basic' and \
            streql.equals(auth.username, username) and streql.equals(auth.password, password):
        return
    return Response(status=401,
                    headers={'WWW-Authenticate': 'Basic realm="DMP Admin"'})
Пример #3
0
    def on_post(self, req, resp):
        token = req.headers.get('X-GITLAB-TOKEN')
        if not token or not equals(token, GITLAB_TOKEN):
            raise falcon.HTTPBadRequest('Yoyo', '')

        try:
            data = ujson.load(req.stream)
        except:
            raise falcon.HTTPBadRequest('Bad body', '')
        logger.debug('Got webhook request: %s', data)

        if data['object_kind'] != 'pipeline':
            resp.body = '["meh"]'
            return

        commit = data['commit']
        attributes = data['object_attributes']
        status = attributes['status']
        logger.info('Processing pipeline event %s, status: %s, commit: %s, '
                    'commit message:\n%s',
                    attributes['id'], status, commit['id'], commit['message'])

        if status == 'success' or status == 'failed':
            # build finished, download as many artifacts as possible
            for build in data['builds']:
                logger.info('Processing build %s(%s), status: %s...',
                            build['name'], build['id'], build['status'])
                if build['status'] != 'success':
                    continue
                build_fetch_queue.put(build)
        resp.body = '["ok"]'
Пример #4
0
 def decorated(*args, **kwargs):
     """Check the header."""
     token = request.headers.get("x-ersa-auth-token", "")
     if streql.equals(token, app.config["ERSA_AUTH_TOKEN"]):
         return func(*args, **kwargs)
     else:
         return "", 401
Пример #5
0
def is_client_digest_valid(client_digest, api_key, window, method, path, body):
    text = '%s %s %s %s' % (window, method, path, body)
    HMAC = hmac.new(api_key, text, hashlib.sha512)
    digest = base64.urlsafe_b64encode(HMAC.digest())
    if equals(client_digest, digest):
        return True
    return False
Пример #6
0
 def render_POST(self, request):
     bootstrap_token = os.environ.get("BOOTSTRAP_TOKEN")
     data = json.loads(request.content.read())
     if streql.equals(data["bootstrap_token"].encode("ascii"),
                      bootstrap_token):
         # authenticated!
         pass
Пример #7
0
def verify_tag(ciphertext, key):
	"""Verify the tag on a ciphertext."""
	tag_start = len(ciphertext) - __TAG_LEN
	data = ciphertext[:tag_start]
	tag = ciphertext[tag_start:]
	actual_tag = new_tag(data, key)
	return streql.equals(actual_tag, tag)
Пример #8
0
def verify_tag(ciphertext, key):
    """Verify the tag on a ciphertext."""
    tag_start = len(ciphertext) - __TAG_LEN
    data = ciphertext[:tag_start]
    tag = ciphertext[tag_start:]
    actual_tag = new_tag(data, key)
    return streql.equals(actual_tag, tag)
Пример #9
0
    def process_request(self, req, resp):
        # http basic auth
        if self.config['server'].get('enable_basic_auth'):
            hdr_auth = req.get_header('AUTHORIZATION')
            if not hdr_auth:
                raise falcon.HTTPUnauthorized('Access denied',
                                              'No auth header', [])

            auth = re.sub('^Basic ', '', hdr_auth)
            usr, pwd = decodestring(auth).split(':')
            if not equals(self.basic_auth.get(usr, ''), pwd):
                logger.warning('basic auth failure: %s', usr)
                raise falcon.HTTPUnauthorized('Access denied',
                                              'Basic auth failure', [])

        segments = req.path.strip('/').split('/')
        if segments[0] == 'api':
            if len(segments) >= 3:
                # twilio validation
                if segments[2] == 'twilio':
                    sig = req.get_header('X_TWILIO_SIGNATURE')
                    if sig is None:
                        logger.warning("no twilio signature found!")
                        raise falcon.HTTPUnauthorized('Access denied',
                                                      'No Twilio signature',
                                                      [])
                    uri = [
                        req.protocol, '://',
                        req.get_header('HOST'),
                        self.config['server'].get('lb_routing_path',
                                                  ''), req.path
                    ]
                    if req.query_string:
                        uri.append('?')
                        uri.append(req.query_string)
                    post_body = req.context['body']
                    expected_sigs = [
                        compute_signature(t, ''.join(uri), post_body)
                        for t in self.twilio_auth_token
                    ]
                    if sig not in expected_sigs:
                        logger.warning(
                            'twilio validation failure: %s not in possible sigs: %s',
                            sig, expected_sigs)
                        raise falcon.HTTPUnauthorized('Access denied',
                                                      'Twilio auth failure',
                                                      [])
                    return
                elif segments[2] == 'gmail' or segments[
                        2] == 'gmail-oneclick' or segments[2] == 'slack':
                    return
        elif len(segments) == 1:
            if segments[0] == 'health' or segments[0] == 'healthcheck':
                return
            elif segments[0] == self.config['gmail'].get('verification_code'):
                return

        raise falcon.HTTPUnauthorized('Access denied', 'Authentication failed',
                                      [])
Пример #10
0
    def verify_tag(self, data):
        pkt_data = data[:len(data)-SHA384_LEN]
        pkt_tag = data[len(data)-SHA384_LEN:]
        tag = HMAC.new(self.hmac_rxkey, msg=pkt_data, digestmod=SHA384).digest()[:SHA384_LEN]

        if NOSTREQL == True:
            return local_streql(pkt_tag, tag)
        else:
            return streql.equals(pkt_tag, tag)
Пример #11
0
    def verify_tag(self, data):
        pkt_data = data[:len(data) - SHA384_LEN]
        pkt_tag = data[len(data) - SHA384_LEN:]
        tag = HMAC.new(self.hmac_rxkey, msg=pkt_data,
                       digestmod=SHA384).digest()[:SHA384_LEN]

        if NOSTREQL == True:
            return local_streql(pkt_tag, tag)
        else:
            return streql.equals(pkt_tag, tag)
Пример #12
0
 def testEqualStrings(self):
   self.assertTrue(equals(b('foo'), b('foo')))
   self.assertTrue(equals(u('foo'), u('foo')))
   self.assertTrue(equals(b('foo'), u('foo')))
   self.assertTrue(equals(u('foo'), b('foo')))
   self.assertTrue(equals('hello'*1000, 'hello'*1000))
   if PYTHON3:
     self.assertTrue(equals(bytes('hello\xa0world', 'utf8'), 'hello\xa0world'))
   else:
     self.assertTrue(equals('hello\xc2\xa0world', 'hello\xc2\xa0world'.decode('utf8')))
Пример #13
0
 def testWithEmptyStrings(self):
   self.assertTrue(equals(b(''), b('')))
   self.assertFalse(equals(b('a'), b('')))
   self.assertFalse(equals(b(''), b('a')))
   self.assertTrue(equals(u(''), u('')))
   self.assertFalse(equals(u('a'), u('')))
   self.assertFalse(equals(u(''), u('a')))
Пример #14
0
  def does_password_match(self, password):
    """Checks if the given password matches the given admin user.

    Agrs:
      password: The password to check an admin user by.

    Returns:
      True if the password matches the admin user and False otherwise.
    """
    hashed = bcrypt.hashpw(password.encode('utf-8'), self.password.encode('utf-8'))
    # streql is a constant time string comparison tool to prevent timing-based
    # attacks. See here for more info: https://github.com/PeterScott/streql
    return streql.equals(hashed, self.password)
    def verify_payload(signed_payload, client_secret):
        """
        Given a signed payload (usually passed as parameter in a GET request to the app's load URL) and a client secret,
        authenticates the payload and returns the user's data, or False on fail.

        Uses constant-time str comparison to prevent vulnerability to timing attacks.
        """
        encoded_json, encoded_hmac = signed_payload.split('.')
        dc_json = base64.b64decode(encoded_json)
        signature = base64.b64decode(encoded_hmac)
        expected_sig = hmac.new(client_secret.encode(), base64.b64decode(encoded_json), hashlib.sha256).hexdigest()
        authorised = streql.equals(signature, expected_sig)
        return json.loads(dc_json.decode()) if authorised else False
Пример #16
0
def xsrf_protect():
  """Verifies that an xsrf token is included for all non-get requests

  Slight modification of http://flask.pocoo.org/snippets/3/
  """
  if ufo.app.config['TESTING']:
    return

  if flask.request.method == 'GET':
    return

  token = flask.session['_xsrf_token']
  if not token or not streql.equals(token, flask.request.form.get('_xsrf_token')):
    flask.abort(403)
Пример #17
0
    def does_password_match(self, password):
        """Checks if the given password matches the given admin user.

    Agrs:
      password: The password to check an admin user by.

    Returns:
      True if the password matches the admin user and False otherwise.
    """
        hashed = bcrypt.hashpw(password.encode('utf-8'),
                               self.password.encode('utf-8'))
        # streql is a constant time string comparison tool to prevent timing-based
        # attacks. See here for more info: https://github.com/PeterScott/streql
        return streql.equals(hashed, self.password)
    def verify_payload(signed_payload, client_secret):
        """
        Given a signed payload (usually passed as parameter in a GET request to the app's load URL) and a client secret,
        authenticates the payload and returns the user's data, or False on fail.

        Uses constant-time str comparison to prevent vulnerability to timing attacks.
        """
        encoded_json, encoded_hmac = signed_payload.split('.')
        dc_json = base64.b64decode(encoded_json)
        signature = base64.b64decode(encoded_hmac)
        expected_sig = hmac.new(client_secret.encode(),
                                base64.b64decode(encoded_json),
                                hashlib.sha256).hexdigest()
        authorised = streql.equals(signature, expected_sig)
        return json.loads(dc_json.decode()) if authorised else False
Пример #19
0
    def check_api_key(self):
        """Checks whether the requester client has successfully proved its
        identity.

        By default this check consists on comparing the
        ``X-Backend-Key`` request header value with the key stablished in
        :py:attr:`api_key` when this object is created.
        """
        try:
            key = self.request.headers["X-Backend-Key"]
        except KeyError:
            raise HTTPError(401, "Missing X-Backend-Key header")

        if not equals(key, self.api_key):
            raise HTTPError(401, "Invalid API key")
def validate_password(password, correct_hash):
    if isinstance(password, six.text_type):
        password = password.encode('utf-8')

    params = correct_hash.split(b':')
    if len(params) != 4:
        return False

    algorithm = params[0].decode('utf-8')
    iterations = int(params[1])
    salt = params[2]
    hash = base64.b64decode(params[3])

    computed_hash = hashlib.pbkdf2_hmac(
        algorithm, password, salt, iterations)[0:len(hash)]

    return streql.equals(hash, computed_hash)
Пример #21
0
    def on_post(self, req, resp):
        token = req.headers.get('X-GITLAB-TOKEN')
        if not token or not equals(token, GITLAB_TOKEN):
            raise falcon.HTTPBadRequest('Yoyo', '')

        try:
            data = ujson.load(req.stream)
        except:
            raise falcon.HTTPBadRequest('Bad body', '')
        logger.debug('Got webhook request: %s', data)

        if data['object_kind'] != 'pipeline':
            resp.body = '["meh"]'
            return

        commit = data['commit']
        attributes = data['object_attributes']
        status = attributes['status']
        logger.info(
            'Processing pipeline event %s, status: %s, commit: %s, '
            'commit message:\n%s', attributes['id'], status, commit['id'],
            commit['message'])

        if status == 'success' or status == 'failed':
            # build finished, download as many artifacts as possible
            for build in data['builds']:
                if not build['name'].startswith('build_'):
                    logger.debug(
                        'Skipping non-build job %s(%s), status: %s...',
                        build['name'], build['id'], build['status'])
                    continue
                logger.info('Processing build %s(%s), status: %s...',
                            build['name'], build['id'], build['status'])
                if build['status'] != 'success':
                    continue
                build_fetch_queue.put(build)
        resp.body = '["ok"]'
Пример #22
0
    def process_request(self, req, resp):
        if self.debug:
            return
        # CORS Pre-flight
        if req.method == 'OPTIONS':
            resp.status = falcon.HTTP_204
            return
        # http basic auth
        if self.config['server'].get('enable_basic_auth'):
            hdr_auth = req.get_header('AUTHORIZATION')
            if not hdr_auth:
                raise falcon.HTTPUnauthorized('Access denied',
                                              'No auth header', [])

            auth = re.sub('^Basic ', '', hdr_auth)
            usr, pwd = decodestring(auth).split(':')
            if not equals(self.basic_auth.get(usr, ''), pwd):
                logger.warning('basic auth failure: %s', usr)
                raise falcon.HTTPUnauthorized('Access denied',
                                              'Basic auth failure', [])

        segments = req.path.strip('/').split('/')
        if segments[0] == 'api':
            if len(segments) >= 3:
                # twilio validation
                if segments[2] == 'twilio':
                    sig = req.get_header('X_TWILIO_SIGNATURE')
                    if sig is None:
                        logger.warning("no twilio signature found!")
                        raise falcon.HTTPUnauthorized('Access denied',
                                                      'No Twilio signature',
                                                      [])
                    uri = [
                        req.protocol, '://',
                        req.get_header('HOST'),
                        self.config['server'].get('lb_routing_path',
                                                  ''), req.path
                    ]
                    if req.query_string:
                        uri.append('?')
                        uri.append(req.query_string)
                    post_body = req.context['body']
                    expected_sigs = [
                        compute_signature(t, ''.join(uri), post_body)
                        for t in self.twilio_auth_token
                    ]
                    sig = sig.encode('utf8')
                    if sig not in expected_sigs:
                        logger.warning(
                            'twilio validation failure: %s not in possible sigs: %s',
                            sig, expected_sigs)
                        raise falcon.HTTPUnauthorized('Access denied',
                                                      'Twilio auth failure',
                                                      [])
                    return
                elif self.mobile and (segments[2] == 'mobile'
                                      or segments[2] == 'oncall'):
                    # Only allow refresh tokens for /refresh, only access for all else
                    table = 'refresh_token' if segments[
                        3] == 'refresh' else 'access_token'
                    key_query = '''SELECT `key`, `target`.`name`
                                   FROM `%s` JOIN `target` ON `user_id` = `target`.`id`
                                   WHERE `%s`.`id` = %%s
                                   AND `expiration` > %%s''' % (table, table)
                    method = req.method
                    auth = req.get_header('Authorization', required=True)

                    items = urllib2.parse_http_list(auth)
                    parts = urllib2.parse_keqv_list(items)

                    if 'signature' not in parts or 'keyId' not in parts or 'timestamp' not in parts:
                        raise falcon.HTTPUnauthorized(
                            'Authentication failure: invalid header')

                    try:
                        window = int(parts['timestamp'])
                        time_diff = abs(time.time() - window)
                    except ValueError:
                        raise falcon.HTTPUnauthorized(
                            'Authentication failure: invalid header')
                    client_digest = parts['signature']
                    key_id = parts['keyId']
                    body = req.context['body'].decode('utf8')
                    path = req.env['PATH_INFO']
                    qs = req.env['QUERY_STRING']
                    if qs:
                        path = path + '?' + qs
                    text = '%s %s %s %s' % (window, method, path, body)
                    text = text.encode('utf8')

                    conn = db.connect()
                    cursor = conn.cursor()
                    cursor.execute(key_query, (key_id, time.time()))
                    row = cursor.fetchone()
                    conn.close()
                    # make sure that there exists a row for the corresponding username
                    if row is None:
                        raise falcon.HTTPUnauthorized(
                            'Authentication failure: server')
                    key = self.fernet.decrypt(str(row[0]).encode('utf8'))
                    key = key
                    req.context['user'] = row[1]

                    HMAC = hmac.new(key, text, hashlib.sha512)
                    digest = urlsafe_b64encode(HMAC.digest())

                    if hmac.compare_digest(
                            client_digest.encode('utf8'),
                            digest) and time_diff < self.time_window:
                        return
                    else:
                        raise falcon.HTTPUnauthorized(
                            'Authentication failure: server')
                elif segments[2] == 'gmail' or segments[
                        2] == 'gmail-oneclick' or segments[
                            2] == 'slack' or segments[2] == 'ical':
                    return
        elif len(segments) == 1:
            if segments[0] == 'health' or segments[0] == 'healthcheck':
                return
            elif segments[0] == self.config.get('gmail',
                                                {}).get('verification_code'):
                return

        elif segments[0] == 'saml':
            return
        raise falcon.HTTPUnauthorized('Access denied', 'Authentication failed',
                                      [])
Пример #23
0
 def valid_token(self, token):
     return equals(self.verification_token, token)
Пример #24
0
 def testUnequalStrings(self):
   self.assertFalse(equals(b('foo'), b('bar')))
   self.assertFalse(equals(u('foo'), u('bar')))
   self.assertFalse(equals(b('hello, world!'), b('hello, world.')))
   self.assertFalse(equals(b('aaa'), b('aa')))
   self.assertFalse(equals(u('aaa'), u('aa')))
Пример #25
0
 def sig_verify(self, plaintext, signature):
     '''
     Verify a signature, by comparing it against a new signature
     of the same source data.
     '''
     return streql.equals(signature.export(), self.sign(plaintext).export())
Пример #26
0
 def verify_tag(self, data):
     pkt_data = data[:len(data)-SHA384_LEN]
     pkt_tag = data[len(data)-SHA384_LEN:]
     tag = HMAC.new(self.key, msg=pkt_data, digestmod=SHA384).digest()[:SHA384_LEN]
     return streql.equals(pkt_tag, tag)
Пример #27
0
 def render_POST(self, request):
     bootstrap_token = os.environ.get("BOOTSTRAP_TOKEN")
     data = json.loads(request.content.read())
     if streql.equals(data["bootstrap_token"].encode("ascii"), bootstrap_token):
         # authenticated!
         pass