]> jfr.im git - irc/charybdis-ircd/charybdis.git/commitdiff
tests: Verify behaviour if services authenticates a user after SASL is aborted
authorSimon Arlott <sa.me.uk>
Sat, 23 Feb 2019 12:31:56 +0000 (12:31 +0000)
committerSimon Arlott <sa.me.uk>
Sat, 23 Feb 2019 13:02:15 +0000 (13:02 +0000)
.gitignore
tests/Makefile.am
tests/TESTS
tests/client_util.c
tests/client_util.h
tests/runtime/modules/autoload/ip_cloaking.so [deleted symlink]
tests/runtime/modules/autoload/ip_cloaking_3.0.so [deleted symlink]
tests/runtime/modules/autoload/ip_cloaking_4.0.so [deleted symlink]
tests/runtime/modules/autoload/ip_cloaking_old.so [deleted symlink]
tests/sasl_abort1.c [new file with mode: 0644]
tests/sasl_abort1.conf [new file with mode: 0644]

index 39347b7ea7816bc6af691d2711f6230d7d6390dc..cfeceb181674bb2068b7f4991591bb23fca99f03 100644 (file)
@@ -62,6 +62,7 @@ tests/msgbuf_unparse1
 tests/rb_dictionary1
 tests/rb_snprintf_append1
 tests/rb_snprintf_try_append1
+tests/sasl_abort1
 tests/send1
 tests/serv_connect1
 tests/substitution1
index 3318c8761d8d8ff974bd91ca3bf079fb7144ec4c..0efb4c7f662b065ca5ff90b04fa1da505bc6e303 100644 (file)
@@ -4,6 +4,7 @@ check_PROGRAMS = runtests \
        rb_dictionary1 \
        rb_snprintf_append1 \
        rb_snprintf_try_append1 \
+       sasl_abort1 \
        send1 \
        serv_connect1 \
        substitution1
@@ -26,6 +27,7 @@ msgbuf_unparse1_SOURCES = msgbuf_unparse1.c
 rb_dictionary1_SOURCES = rb_dictionary1.c
 rb_snprintf_append1_SOURCES = rb_snprintf_append1.c
 rb_snprintf_try_append1_SOURCES = rb_snprintf_try_append1.c
+sasl_abort1_SOURCES = sasl_abort1.c ircd_util.c client_util.c
 send1_SOURCES = send1.c ircd_util.c client_util.c
 serv_connect1_SOURCES = serv_connect1.c ircd_util.c client_util.c
 substitution1_SOURCES = substitution1.c
index ce1b3e7d1142e96cd099f6c3250b1ce44a96a2e3..61e51d74f61aa85baf892cc9948f01d8676bc160 100644 (file)
@@ -3,6 +3,7 @@ msgbuf_unparse1
 rb_dictionary1
 rb_snprintf_append1
 rb_snprintf_try_append1
+sasl_abort1
 send1
 serv_connect1
 substitution1
index 04c22e0b4b3fca6ab5b19b4fa70627ad7ccfb4b8..796782d5e825039e069e20bd2d2b86f1426f40a4 100644 (file)
 
 #include "hash.h"
 #include "s_newconf.h"
+#include "parse.h"
+#include "listener.h"
 
 #define MSG "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__
 
+static struct Listener fake_listener = {
+       .next = NULL,
+       .name = "fake",
+       .F = NULL,
+       .ref_count = 0,
+       .active = 1,
+       .ssl = 1,
+       .defer_accept = 0,
+       .sctp = false,
+       .wsock = 0,
+       .addr = {
+               { .ss_family = AF_INET6 },
+               { .ss_family = AF_INET6 },
+       },
+       .vhost = { "fake" },
+};
+
+struct Client *make_local_unknown(void)
+{
+       struct Client *client;
+
+       client = make_client(NULL);
+       rb_dlinkMoveNode(&client->localClient->tnode, &unknown_list, &lclient_list);
+       client->servptr = &me;
+       rb_dlinkAdd(client, &client->lnode, &client->servptr->serv->users);
+       client->localClient->listener = &fake_listener;
+       client->preClient->auth.accepted = true;
+
+       return client;
+}
+
 struct Client *make_local_person(void)
 {
        return make_local_person_nick(TEST_NICK);
@@ -44,10 +77,7 @@ struct Client *make_local_person_full(const char *nick, const char *username, co
 {
        struct Client *client;
 
-       client = make_client(NULL);
-       rb_dlinkMoveNode(&client->localClient->tnode, &unknown_list, &lclient_list);
-       client->servptr = &me;
-       rb_dlinkAdd(client, &client->lnode, &client->servptr->serv->users);
+       client = make_local_unknown();
        make_user(client);
        SetClient(client);
 
@@ -187,6 +217,15 @@ char *get_client_sendq(const struct Client *client)
        return "";
 }
 
+void client_util_parse(struct Client *client, const char *message)
+{
+       char *copy = rb_strdup(message);
+
+       parse(client, copy, copy+strlen(copy));
+
+       rb_free(copy);
+}
+
 void client_util_init(void)
 {
 }
index da0bdbb312ef167f5bb8fd1de908f8212199ae03..45e8d5fcf0bacba0bc501797b15ab8288fa4195f 100644 (file)
@@ -63,6 +63,7 @@
 void client_util_init(void);
 void client_util_free(void);
 
+struct Client *make_local_unknown(void);
 struct Client *make_local_person(void);
 struct Client *make_local_person_nick(const char *nick);
 struct Client *make_local_person_full(const char *nick, const char *username, const char *hostname, const char *ip, const char *realname);
@@ -83,11 +84,17 @@ struct Channel *make_channel(void);
 
 char *get_client_sendq(const struct Client *client);
 
+void client_util_parse(struct Client *client, const char *message);
+
 #define is_client_sendq_empty(client, message, ...) do { \
                is_string("", get_client_sendq(client), message, ##__VA_ARGS__); \
        } while (0)
 
-#define is_client_sendq(queue, client, message, ...) do { \
+#define is_client_sendq_one(queue, client, message, ...) do { \
                is_string(queue, get_client_sendq(client), message, ##__VA_ARGS__); \
+       } while (0)
+
+#define is_client_sendq(queue, client, message, ...) do { \
+               is_client_sendq_one(queue, client, message, ##__VA_ARGS__); \
                is_client_sendq_empty(client, message, ##__VA_ARGS__); \
        } while (0)
diff --git a/tests/runtime/modules/autoload/ip_cloaking.so b/tests/runtime/modules/autoload/ip_cloaking.so
deleted file mode 120000 (symlink)
index a76d819..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../extensions/.libs/ip_cloaking.so
\ No newline at end of file
diff --git a/tests/runtime/modules/autoload/ip_cloaking_3.0.so b/tests/runtime/modules/autoload/ip_cloaking_3.0.so
deleted file mode 120000 (symlink)
index f4d7a53..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../extensions/.libs/ip_cloaking_3.0.so
\ No newline at end of file
diff --git a/tests/runtime/modules/autoload/ip_cloaking_4.0.so b/tests/runtime/modules/autoload/ip_cloaking_4.0.so
deleted file mode 120000 (symlink)
index 2096024..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../extensions/.libs/ip_cloaking_4.0.so
\ No newline at end of file
diff --git a/tests/runtime/modules/autoload/ip_cloaking_old.so b/tests/runtime/modules/autoload/ip_cloaking_old.so
deleted file mode 120000 (symlink)
index 06a62ee..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../extensions/.libs/ip_cloaking_old.so
\ No newline at end of file
diff --git a/tests/sasl_abort1.c b/tests/sasl_abort1.c
new file mode 100644 (file)
index 0000000..d2e5321
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  sasl_abort1.c: Test SASL abort from the ircd to services
+ *  Copyright 2019 Simon Arlott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "tap/basic.h"
+
+#include "ircd_util.h"
+#include "client_util.h"
+
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "hash.h"
+
+#define MSG "%s:%d (%s; aborted=%d, by_user=%d)", __FILE__, __LINE__, __FUNCTION__, aborted, by_user
+
+static void common_sasl_test(bool aborted, bool by_user)
+{
+       ircd_util_init(__FILE__);
+       client_util_init();
+
+       struct Client *user = make_local_unknown();
+       struct Client *server = make_remote_server(&me);
+       struct Client *remote = make_remote_person(server);
+
+       rb_inet_pton_sock(TEST_IP, (struct sockaddr *)&user->localClient->ip);
+       rb_strlcpy(user->host, TEST_HOSTNAME, sizeof(user->host));
+       rb_inet_ntop_sock((struct sockaddr *)&user->localClient->ip, user->sockhost, sizeof(user->sockhost));
+
+       strcpy(server->id, TEST_SERVER_ID);
+       strcpy(remote->id, TEST_REMOTE_ID);
+       add_to_id_hash(remote->id, remote);
+       server->localClient->caps = CAP_ENCAP | CAP_TS6;
+       remote->umodes |= UMODE_SERVICE;
+
+       client_util_parse(user, "CAP LS 302" CRLF);
+       const char *line;
+       while ((line = get_client_sendq(user)) && strcmp(line, "")) {
+               printf("%s", line);
+       }
+
+       client_util_parse(user, "NICK " TEST_NICK CRLF);
+       client_util_parse(user, "USER " TEST_USERNAME " 0 0 :" TEST_REALNAME CRLF);
+       is_client_sendq_empty(user, MSG);
+
+       user->tsinfo = 42;
+
+       client_util_parse(user, "CAP REQ :sasl" CRLF);
+       is_client_sendq(":" TEST_ME_NAME " CAP " TEST_NICK " ACK :sasl" CRLF, user, MSG);
+
+       client_util_parse(user, "AUTHENTICATE EXTERNAL" CRLF);
+       is_client_sendq_empty(user, MSG);
+
+       is_client_sendq_one(":" TEST_ME_ID " ENCAP " TEST_SERVER_NAME " SASL " TEST_ME_ID "AAAAAB " TEST_REMOTE_ID " H " TEST_HOSTNAME " " TEST_IP " P" CRLF, server, MSG);
+       is_client_sendq_one(":" TEST_ME_ID " ENCAP " TEST_SERVER_NAME " SASL " TEST_ME_ID "AAAAAB " TEST_REMOTE_ID " S EXTERNAL" CRLF, server, MSG);
+       is_client_sendq_empty(server, MSG);
+
+       if (aborted) {
+               if (by_user) {
+                       // Explicit abort by user
+                       client_util_parse(user, "AUTHENTICATE *" CRLF);
+                       is_client_sendq(":" TEST_ME_NAME " 906 " TEST_NICK " :SASL authentication aborted" CRLF, user, MSG);
+
+                       client_util_parse(user, "CAP END" CRLF);
+                       ok(IsClient(user), MSG);
+               } else {
+                       // Implicit abort by completing registration
+                       client_util_parse(user, "CAP END" CRLF);
+                       ok(IsClient(user), MSG);
+                       is_client_sendq_one(":" TEST_ME_NAME " 906 " TEST_NICK " :SASL authentication aborted" CRLF, user, MSG);
+               }
+
+               is_client_sendq_one(":" TEST_ME_ID " ENCAP " TEST_SERVER_NAME " SASL " TEST_ME_ID "AAAAAB " TEST_REMOTE_ID " D A" CRLF, server, MSG);
+               is_client_sendq(":" TEST_ME_ID " UID " TEST_NICK " 1 42 +i ~" TEST_USERNAME " " TEST_HOSTNAME " " TEST_IP " " TEST_ME_ID "AAAAAB :" TEST_REALNAME CRLF, server, MSG);
+       } else {
+               // Return a successful auth
+               client_util_parse(server, ":" TEST_SERVER_NAME " ENCAP " TEST_ME_NAME " SASL " TEST_REMOTE_ID " " TEST_ME_ID "AAAAAB D S" CRLF);
+
+               // User should be authenticated
+               is_client_sendq_one(":" TEST_ME_NAME " 903 " TEST_NICK " :SASL authentication successful" CRLF, user, MSG);
+
+               client_util_parse(user, "CAP END" CRLF);
+               ok(IsClient(user), MSG);
+       }
+
+       is_client_sendq_one(":" TEST_ME_NAME " 001 " TEST_NICK " :Welcome to the Test Internet Relay Chat Network " TEST_NICK CRLF, user, MSG);
+       while ((line = get_client_sendq(user)) && strcmp(line, "")) {
+               printf("%s", line);
+       }
+
+       if (aborted) {
+               // Return a successful auth after auth was aborted
+               client_util_parse(server, ":" TEST_SERVER_NAME " ENCAP " TEST_ME_NAME " SASL " TEST_REMOTE_ID " " TEST_ME_ID "AAAAAB D S" CRLF);
+
+               // User should not be authenticated
+               is_client_sendq_empty(user, MSG);
+       }
+
+       remove_local_person(user);
+       remove_remote_person(remote);
+       remove_remote_server(server);
+
+       client_util_free();
+       ircd_util_free();
+}
+
+static void successful_login(void)
+{
+       common_sasl_test(false, false);
+}
+
+static void successful_login_after_aborted_by_registration(void)
+{
+       common_sasl_test(true, false);
+}
+
+static void successful_login_after_aborted_by_user(void)
+{
+       common_sasl_test(true, true);
+}
+
+int main(int argc, char *argv[])
+{
+       plan_lazy();
+
+       successful_login();
+       successful_login_after_aborted_by_registration();
+       successful_login_after_aborted_by_user();
+
+       return 0;
+}
diff --git a/tests/sasl_abort1.conf b/tests/sasl_abort1.conf
new file mode 100644 (file)
index 0000000..b3b0ea5
--- /dev/null
@@ -0,0 +1,44 @@
+serverinfo {
+       sid = "0AA";
+       name = "me.test";
+       description = "Test server";
+       network_name = "Test network";
+};
+
+
+class "default" {
+       ping_time = 1000 minutes;
+       connectfreq = 1000 minutes;
+       number_per_ident = 1000;
+       number_per_ip = 1000;
+       number_per_ip_global = 1000;
+       cidr_ipv4_bitlen = 24;
+       cidr_ipv6_bitlen = 64;
+       number_per_cidr = 1000;
+       max_number = 1000;
+       sendq = 4 megabytes;
+};
+
+connect "remote.test" {
+       host = "::1";
+       fingerprint = "test";
+       class = "default";
+};
+
+service {
+       name = "remote.test";
+};
+
+privset "admin" {
+       privs = oper:admin;
+};
+
+auth {
+       user = "*@*";
+       class = "default";
+};
+
+general {
+       sasl_service = "remote_test";
+       ping_cookie = no;
+};