Continued development of AuthenticationToken Validation Service.
This commit is contained in:
		| @@ -157,6 +157,11 @@ IpcClientSubmitReq( | |||||||
| //                               pointer to the buffer containing the data | //                               pointer to the buffer containing the data | ||||||
| //                               received from the server. | //                               received from the server. | ||||||
| // | // | ||||||
|  | //                               The returned buffer always contains a NULL after the | ||||||
|  | //                               data indicated. You may be able to leverage this to | ||||||
|  | //                               treat the data as a NULL terminated string in cases | ||||||
|  | //                               where the request consists of ASCII characters. | ||||||
|  | // | ||||||
| //                pServerDataLen - Pointer to variable that will receive the | //                pServerDataLen - Pointer to variable that will receive the | ||||||
| //                                 length of the data received from the server. | //                                 length of the data received from the server. | ||||||
| // | // | ||||||
| @@ -165,7 +170,10 @@ IpcClientSubmitReq( | |||||||
| // | // | ||||||
| // Abstract:      Method to submit a request. | // Abstract:      Method to submit a request. | ||||||
| // | // | ||||||
| // Note: The routine blocks until the request completes. | // Notes:         The routine blocks until the request completes. | ||||||
|  | //  | ||||||
|  | //                The buffer returned with the server data must be released | ||||||
|  | //                by the calling application by calling free(). | ||||||
| // | // | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
|  |  | ||||||
|   | |||||||
| @@ -89,6 +89,11 @@ IpcServerGetRequestData( | |||||||
| // Notes:         The returned buffer SHOULD NOT be released by the calling | // Notes:         The returned buffer SHOULD NOT be released by the calling | ||||||
| //                application. | //                application. | ||||||
| //  | //  | ||||||
|  | //                The returned buffer always contains a NULL after the | ||||||
|  | //                data indicated. You may be able to leverage this to | ||||||
|  | //                treat the data as a NULL terminated string in cases | ||||||
|  | //                where the request consists of ASCII characters. | ||||||
|  | // | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ ROOT = ../../../.. | |||||||
|  |  | ||||||
| LIBDIR = $(ROOT)/$(LIB) | LIBDIR = $(ROOT)/$(LIB) | ||||||
| BINDIR = $(ROOT)/$(BIN) | BINDIR = $(ROOT)/$(BIN) | ||||||
|  | JAVA_LIBDIR = /usr/lib/jvm/java-1.5.0-sun-1.5.0_07/jre/lib/i386/server | ||||||
|  |  | ||||||
| # handle Mono secondary dependencies | # handle Mono secondary dependencies | ||||||
| export MONO_PATH := $(MONO_PATH) | export MONO_PATH := $(MONO_PATH) | ||||||
| @@ -56,8 +57,8 @@ RESOURCES = | |||||||
| DEFINES += -Wno-format-extra-args -fno-strict-aliasing -fshort-wchar  | DEFINES += -Wno-format-extra-args -fno-strict-aliasing -fshort-wchar  | ||||||
| CFLAGS += $(INCLUDES) $(DEFINES) | CFLAGS += $(INCLUDES) $(DEFINES) | ||||||
| CPPFLAGS += -fPIC $(INCLUDES) $(DEFINES) | CPPFLAGS += -fPIC $(INCLUDES) $(DEFINES) | ||||||
| LIBS = -lpthread -lcasa_s_ipc | LIBS = -lpthread -lcasa_s_ipc -ljvm | ||||||
| LDFLAGS = -L$(LIBDIR)/$(TARGET_CFG) | LDFLAGS = -L$(LIBDIR)/$(TARGET_CFG) -L$(JAVA_LIBDIR) | ||||||
|  |  | ||||||
| OBJDIR = ./$(TARGET_CFG)/$(LIB) | OBJDIR = ./$(TARGET_CFG)/$(LIB) | ||||||
| OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) $(addprefix $(OBJDIR)/, $(CPPFILES:%.cpp=%.o)) | OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) $(addprefix $(OBJDIR)/, $(CPPFILES:%.cpp=%.o)) | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ | |||||||
| //===[ Include files ]===================================================== | //===[ Include files ]===================================================== | ||||||
|  |  | ||||||
| #include "internal.h" | #include "internal.h" | ||||||
|  | #include <jni.h> | ||||||
|  |  | ||||||
| //===[ External data ]===================================================== | //===[ External data ]===================================================== | ||||||
|  |  | ||||||
| @@ -54,10 +55,12 @@ int   beginThreads = 5; | |||||||
| int   growThreads = 5; | int   growThreads = 5; | ||||||
| int   maxThreads = 4096; | int   maxThreads = 4096; | ||||||
| int   minWaitingThreads = beginThreads; | int   minWaitingThreads = beginThreads; | ||||||
|  | int   maxWaitingThreads = beginThreads * 4; | ||||||
|  |  | ||||||
| // Worker thread pool operating parameters | // Worker thread pool operating parameters | ||||||
| double   numThreads = 0; | double   numThreads = 0; | ||||||
| double   numBusyThreads = 0; | double   numBusyThreads = 0; | ||||||
|  | double   numPerishingThreads = 0; | ||||||
|  |  | ||||||
| // Listen Port Number | // Listen Port Number | ||||||
| int   listenPortNumber = 5000; | int   listenPortNumber = 5000; | ||||||
| @@ -85,6 +88,16 @@ pthread_cond_t    serverCondition; | |||||||
| // Operating parameters | // Operating parameters | ||||||
| bool  terminating = false; | bool  terminating = false; | ||||||
|  |  | ||||||
|  | // Java parameters | ||||||
|  | JavaVM   *g_jvm = NULL; | ||||||
|  | JNIEnv   *g_env = NULL; | ||||||
|  |  | ||||||
|  | // Java AuthenticationToken Class and method name | ||||||
|  | //char  authTokenClassName[] = "jtest"; | ||||||
|  | //char  authTokenClassValidateMethodName[] = "test4"; | ||||||
|  | char  authTokenClassName[] = "com.novell.casa.authtoksvc.AuthToken"; | ||||||
|  | char  authTokenClassValidateMethodName[] = "validate"; | ||||||
|  |  | ||||||
|  |  | ||||||
| //++======================================================================= | //++======================================================================= | ||||||
| void | void | ||||||
| @@ -188,12 +201,17 @@ WorkerThreadWaiting(void) | |||||||
|    // Acquire our mutex |    // Acquire our mutex | ||||||
|    pthread_mutex_lock(&serverMutex); |    pthread_mutex_lock(&serverMutex); | ||||||
|  |  | ||||||
|    // Decrement the numBusyThread count and determine if there are |    // Decrement the numBusyThread count | ||||||
|    // too many of us laying around. |  | ||||||
|    numBusyThreads --; |    numBusyThreads --; | ||||||
|    if ((numThreads - numBusyThreads) > minWaitingThreads |  | ||||||
|        && ((numBusyThreads + growThreads) / numThreads) < 0.33 ) |    // Check if we have too many idle workers | ||||||
|  |    if ((numThreads - numBusyThreads - numPerishingThreads) > maxWaitingThreads | ||||||
|  |        && numThreads > beginThreads) | ||||||
|  |    { | ||||||
|  |       // We want to let this worker perish | ||||||
|  |       numPerishingThreads ++; | ||||||
|       retValue = true; |       retValue = true; | ||||||
|  |    } | ||||||
|    else |    else | ||||||
|       retValue = false; |       retValue = false; | ||||||
|  |  | ||||||
| @@ -222,57 +240,137 @@ WorkerThread(void*) | |||||||
| // L0 | // L0 | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
| { | { | ||||||
|  |    bool  perishingThread = false; | ||||||
|  |  | ||||||
|    DbgTrace(1, "WorkerThread- Start\n", 0); |    DbgTrace(1, "WorkerThread- Start\n", 0); | ||||||
|  |  | ||||||
|    // Set the thread in the detached state so that it is cleaned up when it exits |    // Set the thread in the detached state so that it is cleaned up when it exits | ||||||
| 	pthread_detach(pthread_self()); | 	pthread_detach(pthread_self()); | ||||||
|  |  | ||||||
|    // Loop until told to terminate |    // Attach the thread to the JVM | ||||||
|    while (!terminating) |    JNIEnv *env; | ||||||
|  |    if (g_jvm->AttachCurrentThread((void**) &env, NULL) >= 0) | ||||||
|    { |    { | ||||||
|       // Get a request that needs servicing |       // We are now attached to the JVM, find the helper class that | ||||||
|       int32_t requestId = IpcServerGetRequest(); |       // we need. | ||||||
|       if (requestId != 0) |       jclass helperClass = env->FindClass(authTokenClassName); | ||||||
|  |       if (helperClass) | ||||||
|       { |       { | ||||||
|          // We got a request that needs servicing, now get the |          // Helper class found, now get the id of the method that we invoke | ||||||
|          // data associated with it. |          jmethodID mId = env->GetStaticMethodID(helperClass, | ||||||
|          char *pReqData; |                                                 authTokenClassValidateMethodName, | ||||||
|          int dataLen = IpcServerGetRequestData(requestId, &pReqData); |                                                 "(Ljava/lang/String;)Ljava/lang/String;"); | ||||||
|          if (dataLen != 0) |          if (mId) | ||||||
|          { |          { | ||||||
|             // Indicate that we are now busy |             // Loop until told to terminate | ||||||
|             WorkerThreadBusy(); |             while (!terminating) | ||||||
|  |  | ||||||
|             // Just echo the data back as the reply |  | ||||||
|             IpcServerCompleteRequest(requestId, pReqData); |  | ||||||
|  |  | ||||||
|             // Indicate that we are no longer busy and get indication of |  | ||||||
|             // whether or not we should continue to try to process requests. |  | ||||||
|             if (WorkerThreadWaiting() == true) |  | ||||||
|             { |             { | ||||||
|                DbgTrace(1, "WorkerThread- Requested to terminate\n", 0); |                // Get a request that needs servicing | ||||||
|                break; |                int32_t requestId = IpcServerGetRequest(); | ||||||
|  |                if (requestId != 0) | ||||||
|  |                { | ||||||
|  |                   // We got a request that needs servicing, now get the | ||||||
|  |                   // data associated with it. | ||||||
|  |                   char *pReqData; | ||||||
|  |                   int dataLen = IpcServerGetRequestData(requestId, &pReqData); | ||||||
|  |                   if (dataLen != 0) | ||||||
|  |                   { | ||||||
|  |                      // Indicate that we are now busy | ||||||
|  |                      WorkerThreadBusy(); | ||||||
|  |  | ||||||
|  |                      // Lets push the jvm local frame to allow us to clean up our local | ||||||
|  |                      // references later. | ||||||
|  |                      env->PushLocalFrame(10); | ||||||
|  |  | ||||||
|  |                      jstring inString = env->NewStringUTF(pReqData); | ||||||
|  |                      if (inString) | ||||||
|  |                      { | ||||||
|  |                         // Invoke our helper method | ||||||
|  |                         jstring outString = (jstring) env->CallStaticObjectMethod(helperClass, mId, inString); | ||||||
|  |                         if (outString) | ||||||
|  |                         { | ||||||
|  |                            // The helper method succeded, complete the request. | ||||||
|  |                            const char *pOutChars = env->GetStringUTFChars(outString, NULL); | ||||||
|  |                            if (pOutChars) | ||||||
|  |                            { | ||||||
|  |                               IpcServerCompleteRequest(requestId, (char*) pOutChars); | ||||||
|  |                               env->ReleaseStringUTFChars(outString, pOutChars); | ||||||
|  |                            } | ||||||
|  |                            else | ||||||
|  |                            { | ||||||
|  |                               DbgTrace(0, "WorkerThread- Unable to get UTF characters\n", 0); | ||||||
|  |                               IpcServerAbortRequest(requestId); | ||||||
|  |                            } | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                            // The helper method failed, just abort the request. | ||||||
|  |                            IpcServerAbortRequest(requestId); | ||||||
|  |                         } | ||||||
|  |                      } | ||||||
|  |                      else | ||||||
|  |                      { | ||||||
|  |                         DbgTrace(0, "WorkerThread- UTF String allocation failure\n", 0); | ||||||
|  |                         IpcServerAbortRequest(requestId); | ||||||
|  |                      } | ||||||
|  |  | ||||||
|  |                      // Pop the jvm local frame to clean up our local references | ||||||
|  |                      env->PopLocalFrame(NULL); | ||||||
|  |  | ||||||
|  |                      // Indicate that we are no longer busy and get indication of | ||||||
|  |                      // whether or not we should continue to try to process requests. | ||||||
|  |                      if (WorkerThreadWaiting() == true) | ||||||
|  |                      { | ||||||
|  |                         DbgTrace(1, "WorkerThread- Requested to terminate\n", 0); | ||||||
|  |  | ||||||
|  |                         // Remember that we are a perishing thread so that we can reduce the | ||||||
|  |                         // count as we exit. | ||||||
|  |                         perishingThread = true; | ||||||
|  |                         break; | ||||||
|  |                      } | ||||||
|  |                   } | ||||||
|  |                   else | ||||||
|  |                   { | ||||||
|  |                      DbgTrace(0, "WorkerThread- Error obtaining Request data\n", 0); | ||||||
|  |                      IpcServerAbortRequest(requestId); | ||||||
|  |                   } | ||||||
|  |                } | ||||||
|  |                else | ||||||
|  |                { | ||||||
|  |                   // No need to service requests any longer | ||||||
|  |                   break; | ||||||
|  |                } | ||||||
|             } |             } | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|          { |          { | ||||||
|             DbgTrace(0, "WorkerThread- Error obtaining Request data\n", 0); |             DbgTrace(0, "WorkerThread- Failed to get method id\n", 0); | ||||||
|             IpcServerAbortRequest(requestId); |  | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // No need to service requests any longer |          DbgTrace(0, "WorkerThread- Failed to find helper class\n", 0); | ||||||
|          break; |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       // Detach from the JVM | ||||||
|  |       g_jvm->DetachCurrentThread(); | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       DbgTrace(0, "WorkerThread- Failed to attach to JVM\n", 0); | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    // Decrement the number of worker threads and signal our main thread |    // Decrement the number of worker threads and signal our main thread | ||||||
|    // to terminate itself if we are the last worker thread. |    // to terminate itself if we are the last worker thread. | ||||||
|    pthread_mutex_lock(&serverMutex); |    pthread_mutex_lock(&serverMutex); | ||||||
|  |  | ||||||
|  |    if (perishingThread) | ||||||
|  |       numPerishingThreads --; | ||||||
|  |  | ||||||
|    numThreads --; |    numThreads --; | ||||||
|    if (numThreads == 0) |    if (numThreads == 0) | ||||||
|       pthread_cond_signal(&serverCondition); |       pthread_cond_signal(&serverCondition); | ||||||
|  |  | ||||||
|    pthread_mutex_unlock(&serverMutex); |    pthread_mutex_unlock(&serverMutex); | ||||||
|  |  | ||||||
|    DbgTrace(1, "WorkerThread- End\n", 0); |    DbgTrace(1, "WorkerThread- End\n", 0); | ||||||
| @@ -314,6 +412,78 @@ SigTermHandler( | |||||||
| }  /*-- SigTermHandler() --*/ | }  /*-- SigTermHandler() --*/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | int | ||||||
|  | InitJavaInvoke(void) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L0 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    int   retStatus = -1; | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "InitJavaInvoke- Start\n", 0); | ||||||
|  |  | ||||||
|  |    //JavaVMOption options[1]; | ||||||
|  |    //options[0].optionString = "-Djava.class.path=."; | ||||||
|  |    JavaVMOption options[1]; | ||||||
|  |    options[0].optionString = "-Djava.class.path=/usr/share/java:/etc/CASA/authtoken"; | ||||||
|  |    JavaVMInitArgs vm_args; | ||||||
|  |    vm_args.version = JNI_VERSION_1_4; | ||||||
|  |    vm_args.options = options; | ||||||
|  |    vm_args.nOptions = 1; | ||||||
|  |    vm_args.ignoreUnrecognized = true; | ||||||
|  |    if (JNI_CreateJavaVM(&g_jvm, (void**)&g_env, &vm_args) >= 0) | ||||||
|  |    { | ||||||
|  |       // Success | ||||||
|  |       retStatus = 0; | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       DbgTrace(0, "InitJavaInvoke- Error creating Java VM\n", 0); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "InitJavaInvoke- End, retStatus = %08X\n", retStatus); | ||||||
|  |  | ||||||
|  |    return retStatus; | ||||||
|  |  | ||||||
|  | }  /*-- InitJavaInvoke() --*/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //++======================================================================= | ||||||
|  | void | ||||||
|  | UnInitJavaInvoke(void) | ||||||
|  | // | ||||||
|  | //  Arguments:  | ||||||
|  | // | ||||||
|  | //  Returns:    | ||||||
|  | // | ||||||
|  | //  Abstract:   | ||||||
|  | // | ||||||
|  | //  Notes: | ||||||
|  | // | ||||||
|  | // L0 | ||||||
|  | //=======================================================================-- | ||||||
|  | { | ||||||
|  |    DbgTrace(1, "UnInitJavaInvoke- Start\n", 0); | ||||||
|  |  | ||||||
|  |    // Destroy the jvm | ||||||
|  |    g_jvm->DestroyJavaVM(); | ||||||
|  |    g_jvm = NULL; | ||||||
|  |    g_env = NULL; | ||||||
|  |  | ||||||
|  |    DbgTrace(1, "UnInitJavaInvoke- End\n", 0); | ||||||
|  |  | ||||||
|  | }  /*-- UnInitJavaInvoke() --*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| //++======================================================================= | //++======================================================================= | ||||||
| void | void | ||||||
| DaemonInit( | DaemonInit( | ||||||
| @@ -572,53 +742,65 @@ main( | |||||||
|       pthread_mutex_init(&interlockedMutex, NULL); |       pthread_mutex_init(&interlockedMutex, NULL); | ||||||
|       pthread_mutex_init(&serverMutex, NULL); |       pthread_mutex_init(&serverMutex, NULL); | ||||||
|  |  | ||||||
|       // Initialize the condition that we will use to wait |       // Initialize the JVM | ||||||
|       // for the exit of all of our worker threads. |       if (InitJavaInvoke() == 0) | ||||||
|       if (pthread_cond_init(&serverCondition, NULL) == 0) |  | ||||||
|       { |       { | ||||||
|          // Initialize the IPC Server |          // Initialize the condition that we will use to wait | ||||||
|          if (IpcServerInit(appName, |          // for the exit of all of our worker threads. | ||||||
|                            DebugLevel, |          if (pthread_cond_init(&serverCondition, NULL) == 0) | ||||||
|                            UseSyslog) == 0) |  | ||||||
|          { |          { | ||||||
|             // Now setup the appropriate listen address |             // Initialize the IPC Server | ||||||
|             int setAddressResult; |             if (IpcServerInit(appName, | ||||||
|             if (listenPortNumber == 0) |                               DebugLevel, | ||||||
|                setAddressResult = IpcServerSetUnAddress(DOMAIN_SOCKET_FILE_NAME); |                               UseSyslog) == 0) | ||||||
|             else |  | ||||||
|                setAddressResult = IpcServerSetInAddress(listenPortNumber); |  | ||||||
|  |  | ||||||
|             if (setAddressResult == 0) |  | ||||||
|             { |             { | ||||||
|                // Now start the IPC server |                // Now setup the appropriate listen address | ||||||
|                if (IpcServerStart() == 0) |                int setAddressResult; | ||||||
|  |                if (listenPortNumber == 0) | ||||||
|  |                   setAddressResult = IpcServerSetUnAddress(DOMAIN_SOCKET_FILE_NAME); | ||||||
|  |                else | ||||||
|  |                   setAddressResult = IpcServerSetInAddress(listenPortNumber); | ||||||
|  |  | ||||||
|  |                if (setAddressResult == 0) | ||||||
|                { |                { | ||||||
|                   // Acquire our mutex |                   // Now start the IPC server | ||||||
|                   pthread_mutex_lock(&serverMutex); |                   if (IpcServerStart() == 0) | ||||||
|  |                   { | ||||||
|  |                      // Acquire our mutex | ||||||
|  |                      pthread_mutex_lock(&serverMutex); | ||||||
|  |  | ||||||
|                   // Start worker threads |                      // Start worker threads | ||||||
|                   GrowWorkerThreadPool(beginThreads); |                      GrowWorkerThreadPool(beginThreads); | ||||||
|  |  | ||||||
|                   // Wait for the worker threads to terminate |                      // Wait for the worker threads to terminate | ||||||
|                   pthread_cond_wait(&serverCondition, &serverMutex); |                      pthread_cond_wait(&serverCondition, &serverMutex); | ||||||
|  |  | ||||||
|                   // Release our mutex |                      // Release our mutex | ||||||
|                   pthread_mutex_unlock(&serverMutex); |                      pthread_mutex_unlock(&serverMutex); | ||||||
|  |  | ||||||
|  |                      DbgTrace(0, "main- Exiting, numThreads = %d\n", numThreads); | ||||||
|  |                   } | ||||||
|  |                } | ||||||
|  |                else | ||||||
|  |                { | ||||||
|  |                   DbgTrace(0, "main- Setting of listen address failed\n", 0); | ||||||
|                } |                } | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                DbgTrace(0, "main- Setting of listen address failed\n", 0); |                DbgTrace(0, "main- Initialization of Ipc server failed\n", 0); | ||||||
|             } |             } | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|          { |          { | ||||||
|             DbgTrace(0, "main- Initialization of Ipc server failed\n", 0); |             DbgTrace(0, "main- Condition initialization failed\n", 0); | ||||||
|          } |          } | ||||||
|  |          // Un-initialize JVM | ||||||
|  |          UnInitJavaInvoke(); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          DbgTrace(0, "main- Condition initialization failed\n", 0); |          DbgTrace(0, "main- JVM initialization failed\n", 0); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|    else |    else | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ | |||||||
| #include <micasa_types.h> | #include <micasa_types.h> | ||||||
| #include <casa_status.h> | #include <casa_status.h> | ||||||
| #include <casa_s_authtoken.h> | #include <casa_s_authtoken.h> | ||||||
|  | #include <casa_c_ipc.h> | ||||||
| #include "proto.h" | #include "proto.h" | ||||||
| #include "list_entry.h" | #include "list_entry.h" | ||||||
| #include "config_if.h" | #include "config_if.h" | ||||||
|   | |||||||
| @@ -46,7 +46,6 @@ MODULE_NAME = libcasa_s_authtoken | |||||||
| MODULE_EXT = so | MODULE_EXT = so | ||||||
|  |  | ||||||
| CFILES = ../config.c \ | CFILES = ../config.c \ | ||||||
| 	 ../authtoken.c \ |  | ||||||
| 	 ../principal.c \ | 	 ../principal.c \ | ||||||
| 	 ../util.c \ | 	 ../util.c \ | ||||||
| 	 ../validate.c \ | 	 ../validate.c \ | ||||||
| @@ -58,8 +57,8 @@ INCLUDES = -I. -I.. -I$(CASAINCLUDE) -I../../../include | |||||||
| RESOURCES = | RESOURCES = | ||||||
| DEFINES = -Wno-format-extra-args -fno-strict-aliasing  | DEFINES = -Wno-format-extra-args -fno-strict-aliasing  | ||||||
| CFLAGS += $(INCLUDES) $(DEFINES) | CFLAGS += $(INCLUDES) $(DEFINES) | ||||||
| LIBS = -lpthread -ldl -lexpat | LIBS = -lpthread -ldl -lexpat -lcasa_c_ipc | ||||||
| LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) | LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(ROOT)/lib/$(TARGET_CFG) | ||||||
|  |  | ||||||
| OBJDIR = ./$(TARGET_CFG)/$(LIB) | OBJDIR = ./$(TARGET_CFG)/$(LIB) | ||||||
| OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) | OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) | ||||||
|   | |||||||
| @@ -41,6 +41,10 @@ int   DebugLevel = 0; | |||||||
| static | static | ||||||
| bool  g_moduleInitialized = false; | bool  g_moduleInitialized = false; | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // IPC Client Sub-system variables | ||||||
|  | //  | ||||||
|  | uint32_t atvsEndPointHandle;  // Authentication Token Validation Service endpoint handle | ||||||
|  |  | ||||||
| //++======================================================================= | //++======================================================================= | ||||||
| CasaStatus SSCS_CALL | CasaStatus SSCS_CALL | ||||||
| @@ -126,8 +130,37 @@ ValidateAuthToken( | |||||||
|                retStatus = IdenTokenInit(); |                retStatus = IdenTokenInit(); | ||||||
|                if (CASA_SUCCESS(retStatus)) |                if (CASA_SUCCESS(retStatus)) | ||||||
|                { |                { | ||||||
|                   // Success |                   // Initialize the Client Ipc Subsystem | ||||||
|                   g_moduleInitialized = true; |                   if (IpcClientInit("CASA_AuthTokenValidate", | ||||||
|  |                                     true, | ||||||
|  |                                     DebugLevel, | ||||||
|  |                                     false) == 0) | ||||||
|  |                   { | ||||||
|  |                      // Open endpoint for the Authentication Token Validation Service | ||||||
|  |                      if (IpcClientOpenInetRemoteEndPoint(5000, | ||||||
|  |                                                          0x7F000001, | ||||||
|  |                                                          0, | ||||||
|  |                                                          &atvsEndPointHandle) == 0) | ||||||
|  |                      { | ||||||
|  |                         // Success | ||||||
|  |                         g_moduleInitialized = true; | ||||||
|  |                      } | ||||||
|  |                      else | ||||||
|  |                      { | ||||||
|  |                         DbgTrace(0, "-ValidateAuthToken- Failed to open remote endpoint\n", 0); | ||||||
|  |                         IpcClientShutdown(); | ||||||
|  |                         IdenTokenUninit(); | ||||||
|  |                         PrincipalIfUninit(); | ||||||
|  |                         ConfigIfUninit(); | ||||||
|  |                      } | ||||||
|  |                   } | ||||||
|  |                   else | ||||||
|  |                   { | ||||||
|  |                      DbgTrace(0, "-ValidateAuthToken- Ipc subsystem initialization failed\n", 0); | ||||||
|  |                      IdenTokenUninit(); | ||||||
|  |                      PrincipalIfUninit(); | ||||||
|  |                      ConfigIfUninit(); | ||||||
|  |                   } | ||||||
|                } |                } | ||||||
|                else |                else | ||||||
|                { |                { | ||||||
| @@ -157,71 +190,87 @@ ValidateAuthToken( | |||||||
|                           &decodedTokenBufLen); |                           &decodedTokenBufLen); | ||||||
|    if (CASA_SUCCESS(retStatus)) |    if (CASA_SUCCESS(retStatus)) | ||||||
|    { |    { | ||||||
|       AuthToken *pAuthToken; |       char *pIdenTokenData; | ||||||
|  |       int idenTokenDataLen; | ||||||
|  |  | ||||||
|       // Token was decoded successfully, now create an authentication token object with it. |       // Token was decoded successfully, now submit the authentication token to the | ||||||
|       retStatus = CreateAuthToken(pDecodedTokenBuf, decodedTokenBufLen, &pAuthToken); |       // authentication token validation service. | ||||||
|       if (CASA_SUCCESS(retStatus)) |       if (IpcClientSubmitReq(atvsEndPointHandle, | ||||||
|  |                              pDecodedTokenBuf, | ||||||
|  |                              decodedTokenBufLen, | ||||||
|  |                              &pIdenTokenData, | ||||||
|  |                              &idenTokenDataLen) == 0) | ||||||
|       { |       { | ||||||
|          // Now check the validity of the token |          // The submit succeeded, make sure that we got some identity data back. | ||||||
|          retStatus = CheckAuthToken(pAuthToken, pServiceName); |          if (pIdenTokenData) | ||||||
|          if (CASA_SUCCESS(retStatus)) |  | ||||||
|          { |          { | ||||||
|             IdenTokenProviderIf  *pIdenTokenProviderIf; |             if (idenTokenDataLen != 0) | ||||||
|  |  | ||||||
|             // The token was validated, now |  | ||||||
|             // Obtain Identity Token Provider interface |  | ||||||
|             retStatus = GetIdenTokenProviderInterface(pAuthToken->pIdenTokenType, |  | ||||||
|                                                       &pIdenTokenProviderIf); |  | ||||||
|             if (CASA_SUCCESS(retStatus)) |  | ||||||
|             { |             { | ||||||
|                IdenTokenIf *pIdenTokenIf; |                IdenTokenProviderIf  *pIdenTokenProviderIf; | ||||||
|  |  | ||||||
|                // Use the Identity Token Provider to get an Identity Token Interface instance |                // The authentication token was validated, now obtain | ||||||
|                retStatus = pIdenTokenProviderIf->getIdentityTokenIf(pIdenTokenProviderIf, |                // Identity Token Provider interface. | ||||||
|                                                                     pAuthToken->pIdenToken, |                retStatus = GetIdenTokenProviderInterface("CasaIdentityToken",    // tbd - Hard code until we enhance the protocol with the atvs to also return this information. | ||||||
|                                                                     pAuthToken->idenTokenLen, |                                                          &pIdenTokenProviderIf); | ||||||
|                                                                     &pIdenTokenIf); |  | ||||||
|                if (CASA_SUCCESS(retStatus)) |                if (CASA_SUCCESS(retStatus)) | ||||||
|                { |                { | ||||||
|                   // Now create a principal interface instance with the identity information present in |                   IdenTokenIf *pIdenTokenIf; | ||||||
|                   // the identity token. |  | ||||||
|                   retStatus = GetPrincipalInterface(pIdenTokenIf, &pPrincipalIf); |                   // Use the Identity Token Provider to get an Identity Token Interface instance | ||||||
|  |                   retStatus = pIdenTokenProviderIf->getIdentityTokenIf(pIdenTokenProviderIf, | ||||||
|  |                                                                        pIdenTokenData, | ||||||
|  |                                                                        idenTokenDataLen, | ||||||
|  |                                                                        &pIdenTokenIf); | ||||||
|                   if (CASA_SUCCESS(retStatus)) |                   if (CASA_SUCCESS(retStatus)) | ||||||
|                   { |                   { | ||||||
|                      // Success, return the principal interface to the caller. |                      // Now create a principal interface instance with the identity information present in | ||||||
|                      *ppPrincipalIf = pPrincipalIf; |                      // the identity token. | ||||||
|  |                      retStatus = GetPrincipalInterface(pIdenTokenIf, &pPrincipalIf); | ||||||
|  |                      if (CASA_SUCCESS(retStatus)) | ||||||
|  |                      { | ||||||
|  |                         // Success, return the principal interface to the caller. | ||||||
|  |                         *ppPrincipalIf = pPrincipalIf; | ||||||
|  |                      } | ||||||
|  |                      else | ||||||
|  |                      { | ||||||
|  |                         DbgTrace(0, "-ValidateAuthToken- Failed to instantiate principal interface\n", 0); | ||||||
|  |                      } | ||||||
|  |  | ||||||
|  |                      // Release identity token interface | ||||||
|  |                      pIdenTokenIf->releaseReference(pIdenTokenIf); | ||||||
|                   } |                   } | ||||||
|                   else |                   else | ||||||
|                   { |                   { | ||||||
|                      DbgTrace(0, "-ValidateAuthToken- Failed to instantiate principal interface\n", 0); |                      DbgTrace(0, "-ValidateAuthToken- Failed to instantiate identity token\n", 0); | ||||||
|                   } |                   } | ||||||
|  |  | ||||||
|                   // Release identity token interface |                   // Release identity token provider interface | ||||||
|                   pIdenTokenIf->releaseReference(pIdenTokenIf); |                   pIdenTokenProviderIf->releaseReference(pIdenTokenProviderIf); | ||||||
|                } |                } | ||||||
|                else |                else | ||||||
|                { |                { | ||||||
|                   DbgTrace(0, "-ValidateAuthToken- Failed to instantiate identity token\n", 0); |                   DbgTrace(0, "-ValidateAuthToken- Failed to obtain identity token provider interface\n", 0); | ||||||
|                } |                } | ||||||
|  |  | ||||||
|                // Release identity token provider interface |  | ||||||
|                pIdenTokenProviderIf->releaseReference(pIdenTokenProviderIf); |  | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                DbgTrace(0, "-ValidateAuthToken- Failed to obtain identity token provider interface\n", 0); |                DbgTrace(0, "-ValidateAuthToken- ValidateAuthToken submit did not return identity token data\n", 0); | ||||||
|             } |             } | ||||||
|          } |  | ||||||
|  |  | ||||||
|          // Free the AuthToken object |             // Free the buffer containing the identity token data | ||||||
|          RelAuthToken(pAuthToken); |             free(pIdenTokenData); | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             DbgTrace(0, "-ValidateAuthToken- ValidateAuthToken submit did not return identity token data buffer\n", 0); | ||||||
|  |          } | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          DbgTrace(0, "-ValidateAuthToken- Failed to create authentication token object\n", 0); |          DbgTrace(1, "-ValidateAuthToken- ValidateAuthToken submit failed\n", 0); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |  | ||||||
|       // Free the decoded token buffer |       // Free the decoded token buffer | ||||||
|       free(pDecodedTokenBuf); |       free(pDecodedTokenBuf); | ||||||
|    } |    } | ||||||
|   | |||||||
| @@ -447,10 +447,12 @@ CChannel::connectionThread( | |||||||
|  |  | ||||||
|                         DbgTrace(2, "CChannel::connectionThread- Processing Request Data Packet, Obj = %08X\n", pCChannel); |                         DbgTrace(2, "CChannel::connectionThread- Processing Request Data Packet, Obj = %08X\n", pCChannel); | ||||||
|  |  | ||||||
|                         // Allocate a buffer big enough to receive the payload |                         // Allocate a buffer big enough to receive the payload. Allow space to NULL terminate. | ||||||
|                         pRecvBuff = (char*) malloc(payloadLength); |                         pRecvBuff = (char*) malloc(payloadLength + 1); | ||||||
|                         if (pRecvBuff != NULL) |                         if (pRecvBuff != NULL) | ||||||
|                         { |                         { | ||||||
|  |                            pRecvBuff[payloadLength] = '\0'; | ||||||
|  |  | ||||||
|                            // Buffer allocated, receive the request payload. |                            // Buffer allocated, receive the request payload. | ||||||
|                            while (1) |                            while (1) | ||||||
|                            { |                            { | ||||||
|   | |||||||
| @@ -380,6 +380,11 @@ IpcClientSubmitReq( | |||||||
| //                               pointer to the buffer containing the data | //                               pointer to the buffer containing the data | ||||||
| //                               received from the server. | //                               received from the server. | ||||||
| // | // | ||||||
|  | //                               The returned buffer always contains a NULL after the | ||||||
|  | //                               data indicated. You may be able to leverage this to | ||||||
|  | //                               treat the data as a NULL terminated string in cases | ||||||
|  | //                               where the request consists of ASCII characters. | ||||||
|  | //  | ||||||
| //                pServerDataLen - Pointer to variable that will receive the | //                pServerDataLen - Pointer to variable that will receive the | ||||||
| //                                 length of the data received from the server. | //                                 length of the data received from the server. | ||||||
| // | // | ||||||
| @@ -388,7 +393,10 @@ IpcClientSubmitReq( | |||||||
| // | // | ||||||
| // Abstract:      Method to submit a request. | // Abstract:      Method to submit a request. | ||||||
| // | // | ||||||
| // Note: The routine blocks until the request completes. | // Notes:         The routine blocks until the request completes. | ||||||
|  | //  | ||||||
|  | //                The buffer returned with the server data must be released | ||||||
|  | //                by the calling application by calling free(). | ||||||
| // | // | ||||||
| // L0 | // L0 | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
|   | |||||||
| @@ -157,7 +157,7 @@ ExecuteTests(void) | |||||||
|    // Initialize the Client Ipc Subsystem |    // Initialize the Client Ipc Subsystem | ||||||
|    if (IpcClientInit("TestClient", |    if (IpcClientInit("TestClient", | ||||||
|                      true, |                      true, | ||||||
|                      3, |                      DebugLevel, | ||||||
|                      false) == 0) |                      false) == 0) | ||||||
|    { |    { | ||||||
|       // Set the server listen address |       // Set the server listen address | ||||||
| @@ -235,6 +235,7 @@ main( | |||||||
|    bool        doneScanning = false; |    bool        doneScanning = false; | ||||||
|    bool        invalidOption = false; |    bool        invalidOption = false; | ||||||
|    int         option; |    int         option; | ||||||
|  |    int         initialCount; | ||||||
|  |  | ||||||
|    printf("**** Ipc Client test ****\n"); |    printf("**** Ipc Client test ****\n"); | ||||||
|  |  | ||||||
| @@ -284,7 +285,9 @@ main( | |||||||
|    { |    { | ||||||
|       printf("submitReqCount = %d\n", submitReqCount); |       printf("submitReqCount = %d\n", submitReqCount); | ||||||
|       printf("submitThreadCount = %d\n", submitThreadCount); |       printf("submitThreadCount = %d\n", submitThreadCount); | ||||||
|  |       initialCount = submitReqCount; | ||||||
|       ExecuteTests(); |       ExecuteTests(); | ||||||
|  |       printf("Submits issued = %d\n", initialCount - submitReqCount); | ||||||
|    } |    } | ||||||
|    else |    else | ||||||
|    { |    { | ||||||
|   | |||||||
| @@ -68,28 +68,19 @@ extern pthread_mutex_t interlockedMutex; | |||||||
| // DbgTrace macro define | // DbgTrace macro define | ||||||
| // | // | ||||||
| #define MAX_FORMAT_STRING_LEN 1024 | #define MAX_FORMAT_STRING_LEN 1024 | ||||||
| #define DbgTrace(LEVEL, X, Y) {                                               \ | #define DbgTrace(LEVEL, X, Y) {                                      \ | ||||||
|    if (LEVEL == 0) {                                                          \ |    if (LEVEL == 0 || DebugLevel >= LEVEL) {                          \ | ||||||
|       char *pFormatString = new char[MAX_FORMAT_STRING_LEN];                  \ |       if (UseSyslog)                                                 \ | ||||||
|       if (pFormatString) {                                                    \ |          syslog(LOG_USER | LOG_INFO, X, Y);                          \ | ||||||
|          snprintf(pFormatString, MAX_FORMAT_STRING_LEN, X, Y);                \ |       else {                                                         \ | ||||||
|          if (UseSyslog)                                                       \ |          char *pFormatString = new char[MAX_FORMAT_STRING_LEN];      \ | ||||||
|             syslog(LOG_USER | LOG_INFO, "%s -%s", pAppName, pFormatString);   \ |          if (pFormatString) {                                        \ | ||||||
|          else                                                                 \ |             snprintf(pFormatString, MAX_FORMAT_STRING_LEN, X, Y);    \ | ||||||
|             fprintf(stderr, "%s -%s", pAppName, pFormatString);               \ |             fprintf(stderr, "%s -%s", pAppName, pFormatString);      \ | ||||||
|          delete[] pFormatString;                                              \ |             delete[] pFormatString;                                  \ | ||||||
|       }                                                                       \ |          }                                                           \ | ||||||
|    } else if (DebugLevel >= LEVEL) {                                          \ |       }                                                              \ | ||||||
|       char *pFormatString = new char[MAX_FORMAT_STRING_LEN];                  \ |    }                                                                 \ | ||||||
|       if (pFormatString) {                                                    \ |  | ||||||
|          snprintf(pFormatString, MAX_FORMAT_STRING_LEN, X, Y);                \ |  | ||||||
|          if (UseSyslog)                                                       \ |  | ||||||
|             syslog(LOG_USER | LOG_DEBUG, "%s -%s", pAppName, pFormatString);  \ |  | ||||||
|          else                                                                 \ |  | ||||||
|             fprintf(stderr, "%s -%s", pAppName, pFormatString);               \ |  | ||||||
|          delete[] pFormatString;                                              \ |  | ||||||
|       }                                                                       \ |  | ||||||
|    }                                                                          \ |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // | // | ||||||
|   | |||||||
| @@ -291,10 +291,12 @@ SChannel::connectionThread( | |||||||
|  |  | ||||||
|                         DbgTrace(2, "SChannel::connectionThread- Processing Request Data Packet, Obj = %08X\n", pSChannel); |                         DbgTrace(2, "SChannel::connectionThread- Processing Request Data Packet, Obj = %08X\n", pSChannel); | ||||||
|  |  | ||||||
|                         // Allocate a buffer big enough to receive the payload |                         // Allocate a buffer big enough to receive the payload. Allow space to NULL terminate. | ||||||
|                         pRecvBuff = new char[payloadLength]; |                         pRecvBuff = new char[payloadLength + 1]; | ||||||
|                         if (pRecvBuff != NULL) |                         if (pRecvBuff != NULL) | ||||||
|                         { |                         { | ||||||
|  |                            pRecvBuff[payloadLength] = '\0'; | ||||||
|  |  | ||||||
|                            // Buffer allocated, receive the Req payload. |                            // Buffer allocated, receive the Req payload. | ||||||
|                            while (1) |                            while (1) | ||||||
|                            { |                            { | ||||||
|   | |||||||
| @@ -830,6 +830,10 @@ IpcServerGetRequestData( | |||||||
| // Notes:         The returned buffer SHOULD NOT be released by the calling | // Notes:         The returned buffer SHOULD NOT be released by the calling | ||||||
| //                application. | //                application. | ||||||
| // | // | ||||||
|  | //                The returned buffer always contains a NULL after the | ||||||
|  | //                data indicated. You may be able to leverage this to | ||||||
|  | //                treat the data as a NULL terminated string in cases | ||||||
|  | //                where the request consists of ASCII characters. | ||||||
| // L1 | // L1 | ||||||
| //=======================================================================-- | //=======================================================================-- | ||||||
| { | { | ||||||
|   | |||||||
| @@ -166,7 +166,7 @@ ExecuteTests(void) | |||||||
|  |  | ||||||
|    // Initialize the Svc Ipc Subsystem |    // Initialize the Svc Ipc Subsystem | ||||||
|    if (IpcServerInit("TestServer", |    if (IpcServerInit("TestServer", | ||||||
|                      3, |                      DebugLevel, | ||||||
|                      false) == 0) |                      false) == 0) | ||||||
|    { |    { | ||||||
|       // Set the server listen address |       // Set the server listen address | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user