349 lines
10 KiB
C
349 lines
10 KiB
C
/* This file is part of the Project Athena Zephyr Notification System.
|
|
* It contains the server unit tests.
|
|
*
|
|
* Created by: Karl Ramm
|
|
*
|
|
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
|
|
* For copying and distribution information, see the file
|
|
* "mit-copyright.h".
|
|
*/
|
|
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <netinet/in.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <syslog.h>
|
|
|
|
#include "zserver.h"
|
|
|
|
int ulogin_add_user(ZNotice_t *notice, Exposure_type exposure,
|
|
struct sockaddr_in *who);
|
|
Exposure_type ulogin_remove_user(ZNotice_t *notice,
|
|
struct sockaddr_in *who,
|
|
int *err_return);
|
|
int ulogin_find(char *user, struct in_addr *host,
|
|
unsigned int port);
|
|
int ulogin_find_user(char *user);
|
|
void ulogin_flush_user(ZNotice_t *notice);
|
|
extern Location *locations;
|
|
|
|
#define TEST(EXP) \
|
|
do { \
|
|
printf("%s:%d: %s: ", __FILE__, __LINE__, #EXP); \
|
|
fflush(stdout); \
|
|
if (EXP) { \
|
|
puts("PASS"); \
|
|
} else { \
|
|
puts("FAIL"); \
|
|
failures++; \
|
|
} \
|
|
fflush(stdout); \
|
|
} while (0)
|
|
|
|
#define V(EXP) \
|
|
do { \
|
|
printf("%s:%d: %s\n", __FILE__, __LINE__, #EXP); \
|
|
fflush(stdout); \
|
|
EXP; \
|
|
} while (0)
|
|
|
|
#define VI(EXP) \
|
|
do { \
|
|
int result; \
|
|
printf("%s:%d: %s ->", __FILE__, __LINE__, #EXP); \
|
|
fflush(stdout); \
|
|
result=EXP; \
|
|
printf(" %d\n", result); \
|
|
fflush(stdout); \
|
|
} while (0)
|
|
|
|
#define PP(s) \
|
|
do { \
|
|
printf("%s:%d: %s\n", __FILE__, __LINE__, s); \
|
|
fflush(stdout); \
|
|
} while (0)
|
|
|
|
#define P1(fmt, x) \
|
|
do { \
|
|
printf("%s:%d: " fmt "\n", __FILE__, __LINE__, x); \
|
|
fflush(stdout); \
|
|
} while (0)
|
|
|
|
int failures = 0;
|
|
|
|
void test_uloc(void);
|
|
void test_acl_files(void);
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int logopt = 0;
|
|
#if 0 && defined(LOG_PERROR)
|
|
logopt = LOG_PERROR;
|
|
#endif
|
|
openlog("test_server", logopt, LOG_USER);
|
|
puts("Zephyr server testing");
|
|
puts("");
|
|
|
|
test_uloc();
|
|
test_acl_files();
|
|
|
|
if(failures)
|
|
printf("\n%d FAILURES\n", failures);
|
|
|
|
exit(!(failures == 0));
|
|
}
|
|
|
|
void
|
|
test_uloc(void)
|
|
{
|
|
ZNotice_t z1, z2, z0, z4;
|
|
String *s1, *s2, *s0, *s4;
|
|
struct sockaddr_in who1, who2, who3, who0, who4;
|
|
int ret;
|
|
|
|
puts("uloc storage routines");
|
|
|
|
TEST(ulogin_find_user("nonexistent") == -1);
|
|
|
|
/* fake up just enough */
|
|
who1.sin_family = AF_INET;
|
|
who1.sin_port = 1;
|
|
who1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
|
|
z1.z_class_inst = "user1";
|
|
z1.z_port = 1;
|
|
z1.z_message = "here\0now\0this\0";
|
|
z1.z_message_len = 14;
|
|
|
|
s1 = make_string(z1.z_class_inst, 0);
|
|
|
|
TEST(ulogin_add_user(&z1, NET_ANN, &who1) == 0);
|
|
TEST(ulogin_find_user("user1") != -1);
|
|
|
|
who2.sin_family = AF_INET;
|
|
who2.sin_port = 2;
|
|
who2.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
|
|
z2.z_class_inst = "user2";
|
|
z2.z_port = 2;
|
|
z2.z_message = "here\0now\0this\0";
|
|
z2.z_message_len = 14;
|
|
|
|
s2 = make_string(z2.z_class_inst, 0);
|
|
|
|
TEST(ulogin_add_user(&z2, NET_ANN, &who2) == 0);
|
|
TEST(ulogin_find_user("user2") != -1);
|
|
TEST(locations[ulogin_find_user("user1")].user == s1);
|
|
TEST(locations[ulogin_find_user("user2")].user == s2);
|
|
TEST(ulogin_add_user(&z1, NET_ANN, &who1) == 0);
|
|
TEST(locations[ulogin_find_user("user1")].user == s1);
|
|
TEST(locations[ulogin_find_user("user2")].user == s2);
|
|
|
|
who3.sin_family = AF_INET;
|
|
who3.sin_port = 3;
|
|
who3.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
|
|
TEST(ulogin_find("user1", &who3.sin_addr, 3) == -1);
|
|
|
|
who0.sin_family = AF_INET;
|
|
who0.sin_port = 3;
|
|
who0.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
|
|
z0.z_class_inst = "user0";
|
|
z0.z_port = 3;
|
|
z0.z_message = "here\0now\0this\0";
|
|
z0.z_message_len = 14;
|
|
|
|
s0 = make_string(z0.z_class_inst, 0);
|
|
|
|
TEST(ulogin_add_user(&z0, NET_ANN, &who0) == 0);
|
|
TEST(ulogin_find_user("user0") != -1);
|
|
TEST(locations[ulogin_find_user("user1")].user == s1);
|
|
TEST(locations[ulogin_find_user("user2")].user == s2);
|
|
|
|
TEST(ulogin_remove_user(&z0, &who0, &ret) == NET_ANN && ret == 0);
|
|
/* 1 = NOLOC */
|
|
TEST(ulogin_remove_user(&z0, &who0, &ret) == NONE && ret == 1);
|
|
|
|
TEST(ulogin_add_user(&z0, NET_ANN, &who0) == 0);
|
|
TEST(ulogin_remove_user(&z1, &who0, &ret) == NET_ANN && ret == 0);
|
|
|
|
V(ulogin_flush_user(&z0));
|
|
TEST(ulogin_find_user("user0") == -1);
|
|
|
|
TEST(ulogin_add_user(&z0, NET_ANN, &who0) == 0);
|
|
TEST(ulogin_add_user(&z1, NET_ANN, &who1) == 0);
|
|
V(ulogin_flush_user(&z1));
|
|
TEST(ulogin_find_user("user1") == -1);
|
|
|
|
who4.sin_family = AF_INET;
|
|
who4.sin_port = 4;
|
|
who4.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
z4.z_class_inst = "user4";
|
|
z4.z_port = 4;
|
|
z4.z_message = "here\0now\0this\0";
|
|
z4.z_message_len = 14;
|
|
|
|
s4 = make_string(z4.z_class_inst, 0);
|
|
|
|
TEST(ulogin_add_user(&z4, NET_ANN, &who4) == 0);
|
|
|
|
V(uloc_flush_client(&who2));
|
|
TEST(locations[ulogin_find_user("user0")].user == s0);
|
|
TEST(ulogin_find_user("user1") == -1);
|
|
TEST(ulogin_find_user("user2") == -1);
|
|
TEST(locations[ulogin_find_user("user4")].user == s4);
|
|
|
|
V(uloc_hflush(&who0.sin_addr));
|
|
TEST(ulogin_find_user("user0") == -1);
|
|
TEST(ulogin_find_user("user1") == -1);
|
|
TEST(ulogin_find_user("user2") == -1);
|
|
TEST(locations[ulogin_find_user("user4")].user == s4);
|
|
puts("");
|
|
}
|
|
|
|
void
|
|
test_acl_files(){
|
|
char filename[]="/tmp/test_server_acl.XXXXXX";
|
|
int fd;
|
|
int result;
|
|
struct sockaddr_in who_zero;
|
|
struct sockaddr_in who_localhost;
|
|
struct sockaddr_in who_broadcast;
|
|
|
|
memset(&who_zero, 0, sizeof(who_zero));
|
|
memset(&who_localhost, 0, sizeof(who_localhost));
|
|
memset(&who_broadcast, 0, sizeof(who_broadcast));
|
|
|
|
who_localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
who_broadcast.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
|
|
|
puts("low-level acl routines");
|
|
puts("");
|
|
|
|
fd = mkstemp(filename);
|
|
P1("acl file is %s", filename);
|
|
|
|
PP("empty acl");
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 0);
|
|
|
|
write(fd, "*\n", 2);
|
|
acl_cache_reset();
|
|
PP("acl of *");
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 1);
|
|
TEST(acl_check(filename, "bar", NULL) == 1);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
write(fd, "foo\n", 4);
|
|
acl_cache_reset();
|
|
PP("acl of just foo");
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 1);
|
|
TEST(acl_check(filename, "bar", NULL) == 0);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
write(fd, "*@TIM.EDU\n", 10);
|
|
acl_cache_reset();
|
|
PP("acl of *@TIM.EDU");
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 0);
|
|
TEST(acl_check(filename, "bar", NULL) == 0);
|
|
TEST(acl_check(filename, "foo@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 1);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
write(fd, "*.*@TIM.EDU\n", 12);
|
|
acl_cache_reset();
|
|
PP("acl of *.*@TIM.EDU");
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 0);
|
|
TEST(acl_check(filename, "bar", NULL) == 0);
|
|
TEST(acl_check(filename, "foo@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 1);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
write(fd, "foo@TIM.EDU\n", 12);
|
|
acl_cache_reset();
|
|
PP("acl of foo@TIM.EDU");
|
|
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 0);
|
|
TEST(acl_check(filename, "bar", NULL) == 0);
|
|
TEST(acl_check(filename, "foo@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "f\\oo@TIM.EDU", NULL) == 0);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 0);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
write(fd, "!bar@TIM.EDU\n*@*\n", 17);
|
|
acl_cache_reset();
|
|
PP("acl of !bar@TIM.EDU, *@*");
|
|
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 1);
|
|
TEST(acl_check(filename, "bar", NULL) == 1);
|
|
TEST(acl_check(filename, "foo@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "f\\oo@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 0);
|
|
|
|
TEST(acl_check(filename, NULL, &who_zero) == 0);
|
|
TEST(acl_check(filename, NULL, &who_localhost) == 0);
|
|
|
|
write(fd, "@0.0.0.0\n", 9);
|
|
acl_cache_reset();
|
|
PP("acl +@0.0.0.0");
|
|
|
|
TEST(acl_check(filename, NULL, &who_zero) == 1);
|
|
TEST(acl_check(filename, NULL, &who_localhost) == 0);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", &who_zero) == 0);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
ftruncate(fd, 0);
|
|
write(fd, "*@*\n@0.0.0.0\n!@127.0.0.0/8\n", 27);
|
|
acl_cache_reset();
|
|
PP("acl *@*, @0.0.0.0, !@127/8");
|
|
|
|
TEST(acl_check(filename, NULL, &who_zero) == 1);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", &who_zero) == 1);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", &who_localhost) == 0);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
ftruncate(fd, 0);
|
|
write(fd, "*/root@TIM.EDU\n", 15);
|
|
acl_cache_reset();
|
|
PP("acl */root@TIM.EDU");
|
|
TEST(acl_check(filename, NULL, NULL) == 0);
|
|
TEST(acl_check(filename, "foo", NULL) == 0);
|
|
TEST(acl_check(filename, "bar", NULL) == 0);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 0);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 0);
|
|
TEST(acl_check(filename, "foo/root@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "bar/root@TIM.EDU", NULL) == 1);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
ftruncate(fd, 0);
|
|
write(fd, "foo/*@TIM.EDU\n", 14);
|
|
acl_cache_reset();
|
|
PP("acl foo/*@TIM.EDU");
|
|
TEST(acl_check(filename, "foo@TIM.EDU", NULL) == 0);
|
|
TEST(acl_check(filename, "bar@TIM.EDU", NULL) == 0);
|
|
TEST(acl_check(filename, "foo/root@TIM.EDU", NULL) == 1);
|
|
TEST(acl_check(filename, "bar/root@TIM.EDU", NULL) == 0);
|
|
|
|
PP("check vs. nonexistent acl");
|
|
TEST(acl_check("/nonexistent", "foo", NULL) == 0);
|
|
unlink(filename);
|
|
puts("");
|
|
}
|