• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 """
7 TLS server automaton. This makes for a primitive TLS stack.
8 Obviously you need rights for network access.
9 
10 We support versions SSLv2 to TLS 1.2, along with many features.
11 There is no session resumption mechanism for now.
12 
13 In 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 
19 from __future__ import print_function
20 import socket
21 
22 from scapy.pton_ntop import inet_pton
23 from scapy.utils import randstring, repr_hex
24 from scapy.automaton import ATMT
25 from scapy.layers.tls.automaton import _TLSAutomaton
26 from scapy.layers.tls.cert import PrivKeyRSA, PrivKeyECDSA
27 from scapy.layers.tls.basefields import _tls_version
28 from scapy.layers.tls.session import tlsSession
29 from scapy.layers.tls.handshake import *
30 from scapy.layers.tls.handshake_sslv2 import *
31 from scapy.layers.tls.record import (TLS, TLSAlert, TLSChangeCipherSpec,
32                                      TLSApplicationData)
33 from scapy.layers.tls.crypto.suites import (_tls_cipher_suites_cls,
34                                             get_usable_ciphersuites)
35 
36 
37 class 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