Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Options for controlling server authentication behavior #144

Open
wants to merge 5 commits into
base: v1.x/staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
51 changes: 40 additions & 11 deletions c/httpserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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){
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -2806,20 +2833,23 @@ 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));

return keyValueBuffer;
}

static enableSessionCookie = TRUE;
static 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",
Expand All @@ -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 {
Expand All @@ -2848,7 +2878,7 @@ static int serviceAuthNativeWithSessionToken(HttpService *service, HttpRequest *

AUTH_TRACE("AUTH: tokenCookieText: %s\n",(tokenCookieText ? tokenCookieText : "<noAuthToken>"));

if (tokenCookieText){
if (tokenCookieText && enableSessionCookie){
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3,
"serviceAuthNativeWithSessionToken: tokenCookieText: %s\n",
(tokenCookieText ? tokenCookieText : "<noAuthToken>"));
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 9 additions & 1 deletion h/httpserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The int flip is intentional. The header did not match the code.

HttpServer *makeHttpServer(STCBase *base, int port, int *returnCode, int *reasonCode);

#ifdef USE_RS_SSL
Expand Down