GSS Acquire Cred calling out correctly; slight reorginzation
[gssweb.git] / json_gssapi / test / GSSCreateSecContextTest.cpp
1 /*
2  * Copyright (c) 2014 <copyright holder> <email>
3  * 
4  * For license details, see the LICENSE file in the root of this project.
5  * 
6  */
7
8
9 #include "GSSCreateSecContextTest.h"
10 #include "GSSCreateSecContextCommand.h"
11 #include "command_mocks/InitSecContextMock.h"
12 #include <iostream>
13 #include <string.h>
14 #include <exception>
15 #include "util_json.h"
16
17 // Registers the fixture into the 'registry'
18 CPPUNIT_TEST_SUITE_REGISTRATION( GSSCreateSecContextTest );
19
20
21
22 static OM_uint32 KRB5_CALLCONV
23 mock_init_sec(
24     OM_uint32             *minor_status,
25     gss_cred_id_t          claimant_cred_handle,
26     gss_ctx_id_t          *context_handle,
27     gss_name_t             target_name,
28     gss_OID                mech_type,
29     OM_uint32              req_flags,
30     OM_uint32              time_req,
31     gss_channel_bindings_t input_chan_bindings,
32     gss_buffer_t           input_token,
33     gss_OID               *actual_mech_type,
34     gss_buffer_t           output_token,
35     OM_uint32             *ret_flags,
36     OM_uint32             *time_rec)
37 {
38   InitSecContextMock::visited = true;
39   
40   /* Copy in the input to this function */
41   InitSecContextMock::claimant_cred_handle = claimant_cred_handle;
42   InitSecContextMock::target_name = target_name;
43   InitSecContextMock::mech_type = mech_type;
44   InitSecContextMock::req_flags = req_flags;
45   InitSecContextMock::time_req = time_req;
46   InitSecContextMock::input_chan_bindings = input_chan_bindings;
47   InitSecContextMock::input_token.length = input_token->length;
48   InitSecContextMock::input_token.value = input_token->value;
49   
50   
51   /* Copy out the output from this function */
52   *minor_status = InitSecContextMock::minor_status;
53   *actual_mech_type = InitSecContextMock::actual_mech_type;
54   output_token->length = InitSecContextMock::output_token.length;
55   output_token->value = InitSecContextMock::output_token.value;
56   *ret_flags = InitSecContextMock::ret_flags;
57   *time_rec = InitSecContextMock::time_rec;
58   
59   /* Handle the one that's I/O */
60     if (*context_handle == GSS_C_NO_CONTEXT)
61   {
62     *context_handle = InitSecContextMock::context_handle;
63   } else if (*context_handle != InitSecContextMock::context_handle)
64   {
65     InitSecContextMock::invalidContextHandle = true;
66   }
67
68   return InitSecContextMock::retVal;
69 }
70
71
72 void
73 GSSCreateSecContextTest::setUp()
74 {
75   InitSecContextMock::reset();
76 }
77
78 void
79 GSSCreateSecContextTest::tearDown()
80 {
81 }
82
83 void
84 GSSCreateSecContextTest::testConstructor()
85 {
86   GSSCreateSecContextCommand cmd = GSSCreateSecContextCommand();
87   void *cmdFn;
88   void *GSSFn;
89   
90   cmdFn = cmd.getGSSFunction();
91   GSSFn = (void *)&gss_init_sec_context;
92   CPPUNIT_ASSERT_MESSAGE("The default constructor for GSSCreateSecContextCommand should assign the function gss_init_sec_context", cmdFn == GSSFn);
93 }
94
95
96 void GSSCreateSecContextTest::testConstructorWithJSONObject()
97 {
98   const char* input = "{\"method\": \"gss_create_sec_context\", \
99     \"arguments\": {\"req_flags\": \"1\", \
100     \"time_req\": \"2\", \
101     \"mech_type\": \"{ 1 2 840 113554 1 2 1 4 }\", \
102     \"target_name\": \"me@my.sha/DOW\"}}";
103
104   json_error_t jsonErr;
105   JSONObject json = JSONObject::load(input, 0, &jsonErr);
106   
107   GSSCreateSecContextCommand cmd = GSSCreateSecContextCommand(
108     &json, 
109     (void *)&mock_init_sec
110   );
111   
112   
113   const char *from_json = json["arguments"]["target_name"].string();
114   const char *from_cmd = cmd.getTargetDisplayName();
115   
116   CPPUNIT_ASSERT_MESSAGE(
117     "The object does not have a target name.",
118     ( strcmp(from_json, from_cmd) == 0 )
119   );
120   
121   CPPUNIT_ASSERT_EQUAL_MESSAGE(
122     "The context_handle values differ.",
123     json["arguments"]["context_handle"].integer(),
124     (json_int_t)cmd.getContextHandle()
125   );
126   
127   CPPUNIT_ASSERT_MESSAGE(
128     "The mech_type values differ.",
129     ( strcmp(json["arguments"]["mech_type"].string(), cmd.getMechType()) == 0 )
130   );
131   
132   CPPUNIT_ASSERT_EQUAL_MESSAGE(
133     "The req_flags differ.",
134     (int)json["arguments"]["req_flags"].integer(),
135     (int)cmd.getReqFlags()
136   );
137   
138   CPPUNIT_ASSERT_EQUAL_MESSAGE(
139     "The req_flags differ.",
140     (int)json["arguments"]["time_req"].integer(),
141     (int)cmd.getTimeReq()
142   );
143   
144 }
145
146 void
147 GSSCreateSecContextTest::testEmptyCall()
148 {
149   GSSCreateSecContextCommand cmd ((void *)&mock_init_sec);
150   
151   /* Set expectations on what the GSS function will be called with */
152   cmd.time_req = rand() % 1024;
153   cmd.req_flags = rand() % 1024;
154   cmd.target_name = NULL;
155   cmd.context_handle = GSS_C_NO_CONTEXT;
156   
157   CPPUNIT_ASSERT_MESSAGE(
158     "The mech_type values differ.",
159     ( strcmp("{ 1 2 840 113554 1 2 1 4 }", cmd.getMechType()) == 0 )
160   );
161   
162   
163   
164   /* Set expectations on what the GSS function will produce */
165   InitSecContextMock::retVal = rand() % 1024;
166   InitSecContextMock::minor_status = rand() % 1024;
167   InitSecContextMock::context_handle = GSS_C_NO_CONTEXT;
168   InitSecContextMock::actual_mech_type = NULL;
169   InitSecContextMock::output_token.value = (void *)"http@project-moonshot.org/PROJECT-MOONSHOT.ORG\0";
170   InitSecContextMock::output_token.length = strlen((char *)InitSecContextMock::output_token.value);
171   InitSecContextMock::ret_flags = rand() % 1024;
172   InitSecContextMock::time_req = rand() % 1024;
173   
174   cmd.execute();
175   
176   /* Check that init_sec_context's inputs are sent correctly */
177   CPPUNIT_ASSERT_MESSAGE(
178     "The GSS function was not invoked!",
179     InitSecContextMock::visited
180   );
181   CPPUNIT_ASSERT_EQUAL_MESSAGE(
182     "The time_req field was not used in the call to init_sec_context",
183     cmd.time_req,
184     InitSecContextMock::time_req
185   );
186   CPPUNIT_ASSERT_EQUAL_MESSAGE(
187     "The req_flags field was not used in the call to init_sec_context",
188     cmd.req_flags,
189     InitSecContextMock::req_flags
190   );
191   CPPUNIT_ASSERT_EQUAL_MESSAGE(
192     "The mech_type field was not used in the call to init_sec_context",
193     cmd.mech_type,
194     InitSecContextMock::mech_type
195   );
196   CPPUNIT_ASSERT_EQUAL_MESSAGE(
197     "The target_name field was not used in the call to init_sec_context",
198     cmd.target_name,
199     InitSecContextMock::target_name
200   );
201   
202   
203   /* Check that init_sec_context's outputs are captured correctly */
204   CPPUNIT_ASSERT_EQUAL_MESSAGE(
205     "Return value was not copied back to the command.",
206     InitSecContextMock::retVal,
207     cmd.retVal
208   );
209   CPPUNIT_ASSERT_EQUAL_MESSAGE(
210     "Status was not copied back to the command.",
211     InitSecContextMock::minor_status,
212     cmd.minor_status
213   );
214   CPPUNIT_ASSERT_EQUAL_MESSAGE(
215     "context_handle was not copied back to the command.",
216     InitSecContextMock::context_handle,
217     cmd.context_handle
218   );
219   CPPUNIT_ASSERT_EQUAL_MESSAGE(
220     "actual_mech_type was not copied back to the command.",
221     InitSecContextMock::actual_mech_type,
222     cmd.actual_mech_type
223   );
224   CPPUNIT_ASSERT_EQUAL_MESSAGE(
225     "output_token was not copied back to the command.",
226     InitSecContextMock::output_token.value,
227     cmd.output_token.value
228   );
229   CPPUNIT_ASSERT_EQUAL_MESSAGE(
230     "ret_flags was not copied back to the command.",
231     InitSecContextMock::ret_flags,
232     cmd.ret_flags
233   );
234   CPPUNIT_ASSERT_EQUAL_MESSAGE(
235     "time_rec was not copied back to the command.",
236     InitSecContextMock::time_rec,
237     cmd.time_rec
238   );
239 }
240
241 void GSSCreateSecContextTest::testJSONMarshal()
242 {
243   /* Variables */
244   GSSCreateSecContextCommand cmd ((void *)&mock_init_sec);
245   JSONObject *result;
246   
247   /* Error checking */
248   
249   /* Setup */
250   // Set expectations on what the GSS function will produce
251   InitSecContextMock::retVal = GSS_S_BAD_MECH;
252   InitSecContextMock::minor_status = 20;
253   InitSecContextMock::context_handle = GSS_C_NO_CONTEXT;
254   InitSecContextMock::actual_mech_type = (gss_OID)GSS_C_MA_MECH_NEGO;
255   InitSecContextMock::output_token.value = (void *)"http@project-moonshot.org/PROJECT-MOONSHOT.ORG\0";
256   InitSecContextMock::output_token.length = strlen((char *)InitSecContextMock::output_token.value);
257   InitSecContextMock::ret_flags = GSS_C_MUTUAL_FLAG | 
258       GSS_C_REPLAY_FLAG | 
259       GSS_C_SEQUENCE_FLAG | 
260       GSS_C_CONF_FLAG | 
261       GSS_C_INTEG_FLAG | 
262       GSS_C_ANON_FLAG | 
263       GSS_C_PROT_READY_FLAG;
264   InitSecContextMock::time_req = GSS_C_INDEFINITE;
265   
266   /* Main */
267   cmd.execute();
268   result = cmd.toJSON();
269   
270   CPPUNIT_ASSERT_MESSAGE(
271     "The command name is incorrect",
272     ( strcmp("gss_init_sec_context", 
273              (*result)["command"].string() ) == 0 )
274   );
275   
276   
277   CPPUNIT_ASSERT_EQUAL_MESSAGE(
278     "The return value was reported incorrectly",
279     (int)InitSecContextMock::retVal,
280     (int)( (*result)["return_values"]["major_status"].integer() )
281   );
282   
283   CPPUNIT_ASSERT_EQUAL_MESSAGE(
284     "The minor_status value was reported incorrectly",
285     (int)InitSecContextMock::minor_status,
286     (int)( (*result)["return_values"]["minor_status"].integer() )
287   );
288   
289   CPPUNIT_ASSERT_MESSAGE(
290     "The actual_mech_type value was reported incorrectly",
291     ( strcmp("{ 1 3 6 1 5 5 13 4 }", 
292              (*result)["return_values"]["actual_mech_type"].string() ) == 0 )
293   );
294   
295   CPPUNIT_ASSERT_MESSAGE(
296     "The output_token value was reported incorrectly",
297     ( strcmp((const char *)(InitSecContextMock::output_token.value), 
298              (*result)["return_values"]["output_token"].string() ) == 0 )
299   );
300   
301   CPPUNIT_ASSERT_EQUAL_MESSAGE(
302     "The minor_status value was reported incorrectly",
303     (int)InitSecContextMock::ret_flags,
304     (int)( (*result)["return_values"]["ret_flags"].integer() )
305   );
306   
307   CPPUNIT_ASSERT_EQUAL_MESSAGE(
308     "The minor_status value was reported incorrectly",
309     (int)InitSecContextMock::time_rec,
310     (int)( (*result)["return_values"]["time_rec"].integer() )
311   );
312   
313   
314   /* Cleanup */
315   /* Return */
316 }
317
318