2 * Copyright (c) 2014 <copyright holder> <email>
4 * For license details, see the LICENSE file in the root of this project.
9 #include "GSSCreateSecContextTest.h"
10 #include "GSSInitSecContext.h"
11 #include "command_mocks/InitSecContextMock.h"
15 #include "util_json.h"
16 #include <cache/GSSContextCache.h>
17 #include <cache/GSSNameCache.h>
18 #include <datamodel/GSSContext.h>
19 #include <utils/base64.h>
21 // Registers the fixture into the 'registry'
22 CPPUNIT_TEST_SUITE_REGISTRATION( GSSCreateSecContextTest );
26 static OM_uint32 KRB5_CALLCONV
28 OM_uint32 *minor_status,
29 gss_cred_id_t claimant_cred_handle,
30 gss_ctx_id_t *context_handle,
31 gss_name_t target_name,
35 gss_channel_bindings_t input_chan_bindings,
36 gss_buffer_t input_token,
37 gss_OID *actual_mech_type,
38 gss_buffer_t output_token,
42 gss_ctx_id_t tmpContext;
44 InitSecContextMock::visited = true;
46 /* Copy in the input to this function */
47 InitSecContextMock::claimant_cred_handle = claimant_cred_handle;
48 InitSecContextMock::target_name = target_name;
49 InitSecContextMock::mech_type = mech_type;
50 InitSecContextMock::req_flags = req_flags;
51 InitSecContextMock::time_req = time_req;
52 InitSecContextMock::input_chan_bindings = input_chan_bindings;
53 InitSecContextMock::input_token.length = input_token->length;
54 InitSecContextMock::input_token.value = input_token->value;
57 /* Copy out the output from this function */
58 *minor_status = InitSecContextMock::minor_status;
59 *actual_mech_type = InitSecContextMock::actual_mech_type;
60 output_token->length = InitSecContextMock::output_token.length;
61 output_token->value = InitSecContextMock::output_token.value;
62 *ret_flags = InitSecContextMock::ret_flags;
63 *time_rec = InitSecContextMock::time_rec;
65 /* Handle the one that's I/O */
66 tmpContext = *context_handle;
67 *context_handle = InitSecContextMock::context_handle;
68 InitSecContextMock::context_handle = tmpContext;
70 return InitSecContextMock::retVal;
75 GSSCreateSecContextTest::setUp()
77 InitSecContextMock::reset();
81 GSSCreateSecContextTest::tearDown()
86 GSSCreateSecContextTest::testConstructor()
88 GSSInitSecContext cmd = GSSInitSecContext();
92 cmdFn = cmd.getGSSFunction();
93 GSSFn = (void *)&gss_init_sec_context;
94 CPPUNIT_ASSERT_MESSAGE(
95 "The default constructor for GSSCreateSecContextCommand should assign the function gss_init_sec_context",
98 // Check that we defaut to the moonshot OID
99 CPPUNIT_ASSERT_EQUAL_MESSAGE(
100 "The mech_type default value is unexpected.",
101 std::string("{ 1 3 6 1 5 5 15 1 1 18 }"),
102 cmd.getMechType().toString()
108 * "method": "gss_create_sec_context",
113 * "mech_type": "{ 1 2 840 113554 1 2 1 4 }",
114 * "target_name": "me@my.sha/DOW"
118 void GSSCreateSecContextTest::testConstructorWithJSONObject()
120 OM_uint32 major, minor;
123 char *source_name = (char *)"HTTP@localhost\0";
126 major = gss_import_name(&minor, GSSBuffer(source_name).toGss(), GSS_C_NT_HOSTBASED_SERVICE, &src);
127 if (GSS_ERROR(major))
129 OM_uint32 min, context;
132 std::cout << "Error in importing name." << std::endl;
133 gss_display_status(&min, major, GSS_C_GSS_CODE, GSS_C_NT_HOSTBASED_SERVICE, &context, &buf);
134 std::cout << " message: " << (char *)buf.value << std::endl;
136 CPPUNIT_ASSERT_MESSAGE(
137 "Could not generate a name to test GSSCreateSecContext JSON parsing.",
140 source.setValue(src);
141 std::string key = GSSNameCache::instance()->store(source);
143 std::string input = "{\"req_flags\": \"1\", \
144 \"time_req\": \"2\", \
145 \"mech_type\": \"{ 1 2 840 113554 1 2 1 4 }\", \
146 \"target_name\": \"";
147 input = input + key + "\"}";
149 json_error_t jsonErr;
150 const char *in = input.c_str();
151 JSONObject json = JSONObject::load(in, 0, &jsonErr);
153 GSSInitSecContext cmd = GSSInitSecContext(
155 (void *)&mock_init_sec
158 const char *from_cmd = cmd.getTargetDisplayName();
160 CPPUNIT_ASSERT_MESSAGE(
161 "The object does not have a target name.",
162 ( strcmp(source_name, from_cmd) == 0 )
165 CPPUNIT_ASSERT_EQUAL_MESSAGE(
166 "The context_handle values differ.",
167 json["context_handle"].integer(),
168 (json_int_t)cmd.getContextHandle()
171 CPPUNIT_ASSERT_EQUAL_MESSAGE(
172 "The mech_type values differ.",
173 std::string(json["mech_type"].string()),
174 cmd.getMechType().toString()
177 CPPUNIT_ASSERT_EQUAL_MESSAGE(
178 "The req_flags differ.",
179 (int)json["req_flags"].integer(),
180 (int)cmd.getReqFlags()
183 CPPUNIT_ASSERT_EQUAL_MESSAGE(
184 "The req_flags differ.",
185 (int)json["time_req"].integer(),
186 (int)cmd.getTimeReq()
192 GSSCreateSecContextTest::testEmptyCall()
194 gss_ctx_id_t expectedResult, expectedArgument;
196 GSSInitSecContext cmd ((void *)&mock_init_sec);
198 /* Set expectations on what the GSS function will be called with */
199 cmd.time_req = rand() % 1024;
200 cmd.req_flags = rand() % 1024;
201 cmd.target_name = NULL;
202 cmd.context_handle = expectedArgument = (gss_ctx_id_t)(long)rand();
206 /* Set expectations on what the GSS function will produce */
207 InitSecContextMock::retVal = rand() % 1024;
208 InitSecContextMock::minor_status = rand() % 1024;
209 InitSecContextMock::context_handle = expectedResult = (gss_ctx_id_t)(long)rand();
210 InitSecContextMock::actual_mech_type = NULL;
211 InitSecContextMock::output_token.value = (void *)"http@project-moonshot.org/PROJECT-MOONSHOT.ORG\0";
212 InitSecContextMock::output_token.length = strlen((char *)InitSecContextMock::output_token.value);
213 InitSecContextMock::ret_flags = rand() % 1024;
214 InitSecContextMock::time_req = rand() % 1024;
218 /* Check that init_sec_context's inputs are sent correctly */
219 CPPUNIT_ASSERT_MESSAGE(
220 "The GSS function was not invoked!",
221 InitSecContextMock::visited
223 CPPUNIT_ASSERT_EQUAL_MESSAGE(
224 "The time_req field was not used in the call to init_sec_context",
226 InitSecContextMock::time_req
228 CPPUNIT_ASSERT_EQUAL_MESSAGE(
229 "The req_flags field was not used in the call to init_sec_context",
231 InitSecContextMock::req_flags
233 CPPUNIT_ASSERT_EQUAL_MESSAGE(
234 "The mech_type field was not used in the call to init_sec_context",
235 cmd.getMechType().toGss(),
236 InitSecContextMock::mech_type
238 CPPUNIT_ASSERT_EQUAL_MESSAGE(
239 "The target_name field was not used in the call to init_sec_context",
241 InitSecContextMock::target_name
245 /* Check that init_sec_context's outputs are captured correctly */
246 CPPUNIT_ASSERT_EQUAL_MESSAGE(
247 "Return value was not copied back to the command.",
248 InitSecContextMock::retVal,
251 CPPUNIT_ASSERT_EQUAL_MESSAGE(
252 "Status was not copied back to the command.",
253 InitSecContextMock::minor_status,
256 CPPUNIT_ASSERT_EQUAL_MESSAGE(
257 "context_handle was not copied back to the command.",
261 CPPUNIT_ASSERT_EQUAL_MESSAGE(
262 "context_handle was not copied back to the command.",
264 InitSecContextMock::context_handle
266 CPPUNIT_ASSERT_EQUAL_MESSAGE(
267 "actual_mech_type was not copied back to the command.",
268 InitSecContextMock::actual_mech_type,
269 cmd.getActualMechType().toGss()
271 CPPUNIT_ASSERT_EQUAL_MESSAGE(
272 "output_token was not copied back to the command.",
273 InitSecContextMock::output_token.value,
274 cmd.output_token.value
276 CPPUNIT_ASSERT_EQUAL_MESSAGE(
277 "ret_flags was not copied back to the command.",
278 InitSecContextMock::ret_flags,
281 CPPUNIT_ASSERT_EQUAL_MESSAGE(
282 "time_rec was not copied back to the command.",
283 InitSecContextMock::time_rec,
287 // Set this to no context, or cleanup attempts to free the not-a-real-pointer.
288 InitSecContextMock::context_handle = GSS_C_NO_CONTEXT;
292 /* Expected JSON output:
295 * "command": "gss_init_sec_context",
298 * "context_handle": "base64_encoded_string",
299 * "major_status": ##,
300 * "output_token": "http@project-moonshot.org/PROJECT-MOONSHOT.ORG",
301 * "actual_mech_type": "{ 1 3 6 1 5 5 13 4 }",
302 * "minor_status": ##,
309 void GSSCreateSecContextTest::testJSONMarshal()
312 GSSInitSecContext cmd ((void *)&mock_init_sec);
314 GSSContextCache *cache = GSSContextCache::instance();
316 gss_ctx_id_t expectedResult;
321 // Set expectations on what the GSS function will produce
322 InitSecContextMock::retVal = GSS_S_CONTINUE_NEEDED;
323 InitSecContextMock::minor_status = 0;
324 InitSecContextMock::context_handle = expectedResult = (gss_ctx_id_t)(long)rand();
325 InitSecContextMock::actual_mech_type = (gss_OID)GSS_C_MA_MECH_NEGO;
326 InitSecContextMock::output_token.value = (void *)"http@project-moonshot.org/PROJECT-MOONSHOT.ORG\0";
327 InitSecContextMock::output_token.length = strlen((char *)InitSecContextMock::output_token.value);
328 InitSecContextMock::ret_flags = GSS_C_MUTUAL_FLAG |
330 GSS_C_SEQUENCE_FLAG |
334 GSS_C_PROT_READY_FLAG;
335 InitSecContextMock::time_req = GSS_C_INDEFINITE;
339 result = cmd.toJSON();
341 std::cout << "create sec context json: " << result->dump() << "\n";*/
343 CPPUNIT_ASSERT_EQUAL_MESSAGE(
344 "The return value was reported incorrectly",
345 (int)InitSecContextMock::retVal,
346 (int)( (*result)["major_status"].integer() )
349 CPPUNIT_ASSERT_EQUAL_MESSAGE(
350 "The minor_status value was reported incorrectly",
351 (int)InitSecContextMock::minor_status,
352 (int)( (*result)["minor_status"].integer() )
355 CPPUNIT_ASSERT_MESSAGE(
356 "The actual_mech_type value was reported incorrectly",
357 ( strcmp("{ 1 3 6 1 5 5 13 4 }",
358 (*result)["actual_mech_type"].string() ) == 0 )
364 std::string str = (*result)["output_token"].string();
365 unsigned char *decoded = base64_decode(str, &len);
366 CPPUNIT_ASSERT_MESSAGE(
367 "The output_token value was reported incorrectly",
368 ( strcmp((const char *)(InitSecContextMock::output_token.value),
369 (const char *)decoded ) == 0 )
372 CPPUNIT_ASSERT_EQUAL_MESSAGE(
373 "The minor_status value was reported incorrectly",
374 (int)InitSecContextMock::ret_flags,
375 (int)( (*result)["ret_flags"].integer() )
378 CPPUNIT_ASSERT_EQUAL_MESSAGE(
379 "The minor_status value was reported incorrectly",
380 (int)InitSecContextMock::time_rec,
381 (int)( (*result)["time_rec"].integer() )
384 context = cache->retrieve( (*result)["context_handle"].string() );
386 CPPUNIT_ASSERT_EQUAL_MESSAGE(
387 "The returned context was reported incorrectly",
388 (long)expectedResult,
389 (long)context.getContext()