1## This file is part of Scapy
2## Copyright (C) 2007, 2008, 2009 Arnaud Ebalard
3##               2015, 2016, 2017 Maxence Tury
4## This program is published under a GPLv2 license
5
6"""
7TLS server automaton. This makes for a primitive TLS stack.
8Obviously you need rights for network access.
9
10We support versions SSLv2 to TLS 1.2, along with many features.
11There is no session resumption mechanism for now.
12
13In order to run a server listening on tcp/4433:
14> from scapy.all import *
15> t = TLSServerAutomaton(mycert='<cert.pem>', mykey='<key.pem>')
16> t.run()
17"""
18
19from __future__ import print_function
20import socket
21
22from scapy.pton_ntop import inet_pton
23from scapy.utils import randstring, repr_hex
24from scapy.automaton import ATMT
25from scapy.layers.tls.automaton import _TLSAutomaton
26from scapy.layers.tls.cert import PrivKeyRSA, PrivKeyECDSA
27from scapy.layers.tls.basefields import _tls_version
28from scapy.layers.tls.session import tlsSession
29from scapy.layers.tls.handshake import *
30from scapy.layers.tls.handshake_sslv2 import *
31from scapy.layers.tls.record import (TLS, TLSAlert, TLSChangeCipherSpec,
32                                     TLSApplicationData)
33from scapy.layers.tls.crypto.suites import (_tls_cipher_suites_cls,
34                                            get_usable_ciphersuites)
35
36
37class TLSServerAutomaton(_TLSAutomaton):
38    """
39    A simple TLS test server automaton. Try to overload some states or
40    conditions and see what happens on the other side.
41
42    Because of socket and automaton limitations, for now, the best way to
43    interrupt the server is by sending him 'stop_server'. Interruptions with
44    Ctrl-Z should work, but this might leave a loose listening socket behind.
45
46    In case the server receives a TLSAlert (whatever its type), or a 'goodbye'
47    message in a SSLv2 version, he will close the client session with a
48    similar message, and start waiting for new client connections.
49
50    _'mycert' and 'mykey' may be provided as filenames. They are needed for any
51    server authenticated handshake.
52    _'preferred_ciphersuite' allows the automaton to choose a cipher suite when
53    offered in the ClientHello. If absent, another one will be chosen.
54    _'client_auth' means the client has to provide a certificate.
55    _'is_echo_server' means that everything received will be sent back.
56    _'max_client_idle_time' is the maximum silence duration from the client.
57    Once this limit has been reached, the client (if still here) is dropped,
58    and we wait for a new connection.
59    """
60    def parse_args(self, server="127.0.0.1", sport=4433,
61                         mycert=None, mykey=None,
62                         preferred_ciphersuite=None,
63                         client_auth=False,
64                         is_echo_server=True,
65                         max_client_idle_time=60,
66                         **kargs):
67
68        super(TLSServerAutomaton, self).parse_args(mycert=mycert,
69                                                   mykey=mykey,
70                                                   **kargs)
71        try:
72            if ':' in server:
73                inet_pton(socket.AF_INET6, server)
74            else:
75                inet_pton(socket.AF_INET, server)
76            tmp = socket.getaddrinfo(server, sport)
77        except:
78            tmp = socket.getaddrinfo(socket.getfqdn(server), sport)
79
80        self.serversocket = None
81        self.ip_family = tmp[0][0]
82        self.local_ip = tmp[0][4][0]
83        self.local_port = sport
84        self.remote_ip = None
85        self.remote_port = None
86
87        self.preferred_ciphersuite = preferred_ciphersuite
88        self.client_auth = client_auth
89        self.is_echo_server = is_echo_server
90        self.max_client_idle_time = max_client_idle_time
91
92
93    def vprint_sessioninfo(self):
94        if self.verbose:
95            s = self.cur_session
96            v = _tls_version[s.tls_version]
97            self.vprint("Version       : %s" % v)
98            cs = s.wcs.ciphersuite.name
99            self.vprint("Cipher suite  : %s" % cs)
100            ms = s.master_secret
101            self.vprint("Master secret : %s" % repr_hex(ms))
102            if s.client_certs:
103                self.vprint("Client certificate chain: %r" % s.client_certs)
104            self.vprint()
105
106    def http_sessioninfo(self):
107        header  = "HTTP/1.1 200 OK\r\n"
108        header += "Server: Scapy TLS Extension\r\n"
109        header += "Content-type: text/html\r\n"
110        header += "Content-length: %d\r\n\r\n"
111        s = "----- Scapy TLS Server Automaton -----\n\n"
112        s += "Information on current TLS session:\n\n"
113        s += "Local end     : %s:%d\n" % (self.local_ip, self.local_port)
114        s += "Remote end    : %s:%d\n" % (self.remote_ip, self.remote_port)
115        v = _tls_version[self.cur_session.tls_version]
116        s += "Version       : %s\n" % v
117        cs = self.cur_session.wcs.ciphersuite.name
118        s += "Cipher suite  : %s\n" % cs
119        ms = self.cur_session.master_secret
120        s += "Master secret : %s\n" % repr_hex(ms)
121        body = "<html><body><pre>%s</pre></body></html>\r\n\r\n" % s
122        answer = (header+body) % len(body)
123        return answer
124
125
126    @ATMT.state(initial=True)
127    def INITIAL(self):
128        self.vprint("Starting TLS server automaton.")
129        self.vprint("Receiving 'stop_server' will cause a graceful exit.")
130        self.vprint("Interrupting with Ctrl-Z might leave a loose socket hanging.")
131        raise self.BIND()
132
133    @ATMT.state()
134    def BIND(self):
135        s = socket.socket(self.ip_family, socket.SOCK_STREAM)
136        self.serversocket = s
137        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
138        try:
139            s.bind((self.local_ip, self.local_port))
140            s.listen(1)
141        except:
142            m = "Unable to bind on %s:%d!" % (self.local_ip, self.local_port)
143            self.vprint()
144            self.vprint(m)
145            self.vprint("Maybe some server is already listening there?")
146            self.vprint()
147            raise self.FINAL()
148        raise self.WAITING_CLIENT()
149
150    @ATMT.state()
151    def WAITING_CLIENT(self):
152        self.vprint()
153        self.vprint("Waiting for a new client on %s:%d" % (self.local_ip,
154                                                           self.local_port))
155        self.socket, addr = self.serversocket.accept()
156        if not isinstance(addr, tuple):
157            addr = self.socket.getpeername()
158        if len(addr) > 2:
159            addr = (addr[0], addr[1])
160        self.remote_ip, self.remote_port = addr
161        self.vprint("Accepted connection from %s:%d" % (self.remote_ip,
162                                                        self.remote_port))
163        self.vprint()
164        raise self.INIT_TLS_SESSION()
165
166    @ATMT.state()
167    def INIT_TLS_SESSION(self):
168        """
169        XXX We should offer the right key according to the client's suites. For
170        now server_rsa_key is only used for RSAkx, but we should try to replace
171        every server_key with both server_rsa_key and server_ecdsa_key.
172        """
173        self.cur_session = tlsSession(connection_end="server")
174        self.cur_session.server_certs = [self.mycert]
175        self.cur_session.server_key = self.mykey
176        if isinstance(self.mykey, PrivKeyRSA):
177            self.cur_session.server_rsa_key = self.mykey
178        #elif isinstance(self.mykey, PrivKeyECDSA):
179        #    self.cur_session.server_ecdsa_key = self.mykey
180        raise self.WAITING_CLIENTFLIGHT1()
181
182    @ATMT.state()
183    def WAITING_CLIENTFLIGHT1(self):
184        self.get_next_msg()
185        raise self.RECEIVED_CLIENTFLIGHT1()
186
187    @ATMT.state()
188    def RECEIVED_CLIENTFLIGHT1(self):
189        pass
190
191    ########################### TLS handshake #################################
192
193    @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=1)
194    def should_handle_ClientHello(self):
195        self.raise_on_packet(TLSClientHello,
196                             self.HANDLED_CLIENTHELLO)
197
198    @ATMT.state()
199    def HANDLED_CLIENTHELLO(self):
200        raise self.PREPARE_SERVERFLIGHT1()
201
202    @ATMT.condition(HANDLED_CLIENTHELLO)
203    def should_check_ciphersuites(self):
204        """
205        We extract cipher suites candidates from the client's proposition.
206        """
207        if isinstance(self.mykey, PrivKeyRSA):
208            kx = "RSA"
209        elif isinstance(self.mykey, PrivKeyECDSA):
210            kx = "ECDSA"
211        if get_usable_ciphersuites(self.cur_pkt.ciphers, kx):
212            return
213        raise self.NO_USABLE_CIPHERSUITE()
214
215    @ATMT.state()
216    def NO_USABLE_CIPHERSUITE(self):
217        self.vprint("No usable cipher suite!")
218        raise self.CLOSE_NOTIFY()
219
220    @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=3)
221    def missing_ClientHello(self):
222        raise self.MISSING_CLIENTHELLO()
223
224    @ATMT.state(final=True)
225    def MISSING_CLIENTHELLO(self):
226        self.vprint("Missing ClientHello message!")
227        raise self.CLOSE_NOTIFY()
228
229    @ATMT.state()
230    def PREPARE_SERVERFLIGHT1(self):
231        self.add_record()
232
233    @ATMT.condition(PREPARE_SERVERFLIGHT1)
234    def should_add_ServerHello(self):
235        """
236        Selecting a cipher suite should be no trouble as we already caught
237        the None case previously.
238
239        Also, we do not manage extensions at all.
240        """
241        if isinstance(self.mykey, PrivKeyRSA):
242            kx = "RSA"
243        elif isinstance(self.mykey, PrivKeyECDSA):
244            kx = "ECDSA"
245        usable_suites = get_usable_ciphersuites(self.cur_pkt.ciphers, kx)
246        c = usable_suites[0]
247        if self.preferred_ciphersuite in usable_suites:
248            c = self.preferred_ciphersuite
249        self.add_msg(TLSServerHello(cipher=c))
250        raise self.ADDED_SERVERHELLO()
251
252    @ATMT.state()
253    def ADDED_SERVERHELLO(self):
254        pass
255
256    @ATMT.condition(ADDED_SERVERHELLO)
257    def should_add_Certificate(self):
258        c = self.buffer_out[-1].msg[0].cipher
259        if not _tls_cipher_suites_cls[c].kx_alg.anonymous:
260            self.add_msg(TLSCertificate(certs=self.cur_session.server_certs))
261        raise self.ADDED_CERTIFICATE()
262
263    @ATMT.state()
264    def ADDED_CERTIFICATE(self):
265        pass
266
267    @ATMT.condition(ADDED_CERTIFICATE)
268    def should_add_ServerKeyExchange(self):
269        c = self.buffer_out[-1].msg[0].cipher
270        if not _tls_cipher_suites_cls[c].kx_alg.no_ske:
271            self.add_msg(TLSServerKeyExchange())
272        raise self.ADDED_SERVERKEYEXCHANGE()
273
274    @ATMT.state()
275    def ADDED_SERVERKEYEXCHANGE(self):
276        pass
277
278    @ATMT.condition(ADDED_SERVERKEYEXCHANGE)
279    def should_add_CertificateRequest(self):
280        if self.client_auth:
281            self.add_msg(TLSCertificateRequest())
282        raise self.ADDED_CERTIFICATEREQUEST()
283
284    @ATMT.state()
285    def ADDED_CERTIFICATEREQUEST(self):
286        pass
287
288    @ATMT.condition(ADDED_CERTIFICATEREQUEST)
289    def should_add_ServerHelloDone(self):
290        self.add_msg(TLSServerHelloDone())
291        raise self.ADDED_SERVERHELLODONE()
292
293    @ATMT.state()
294    def ADDED_SERVERHELLODONE(self):
295        pass
296
297    @ATMT.condition(ADDED_SERVERHELLODONE)
298    def should_send_ServerFlight1(self):
299        self.flush_records()
300        raise self.WAITING_CLIENTFLIGHT2()
301
302    @ATMT.state()
303    def WAITING_CLIENTFLIGHT2(self):
304        self.get_next_msg()
305        raise self.RECEIVED_CLIENTFLIGHT2()
306
307    @ATMT.state()
308    def RECEIVED_CLIENTFLIGHT2(self):
309        pass
310
311    @ATMT.condition(RECEIVED_CLIENTFLIGHT2, prio=1)
312    def should_handle_ClientCertificate(self):
313        self.raise_on_packet(TLSCertificate,
314                             self.HANDLED_CLIENTCERTIFICATE)
315
316    @ATMT.condition(RECEIVED_CLIENTFLIGHT2, prio=2)
317    def no_ClientCertificate(self):
318        if self.client_auth:
319            raise self.MISSING_CLIENTCERTIFICATE()
320        raise self.HANDLED_CLIENTCERTIFICATE()
321
322    @ATMT.state()
323    def MISSING_CLIENTCERTIFICATE(self):
324        self.vprint("Missing ClientCertificate!")
325        raise self.CLOSE_NOTIFY()
326
327    @ATMT.state()
328    def HANDLED_CLIENTCERTIFICATE(self):
329        if self.client_auth:
330            self.vprint("Received client certificate chain...")
331
332    @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=1)
333    def should_handle_ClientKeyExchange(self):
334        self.raise_on_packet(TLSClientKeyExchange,
335                             self.HANDLED_CLIENTKEYEXCHANGE)
336
337    @ATMT.state()
338    def HANDLED_CLIENTKEYEXCHANGE(self):
339        pass
340
341    @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=2)
342    def should_handle_Alert_from_ClientCertificate(self):
343        self.raise_on_packet(TLSAlert,
344                             self.HANDLED_ALERT_FROM_CLIENTCERTIFICATE)
345
346    @ATMT.state()
347    def HANDLED_ALERT_FROM_CLIENTCERTIFICATE(self):
348        self.vprint("Received Alert message instead of ClientKeyExchange!")
349        raise self.CLOSE_NOTIFY()
350
351    @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=3)
352    def missing_ClientKeyExchange(self):
353        raise self.MISSING_CLIENTKEYEXCHANGE()
354
355    @ATMT.state()
356    def MISSING_CLIENTKEYEXCHANGE(self):
357        self.vprint("Missing ClientKeyExchange!")
358        raise self.CLOSE_NOTIFY()
359
360    @ATMT.condition(HANDLED_CLIENTKEYEXCHANGE, prio=1)
361    def should_handle_CertificateVerify(self):
362        self.raise_on_packet(TLSCertificateVerify,
363                             self.HANDLED_CERTIFICATEVERIFY)
364
365    @ATMT.condition(HANDLED_CLIENTKEYEXCHANGE, prio=2)
366    def no_CertificateVerify(self):
367        if self.client_auth:
368            raise self.MISSING_CERTIFICATEVERIFY()
369        raise self.HANDLED_CERTIFICATEVERIFY()
370
371    @ATMT.state()
372    def MISSING_CERTIFICATEVERIFY(self):
373        self.vprint("Missing CertificateVerify!")
374        raise self.CLOSE_NOTIFY()
375
376    @ATMT.state()
377    def HANDLED_CERTIFICATEVERIFY(self):
378        pass
379
380    @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=1)
381    def should_handle_ChangeCipherSpec(self):
382        self.raise_on_packet(TLSChangeCipherSpec,
383                             self.HANDLED_CHANGECIPHERSPEC)
384
385    @ATMT.state()
386    def HANDLED_CHANGECIPHERSPEC(self):
387        pass
388
389    @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=2)
390    def should_handle_Alert_from_ClientKeyExchange(self):
391        self.raise_on_packet(TLSAlert,
392                             self.HANDLED_ALERT_FROM_CLIENTKEYEXCHANGE)
393
394    @ATMT.state()
395    def HANDLED_ALERT_FROM_CLIENTKEYEXCHANGE(self):
396        self.vprint("Received Alert message instead of ChangeCipherSpec!")
397        raise self.CLOSE_NOTIFY()
398
399    @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=3)
400    def missing_ChangeCipherSpec(self):
401        raise self.MISSING_CHANGECIPHERSPEC()
402
403    @ATMT.state()
404    def MISSING_CHANGECIPHERSPEC(self):
405        self.vprint("Missing ChangeCipherSpec!")
406        raise self.CLOSE_NOTIFY()
407
408    @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=1)
409    def should_handle_ClientFinished(self):
410        self.raise_on_packet(TLSFinished,
411                             self.HANDLED_CLIENTFINISHED)
412
413    @ATMT.state()
414    def HANDLED_CLIENTFINISHED(self):
415        raise self.PREPARE_SERVERFLIGHT2()
416
417    @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=2)
418    def should_handle_Alert_from_ClientFinished(self):
419        self.raise_on_packet(TLSAlert,
420                             self.HANDLED_ALERT_FROM_CHANGECIPHERSPEC)
421
422    @ATMT.state()
423    def HANDLED_ALERT_FROM_CHANGECIPHERSPEC(self):
424        self.vprint("Received Alert message instead of Finished!")
425        raise self.CLOSE_NOTIFY()
426
427    @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=3)
428    def missing_ClientFinished(self):
429        raise self.MISSING_CLIENTFINISHED()
430
431    @ATMT.state()
432    def MISSING_CLIENTFINISHED(self):
433        self.vprint("Missing Finished!")
434        raise self.CLOSE_NOTIFY()
435
436    @ATMT.state()
437    def PREPARE_SERVERFLIGHT2(self):
438        self.add_record()
439
440    @ATMT.condition(PREPARE_SERVERFLIGHT2)
441    def should_add_ChangeCipherSpec(self):
442        self.add_msg(TLSChangeCipherSpec())
443        raise self.ADDED_CHANGECIPHERSPEC()
444
445    @ATMT.state()
446    def ADDED_CHANGECIPHERSPEC(self):
447        pass
448
449    @ATMT.condition(ADDED_CHANGECIPHERSPEC)
450    def should_add_ServerFinished(self):
451        self.add_record()
452        self.add_msg(TLSFinished())
453        raise self.ADDED_SERVERFINISHED()
454
455    @ATMT.state()
456    def ADDED_SERVERFINISHED(self):
457        pass
458
459    @ATMT.condition(ADDED_SERVERFINISHED)
460    def should_send_ServerFlight2(self):
461        self.flush_records()
462        raise self.SENT_SERVERFLIGHT2()
463
464    @ATMT.state()
465    def SENT_SERVERFLIGHT2(self):
466        self.vprint("TLS handshake completed!")
467        self.vprint_sessioninfo()
468        if self.is_echo_server:
469            self.vprint("Will now act as a simple echo server.")
470        raise self.WAITING_CLIENTDATA()
471
472    ####################### end of TLS handshake ##############################
473
474    @ATMT.state()
475    def WAITING_CLIENTDATA(self):
476        self.get_next_msg(self.max_client_idle_time, 1)
477        raise self.RECEIVED_CLIENTDATA()
478
479    @ATMT.state()
480    def RECEIVED_CLIENTDATA(self):
481        pass
482
483    @ATMT.condition(RECEIVED_CLIENTDATA)
484    def should_handle_ClientData(self):
485        if not self.buffer_in:
486            self.vprint("Client idle time maxed out.")
487            raise self.CLOSE_NOTIFY()
488        p = self.buffer_in[0]
489        self.buffer_in = self.buffer_in[1:]
490
491        recv_data = b""
492        if isinstance(p, TLSApplicationData):
493            print("> Received: %r" % p.data)
494            recv_data = p.data
495            lines = recv_data.split(b"\n")
496            stop = False
497            for l in lines:
498                if l.startswith(b"stop_server"):
499                    stop = True
500                    break
501            if stop:
502                raise self.CLOSE_NOTIFY_FINAL()
503        elif isinstance(p, TLSAlert):
504            print("> Received: %r" % p)
505            raise self.CLOSE_NOTIFY()
506        else:
507            print("> Received: %r" % p)
508
509        if recv_data.startswith(b"GET / HTTP/1.1"):
510            p = TLSApplicationData(data=self.http_sessioninfo())
511
512        if self.is_echo_server or recv_data.startswith(b"GET / HTTP/1.1"):
513            self.add_record()
514            self.add_msg(p)
515            raise self.ADDED_SERVERDATA()
516
517        raise self.HANDLED_CLIENTDATA()
518
519    @ATMT.state()
520    def HANDLED_CLIENTDATA(self):
521        raise self.WAITING_CLIENTDATA()
522
523    @ATMT.state()
524    def ADDED_SERVERDATA(self):
525        pass
526
527    @ATMT.condition(ADDED_SERVERDATA)
528    def should_send_ServerData(self):
529        self.flush_records()
530        raise self.SENT_SERVERDATA()
531
532    @ATMT.state()
533    def SENT_SERVERDATA(self):
534        raise self.WAITING_CLIENTDATA()
535
536    @ATMT.state()
537    def CLOSE_NOTIFY(self):
538        self.vprint()
539        self.vprint("Sending a TLSAlert to the client...")
540
541    @ATMT.condition(CLOSE_NOTIFY)
542    def close_session(self):
543        self.add_record()
544        self.add_msg(TLSAlert(level=1, descr=0))
545        try:
546            self.flush_records()
547        except:
548            self.vprint("Could not send termination Alert, maybe the client left?")
549            self.buffer_out = []
550        self.socket.close()
551        raise self.WAITING_CLIENT()
552
553    @ATMT.state()
554    def CLOSE_NOTIFY_FINAL(self):
555        self.vprint()
556        self.vprint("Sending a TLSAlert to the client...")
557
558    @ATMT.condition(CLOSE_NOTIFY_FINAL)
559    def close_session_final(self):
560        self.add_record()
561        self.add_msg(TLSAlert(level=1, descr=0))
562        try:
563            self.flush_records()
564        except:
565            self.vprint("Could not send termination Alert, maybe the client left?")
566        # We might call shutdown, but unit tests with s_client fail with this.
567        #self.socket.shutdown(1)
568        self.socket.close()
569        raise self.FINAL()
570
571    ########################## SSLv2 handshake ################################
572
573    @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=2)
574    def sslv2_should_handle_ClientHello(self):
575        self.raise_on_packet(SSLv2ClientHello,
576                             self.SSLv2_HANDLED_CLIENTHELLO)
577
578    @ATMT.state()
579    def SSLv2_HANDLED_CLIENTHELLO(self):
580        pass
581
582    @ATMT.condition(SSLv2_HANDLED_CLIENTHELLO)
583    def sslv2_should_add_ServerHello(self):
584        self.add_record(is_sslv2=True)
585        cert = self.mycert
586        ciphers = [0x010080, 0x020080, 0x030080, 0x040080,
587                   0x050080, 0x060040, 0x0700C0]
588        connection_id = randstring(16)
589        p = SSLv2ServerHello(cert=cert,
590                             ciphers=ciphers,
591                             connection_id=connection_id)
592        self.add_msg(p)
593        raise self.SSLv2_ADDED_SERVERHELLO()
594
595    @ATMT.state()
596    def SSLv2_ADDED_SERVERHELLO(self):
597        pass
598
599    @ATMT.condition(SSLv2_ADDED_SERVERHELLO)
600    def sslv2_should_send_ServerHello(self):
601        self.flush_records()
602        raise self.SSLv2_SENT_SERVERHELLO()
603
604    @ATMT.state()
605    def SSLv2_SENT_SERVERHELLO(self):
606        raise self.SSLv2_WAITING_CLIENTMASTERKEY()
607
608    @ATMT.state()
609    def SSLv2_WAITING_CLIENTMASTERKEY(self):
610        self.get_next_msg()
611        raise self.SSLv2_RECEIVED_CLIENTMASTERKEY()
612
613    @ATMT.state()
614    def SSLv2_RECEIVED_CLIENTMASTERKEY(self):
615        pass
616
617    @ATMT.condition(SSLv2_RECEIVED_CLIENTMASTERKEY, prio=1)
618    def sslv2_should_handle_ClientMasterKey(self):
619        self.raise_on_packet(SSLv2ClientMasterKey,
620                             self.SSLv2_HANDLED_CLIENTMASTERKEY)
621
622    @ATMT.condition(SSLv2_RECEIVED_CLIENTMASTERKEY, prio=2)
623    def missing_ClientMasterKey(self):
624        raise self.SSLv2_MISSING_CLIENTMASTERKEY()
625
626    @ATMT.state()
627    def SSLv2_MISSING_CLIENTMASTERKEY(self):
628        self.vprint("Missing SSLv2 ClientMasterKey!")
629        raise self.SSLv2_CLOSE_NOTIFY()
630
631    @ATMT.state()
632    def SSLv2_HANDLED_CLIENTMASTERKEY(self):
633        raise self.SSLv2_RECEIVED_CLIENTFINISHED()
634
635    @ATMT.state()
636    def SSLv2_RECEIVED_CLIENTFINISHED(self):
637        pass
638
639    @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=1)
640    def sslv2_should_handle_ClientFinished(self):
641        self.raise_on_packet(SSLv2ClientFinished,
642                             self.SSLv2_HANDLED_CLIENTFINISHED)
643
644    @ATMT.state()
645    def SSLv2_HANDLED_CLIENTFINISHED(self):
646        pass
647
648    @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=1)
649    def sslv2_should_add_ServerVerify_from_ClientFinished(self):
650        hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed]
651        if SSLv2ServerVerify in hs_msg:
652            return
653        self.add_record(is_sslv2=True)
654        p = SSLv2ServerVerify(challenge=self.cur_session.sslv2_challenge)
655        self.add_msg(p)
656        raise self.SSLv2_ADDED_SERVERVERIFY()
657
658    @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=2)
659    def sslv2_should_add_ServerVerify_from_NoClientFinished(self):
660        hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed]
661        if SSLv2ServerVerify in hs_msg:
662            return
663        self.add_record(is_sslv2=True)
664        p = SSLv2ServerVerify(challenge=self.cur_session.sslv2_challenge)
665        self.add_msg(p)
666        raise self.SSLv2_ADDED_SERVERVERIFY()
667
668    @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=3)
669    def sslv2_missing_ClientFinished(self):
670        raise self.SSLv2_MISSING_CLIENTFINISHED()
671
672    @ATMT.state()
673    def SSLv2_MISSING_CLIENTFINISHED(self):
674        self.vprint("Missing SSLv2 ClientFinished!")
675        raise self.SSLv2_CLOSE_NOTIFY()
676
677    @ATMT.state()
678    def SSLv2_ADDED_SERVERVERIFY(self):
679        pass
680
681    @ATMT.condition(SSLv2_ADDED_SERVERVERIFY)
682    def sslv2_should_send_ServerVerify(self):
683        self.flush_records()
684        raise self.SSLv2_SENT_SERVERVERIFY()
685
686    @ATMT.state()
687    def SSLv2_SENT_SERVERVERIFY(self):
688        hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed]
689        if SSLv2ClientFinished in hs_msg:
690            raise self.SSLv2_HANDLED_CLIENTFINISHED()
691        else:
692            raise self.SSLv2_RECEIVED_CLIENTFINISHED()
693
694    ####################### SSLv2 client authentication #######################
695
696    @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=2)
697    def sslv2_should_add_RequestCertificate(self):
698        hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed]
699        if not self.client_auth or SSLv2RequestCertificate in hs_msg:
700            return
701        self.add_record(is_sslv2=True)
702        self.add_msg(SSLv2RequestCertificate(challenge=randstring(16)))
703        raise self.SSLv2_ADDED_REQUESTCERTIFICATE()
704
705    @ATMT.state()
706    def SSLv2_ADDED_REQUESTCERTIFICATE(self):
707        pass
708
709    @ATMT.condition(SSLv2_ADDED_REQUESTCERTIFICATE)
710    def sslv2_should_send_RequestCertificate(self):
711        self.flush_records()
712        raise self.SSLv2_SENT_REQUESTCERTIFICATE()
713
714    @ATMT.state()
715    def SSLv2_SENT_REQUESTCERTIFICATE(self):
716        raise self.SSLv2_WAITING_CLIENTCERTIFICATE()
717
718    @ATMT.state()
719    def SSLv2_WAITING_CLIENTCERTIFICATE(self):
720        self.get_next_msg()
721        raise self.SSLv2_RECEIVED_CLIENTCERTIFICATE()
722
723    @ATMT.state()
724    def SSLv2_RECEIVED_CLIENTCERTIFICATE(self):
725        pass
726
727    @ATMT.condition(SSLv2_RECEIVED_CLIENTCERTIFICATE, prio=1)
728    def sslv2_should_handle_ClientCertificate(self):
729        self.raise_on_packet(SSLv2ClientCertificate,
730                             self.SSLv2_HANDLED_CLIENTCERTIFICATE)
731
732    @ATMT.condition(SSLv2_RECEIVED_CLIENTCERTIFICATE, prio=2)
733    def sslv2_missing_ClientCertificate(self):
734        raise self.SSLv2_MISSING_CLIENTCERTIFICATE()
735
736    @ATMT.state()
737    def SSLv2_MISSING_CLIENTCERTIFICATE(self):
738        self.vprint("Missing SSLv2 ClientCertificate!")
739        raise self.SSLv2_CLOSE_NOTIFY()
740
741    @ATMT.state()
742    def SSLv2_HANDLED_CLIENTCERTIFICATE(self):
743        selv.vprint("Received client certificate...")
744        # We could care about the client CA, but we don't.
745        raise self.SSLv2_HANDLED_CLIENTFINISHED()
746
747    ################### end of SSLv2 client authentication ####################
748
749    @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=3)
750    def sslv2_should_add_ServerFinished(self):
751        self.add_record(is_sslv2=True)
752        self.add_msg(SSLv2ServerFinished(sid=randstring(16)))
753        raise self.SSLv2_ADDED_SERVERFINISHED()
754
755    @ATMT.state()
756    def SSLv2_ADDED_SERVERFINISHED(self):
757        pass
758
759    @ATMT.condition(SSLv2_ADDED_SERVERFINISHED)
760    def sslv2_should_send_ServerFinished(self):
761        self.flush_records()
762        raise self.SSLv2_SENT_SERVERFINISHED()
763
764    @ATMT.state()
765    def SSLv2_SENT_SERVERFINISHED(self):
766        self.vprint("SSLv2 handshake completed!")
767        self.vprint_sessioninfo()
768        if self.is_echo_server:
769            self.vprint("Will now act as a simple echo server.")
770        raise self.SSLv2_WAITING_CLIENTDATA()
771
772    ######################## end of SSLv2 handshake ###########################
773
774    @ATMT.state()
775    def SSLv2_WAITING_CLIENTDATA(self):
776        self.get_next_msg(self.max_client_idle_time, 1)
777        raise self.SSLv2_RECEIVED_CLIENTDATA()
778
779    @ATMT.state()
780    def SSLv2_RECEIVED_CLIENTDATA(self):
781        pass
782
783    @ATMT.condition(SSLv2_RECEIVED_CLIENTDATA)
784    def sslv2_should_handle_ClientData(self):
785        if not self.buffer_in:
786            self.vprint("Client idle time maxed out.")
787            raise self.SSLv2_CLOSE_NOTIFY()
788        p = self.buffer_in[0]
789        self.buffer_in = self.buffer_in[1:]
790        if hasattr(p, "load"):
791            cli_data = p.load
792            print("> Received: %r" % cli_data)
793            if cli_data.startswith(b"goodbye"):
794                self.vprint()
795                self.vprint("Seems like the client left...")
796                raise self.WAITING_CLIENT()
797        else:
798            cli_data = str(p)
799            print("> Received: %r" % p)
800
801        lines = cli_data.split(b"\n")
802        stop = False
803        for l in lines:
804            if l.startswith(b"stop_server"):
805                stop = True
806                break
807        if stop:
808            raise self.SSLv2_CLOSE_NOTIFY_FINAL()
809
810        answer = b""
811        if cli_data.startswith(b"GET / HTTP/1.1"):
812            p = Raw(self.http_sessioninfo())
813
814        if self.is_echo_server or recv_data.startswith(b"GET / HTTP/1.1"):
815            self.add_record(is_sslv2=True)
816            self.add_msg(p)
817            raise self.SSLv2_ADDED_SERVERDATA()
818
819        raise self.SSLv2_HANDLED_CLIENTDATA()
820
821    @ATMT.state()
822    def SSLv2_HANDLED_CLIENTDATA(self):
823        raise self.SSLv2_WAITING_CLIENTDATA()
824
825    @ATMT.state()
826    def SSLv2_ADDED_SERVERDATA(self):
827        pass
828
829    @ATMT.condition(SSLv2_ADDED_SERVERDATA)
830    def sslv2_should_send_ServerData(self):
831        self.flush_records()
832        raise self.SSLv2_SENT_SERVERDATA()
833
834    @ATMT.state()
835    def SSLv2_SENT_SERVERDATA(self):
836        raise self.SSLv2_WAITING_CLIENTDATA()
837
838    @ATMT.state()
839    def SSLv2_CLOSE_NOTIFY(self):
840        """
841        There is no proper way to end an SSLv2 session.
842        We try and send a 'goodbye' message as a substitute.
843        """
844        self.vprint()
845        self.vprint("Trying to send 'goodbye' to the client...")
846
847    @ATMT.condition(SSLv2_CLOSE_NOTIFY)
848    def sslv2_close_session(self):
849        self.add_record()
850        self.add_msg(Raw('goodbye'))
851        try:
852            self.flush_records()
853        except:
854            self.vprint("Could not send our goodbye. The client probably left.")
855            self.buffer_out = []
856        self.socket.close()
857        raise self.WAITING_CLIENT()
858
859    @ATMT.state()
860    def SSLv2_CLOSE_NOTIFY_FINAL(self):
861        """
862        There is no proper way to end an SSLv2 session.
863        We try and send a 'goodbye' message as a substitute.
864        """
865        self.vprint()
866        self.vprint("Trying to send 'goodbye' to the client...")
867
868    @ATMT.condition(SSLv2_CLOSE_NOTIFY_FINAL)
869    def sslv2_close_session_final(self):
870        self.add_record()
871        self.add_msg(Raw('goodbye'))
872        try:
873            self.flush_records()
874        except:
875            self.vprint("Could not send our goodbye. The client probably left.")
876        self.socket.close()
877        raise self.FINAL()
878
879    @ATMT.state(final=True)
880    def FINAL(self):
881        self.vprint("Closing server socket...")
882        self.serversocket.close()
883        self.vprint("Ending TLS server automaton.")
884
885