762 lines
23 KiB
Diff
762 lines
23 KiB
Diff
|
From 10ac4d4822023b24734acde3c07186937ad52813 Mon Sep 17 00:00:00 2001
|
||
|
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||
|
Date: Wed, 6 Jan 2021 12:38:46 +0100
|
||
|
Subject: [PATCH] Some basic PLAIN auth tests
|
||
|
|
||
|
Signed-off-by: Dmitry Belyavskiy <beldmit@gmail.com>
|
||
|
---
|
||
|
tests/runtests.py | 91 +++++++++++++++++++++++++++++++++++++++++
|
||
|
tests/t_gssapi_cli.c | 97 +++++++++++++++++++++++++++++++++++++++-----
|
||
|
tests/t_gssapi_srv.c | 78 +++++++++++++++++++++++++++--------
|
||
|
3 files changed, 239 insertions(+), 27 deletions(-)
|
||
|
|
||
|
diff --git a/tests/runtests.py b/tests/runtests.py
|
||
|
index fc9cf244..513ed3ff 100755
|
||
|
--- a/tests/runtests.py
|
||
|
+++ b/tests/runtests.py
|
||
|
@@ -239,6 +239,96 @@ def gssapi_tests(testdir):
|
||
|
|
||
|
os.killpg(kdc.pid, signal.SIGTERM)
|
||
|
|
||
|
+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
|
||
|
+
|
||
|
+ print("PASS: PLAIN CLI({}) SRV({})".format(
|
||
|
+ cli.stdout.read().decode('utf-8').strip(),
|
||
|
+ srv.stdout.read().decode('utf-8').strip()))
|
||
|
+ return
|
||
|
+
|
||
|
+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
|
||
|
+
|
||
|
+ print("FAIL: This test should fail [CLI({}) SRV({})]".format(
|
||
|
+ cli.stdout.read().decode('utf-8').strip(),
|
||
|
+ srv.stdout.read().decode('utf-8').strip()))
|
||
|
+ return
|
||
|
+
|
||
|
+def plain_tests(testdir):
|
||
|
+ sasldbfile, sasldbenv = setup_plain(testdir)
|
||
|
+ #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv))
|
||
|
+ print('SASLDB PLAIN:')
|
||
|
+ print(' ', end='')
|
||
|
+ plain_test(sasldbfile, sasldbenv)
|
||
|
+
|
||
|
+ print('SASLDB PLAIN PASSWORD MISMATCH:')
|
||
|
+ print(' ', end='')
|
||
|
+ plain_mismatch_test(sasldbfile, sasldbenv)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
@@ -254,3 +344,4 @@ def gssapi_tests(testdir):
|
||
|
os.makedirs(T)
|
||
|
|
||
|
gssapi_tests(T)
|
||
|
+ plain_tests(T)
|
||
|
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
|
||
|
index a44a3f58..20d22070 100644
|
||
|
--- a/tests/t_gssapi_cli.c
|
||
|
+++ b/tests/t_gssapi_cli.c
|
||
|
@@ -16,6 +16,8 @@
|
||
|
#include <saslplug.h>
|
||
|
#include <saslutil.h>
|
||
|
|
||
|
+const char *testpass = NULL;
|
||
|
+
|
||
|
static int setup_socket(void)
|
||
|
{
|
||
|
struct sockaddr_in addr;
|
||
|
@@ -34,9 +36,60 @@ static int setup_socket(void)
|
||
|
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;
|
||
|
@@ -46,12 +99,18 @@ int main(int argc, char *argv[])
|
||
|
char cb_buf[256];
|
||
|
int sd;
|
||
|
int c, r;
|
||
|
+ const char *sasl_mech = "GSSAPI";
|
||
|
+ int plain = 0;
|
||
|
|
||
|
- while ((c = getopt(argc, argv, "c:")) != EOF) {
|
||
|
+ while ((c = getopt(argc, argv, "c:P:")) != EOF) {
|
||
|
switch (c) {
|
||
|
case 'c':
|
||
|
parse_cb(&cb, cb_buf, 256, optarg);
|
||
|
break;
|
||
|
+ case 'P':
|
||
|
+ plain = 1;
|
||
|
+ testpass = optarg;
|
||
|
+ break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
@@ -64,6 +123,22 @@ int main(int argc, char *argv[])
|
||
|
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;
|
||
|
+
|
||
|
+ 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;
|
||
|
+ }
|
||
|
|
||
|
r = sasl_client_init(callbacks);
|
||
|
if (r != SASL_OK) exit(-1);
|
||
|
@@ -78,11 +153,11 @@ int main(int argc, char *argv[])
|
||
|
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
|
||
|
}
|
||
|
|
||
|
- r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
|
||
|
+ 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();
|
||
|
@@ -92,11 +167,11 @@ int main(int argc, char *argv[])
|
||
|
len = 8192;
|
||
|
recv_string(sd, buf, &len);
|
||
|
|
||
|
- 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 --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
|
||
|
index ef1217f6..430cad65 100644
|
||
|
--- a/tests/t_gssapi_srv.c
|
||
|
+++ b/tests/t_gssapi_srv.c
|
||
|
@@ -1,4 +1,5 @@
|
||
|
-/* Copyright (C) Simo Sorce <simo@redhat.com>
|
||
|
+/* Copyright (C) Simo Sorce <simo@redhat.com>,
|
||
|
+ * Dmitry Belyavskiy <dbelyavs@redhat.com>
|
||
|
* See COPYING file for License */
|
||
|
|
||
|
#include "t_common.h"
|
||
|
@@ -15,6 +16,10 @@
|
||
|
#include <arpa/inet.h>
|
||
|
#include <saslplug.h>
|
||
|
|
||
|
+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 @@ static int setup_socket(void)
|
||
|
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;
|
||
|
@@ -56,25 +90,33 @@ int main(int argc, char *argv[])
|
||
|
unsigned char cb_buf[256];
|
||
|
int sd;
|
||
|
int c, r;
|
||
|
+ const char *sasl_mech = "GSSAPI";
|
||
|
+ int plain = 0;
|
||
|
|
||
|
- while ((c = getopt(argc, argv, "c:")) != EOF) {
|
||
|
+ while ((c = getopt(argc, argv, "c:P:")) != EOF) {
|
||
|
switch (c) {
|
||
|
case 'c':
|
||
|
parse_cb(&cb, cb_buf, 256, optarg);
|
||
|
break;
|
||
|
+ case 'P':
|
||
|
+ plain = 1;
|
||
|
+ sasldb_path = optarg;
|
||
|
+ break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-
|
||
|
/* initialize the sasl library */
|
||
|
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);
|
||
|
@@ -90,16 +132,20 @@ int main(int argc, char *argv[])
|
||
|
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
|
||
|
}
|
||
|
|
||
|
+ if (plain) {
|
||
|
+ sasl_mech = "PLAIN";
|
||
|
+ }
|
||
|
+
|
||
|
sd = setup_socket();
|
||
|
|
||
|
len = 8192;
|
||
|
recv_string(sd, buf, &len);
|
||
|
|
||
|
- r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
|
||
|
+ 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) {
|
||
|
@@ -107,12 +153,12 @@ int main(int argc, char *argv[])
|
||
|
len = 8192;
|
||
|
recv_string(sd, buf, &len);
|
||
|
|
||
|
- 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);
|
||
|
+ }
|
||
|
|
||
|
}
|
||
|
|
||
|
From d95b0afef1289194148090874799428e9e4f4cff Mon Sep 17 00:00:00 2001
|
||
|
From: Simo Sorce <idra@samba.org>
|
||
|
Date: Wed, 15 Apr 2020 11:57:17 -0400
|
||
|
Subject: [PATCH] Test GSS-SPNEGO as well
|
||
|
|
||
|
Signed-off-by: Simo Sorce <simo@redhat.com>
|
||
|
---
|
||
|
tests/runtests.py | 91 ++++++++++++++++++++++++++++++++++++++++----
|
||
|
tests/t_common.c | 13 ++++---
|
||
|
tests/t_common.h | 3 +-
|
||
|
tests/t_gssapi_cli.c | 22 ++++++++++-
|
||
|
tests/t_gssapi_srv.c | 25 ++++++++++--
|
||
|
5 files changed, 134 insertions(+), 20 deletions(-)
|
||
|
|
||
|
diff --git a/tests/runtests.py b/tests/runtests.py
|
||
|
index 513ed3ff..7be60745 100755
|
||
|
--- a/tests/runtests.py
|
||
|
+++ b/tests/runtests.py
|
||
|
@@ -6,6 +6,7 @@
|
||
|
import shutil
|
||
|
import signal
|
||
|
import subprocess
|
||
|
+import sys
|
||
|
import time
|
||
|
from string import Template
|
||
|
|
||
|
@@ -149,11 +150,12 @@ def gssapi_basic_test(kenv):
|
||
|
srv.returncode, srv.stderr.read().decode('utf-8')))
|
||
|
except Exception as e:
|
||
|
print("FAIL: {}".format(e))
|
||
|
- return
|
||
|
+ return 1
|
||
|
|
||
|
print("PASS: CLI({}) SRV({})".format(
|
||
|
cli.stdout.read().decode('utf-8').strip(),
|
||
|
srv.stdout.read().decode('utf-8').strip()))
|
||
|
+ return 0
|
||
|
|
||
|
def gssapi_channel_binding_test(kenv):
|
||
|
try:
|
||
|
@@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv):
|
||
|
srv.returncode, srv.stderr.read().decode('utf-8')))
|
||
|
except Exception as e:
|
||
|
print("FAIL: {}".format(e))
|
||
|
- return
|
||
|
+ return 1
|
||
|
|
||
|
print("PASS: CLI({}) SRV({})".format(
|
||
|
cli.stdout.read().decode('utf-8').strip(),
|
||
|
srv.stdout.read().decode('utf-8').strip()))
|
||
|
+ return 0
|
||
|
|
||
|
def gssapi_channel_binding_mismatch_test(kenv):
|
||
|
result = "FAIL"
|
||
|
@@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv):
|
||
|
cli.returncode, cli_err, srv.returncode, srv_err))
|
||
|
except Exception as e:
|
||
|
print("{}: {}".format(result, e))
|
||
|
- return
|
||
|
+ 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 gss_spnego_basic_test(kenv):
|
||
|
+ try:
|
||
|
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"],
|
||
|
+ stdout=subprocess.PIPE,
|
||
|
+ stderr=subprocess.PIPE, env=kenv)
|
||
|
+ srv.stdout.readline() # Wait for srv to say it is ready
|
||
|
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"],
|
||
|
+ stdout=subprocess.PIPE,
|
||
|
+ stderr=subprocess.PIPE, env=kenv)
|
||
|
+ 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: CLI({}) SRV({})".format(
|
||
|
+ cli.stdout.read().decode('utf-8').strip(),
|
||
|
+ srv.stdout.read().decode('utf-8').strip()))
|
||
|
+ return 0
|
||
|
+
|
||
|
+def gss_spnego_zeromaxssf_test(kenv):
|
||
|
+ try:
|
||
|
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"],
|
||
|
+ stdout=subprocess.PIPE,
|
||
|
+ stderr=subprocess.PIPE, env=kenv)
|
||
|
+ srv.stdout.readline() # Wait for srv to say it is ready
|
||
|
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"],
|
||
|
+ stdout=subprocess.PIPE,
|
||
|
+ stderr=subprocess.PIPE, env=kenv)
|
||
|
+ 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: CLI({}) SRV({})".format(
|
||
|
+ cli.stdout.read().decode('utf-8').strip(),
|
||
|
+ srv.stdout.read().decode('utf-8').strip()))
|
||
|
+ return 0
|
||
|
|
||
|
def gssapi_tests(testdir):
|
||
|
""" SASL/GSSAPI Tests """
|
||
|
@@ -225,19 +287,30 @@ def gssapi_tests(testdir):
|
||
|
#print("KDC: {}, ENV: {}".format(kdc, kenv))
|
||
|
kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
|
||
|
|
||
|
+ err = 0
|
||
|
+
|
||
|
print('GSSAPI BASIC:')
|
||
|
print(' ', end='')
|
||
|
- gssapi_basic_test(kenv)
|
||
|
+ err += gssapi_basic_test(kenv)
|
||
|
|
||
|
print('GSSAPI CHANNEL BINDING:')
|
||
|
print(' ', end='')
|
||
|
- gssapi_channel_binding_test(kenv)
|
||
|
+ err += gssapi_channel_binding_test(kenv)
|
||
|
|
||
|
print('GSSAPI CHANNEL BINDING MISMTACH:')
|
||
|
print(' ', end='')
|
||
|
- gssapi_channel_binding_mismatch_test(kenv)
|
||
|
+ err += gssapi_channel_binding_mismatch_test(kenv)
|
||
|
+
|
||
|
+ print('GSS-SPNEGO BASIC:')
|
||
|
+ print(' ', end='')
|
||
|
+ err += gss_spnego_basic_test(kenv)
|
||
|
+
|
||
|
+ print('GSS-SPNEGO 0 MAXSSF:')
|
||
|
+ print(' ', end='')
|
||
|
+ err += gss_spnego_zeromaxssf_test(kenv)
|
||
|
|
||
|
os.killpg(kdc.pid, signal.SIGTERM)
|
||
|
+ return err
|
||
|
|
||
|
def setup_plain(testdir):
|
||
|
""" Create sasldb file """
|
||
|
@@ -343,5 +416,9 @@ def plain_tests(testdir):
|
||
|
shutil.rmtree(T)
|
||
|
os.makedirs(T)
|
||
|
|
||
|
- gssapi_tests(T)
|
||
|
plain_tests(T)
|
||
|
+
|
||
|
+ err = gssapi_tests(T)
|
||
|
+ if err != 0:
|
||
|
+ print('{} test(s) FAILED'.format(err))
|
||
|
+ sys.exit(-1)
|
||
|
diff --git a/tests/t_common.c b/tests/t_common.c
|
||
|
index 478e6a1f..f56098ef 100644
|
||
|
--- a/tests/t_common.c
|
||
|
+++ b/tests/t_common.c
|
||
|
@@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l)
|
||
|
if (ret != l) s_error("send data", ret, l, errno);
|
||
|
}
|
||
|
|
||
|
-void recv_string(int sd, char *buf, unsigned int *buflen)
|
||
|
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof)
|
||
|
{
|
||
|
+ unsigned int bufsize = *buflen;
|
||
|
unsigned int l;
|
||
|
ssize_t ret;
|
||
|
|
||
|
+ *buflen = 0;
|
||
|
+
|
||
|
ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
|
||
|
+ if (allow_eof && ret == 0) return;
|
||
|
if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
|
||
|
|
||
|
- if (l == 0) {
|
||
|
- *buflen = 0;
|
||
|
- return;
|
||
|
- }
|
||
|
+ if (l == 0) return;
|
||
|
|
||
|
- if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
|
||
|
+ if (bufsize < l) s_error("recv len", l, bufsize, E2BIG);
|
||
|
|
||
|
ret = recv(sd, buf, l, 0);
|
||
|
if (ret != l) s_error("recv data", ret, l, errno);
|
||
|
diff --git a/tests/t_common.h b/tests/t_common.h
|
||
|
index a10def17..be24a53d 100644
|
||
|
--- a/tests/t_common.h
|
||
|
+++ b/tests/t_common.h
|
||
|
@@ -4,6 +4,7 @@
|
||
|
#include "config.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
+#include <stdbool.h>
|
||
|
#include <stdio.h>
|
||
|
#include <sys/socket.h>
|
||
|
|
||
|
@@ -12,7 +13,7 @@
|
||
|
|
||
|
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
|
||
|
void send_string(int sd, const char *s, unsigned int l);
|
||
|
-void recv_string(int sd, char *buf, unsigned int *buflen);
|
||
|
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
|
||
|
void saslerr(int why, const char *what);
|
||
|
int getpath(void *context __attribute__((unused)), const char **path);
|
||
|
void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
|
||
|
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
|
||
|
index 20d22070..b1dd6ce0 100644
|
||
|
--- a/tests/t_gssapi_cli.c
|
||
|
+++ b/tests/t_gssapi_cli.c
|
||
|
@@ -101,8 +101,10 @@ int main(int argc, char *argv[])
|
||
|
int c, r;
|
||
|
const char *sasl_mech = "GSSAPI";
|
||
|
int plain = 0;
|
||
|
+ bool spnego = false;
|
||
|
+ bool zeromaxssf = false;
|
||
|
|
||
|
- while ((c = getopt(argc, argv, "c:P:")) != EOF) {
|
||
|
+ while ((c = getopt(argc, argv, "c:P:zN")) != EOF) {
|
||
|
switch (c) {
|
||
|
case 'c':
|
||
|
parse_cb(&cb, cb_buf, 256, optarg);
|
||
|
@@ -111,6 +113,12 @@ int main(int argc, char *argv[])
|
||
|
plain = 1;
|
||
|
testpass = optarg;
|
||
|
break;
|
||
|
+ case 'z':
|
||
|
+ zeromaxssf = true;
|
||
|
+ break;
|
||
|
+ case 'N':
|
||
|
+ spnego = true;
|
||
|
+ break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
@@ -153,6 +161,16 @@ int main(int argc, char *argv[])
|
||
|
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
|
||
|
}
|
||
|
|
||
|
+ if (spnego) {
|
||
|
+ sasl_mech = "GSS-SPNEGO";
|
||
|
+ }
|
||
|
+
|
||
|
+ if (zeromaxssf) {
|
||
|
+ /* set all security properties to 0 including maxssf */
|
||
|
+ sasl_security_properties_t secprops = { 0 };
|
||
|
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
|
||
|
+ }
|
||
|
+
|
||
|
r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
|
||
|
if (r != SASL_OK && r != SASL_CONTINUE) {
|
||
|
saslerr(r, "starting SASL negotiation");
|
||
|
@@ -165,7 +183,7 @@ int main(int argc, char *argv[])
|
||
|
while (r == SASL_CONTINUE) {
|
||
|
send_string(sd, data, len);
|
||
|
len = 8192;
|
||
|
- recv_string(sd, buf, &len);
|
||
|
+ recv_string(sd, buf, &len, false);
|
||
|
|
||
|
r = sasl_client_step(conn, buf, len, NULL, &data, &len);
|
||
|
if (r != SASL_OK && r != SASL_CONTINUE) {
|
||
|
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
|
||
|
index 430cad65..0adbd12f 100644
|
||
|
--- a/tests/t_gssapi_srv.c
|
||
|
+++ b/tests/t_gssapi_srv.c
|
||
|
@@ -92,8 +92,10 @@ int main(int argc, char *argv[])
|
||
|
int c, r;
|
||
|
const char *sasl_mech = "GSSAPI";
|
||
|
int plain = 0;
|
||
|
+ bool spnego = false;
|
||
|
+ bool zeromaxssf = false;
|
||
|
|
||
|
- while ((c = getopt(argc, argv, "c:P:")) != EOF) {
|
||
|
+ while ((c = getopt(argc, argv, "c:P:zN")) != EOF) {
|
||
|
switch (c) {
|
||
|
case 'c':
|
||
|
parse_cb(&cb, cb_buf, 256, optarg);
|
||
|
@@ -102,6 +104,12 @@ int main(int argc, char *argv[])
|
||
|
plain = 1;
|
||
|
sasldb_path = optarg;
|
||
|
break;
|
||
|
+ case 'z':
|
||
|
+ zeromaxssf = true;
|
||
|
+ break;
|
||
|
+ case 'N':
|
||
|
+ spnego = true;
|
||
|
+ break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
@@ -136,10 +144,20 @@ int main(int argc, char *argv[])
|
||
|
sasl_mech = "PLAIN";
|
||
|
}
|
||
|
|
||
|
+ if (spnego) {
|
||
|
+ sasl_mech = "GSS-SPNEGO";
|
||
|
+ }
|
||
|
+
|
||
|
+ if (zeromaxssf) {
|
||
|
+ /* set all security properties to 0 including maxssf */
|
||
|
+ sasl_security_properties_t secprops = { 0 };
|
||
|
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
|
||
|
+ }
|
||
|
+
|
||
|
sd = setup_socket();
|
||
|
|
||
|
len = 8192;
|
||
|
- recv_string(sd, buf, &len);
|
||
|
+ recv_string(sd, buf, &len, false);
|
||
|
|
||
|
r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
|
||
|
if (r != SASL_OK && r != SASL_CONTINUE) {
|
||
|
@@ -151,7 +169,7 @@ int main(int argc, char *argv[])
|
||
|
while (r == SASL_CONTINUE) {
|
||
|
send_string(sd, data, len);
|
||
|
len = 8192;
|
||
|
- recv_string(sd, buf, &len);
|
||
|
+ recv_string(sd, buf, &len, true);
|
||
|
|
||
|
r = sasl_server_step(conn, buf, len, &data, &len);
|
||
|
if (r != SASL_OK && r != SASL_CONTINUE) {
|
||
|
@@ -159,7 +177,6 @@ int main(int argc, char *argv[])
|
||
|
printf("\n%s\n", sasl_errdetail(conn));
|
||
|
exit(-1);
|
||
|
}
|
||
|
-
|
||
|
}
|
||
|
|
||
|
if (r != SASL_OK) exit(-1);
|
||
|
|