source: web/old/remctl-2.14/tests/util/tokens-t.c @ f6f3e91

web
Last change on this file since f6f3e91 was f6f3e91, checked in by Jessica B. Hamrick <jhamrick@…>, 15 years ago

Preserve directory hierarchy (not sure what happened to it)

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * tokens test suite.
3 *
4 * Written by Russ Allbery <rra@stanford.edu>
5 * Copyright 2006, 2007, 2009
6 *     Board of Trustees, Leland Stanford Jr. University
7 *
8 * See LICENSE for licensing terms.
9 */
10
11#include <config.h>
12#include <portable/system.h>
13#include <portable/gssapi.h>
14#include <portable/socket.h>
15
16#include <fcntl.h>
17#include <sys/stat.h>
18#include <sys/time.h>
19#include <sys/wait.h>
20
21#include <tests/tap/basic.h>
22#include <util/util.h>
23
24/* A token for testing. */
25static const char token[] = { 3, 0, 0, 0, 5, 'h', 'e', 'l', 'l', 'o' };
26
27
28/*
29 * Create a server socket, wait for a connection, and return the connected
30 * socket.
31 */
32static int
33create_server(void)
34{
35    int fd, conn, marker;
36    struct sockaddr_in saddr;
37    int on = 1;
38
39    saddr.sin_family = AF_INET;
40    saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
41    saddr.sin_port = htons(14373);
42    fd = socket(AF_INET, SOCK_STREAM, 0);
43    if (fd < 0)
44        sysbail("error creating socket");
45    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
46    if (bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
47        sysbail("error binding socket");
48    if (listen(fd, 1) < 0)
49        sysbail("error listening on socket");
50    marker = open("server-ready", O_CREAT | O_TRUNC, 0666);
51    if (marker < 0)
52        sysbail("cannot create marker file");
53    conn = accept(fd, NULL, 0);
54    if (conn < 0)
55        sysbail("error accepting connection");
56    return conn;
57}
58
59
60/*
61 * Create a client socket, it for a connection, and return the connected
62 * socket.
63 */
64static int
65create_client(void)
66{
67    int fd;
68    struct sockaddr_in saddr;
69    struct timeval tv;
70
71    saddr.sin_family = AF_INET;
72    saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
73    saddr.sin_port = htons(14373);
74    fd = socket(AF_INET, SOCK_STREAM, 0);
75    if (fd < 0)
76        sysbail("error creating socket");
77    alarm(1);
78    while (access("server-ready", F_OK) != 0) {
79        tv.tv_sec = 0;
80        tv.tv_usec = 10000;
81        select(0, NULL, NULL, NULL, &tv);
82    }
83    alarm(0);
84    if (connect(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
85        sysbail("error connecting");
86    return fd;
87}
88
89
90/*
91 * Send a hand-constructed token to a file descriptor.
92 */
93static void
94send_hand_token(int fd)
95{
96    xwrite(fd, token, sizeof(token));
97}
98
99
100/*
101 * Send a token via token_send to a file descriptor.
102 */
103static void
104send_regular_token(int fd)
105{
106    gss_buffer_desc buffer;
107
108    buffer.value = xmalloc(5);
109    memcpy(buffer.value, "hello", 5);
110    buffer.length = 5;
111    token_send(fd, 3, &buffer);
112}
113
114
115int
116main(void)
117{
118    pid_t child;
119    int server, client, status, flags;
120    char buffer[20];
121    ssize_t length;
122    gss_buffer_desc result;
123
124    alarm(2);
125
126    plan(10);
127    if (chdir(getenv("BUILD")) < 0)
128        sysbail("can't chdir to BUILD");
129
130    unlink("server-ready");
131    child = fork();
132    if (child < 0)
133        sysbail("cannot fork");
134    else if (child == 0) {
135        server = create_server();
136        send_regular_token(server);
137        exit(0);
138    } else {
139        client = create_client();
140        length = read(client, buffer, 12);
141        is_int(10, length, "received token has correct length");
142        ok(memcmp(buffer, token, 10) == 0, "...and correct data");
143        waitpid(child, NULL, 0);
144    }
145
146    unlink("server-ready");
147    child = fork();
148    if (child < 0)
149        sysbail("cannot fork");
150    else if (child == 0) {
151        server = create_server();
152        send_hand_token(server);
153        exit(0);
154    } else {
155        client = create_client();
156        status = token_recv(client, &flags, &result, 5);
157        is_int(TOKEN_OK, status, "received hand-rolled token");
158        is_int(3, flags, "...with right flags");
159        is_int(5, result.length, "...and right length");
160        ok(memcmp(result.value, "hello", 5) == 0, "...and right data");
161        waitpid(child, NULL, 0);
162    }
163
164    unlink("server-ready");
165    child = fork();
166    if (child < 0)
167        sysbail("cannot fork");
168    else if (child == 0) {
169        server = create_server();
170        xwrite(server, "\0\0\0\0\1", 5);
171        exit(0);
172    } else {
173        client = create_client();
174        status = token_recv(client, &flags, &result, 200);
175        is_int(TOKEN_FAIL_INVALID, status, "receive invalid token");
176        waitpid(child, NULL, 0);
177    }
178
179    unlink("server-ready");
180    child = fork();
181    if (child < 0)
182        sysbail("cannot fork");
183    else if (child == 0) {
184        server = create_server();
185        send_hand_token(server);
186        exit(0);
187    } else {
188        client = create_client();
189        status = token_recv(client, &flags, &result, 4);
190        is_int(TOKEN_FAIL_LARGE, status, "receive too-large token");
191        waitpid(child, NULL, 0);
192    }
193
194    unlink("server-ready");
195    child = fork();
196    if (child < 0)
197        sysbail("cannot fork");
198    else if (child == 0) {
199        server = create_server();
200        close(server);
201        exit(0);
202    } else {
203        client = create_client();
204        status = token_recv(client, &flags, &result, 4);
205        is_int(TOKEN_FAIL_EOF, status, "receive end of file");
206        waitpid(child, NULL, 0);
207    }
208    unlink("server-ready");
209
210    /* Special test for error handling when sending tokens. */
211    server = open("/dev/full", O_RDWR);
212    if (server < 0)
213        skip("/dev/full not available");
214    else {
215        result.value = xmalloc(5);
216        memcpy(result.value, "hello", 5);
217        result.length = 5;
218        status = token_send(server, 3, &result);
219        free(result.value);
220        is_int(TOKEN_FAIL_SOCKET, status, "can't send due to system error");
221        close(server);
222    }
223
224    return 0;
225}
Note: See TracBrowser for help on using the repository browser.