Beispiel #1
0
    def _prepare_artifacts(self, attributes):
        """Converts the request and attributes into an artifacts dict."""
        artifacts = {
            "method": self.req["method"],
            "host": self.req["host"],
            "port": self.req["port"],
            "resource": util.parse_normalized_url(self.req["url"])["resource"],
        }
        artifact_keys = ["ts", "nonce", "hash", "ext", "app", "dlg", "mac", "id"]

        attrs = attributes.keys()
        for key in artifact_keys:
            if key in attrs:
                artifacts[key] = attributes[key]
            else:
                # I think we want empty strings in normalized header mac
                artifacts[key] = ""
        return artifacts
Beispiel #2
0
    def _prepare_artifacts(self, attributes):
        """Converts the request and attributes into an artifacts dict."""
        artifacts = {
            'method': self.req['method'],
            'host': self.req['host'],
            'port': self.req['port'],
            'resource': util.parse_normalized_url(self.req['url'])['resource'],
        }
        artifact_keys = ['ts', 'nonce', 'hash', 'ext',
                         'app', 'dlg', 'mac', 'id']

        attrs = attributes.keys()
        for key in artifact_keys:
            if key in attrs:
                artifacts[key] = attributes[key]
            else:
                # I think we want empty strings in normalized header mac
                artifacts[key] = ''
        return artifacts
    def _prepare_artifacts(self, attributes):
        """Converts the request and attributes into an artifacts dict."""
        artifacts = {
            'method': self.req['method'],
            'host': self.req['host'],
            'port': self.req['port'],
            'resource': util.parse_normalized_url(self.req['url'])['resource'],
        }
        artifact_keys = [
            'ts', 'nonce', 'hash', 'ext', 'app', 'dlg', 'mac', 'id'
        ]

        attrs = attributes.keys()
        for key in artifact_keys:
            if key in attrs:
                artifacts[key] = attributes[key]
            else:
                # I think we want empty strings in normalized header mac
                artifacts[key] = ''
        return artifacts
def get_bewit(uri, options=None):
    # XXX Where is credentials here?
    """
    Generate a bewit value for a given URI

    Compatibility Note: HAWK exposes this as hawk.uri.getBewit

    credentials is an object with the following keys: 'id, 'key',
    'algorithm'.

    options is an object with the following optional keys: 'ext',
    'localtime_offset_msec'

    uri: 'http://example.com/resource?a=b' or object from Url.parse()
    options: {

    Required

    credentials: {
    id: 'dh37fgj492je',
    key: 'aoijedoaijsdlaksjdl',
    algorithm: 'sha256'              // 'sha1', 'sha256'
    },
    ttl_sec: 60 * 60,                    // TTL in seconds

    Optional

    ext: 'application-specific',         // Application specific data
    // sent via the ext attribute.
    localtime_offset_msec: 400           // Time offset to sync with
    // server time
    }
    """

    if not valid_bewit_args(uri, options):
        return ''

    now = time.time() + int(options['localtime_offset_msec'])

    creds = options['credentials']
    if 'id' not in creds or 'key' not in creds or 'algorithm' not in creds:
        raise BadRequest

    url_parts = util.parse_normalized_url(uri)

    exp = now + int(options['ttl_sec'])

    resource = url_parts['path']
    if len(url_parts['query']) > 0:
        resource += '?' + url_parts['query']

    artifacts = {
        'ts': int(exp),
        'nonce': '',
        'method': 'GET',
        'resource': resource,
        'host': url_parts['hostname'],
        'port': str(url_parts['port']),
        'ext': options['ext']
    }

    return hcrypto.calculate_bewit(creds, artifacts, exp)
def header(url, method, options=None):
    """
    :param uri: 'http://example.com/resource?a=b'
    :param method: HTTP verb ('GET', 'POST', etc)
    :param options:

    Required Options:
    credentials (id, key, algorithm)

    Optional:
    ext:
    Application specific data (string)
    timestamp:
    A pre-calculated timestamp
    nonce:
    '2334f34f':  A pre-generated nonce
    localtimeOffsetMsec:
    Time offset to sync with server time (ignored if timestamp
    provided) (Example 400)
    payload:
    UTF-8 encoded string for body hash generation (ignored if hash
    provided) (Example '{"some":"payload"}')
    contentType:
    Payload content-type (ignored if hash provided) (Example
    'application/json')
    hash:
    Pre-calculated payload hash (Example 'U4MKKSmiVxk37JCCrAVIjV=')
    app:
    Oz application id ('24s23423f34dx')
    dlg:
    Oz delegated-by application id - '234sz34tww3sd'
    """
    result = {'field': '', 'artifacts': {}}

    if url is None or len(url) == 0:
        log.info("Bad URL skipping")
        return result

    if method is None or len(method) == 0:
        log.info("Bad method skipping")
        return result

    if not isinstance(options, dict):
        log.info("Bad options skipping")
        return result

    if 'credentials' not in options:
        log.info("Bad credentials skipping")
        return result

    cred = options['credentials']
    if 'id' not in cred or 'key' not in cred or 'algorithm' not in cred:
        log.info("Bad credentail elements skipping")
        return result

    timestamp = math.floor(time.time())
    if 'timestamp' in options:
        offset = 0
        if 'localtimeOffsetMsec' in options:
            offset = int(options['localtimeOffsetMsec'])
        timestamp = math.floor(options['timestamp'] + offset)

    if 'nonce' not in options:
        options['nonce'] = hcrypto.random_string(6)

    url_parts = util.parse_normalized_url(url)

    # TODO use None or '' for these optional artifacts?
    if 'hash' not in options:
        options['hash'] = None
    if 'ext' not in options:
        options['ext'] = None
    if 'app' not in options:
        options['app'] = None
    if 'dlg' not in options:
        options['dlg'] = None

    resource = url_parts['resource']

    log.debug('parsed URL parts: %s' % pprint.pformat(url_parts))

    artifacts = {
        'ts': int(timestamp),
        'nonce': options['nonce'],
        'method': method,
        'resource': resource,
        'host': url_parts['hostname'],
        'port': url_parts['port'],
        'hash': options['hash'],
        'ext': options['ext'],
        'app': options['app'],
        'dlg': options['dlg']
    }

    result['artifacts'] = artifacts

    if artifacts['hash'] is None and 'payload' in options:
        if 'contentType' not in options:
            options['contentType'] = 'text/plain'
        log.debug('about to hash payload: %s' % options['payload'])
        log.debug('algorithm=%s, contentType=%s' %
                  (cred['algorithm'], options['contentType']))
        artifacts['hash'] = hcrypto.calculate_payload_hash(
            options['payload'], cred['algorithm'], options['contentType'])

    log.debug('artifacts=%s' % pprint.pformat(artifacts))

    mac = hcrypto.calculate_mac('header', cred, artifacts)

    _header = ''.join([
        'Hawk id="',
        cred['id'],
        '"',
        ', ts="',
        str(artifacts['ts']),
        '"',
        ', nonce="',
        artifacts['nonce'],
        '"',
    ])

    if len(artifacts['hash']) > 0:
        _header += ', hash="' + artifacts['hash'] + '"'

    if artifacts['ext'] is not None and len(artifacts['ext']) > 0:
        util.check_header_attribute(artifacts['ext'])
        h_ext = artifacts['ext'].replace('\\', '\\\\').replace('\n', '\\n')
        _header += ', ext="' + h_ext + '"'

    _header += ', mac="' + mac + '"'

    if artifacts['app'] is not None:
        _header += ', app="' + artifacts['app'] + '"'
        if artifacts['dlg'] is not None:
            _header += ', dlg="' + artifacts['dlg'] + '"'

    result['field'] = _header

    return result
Beispiel #6
0
def get_bewit(uri, options=None):
    # XXX Where is credentials here?
    """
    Generate a bewit value for a given URI

    Compatibility Note: HAWK exposes this as hawk.uri.getBewit

    credentials is an object with the following keys: 'id, 'key',
    'algorithm'.

    options is an object with the following optional keys: 'ext',
    'localtime_offset_msec'

    uri: 'http://example.com/resource?a=b' or object from Url.parse()
    options: {

    Required

    credentials: {
    id: 'dh37fgj492je',
    key: 'aoijedoaijsdlaksjdl',
    algorithm: 'sha256'              // 'sha1', 'sha256'
    },
    ttl_sec: 60 * 60,                    // TTL in seconds

    Optional

    ext: 'application-specific',         // Application specific data
    // sent via the ext attribute.
    localtime_offset_msec: 400           // Time offset to sync with
    // server time
    }
    """

    if not valid_bewit_args(uri, options):
        return ''

    now = time.time() + int(options['localtime_offset_msec'])

    creds = options['credentials']
    if 'id' not in creds or 'key' not in creds or 'algorithm' not in creds:
        raise BadRequest

    url_parts = util.parse_normalized_url(uri)

    exp = now + int(options['ttl_sec'])

    resource = url_parts['path']
    if len(url_parts['query']) > 0:
        resource += '?' + url_parts['query']

    artifacts = {
        'ts': int(exp),
        'nonce': '',
        'method': 'GET',
        'resource': resource,
        'host': url_parts['hostname'],
        'port': str(url_parts['port']),
        'ext': options['ext']
        }

    return hcrypto.calculate_bewit(creds, artifacts, exp)
Beispiel #7
0
def header(url, method, options=None):
    """
    :param uri: 'http://example.com/resource?a=b'
    :param method: HTTP verb ('GET', 'POST', etc)
    :param options:

    Required Options:
    credentials (id, key, algorithm)

    Optional:
    ext:
    Application specific data (string)
    timestamp:
    A pre-calculated timestamp
    nonce:
    '2334f34f':  A pre-generated nonce
    localtimeOffsetMsec:
    Time offset to sync with server time (ignored if timestamp
    provided) (Example 400)
    payload:
    UTF-8 encoded string for body hash generation (ignored if hash
    provided) (Example '{"some":"payload"}')
    contentType:
    Payload content-type (ignored if hash provided) (Example
    'application/json')
    hash:
    Pre-calculated payload hash (Example 'U4MKKSmiVxk37JCCrAVIjV=')
    app:
    Oz application id ('24s23423f34dx')
    dlg:
    Oz delegated-by application id - '234sz34tww3sd'
    """
    result = {'field': '', 'artifacts': {}}

    if url is None or len(url) == 0:
        log.info("Bad URL skipping")
        return result

    if method is None or len(method) == 0:
        log.info("Bad method skipping")
        return result

    if not isinstance(options, dict):
        log.info("Bad options skipping")
        return result

    if 'credentials' not in options:
        log.info("Bad credentials skipping")
        return result

    cred = options['credentials']
    if 'id' not in cred or 'key' not in cred or 'algorithm' not in cred:
        log.info("Bad credentail elements skipping")
        return result

    timestamp = math.floor(time.time())
    if 'timestamp' in options:
        offset = 0
        if 'localtimeOffsetMsec' in options:
            offset = int(options['localtimeOffsetMsec'])
        timestamp = math.floor(options['timestamp'] + offset)

    if 'nonce' not in options:
        options['nonce'] = hcrypto.random_string(6)

    url_parts = util.parse_normalized_url(url)

    # TODO use None or '' for these optional artifacts?
    if 'hash' not in options:
        options['hash'] = None
    if 'ext' not in options:
        options['ext'] = None
    if 'app' not in options:
        options['app'] = None
    if 'dlg' not in options:
        options['dlg'] = None

    resource = url_parts['resource']

    log.debug('parsed URL parts: %s' % pprint.pformat(url_parts))

    artifacts = {
        'ts': int(timestamp),
        'nonce': options['nonce'],
        'method': method,
        'resource': resource,
        'host': url_parts['hostname'],
        'port': url_parts['port'],
        'hash': options['hash'],
        'ext': options['ext'],
        'app': options['app'],
        'dlg': options['dlg']
    }

    result['artifacts'] = artifacts

    if artifacts['hash'] is None and 'payload' in options:
        if 'contentType' not in options:
            options['contentType'] = 'text/plain'
        log.debug('about to hash payload: %s' % options['payload'])
        log.debug('algorithm=%s, contentType=%s'
                  % (cred['algorithm'], options['contentType']))
        artifacts['hash'] = hcrypto.calculate_payload_hash(
               options['payload'], cred['algorithm'], options['contentType'])

    log.debug('artifacts=%s' % pprint.pformat(artifacts))

    mac = hcrypto.calculate_mac('header', cred, artifacts)

    _header = ''.join([
        'Hawk id="', cred['id'], '"',
        ', ts="', str(artifacts['ts']), '"',
        ', nonce="', artifacts['nonce'], '"',
    ])

    if len(artifacts['hash']) > 0:
        _header += ', hash="' + artifacts['hash'] + '"'

    if artifacts['ext'] is not None and len(artifacts['ext']) > 0:
        util.check_header_attribute(artifacts['ext'])
        h_ext = artifacts['ext'].replace('\\', '\\\\').replace('\n', '\\n')
        _header += ', ext="' + h_ext + '"'

    _header += ', mac="' + mac + '"'

    if artifacts['app'] is not None:
        _header += ', app="' + artifacts['app'] + '"'
        if artifacts['dlg'] is not None:
            _header += ', dlg="' + artifacts['dlg'] + '"'

    result['field'] = _header

    return result