[f6f3e91] | 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 | } |
---|