diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..5489bbd1c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# Zowe Common C Changelog + +## `1.13.0` + +- Added struct to control server authentication behavior, such as session length and cookie name +- Initialized http server log earlier, a bugfix to show error messages that were hidden before. diff --git a/c/httpserver.c b/c/httpserver.c index 51e773e8f..f007feef8 100644 --- a/c/httpserver.c +++ b/c/httpserver.c @@ -1375,7 +1375,7 @@ static int initSessionTokenKey(SessionTokenKey *key) { int icsfRC = icsfGenerateRandomNumber(key, sizeof(SessionTokenKey), &icsfRSN); if (icsfRC != 0) { zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_SEVERE, - "Error: session token key not generated, RC = %d, RSN = %d\n", + "Error: ICSF generation of random number failed. Session token key not generated, RC = %d, RSN = %d\n", icsfRC, icsfRSN); return -1; } @@ -1477,13 +1477,38 @@ static int decodeSessionToken(ShortLivedHeap *slh, } HttpServer *makeHttpServer2(STCBase *base, + InetAddr *addr, + int port, + int tlsFlags, + int *returnCode, int *reasonCode) { + return makeHttpServer3(base, addr, port, tlsFlags, NULL, returnCode, reasonCode); +} + +HttpServer *makeHttpServer3(STCBase *base, InetAddr *addr, int port, int tlsFlags, + AuthOptions *authOptions, int *returnCode, int *reasonCode){ - + logConfigureComponent(NULL, LOG_COMP_HTTPSERVER, "httpserver", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); + + if (authOptions != NULL) { + if (authOptions->defaultSessionValiditySeconds > 0) { + defaultSessionValiditySeconds = authOptions->defaultSessionValiditySeconds; + } + if (authOptions->sessionTokenCookieName != NULL) { + sessionTokenCookieName = authOptions->sessionTokenCookieName; + } + if (authOptions->enableSessionCookie != NULL) { + enableSessionCookie = authOptions->enableSessionCookie; + } + if (authOptions->enableBasicAuth != NULL) { + enableBasicAuth = authOptions->enableBasicAuth; + } + } + SessionTokenKey sessionTokenKey = {0}; - if (initSessionTokenKey(&sessionTokenKey) != 0) { + if (initSessionTokenKey(&sessionTokenKey) != 0 && (enableSessionCookie == TRUE)) { return NULL; } @@ -1584,7 +1609,7 @@ int httpServerSetSessionTokenKey(HttpServer *server, unsigned int size, } HttpServer *makeHttpServer(STCBase *base, int port, int *returnCode, int *reasonCode){ - return makeHttpServer2(base, NULL, port, 0, returnCode, reasonCode); + return makeHttpServer3(base, NULL, port, 0, NULL, returnCode, reasonCode); } int registerHttpService(HttpServer *server, HttpService *service){ @@ -2374,6 +2399,7 @@ static int proxyServe(HttpService *service, */ #define SESSION_TOKEN_COOKIE_NAME "jedHTTPSession" +static char *sessionTokenCookieName=SESSION_TOKEN_COOKIE_NAME; static char *getCookieValue(HttpRequest *request, char *cookieName){ HttpHeader *cookieHeader = getHeader(request,"Cookie"); @@ -2723,6 +2749,7 @@ static int64 getFineGrainedTime(){ #endif #define SESSION_VALIDITY_IN_SECONDS 3600 +static int defaultSessionValiditySeconds = SESSION_VALIDITY_IN_SECONDS; static int sessionTokenStillValid(HttpService *service, HttpRequest *request, char *sessionTokenText){ HttpServer *server = service->server; @@ -2761,7 +2788,7 @@ static int sessionTokenStillValid(HttpService *service, HttpRequest *request, ch uint64 decodedTimestamp= strtoull(plaintextSessionToken+colonPos+1, NULL, 16); uint64 serverInstanceUID = strtoull(plaintextSessionToken+colonPos2+1, NULL, 16); uint64 now = getFineGrainedTime(); - uint64 interval = ((uint64)SESSION_VALIDITY_IN_SECONDS)*ONE_SECOND; + uint64 interval = ((uint64)defaultSessionValiditySeconds)*ONE_SECOND; uint64 difference = now-decodedTimestamp; AUTH_TRACE("decodedTimestamp=%llx;now=%llx;difference=%llx;interval=%llx;tokenUID=%llx;serverUID=%llx\n", @@ -2806,8 +2833,8 @@ static char *generateSessionTokenKeyValue(HttpService *service, HttpRequest *req char *base64Output = encodeBase64(slh,tokenCiphertext,tokenPlaintextLength,&encodedLength,TRUE); char *keyValueBuffer = SLHAlloc(slh,512); memset(keyValueBuffer,0,512); - int keyLength = strlen(SESSION_TOKEN_COOKIE_NAME); - memcpy(keyValueBuffer,SESSION_TOKEN_COOKIE_NAME,keyLength); + int keyLength = strlen(sessionTokenCookieName); + memcpy(keyValueBuffer,sessionTokenCookieName,keyLength); int offset = keyLength; keyValueBuffer[keyLength] = '='; memcpy(keyValueBuffer+keyLength+1,base64Output,strlen(base64Output)); @@ -2815,11 +2842,14 @@ static char *generateSessionTokenKeyValue(HttpService *service, HttpRequest *req return keyValueBuffer; } +static int enableSessionCookie = TRUE; +static int enableBasicAuth = TRUE; + static int serviceAuthNativeWithSessionToken(HttpService *service, HttpRequest *request, HttpResponse *response, int *clearSessionToken, AuthResponse *authResponse){ int authDataFound = FALSE; HttpHeader *authenticationHeader = getHeader(request,"Authorization"); - char *tokenCookieText = getCookieValue(request,SESSION_TOKEN_COOKIE_NAME); + char *tokenCookieText = getCookieValue(request,sessionTokenCookieName); zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "serviceAuthNativeWithSessionToken: authenticationHeader 0x%p, authenticationHeader(hex) = 0x%x\n", @@ -2829,7 +2859,7 @@ static int serviceAuthNativeWithSessionToken(HttpService *service, HttpRequest * service->authExtractionFunction); if (authenticationHeader) { - if (extractBasicAuth(request,authenticationHeader)){ + if (enableBasicAuth && extractBasicAuth(request,authenticationHeader)){ authDataFound = TRUE; } } else { @@ -2848,7 +2878,7 @@ static int serviceAuthNativeWithSessionToken(HttpService *service, HttpRequest * AUTH_TRACE("AUTH: tokenCookieText: %s\n",(tokenCookieText ? tokenCookieText : "")); - if (tokenCookieText){ + if (tokenCookieText && enableSessionCookie){ zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "serviceAuthNativeWithSessionToken: tokenCookieText: %s\n", (tokenCookieText ? tokenCookieText : "")); @@ -5521,7 +5551,6 @@ void registerHttpServerModuleWithBase(HttpServer *server, STCBase *base) int mainHttpLoop(HttpServer *server){ STCBase *base = server->base; - logConfigureComponent(NULL, LOG_COMP_HTTPSERVER, "httpserver", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); /* server pointer will be copied/accessible from module->data */ STCModule *httpModule = stcRegisterModule(base, STC_MODULE_JEDHTTP, diff --git a/h/httpserver.h b/h/httpserver.h index cf7e44030..3590575ac 100644 --- a/h/httpserver.h +++ b/h/httpserver.h @@ -63,6 +63,13 @@ #define HTTP_SERVER_PRIVILEGED_SERVER_PROPERTY "zisServerName" +typedef struct AuthOptions_tag{ + int defaultSessionValiditySeconds; /* overrides default if greater than 0 */ + int enableSessionCookie; /* not needed if using SSO or BA */ + int enableBasicAuth; /* not needed if using SSO or cookie */ + char *sessionTokenCookieName; /* would override default */ +} AuthOptions; + typedef struct BigBuffer_tag{ ShortLivedHeap *slh; /* can be null */ char *data; @@ -412,7 +419,8 @@ HttpRequest *dequeueHttpRequest(HttpRequestParser *parser); HttpRequestParser *makeHttpRequestParser(ShortLivedHeap *slh); HttpResponse *makeHttpResponse(HttpRequest *request, ShortLivedHeap *slh, Socket *socket); -HttpServer *makeHttpServer2(STCBase *base, InetAddr *ip, int tlsFlags, int port, int *returnCode, int *reasonCode); +HttpServer *makeHttpServer3(STCBase *base, InetAddr *ip, int port, int tlsFlags, AuthOptions *authOptions, int *returnCode, int *reasonCode); +HttpServer *makeHttpServer2(STCBase *base, InetAddr *ip, int port, int tlsFlags, int *returnCode, int *reasonCode); HttpServer *makeHttpServer(STCBase *base, int port, int *returnCode, int *reasonCode); #ifdef USE_RS_SSL