From 647a2a113a1d484dd65244793e37e10c6e1721ac Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 25 Oct 2019 12:46:28 -0700 Subject: [PATCH] add option to not use pipes, to make it easier to see the output... start adding an end to end test --- ntunnel.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/ntunnel.py b/ntunnel.py index 1cc1de4..921a587 100644 --- a/ntunnel.py +++ b/ntunnel.py @@ -7,7 +7,7 @@ from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives.serialization import load_pem_private_key from noise.connection import NoiseConnection, Keypair -import tracemalloc; tracemalloc.start() +#import tracemalloc; tracemalloc.start() import argparse import asyncio @@ -242,6 +242,12 @@ class Tests_misc(unittest.TestCase): msg = os.urandom(i) self.assertEqual(len(msg), dec(enc(msg) + msg)) +def cmd_client(args): + pass + +def cmd_server(args): + pass + def cmd_genkey(args): keypair = genkeypair() @@ -258,7 +264,7 @@ def cmd_genkey(args): print('ntun-x448', base64.urlsafe_b64encode(pub).decode('ascii'), file=fp) except FileExistsError: print('failed to create %s, file exists.' % fname, file=sys.stderr) - sys.exit(1) + sys.exit(2) enc = serialization.Encoding.PEM format = serialization.PrivateFormat.PKCS8 @@ -275,6 +281,20 @@ def main(): parser_gk.add_argument('fname', type=str, help='file name for the key') parser_gk.set_defaults(func=cmd_genkey) + parser_serv = subparsers.add_parser('server', help='run a server') + parser_serv.add_argument('-c', action='append', type=str, help='file of authorized client keys, or a .pub file') + parser_serv.add_argument('servkey', type=str, help='file name for the server key') + parser_serv.add_argument('servlisten', type=str, help='Connection that the server listens on') + parser_serv.add_argument('servtarget', type=str, help='Connection that the server connects to') + parser_serv.set_defaults(func=cmd_server) + + parser_client = subparsers.add_parser('client', help='run a client') + parser_client.add_argument('clientkey', type=str, help='file name for the client private key') + parser_client.add_argument('servkey', type=str, help='file name for the server public key') + parser_client.add_argument('clientlisten', type=str, help='Connection that the client listens on') + parser_client.add_argument('clienttarget', type=str, help='Connection that the client connects to') + parser_client.set_defaults(func=cmd_client) + args = parser.parse_args() try: @@ -327,14 +347,56 @@ class TestMain(unittest.TestCase): # And that it exited w/ the correct code self.assertEqual(proc.returncode, 5) - def run_with_args(self, *args): + def run_with_args(self, *args, pipes=True): + kwargs = {} + if pipes: + kwargs.update(dict( + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE)) return asyncio.create_subprocess_exec(sys.executable, - __file__, *args, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE) + # XXX - figure out how to add coverage data on these runs + #'-m', 'coverage', 'run', '-p', + __file__, *args, **kwargs) - def test_both(self): - pass + async def genkey(self, name): + proc = await self.run_with_args('genkey', name) + + await proc.wait() + + self.assertEqual(proc.returncode, 0) + + @async_test + async def test_both(self): + # Generate necessar keys + await self.genkey('server_key') + await self.genkey('client_key') + + ptclientstr = _makeunix(os.path.join(self.tempdir, 'incclient.sock')) + incservstr = _makeunix(os.path.join(self.tempdir, 'incserv.sock')) + servtargstr = _makeunix(os.path.join(self.tempdir, 'servtarget.sock')) + + # Setup pt target listener + pttarg = _makeunix('servtarget.sock') + ptsock = [] + def ptsockaccept(reader, writer, ptsock=ptsock): + ptsock.append((reader, writer)) + + # Bind to pt listener + lsock = await listensockstr(pttarg, ptsockaccept) + + # Startup the server + server = await self.run_with_args('server', + '-c', 'client_key.pub', + 'server_key', incservstr, servtargstr, + pipes=False) + + # Startup the client + server = await self.run_with_args('client', + 'client_key', 'server_key.pub', ptclientstr, incservstr, + pipes=False) + + # Connect to the client + reader, writer = await connectsockstr(ptclientstr) @async_test async def test_genkey(self): @@ -343,6 +405,8 @@ class TestMain(unittest.TestCase): await proc.wait() + #print(await proc.communicate()) + self.assertEqual(proc.returncode, 0) with open('somefile.pub', encoding='ascii') as fp: @@ -370,7 +434,7 @@ class TestMain(unittest.TestCase): self.assertEqual(b'failed to create somefile.pub, file exists.\n', stderrdata) # And that it exited w/ the correct code - self.assertEqual(proc.returncode, 1) + self.assertEqual(proc.returncode, 2) class TestNoiseFowarder(unittest.TestCase): def setUp(self):