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

Introduce RBAC checking via custom authHandler function #218

Open
wants to merge 28 commits into
base: v1.x/staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
756b42c
Some prototype RBAC checking + unfinished comments
DivergentEuropeans May 24, 2021
37a9bd7
request->username works properly
DivergentEuropeans May 24, 2021
d11786a
Removed logging for TSO credentials
DivergentEuropeans May 25, 2021
552f551
Change up switch case logic to handle backwards compatibility
DivergentEuropeans May 31, 2021
56d3941
Moved core RBAC auth code from zowe-common-c into ZSS
DivergentEuropeans Jun 3, 2021
faa29df
Merge branch 'staging' of github.com:zowe/zowe-common-c into RBAC-sup…
DivergentEuropeans Jun 3, 2021
f6d670d
Made authHandlers into an array of structs
DivergentEuropeans Jun 7, 2021
f8e6a20
Clean-up + changed authType to string in httpServer.c
DivergentEuropeans Jun 7, 2021
1b55568
Missed a few things
DivergentEuropeans Jun 7, 2021
c5c9bac
Removed comment
DivergentEuropeans Jun 7, 2021
20ad412
Code review changes
DivergentEuropeans Jun 11, 2021
1673b5f
Removed unneeded comment
DivergentEuropeans Jun 11, 2021
632cb11
Some code cleanup
Jun 23, 2021
517679b
Revert back to integer authType
Jul 1, 2021
305ab94
Remove SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN_NO_RBAC
Jul 1, 2021
be35a36
Refactor authorization code
Jul 1, 2021
166c715
Provide ability to pass userData into AuthorizationCheck
Jul 2, 2021
be5f0e5
Minor refactoring
Jul 5, 2021
59fc275
Merge branch 'staging' of github.com:zowe/zowe-common-c into RBAC-sup…
DivergentEuropeans Aug 19, 2021
c5880dd
Merge branch 'rbac-code-cleanup' of https://github.com/lchudinov/zowe…
DivergentEuropeans Aug 19, 2021
16b4ef9
Merge branch 'rbac-refactoring' of https://github.com/lchudinov/zowe-…
DivergentEuropeans Aug 19, 2021
979e105
Merge branch 'staging' of github.com:zowe/zowe-common-c into RBAC-sup…
DivergentEuropeans Aug 29, 2021
9d7f631
Add return code for registerHttpAuthorizationHandler
Aug 31, 2021
2a1ab84
Merge pull request #233 from lchudinov/feature/add-return-code-for-re…
lchudinov Aug 31, 2021
e736e8d
Rename AuthorizationHandler to HttpAuthorize
Aug 31, 2021
2f45fb2
Merge pull request #234 from lchudinov/feature/rename-authorization-h…
ifakhrutdinov Aug 31, 2021
58bf017
Merge branch 'staging' of github.com:zowe/zowe-common-c into RBAC-sup…
DivergentEuropeans Sep 24, 2021
14a7225
Merge remote-tracking branch 'origin/staging' into RBAC-support
Nov 29, 2021
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
60 changes: 49 additions & 11 deletions c/httpserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -3397,12 +3397,14 @@ static int handleHttpService(HttpServer *server,

AuthResponse authResponse;

switch (service->authType){

case SERVICE_AUTH_NONE:
int authorized = TRUE;

if (strcmp(service->authType, SERVICE_AUTH_NONE) == 0)
{
request->authenticated = TRUE;
break;
case SERVICE_AUTH_SAF:
}
else if (strcmp(service->authType, SERVICE_AUTH_SAF) == 0)
{
/* SAF Authentication just checks that user is known at ALL to SAF.
Additional privilege (Facility Class Profile) checking maybe done later
or added to the generic SAF support in server.
Expand All @@ -3411,14 +3413,15 @@ static int handleHttpService(HttpServer *server,
printf("saf auth needed for service %s\n",service->name);
#endif
request->authenticated = safAuthenticate(service, request, &authResponse);
break;
case SERVICE_AUTH_CUSTOM:
}
/* case SERVICE_AUTH_CUSTOM: - Safe to remove?
#ifdef DEBUG
printf("CUSTOM auth not yet supported\n");
#endif
request->authenticated = FALSE;
break;
case SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN:
break; */
else if (strcmp(service->authType, SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN_NO_RBAC) == 0)
{
switch (server->config->authTokenType) {
case SERVICE_AUTH_TOKEN_TYPE_JWT:
case SERVICE_AUTH_TOKEN_TYPE_JWT_WITH_LEGACY_FALLBACK:
Expand All @@ -3433,10 +3436,43 @@ static int handleHttpService(HttpServer *server,
request->authenticated = serviceAuthNativeWithSessionToken(service,request,response,&clearSessionToken, &authResponse);
break;
}
break;
}
else /* Type was not found, checking custom handlers */
{
switch (server->config->authTokenType) {
case SERVICE_AUTH_TOKEN_TYPE_JWT:
case SERVICE_AUTH_TOKEN_TYPE_JWT_WITH_LEGACY_FALLBACK:
request->authenticated = serviceAuthWithJwt(service, request, response);

if (request->authenticated ||
service->server->config->authTokenType
!= SERVICE_AUTH_TOKEN_TYPE_JWT_WITH_LEGACY_FALLBACK) {
break;
} /* else fall through */
case SERVICE_AUTH_TOKEN_TYPE_LEGACY:
request->authenticated = serviceAuthNativeWithSessionToken(service,request,response,&clearSessionToken, &authResponse);
break;
}
if (request->authenticated) {
int size = sizeof(server->authHandler)/sizeof(server->authHandler[0]);
DivergentEuropeans marked this conversation as resolved.
Show resolved Hide resolved
for (int i = 0; i < size; i++) {
if (server->authHandler[i] != NULL) {
if (strcmp(server->authHandler[i]->type, SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN) == 0) {
authorized = service->server->authHandler[i]->authFunction(service, request, response);
if (!authorized) {
break;
}
}
} else {
break;
}
}
} else {
authorized = FALSE;
}
}
#ifdef DEBUG
printf("service=%s authenticated=%d\n",service->name,request->authenticated);
printf("service=%s authenticated=%d authorized=%d\n",service->name,request->authenticated,authorized);
#endif
if (request->authenticated == FALSE){
if (service->authFlags & SERVICE_AUTH_FLAG_OPTIONAL) {
Expand All @@ -3445,6 +3481,8 @@ static int handleHttpService(HttpServer *server,
} else {
respondWithAuthError(response, &authResponse);
}
} else if (!authorized) {
respondWithError(response, HTTP_STATUS_FORBIDDEN, "Forbidden");
DivergentEuropeans marked this conversation as resolved.
Show resolved Hide resolved
// Response is finished on return
} else {

Expand Down
17 changes: 12 additions & 5 deletions h/httpserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
#define SERVICE_TYPE_PROXY 5
#define SERVICE_TYPE_FILES_SECURE 6

#define SERVICE_AUTH_NONE 1
#define SERVICE_AUTH_SAF 2
#define SERVICE_AUTH_CUSTOM 3 /* done by service */
#define SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN 4
#define SERVICE_AUTH_NONE "NONE"
#define SERVICE_AUTH_SAF "SAF"
#define SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN "NATIVE_WITH_SESSION_TOKEN"
#define SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN_NO_RBAC "NATIVE_WITH_SESSION_TOKEN_NO_RBAC"

#define SERVICE_AUTH_TOKEN_TYPE_LEGACY 0
#define SERVICE_AUTH_TOKEN_TYPE_JWT_WITH_LEGACY_FALLBACK 1
Expand Down Expand Up @@ -146,6 +146,7 @@ typedef int HttpServiceServe(struct HttpService_tag *service, HttpResponse *resp
typedef int AuthExtract(struct HttpService_tag *service, HttpRequest *request);
typedef int AuthValidate(struct HttpService_tag *service, HttpRequest *request);
typedef int HttpServiceInsertCustomHeaders(struct HttpService_tag *service, HttpResponse *response);
typedef int AuthHandle(struct HttpService_tag *service, HttpRequest *request, HttpResponse *response);

/*
returns HTTP_SERVICE_SUCCESS or other fail codes in same group
Expand Down Expand Up @@ -180,7 +181,7 @@ typedef struct HttpService_tag{
char **parsedMaskParts;
int matchFlags;
int serviceType;
int authType;
char *authType;
int runInSubtask;
void *authority; /* NULL unless AUTH_CUSTOM */
AuthExtract *authExtractionFunction;
Expand All @@ -207,6 +208,11 @@ typedef struct HttpService_tag{
int authFlags;
} HttpService;

typedef struct HttpAuthHandler_tag{
char *type;
AuthHandle *authFunction;
} HttpAuthHandler;

typedef struct HTTPServerConfig_tag {
int port;
HttpService *serviceList;
Expand All @@ -229,6 +235,7 @@ typedef struct HttpServer_tag{
uint64 serverInstanceUID; /* may be something smart at some point. Now just startup STCK */
void *sharedServiceMem; /* address shared by all HttpServices */
hashtable *loggingIdsByName; /* contains a map of pluginID -> loggingID */
HttpAuthHandler *authHandler[64]; /* contains array of authHandlers (type + auth func) for HttpServices */
} HttpServer;

typedef struct WSReadMachine_tag{
Expand Down