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