Mercurial > dropbear
annotate test/test_dropbear.py @ 1870:0dcc5b0d93fa
Make re-exec work with "dropbearmulti dropbear"
The re-exec needs to know to use the dropbearmulti binary instead.
Add a test for this case.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 01 Feb 2022 22:18:23 +0800 |
parents | 49ce974c3215 |
children | 81991ded740f |
rev | line source |
---|---|
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
1 import subprocess |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
2 import os |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
3 import pty |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
4 import tempfile |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
5 import logging |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
6 import time |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
7 import socketserver |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
8 import threading |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
9 import queue |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
10 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
11 import pytest |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
12 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
13 LOCALADDR="127.0.5.5" |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
14 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
15 @pytest.fixture(scope="module") |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
16 def dropbear(request): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
17 opt = request.config.option |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
18 if opt.remote: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
19 yield None |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
20 return |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
21 |
1870
0dcc5b0d93fa
Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents:
1864
diff
changeset
|
22 # split so that "dropbearmulti dropbear" works |
0dcc5b0d93fa
Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents:
1864
diff
changeset
|
23 args = opt.dropbear.split() + [ |
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
24 "-p", LOCALADDR, # bind locally only |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
25 "-r", opt.hostkey, |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
26 "-p", opt.port, |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
27 "-F", "-E", |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
28 ] |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
29 p = subprocess.Popen(args, stderr=subprocess.PIPE, text=True) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
30 # Wait until it has started listening |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
31 for l in p.stderr: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
32 if "Not backgrounding" in l: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
33 break |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
34 # Check it's still running |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
35 assert p.poll() is None |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
36 # Ready |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
37 yield p |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
38 p.terminate() |
1852
e0c1825c567d
Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents:
1841
diff
changeset
|
39 print("Terminated dropbear. Flushing output:") |
e0c1825c567d
Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents:
1841
diff
changeset
|
40 for l in p.stderr: |
e0c1825c567d
Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents:
1841
diff
changeset
|
41 print(l.rstrip()) |
e0c1825c567d
Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents:
1841
diff
changeset
|
42 print("Done") |
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
43 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
44 def dbclient(request, *args, **kwargs): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
45 opt = request.config.option |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
46 host = opt.remote or LOCALADDR |
1870
0dcc5b0d93fa
Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents:
1864
diff
changeset
|
47 # split so that "dropbearmulti dbclient" works |
0dcc5b0d93fa
Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents:
1864
diff
changeset
|
48 base_args = opt.dbclient.split() + ["-y", host, "-p", opt.port] |
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
49 if opt.user: |
1870
0dcc5b0d93fa
Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents:
1864
diff
changeset
|
50 base_args.extend(['-l', opt.user]) |
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
51 full_args = base_args + list(args) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
52 bg = kwargs.get("background") |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
53 if "background" in kwargs: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
54 del kwargs["background"] |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
55 if bg: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
56 return subprocess.Popen(full_args, **kwargs) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
57 else: |
1841
d757f48ae29f
Add a default 10 second timeout for tests
Matt Johnston <matt@ucc.asn.au>
parents:
1836
diff
changeset
|
58 kwargs.setdefault("timeout", 10) |
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
59 # wait for response |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
60 return subprocess.run(full_args, **kwargs) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
61 |
1863 | 62 def own_venv_command(): |
63 """ Returns a command to run as a prefix to get the same venv | |
64 as the current running Python. Returns '' on not a virtualenv | |
65 """ | |
66 try: | |
67 venv = os.environ['VIRTUAL_ENV'] | |
68 except KeyError: | |
69 return "" | |
70 | |
71 # note: bash/zsh unix specific | |
72 return f"source {venv}/bin/activate" | |
73 | |
1836
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
74 class HandleTcp(socketserver.ThreadingMixIn, socketserver.TCPServer): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
75 """ Listens for a single incoming request, sends a response if given, |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
76 and returns the inbound data. |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
77 Reponse can be a queue object, in which case each item in the queue will |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
78 be sent as a response, until it receives a None item. |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
79 """ |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
80 def __init__(self, port, timeout, response=None): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
81 super().__init__(('localhost', port), self.Handler) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
82 self.port = port |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
83 self.timeout = timeout |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
84 self.response = response |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
85 self.sink = None |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
86 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
87 class Handler(socketserver.StreamRequestHandler): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
88 def handle(self): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
89 if isinstance(self.server.response, queue.Queue): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
90 while True: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
91 i = self.server.response.get() |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
92 if i is None: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
93 break |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
94 self.wfile.write(i) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
95 elif self.server.response: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
96 self.wfile.write(self.server.response) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
97 assert self.server.sink is None, ">1 request sent to handler" |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
98 self.server.sink = self.rfile.read() |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
99 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
100 def __enter__(self): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
101 self.server_thread = threading.Thread(target=self.serve_forever) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
102 self.server_thread.daemon = True |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
103 self.server_thread.start() |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
104 return self |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
105 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
106 def __exit__(self, *exc_stuff): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
107 self.shutdown() |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
108 self.server_thread.join() |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
109 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
110 def inbound(self): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
111 """ Returns the data sent to the socket """ |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
112 return self.sink |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
113 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
114 def readall_socket(sock): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
115 b = [] |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
116 while True: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
117 i = sock.recv(4096) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
118 if not i: |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
119 break |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
120 b.append(i) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
121 return b''.join(b) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
122 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
123 # returns a str |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
124 def random_alnum(size): |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
125 r = os.urandom(500 + size*5) |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
126 return bytes(i for i in r if bytes((i,)).isalnum())[:size].decode() |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
127 |
06c7ddbb9dd6
Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff
changeset
|
128 |