Beispiel #1
0
 def set_value(self, values):
     if not self["mechanism"] in self.plain_mechs:
         if values:
             self.xml.text = bytes(base64.b64encode(values)).decode("utf-8")
         elif values == b"":
             self.xml.text = "="
     else:
         self.xml.text = bytes(values).decode("utf-8")
Beispiel #2
0
 def set_value(self, values):
     if not self['mechanism'] in self.plain_mechs:
         if values:
             self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
         elif values == b'':
             self.xml.text = '='
     else:
         self.xml.text = bytes(values).decode('utf-8')
Beispiel #3
0
 def set_value(self, values):
     if not self['mechanism'] in self.plain_mechs:
         if values:
             self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
         elif values == b'':
             self.xml.text = '='
     else:
         self.xml.text = bytes(values).decode('utf-8')
Beispiel #4
0
    def response(self, prefix=b''):
        nc = bytes('%08x' % self.nonce_count)

        a1 = bytes(self.hash(self.A1()).hexdigest().lower())
        a2 = bytes(self.hash(self.A2(prefix)).hexdigest().lower())
        s = self.nonce + b':' + nc + b':' + self.cnonce + \
                         b':' + self.qop + b':' + a2

        return bytes(self.hash(a1 + b':' + s).hexdigest().lower())
Beispiel #5
0
    def response(self, prefix=b''):
        nc = bytes('%08x' % self.nonce_count)

        a1 = bytes(self.hash(self.A1()).hexdigest().lower())
        a2 = bytes(self.hash(self.A2(prefix)).hexdigest().lower())
        s = self.nonce + b':' + nc + b':' + self.cnonce + \
                         b':' + self.qop + b':' + a2

        return bytes(self.hash(a1 + b':' + s).hexdigest().lower())
Beispiel #6
0
def choose(mech_list,
           credentials,
           security_settings,
           limit=None,
           min_mech=None):
    available_mechs = set(MECHANISMS.keys())
    if limit is None:
        limit = set(mech_list)
    if not isinstance(limit, set):
        limit = set(limit)
    if not isinstance(mech_list, set):
        mech_list = set(mech_list)

    mech_list = mech_list.intersection(limit)
    available_mechs = available_mechs.intersection(mech_list)

    best_score = MECH_SEC_SCORES.get(min_mech, -1)
    best_mech = None
    for name in available_mechs:
        if name in MECH_SEC_SCORES:
            if MECH_SEC_SCORES[name] > best_score:
                best_score = MECH_SEC_SCORES[name]
                best_mech = name
    if best_mech is None:
        raise SASLNoAppropriateMechanism()

    mech_class = MECHANISMS[best_mech]

    try:
        creds = credentials(mech_class.required_credentials,
                            mech_class.optional_credentials)
        for req in mech_class.required_credentials:
            if req not in creds:
                raise SASLCancelled('Missing credential: %s' % req)
        for opt in mech_class.optional_credentials:
            if opt not in creds:
                creds[opt] = b''
        for cred in creds:
            if cred in ('username', 'password', 'authzid'):
                creds[cred] = bytes(saslprep(creds[cred]))
            else:
                creds[cred] = bytes(creds[cred])
        security_opts = security_settings(mech_class.security)

        return mech_class(best_mech, creds, security_opts)
    except SASLCancelled as e:
        log.info('SASL: %s: %s', best_mech, e.message)
        mech_list.remove(best_mech)
        return choose(mech_list,
                      credentials,
                      security_settings,
                      limit=limit,
                      min_mech=min_mech)
Beispiel #7
0
 def set_binval(self, value):
     self.del_binval()
     parent = self.parent()
     if value:
         xml = ET.Element('{%s}BINVAL' % self.namespace)
         xml.text = bytes(base64.b64encode(value)).decode('utf-8')
         parent.append(xml)
Beispiel #8
0
    def process_1(self, challenge):
        self.step = 1
        data = {}

        self.cnonce = bytes(('%s' % random.random())[2:])

        gs2_cbind_flag = b'n'
        if self.credentials['channel_binding']:
            if self.use_channel_binding:
                gs2_cbind_flag = b'p=tls-unique'
            else:
                gs2_cbind_flag = b'y'

        authzid = b''
        if self.credentials['authzid']:
            authzid = b'a=' + self.saslname(self.credentials['authzid'])

        self.gs2_header = gs2_cbind_flag + b',' + authzid + b','

        nonce = b'r=' + self.cnonce
        username = b'n=' + self.saslname(self.credentials['username'])

        self.client_first_message_bare = username + b',' + nonce
        self.client_first_message = self.gs2_header + \
                                    self.client_first_message_bare

        return self.client_first_message
Beispiel #9
0
    def process_1(self, challenge):
        self.step = 1
        data = {}

        self.cnonce = bytes(('%s' % random.random())[2:])

        gs2_cbind_flag = b'n'
        if self.credentials['channel_binding']:
            if self.use_channel_binding:
                gs2_cbind_flag = b'p=tls-unique'
            else:
                gs2_cbind_flag = b'y'

        authzid = b''
        if self.credentials['authzid']:
            authzid = b'a=' + self.saslname(self.credentials['authzid'])

        self.gs2_header = gs2_cbind_flag + b',' + authzid + b','

        nonce = b'r=' + self.cnonce
        username = b'n=' + self.saslname(self.credentials['username'])

        self.client_first_message_bare = username + b',' + nonce
        self.client_first_message = self.gs2_header + \
                                    self.client_first_message_bare

        return self.client_first_message
 def set_binval(self, value):
     self.del_binval()
     parent = self.parent()
     if value:
         xml = ET.Element('{%s}BINVAL' % self.namespace)
         xml.text = bytes(base64.b64encode(value)).decode('utf-8')
         parent.append(xml)
Beispiel #11
0
def choose(mech_list, credentials, security_settings, limit=None, min_mech=None):
    available_mechs = set(MECHANISMS.keys())
    if limit is None:
        limit = set(mech_list)
    if not isinstance(limit, set):
        limit = set(limit)
    if not isinstance(mech_list, set):
        mech_list = set(mech_list)

    mech_list = mech_list.intersection(limit)
    available_mechs = available_mechs.intersection(mech_list)

    best_score = MECH_SEC_SCORES.get(min_mech, -1)
    best_mech = None
    for name in available_mechs:
        if name in MECH_SEC_SCORES:
            if MECH_SEC_SCORES[name] > best_score:
                best_score = MECH_SEC_SCORES[name]
                best_mech = name
    if best_mech is None:
        raise SASLNoAppropriateMechanism()

    mech_class = MECHANISMS[best_mech]

    try:
        creds = credentials(mech_class.required_credentials,
                            mech_class.optional_credentials)
        for req in mech_class.required_credentials:
            if req not in creds:
                raise SASLCancelled('Missing credential: %s' % req)
        for opt in mech_class.optional_credentials:
            if opt not in creds:
                creds[opt] = b''
        for cred in creds:
            if cred in ('username', 'password', 'authzid'):
                creds[cred] = bytes(saslprep(creds[cred]))
            else:
                creds[cred] = bytes(creds[cred])
        security_opts = security_settings(mech_class.security)

        return mech_class(best_mech, creds, security_opts)
    except SASLCancelled as e:
        log.info('SASL: %s: %s', best_mech, e.message)
        mech_list.remove(best_mech)
        return choose(mech_list, credentials, security_settings,
                limit=limit,
                min_mech=min_mech)
Beispiel #12
0
 def Hi(self, text, salt, iterations):
     text = bytes(text)
     ui1 = self.HMAC(text, salt + b'\0\0\0\01')
     ui = ui1
     for i in range(iterations - 1):
         ui1 = self.HMAC(text, ui1)
         ui = XOR(ui, ui1)
     return ui
Beispiel #13
0
 def Hi(self, text, salt, iterations):
     text = bytes(text)
     ui1 = self.HMAC(text, salt + b'\0\0\0\01')
     ui = ui1
     for i in range(iterations - 1):
         ui1 = self.HMAC(text, ui1)
         ui = XOR(ui, ui1)
     return ui
Beispiel #14
0
 def respond(self):
     data = {
         'username': quote(self.credentials['username']),
         'authzid': quote(self.credentials['authzid']),
         'realm': quote(self.credentials['realm']),
         'nonce': quote(self.nonce),
         'cnonce': quote(self.cnonce),
         'nc': bytes('%08x' % self.nonce_count),
         'qop': self.qop,
         'digest-uri': quote(self.digest_uri()),
         'response': self.response(b'AUTHENTICATE'),
         'maxbuf': self.maxbuf,
         'charset': 'utf-8'
     }
     resp = b''
     for key, value in data.items():
         if value and value != b'""':
             resp += b',' + bytes(key) + b'=' + bytes(value)
     return resp[1:]
Beispiel #15
0
 def respond(self):
     data = {
         'username': quote(self.credentials['username']),
         'authzid': quote(self.credentials['authzid']),
         'realm': quote(self.credentials['realm']),
         'nonce': quote(self.nonce),
         'cnonce': quote(self.cnonce),
         'nc': bytes('%08x' % self.nonce_count),
         'qop': self.qop,
         'digest-uri': quote(self.digest_uri()),
         'response': self.response(b'AUTHENTICATE'),
         'maxbuf': self.maxbuf,
         'charset': 'utf-8'
     }
     resp = b''
     for key, value in data.items():
         if value and value != b'""':
             resp += b',' + bytes(key) + b'=' + bytes(value)
     return resp[1:]
Beispiel #16
0
    def parse(self, challenge=b''):
        data = {}
        var_name = b''
        var_value = b''

        # States: var, new_var, end, quote, escaped_quote
        state = 'var'


        for char in challenge:
            char = bytes([char])

            if state == 'var':
                if char.isspace():
                    continue
                if char == b'=':
                    state = 'value'
                else:
                    var_name += char
            elif state == 'value':
                if char == b'"':
                    state = 'quote'
                elif char == b',':
                    if var_name:
                        data[var_name.decode('utf-8')] = var_value
                    var_name = b''
                    var_value = b''
                    state = 'var'
                else:
                    var_value += char
            elif state == 'escaped':
                var_value += char
            elif state == 'quote':
                if char == b'\\':
                    state = 'escaped'
                elif char == b'"':
                    state = 'end'
                else:
                    var_value += char
            else:
                if char == b',':
                    if var_name:
                        data[var_name.decode('utf-8')] = var_value
                    var_name = b''
                    var_value = b''
                    state = 'var'
                else:
                    var_value += char

        if var_name:
            data[var_name.decode('utf-8')] = var_value
        var_name = b''
        var_value = b''
        state = 'var'
        return data
Beispiel #17
0
    def parse(self, challenge=b''):
        data = {}
        var_name = b''
        var_value = b''

        # States: var, new_var, end, quote, escaped_quote
        state = 'var'


        for char in challenge:
            char = bytes([char])

            if state == 'var':
                if char.isspace():
                    continue
                if char == b'=':
                    state = 'value'
                else:
                    var_name += char
            elif state == 'value':
                if char == b'"':
                    state = 'quote'
                elif char == b',':
                    if var_name:
                        data[var_name.decode('utf-8')] = var_value
                    var_name = b''
                    var_value = b''
                    state = 'var'
                else:
                    var_value += char
            elif state == 'escaped':
                var_value += char
            elif state == 'quote':
                if char == b'\\':
                    state = 'escaped'
                elif char == b'"':
                    state = 'end'
                else:
                    var_value += char
            else:
                if char == b',':
                    if var_name:
                        data[var_name.decode('utf-8')] = var_value
                    var_name = b''
                    var_value = b''
                    state = 'var'
                else:
                    var_value += char

        if var_name:
            data[var_name.decode('utf-8')] = var_value
        var_name = b''
        var_value = b''
        state = 'var'
        return data
Beispiel #18
0
    def process(self, challenge=b''):
        if not challenge:
            return None

        username = self.credentials['username']
        password = self.credentials['password']

        mac = hmac.HMAC(key=password, digestmod=self.hash)
        mac.update(challenge)

        return username + b' ' + bytes(mac.hexdigest())
Beispiel #19
0
    def process(self, challenge=b''):
        if not challenge:
            return None

        username = self.credentials['username']
        password = self.credentials['password']

        mac = hmac.HMAC(key=password, digestmod=self.hash)
        mac.update(challenge)

        return username + b' ' + bytes(mac.hexdigest())
Beispiel #20
0
    def A1(self):
        username = self.credentials['username']
        password = self.credentials['password']
        authzid = self.credentials['authzid']
        realm = self.credentials['realm']

        a1 = self.hash()
        a1.update(username + b':' + realm + b':' + password)
        a1 = a1.digest()
        a1 += b':' + self.nonce + b':' + self.cnonce
        if authzid:
            a1 += b':' + authzid

        return bytes(a1)
Beispiel #21
0
    def A1(self):
        username = self.credentials['username']
        password = self.credentials['password']
        authzid = self.credentials['authzid']
        realm = self.credentials['realm']

        a1 = self.hash()
        a1.update(username + b':' + realm + b':' + password)
        a1 = a1.digest()
        a1 += b':' + self.nonce + b':' + self.cnonce
        if authzid:
            a1 += b':' + authzid

        return bytes(a1)
Beispiel #22
0
    def process(self, challenge=b''):
        if challenge:
            values = {}
            for kv in challenge.split(b'&'):
                key, value = kv.split(b'=')
                values[key] = value

            resp_data = {
                b'method': values[b'method'],
                b'v': b'1.0',
                b'call_id': b'1.0',
                b'nonce': values[b'nonce'],
                b'access_token': self.credentials['access_token'],
                b'api_key': self.credentials['api_key']
            }

            resp = '&'.join(['%s=%s' % (k.decode("utf-8"), v.decode("utf-8")) for k, v in resp_data.items()])
            return bytes(resp)
        return b''
Beispiel #23
0
    def process(self, challenge=b''):
        if challenge:
            values = {}
            for kv in challenge.split(b'&'):
                key, value = kv.split(b'=')
                values[key] = value

            resp_data = {
                b'method': values[b'method'],
                b'v': b'1.0',
                b'call_id': b'1.0',
                b'nonce': values[b'nonce'],
                b'access_token': self.credentials['access_token'],
                b'api_key': self.credentials['api_key']
            }

            resp = '&'.join(['%s=%s' % (k.decode("utf-8"), v.decode("utf-8")) for k, v in resp_data.items()])
            return bytes(resp)
        return b''
Beispiel #24
0
    def process(self, challenge=b''):
        if not challenge:
            if self.cnonce and self.nonce and self.nonce_count and self.qop:
                self.nonce_count += 1
                return self.respond()
            return None

        data = self.parse(challenge)
        if 'rspauth' in data:
            if data['rspauth'] != self.response():
                raise SASLMutualAuthFailed()
        else:
            self.nonce_count = 1
            self.cnonce = bytes('%s' % random.random())[2:]
            self.qops = data.get('qop', [b'auth'])
            self.qop = b'auth'
            if 'nonce' in data:
                self.nonce = data['nonce']
            if 'realm' in data and not self.credentials['realm']:
                self.credentials['realm'] = data['realm']

            return self.respond()
Beispiel #25
0
    def process(self, challenge=b''):
        if not challenge:
            if self.cnonce and self.nonce and self.nonce_count and self.qop:
                self.nonce_count += 1
                return self.respond()
            return None

        data = self.parse(challenge)
        if 'rspauth' in data:
            if data['rspauth'] != self.response():
                raise SASLMutualAuthFailed()
        else:
            self.nonce_count = 1
            self.cnonce = bytes('%s' % random.random())[2:]
            self.qops = data.get('qop', [b'auth'])
            self.qop = b'auth'
            if 'nonce' in data:
                self.nonce = data['nonce']
            if 'realm' in data and not self.credentials['realm']:
                self.credentials['realm'] = data['realm']

            return self.respond()
Beispiel #26
0
def to_b64(data):
    return bytes(base64.b64encode(bytes(data))).decode('utf-8')
 def get_binval(self):
     parent = self.parent()
     xml = parent.xml.find('{%s}BINVAL' % self.namespace)
     if xml is not None:
         return base64.b64decode(bytes(xml.text))
     return b''
Beispiel #28
0
def from_b64(data):
    return bytes(base64.b64decode(bytes(data)))
Beispiel #29
0
 def set_data(self, value):
     self.xml.text = bytes(base64.b64encode(value)).decode('utf-8')
Beispiel #30
0
 def get_value(self):
     return base64.b64decode(bytes(self.xml.text))
Beispiel #31
0
 def A2(self, prefix=b''):
     a2 = prefix + b':' + self.digest_uri()
     if self.qop in (b'auth-int', b'auth-conf'):
         a2 += b':00000000000000000000000000000000'
     return bytes(a2)
Beispiel #32
0
 def get_binval(self):
     parent = self.parent()
     xml = parent.find('{%s}BINVAL' % self.namespace)
     if xml is not None:
         return base64.b64decode(bytes(xml.text))
     return b''
Beispiel #33
0
 def set_value(self, value):
     if value:
         self.xml.text = b64encode(bytes(value)).decode()
     else:
         self.xml.text = ''
Beispiel #34
0
 def A2(self, prefix=b''):
     a2 = prefix + b':' + self.digest_uri()
     if self.qop in (b'auth-int', b'auth-conf'):
         a2 += b':00000000000000000000000000000000'
     return bytes(a2)
Beispiel #35
0
 def get_data(self):
     return base64.b64decode(bytes(self.xml.text))
Beispiel #36
0
 def set_data(self, value):
     self.xml.text = bytes(base64.b64encode(value)).decode('utf-8')
Beispiel #37
0
 def set_value(self, values):
     if values:
         self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
     else:
         self.xml.text = '='
Beispiel #38
0
 def get_value(self):
     return base64.b64decode(bytes(self.xml.text))
Beispiel #39
0
 def set_value(self, value):
     if value:
         self.xml.text = b64encode(bytes(value)).decode()
     else:
         self.xml.text = ''
Beispiel #40
0
 def get_value(self):
     if not self["mechanism"] in self.plain_mechs:
         return base64.b64decode(bytes(self.xml.text))
     else:
         return self.xml.text
Beispiel #41
0
 def set_value(self, values):
     if values:
         self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
     else:
         self.xml.text = '='
Beispiel #42
0
def from_b64(data):
    return bytes(base64.b64decode(bytes(data)))
Beispiel #43
0
 def get_value(self):
     if self.xml.text:
         return b64decode(bytes(self.xml.text))
     return ''
Beispiel #44
0
def to_b64(data):
    return bytes(base64.b64encode(bytes(data))).decode('utf-8')
Beispiel #45
0
 def set_value(self, value):
     self.xml.text = ''
     if value:
         self.xml.text = b64encode(bytes(value))
Beispiel #46
0
 def get_data(self):
     return base64.b64decode(bytes(self.xml.text))
Beispiel #47
0
 def get_value(self):
     if not self['mechanism'] in self.plain_mechs:
         return base64.b64decode(bytes(self.xml.text))
     else:
         return self.xml.text