made C auth server
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 15 Sep 2005 22:59:37 +0000 (22:59 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 15 Sep 2005 22:59:37 +0000 (22:59 +0000)
added utils code for C servers, including some fieldmapper handling code
fieldmapper now copies headers over to INCLUDE/openils/
install scripts now install c-apps

git-svn-id: svn://svn.open-ils.org/ILS/trunk@1832 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/Makefile
Open-ILS/src/apachemods/Makefile
Open-ILS/src/apachemods/fieldmapper_lookup-gen.pl
Open-ILS/src/c-apps/Makefile [new file with mode: 0644]
Open-ILS/src/c-apps/oils_auth.c [new file with mode: 0644]
Open-ILS/src/c-apps/oils_utils.c [new file with mode: 0644]
Open-ILS/src/c-apps/oils_utils.h [new file with mode: 0644]
OpenSRF/bin/opensrf_all
OpenSRF/src/utils/utils.c
OpenSRF/src/utils/utils.h
install.sh

index fdaf67d..70a0c2c 100644 (file)
@@ -4,12 +4,13 @@ export LDFLAGS                        = -L $(TMPDIR) -L .
 export CFLAGS                  = -g -Wall -O2 -fPIC -I$(LIBXML2_HEADERS) -I$(APACHE2_HEADERS) \
                                                                -I$(LIBXML2_HEADERS)/libxml  -I$(TMP) -I$(TMPDIR)
 
-export INCLUDEDIR += "/openils/"
+export INCDIR = "$(INCLUDEDIR)/openils/"
 
-all: mod_xmltools mod_ils_rest_gateway
+all: msg mod_xmltools mod_ils_rest_gateway c_apps
 
 
-install:       perl-install web-install string-templates-install storage-bootstrap cgi-bootstrap xsl-install
+
+install:       perl-install web-install string-templates-install storage-bootstrap cgi-bootstrap xsl-install c_apps-install
 
 web-install:   webcore-install autojs-install  mod_xmltools-install mod_ils_rest_gateway-install
 
@@ -37,9 +38,18 @@ mod_xmltools-install:
 webcore-install:
        @echo $@
        echo "Copying web into $(WEBDIR)"
+       # XXX put these back
        #mkdir -p $(WEBDIR)
        #cp -r ../web/* $(WEBDIR)
 
+c_apps:        mod_ils_rest_gateway
+       @echo $@
+       make -C c-apps
+
+c_apps-install:
+       @echo $@
+       make -C c-apps install
+
 autojs-install:
        @echo $@
        cp extras/fieldmapper.pl $(BINDIR)
index 380f6aa..816a885 100644 (file)
@@ -21,15 +21,18 @@ fieldmapper_lookup.c:
 # ------------------------------------------------------
 
 mod_xmltools.so: mod_xmltools.o apachetools.o  xmltools.o 
-       echo $@
+       @echo $@
        $(CC) $(LDFLAGS) $(LDLIBS) -shared -W1 apachetools.o xmltools.o mod_xmltools.o -o $@
 
 libfieldmapper.so:     fieldmapper_lookup.o
-       echo $@
+       @echo $@
+       mkdir -p $(TMPDIR)/openils/
+       cp fieldmapper_lookup.h $(TMPDIR)/openils/
        $(CC) $(LDFLAGS) $(LDLIBS) -shared -W1 fieldmapper_lookup.o -o $@
+       cp libfieldmapper.so $(TMPDIR)/libfieldmapper.so
 
 mod_ils_rest_gateway.so:       libfieldmapper.so ils_rest_gateway.o json_xml.o
-       echo $@
+       @echo $@
        $(CC) $(LDFLAGS) $(LDLIBS) -shared -W1 json_xml.o ils_rest_gateway.o -lfieldmapper -o $@
 
 # ------------------------------------------------------
@@ -37,8 +40,9 @@ mod_ils_rest_gateway.so:      libfieldmapper.so ils_rest_gateway.o json_xml.o
 
 libfieldmapper-install:        libfieldmapper.so
        echo installing libfieldmapper.so
-       mkdir -p $(INCLUDEDIR)/
-       cp fieldmapper_lookup.h $(INCLUDEDIR)/
+       mkdir -p $(INCDIR)/
+       @echo "Copying fieldmapper_lookup.h to $(INCDIR)"
+       cp fieldmapper_lookup.h $(INCDIR)/
        cp libfieldmapper.so $(LIBDIR)/libfieldmapper.so
 
 
index f3ae179..76f4c00 100755 (executable)
@@ -68,7 +68,7 @@ print SOURCE <<C;
 }
 
 int fm_ntop(char* class, char* field) {
-       if (class == NULL) return 0;
+       if (class == NULL) return -1;
 C
 
 
diff --git a/Open-ILS/src/c-apps/Makefile b/Open-ILS/src/c-apps/Makefile
new file mode 100644 (file)
index 0000000..55996cf
--- /dev/null
@@ -0,0 +1,18 @@
+LDLIBS += -lobjson -lopensrf -lfieldmapper
+CFLAGS += -DOSRF_LOG_PARAMS
+
+all:   oils_auth.so
+
+oils_utils.o:  oils_utils.c oils_utils.h
+oils_auth.o:   oils_auth.c
+
+
+oils_auth.so:  oils_auth.o oils_utils.o
+       $(CC) -shared -W1 $(LDLIBS) $(LDFLAGS) oils_utils.o oils_auth.o -o $(TMPDIR)/oils_auth.so
+
+install:
+       cp $(TMPDIR)/oils_auth.so $(LIBDIR)/
+
+clean:
+       rm -f *.o *.so
+
diff --git a/Open-ILS/src/c-apps/oils_auth.c b/Open-ILS/src/c-apps/oils_auth.c
new file mode 100644 (file)
index 0000000..cdb0e84
--- /dev/null
@@ -0,0 +1,214 @@
+#include "opensrf/osrf_app_session.h"
+#include "opensrf/osrf_application.h"
+#include "objson/object.h"
+#include "opensrf/osrf_log.h"
+#include "oils_utils.h"
+
+#define OILS_AUTH_CACHE_PRFX "oils_auth_"
+
+
+#define MODULENAME "open-ils.auth"
+
+int osrfAppInitialize();
+int osrfAppChildInit();
+int osrfMathRun( osrfMethodContext* );
+
+
+int osrfAppInitialize() {
+
+       osrfLogInit(MODULENAME);
+
+       osrfAppRegisterMethod( 
+               MODULENAME, 
+               "open-ils.auth.authenticate.init", 
+               "oilsAuthInit", 
+               "Start the authentication process and returns the intermediate authentication seed",
+               " [ username ]", 1 );
+
+       osrfAppRegisterMethod( 
+               MODULENAME, 
+               "open-ils.auth.authenticate.complete", 
+               "oilsAuthComplete", 
+               "Completes the authentication process and returns the auth token",
+               "[ username, md5sum( seed + password ) ]", 2 );
+
+       osrfAppRegisterMethod( 
+               MODULENAME, 
+               "open-ils.auth.session.retrieve", 
+               "oilsAuthSessionRetrieve", 
+               "Returns the user object (password blanked) for the given login session",
+               "[ authToken ]", 1 );
+
+       osrfAppRegisterMethod( 
+               MODULENAME, 
+               "open-ils.auth.session.delete", 
+               "oilsAuthSessionDelete", 
+               "Destroys the given login session",
+               "[ authToken ]",  1 );
+
+       return 0;
+}
+
+int osrfAppChildInit() {
+       return 0;
+}
+
+int oilsAuthInit( osrfMethodContext* ctx ) {
+       OSRF_METHOD_VERIFY_CONTEXT(ctx); 
+
+       jsonObject* resp;
+       char* username = NULL;
+       char* seed = NULL;
+       char* md5seed = NULL;
+       char* key = NULL;
+
+       if( (username = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0))) ) {
+
+               seed = va_list_to_string( "%d.%d.%s", time(NULL), getpid(), username );
+               key = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, username );
+
+               md5seed = md5sum(seed);
+               osrfCachePutString( key, md5seed, 30 );
+
+               osrfLog( OSRF_DEBUG, "oilsAuthInit(): has seed %s and key %s", md5seed, key );
+
+               resp = jsonNewObject(md5seed);  
+               osrfAppRequestRespondComplete( ctx->session, ctx->request, resp );
+
+               jsonObjectFree(resp);
+               free(seed);
+               free(md5seed);
+               free(key);
+               return 0;
+       }
+
+       return -1;
+}
+
+
+int oilsAuthComplete( osrfMethodContext* ctx ) {
+       OSRF_METHOD_VERIFY_CONTEXT(ctx); 
+
+       char* uname = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0));
+       char* password = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 1));
+       char* storageMethod = "open-ils.storage.direct.actor.user.search.usrname.atomic";
+
+       if( uname && password ) {
+
+               /* grab the user object from storage */
+               osrfLog( OSRF_DEBUG, "oilsAuth calling method %s with username %s", storageMethod, uname );
+
+               osrfAppSession* session = osrfAppSessionClientInit( "open-ils.storage" ); /**/
+               jsonObject* params = jsonNewObject(uname); /**/
+               int reqid = osrfAppSessionMakeRequest( session, params, storageMethod, 1, NULL );
+               jsonObjectFree(params);
+               osrfMessage* omsg = osrfAppSessionRequestRecv( session, reqid, 60 ); /**/
+
+               if(!omsg) { 
+                       osrfAppSessionFree(session);
+                       return osrfAppRequestRespondException( ctx->session, ctx->request,
+                               "No response from storage server for method %s", storageMethod ); 
+               }
+
+               jsonObject* userObj = osrfMessageGetResult(omsg);
+
+               char* _j = jsonObjectToJSON(userObj);
+               osrfLog( OSRF_DEBUG, "Auth received user object from storage: %s", _j );
+               free(_j);
+
+               /* the method is atomic, grab the first user we receive */
+               if( userObj ) userObj = jsonObjectGetIndex(userObj, 0);
+               
+               if(!userObj) { /* XXX needs to be a 'friendly' exception */
+                       osrfMessageFree(omsg);
+                       osrfAppSessionFree(session);
+                       return osrfAppRequestRespondException( ctx->session, 
+                                       ctx->request, "User %s not found in the database", uname );
+               }
+
+               char* realPassword = oilsFMGetString( userObj, "passwd" ); /**/
+               char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/
+
+               if(!seed) {
+                       osrfMessageFree(omsg);
+                       osrfAppSessionFree(session);
+                       return osrfAppRequestRespondException( ctx->session,
+                               ctx->request, "No authentication seed found. "
+                               "open-ils.auth.authenticate.init must be called first");
+               }
+
+               osrfLog( OSRF_DEBUG, "oilsAuth retrieved seed from cache: %s", seed );
+               char* maskedPw = md5sum( "%s%s", seed, realPassword );
+               if(!maskedPw) return -1;
+               osrfLog( OSRF_DEBUG, "oilsAuth generated masked password %s. "
+                               "Testing against provided password %s", maskedPw, password );
+
+               jsonObject* response;
+
+               if( !strcmp( maskedPw, password ) ) {
+
+                       osrfLog( OSRF_INFO, "Login successful for %s", uname );
+                       char* string = va_list_to_string( "%d.%d.%s", getpid(), time(NULL), uname ); /**/
+                       char* authToken = md5sum(string); /**/
+                       char* authKey = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
+                       oilsFMSetString( userObj, "passwd", "" );
+                       osrfCachePutObject( authKey, userObj, 28800 ); /* XXX config value */
+                       response = jsonNewObject( authToken );
+                       free(string); free(authToken); free(authKey);
+
+               } else {
+                       osrfLog( OSRF_INFO, "Login failed for for %s", uname );
+                       response = jsonNewNumberObject(0);
+               }
+
+               osrfAppRequestRespondComplete( ctx->session, ctx->request, response ); 
+               jsonObjectFree(response);
+               osrfMessageFree(omsg);
+               osrfAppSessionFree(session);
+
+       } else {
+               return osrfAppRequestRespondException( ctx->session, ctx->request, 
+                       "username and password required for method: %s", ctx->method->name );
+       }
+
+       return 0;
+
+}
+
+int oilsAuthSessionRetrieve( osrfMethodContext* ctx ) {
+       OSRF_METHOD_VERIFY_CONTEXT(ctx); 
+
+       char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0));
+       jsonObject* userObj = NULL;
+
+       if( authToken ){
+               char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
+               userObj = osrfCacheGetObject( key ); /**/
+               free(key);
+       }
+
+       osrfAppRequestRespondComplete( ctx->session, ctx->request, userObj );
+       jsonObjectFree(userObj);
+       return 0;
+}
+
+int oilsAuthSessionDelete( osrfMethodContext* ctx ) {
+       OSRF_METHOD_VERIFY_CONTEXT(ctx); 
+
+       char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
+       jsonObject* resp = NULL;
+
+       if( authToken ) {
+               char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
+               osrfCacheRemove(key);
+               resp = jsonNewObject(authToken); /**/
+               free(key);
+       }
+
+       osrfAppRequestRespondComplete( ctx->session, ctx->request, resp );
+       jsonObjectFree(resp);
+       return 0;
+}
+
+
+
diff --git a/Open-ILS/src/c-apps/oils_utils.c b/Open-ILS/src/c-apps/oils_utils.c
new file mode 100644 (file)
index 0000000..c2fe147
--- /dev/null
@@ -0,0 +1,25 @@
+#include "oils_utils.h"
+
+char* oilsFMGetString( jsonObject* object, char* field ) {
+       return jsonObjectToSimpleString(oilsFMGetObject( object, field ));
+}
+
+
+jsonObject* oilsFMGetObject( jsonObject* object, char* field ) {
+       if(!(object && field)) return NULL;
+       if( object->type != JSON_ARRAY || !object->classname ) return NULL;
+       int pos = fm_ntop(object->classname, field);
+       if( pos > -1 ) return jsonObjectGetIndex( object, pos );
+       return NULL;
+}
+
+
+int oilsFMSetString( jsonObject* object, char* field, char* string ) {
+       if(!(object && field && string)) return -1;
+       int pos = fm_ntop(object->classname, field);
+       if( pos > -1 ) {
+               jsonObjectSetIndex( object, pos, jsonNewObject(string) );
+               return 0;
+       }
+       return -1;
+}
diff --git a/Open-ILS/src/c-apps/oils_utils.h b/Open-ILS/src/c-apps/oils_utils.h
new file mode 100644 (file)
index 0000000..9c30bdc
--- /dev/null
@@ -0,0 +1,33 @@
+#include "objson/object.h"
+#include "openils/fieldmapper_lookup.h"
+
+/**
+  Returns the string value for field 'field' in the given object.
+  This method calls jsonObjectToSimpleString so numbers will be
+  returned as strings.
+  @param object The object to inspect
+  @param field The field whose value is requsted
+  @return The string at the given position, if none exists, 
+  then NULL is returned.  The caller must free the returned string
+  */
+char* oilsFMGetString( jsonObject* object, char* field );
+
+
+/**
+  Returns the jsonObject found at the specified field in the
+  given object.
+  @param object The object to inspect
+  @param field The field whose value is requsted
+  @return The found object or NULL if none exists.  Do NOT free the 
+  returned object.
+  */
+jsonObject* oilsFMGetObject( jsonObject* object, char* field );
+
+/**
+  Sets the given field in the given object to the given string
+  @param object The object to update
+  @param field The field to change
+  @param string The new data
+  @return 0 if the field was updated successfully, -1 on error
+  */
+int oilsFMSetString( jsonObject* object, char* field, char* string );
index 9f19e87..cdc998c 100755 (executable)
@@ -125,7 +125,7 @@ function stopMe {
        sleep 1;
        
        echo "Stopping The Router...";
-       killall opensrf_router;
+       killall "OpenSRF Router"
        
        sleep 1;
        
index 0922544..9c42578 100644 (file)
@@ -397,16 +397,18 @@ char* file_to_string(const char* filename) {
 }
 
 
-char* md5sum( char* text ) {
+char* md5sum( char* text, ... ) {
 
        struct md5_ctx ctx;
        unsigned char digest[16];
 
        MD5_start (&ctx);
 
+       VA_LIST_TO_STRING(text);
+
        int i;
-       for ( i=0 ; i != strlen(text) ; i++ )
-               MD5_feed (&ctx, text[i]);
+       for ( i=0 ; i != strlen(VA_BUF) ; i++ )
+               MD5_feed (&ctx, VA_BUF[i]);
 
        MD5_stop (&ctx, digest);
 
index a5ecb45..1737c29 100644 (file)
@@ -181,7 +181,7 @@ char* file_to_string(const char* filename);
   Calculates the md5 of the text provided.
   The returned string must be freed by the caller.
   */
-char* md5sum( char* text );
+char* md5sum( char* text, ... );
 
 
 #endif
index e6d0d28..a057363 100755 (executable)
@@ -173,10 +173,12 @@ function runInstall {
                                ;;
 
                        "openils_core" )
+                               if building; then $MAKE -C "$OPENILSDIR" "c_apps"; fi;
                                if installing; then 
                                        $MAKE -C "$OPENILSDIR" "perl-install"; 
                                        $MAKE -C "$OPENILSDIR" "string-templates-install"; 
                                        $MAKE -C "$OPENILSDIR" "xsl-install"; 
+                                       $MAKE -C "$OPENILSDIR" "c_apps-install"; 
                                fi;
                                ;;