Add Janet copyright to GSS command files.
[gssweb.git] / json_gssapi / src / commands / GSSInitSecContext.cpp
1 /*
2  * Copyright (c) 2014, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 // MRW -- Add proper copyright boilerplate to all files
35
36 #include "GSSInitSecContext.h"
37 #include "GSSException.h"
38 #include <cache/GSSContextCache.h>
39 #include <cache/GSSNameCache.h>
40 #include <datamodel/GSSName.h>
41 #include <gssapi.h>
42 #include <stdexcept>
43 #include <stdlib.h>
44 #include <string.h>
45
46 typedef OM_uint32 (*init_sec_context)(
47     OM_uint32 *,        /* minor_status */
48     gss_cred_id_t,      /* claimant_cred_handle */
49     gss_ctx_id_t *,     /* context_handle */
50     gss_name_t,         /* target_name */
51     gss_OID,            /* mech_type (used to be const) */
52     OM_uint32,          /* req_flags */
53     OM_uint32,          /* time_req */
54     gss_channel_bindings_t,     /* input_chan_bindings */
55     gss_buffer_t,       /* input_token */
56     gss_OID *,          /* actual_mech_type */
57     gss_buffer_t,       /* output_token */
58     OM_uint32 *,        /* ret_flags */
59     OM_uint32 *         /* time_req */
60 );
61
62 void
63 GSSInitSecContext::execute()
64 {
65   /* Variables */
66   init_sec_context fn = (init_sec_context)function;
67   gss_OID actual_mech_type;
68   
69   /* Error checking */
70   
71   /* Setup */
72   if (output_token.length > 0)
73     retVal = gss_release_buffer(&minor_status, &output_token);
74
75   /* Main */
76   // MRW -- fix so that this uses all of the vars from the object 
77   retVal = fn(
78     &minor_status,
79     GSS_C_NO_CREDENTIAL,
80     &context_handle,
81     targetName.toGss(),
82     mechType.toGss(),
83     req_flags,
84     time_req,
85     GSS_C_NO_CHANNEL_BINDINGS,
86     &input_token,
87     &actual_mech_type,
88     &output_token,
89     &ret_flags,
90     &time_rec);
91   
92   if ( GSS_ERROR(this->retVal) )
93   {
94     // MRW -- steal code from import name
95     std::string errMsg;
96     errMsg += "Cannot init_sec_context: ";
97     throw GSSException(errMsg.c_str(), this->retVal, this->minor_status, mechType.toGss());
98   }
99   
100   actualMechType.setValue(actual_mech_type);
101   
102   context.setContext(context_handle, true);
103   contextKey = GSSContextCache::instance()->store(context);
104   
105   /* Cleanup */
106   
107   /* Return */
108 }
109
110 #if 0
111 const char* GSSInitSecContext::getTargetDisplayName()
112 {
113   /* Variables */
114   gss_buffer_desc output_name;
115   gss_OID output_type;
116   OM_uint32 major, minor;
117   const char *ret;
118   
119   /* error checking */
120   
121   /* Setup */
122   
123   /* Main */
124   major = gss_display_name(&minor, target_name, &output_name, &output_type);
125   if (major == GSS_S_COMPLETE)
126     ret = (const char *)output_name.value;
127   else
128     ret = NULL;
129   
130   /* cleanup */
131   
132   /* return */
133   return( ret );
134 }
135 #endif
136
137 bool GSSInitSecContext::loadParameters(JSONObject *params)
138 {
139   /* Variables */
140   std::string key;
141   
142   /* Error checking */
143   if ( params->isNull() )
144     return true;
145   
146   /* Setup */
147   
148   /* Main processing */
149   // MRW -- finish parsing all of the variables
150   // claimant_cred_handle
151
152   // context_handle
153   if ( ! params->get("context_handle").isNull() )
154   {
155     this->context_handle = GSS_C_NO_CONTEXT;
156     if (params->get("context_handle").isString())
157     {
158       key = params->get("context_handle").string();
159       context = GSSContextCache::instance()->retrieve( key.c_str() );
160       this->context_handle = context.getContext();
161     }
162     if (GSS_C_NO_CONTEXT == this->context_handle)
163       throw std::invalid_argument( "Could not find the context_handle." );
164   }
165   
166   // target_name
167   if ( ! params->get("target_name").isNull() )
168   {
169     this->target_name = GSS_C_NO_NAME;
170     if (params->get("target_name").isString())
171     {
172       key = params->get("target_name").string();
173       
174       targetName = GSSNameCache::instance()->retrieve(key);
175       
176       this->target_name = targetName.toGss();
177     }
178     if (GSS_C_NO_NAME == this->target_name)
179       throw std::invalid_argument( "Could not find the target_name" );
180   }
181   
182   // mech_type  
183   if ( ! params->get("mech_type").isNull() )
184   {
185     key.clear();
186     if (params->get("mech_type").isString())
187     {
188       key = params->get("mech_type").string();
189       mechType.setValue(key);
190     }
191     if (GSS_C_NO_OID == this->mechType.toGss() )
192       throw std::invalid_argument( std::string() + "Could not create a mech_type OID from '" + key + "'");
193   }
194   
195   // req_flags
196   if ( !params->get("req_flags").isNull() )
197     this->req_flags = params->get("req_flags").integer();
198
199   // time_req
200   if ( !params->get("time_req").isNull() )
201     this->time_req = params->get("time_req").integer();
202
203   // input_chennel_bindings
204
205   // input_token
206   if ( ! params->get("input_token").isNull() )
207   {
208     key = params->get("input_token").string();
209     this->input_token.value = (void *)key.c_str();
210     this->input_token.length = key.length();
211   }
212
213   /* Cleanup */
214   
215   /* Return */
216   return true;
217 }
218
219 bool GSSInitSecContext::zeroOut(bool initialized)
220 {
221   /* Error checking */
222   /* Variables */
223   OM_uint32 minor;
224   gss_buffer_desc output;
225   
226   /* Setup */
227   /* Main */
228
229   // Free up existing memory if it's been set.  
230   if (initialized)
231   {
232     if (this->context_handle != NULL)
233       gss_delete_sec_context(&minor, &(this->context_handle), &output);
234     
235     if (this->target_name != NULL)
236       gss_release_name(&minor, &(this->target_name));
237       
238     if (this->output_token.length > 0)
239       gss_release_buffer(&minor, &output_token);
240     
241     if (this->input_token.length > 0)
242       gss_release_buffer(&minor, &input_token);
243   }
244
245   // Now set things to reasonable defaults
246   this->retVal = 0;
247   this->minor_status = 0;
248   this->req_flags = 0;
249   this->time_req = 0;
250   this->ret_flags = 0;
251   this->time_rec = 0;
252
253   this->context_handle = GSS_C_NO_CONTEXT;
254   this->target_name = GSS_C_NO_NAME;
255   this->mechType.setValue( (char *)"{ 1 3 6 1 5 5 15 1 1 18 }" );
256   this->input_token.length = 0;
257   this->input_token.value = NULL;
258   this->output_token.length = 0;
259   this->output_token.value = NULL;
260
261   /* Cleanup */
262   /* Return */
263   return(true);
264 }
265
266 JSONObject *GSSInitSecContext::toJSON()
267 {
268   /* Variables */
269   // MRW -- values should be scoped to the class, so execute can set error values?
270   JSONObject *values = new JSONObject();
271   
272   /* Error checking */
273   
274   /* Setup */
275   
276   /* Main */
277   values->set("major_status", this->retVal);
278   values->set("minor_status", this->minor_status);
279   values->set("context_handle", this->contextKey.c_str());
280   values->set("actual_mech_type", this->getActualMechType().toString().c_str());
281   values->set("output_token", (const char *)this->output_token.value);
282   values->set("ret_flags", this->ret_flags);
283   values->set("time_rec", this->time_rec);
284   // MRW -- modify for new error handling
285
286   /* Cleanup */
287   
288   /* Return */
289   return(values);
290 }
291
292 GSSInitSecContext::GSSInitSecContext(
293   JSONObject *params, 
294   void *fn) : GSSCommand(params)
295 {
296   zeroOut(false);
297   loadParameters(params);
298   function = fn;
299 }
300
301 GSSInitSecContext::GSSInitSecContext(void *fn)
302 {
303   zeroOut(false);
304   function = fn;
305 }
306