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}
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}
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}
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
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <cclassad.h>
#include <glite/security/glite_gss.h>
#include "authz_policy.h"
+#include "server_state.h"
+#include "crypto.h"
struct action_name action_names[] = {
{ ADMIN_ACCESS, "ADMIN_ACCESS" },
{ READ_ALL, "READ_ALL" },
{ PURGE, "PURGE" },
{ GRANT_OWNERSHIP, "GRANT_OWNERSHIP" },
+ { READ_ANONYMIZED, "READ_ANONYMIZED" },
};
static int num_actions =
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;
+}
READ_ALL = 1 << 7,
PURGE = 1 << 8,
GRANT_OWNERSHIP = 1 << 9,
+ READ_ANONYMIZED = 1 << 10,
} authz_action;
typedef struct action_name {
int
blacken_fields(edg_wll_JobStat *, int flags);
+int
+anonymize_stat(edg_wll_Context, edg_wll_JobStat *);
+
#endif
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <openssl/sha.h>
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+
+#include <glite/lbu/log.h>
+#include <glite/lb/context-int.h>
+
+#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;
+}
--- /dev/null
+#ifndef GLITE_LB_CRYPTO_H
+#define GLITE_LB_CRYPTO_H
+
+#include <glite/lb/context.h>
+
+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
const char *dest_url,
const char *owner,
int flags,
- int authz_flags,
int expires,
const edg_wll_JobStat notif_job_stat)
{
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;
const char *dest_url,
const char *owner,
int flags,
- int authz_flags,
int expires,
const edg_wll_JobStat notif_job_stat);
/**
* 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
}
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,
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);
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;
}
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);
}
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;
+}
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);
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;
/* 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; i<sizeof(jobc)/sizeof(jobc[0]); i++) free(jobc[i]);
goto err;
* effective VOMS groups of the recipient are not available here, should be
* probably stored along with the registration.
*/
-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)
{
int ret;
struct _edg_wll_GssPrincipal_data princ;
edg_wll_Acl acl = NULL;
+ int authz_flags = 0;
memset(&princ, 0, sizeof(princ));
- *authz_flags = 0;
-
- edg_wll_ResetError(ctx);
- if (strcmp(stat->owner,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;
}
const char *owner;
int flags;
time_t expire;
- int authz_flags;
size_t i;
char *ju;
char *row[4] = {};
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;
}
#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 *);