blob: a592ec3a303e3991420c058ae07cd51948de0dff [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001#
2# server.py
3#
4# Copyright (C) 2001 Martin Sjögren and AB Strakt, All rights reserved
5#
6# $Id: server.py,v 1.2 2002/07/25 08:26:34 martin Exp $
7#
8"""
9Simple echo server, using nonblocking I/O
10"""
11
12from OpenSSL import SSL
13import sys, os, select, socket
14
15
16def verify_cb(conn, cert, errnum, depth, ok):
17 # This obviously has to be updated
18 print 'Got certificate: %s' % cert.get_subject()
19 return ok
20
21if len(sys.argv) < 2:
22 print 'Usage: python[2] server.py PORT'
23 sys.exit(1)
24
25dir = os.path.dirname(sys.argv[0])
26if dir == '':
27 dir = os.curdir
28
29# Initialize context
30ctx = SSL.Context(SSL.SSLv23_METHOD)
31ctx.set_options(SSL.OP_NO_SSLv2)
32ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) # Demand a certificate
33ctx.use_privatekey_file (os.path.join(dir, 'server.pkey'))
34ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
35ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
36
37# Set up server
38server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
39server.bind(('', int(sys.argv[1])))
40server.listen(3)
41server.setblocking(0)
42
43clients = {}
44writers = {}
45
46def dropClient(cli, errors=None):
47 if errors:
48 print 'Client %s left unexpectedly:' % (clients[cli],)
49 print ' ', errors
50 else:
51 print 'Client %s left politely' % (clients[cli],)
52 del clients[cli]
53 if writers.has_key(cli):
54 del writers[cli]
55 if not errors:
56 cli.shutdown()
57 cli.close()
58
59while 1:
60 try:
61 r,w,_ = select.select([server]+clients.keys(), writers.keys(), [])
62 except:
63 break
64
65 for cli in r:
66 if cli == server:
67 cli,addr = server.accept()
68 print 'Connection from %s' % (addr,)
69 clients[cli] = addr
70
71 else:
72 try:
73 ret = cli.recv(1024)
74 except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
75 pass
76 except SSL.ZeroReturnError:
77 dropClient(cli)
78 except SSL.Error, errors:
79 dropClient(cli, errors)
80 else:
81 if not writers.has_key(cli):
82 writers[cli] = ''
83 writers[cli] = writers[cli] + ret
84
85 for cli in w:
86 try:
87 ret = cli.send(writers[cli])
88 except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
89 pass
90 except SSL.ZeroReturnError:
91 dropClient(cli)
92 except SSL.Error, errors:
93 dropClient(cli, errors)
94 else:
95 writers[cli] = writers[cli][ret:]
96 if writers[cli] == '':
97 del writers[cli]
98
99for cli in clients.keys():
100 cli.close()
101server.close()