1 | /* |
---|
2 | * Test suite for errors returned by the server. |
---|
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 | |
---|
14 | #include <signal.h> |
---|
15 | #include <sys/wait.h> |
---|
16 | |
---|
17 | #include <client/internal.h> |
---|
18 | #include <client/remctl.h> |
---|
19 | #include <tests/tap/basic.h> |
---|
20 | #include <tests/tap/kerberos.h> |
---|
21 | #include <tests/tap/remctl.h> |
---|
22 | #include <util/util.h> |
---|
23 | |
---|
24 | |
---|
25 | /* |
---|
26 | * Run the given command and return the error code from the server, or |
---|
27 | * ERROR_INTERNAL if the command unexpectedly succeeded or we didn't get an |
---|
28 | * error code. |
---|
29 | */ |
---|
30 | static int |
---|
31 | test_error(struct remctl *r, const char *arg) |
---|
32 | { |
---|
33 | struct remctl_output *output; |
---|
34 | const char *command[] = { "test", NULL, NULL }; |
---|
35 | |
---|
36 | command[1] = arg; |
---|
37 | if (!remctl_command(r, command)) { |
---|
38 | notice("# remctl error %s", remctl_error(r)); |
---|
39 | return ERROR_INTERNAL; |
---|
40 | } |
---|
41 | do { |
---|
42 | output = remctl_output(r); |
---|
43 | switch (output->type) { |
---|
44 | case REMCTL_OUT_OUTPUT: |
---|
45 | notice("# test %s returned output: %.*s", arg, |
---|
46 | (int) output->length, output->data); |
---|
47 | break; |
---|
48 | case REMCTL_OUT_STATUS: |
---|
49 | notice("# test %s returned status %d", arg, output->status); |
---|
50 | return ERROR_INTERNAL; |
---|
51 | case REMCTL_OUT_ERROR: |
---|
52 | return output->error; |
---|
53 | case REMCTL_OUT_DONE: |
---|
54 | notice("# unexpected done token"); |
---|
55 | return ERROR_INTERNAL; |
---|
56 | } |
---|
57 | } while (output->type == REMCTL_OUT_OUTPUT); |
---|
58 | return ERROR_INTERNAL; |
---|
59 | } |
---|
60 | |
---|
61 | |
---|
62 | /* |
---|
63 | * Try to send a command with 10K arguments to the server. This should result |
---|
64 | * in ERROR_TOOMANY_ARGS given the current server limits. |
---|
65 | */ |
---|
66 | static int |
---|
67 | test_excess_args(struct remctl *r) |
---|
68 | { |
---|
69 | struct remctl_output *output; |
---|
70 | const char **command; |
---|
71 | size_t i; |
---|
72 | |
---|
73 | command = xmalloc((10 * 1024 + 3) * sizeof(const char *)); |
---|
74 | command[0] = "test"; |
---|
75 | command[1] = "echo"; |
---|
76 | for (i = 2; i < (10 * 1024) + 2; i++) |
---|
77 | command[i] = "a"; |
---|
78 | command[10 * 1024 + 2] = NULL; |
---|
79 | if (!remctl_command(r, command)) { |
---|
80 | notice("# remctl error %s", remctl_error(r)); |
---|
81 | return ERROR_INTERNAL; |
---|
82 | } |
---|
83 | free(command); |
---|
84 | do { |
---|
85 | output = remctl_output(r); |
---|
86 | switch (output->type) { |
---|
87 | case REMCTL_OUT_OUTPUT: |
---|
88 | notice("# test echo returned output: %.*s", (int) output->length, |
---|
89 | output->data); |
---|
90 | break; |
---|
91 | case REMCTL_OUT_STATUS: |
---|
92 | notice("# test echo returned status %d", output->status); |
---|
93 | return ERROR_INTERNAL; |
---|
94 | case REMCTL_OUT_ERROR: |
---|
95 | return output->error; |
---|
96 | case REMCTL_OUT_DONE: |
---|
97 | notice("# unexpected done token"); |
---|
98 | return ERROR_INTERNAL; |
---|
99 | } |
---|
100 | } while (output->type == REMCTL_OUT_OUTPUT); |
---|
101 | return ERROR_INTERNAL; |
---|
102 | } |
---|
103 | |
---|
104 | |
---|
105 | int |
---|
106 | main(void) |
---|
107 | { |
---|
108 | char *principal, *config, *path; |
---|
109 | struct remctl *r; |
---|
110 | pid_t remctld; |
---|
111 | int status; |
---|
112 | |
---|
113 | /* Unless we have Kerberos available, we can't really do anything. */ |
---|
114 | if (chdir(getenv("SOURCE")) < 0) |
---|
115 | bail("can't chdir to SOURCE"); |
---|
116 | principal = kerberos_setup(); |
---|
117 | if (principal == NULL) |
---|
118 | skip_all("Kerberos tests not configured"); |
---|
119 | plan(4); |
---|
120 | config = concatpath(getenv("SOURCE"), "data/conf-simple"); |
---|
121 | path = concatpath(getenv("BUILD"), "../server/remctld"); |
---|
122 | remctld = remctld_start(path, principal, config); |
---|
123 | |
---|
124 | /* Run the tests. */ |
---|
125 | r = remctl_new(); |
---|
126 | if (!remctl_open(r, "localhost", 14373, principal)) |
---|
127 | bail("cannot contact remctld"); |
---|
128 | status = test_error(r, "bad-command"); |
---|
129 | is_int(ERROR_UNKNOWN_COMMAND, status, "unknown command"); |
---|
130 | status = test_error(r, "noauth"); |
---|
131 | is_int(ERROR_ACCESS, status, "access denied"); |
---|
132 | status = test_excess_args(r); |
---|
133 | is_int(ERROR_TOOMANY_ARGS, status, "too many arguments"); |
---|
134 | status = test_error(r, NULL); |
---|
135 | is_int(ERROR_UNKNOWN_COMMAND, status, "unknown command"); |
---|
136 | remctl_close(r); |
---|
137 | |
---|
138 | remctld_stop(remctld); |
---|
139 | kerberos_cleanup(); |
---|
140 | return 0; |
---|
141 | } |
---|