From: Daniel KouĊ™il Date: Sun, 22 Jan 2012 22:50:44 +0000 (+0000) Subject: Support for anonymization of states X-Git-Tag: merge_jobhistory_head_src~2 X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=4a01854cb99c633e25a6ef03994a1828791376f9;p=jra1mw.git Support for anonymization of states - a server-wide salt is used to make the hashes unique - aggregation of the authz code; in the notification part it's been moved only before the message is actualy sent out - a new authorization category (READ_ANONYMIZED) introduced --- diff --git a/org.glite.lb.server/Makefile b/org.glite.lb.server/Makefile index c9f9885..c87d4de 100644 --- a/org.glite.lb.server/Makefile +++ b/org.glite.lb.server/Makefile @@ -170,7 +170,7 @@ BKSERVER_BASE_OBJS:= \ openserver.o query.o userjobs.o db_store.o request.o store.o \ stored_master.o srv_purge.o server_state.o dump.o lb_authz.o load.o \ notification.o il_notification.o notif_match.o stats.o db_calls.o db_supp.o lb_rss.o pretty_print_wrapper.o \ - policy_gram.o policy_lex.o authz_policy.o + policy_gram.o policy_lex.o authz_policy.o crypto.o gsoap_version ?= ${gsoap_default_version} @@ -214,7 +214,7 @@ endif INDEX_OBJS:= index.o index_parse.o jobstat_supp.o openserver.o \ jobstat.o query.o get_events.o write2rgma.o index_lex.o \ lb_authz.o store.o bkindex.o stats.o\ - request.o db_store.o srv_purge.o notif_match.o il_lbproxy.o dump.o lb_xml_parse.o il_notification.o lb_proto.o lb_text.o server_state.o lb_xml_parse_V21.o lb_html.o cond_dump.o notification.o seqcode.o userjobs.o load.o db_calls.o db_supp.o lb_rss.o pretty_print_wrapper.o authz_policy.o + request.o db_store.o srv_purge.o notif_match.o il_lbproxy.o dump.o lb_xml_parse.o il_notification.o lb_proto.o lb_text.o server_state.o lb_xml_parse_V21.o lb_html.o cond_dump.o notification.o seqcode.o userjobs.o load.o db_calls.o db_supp.o lb_rss.o pretty_print_wrapper.o authz_policy.o crypto.o INDEX_LIBS:= ${SRVBONES_LIB} ${COMMON_LIBS} ${LB_MACHINE_LIB} ${EXT_LIBS} ${LB_UTILS_DB_LIB} @@ -234,7 +234,8 @@ LIB_OBJS_BK:= \ openserver.o query.o userjobs.o db_store.o request.o store.o \ stored_master.o srv_purge.o server_state.o dump.o lb_authz.o load.o \ notification.o il_notification.o notif_match.o stats.o write2rgma.o \ - db_calls.o db_supp.o lb_rss.o pretty_print_wrapper.o authz_policy.o + db_calls.o db_supp.o lb_rss.o pretty_print_wrapper.o authz_policy.o \ + crypto.o MONDB_OBJS:=mon-db.o ${LIB_OBJS_BK} MONDB_LIBS:=${COMMON_LIBS} ${LB_MACHINE_LIB} ${LB_UTILS_DB_LIB} ${EXT_LIBS} diff --git a/org.glite.lb.server/interface/lb_authz.h b/org.glite.lb.server/interface/lb_authz.h index 9295d0c..8da9f42 100644 --- a/org.glite.lb.server/interface/lb_authz.h +++ b/org.glite.lb.server/interface/lb_authz.h @@ -97,6 +97,14 @@ edg_wll_get_fqans(edg_wll_Context ctx, struct vomsdata *voms_info, int edg_wll_acl_print(edg_wll_Context ctx, edg_wll_Acl a, char **policy); +int +check_jobstat_authz(edg_wll_Context ctx, + const edg_wll_JobStat *stat, + int job_flags, + edg_wll_Acl acl, + struct _edg_wll_GssPrincipal_data *peer, + int *authz_flags); + #ifdef __cplusplus } #endif diff --git a/org.glite.lb.server/src/authz_policy.c b/org.glite.lb.server/src/authz_policy.c index 0343cbb..16c7d2a 100644 --- a/org.glite.lb.server/src/authz_policy.c +++ b/org.glite.lb.server/src/authz_policy.c @@ -17,11 +17,14 @@ limitations under the License. #include #include +#include #include #include #include "authz_policy.h" +#include "server_state.h" +#include "crypto.h" struct action_name action_names[] = { { ADMIN_ACCESS, "ADMIN_ACCESS" }, @@ -34,6 +37,7 @@ struct action_name action_names[] = { { READ_ALL, "READ_ALL" }, { PURGE, "PURGE" }, { GRANT_OWNERSHIP, "GRANT_OWNERSHIP" }, + { READ_ANONYMIZED, "READ_ANONYMIZED" }, }; static int num_actions = @@ -201,3 +205,47 @@ blacken_fields(edg_wll_JobStat *stat, int flags) edg_wll_FreeStatus(&new_stat); return 0; } + +int +anonymize_stat(edg_wll_Context ctx, edg_wll_JobStat *stat) +{ + char *salt = NULL, *hash; + int ret; + + ret = edg_wll_GetServerState(ctx, EDG_WLL_STATE_ANONYMIZATION_SALT, &salt); + switch (ret) { + case ENOENT: + edg_wll_ResetError(ctx); + ret = generate_salt(ctx, &salt); + if (ret) + break; + ret = edg_wll_SetServerState(ctx, EDG_WLL_STATE_ANONYMIZATION_SALT, salt); + break; + default: + break; + } + if (ret) + goto end; + + ret = sha256_salt(ctx, stat->owner, salt, &hash); + if (ret) + goto end; + free(stat->owner); + stat->owner = hash; + + if (stat->payload_owner) { + ret = sha256_salt(ctx, stat->payload_owner, salt, &hash); + if (ret) + goto end; + free(stat->payload_owner); + stat->payload_owner = hash; + } + + ret = 0; + +end: + if (salt) + free(salt); + + return ret; +} diff --git a/org.glite.lb.server/src/authz_policy.h b/org.glite.lb.server/src/authz_policy.h index 2f93e92..c1b035d 100644 --- a/org.glite.lb.server/src/authz_policy.h +++ b/org.glite.lb.server/src/authz_policy.h @@ -34,6 +34,7 @@ typedef enum { READ_ALL = 1 << 7, PURGE = 1 << 8, GRANT_OWNERSHIP = 1 << 9, + READ_ANONYMIZED = 1 << 10, } authz_action; typedef struct action_name { @@ -70,4 +71,7 @@ find_authz_attr(const char *name); int blacken_fields(edg_wll_JobStat *, int flags); +int +anonymize_stat(edg_wll_Context, edg_wll_JobStat *); + #endif diff --git a/org.glite.lb.server/src/crypto.c b/org.glite.lb.server/src/crypto.c new file mode 100644 index 0000000..34d2cc7 --- /dev/null +++ b/org.glite.lb.server/src/crypto.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "crypto.h" + +int +sha256_salt(edg_wll_Context ctx, const char *string, + const char *salt, char **hash) +{ + SHA256_CTX context; + unsigned char md[SHA256_DIGEST_LENGTH]; + char output[SHA256_DIGEST_LENGTH+1]; + char *input; + int ret, i; + + SSL_library_init(); + OpenSSL_add_all_algorithms(); + + ret = asprintf(&input, "%s%s", string, salt); + if (ret < 0) + return edg_wll_SetError(ctx, ENOMEM, "Computing hash"); + + SHA256_Init(&context); + SHA256_Update(&context, input, strlen(input)); + SHA256_Final(md, &context); + free(input); + + for (i=0; i < SHA256_DIGEST_LENGTH; i++) + sprintf(output + i*2, "%02x", md[i]); + output[SHA256_DIGEST_LENGTH*2] = '\0'; + + *hash = strdup(output); + if (*hash == NULL) + return edg_wll_SetError(ctx, ENOMEM, "Computing hash"); + + return 0; +} + +int +generate_salt(edg_wll_Context ctx, char **new_salt) +{ + int ret, i; + unsigned char rand_bytes[16]; + char salt[sizeof(rand_bytes)*2 + 1]; + + ret = RAND_bytes(rand_bytes, sizeof(rand_bytes)); + if (ret != 1) { + glite_common_log_msg(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_ERROR, + "Failed to generate random seed"); + return edg_wll_SetError(ctx,EINVAL,"Anonymization failed"); + } + + for (i = 0; i < sizeof(rand_bytes); i++) + sprintf(salt + i*2, "%02x", rand_bytes[i]); + salt[sizeof(salt) - 1] = '\0'; + + *new_salt = strdup(salt); + if (*new_salt == NULL) + return edg_wll_SetError(ctx,ENOMEM,NULL); + + return 0; +} diff --git a/org.glite.lb.server/src/crypto.h b/org.glite.lb.server/src/crypto.h new file mode 100644 index 0000000..c4f16b9 --- /dev/null +++ b/org.glite.lb.server/src/crypto.h @@ -0,0 +1,13 @@ +#ifndef GLITE_LB_CRYPTO_H +#define GLITE_LB_CRYPTO_H + +#include + +int +sha256_salt(edg_wll_Context ctx, const char *string, + const char *salt, char **hash); + +int +generate_salt(edg_wll_Context ctx, char **new_salt); + +#endif diff --git a/org.glite.lb.server/src/il_notification.c b/org.glite.lb.server/src/il_notification.c index 5995c95..fc82346 100644 --- a/org.glite.lb.server/src/il_notification.c +++ b/org.glite.lb.server/src/il_notification.c @@ -187,7 +187,6 @@ edg_wll_NotifJobStatus(edg_wll_Context context, const char *dest_url, const char *owner, int flags, - int authz_flags, int expires, const edg_wll_JobStat notif_job_stat) { @@ -202,9 +201,18 @@ edg_wll_NotifJobStatus(edg_wll_Context context, stat.condor_jdl = NULL; stat.rsl = NULL; } - if (authz_flags) - blacken_fields(&stat, authz_flags); + ret = edg_wll_NotifCheckAuthz(context, &stat, flags, owner); + if (ret != 1) { + char *ju; + glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, + "[%d] authorization failed when sending notification for job %s", + getpid(), + ju = glite_jobid_getUnique(stat.jobId)); + free(ju); + return edg_wll_SetError(context, EPERM, NULL); + } + if(edg_wll_JobStatusToXML(context, stat, &xml_data)) goto out; diff --git a/org.glite.lb.server/src/il_notification.h b/org.glite.lb.server/src/il_notification.h index 5490193..4afe090 100644 --- a/org.glite.lb.server/src/il_notification.h +++ b/org.glite.lb.server/src/il_notification.h @@ -84,7 +84,6 @@ edg_wll_NotifJobStatus(edg_wll_Context context, const char *dest_url, const char *owner, int flags, - int authz_flags, int expires, const edg_wll_JobStat notif_job_stat); @@ -120,7 +119,7 @@ int edg_wll_NotifMatch(edg_wll_Context context, const edg_wll_JobStat *oldstat, /** * Check permissions on job status. */ -int edg_wll_NotifCheckACL(edg_wll_Context ctx,const edg_wll_JobStat *stat,const char *recip, int *authz_flags); +int edg_wll_NotifCheckAuthz(edg_wll_Context ctx,edg_wll_JobStat *stat,int flags,const char *recip); #ifdef __cplusplus } diff --git a/org.glite.lb.server/src/jobstat.c b/org.glite.lb.server/src/jobstat.c index 1f01e6a..13c5c70 100644 --- a/org.glite.lb.server/src/jobstat.c +++ b/org.glite.lb.server/src/jobstat.c @@ -89,38 +89,6 @@ static char* matched_substr(char *in, regmatch_t match) return s; } -static int -check_jobstat_authz(edg_wll_Context ctx, - edg_wll_JobStat *stat, - edg_wll_Acl acl, - int *flags) -{ - struct _edg_wll_GssPrincipal_data princ; - - *flags = 0; - - if (ctx->noAuth) - return 1; - if (ctx->peerName == NULL) - return 0; - if (edg_wll_gss_equal_subj(ctx->peerName, stat->owner)) - return 1; - if (stat->payload_owner && edg_wll_gss_equal_subj(ctx->peerName, stat->payload_owner)) - return 1; - if (acl && edg_wll_CheckACL(ctx, acl, EDG_WLL_CHANGEACL_READ) == 0) - return 1; - edg_wll_ResetError(ctx); - princ.name = ctx->peerName; - princ.fqans = ctx->fqans; - if (check_authz_policy(&ctx->authz_policy, &princ, READ_ALL)) - return 1; - if (check_authz_policy(&ctx->authz_policy, &princ, STATUS_FOR_MONITORING)) { - *flags |= STATUS_FOR_MONITORING; - return 1; - } - return 0; -} - int edg_wll_JobStatusServer( edg_wll_Context ctx, glite_jobid_const_t job, @@ -145,7 +113,7 @@ int edg_wll_JobStatusServer( glite_lbu_Statement sh = NULL; int num_sub, num_f, i, ii; int authz_flags = 0; - + struct _edg_wll_GssPrincipal_data peer; edg_wll_ResetError(ctx); @@ -175,7 +143,11 @@ int edg_wll_JobStatusServer( if (edg_wll_GetACL(ctx, job, &acl)) goto rollback; - if (check_jobstat_authz(ctx, stat, acl, &authz_flags) == 0) { + + memset(&peer, 0, sizeof(peer)); + peer.name = ctx->peerName; + peer.fqans = ctx->fqans; + if (check_jobstat_authz(ctx, stat, flags, acl, &peer, &authz_flags) == 0) { edg_wll_SetError(ctx, EPERM, "not owner"); goto rollback; } @@ -425,9 +397,12 @@ rollback: free(string_jobid); free(md5_jobid); - if (authz_flags) + if (authz_flags & STATUS_FOR_MONITORING) blacken_fields(stat, authz_flags); + if (authz_flags & READ_ANONYMIZED) + anonymize_stat(ctx, stat); + return edg_wll_Error(ctx, NULL, NULL); } diff --git a/org.glite.lb.server/src/lb_authz.c b/org.glite.lb.server/src/lb_authz.c index b6130e2..6cc9981 100644 --- a/org.glite.lb.server/src/lb_authz.c +++ b/org.glite.lb.server/src/lb_authz.c @@ -1170,3 +1170,42 @@ end: return ret; } + +int +check_jobstat_authz(edg_wll_Context ctx, + const edg_wll_JobStat *stat, + int job_flags, + edg_wll_Acl acl, + struct _edg_wll_GssPrincipal_data *peer, + int *authz_flags) +{ + *authz_flags = 0; + + if (peer == NULL || peer->name == NULL) + return 0; + + if (edg_wll_gss_equal_subj(peer->name, stat->owner)) + return 1; + if (stat->payload_owner && edg_wll_gss_equal_subj(peer->name, stat->payload_owner)) + return 1; + + if (job_flags & EDG_WLL_NOTIF_HISTORY || + check_authz_policy(&ctx->authz_policy, peer, READ_ANONYMIZED)) + *authz_flags |= READ_ANONYMIZED; + + if (ctx->noAuth || + edg_wll_amIroot(peer->name, peer->fqans, &ctx->authz_policy)) + return 1; + if (acl && edg_wll_CheckACL_princ(ctx, acl, EDG_WLL_CHANGEACL_READ, peer) == 0) + return 1; + edg_wll_ResetError(ctx); + + if (check_authz_policy(&ctx->authz_policy, peer, READ_ALL)) + return 1; + if (check_authz_policy(&ctx->authz_policy, peer, STATUS_FOR_MONITORING)) { + *authz_flags |= STATUS_FOR_MONITORING; + return 1; + } + + return 0; +} diff --git a/org.glite.lb.server/src/notif_match.c b/org.glite.lb.server/src/notif_match.c index da19988..b99820e 100644 --- a/org.glite.lb.server/src/notif_match.c +++ b/org.glite.lb.server/src/notif_match.c @@ -49,7 +49,7 @@ int edg_wll_NotifMatch(edg_wll_Context ctx, const edg_wll_JobStat *oldstat, cons edg_wll_NotifId nid = NULL; char *jobq,*ju = NULL,*jobc[6]; glite_lbu_Statement jobs = NULL; - int ret,flags,authz_flags = 0; + int ret,flags; size_t i; time_t expires,now = time(NULL); @@ -121,8 +121,7 @@ int edg_wll_NotifMatch(edg_wll_Context ctx, const edg_wll_JobStat *oldstat, cons glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, "[%d] NOTIFY:%s expired at %s UTC", getpid(),jobc[0],asctime(gmtime(&expires))); } - else if (notif_match_conditions(ctx,oldstat,&newstat,jobc[4],flags) && - edg_wll_NotifCheckACL(ctx,&newstat,jobc[3], &authz_flags)) + else if (notif_match_conditions(ctx,oldstat,&newstat,jobc[4],flags)) { char *errt, *errd; char *dest; @@ -152,7 +151,7 @@ int edg_wll_NotifMatch(edg_wll_Context ctx, const edg_wll_JobStat *oldstat, cons /* XXX: only temporary hack!!! */ ctx->p_instance = strdup(""); - if ( edg_wll_NotifJobStatus(ctx, nid, dest, jobc[3], atoi(jobc[5]), authz_flags, expires, newstat) ) + if ( edg_wll_NotifJobStatus(ctx, nid, dest, jobc[3], atoi(jobc[5]), expires, newstat) ) { for (i=0; iowner,recip) == 0 - || edg_wll_amIroot(recip,NULL,&ctx->authz_policy)) return 1; - if (stat->payload_owner && strcmp(stat->payload_owner,recip) == 0) - return 1; princ.name = (char *)recip; - if (check_authz_policy(&ctx->authz_policy, &princ, READ_ALL)) - return 1; if (stat->acl) { acl = calloc(1,sizeof *acl); ret = edg_wll_DecodeACL(stat->acl,&acl->value); if (ret) { - edg_wll_FreeAcl(acl); - edg_wll_SetError(ctx,EINVAL,"decoding ACL"); - return 0; + free(acl); + acl = NULL; } + } - acl->string = stat->acl; - ret = edg_wll_CheckACL(ctx, acl, EDG_WLL_CHANGEACL_READ); - acl->string = NULL; + ret = check_jobstat_authz(ctx, stat, flags, acl, &princ, &authz_flags); + if (acl) edg_wll_FreeAcl(acl); - if (ret == 0) - return 1; - edg_wll_ResetError(ctx); - } + if (ret != 1) + return ret; - if (check_authz_policy(&ctx->authz_policy, &princ, STATUS_FOR_MONITORING)) { - *authz_flags |= STATUS_FOR_MONITORING; - return 1; - } + if (authz_flags & STATUS_FOR_MONITORING) + blacken_fields(stat, authz_flags); + if (authz_flags & READ_ANONYMIZED) + anonymize_stat(ctx, stat); - return 0; + return ret; } diff --git a/org.glite.lb.server/src/notification.c b/org.glite.lb.server/src/notification.c index 21e5236..299b35a 100644 --- a/org.glite.lb.server/src/notification.c +++ b/org.glite.lb.server/src/notification.c @@ -1001,7 +1001,6 @@ static int notif_streaming_event_cb(edg_wll_Context ctx, glite_jobid_t jobid, ed const char *owner; int flags; time_t expire; - int authz_flags; size_t i; char *ju; char *row[4] = {}; @@ -1023,19 +1022,12 @@ static int notif_streaming_event_cb(edg_wll_Context ctx, glite_jobid_t jobid, ed flags = atoi(row[2]); owner = row[3]; - if (!edg_wll_NotifCheckACL(ctx, (const edg_wll_JobStat *)stat, owner, &authz_flags)) { - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "[%d] NOTIFY stream: %s, authorization failed, job %s", getpid(), lctx->nid_s, ju = glite_jobid_getUnique(stat->jobId)); - free(ju); ju = NULL; - edg_wll_ResetError(ctx); - goto cleanup; - } - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "[%d] NOTIFY stream: %s, job %s, destination '%s'", getpid(), lctx->nid_s, ju = glite_jobid_getUnique(stat->jobId), row[0]); free(ju); ju = NULL; dest = strdup(row[0]); /*XXX: ??? copied from notif_match.c */ free(ctx->p_instance); ctx->p_instance = strdup(""); - if (edg_wll_NotifJobStatus(ctx, lctx->nid, dest, owner, flags, authz_flags, expire, (const edg_wll_JobStat)(*stat)) != 0) { + if (edg_wll_NotifJobStatus(ctx, lctx->nid, dest, owner, flags, expire, (const edg_wll_JobStat)(*stat)) != 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_ERROR, "[%d] NOTIFY stream: %s, error", getpid(), lctx->nid_s); goto cleanup; } diff --git a/org.glite.lb.server/src/server_state.h b/org.glite.lb.server/src/server_state.h index 25b3db1..d50b342 100644 --- a/org.glite.lb.server/src/server_state.h +++ b/org.glite.lb.server/src/server_state.h @@ -22,6 +22,7 @@ limitations under the License. #define EDG_WLL_STATE_DUMP_START "StartDump" #define EDG_WLL_STATE_DUMP_END "EndDump" +#define EDG_WLL_STATE_ANONYMIZATION_SALT "AnonymizationSalt" int edg_wll_GetServerState(edg_wll_Context,const char *,char **); int edg_wll_SetServerState(edg_wll_Context,const char *,const char *);