tests: Verify behaviour if services authenticates a user after SASL is aborted
This commit is contained in:
parent
ac5a5a0cfa
commit
958c354cca
11 changed files with 252 additions and 9 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,6 +3,7 @@ msgbuf_unparse1
|
|||
rb_dictionary1
|
||||
rb_snprintf_append1
|
||||
rb_snprintf_try_append1
|
||||
sasl_abort1
|
||||
send1
|
||||
serv_connect1
|
||||
substitution1
|
||||
|
|
|
@ -27,9 +27,42 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../../../extensions/.libs/ip_cloaking.so
|
|
@ -1 +0,0 @@
|
|||
../../../../extensions/.libs/ip_cloaking_3.0.so
|
|
@ -1 +0,0 @@
|
|||
../../../../extensions/.libs/ip_cloaking_4.0.so
|
|
@ -1 +0,0 @@
|
|||
../../../../extensions/.libs/ip_cloaking_old.so
|
153
tests/sasl_abort1.c
Normal file
153
tests/sasl_abort1.c
Normal file
|
@ -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;
|
||||
}
|
44
tests/sasl_abort1.conf
Normal file
44
tests/sasl_abort1.conf
Normal file
|
@ -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;
|
||||
};
|
Loading…
Reference in a new issue