source: remit/util/SocketAuth.py @ e1ae8b3

client
Last change on this file since e1ae8b3 was e1ae8b3, checked in by Alex Dehnert <adehnert@…>, 15 years ago

Do argument-length checking in SocketAuth?

  • Property mode set to 100644
File size: 2.3 KB
Line 
1from django.contrib.auth.models import User
2import socket
3import settings
4
5class SocketAuthBackend():
6    """
7    SocketAuthBackend provides a simple way to authenticate with another process.
8
9    The protocol is simple:
10    * Open a connection to a socket.
11    * On the first line, pass the name of the operation
12    * Then, on successive lines, pass additional arguments, one per line
13    * Close the write half of the socket
14    * The authentication server sends back a reply, one tuple element
15      per line
16
17    Queries include:
18    * AUTHENTICATE(username, password) => boolean
19    * FINGER(username) => (first name, last name, email, )
20    """
21    def authenticate(self, username, password, ):
22        (result,) = query(1, "AUTHENTICATE", username, password, )
23        print result
24        if result == 'true':
25            try:
26                user = User.objects.get(username=username)
27                if len(user.groups.filter(name='local-auth-only')) > 0:
28                    if user.check_password(password):
29                        return user
30                    else:
31                        return None
32                else:
33                    return user
34            except User.DoesNotExist:
35                user = User(username=username, password='SocketAuth')
36                user.is_staff = False
37                user.is_superuser = False
38                # Is there a race condition here? Yes.
39                # Should I do more error-checking? Yes.
40                # Do I care? No.
41                (first, last, email,) = query(3, 'FINGER', username)
42                user.first_name = first
43                user.last_name = last
44                user.email = email
45                user.save()
46                return user
47        return None
48
49    def get_user(self, user_id):
50        try:
51            return User.objects.get(pk=user_id)
52        except User.DoesNotExist:
53            return None
54
55def query(length, *args):
56    conn = socket.socket(socket.AF_UNIX)
57    conn.connect(settings.AUTH_SOCK)
58    conn.send('\n'.join(args))
59    conn.shutdown(socket.SHUT_WR)
60    result = conn.makefile().read().split('\n')
61    if(len(result)==length+1 and result[-1] == ''):
62        result = result[:-1]
63    if len(result) != length:
64        raise ValueError("Got return value of length %d to query '%s'; needed length %d" % (len(result), args[0], length, ))
65    conn.close()
66    return result
Note: See TracBrowser for help on using the repository browser.