def test_set_password(): '''Test the SETPASSWORD command''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_set_password(): failed to connect to server: {status.info()}" # Moved all the test code to integration_setup.init_admin(), because that kind of setup is # needed for other tests. status = init_admin(conn, dbdata) assert not status.error( ), f"test_set_password(): init_admin failed: {status.info()}" badpassword = Password('MyS3cretPassw*rd') newpassword = Password('Renovate-Baggy-Grunt-Override') status = serverconn.setpassword(conn, badpassword.hashstring, newpassword.hashstring) assert status.error() and status['Code'] == 402, \ "test_set_password: failed to catch bad password" status = serverconn.setpassword(conn, dbdata['admin_password'].hashstring, newpassword.hashstring) assert not status.error(), "test_set_password: failed to update password" conn.disconnect()
def test_connect(): '''Tests just the basic connection to the server and parsing the greeting''' conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_connect(): failed to connect to server: {status.info()}" conn.disconnect()
def test_reset_password(): '''Tests password reset code''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_login(): failed to connect to server: {status.info()}" password = Password('Linguini2Pegboard*Album') devid = '14142135-9c22-4d3e-84a3-2aa281f65714' keypair = EncryptionPair( CryptoString(r'CURVE25519:mO?WWA-k2B2O|Z%fA`~s3^$iiN{5R->#jxO@cy6{'), CryptoString(r'CURVE25519:2bLf2vMA?GA2?L~tv<PA9XOw6e}V~ObNi7C&qek>')) status = serverconn.regcode(conn, 'admin', dbdata['admin_regcode'], password.hashstring, devid, keypair, '') assert not status.error( ), f"test_reset_password(): regcode failed: {status.info()}" status = serverconn.login(conn, dbdata['admin_wid'], CryptoString(dbdata['oekey'])) assert not status.error( ), f"test_reset_password(): login phase failed: {status.info()}" status = serverconn.password(conn, dbdata['admin_wid'], password.hashstring) assert not status.error( ), f"test_reset_password(): password phase failed: {status.info()}" status = serverconn.device(conn, devid, keypair) assert not status.error(), "test_reset_password(): device phase failed: " \ f"{status.info()}" status = init_user(conn, dbdata) assert not status.error( ), f"test_reset_password(): user init failed: {status.info()}" status = serverconn.reset_password(conn, dbdata['user_wid']) assert not status.error( ), f"test_reset_password(): password reset failed: {status.info()}" resetdata = status status = serverconn.logout(conn) assert not status.error( ), f"test_reset_password(): admin logout failed: {status.info()}" newpassword = Password('SomeOth3rPassw*rd') status = serverconn.passcode(conn, dbdata['user_wid'], resetdata['resetcode'], newpassword.hashstring) assert not status.error( ), f"test_reset_password(): passcode failed: {status.info()}"
def test_preregister_regcode(): '''Test the preregister and regcode commands''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_login(): failed to connect to server: {status.info()}" password = Password('Linguini2Pegboard*Album') devid = '14142135-9c22-4d3e-84a3-2aa281f65714' keypair = EncryptionPair( CryptoString(r'CURVE25519:mO?WWA-k2B2O|Z%fA`~s3^$iiN{5R->#jxO@cy6{'), CryptoString(r'CURVE25519:2bLf2vMA?GA2?L~tv<PA9XOw6e}V~ObNi7C&qek>')) status = serverconn.regcode(conn, 'admin', dbdata['admin_regcode'], password.hashstring, devid, keypair, '') assert not status.error( ), f"test_preregister_regcode(): regcode failed: {status.info()}" status = serverconn.login(conn, dbdata['admin_wid'], CryptoString(dbdata['oekey'])) assert not status.error( ), f"test_preregister_regcode(): login phase failed: {status.info()}" status = serverconn.password(conn, dbdata['admin_wid'], password.hashstring) assert not status.error( ), f"test_preregister_regcode(): password phase failed: {status.info()}" status = serverconn.device(conn, devid, keypair) assert not status.error(), "test_preregister_regcode(): device phase failed: " \ f"{status.info()}" status = serverconn.preregister(conn, '', 'csimons', 'example.net') assert not status.error( ), "test_preregister_regcode(): uid preregistration failed" assert status['domain'] == 'example.net' and 'wid' in status and 'regcode' in status and \ status['uid'] == 'csimons', "test_preregister_regcode(): failed to return expected data" regdata = status password = Password('MyS3cretPassw*rd') devpair = EncryptionPair() status = serverconn.regcode(conn, 'csimons', regdata['regcode'], password.hashstring, '11111111-1111-1111-1111-111111111111', devpair, 'example.net') assert not status.error(), "test_preregister_regcode(): uid regcode failed" conn.disconnect()
def keycard_admin(config, conn) -> dict: '''Uploads a keycard entry for the admin account''' conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_addentry(): failed to connect to server: {status.info()}" crepair = EncryptionPair( CryptoString(r'CURVE25519:mO?WWA-k2B2O|Z%fA`~s3^$iiN{5R->#jxO@cy6{'), CryptoString(r'CURVE25519:2bLf2vMA?GA2?L~tv<PA9XOw6e}V~ObNi7C&qek>')) crspair = SigningPair( CryptoString(r'ED25519:E?_z~5@+tkQz!iXK?oV<Zx(ec;=27C8Pjm((kRc|'), CryptoString(r'ED25519:u4#h6LEwM6Aa+f<++?lma4Iy63^}V$JOP~ejYkB;')) epair = EncryptionPair( CryptoString(r'CURVE25519:Umbw0Y<^cf1DN|>X38HCZO@Je(zSe6crC6X_C_0F'), CryptoString(r'CURVE25519:Bw`F@ITv#sE)2NnngXWm7RQkxg{TYhZQbebcF5b$')) entry = keycard.UserEntry() entry.set_fields({ 'Name': 'Administrator', 'Workspace-ID': config['admin_wid'], 'User-ID': 'admin', 'Domain': 'example.com', 'Contact-Request-Verification-Key': crspair.get_public_key(), 'Contact-Request-Encryption-Key': crepair.get_public_key(), 'Public-Encryption-Key': epair.get_public_key() }) status = serverconn.addentry(conn, entry, CryptoString(config['ovkey']), crspair) assert not status.error( ), f"test_addentry: failed to add entry: {status.info()}" return { 'admin_crepair': crepair, 'admin_crspair': crspair, 'admin_epair': epair }
def test_addentry(): '''Tests the addentry() command''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_addentry(): failed to connect to server: {status.info()}" # Moved all the test code to integration_setup.init_admin(), because that kind of setup is # needed for other tests. status = init_admin(conn, dbdata) assert not status.error( ), f"test_addentry(): init_admin failed: {status.info()}" conn.disconnect()
def test_iscurrent(): '''Tests the iscurrent() command''' dbconn = setup_test() init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_login(): failed to connect to server: {status.info()}" status = serverconn.iscurrent(conn, 1) assert not status.error( ), f"test_iscurrent(): org failure check failed: {status.info()}" status = serverconn.iscurrent(conn, 2) assert not status.error( ), f"test_iscurrent(): org success check failed: {status.info()}"
def test_unregister(): '''Tests the unregister() command''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_unregister(): failed to connect to server: {status.info()}" status = init_admin(conn, dbdata) assert not status.error( ), f"test_unregister(): init_admin failed: {status.info()}" status = init_user(conn, dbdata) assert not status.error( ), f"test_unregister(): init_user failed: {status.info()}" status = serverconn.logout(conn) assert not status.error( ), f"test_unregister(): logout failed: {status.info()}" status = serverconn.login(conn, dbdata['user_wid'], CryptoString(dbdata['oekey'])) assert not status.error( ), f"test_unregister(): user login phase failed: {status.info()}" status = serverconn.password(conn, dbdata['user_wid'], dbdata['user_password'].hashstring) assert not status.error( ), f"test_unregister(): password phase failed: {status.info()}" status = serverconn.device(conn, dbdata['user_devid'], dbdata['user_devpair']) assert not status.error( ), f"test_unregister(): device phase failed: {status.info()}" status = serverconn.unregister(conn, dbdata['user_password'].hashstring, '') assert not status.error( ), f"test_unregister(): unregister failed: {status.info()}" conn.disconnect()
def test_getwid(): '''Tests serverconn.getwid(), which returns a WID for an Anselus address''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_getwid(): failed to connect to server: {status.info()}" status = init_admin(conn, dbdata) assert not status.error( ), f"test_getwid(): init_admin failed: {status.info()}" status = serverconn.getwid(conn, 'admin', 'example.com') assert not status.error(), f"test_getwid(): getwid failed: {status.info()}" assert status['Workspace-ID'] == dbdata[ 'admin_wid'], "test_getwid(): admin wid mismatch" conn.disconnect()
def test_overflow(): '''Tests the server's command handling for commands greater than 8K''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() assert conn.connect('localhost', 2001), "Connection to server at localhost:2001 failed" # password is 'SandstoneAgendaTricycle' pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCq' \ 'dcCYkJLok65qussSyhN5TTZP+OTgzEI' devid = '22222222-2222-2222-2222-222222222222' devpair = EncryptionPair( CryptoString(r'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z'), CryptoString(r'CURVE25519:W30{oJ?w~NBbj{F8Ag4~<bcWy6_uQ{i{X?NDq4^l')) dbdata['pwhash'] = pwhash dbdata['devid'] = devid dbdata['devpair'] = devpair regcode_admin(dbdata, conn) login_admin(dbdata, conn) conn.send_message({ 'Action': "REGISTER", 'Data': { 'Workspace-ID': 'A' * 10240, 'Password-Hash': pwhash, 'Device-ID': '11111111-1111-1111-1111-111111111111', 'Device-Key': 'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z' } }) response = conn.read_response(server_response) assert response['Code'] == 400 and response['Status'] == 'BAD REQUEST', \ 'test_overflow: failed to catch overflow' conn.send_message({'Action': "QUIT"})
def test_set_status(): '''Test the SETSTATUS command''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_set_workstatus(): failed to connect to server: {status.info()}" status = init_admin(conn, dbdata) assert not status.error( ), f"test_set_workstatus(): init_admin failed: {status.info()}" status = init_user(conn, dbdata) assert not status.error( ), f"test_set_workstatus(): init_user failed: {status.info()}" status = serverconn.setstatus(conn, dbdata['user_wid'], 'disabled') assert not status.error( ), f"test_set_workstatus(): set_workstatus failed: {status.info()}" conn.disconnect()
def test_devkey(): '''Tests the devkey() command''' dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_devkey(): failed to connect to server: {status.info()}" status = init_admin(conn, dbdata) assert not status.error( ), f"test_devkey(): init_admin failed: {status.info()}" newdevpair = EncryptionPair( CryptoString(r'CURVE25519:mO?WWA-k2B2O|Z%fA`~s3^$iiN{5R->#jxO@cy6{'), CryptoString(r'CURVE25519:2bLf2vMA?GA2?L~tv<PA9XOw6e}V~ObNi7C&qek>')) status = serverconn.devkey(conn, dbdata['admin_devid'], dbdata['admin_devpair'], newdevpair) assert not status.error( ), f"test_devkey(): error returned: {status.info()}" conn.disconnect()
def test_register(): '''Test worskpace registration''' # Registration testing only works when the server uses either network or public mode serverdbdata = load_server_config_file() if serverdbdata['global']['registration'] not in ['network', 'public']: return dbconn = setup_test() init_server(dbconn) conn = serverconn.ServerConnection() status = conn.connect('localhost', 2001) assert not status.error( ), f"test_login(): failed to connect to server: {status.info()}" password = Password('MyS3cretPassw*rd') devpair = EncryptionPair() status = serverconn.register(conn, 'csimons', password.hashstring, devpair.public) assert not status.error( ), f"test_register: failed to register test account: {status.info()}" conn.disconnect()
def test_unregister(): '''Test the UNREGISTER command''' # Testing the UNREGISTER command only works when the server uses either network or public mode serverconfig = load_server_config_file() if serverconfig['global']['registration'] not in ['network', 'public']: return dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() assert conn.connect('localhost', 2001), "Connection to server at localhost:2001 failed" # password is 'SandstoneAgendaTricycle' pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCq' \ 'dcCYkJLok65qussSyhN5TTZP+OTgzEI' devid = '22222222-2222-2222-2222-222222222222' devpair = EncryptionPair( CryptoString(r'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z'), CryptoString(r'CURVE25519:W30{oJ?w~NBbj{F8Ag4~<bcWy6_uQ{i{X?NDq4^l')) dbdata['pwhash'] = pwhash dbdata['devid'] = devid dbdata['devpair'] = devpair regcode_admin(dbdata, conn) login_admin(dbdata, conn) userwid = '11111111-1111-1111-1111-111111111111' # password is 'SandstoneAgendaTricycle' pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCq' \ 'dcCYkJLok65qussSyhN5TTZP+OTgzEI' devkey = 'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z' conn.send_message({ 'Action': "REGISTER", 'Data': { 'Workspace-ID': userwid, 'Password-Hash': pwhash, 'Device-ID': devid, 'Device-Key': devkey } }) response = conn.read_response(server_response) assert response['Code'] == 201 and response['Status'] == 'REGISTERED', \ f"test_unregister: test user registration failed: {response['Status']}" # Subtest #1: Try to unregister the admin account conn.send_message({ 'Action': "UNREGISTER", 'Data': { 'Password-Hash': pwhash } }) response = conn.read_response(server_response) assert response['Code'] == 403 and response['Status'] == 'FORBIDDEN', \ "test_unregister(): failed to properly handle trying to unregister admin account" conn.send_message({'Action': "LOGOUT", 'Data': {}}) response = conn.read_response(server_response) assert response['Code'] == 200 and response['Status'] == 'OK' # Set up for subtest #2: log in as the user status = serverconn.login(conn, userwid, CryptoString(dbdata['oekey'])) assert not status.error( ), f"test_unregister(): user login phase failed: {status.info()}" status = serverconn.password(conn, userwid, pwhash) assert not status.error( ), f"test_unregister(): password phase failed: {status.info()}" status = serverconn.device(conn, devid, devpair) assert not status.error( ), f"test_unregister(): device phase failed: {status.info()}" # As a general rule, these anselusd integration tests don't call the regular pyanselus client # library calls because we do extra validation. However, we're going to make an exception in # this test because LOGIN and ADDENTRY are both really big. usercard = keycard.UserEntry() usercard.set_fields({ 'Name': 'Corbin Simons', 'Workspace-ID': userwid, 'User-ID': 'csimons', 'Domain': 'example.com', 'Contact-Request-Verification-Key': 'ED25519:E?_z~5@+tkQz!iXK?oV<Zx(ec;=27C8Pjm((kRc|', 'Contact-Request-Encryption-Key': 'CURVE25519:yBZ0{1fE9{2<b~#i^R+JT-yh-y5M(Wyw_)}_SZOn', 'Public-Encryption-Key': 'CURVE25519:_`UC|vltn_%P5}~vwV^)oY){#uvQSSy(dOD_l(yE' }) crspair = SigningPair( CryptoString(r'ED25519:E?_z~5@+tkQz!iXK?oV<Zx(ec;=27C8Pjm((kRc|'), CryptoString(r'ED25519:u4#h6LEwM6Aa+f<++?lma4Iy63^}V$JOP~ejYkB;')) status = usercard.is_data_compliant() assert not status.error( ), f"test_unregister: user card not compliant: {status.info()}" status = serverconn.addentry(conn, usercard, CryptoString(dbdata['ovkey']), crspair) assert not status.error(), f"test_unregister: addentry() failed: {status.info()}\n" \ f"Server Info: {status['Info']}" # Subtest #2: Unregister regular user from admin account conn.send_message({ 'Action': "UNREGISTER", 'Data': { 'Workspace-ID': userwid, 'Password-Hash': pwhash } }) response = conn.read_response(server_response) assert response['Code'] == 202 and response['Status'] == 'UNREGISTERED', \ f"test_unregister(): user unregistration failed: {response['Status']}" # Check to make sure the database end was handled correctly cur = dbconn.cursor() cur.execute('SELECT password,status FROM workspaces WHERE wid = %s ', (userwid, )) row = cur.fetchone() assert row, "test_unregister(): cleanup check query found no rows" assert row[0] == '-' and row[1] == 'deleted', \ "test_unregister(): server failed to clean up database properly" conn.send_message({'Action': "QUIT"})
def test_register_failures(): '''Tests the server's REGISTER command with failure conditions''' # Testing the REGISTER command only works when the server uses either network or public mode serverconfig = load_server_config_file() if serverconfig['global']['registration'] not in ['network', 'public']: return dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() assert conn.connect('localhost', 2001), "Connection to server at localhost:2001 failed" # password is 'SandstoneAgendaTricycle' pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCq' \ 'dcCYkJLok65qussSyhN5TTZP+OTgzEI' devid = '22222222-2222-2222-2222-222222222222' devpair = EncryptionPair( CryptoString(r'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z'), CryptoString(r'CURVE25519:W30{oJ?w~NBbj{F8Ag4~<bcWy6_uQ{i{X?NDq4^l')) dbdata['pwhash'] = pwhash dbdata['devid'] = devid dbdata['devpair'] = devpair regcode_admin(dbdata, conn) login_admin(dbdata, conn) # Test #1: Attempt registration with unsupported encryption type conn.send_message({ 'Action': "REGISTER", 'Data': { 'Workspace-ID': '11111111-1111-1111-1111-222222222222', 'Password-Hash': pwhash, 'Device-ID': '11111111-1111-1111-1111-111111111111', 'Device-Key': '3DES:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z' } }) response = conn.read_response(server_response) assert response['Code'] == 309 and response['Status'] == 'ENCRYPTION TYPE NOT SUPPORTED', \ 'test_register_failures: subtest #1 failed to catch unsupported encryption' # Test #2: Send bad WID conn.send_message({ 'Action': "REGISTER", 'Data': { 'Workspace-ID': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 'Password-Hash': pwhash, 'Device-ID': '11111111-1111-1111-1111-111111111111', 'Device-Key': 'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z' } }) response = conn.read_response(server_response) assert response['Code'] == 400 and response['Status'] == 'BAD REQUEST', \ 'test_register_failures: subtest #2 failed to catch a bad WID' conn.send_message({'Action': "QUIT"})
def __init__(self): self.fs = ClientStorage() self.active_profile = '' self.conn = serverconn.ServerConnection()
def test_register(): '''Tests the server's REGISTER command - success and duplicate WID condition''' # Testing the REGISTER command only works when the server uses either network or public mode serverconfig = load_server_config_file() if serverconfig['global']['registration'] not in ['network', 'public']: return dbconn = setup_test() dbdata = init_server(dbconn) conn = serverconn.ServerConnection() assert conn.connect('localhost', 2001), "Connection to server at localhost:2001 failed" # password is 'SandstoneAgendaTricycle' pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCq' \ 'dcCYkJLok65qussSyhN5TTZP+OTgzEI' devid = '22222222-2222-2222-2222-222222222222' devpair = EncryptionPair( CryptoString(r'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z'), CryptoString(r'CURVE25519:W30{oJ?w~NBbj{F8Ag4~<bcWy6_uQ{i{X?NDq4^l')) dbdata['pwhash'] = pwhash dbdata['devid'] = devid dbdata['devpair'] = devpair regcode_admin(dbdata, conn) login_admin(dbdata, conn) wid = '11111111-1111-1111-1111-111111111111' # password is 'SandstoneAgendaTricycle' pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCq' \ 'dcCYkJLok65qussSyhN5TTZP+OTgzEI' devkey = 'CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z' # Subtest #1: Regular registration that is supposed to succeed conn.send_message({ 'Action': "REGISTER", 'Data': { 'Workspace-ID': wid, 'Password-Hash': pwhash, 'Device-ID': '11111111-1111-1111-1111-111111111111', 'Device-Key': devkey } }) response = conn.read_response(server_response) assert response['Code'] == 201 and response['Status'] == 'REGISTERED', \ 'test_register: subtest #1 returned an error' # Subtest #2: Attempt registration of existing WID conn.send_message({ 'Action': "REGISTER", 'Data': { 'Workspace-ID': wid, 'Password-Hash': pwhash, 'Device-ID': '11111111-1111-1111-1111-111111111111', 'Device-Key': devkey } }) response = conn.read_response(server_response) assert response['Code'] == 408 and response['Status'] == 'RESOURCE EXISTS', \ 'test_register: subtest #2 failed to catch duplicate registration' conn.send_message({'Action': "QUIT"})