diff -Nru cyrus-sasl-2.1.27/tests/runtests.py cyrus-sasl-2.1.27-beldmit/tests/runtests.py --- cyrus-sasl-2.1.27/tests/runtests.py 2020-12-23 14:31:35.564537485 +0100 +++ cyrus-sasl-2.1.27-beldmit/tests/runtests.py 2020-12-23 14:30:46.933219377 +0100 @@ -313,6 +313,99 @@ return err +def setup_plain(testdir): + """ Create sasldb file """ + sasldbfile = os.path.join(testdir, 'testsasldb.db') + + sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'), + 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')} + + passwdprog = os.path.join(testdir, '../../utils/saslpasswd2') + + echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE) + subprocess.check_call([ + passwdprog, "-f", sasldbfile, "-c", "test", + "-u", "host.realm.test", "-p" + ], stdin=echo.stdout, env=sasldbenv, timeout=5) + + return (sasldbfile, sasldbenv) + +def plain_test(sasldbfile, sasldbenv): + try: + srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=sasldbenv) + srv.stdout.readline() # Wait for srv to say it is ready + cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=sasldbenv) + try: + cli.wait(timeout=5) + srv.wait(timeout=5) + except Exception as e: + print("Failed on {}".format(e)); + cli.kill() + srv.kill() + if cli.returncode != 0 or srv.returncode != 0: + raise Exception("CLI ({}): {} --> SRV ({}): {}".format( + cli.returncode, cli.stderr.read().decode('utf-8'), + srv.returncode, srv.stderr.read().decode('utf-8'))) + except Exception as e: + print("FAIL: {}".format(e)) + return 1 + + print("PASS: PLAIN CLI({}) SRV({})".format( + cli.stdout.read().decode('utf-8').strip(), + srv.stdout.read().decode('utf-8').strip())) + return 0 + +def plain_mismatch_test(sasldbfile, sasldbenv): + result = "FAIL" + try: + srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=sasldbenv) + srv.stdout.readline() # Wait for srv to say it is ready + bindings = base64.b64encode("CLI CBS".encode('utf-8')) + cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=sasldbenv) + try: + cli.wait(timeout=5) + srv.wait(timeout=5) + except Exception as e: + print("Failed on {}".format(e)); + cli.kill() + srv.kill() + if cli.returncode != 0 or srv.returncode != 0: + cli_err = cli.stderr.read().decode('utf-8').strip() + srv_err = srv.stderr.read().decode('utf-8').strip() + if "authentication failure" in srv_err: + result = "PASS" + raise Exception("CLI ({}): {} --> SRV ({}): {}".format( + cli.returncode, cli_err, srv.returncode, srv_err)) + except Exception as e: + print("{}: {}".format(result, e)) + return 0 + + print("FAIL: This test should fail [CLI({}) SRV({})]".format( + cli.stdout.read().decode('utf-8').strip(), + srv.stdout.read().decode('utf-8').strip())) + return 1 + +def plain_tests(testdir): + err = 0 + sasldbfile, sasldbenv = setup_plain(testdir) + #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv)) + print('SASLDB PLAIN:') + print(' ', end='') + err += plain_test(sasldbfile, sasldbenv) + + print('SASLDB PLAIN PASSWORD MISMATCH:') + print(' ', end='') + err += plain_mismatch_test(sasldbfile, sasldbenv) + + return err if __name__ == "__main__": @@ -329,5 +422,9 @@ err = gssapi_tests(T) if err != 0: - print('{} test(s) FAILED'.format(err)) + print('{} GSSAPI test(s) FAILED'.format(err)) + + err = plain_tests(T) + if err != 0: + print('{} PLAIN test(s) FAILED'.format(err)) sys.exit(-1) diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_cli.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c --- cyrus-sasl-2.1.27/tests/t_gssapi_cli.c 2020-12-23 14:31:35.564537485 +0100 +++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c 2021-01-06 11:26:15.460662537 +0100 @@ -16,6 +16,8 @@ #include #include +const char *testpass = NULL; + static int setup_socket(void) { struct sockaddr_in addr; @@ -34,9 +36,60 @@ return sock; } +static int get_user(void *context __attribute__((unused)), + int id, + const char **result, + unsigned *len) +{ + const char *testuser = "test@host.realm.test"; + + if (! result) + return SASL_BADPARAM; + + switch (id) { + case SASL_CB_USER: + case SASL_CB_AUTHNAME: + *result = testuser; + break; + default: + return SASL_BADPARAM; + } + + if (len) *len = strlen(*result); + + return SASL_OK; +} + +static int get_pass(sasl_conn_t *conn __attribute__((unused)), + void *context __attribute__((unused)), + int id, + sasl_secret_t **psecret) +{ + size_t len; + static sasl_secret_t *x; + + /* paranoia check */ + if (! conn || ! psecret || id != SASL_CB_PASS) + return SASL_BADPARAM; + + len = strlen(testpass); + + x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len); + + if (!x) { + return SASL_NOMEM; + } + + x->len = len; + strcpy((char *)x->data, testpass); + + *psecret = x; + return SASL_OK; +} + int main(int argc, char *argv[]) { - sasl_callback_t callbacks[2] = {}; + sasl_callback_t callbacks[4] = {}; char buf[8192]; const char *chosenmech; sasl_conn_t *conn; @@ -49,8 +102,9 @@ const char *sasl_mech = "GSSAPI"; bool spnego = false; bool zeromaxssf = false; + bool plain = false; - while ((c = getopt(argc, argv, "c:zN")) != EOF) { + while ((c = getopt(argc, argv, "c:zNP:")) != EOF) { switch (c) { case 'c': parse_cb(&cb, cb_buf, 256, optarg); @@ -61,6 +115,10 @@ case 'N': spnego = true; break; + case 'P': + plain = true; + testpass = optarg; + break; default: break; } @@ -73,6 +131,12 @@ callbacks[1].id = SASL_CB_LIST_END; callbacks[1].proc = NULL; callbacks[1].context = NULL; + callbacks[2].id = SASL_CB_LIST_END; + callbacks[2].proc = NULL; + callbacks[2].context = NULL; + callbacks[3].id = SASL_CB_LIST_END; + callbacks[3].proc = NULL; + callbacks[3].context = NULL; r = sasl_client_init(callbacks); if (r != SASL_OK) exit(-1); @@ -91,6 +155,16 @@ sasl_mech = "GSS-SPNEGO"; } + if (plain) { + sasl_mech = "PLAIN"; + + callbacks[1].id = SASL_CB_AUTHNAME; + callbacks[1].proc = (sasl_callback_ft)&get_user; + + callbacks[2].id = SASL_CB_PASS; + callbacks[2].proc = (sasl_callback_ft)&get_pass; + } + if (zeromaxssf) { /* set all security properties to 0 including maxssf */ sasl_security_properties_t secprops = { 0 }; @@ -99,9 +173,9 @@ r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech); if (r != SASL_OK && r != SASL_CONTINUE) { - saslerr(r, "starting SASL negotiation"); - printf("\n%s\n", sasl_errdetail(conn)); - exit(-1); + saslerr(r, "starting SASL negotiation"); + printf("\n%s\n", sasl_errdetail(conn)); + exit(-1); } sd = setup_socket(); @@ -111,11 +185,11 @@ len = 8192; recv_string(sd, buf, &len, false); - r = sasl_client_step(conn, buf, len, NULL, &data, &len); - if (r != SASL_OK && r != SASL_CONTINUE) { - saslerr(r, "performing SASL negotiation"); - printf("\n%s\n", sasl_errdetail(conn)); - exit(-1); + r = sasl_client_step(conn, buf, len, NULL, &data, &len); + if (r != SASL_OK && r != SASL_CONTINUE) { + saslerr(r, "performing SASL negotiation"); + printf("\n%s\n", sasl_errdetail(conn)); + exit(-1); } } diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_srv.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c --- cyrus-sasl-2.1.27/tests/t_gssapi_srv.c 2020-12-23 14:31:35.565537492 +0100 +++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c 2021-01-06 11:27:48.373257373 +0100 @@ -1,4 +1,5 @@ -/* Copyright (C) Simo Sorce +/* Copyright (C) Simo Sorce , + * Dmitry Belyavskiy * See COPYING file for License */ #include "t_common.h" @@ -15,6 +16,10 @@ #include #include +const char *sasldb_path = NULL, + *auxprop_plugin = "sasldb", + *pwcheck_method = "auxprop-hashed"; + static int setup_socket(void) { struct sockaddr_in addr; @@ -45,9 +50,38 @@ return sd; } +static int test_getopt(void *context __attribute__((unused)), + const char *plugin_name __attribute__((unused)), + const char *option, + const char **result, + unsigned *len) +{ + if (sasldb_path && !strcmp(option, "sasldb_path")) { + *result = sasldb_path; + if (len) + *len = (unsigned) strlen(sasldb_path); + return SASL_OK; + } + + if (sasldb_path && !strcmp(option, "auxprop_plugin")) { + *result = auxprop_plugin; + if (len) + *len = (unsigned) strlen(auxprop_plugin); + return SASL_OK; + } + + if (sasldb_path && !strcmp(option, "pwcheck_method")) { + *result = pwcheck_method; + if (len) + *len = (unsigned) strlen(pwcheck_method); + return SASL_OK; + } + return SASL_FAIL; +} + int main(int argc, char *argv[]) { - sasl_callback_t callbacks[2] = {}; + sasl_callback_t callbacks[3] = {}; char buf[8192]; sasl_conn_t *conn; const char *data; @@ -59,8 +93,9 @@ const char *sasl_mech = "GSSAPI"; bool spnego = false; bool zeromaxssf = false; + bool plain = false; - while ((c = getopt(argc, argv, "c:zN")) != EOF) { + while ((c = getopt(argc, argv, "c:zNP:")) != EOF) { switch (c) { case 'c': parse_cb(&cb, cb_buf, 256, optarg); @@ -71,6 +106,10 @@ case 'N': spnego = true; break; + case 'P': + plain = true; + sasldb_path = optarg; + break; default: break; } @@ -81,9 +120,12 @@ callbacks[0].id = SASL_CB_GETPATH; callbacks[0].proc = (sasl_callback_ft)&getpath; callbacks[0].context = NULL; - callbacks[1].id = SASL_CB_LIST_END; - callbacks[1].proc = NULL; + callbacks[1].id = SASL_CB_GETOPT; + callbacks[1].proc = (sasl_callback_ft)&test_getopt; callbacks[1].context = NULL; + callbacks[2].id = SASL_CB_LIST_END; + callbacks[2].proc = NULL; + callbacks[2].context = NULL; r = sasl_server_init(callbacks, "t_gssapi_srv"); if (r != SASL_OK) exit(-1); @@ -103,6 +145,10 @@ sasl_mech = "GSS-SPNEGO"; } + if (plain) { + sasl_mech = "PLAIN"; + } + if (zeromaxssf) { /* set all security properties to 0 including maxssf */ sasl_security_properties_t secprops = { 0 }; @@ -116,9 +162,9 @@ r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len); if (r != SASL_OK && r != SASL_CONTINUE) { - saslerr(r, "starting SASL negotiation"); - printf("\n%s\n", sasl_errdetail(conn)); - exit(-1); + saslerr(r, "starting SASL negotiation"); + printf("\n%s\n", sasl_errdetail(conn)); + exit(-1); } while (r == SASL_CONTINUE) { @@ -126,12 +172,12 @@ len = 8192; recv_string(sd, buf, &len, true); - r = sasl_server_step(conn, buf, len, &data, &len); - if (r != SASL_OK && r != SASL_CONTINUE) { - saslerr(r, "performing SASL negotiation"); - printf("\n%s\n", sasl_errdetail(conn)); - exit(-1); - } + r = sasl_server_step(conn, buf, len, &data, &len); + if (r != SASL_OK && r != SASL_CONTINUE) { + saslerr(r, "performing SASL negotiation"); + printf("\n%s\n", sasl_errdetail(conn)); + exit(-1); + } } if (r != SASL_OK) exit(-1);