Пример #1
0
def SRPAuth(sock, user, passphrase=None):
    """Perform an SRP authentication on a socket.  Return the session key
    if authentication was successful, or raise an exception if it was not.
    The other end of the socket must be ready to receive the SRP
    commands."""

    if not passphrase:
        passphrase = getpass.getpass('Enter passphrase for %s: ' % user)

    # Send the USER command.

    sock.send('USER %s\n' % user)

    # Get the client-side keys and send the public one.

    keys = SRP.client_begin(user)
    A = keys[0]
    sock.send(encode_long(A))

    # Read the response.

    file = sock.makefile('rb')
    line = file.readline()
    if line[0:3] != 'KEY':
        raise SRP.NoSuchUser, line
    s = read_string(file)
    B = read_long(file)
    u = read_long(file)

    # Now calculate the session key and send the proof.

    K, m = SRP.client_key(user, passphrase, s, B, u, keys)
    sock.send(encode_string(m))
    line = file.readline()
    if line[0:3] != 'AOK':
        raise SRP.AuthFailure, line

    # Authenticate the host.

    m1 = SRP.host_authenticator(K, A, m)
    m = read_string(file)
    if m != m1:
        raise SRP.AuthFailure, "Host authentication failed."

    # All done, return the session key.

    return K
Пример #2
0
def SRPAuth(sock, user, passphrase = None):
    """Perform an SRP authentication on a socket.  Return the session key
    if authentication was successful, or raise an exception if it was not.
    The other end of the socket must be ready to receive the SRP
    commands."""

    if not passphrase:
	passphrase = getpass.getpass('Enter passphrase for %s: ' % user)

    # Send the USER command.

    sock.send('USER %s\n' % user)

    # Get the client-side keys and send the public one.

    keys = SRP.client_begin(user)
    A = keys[0]
    sock.send(encode_long(A))

    # Read the response.

    file = sock.makefile('rb')
    line = file.readline()
    if line[0:3] != 'KEY':
	raise SRP.NoSuchUser, line
    s = read_string(file)
    B = read_long(file)
    u = read_long(file)

    # Now calculate the session key and send the proof.

    K, m = SRP.client_key(user, passphrase, s, B, u, keys)
    sock.send(encode_string(m))
    line = file.readline()
    if line[0:3] != 'AOK':
	raise SRP.AuthFailure, line

    # Authenticate the host.

    m1 = SRP.host_authenticator(K, A, m)
    m = read_string(file)
    if m != m1:
	raise SRP.AuthFailure, "Host authentication failed."

    # All done, return the session key.

    return K
Пример #3
0
    def handle(self):
	sock = self.request
	file = sock.makefile('rb')

	# Receive the username and public key A from the client.

	while 1:
	    line = file.readline()
	    if not line:
		return
	    if line[0:4] == 'USER':
		l = string.split(line)
		if len(l) == 2:
		    break
	    sock.send('Please specify USER.\n')
	user = l[1]
	try:
	    A = read_long(file)
	except EOFError:
	    return

	# Calculate the public and private values, and send the public stuff
	# to the client.

	try:
	    s, B, u, K, m = SRP.lookup(user, A)
	except SRP.NoSuchUser:
	    sock.send('No such user "%s".\n' % user)
	    return
	sock.send('KEY\n')
	sock.send(encode_string(s))
	sock.send(encode_long(B))
	sock.send(encode_long(u))

	# The client now sends us its proof.

	try:
	    m1 = read_string(file)
	except EOFError:
	    return
	if m != m1:
	    sock.send('Client authentication failed.\n')
	    return
	sock.send('AOK\n')

	# Send the host authentication proof.

	sock.send(encode_string(SRP.host_authenticator(K, A, m)))

	# At this point (assuming the client accepts the host authentication),
	# the socket has been authenticated and K is the secret session key.

	if self.__dict__.has_key('auth_socket'):
	    self.auth_socket(file, sock, K)
	else:

	    # Simple echo server.

	    while 1:
		s = file.readline()
		if not s:
		    return
		sock.send(s)
Пример #4
0
    def message_came_in(self, s, data):
        try:
            msg = bdecode(data)
        except ValueError:
            self.close(s)
            raise NetworkError, 'garbage data'
        if msg.has_key('error'):
            raise ServerError, msg['error']
        socket = self.socket[s]
        srp = socket['srp']
        if socket['state'] == 1:
            K, m = self.auth.client_key(msg['s'], msg['B'], msg['u'],
                                        srp['keys'])
            socket['key'], socket['m_out'] = K, m
            self._send_msg(s, {'m': socket['m_out'].digest()})
            socket['state'] = 2
        elif socket['state'] == 2:
            socket['m_in'] = SRP.host_authenticator(socket['key'], srp['keys'][0], socket['m_out'].digest())
            if socket['m_in'].digest() != msg['auth']:
                raise ServerError, 'Bad host authentication'
                return
            self.nh.set_hmac(s, socket['m_in'], socket['m_out'])
            self.rs.doneflag.set()
        elif socket['state'] == 3:
            self.socket[s]['hash'] = msg['hash']
            self.rs.doneflag.set()
        elif socket['state'] == 4:
            self.close(s)
            secret = crypt(msg['secret'], socket['key'])[0]
            self.auth.save_secret(secret)
            self.rs.doneflag.set()
        elif socket['state'] == 5:
            self.close(s)
            self.rs.doneflag.set()
        elif socket['state'] == 6:
            if len(msg['salt']) < 20:
                self._send_error(s, None, 'Bad salt length')
                self.close(s)
                raise NetworkError, 'Bad salt from server'

            salt = random_string(20)

            key = self.auth.session_key(salt, msg['salt'])
            socket['m_in'] = hmac.new(key, '', sha)
            key = self.auth.session_key(msg['salt'], salt)
            socket['m_out'] = hmac.new(key, '', sha)

            self._send_msg(s, {'auth': socket['m_in'].digest(),
                               'salt': salt})
            socket['state'] = 7
        elif socket['state'] == 7:
            if msg['auth'] != socket['m_out'].digest():
                self._send_error(s, None, 'Bad auth')
                self.close(s)
                raise NetworkError, 'Bad server auth'
            self._req_mode(s, 1)
            self.nh.set_hmac(s, socket['m_in'], socket['m_out'])
            self.socket[s] = [{}, {}, {}, [], 1]
            self.rs.doneflag.set()
        else:
            self.close(s)
Пример #5
0
    def message_came_in(self, s, data):
        socket = self.socket[s]
        try:
            msg = bdecode(data)
        except ValueError:
            self._send_error(s, None, 'garbage data')
            self._close(s)
            return
        if socket['state'] == 0:
            try:
                pw = socket['pw'] = self.passwd.get(msg['user'])
            except KeyError:
                self._send_error(s, None, 'Bad user')
                self._close(s)
                return
            socket['user'] = msg['user']
            if msg['op'] == 'get hash':
                self._send_msg(s, {
                    'hash':
                    sha.new('public hash check' + pw['secret']).digest()
                })
                socket['state'] = 3
            elif msg['op'] == 'secret auth':
                self._secret_auth(s)
            elif msg['op'] == 'srp auth':
                self._srp_auth(s, msg)
            else:
                self._close(s)
        elif socket['state'] == 1:
            srp = socket['srp']
            if srp['m'].digest() != msg['m']:
                self._send_error(s, None, 'Bad password')
                socket['state'] = 3
                return
            auth = SRP.host_authenticator(srp['K'], srp['A'],
                                          srp['m'].digest())
            self._send_msg(s, {'auth': auth.digest()})
            self.nh.set_hmac(s, srp['m'], auth)
            socket['state'] = 2
        elif socket['state'] == 2:
            srp = socket['srp']
            if msg['op'] == 'get secret':
                secret = socket['pw']['secret']
                esecret = crypt(secret, srp['K'])[0]
                self._send_msg(s, {'secret': esecret})
                socket['state'] = 3
            elif msg['op'] == 'set password':
                if socket['user'] == 'anonymous':
                    self._send_error(s, None, 'operation not permitted')
                    self._close(s)
                    return
                v = string_to_long(crypt(msg['v'], srp['K'])[0])
                self.passwd.define(socket['user'], v, msg['s'])
                self._send_msg(s, {'ok': 1})
                self._close(s)
        elif socket['state'] == 3:
            if msg['op'] == 'secret auth':
                self._secret_auth(s)
            elif msg['op'] == 'srp auth':
                self._srp_auth(s, msg)
            else:
                self._close(s)
        elif socket['state'] == 4:
            pw = socket['pw']

            if len(msg['salt']) < 20:
                self._send_error(s, None, 'Bad salt length')
                self._close(s)
                return

            if msg['salt'] + socket['salt'] == socket['salt'] + msg['salt']:
                self._send_error(s, None, 'Bad salt')
                self._close(s)
                return

            base = 'session key' + pw['secret'] + socket['salt'] + msg['salt']
            key = sha.new(base).digest()
            socket['m_in'] = hmac.new(key, '', sha)
            base = 'session key' + pw['secret'] + msg['salt'] + socket['salt']
            key = sha.new(base).digest()
            socket['m_out'] = hmac.new(key, '', sha)

            if msg['auth'] != socket['m_out'].digest():
                self._send_error(s, None, 'Bad password')
                socket['state'] = 3
                return

            self._send_msg(s, {'auth': socket['m_in'].digest()})
            self.nh.set_hmac(s, socket['m_in'], socket['m_out'])
            self._req_mode(s, 1)
            self.socket[s] = [{}, {}, socket['user'], [], 1]
        else:
            self._close(s)
Пример #6
0
    def message_came_in(self, s, data):
        socket = self.socket[s]
        try:
            msg = bdecode(data)
        except ValueError:
            self._send_error(s, None, 'garbage data')
            self._close(s)
            return
        if socket['state'] == 0:
            try:
                pw = socket['pw'] = self.passwd.get(msg['user'])
            except KeyError:
                self._send_error(s, None, 'Bad user')
                self._close(s)
                return
            socket['user'] = msg['user']
            if msg['op'] == 'get hash':
                self._send_msg(s, {'hash': sha.new('public hash check' + pw['secret']).digest()})
                socket['state'] = 3
            elif msg['op'] == 'secret auth':
                self._secret_auth(s)
            elif msg['op'] == 'srp auth':
                self._srp_auth(s, msg)
            else:
                self._close(s)
        elif socket['state'] == 1:
            srp = socket['srp']
            if srp['m'].digest() != msg['m']:
                self._send_error(s, None, 'Bad password')
                socket['state'] = 3
                return
            auth = SRP.host_authenticator(srp['K'], srp['A'], srp['m'].digest())
            self._send_msg(s, {'auth': auth.digest()})
            self.nh.set_hmac(s, srp['m'], auth)
            socket['state'] = 2
        elif socket['state'] == 2:
            srp = socket['srp']
            if msg['op'] == 'get secret':
                secret = socket['pw']['secret']
                esecret = crypt(secret, srp['K'])[0]
                self._send_msg(s, {'secret': esecret})
                socket['state'] = 3
            elif msg['op'] == 'set password':
                if socket['user'] == 'anonymous':
                    self._send_error(s, None, 'operation not permitted')
                    self._close(s)
                    return
                v = string_to_long(crypt(msg['v'], srp['K'])[0])
                self.passwd.define(socket['user'], v, msg['s'])
                self._send_msg(s, {'ok': 1})
                self._close(s)
        elif socket['state'] == 3:
            if msg['op'] == 'secret auth':
                self._secret_auth(s)
            elif msg['op'] == 'srp auth':
                self._srp_auth(s, msg)
            else:
                self._close(s)
        elif socket['state'] == 4:
            pw = socket['pw']

            if len(msg['salt']) < 20:
                self._send_error(s, None, 'Bad salt length')
                self._close(s)
                return

            if msg['salt'] + socket['salt'] == socket['salt'] + msg['salt']:
                self._send_error(s, None, 'Bad salt')
                self._close(s)
                return

            base = 'session key' + pw['secret'] + socket['salt'] + msg['salt']
            key = sha.new(base).digest()
            socket['m_in'] = hmac.new(key, '', sha)
            base = 'session key' + pw['secret'] + msg['salt'] + socket['salt']
            key = sha.new(base).digest()
            socket['m_out'] = hmac.new(key, '', sha)

            if msg['auth'] != socket['m_out'].digest():
                self._send_error(s, None, 'Bad password')
                socket['state'] = 3
                return

            self._send_msg(s, {'auth': socket['m_in'].digest()})
            self.nh.set_hmac(s, socket['m_in'], socket['m_out'])
            self._req_mode(s, 1)
            self.socket[s] = [{}, {}, socket['user'], [], 1]
        else:
            self._close(s)
Пример #7
0
    def message_came_in(self, s, data):
        try:
            msg = bdecode(data)
        except ValueError:
            self.close(s)
            raise NetworkError, 'garbage data'
        if msg.has_key('error'):
            raise ServerError, msg['error']
        socket = self.socket[s]
        srp = socket['srp']
        if socket['state'] == 1:
            K, m = self.auth.client_key(msg['s'], msg['B'], msg['u'],
                                        srp['keys'])
            socket['key'], socket['m_out'] = K, m
            self._send_msg(s, {'m': socket['m_out'].digest()})
            socket['state'] = 2
        elif socket['state'] == 2:
            socket['m_in'] = SRP.host_authenticator(socket['key'],
                                                    srp['keys'][0],
                                                    socket['m_out'].digest())
            if socket['m_in'].digest() != msg['auth']:
                raise ServerError, 'Bad host authentication'
                return
            self.nh.set_hmac(s, socket['m_in'], socket['m_out'])
            self.rs.doneflag.set()
        elif socket['state'] == 3:
            self.socket[s]['hash'] = msg['hash']
            self.rs.doneflag.set()
        elif socket['state'] == 4:
            self.close(s)
            secret = crypt(msg['secret'], socket['key'])[0]
            self.auth.save_secret(secret)
            self.rs.doneflag.set()
        elif socket['state'] == 5:
            self.close(s)
            self.rs.doneflag.set()
        elif socket['state'] == 6:
            if len(msg['salt']) < 20:
                self._send_error(s, None, 'Bad salt length')
                self.close(s)
                raise NetworkError, 'Bad salt from server'

            salt = random_string(20)

            key = self.auth.session_key(salt, msg['salt'])
            socket['m_in'] = hmac.new(key, '', sha)
            key = self.auth.session_key(msg['salt'], salt)
            socket['m_out'] = hmac.new(key, '', sha)

            self._send_msg(s, {'auth': socket['m_in'].digest(), 'salt': salt})
            socket['state'] = 7
        elif socket['state'] == 7:
            if msg['auth'] != socket['m_out'].digest():
                self._send_error(s, None, 'Bad auth')
                self.close(s)
                raise NetworkError, 'Bad server auth'
            self._req_mode(s, 1)
            self.nh.set_hmac(s, socket['m_in'], socket['m_out'])
            self.socket[s] = [{}, {}, {}, [], 1]
            self.rs.doneflag.set()
        else:
            self.close(s)
Пример #8
0
    def handle(self):
        sock = self.request
        file = sock.makefile('rb')

        # Receive the username and public key A from the client.

        while 1:
            line = file.readline()
            if not line:
                return
            if line[0:4] == 'USER':
                l = string.split(line)
                if len(l) == 2:
                    break
            sock.send('Please specify USER.\n')
        user = l[1]
        try:
            A = read_long(file)
        except EOFError:
            return

        # Calculate the public and private values, and send the public stuff
        # to the client.

        try:
            s, B, u, K, m = SRP.lookup(user, A)
        except SRP.NoSuchUser:
            sock.send('No such user "%s".\n' % user)
            return
        sock.send('KEY\n')
        sock.send(encode_string(s))
        sock.send(encode_long(B))
        sock.send(encode_long(u))

        # The client now sends us its proof.

        try:
            m1 = read_string(file)
        except EOFError:
            return
        if m != m1:
            sock.send('Client authentication failed.\n')
            return
        sock.send('AOK\n')

        # Send the host authentication proof.

        sock.send(encode_string(SRP.host_authenticator(K, A, m)))

        # At this point (assuming the client accepts the host authentication),
        # the socket has been authenticated and K is the secret session key.

        if self.__dict__.has_key('auth_socket'):
            self.auth_socket(file, sock, K)
        else:

            # Simple echo server.

            while 1:
                s = file.readline()
                if not s:
                    return
                sock.send(s)