Пример #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')
         else:
             self.xml.text = '='
     else:
         self.xml.text = bytes(values).decode('utf-8')
Пример #2
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())
Пример #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')
         else:
             self.xml.text = '='
     else:
         self.xml.text = bytes(values).decode('utf-8')
Пример #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())
Пример #5
0
 def saslname(self, value):
     escaped = b""
     for char in bytes(value):
         if char == b",":
             escaped += b"=2C"
         elif char == b"=":
             escaped += b"=3D"
         else:
             if isinstance(char, int):
                 char = chr(char)
             escaped += bytes(char)
     return escaped
Пример #6
0
 def saslname(self, value):
     escaped = b''
     for char in bytes(value):
         if char == b',':
             escaped += b'=2C'
         elif char == b'=':
             escaped += b'=3D'
         else:
             if isinstance(char, int):
                 char = chr(char)
             escaped += bytes(char)
     return escaped
Пример #7
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)
Пример #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
Пример #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
Пример #10
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)
Пример #11
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)
Пример #12
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)
Пример #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
Пример #14
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
Пример #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
     }
     resp = b''
     for key, value in data.items():
         if value and value != b'""':
             resp += b',' + bytes(key) + b'=' + bytes(value)
     return resp[1:]
Пример #16
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
     }
     resp = b''
     for key, value in data.items():
         if value and value != b'""':
             resp += b',' + bytes(key) + b'=' + bytes(value)
     return resp[1:]
Пример #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:
            if sys.version_info >= (3, 0):
                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
Пример #18
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:]
Пример #19
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:
            if sys.version_info >= (3, 0):
                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
Пример #20
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())
Пример #21
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())
Пример #22
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)
Пример #23
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)
Пример #24
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, v) for k, v in resp_data.items()])
            return bytes(resp)
        return b""
Пример #25
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, v) for k, v in resp_data.items()])
            return bytes(resp)
        return b''
Пример #26
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()
Пример #27
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()
Пример #28
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)
Пример #29
0
 def get_value(self):
     return base64.b64decode(bytes(self.xml.text))
Пример #30
0
def to_b64(data):
    return bytes(base64.b64encode(bytes(data))).decode('utf-8')
Пример #31
0
def from_b64(data):
    return bytes(base64.b64decode(bytes(data)))
Пример #32
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
Пример #33
0
 def get_data(self):
     return base64.b64decode(bytes(self.xml.text))
Пример #34
0
 def get_value(self):
     return base64.b64decode(bytes(self.xml.text))
Пример #35
0
def to_b64(data):
    return bytes(base64.b64encode(bytes(data))).decode('utf-8')
Пример #36
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)
Пример #37
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''
Пример #38
0
def from_b64(data):
    return bytes(base64.b64decode(bytes(data)))
Пример #39
0
 def set_value(self, value):
     if value:
         self.xml.text = b64encode(bytes(value))
     else:
         self.xml.text = ''
Пример #40
0
 def set_value(self, values):
     if values:
         self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
     else:
         self.xml.text = '='
Пример #41
0
 def get_value(self):
     if self.xml.text:
         return b64decode(bytes(self.xml.text))
     return ''
Пример #42
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
Пример #43
0
 def set_data(self, value):
     self.xml.text = bytes(base64.b64encode(value)).decode('utf-8')
Пример #44
0
 def set_value(self, values):
     if values:
         self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
     else:
         self.xml.text = '='
Пример #45
0
 def set_value(self, value):
     self.xml.text = ''
     if value:
         self.xml.text = b64encode(bytes(value))