Rework the invalid argument for init sec context exception
authorMark Donnelly <mark@painless-security.com>
Fri, 31 Jul 2015 16:33:49 +0000 (12:33 -0400)
committerMark Donnelly <mark@painless-security.com>
Fri, 31 Jul 2015 16:33:49 +0000 (12:33 -0400)
* GSSException:
  * Separate out messages for major an minor error messages
  * Reduce the what() message
  * Change the flow so that major and minor messages are calculated at initialization time, so that everything else can be guaranteed not to throw any exceptions
* GSSRequest:
  * Standardize the formatting of the errors returned by a GSSException
* GSSInitSecContext
  * Throw GSSException instead of invalid_argument when the mech is unacceptable

json_gssapi/src/GSSException.cpp
json_gssapi/src/GSSException.h
json_gssapi/src/GSSRequest.cpp
json_gssapi/src/commands/GSSInitSecContext.cpp

index a799b69..8f8b645 100644 (file)
  */
 
 #include "GSSException.h"
  */
 
 #include "GSSException.h"
+#include "datamodel/GSSBuffer.h"
 #include <sstream>
 #include <sstream>
-#include <ios>
-#include <iostream>
+#include <string>
 
 
-static void disp_status(OM_uint32 status, int status_type, gss_OID mech, std::ostream &output_stream)
+static std::string disp_status(OM_uint32 status, int status_type, gss_OID mech)
 {
 {
+  /* Error checking */
+  /* Variables */
+  GSSBuffer disp_buf;
+  std::string disp_status;
+  
   OM_uint32 disp_major, disp_minor, disp_context;
   OM_uint32 disp_major, disp_minor, disp_context;
-  gss_buffer_desc disp_buf;
 
   disp_context = 0;
   do
 
   disp_context = 0;
   do
@@ -50,21 +54,14 @@ static void disp_status(OM_uint32 status, int status_type, gss_OID mech, std::os
                                    status_type,
                                    mech, 
                                    &disp_context, 
                                    status_type,
                                    mech, 
                                    &disp_context, 
-                                   &disp_buf);
+                                   disp_buf.toGss() );
     if (GSS_ERROR(disp_major))
     if (GSS_ERROR(disp_major))
-    {
-      disp_context = 0; // Get out of this loop.
-      output_stream << "    An error occurred, and then another error" << std::endl <<
-         "    occurred in creating a message to describe the first one. " << std::endl <<
-         "    How embarrassing. It's time to quit before it gets any worse." <<  std::endl <<
-         "    For now, the error code itself was 0x" << std::hex << status << std::dec;
-      std::cout << "\n     -------------------------\n    Something wonky happened in displaying status:\n";
-      std::cout << "     gss_display_status(&disp_minor, " << status << ", " << (int)status_type << ", " << (long int)mech << ", " << disp_context << ", &buf);\n";
-      disp_status(disp_major, GSS_C_GSS_CODE, mech, std::cout);
-      disp_status(disp_minor, GSS_C_MECH_CODE, mech, std::cout);
-    } else
-      output_stream << "    " << (char *)disp_buf.value << std::endl;
+      throw GSSException("An error occurred while dealing with another error.", disp_major, disp_minor, mech);
+    else
+      disp_status += disp_buf.toString();
   } while (disp_context != 0);
   } while (disp_context != 0);
+
+  return(disp_status);
 }
 
 GSSException::GSSException(std::string message, 
 }
 
 GSSException::GSSException(std::string message, 
@@ -75,23 +72,24 @@ GSSException::GSSException(std::string message,
   /* Error checking */
   
   /* Variables */
   /* Error checking */
   
   /* Variables */
-  std::stringstream output_stream;
   /* Setup */
   
   /* Main */
   this->major = major;
   this->minor = minor;
   /* Setup */
   
   /* Main */
   this->major = major;
   this->minor = minor;
-  
-  output_stream << message << std::endl;
-  output_stream << "GSS Error message:" << std::endl;
-  output_stream << "  Major status:" << std::endl;
-  disp_status(major, GSS_C_GSS_CODE, mech, output_stream);
-  output_stream << std::endl;
-  output_stream << "  Minor status details: " << std::endl;
-  disp_status(minor, GSS_C_MECH_CODE, mech, output_stream);
-  reason = output_stream.str();
-  
+  this->mech = mech;
+  this->message = message;
+
+  this->major_msg = disp_status(major, GSS_C_GSS_CODE, mech);
+  this->minor_msg = disp_status(minor, GSS_C_MECH_CODE, mech);
   
   /* Cleanup */
   /* Return */
 }
   
   /* Cleanup */
   /* Return */
 }
+
+const char* GSSException::what(void) const throw()
+{
+  /* Variables */
+  return(this->message.c_str());
+}
+
index 4335020..3f91fa8 100644 (file)
@@ -46,15 +46,19 @@ public:
     GSSException(std::string msg, OM_uint32 major = 0, OM_uint32 minor = 0 , gss_OID mech = GSS_C_NO_OID);
     ~GSSException(void) throw() {  }
       
     GSSException(std::string msg, OM_uint32 major = 0, OM_uint32 minor = 0 , gss_OID mech = GSS_C_NO_OID);
     ~GSSException(void) throw() {  }
       
-    virtual const char* what(void) const throw() { return reason.c_str(); }
+    const char* what(void) const throw();
     
     // Accessors
     OM_uint32 getMajor() { return(major); }
     OM_uint32 getMinor() { return(minor); }
     
     // Accessors
     OM_uint32 getMajor() { return(major); }
     OM_uint32 getMinor() { return(minor); }
+
+    std::string major_status_message() const throw() {return(major_msg);};
+    std::string minor_status_message() const throw() {return(minor_msg);};
     
 private:
     
 private:
-    std::string reason;
+    std::string reason, message, major_msg, minor_msg;
     OM_uint32 major, minor;
     OM_uint32 major, minor;
+    gss_OID mech;
 };
 
 #endif // GSSEXCEPTION_H
 };
 
 #endif // GSSEXCEPTION_H
index 38e6793..2de8b2e 100644 (file)
@@ -81,10 +81,13 @@ void GSSRequest::execute()
       cmd = NULL;
     }
 
       cmd = NULL;
     }
 
-    JSONObject return_values;
+    JSONObject return_values, errors;
+    errors.set("major_status_message", e.major_status_message().c_str());
+    errors.set("minor_status_message", e.minor_status_message().c_str());
+    errors.set("what", e.what());
+    return_values.set("errors", errors);
     return_values.set("major_status", e.getMajor());
     return_values.set("minor_status", e.getMinor());
     return_values.set("major_status", e.getMajor());
     return_values.set("minor_status", e.getMinor());
-    return_values.set("what", e.what());
     response.set("return_values", return_values);
   }
   catch (std::invalid_argument e)
     response.set("return_values", return_values);
   }
   catch (std::invalid_argument e)
index 8b71d81..bf1611f 100644 (file)
@@ -192,8 +192,7 @@ bool GSSInitSecContext::loadParameters(JSONObject *params)
     if (GSS_C_NO_OID == this->mechType.toGss() )
       throw std::invalid_argument( std::string() + "Could not create a mech_type OID from '" + key + "'");
     if ( !(this->mechType.isGssEapMech()) )
     if (GSS_C_NO_OID == this->mechType.toGss() )
       throw std::invalid_argument( std::string() + "Could not create a mech_type OID from '" + key + "'");
     if ( !(this->mechType.isGssEapMech()) )
-      throw std::invalid_argument( std::string() +
-                                  "'" + key + "' must be 1.3.6.1.5.5.15.1.1.*");
+      throw GSSException(string("'") + params->get("mech_type").string() + "' must be in 1.3.6.1.5.5.15.1.1.*", 65536, 0, this->mechType.toGss());
   }
   
   // req_flags
   }
   
   // req_flags