1 | /* |
---|
2 | * gss-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 | |
---|
15 | #include <tests/tap/basic.h> |
---|
16 | #include <tests/tap/kerberos.h> |
---|
17 | #include <util/util.h> |
---|
18 | |
---|
19 | extern char send_buffer[2048]; |
---|
20 | extern char recv_buffer[2048]; |
---|
21 | extern size_t send_length; |
---|
22 | extern size_t recv_length; |
---|
23 | extern int send_flags; |
---|
24 | extern int recv_flags; |
---|
25 | |
---|
26 | |
---|
27 | int |
---|
28 | main(void) |
---|
29 | { |
---|
30 | char *principal; |
---|
31 | gss_buffer_desc name_buf, server_tok, client_tok, *token_ptr; |
---|
32 | gss_name_t server_name, client_name; |
---|
33 | gss_ctx_id_t server_ctx, client_ctx; |
---|
34 | OM_uint32 c_stat, c_min_stat, s_stat, s_min_stat, ret_flags; |
---|
35 | gss_OID doid; |
---|
36 | int status, flags; |
---|
37 | |
---|
38 | /* Unless we have Kerberos available, we can't really do anything. */ |
---|
39 | principal = kerberos_setup(); |
---|
40 | if (principal == NULL) |
---|
41 | skip_all("Kerberos tests not configured"); |
---|
42 | plan(26); |
---|
43 | |
---|
44 | /* |
---|
45 | * We have to set up a context first in order to do this test, which is |
---|
46 | * rather annoying. |
---|
47 | */ |
---|
48 | name_buf.value = principal; |
---|
49 | name_buf.length = strlen(principal) + 1; |
---|
50 | s_stat = gss_import_name(&s_min_stat, &name_buf, GSS_C_NT_USER_NAME, |
---|
51 | &server_name); |
---|
52 | if (s_stat != GSS_S_COMPLETE) |
---|
53 | bail("cannot import name"); |
---|
54 | server_ctx = GSS_C_NO_CONTEXT; |
---|
55 | client_ctx = GSS_C_NO_CONTEXT; |
---|
56 | token_ptr = GSS_C_NO_BUFFER; |
---|
57 | do { |
---|
58 | c_stat = gss_init_sec_context(&c_min_stat, GSS_C_NO_CREDENTIAL, |
---|
59 | &client_ctx, server_name, |
---|
60 | (const gss_OID) GSS_KRB5_MECHANISM, |
---|
61 | GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, |
---|
62 | 0, NULL, token_ptr, NULL, &client_tok, |
---|
63 | &ret_flags, NULL); |
---|
64 | if (token_ptr != GSS_C_NO_BUFFER) |
---|
65 | gss_release_buffer(&c_min_stat, &server_tok); |
---|
66 | if (client_tok.length == 0) |
---|
67 | break; |
---|
68 | s_stat = gss_accept_sec_context(&s_min_stat, &server_ctx, |
---|
69 | GSS_C_NO_CREDENTIAL, &client_tok, |
---|
70 | GSS_C_NO_CHANNEL_BINDINGS, |
---|
71 | &client_name, &doid, &server_tok, |
---|
72 | &ret_flags, NULL, NULL); |
---|
73 | gss_release_buffer(&c_min_stat, &client_tok); |
---|
74 | if (server_tok.length == 0) |
---|
75 | break; |
---|
76 | token_ptr = &server_tok; |
---|
77 | } while (c_stat == GSS_S_CONTINUE_NEEDED |
---|
78 | || s_stat == GSS_S_CONTINUE_NEEDED); |
---|
79 | if (c_stat != GSS_S_COMPLETE || s_stat != GSS_S_COMPLETE) |
---|
80 | bail("cannot establish context"); |
---|
81 | |
---|
82 | /* Okay, we should now be able to send and receive a token. */ |
---|
83 | server_tok.value = (char *) "hello"; |
---|
84 | server_tok.length = 5; |
---|
85 | status = token_send_priv(0, server_ctx, 3, &server_tok, &s_stat, |
---|
86 | &s_min_stat); |
---|
87 | is_int(TOKEN_OK, status, "sent a token successfully"); |
---|
88 | is_int(3, send_flags, "...with the right flags"); |
---|
89 | ok(send_length > 5, "...and enough length"); |
---|
90 | server_tok.value = send_buffer; |
---|
91 | server_tok.length = send_length; |
---|
92 | c_stat = gss_unwrap(&c_min_stat, client_ctx, &server_tok, &client_tok, |
---|
93 | NULL, NULL); |
---|
94 | is_int(GSS_S_COMPLETE, c_stat, "...and it unwrapped"); |
---|
95 | is_int(5, client_tok.length, "...with the right length"); |
---|
96 | ok(memcmp(client_tok.value, "hello", 5) == 0, "...and contents"); |
---|
97 | gss_release_buffer(&c_min_stat, &client_tok); |
---|
98 | client_tok.length = 0; |
---|
99 | client_tok.value = NULL; |
---|
100 | server_tok.value = (char *) "hello"; |
---|
101 | server_tok.length = 5; |
---|
102 | status = token_send_priv(0, server_ctx, 3, &server_tok, &s_stat, |
---|
103 | &s_min_stat); |
---|
104 | is_int(TOKEN_OK, status, "sent another token"); |
---|
105 | memcpy(recv_buffer, send_buffer, send_length); |
---|
106 | recv_length = send_length; |
---|
107 | recv_flags = send_flags; |
---|
108 | status = token_recv_priv(0, client_ctx, &flags, &client_tok, 1024, |
---|
109 | &s_stat, &c_min_stat); |
---|
110 | is_int(TOKEN_OK, status, "received the token"); |
---|
111 | is_int(5, client_tok.length, "...with the right length"); |
---|
112 | ok(memcmp(client_tok.value, "hello", 5) == 0, "...and the right data"); |
---|
113 | is_int(3, flags, "...and the right flags"); |
---|
114 | gss_release_buffer(&c_min_stat, &client_tok); |
---|
115 | |
---|
116 | /* Test receiving too large of a token. */ |
---|
117 | status = token_recv_priv(0, client_ctx, &flags, &client_tok, 4, &s_stat, |
---|
118 | &s_min_stat); |
---|
119 | is_int(TOKEN_FAIL_LARGE, status, "receiving too large of a token"); |
---|
120 | |
---|
121 | /* Test receiving a corrupt token. */ |
---|
122 | recv_length = 4; |
---|
123 | status = token_recv_priv(0, client_ctx, &flags, &client_tok, 1024, |
---|
124 | &s_stat, &s_min_stat); |
---|
125 | is_int(TOKEN_FAIL_GSSAPI, status, "receiving a corrupt token"); |
---|
126 | |
---|
127 | /* |
---|
128 | * Now, fake up a token to make sure that token_recv_priv is doing the |
---|
129 | * right thing. |
---|
130 | */ |
---|
131 | recv_flags = 5; |
---|
132 | client_tok.value = (char *) "hello"; |
---|
133 | client_tok.length = 5; |
---|
134 | c_stat = gss_wrap(&c_min_stat, client_ctx, 1, GSS_C_QOP_DEFAULT, |
---|
135 | &client_tok, NULL, &server_tok); |
---|
136 | is_int(GSS_S_COMPLETE, c_stat, "wrapped a fake token"); |
---|
137 | recv_length = server_tok.length; |
---|
138 | memcpy(recv_buffer, server_tok.value, server_tok.length); |
---|
139 | gss_release_buffer(&c_min_stat, &server_tok); |
---|
140 | status = token_recv_priv(0, server_ctx, &flags, &server_tok, 1024, |
---|
141 | &s_stat, &s_min_stat); |
---|
142 | is_int(TOKEN_OK, status, "received a fake token"); |
---|
143 | is_int(5, flags, "...with the right flags"); |
---|
144 | is_int(5, server_tok.length, "...and the right length"); |
---|
145 | ok(memcmp(server_tok.value, "hello", 5) == 0, "...and data"); |
---|
146 | gss_release_buffer(&c_min_stat, &server_tok); |
---|
147 | |
---|
148 | /* Test the stupid protocol v1 MIC stuff. */ |
---|
149 | server_tok.value = (char *) "hello"; |
---|
150 | server_tok.length = 5; |
---|
151 | c_stat = gss_get_mic(&c_min_stat, client_ctx, GSS_C_QOP_DEFAULT, |
---|
152 | &server_tok, &client_tok); |
---|
153 | is_int(GSS_S_COMPLETE, c_stat, "got MIC for protocol v1 token"); |
---|
154 | memcpy(recv_buffer, client_tok.value, client_tok.length); |
---|
155 | recv_length = client_tok.length; |
---|
156 | recv_flags = TOKEN_MIC; |
---|
157 | status = token_send_priv(0, server_ctx, TOKEN_DATA | TOKEN_SEND_MIC, |
---|
158 | &server_tok, &s_stat, &s_min_stat); |
---|
159 | is_int(TOKEN_OK, status, "sent protocol v1 token with MIC"); |
---|
160 | memcpy(recv_buffer, send_buffer, send_length); |
---|
161 | recv_length = send_length; |
---|
162 | recv_flags = send_flags; |
---|
163 | status = token_recv_priv(0, client_ctx, &flags, &client_tok, 1024, |
---|
164 | &c_stat, &c_min_stat); |
---|
165 | is_int(TOKEN_OK, status, "received protocol v1 token with MIC"); |
---|
166 | is_int(TOKEN_DATA, flags, "...with the right flags"); |
---|
167 | is_int(5, client_tok.length, "...and the right length"); |
---|
168 | ok(memcmp(client_tok.value, "hello", 5) == 0, "...and the right data"); |
---|
169 | is_int(TOKEN_MIC, send_flags, "...and the right send flags"); |
---|
170 | server_tok.value = send_buffer; |
---|
171 | server_tok.length = send_length; |
---|
172 | s_stat = gss_verify_mic(&s_min_stat, server_ctx, &client_tok, &server_tok, |
---|
173 | NULL); |
---|
174 | is_int(GSS_S_COMPLETE, s_stat, "...and would send correct MIC"); |
---|
175 | |
---|
176 | return 0; |
---|
177 | } |
---|