Whitespace change, remove debug printf.
[trust_router.git] / gsscon / gsscon_passive.c
index b94376e..1ede6d3 100755 (executable)
 
 const char *gServiceName = NULL;
 
-int gsscon_passive_authenticate (int           inSocket, 
-                         gss_ctx_id_t *outGSSContext)
+int gsscon_passive_authenticate (int               inSocket, 
+                                gss_buffer_desc    inNameBuffer,
+                                gss_ctx_id_t      *outGSSContext,
+                                client_cb_fn       clientCb,
+                                void              *clientCbData)
 {
     int err = 0;
     OM_uint32 majorStatus;
-    OM_uint32 minorStatus = 0;
+    OM_uint32 minorStatus = 0, minorStatusToo = 0;
     gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT;
-    
+    gss_name_t clientName = GSS_C_NO_NAME, serviceName = GSS_C_NO_NAME;
+    gss_cred_id_t acceptorCredentials = NULL;
+    gss_buffer_desc clientDisplayName = {0, NULL};
     char *inputTokenBuffer = NULL;
     size_t inputTokenBufferLength = 0;
     gss_buffer_desc inputToken;  /* buffer received from the server */
     
     if (inSocket <  0 ) { err = EINVAL; }
     if (!outGSSContext) { err = EINVAL; }
-    
+
+    if (!err) {
+      majorStatus = gss_import_name (&minorStatus, &inNameBuffer, (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &serviceName); 
+      if (majorStatus != GSS_S_COMPLETE) {
+       gsscon_print_gss_errors ("gss_import_name(serviceName)", majorStatus, minorStatus);
+       err = minorStatus ? minorStatus : majorStatus; 
+      }
+    }
+
+    if (!err) {
+      majorStatus = gss_acquire_cred ( &minorStatus, serviceName,
+                                      GSS_C_INDEFINITE, GSS_C_NO_OID_SET,
+                                      GSS_C_ACCEPT, &acceptorCredentials,
+                                      NULL /*mechs out*/, NULL /*time out*/);
+      if (majorStatus != GSS_S_COMPLETE) { 
+       gsscon_print_gss_errors ("gss_acquire_cred", majorStatus, minorStatus);
+       err = minorStatus ? minorStatus : majorStatus; 
+      }
+    }
+
     /* 
      * The main authentication loop:
      *
@@ -106,29 +130,14 @@ int gsscon_passive_authenticate (int           inSocket,
             
             /*
              * accept_sec_context does the actual work of taking the client's 
-             * request and generating an appropriate reply.  Note that we pass 
-             * GSS_C_NO_CREDENTIAL for the service principal.  This causes the 
-             * server to accept any service principal in the server's keytab, 
-             * which enables you to support multihomed hosts by having one key 
-             * in the keytab for each host identity the server responds on.  
-             *
-             * However, since we may have more keys in the keytab than we want 
-             * the server to actually use, we will need to check which service 
-             * principal the client used after authentication succeeds.  See 
-             * ServicePrincipalIsValidForService() for where you would put these 
-             * checks.  We don't check here since if we stopped responding in the 
-             * middle of the authentication negotiation, the client would get an 
-             * EOF, and the user wouldn't know what went wrong.
-             */
-            
-            printf ("Calling gss_accept_sec_context...\n");
+             * request and generating an appropriate reply.              */
             majorStatus = gss_accept_sec_context (&minorStatus, 
                                                   &gssContext, 
-                                                  GSS_C_NO_CREDENTIAL, 
+                                                 acceptorCredentials,
                                                   &inputToken, 
                                                   GSS_C_NO_CHANNEL_BINDINGS, 
-                                                  NULL /* client_name */, 
-                                                  NULL /* actual_mech_type */, 
+                                                  &clientName,
+                                                  NULL /* actual_mech_type */,
                                                   &outputToken, 
                                                   NULL /* req_flags */, 
                                                   NULL /* time_rec */, 
@@ -139,7 +148,7 @@ int gsscon_passive_authenticate (int           inSocket,
                 err = gsscon_write_token (inSocket, outputToken.value, outputToken.length);
                 
                 /* free the output token */
-                gss_release_buffer (&minorStatus, &outputToken);
+                gss_release_buffer (&minorStatusToo, &outputToken);
             }
         }
         
@@ -148,7 +157,17 @@ int gsscon_passive_authenticate (int           inSocket,
             err = minorStatus ? minorStatus : majorStatus; 
         }            
     }
-    
+
+    if (!err) {
+      majorStatus = gss_display_name(&minorStatus, clientName, &clientDisplayName, NULL);
+      if (GSS_ERROR(majorStatus)) {
+       gsscon_print_gss_errors("gss_display_name", majorStatus, minorStatus);
+       err = EINVAL;
+      }
+      if (!err)
+       err = clientCb(clientName, &clientDisplayName, clientCbData);
+    }
+
     if (!err) { 
         *outGSSContext = gssContext;
         gssContext = NULL;
@@ -159,47 +178,17 @@ int gsscon_passive_authenticate (int           inSocket,
     if (inputTokenBuffer) { free (inputTokenBuffer); }
     if (gssContext != GSS_C_NO_CONTEXT) { 
         gss_delete_sec_context (&minorStatus, &gssContext, GSS_C_NO_BUFFER); }
+if (clientName != GSS_C_NO_NAME)
+  gss_release_name(&minorStatus, &clientName);
+if (clientDisplayName.value != NULL)
+  gss_release_buffer(&minorStatus, &clientDisplayName);
+ gss_release_name( &minorStatus, &serviceName);
+ gss_release_cred( &minorStatus, &acceptorCredentials);
         
     return err;
 }
 
-/* --------------------------------------------------------------------------- */
-
-static int ServicePrincipalIsValidForService (const char *inServicePrincipal)
-{
-    int err = 0;
-    krb5_context context = NULL;
-    krb5_principal principal = NULL;
-    
-    if (!inServicePrincipal) { err = EINVAL; }
-    
-    if (!err) {
-        err = krb5_init_context (&context);
-    }
-    
-    if (!err) {
-        err = krb5_parse_name (context, inServicePrincipal, &principal);
-    }
     
-    if (!err) {
-        /* 
-         * Here is where we check to see if the service principal the client 
-         * used is valid.  Typically we would just check that the first component 
-         * is the name of the service provided by the server.  This check exists
-         * to make sure the server is using the correct key in its keytab since
-         * we passed GSS_C_NO_CREDENTIAL into gss_accept_sec_context().
-         */
-        if (gServiceName && strcmp (gServiceName, 
-                                    krb5_princ_name (context, principal)->data) != 0) {
-            err = KRB5KRB_AP_WRONG_PRINC;
-        }
-    }
-    
-    if (principal) { krb5_free_principal (context, principal); }
-    if (context  ) { krb5_free_context (context); }
-    
-    return err;
-}
 
 
 /* --------------------------------------------------------------------------- */
@@ -207,20 +196,6 @@ static int ServicePrincipalIsValidForService (const char *inServicePrincipal)
 static int ClientPrincipalIsAuthorizedForService (const char *inClientPrincipal)
 {
     int err = 0;
-    krb5_context context = NULL;
-    krb5_principal principal = NULL;
-    
-    if (!inClientPrincipal) { err = EINVAL; }
-    
-    if (!err) {
-        err = krb5_init_context (&context);
-    }
-    
-    if (!err) {
-        err = krb5_parse_name (context, inClientPrincipal, &principal);
-    }
-    
-    if (!err) {
         /* 
          * Here is where the server checks to see if the client principal should 
          * be allowed to use your service. Typically it should check both the name 
@@ -228,10 +203,8 @@ static int ClientPrincipalIsAuthorizedForService (const char *inClientPrincipal)
          * realm may be trying to contact your service.  
          */
         err = 0;
-    }
+
     
-    if (principal) { krb5_free_principal (context, principal); }
-    if (context  ) { krb5_free_context (context); }
     
     return err;
 }
@@ -291,44 +264,43 @@ int gsscon_authorize (gss_ctx_id_t  inContext,
         if (nameToken.value) { gss_release_buffer (&minorStatus, &nameToken); }
     }
     
-    if (!err) {
-        /* Pull the service principal string out of the gss name */
-        gss_buffer_desc nameToken;
-        
-        majorStatus = gss_display_name (&minorStatus, 
-                                        serviceName, 
-                                        &nameToken, 
-                                        NULL);
-        if (majorStatus != GSS_S_COMPLETE) { 
-            err = minorStatus ? minorStatus : majorStatus; 
-        }
-        
         if (!err) {
-            servicePrincipal = malloc (nameToken.length + 1);
-            if (servicePrincipal == NULL) { err = ENOMEM; }
-        }
-        
-        if (!err) {
-            memcpy (servicePrincipal, nameToken.value, nameToken.length);
-            servicePrincipal[nameToken.length] = '\0';
-        }        
+    //    /* Pull the service principal string out of the gss name */
+    //    gss_buffer_desc nameToken;
+    //    
+    //    majorStatus = gss_display_name (&minorStatus, 
+    //                                    serviceName, 
+    //                                    &nameToken, 
+    //                                    NULL);
+    //    if (majorStatus != GSS_S_COMPLETE) { 
+    //        err = minorStatus ? minorStatus : majorStatus; 
+    //    }
+    //    
+    //    if (!err) {
+    //        servic7ePrincipal = malloc (nameToken.length + 1);
+    //        if (servicePrincipal == NULL) { err = ENOMEM; }
+    //    }
+    //    
+    //    if (!err) {
+    //        memcpy (servicePrincipal, nameToken.value, nameToken.length);
+    //        servicePrincipal[nameToken.length] = '\0';
+    //    }        
 
-        if (nameToken.value) { gss_release_buffer (&minorStatus, &nameToken); }
-    }
+    //    if (nameToken.value) { gss_release_buffer (&minorStatus, &nameToken); }
+    // }
     
-    if (!err) {
-        int authorizationErr = ServicePrincipalIsValidForService (servicePrincipal);
+
+         int authorizationErr = 0;
+         authorizationErr = ClientPrincipalIsAuthorizedForService (clientPrincipal);
+
+
         
-        if (!authorizationErr) {
-            authorizationErr = ClientPrincipalIsAuthorizedForService (clientPrincipal);
+//        printf ("'%s' is%s authorized for service '%s'\n", 
+//                clientPrincipal, authorizationErr ? " NOT" : "", servicePrincipal);            
+//        
+         *outAuthorized = !authorizationErr;
+         *outAuthorizationError = authorizationErr;
         }
-        
-        printf ("'%s' is%s authorized for service '%s'\n", 
-                clientPrincipal, authorizationErr ? " NOT" : "", servicePrincipal);            
-        
-        *outAuthorized = !authorizationErr;
-        *outAuthorizationError = authorizationErr;
-    }
     
     if (serviceName     ) { gss_release_name (&minorStatus, &serviceName); }
     if (clientName      ) { gss_release_name (&minorStatus, &clientName); }