1 /* 2 * Helper functions for testing WebAuth code. 3 * 4 * Additional functions that are helpful for testing WebAuth code and have 5 * knowledge of WebAuth functions and data structures. 6 * 7 * Written by Russ Allbery <eagle@eyrie.org> 8 * Copyright 2013, 2014 9 * The Board of Trustees of the Leland Stanford Junior University 10 * 11 * See LICENSE for licensing terms. 12 */ 13 14 #ifndef TAP_WEBAUTH_H 15 #define TAP_WEBAUTH_H 1 16 17 #include <config.h> 18 #include <tests/tap/macros.h> 19 20 #include <webauth/tokens.h> /* struct webauth_token_* */ 21 #include <webauth/webkdc.h> /* struct webauth_login */ 22 23 struct kerberos_config; 24 struct webauth_context; 25 struct webauth_keyring; 26 27 /* Empty tokens, used in building test data. */ 28 #define EMPTY_TOKEN_ID { NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, 0, 0 } 29 #define EMPTY_TOKEN_LOGIN { NULL, NULL, NULL, NULL, NULL, 0 } 30 #define EMPTY_TOKEN_PROXY { NULL, NULL, NULL, NULL, NULL, 0, 0, 0 } 31 #define EMPTY_TOKEN_WKFACTOR { NULL, NULL, 0, 0 } 32 #define EMPTY_TOKEN_WKPROXY { NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL } 33 34 /* Empty webauth_login struct, used in building test data. */ 35 #define EMPTY_LOGIN { NULL, NULL, 0 } 36 37 /* Helper macro for a successful login with no message in WebKDC login data. */ 38 #define LOGIN_SUCCESS 0, NULL 39 40 /* Helper macro for no factor information in WebKDC login data. */ 41 #define NO_FACTOR_DATA NULL, NULL 42 43 /* Helper macro for no authorization identities in WebKDC login data. */ 44 #define NO_AUTHZ_IDS { NULL, NULL, NULL } 45 46 /* Helper macros for empty token sets in WebKDC login data. */ 47 #define NO_TOKENS_LOGIN \ 48 { EMPTY_TOKEN_LOGIN, EMPTY_TOKEN_LOGIN, EMPTY_TOKEN_LOGIN } 49 #define NO_TOKENS_WKFACTOR \ 50 { EMPTY_TOKEN_WKFACTOR, EMPTY_TOKEN_WKFACTOR, EMPTY_TOKEN_WKFACTOR } 51 #define NO_TOKENS_WKPROXY \ 52 { EMPTY_TOKEN_WKPROXY, EMPTY_TOKEN_WKPROXY, EMPTY_TOKEN_WKPROXY } 53 54 /* Helper macro for an empty login history in WebKDC login data. */ 55 #define NO_LOGINS { EMPTY_LOGIN, EMPTY_LOGIN, EMPTY_LOGIN } 56 57 /* 58 * All of the following structs for test token data are paralle to the regular 59 * webauth_token_* definitions except that they may omit some data that must 60 * be constructed at runtime and have special handling for some fields. 61 * 62 * All identity strings plus the login password field support the following 63 * special tokens, which are replaced with information from the Kerberos 64 * configuration: 65 * 66 * <principal> Keytab principal 67 * <krb5-principal> Keytab principal prefixed with "krb5:" 68 * <webkdc-principal> Keytab principal prefixed with "WEBKDC:krb5:" 69 * <userprinc> User principal 70 * <username> User principal without the realm 71 * <password> User password 72 * 73 * For creation and expiration if the value is < 10000 and > 0, it is taken as 74 * a *negative* offset from now for creation and a *positive* offset from now 75 * for expiration. If creation is 0, check that the creation is somewhere 76 * around the current time. If expiration is 0, check to ensure that it's in 77 * the future but otherwise don't be picky. 78 */ 79 80 /* 81 * Data for an id token. Authentication data may be generated or checked on 82 * the fly if the auth type is krb5. 83 */ 84 struct wat_token_id { 85 const char *subject; 86 const char *authz_subject; 87 const char *auth; 88 const void *auth_data; 89 size_t auth_data_len; 90 const char *initial_factors; 91 const char *session_factors; 92 unsigned long loa; 93 time_t creation; 94 time_t expiration; 95 }; 96 97 /* Data for a login token. */ 98 struct wat_token_login { 99 const char *username; 100 const char *password; 101 const char *otp; 102 const char *otp_type; 103 const char *device_id; 104 time_t creation; 105 }; 106 107 /* 108 * Data for proxy token. The webkdc_proxy field of a regular proxy token 109 * struct is handled specially. 110 */ 111 struct wat_token_proxy { 112 const char *subject; 113 const char *authz_subject; 114 const char *type; 115 const char *initial_factors; 116 const char *session_factors; 117 unsigned long loa; 118 time_t creation; 119 time_t expiration; 120 }; 121 122 /* 123 * Data for a webkdc-proxy token. Proxy data may be generated or checked on 124 * the fly if the proxy_type is krb5. 125 */ 126 struct wat_token_webkdc_proxy { 127 const char *subject; 128 const char *proxy_type; 129 const char *proxy_subject; 130 const void *data; 131 size_t data_len; 132 const char *initial_factors; 133 unsigned long loa; 134 time_t creation; 135 time_t expiration; 136 137 /* Not included in the wire representation. */ 138 const char *session_factors; 139 }; 140 141 /* 142 * Data for a test service token. Omit the session key, which we generate on 143 * the fly while constructing the test. 144 */ 145 struct wat_token_webkdc_service { 146 const char *subject; 147 time_t creation; 148 time_t expiration; 149 }; 150 151 /* 152 * Test data for a WebKDC login request (<requestTokensRequest>). This is in 153 * a different form than the internal struct so that it can be statically 154 * initialized when building test cases and so that it doesn't contain 155 * encrypted tokens that will vary with each run. 156 */ 157 struct wat_login_request { 158 struct wat_token_webkdc_service service; 159 160 /* Authentication tokens. */ 161 struct wat_token_login logins[3]; 162 struct wat_token_webkdc_proxy wkproxies[3]; 163 struct webauth_token_webkdc_factor wkfactors[3]; 164 165 /* Requested authorization subject. */ 166 const char *authz_subject; 167 168 /* Authentication request from the WAS. */ 169 struct webauth_token_request request; 170 }; 171 172 /* 173 * Expected data for a WebKDC login response (<requestTokensResponse>). This 174 * includes only the data that can't be trivially derived from the request or 175 * from other parts of the response, and is structured differently from the 176 * normal internal data structure so that it can be statically initialized and 177 * doesn't contain encrypted tokens that will vary with each run. 178 */ 179 struct wat_login_response { 180 const char *user_message; 181 const char *login_state; 182 183 /* Represented as strings of comma-separated factors. */ 184 const char *factors_wanted; 185 const char *factors_configured; 186 187 /* Single sign-on tokens and user identity. */ 188 struct wat_token_webkdc_proxy proxies[3]; 189 struct webauth_token_webkdc_factor factor_token; 190 191 /* Only one of result_id or result_proxy will be set. */ 192 struct wat_token_id result_id; 193 struct wat_token_proxy result_proxy; 194 195 /* User information service information from logins. */ 196 struct webauth_login logins[3]; 197 time_t password_expires; 198 199 /* Permitted authorization identities. */ 200 const char *permitted_authz[3]; 201 }; 202 203 /* Data for a single WebKDC login test case. */ 204 struct wat_login_test { 205 const char *name; 206 int status; 207 const char *error; 208 struct wat_login_request request; 209 struct wat_login_response response; 210 }; 211 212 BEGIN_DECLS 213 214 /* Compare two tokens of various types. */ 215 void is_token_error(const struct webauth_token_error *wanted, 216 const struct webauth_token_error *seen, 217 const char *format, ...) 218 __attribute__((__format__(printf, 3, 4))); 219 void is_token_id(const struct webauth_token_id *wanted, 220 const struct webauth_token_id *seen, 221 const char *format, ...) 222 __attribute__((__format__(printf, 3, 4))); 223 void is_token_proxy(const struct webauth_token_proxy *wanted, 224 const struct webauth_token_proxy *seen, 225 const char *format, ...) 226 __attribute__((__format__(printf, 3, 4))); 227 void is_token_webkdc_factor(const struct webauth_token_webkdc_factor *wanted, 228 const struct webauth_token_webkdc_factor *seen, 229 const char *format, ...) 230 __attribute__((__format__(printf, 3, 4))); 231 void is_token_webkdc_proxy(const struct webauth_token_webkdc_proxy *wanted, 232 const struct webauth_token_webkdc_proxy *seen, 233 const char *format, ...) 234 __attribute__((__format__(printf, 3, 4))); 235 236 /* 237 * Run a test of the WebKDC login handling. Takes the WebAuth context in 238 * which to run the tests, the test case description, and the keyring to use 239 * for the WebKDC. 240 */ 241 void run_login_test(struct webauth_context *, const struct wat_login_test *, 242 const struct webauth_keyring *, 243 const struct kerberos_config *) 244 __attribute__((__nonnull__(1, 2, 3))); 245 246 END_DECLS 247 248 #endif /* !TAP_WEBAUTH_H */ 249