blob: 22e1b72bddf13b1aa4bd4b1480970d24fd0577fe [file] [log] [blame]
Jean-Paul Calderone3de9f622008-03-12 14:12:19 -04001# -*- coding: latin-1 -*-
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05002#
Jean-Paul Calderonede0a71e2011-03-02 19:55:11 -05003# Copyright (C) AB Strakt
4# Copyright (C) Jean-Paul Calderone
5# See LICENSE for details.
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04006
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05007"""
8Simple echo server, using nonblocking I/O
9"""
10
11from OpenSSL import SSL
12import sys, os, select, socket
13
14
15def verify_cb(conn, cert, errnum, depth, ok):
16 # This obviously has to be updated
Jim Shaver71ad3682015-04-29 00:09:14 -040017 print('Got certificate: %s' % cert.get_subject())
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050018 return ok
19
20if len(sys.argv) < 2:
Jim Shaver8a4a7ae2015-04-29 01:17:33 -040021 print('Usage: python server.py PORT')
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050022 sys.exit(1)
23
24dir = os.path.dirname(sys.argv[0])
25if dir == '':
26 dir = os.curdir
27
28# Initialize context
29ctx = SSL.Context(SSL.SSLv23_METHOD)
30ctx.set_options(SSL.OP_NO_SSLv2)
31ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) # Demand a certificate
32ctx.use_privatekey_file (os.path.join(dir, 'server.pkey'))
33ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
34ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
35
36# Set up server
37server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
38server.bind(('', int(sys.argv[1])))
39server.listen(3)
40server.setblocking(0)
41
42clients = {}
43writers = {}
44
45def dropClient(cli, errors=None):
46 if errors:
Jim Shaver71ad3682015-04-29 00:09:14 -040047 print('Client %s left unexpectedly:' % (clients[cli],))
48 print(' ', errors)
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050049 else:
Jim Shaver71ad3682015-04-29 00:09:14 -040050 print('Client %s left politely' % (clients[cli],))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050051 del clients[cli]
Jim Shaver71ad3682015-04-29 00:09:14 -040052 if cli in writers:
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050053 del writers[cli]
54 if not errors:
55 cli.shutdown()
56 cli.close()
57
58while 1:
59 try:
Jim Shaver71ad3682015-04-29 00:09:14 -040060 r,w,_ = select.select([server]+list(clients.keys()), list(writers.keys()), [])
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050061 except:
62 break
63
64 for cli in r:
65 if cli == server:
66 cli,addr = server.accept()
Jim Shaver71ad3682015-04-29 00:09:14 -040067 print('Connection from %s' % (addr,))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050068 clients[cli] = addr
69
70 else:
71 try:
72 ret = cli.recv(1024)
73 except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
74 pass
75 except SSL.ZeroReturnError:
76 dropClient(cli)
Jim Shaver71ad3682015-04-29 00:09:14 -040077 except SSL.Error as errors:
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050078 dropClient(cli, errors)
79 else:
Jim Shaver71ad3682015-04-29 00:09:14 -040080 if cli not in writers:
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050081 writers[cli] = ''
82 writers[cli] = writers[cli] + ret
83
84 for cli in w:
85 try:
86 ret = cli.send(writers[cli])
87 except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
88 pass
89 except SSL.ZeroReturnError:
90 dropClient(cli)
Jim Shaver71ad3682015-04-29 00:09:14 -040091 except SSL.Error as errors:
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050092 dropClient(cli, errors)
93 else:
94 writers[cli] = writers[cli][ret:]
95 if writers[cli] == '':
96 del writers[cli]
97
Jim Shaver71ad3682015-04-29 00:09:14 -040098for cli in list(clients.keys()):
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050099 cli.close()
100server.close()