def start(self, properties): self.authzid = properties.get("authzid") # TODO: This isn't very XEP-0178'ish. # XEP-0178 says "=" should be sent when only one id-on-xmppAddr is # in the cert, but we don't know that. Still, this conforms to the # standard and works. if self.authzid: return Response(self.authzid) else: return Response(b"")
def _make_response(self, nonce, salt, iteration_count): """Make a response for the first challenge from the server. :return: the response or a failure indicator. :returntype: `sasl.Response` or `sasl.Failure` """ self._salted_password = self.Hi(self.Normalize(self.password), salt, iteration_count) self.password = None # not needed any more if self.channel_binding: channel_binding = b"c=" + standard_b64encode(self._gs2_header + self._cb_data) else: channel_binding = b"c=" + standard_b64encode(self._gs2_header) client_final_message_without_proof = (channel_binding + b",r=" + nonce) client_key = self.HMAC(self._salted_password, b"Client Key") stored_key = self.H(client_key) auth_message = (self._client_first_message_bare + b"," + self._server_first_message + b"," + client_final_message_without_proof) self._auth_message = auth_message client_signature = self.HMAC(stored_key, auth_message) client_proof = self.XOR(client_key, client_signature) proof = b"p=" + standard_b64encode(client_proof) client_final_message = (client_final_message_without_proof + b"," + proof) return Response(client_final_message)
def challenge(self, challenge): if self.step == 0: ret = kerberos.authGSSClientStep(self._gss, base64.b64encode(challenge)) if ret != kerberos.AUTH_GSS_CONTINUE: self.step = 1 elif self.step == 1: ret = kerberos.authGSSClientUnwrap(self._gss, base64.b64encode(challenge)) response = kerberos.authGSSClientResponse(self._gss) ret = kerberos.authGSSClientWrap(self._gss, response, self.username) response = kerberos.authGSSClientResponse(self._gss) if response is None: return Response(b"") else: return Response(base64.b64decode(response))
def start(self, properties): self.username = properties["username"] self.authzid = properties.get("authzid", "") self.in_properties = properties self.nonce_count = 0 self.response_auth = None self.rspauth_checked = False self.realm = None return Response(None)
def challenge(self, challenge): in_params = dict([part.split('=') for part in challenge.split('&')]) out_params = {} out_params['nonce'] = in_params['nonce'] out_params['method'] = in_params['method'] out_params['access_token'] = self.access_token out_params['api_key'] = self.api_key out_params['call_id'] = float(round(time.time() * 1000)) out_params['v'] = '1.0' data = urllib.urlencode(out_params) return Response(data)
def start(self, properties): self.username = properties["username"] self.password = properties["password"] self.authzid = properties.get("authzid", u"") c_nonce = properties.get("nonce_factory", default_nonce_factory)() if not VALUE_CHARS_RE.match(c_nonce): c_nonce = standard_b64encode(c_nonce) self._c_nonce = c_nonce if self.channel_binding: cb_data = properties.get("channel-binding") if not cb_data: raise ValueError("No channel binding data provided") if "tls-unique" in cb_data: cb_type = "tls-unique" elif "tls-server-end-point" in cb_data: cb_type = "tls-server-end-point" elif cb_data: cb_type = cb_data.keys()[0] self._cb_data = cb_data[cb_type] cb_flag = b"p=" + cb_type.encode("utf-8") else: plus_name = self.name + "-PLUS" if plus_name in properties.get("enabled_mechanisms", []): # -PLUS is enabled (supported) on our side, # but was not selected - that means it was not included # in the server features cb_flag = b"y" else: cb_flag = b"n" if self.authzid: authzid = b"a=" + self.escape(self.authzid.encode("utf-8")) else: authzid = b"" gs2_header = cb_flag + b"," + authzid + b"," self._gs2_header = gs2_header nonce = b"r=" + c_nonce client_first_message_bare = ( b"n=" + self.escape(self.username.encode("utf-8")) + b"," + nonce) self._client_first_message_bare = client_first_message_bare client_first_message = gs2_header + client_first_message_bare return Response(client_first_message)
def _final_challenge(self, challenge): """Process the second challenge from the server and return the response. :Parameters: - `challenge`: the challenge from server. :Types: - `challenge`: `bytes` :return: the response or a failure indicator. :returntype: `sasl.Response` or `sasl.Failure` """ if self._finished: return Failure("extra-challenge") match = SERVER_FINAL_MESSAGE_RE.match(challenge) if not match: logger.debug("Bad final message syntax: {0!r}".format(challenge)) return Failure("bad-challenge") error = match.group("error") if error: logger.debug("Server returned SCRAM error: {0!r}".format(error)) return Failure(u"scram-" + error.decode("utf-8")) verifier = match.group("verifier") if not verifier: logger.debug("No verifier value in the final message") return Failure("bad-succes") server_key = self.HMAC(self._salted_password, b"Server Key") server_signature = self.HMAC(server_key, self._auth_message) if server_signature != a2b_base64(verifier): logger.debug("Server verifier does not match") return Failure("bad-succes") self._finished = True return Response(None)
def _final_challenge(self, challenge): """Process the second challenge from the server and return the response. :Parameters: - `challenge`: the challenge from server. :Types: - `challenge`: `bytes` :return: the response or a failure indicator. :returntype: `sasl.Response` or `sasl.Failure` """ if self.rspauth_checked: return Failure("extra-challenge") challenge = challenge.split(b'\x00')[0] rspauth = None while challenge: match = PARAM_RE.match(challenge) if not match: logger.debug("Challenge syntax error: {0!r}".format(challenge)) return Failure("bad-challenge") challenge = match.group("rest") var = match.group("var") val = match.group("val") logger.debug("{0!r}: {1!r}".format(var, val)) if var == b"rspauth": rspauth = val if not rspauth: logger.debug("Final challenge without rspauth") return Failure("bad-success") if rspauth == self.response_auth: self.rspauth_checked = True return Response(None) else: logger.debug("Wrong rspauth value - peer is cheating?") logger.debug("my rspauth: {0!r}".format(self.response_auth)) return Failure("bad-success")
def _make_response(self, charset, realms, nonce): """Make a response for the first challenge from the server. :Parameters: - `charset`: charset name from the challenge. - `realms`: realms list from the challenge. - `nonce`: nonce value from the challenge. :Types: - `charset`: `bytes` - `realms`: `bytes` - `nonce`: `bytes` :return: the response or a failure indicator. :returntype: `sasl.Response` or `sasl.Failure`""" params = [] realm = self._get_realm(realms, charset) if isinstance(realm, Failure): return realm elif realm: realm = _quote(realm) params.append(b'realm="' + realm + b'"') try: username = self.username.encode(charset) except UnicodeError: logger.debug("Couldn't encode username to {0!r}".format(charset)) return Failure("incompatible-charset") username = _quote(username) params.append(b'username="******"') cnonce = self.in_properties.get("nonce_factory", default_nonce_factory)() cnonce = _quote(cnonce) params.append(b'cnonce="' + cnonce + b'"') params.append(b'nonce="' + nonce + b'"') self.nonce_count += 1 nonce_count = "{0:08x}".format(self.nonce_count).encode("us-ascii") params.append(b'nc=' + nonce_count) params.append(b'qop=auth') serv_type = self.in_properties["service-type"] serv_type = serv_type.encode("us-ascii") serv_name = self.in_properties["service-domain"] host = self.in_properties.get("service-hostname", serv_name) serv_name = serv_name.encode("idna") host = host.encode("idna") if serv_name and serv_name != host: digest_uri = b"/".join((serv_type, host, serv_name)) else: digest_uri = b"/".join((serv_type, host)) digest_uri = _quote(digest_uri) params.append(b'digest-uri="' + digest_uri + b'"') if self.authzid: try: authzid = self.authzid.encode(charset) except UnicodeError: logger.debug( "Couldn't encode authzid to {0!r}".format(charset)) return Failure("incompatible-charset") authzid = _quote(authzid) else: authzid = b"" try: epasswd = self.in_properties["password"].encode(charset) except UnicodeError: logger.debug("Couldn't encode password to {0!r}".format(charset)) return Failure("incompatible-charset") logger.debug("Encoded password: {0!r}".format(epasswd)) urp_hash = _make_urp_hash(username, realm, epasswd) response = _compute_response(urp_hash, nonce, cnonce, nonce_count, authzid, digest_uri) self.response_auth = _compute_response_auth(urp_hash, nonce, cnonce, nonce_count, authzid, digest_uri) params.append(b'response=' + response) if authzid: params.append(b'authzid="' + authzid + b'"') return Response(b",".join(params))
def start(self, properties): self.access_token = properties['facebook_access_token'] self.api_key = properties['facebook_api_key'] return Response(None)