def create_response(challenge, server_name, signer_plug=None, packing=xdr_packing): """Called by a client with the challenge provided by the server to generate a response using the local ssh-agent""" b = ssh.base64url_decode(challenge) hmac_challenge = protocol.VerifiablePayload.deserialize(packing, b) challenge = protocol.Challenge.deserialize(packing, hmac_challenge.payload) if challenge.server_name != server_name: s = "Possible MITM attack. Challenge originates from '%s' " "and not '%s'" % ( challenge.server_name, server_name, ) raise exceptions.InvalidInputException(s) if not signer_plug: signer_plug = ssh.AgentSigner() challenge = protocol.Challenge.deserialize(packing, hmac_challenge.payload) signature = signer_plug.sign(challenge.serialize(packing)) signer_plug.close() response = protocol.Response(signature=signature, hmac_challenge=hmac_challenge) return ssh.base64url_encode(response.serialize(packing))
def _make_token(self, username, expire_time): t = protocol.Token(username=username, valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=expire_time) b = t.serialize(self.packing) payload = protocol.VerifiablePayload(digest=self._hmac(b), payload=b) return ssh.base64url_encode(payload.serialize(self.packing))
def create_challenge(self, username, version=0): """This method returns a challenge suitable for ssh-agent signing. @param username the username of the user requesting a challenge @param version the highest protocol version the clients supports @exception ProtocolVersionError if the client supports """ if len(username) > 64: raise ValueError("Username is too long: " + username) try: key = self.key_provider.get_key(username) fingerprint = key.fingerprint() except exceptions.NoSuchUserException: log.info("No public key found for '%s', faking it." % username) fingerprint = self._hmac(username)[:6] if version < 1: if self.lowest_supported_version > version: raise exceptions.ProtocolVersionError( "Client needs to support at least version %d" % self.lowest_supported_version) c = protocol.Challenge( fingerprint=fingerprint, server_name=self.server_name, unique_data=self.urandom.read(20), valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=int(self.now_func() + RESP_TIMEOUT), username=username) b = c.serialize() payload = protocol.VerifiablePayload(digest=self._hmac(b), payload=b) return ssh.base64url_encode(payload.serialize()) else: c = msgpack_protocol.Challenge( fingerprint=fingerprint, server_name=self.server_name, unique_data=self.urandom.read(20), valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=int(self.now_func() + RESP_TIMEOUT), username=username) return ssh.base64url_encode(c.serialize(self.secret))
def _make_token(self, username, expire_time): t = protocol.Token(username=username, valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=expire_time) b = t.serialize() payload = protocol.VerifiablePayload(digest=self._hmac(b), payload=b) return ssh.base64url_encode(payload.serialize())
def create_challenge(self, username, version=0): """This method returns a challenge suitable for ssh-agent signing. @param username the username of the user requesting a challenge @param version the highest protocol version the clients supports @exception ProtocolVersionError if the client supports """ if len(username) > 64: raise ValueError("Username is too long: " + username) try: key = self.key_provider.get_key(username) fingerprint = key.fingerprint() except exceptions.NoSuchUserException: log.info("No public key found for '%s', faking it." % username) fingerprint = self._hmac(username)[:6] if version < 1: if self.lowest_supported_version > version: raise exceptions.ProtocolVersionError( "Client needs to support at least version %d" % self.lowest_supported_version ) c = protocol.Challenge(fingerprint=fingerprint, server_name=self.server_name, unique_data=self.urandom.read(20), valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=int(self.now_func() + RESP_TIMEOUT), username=username) b = c.serialize() payload = protocol.VerifiablePayload(digest=self._hmac(b), payload=b) return ssh.base64url_encode(payload.serialize()) else: c = msgpack_protocol.Challenge( fingerprint=fingerprint, server_name=self.server_name, unique_data=self.urandom.read(20), valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=int(self.now_func() + RESP_TIMEOUT), username=username) return ssh.base64url_encode(c.serialize(self.secret))
def create_request(username): """ Create a request for a challenge with your username encoded. :param username: the username of the user to authenticate as :return: a request message """ buf = io.BytesIO() msgpack.pack(1, buf) msgpack.pack(ord('q'), buf) msgpack.pack(username, buf) return ssh.base64url_encode(buf.getvalue())
def create_challenge(self, username): """This method creates a challenge suitable for ssh-agent signing.""" key = self.key_provider.get_key(username) c = protocol.Challenge(fingerprint=key.fingerprint(), server_name=self.server_name, unique_data=self.urandom.read(20), valid_from=int(self.now_func() - CLOCK_FUDGE), valid_to=int(self.now_func() + RESP_TIMEOUT), username=username) b = c.serialize() payload = protocol.VerifiablePayload(digest=self._hmac(b), payload=b) return ssh.base64url_encode(payload.serialize())
def create_response(challenge, server_name, signer_plug=None): """Called by a client with the challenge provided by the server to generate a response using the local ssh-agent""" b = ssh.base64url_decode(challenge) if b[0] == 'v': # this is version 0 challenge hmac_challenge = protocol.VerifiablePayload.deserialize(b) challenge = protocol.Challenge.deserialize(hmac_challenge.payload) to_sign = hmac_challenge.payload version_1 = False elif b[0] == '\x01': # version 1 challenge = msgpack_protocol.Challenge.deserialize(b) to_sign = b version_1 = True else: raise exceptions.ProtocolError("invalid first byte of challenge") if challenge.server_name != server_name: s = ("Possible MITM attack. Challenge originates from '%s' " "and not '%s'" % (challenge.server_name, server_name)) raise exceptions.InvalidInputException(s) if not signer_plug: signer_plug = ssh.AgentSigner() signature = signer_plug.sign(to_sign, challenge.fingerprint) signer_plug.close() if version_1: response = msgpack_protocol.Response(challenge=b, signature=signature) else: response = protocol.Response(signature=signature, hmac_challenge=hmac_challenge) return ssh.base64url_encode(response.serialize())
def create_response(challenge, server_name, signer_plug=None): """Called by a client with the challenge provided by the server to generate a response using the local ssh-agent""" b = ssh.base64url_decode(challenge) if b[0] == 'v': # this is version 0 challenge hmac_challenge = protocol.VerifiablePayload.deserialize(b) challenge = protocol.Challenge.deserialize(hmac_challenge.payload) to_sign = hmac_challenge.payload version_1 = False elif b[0] == '\x01': # version 1 challenge = msgpack_protocol.Challenge.deserialize(b) to_sign = b version_1 = True else: raise exceptions.ProtocolError("invalid first byte of challenge") if challenge.server_name != server_name: s = ("Possible MITM attack. Challenge originates from '%s' " "and not '%s'" % (challenge.server_name, server_name)) raise exceptions.InvalidInputException(s) if not signer_plug: signer_plug = ssh.AgentSigner() signature = signer_plug.sign(to_sign, challenge.fingerprint) signer_plug.close() if version_1: response = msgpack_protocol.Response(challenge=b, signature=signature) else: response = protocol.Response( signature=signature, hmac_challenge=hmac_challenge) return ssh.base64url_encode(response.serialize())
def test_b64_roundtrip(self): l = ["a", "ab", "abc", "abcd"] for i in l: self.assertEquals(ssh.base64url_decode(ssh.base64url_encode(i)), i)