int edg_wll_SetErrorGss(edg_wll_Context ctx, const char *desc, edg_wll_GssStatus *gss_code) { char *err_msg; edg_wll_gss_get_error(gss_code, desc, &err_msg); edg_wll_SetError(ctx,EDG_WLL_ERROR_GSS, err_msg); free(err_msg); return ctx->errCode; }
static int gss_reader(void *user_data, char *buffer, int max_len) { int ret; size_t len; struct reader_data *data = (struct reader_data *)user_data; edg_wll_GssStatus gss_stat; ret = edg_wll_gss_read_full(data->gss, buffer, max_len, data->timeout, &len, &gss_stat); if(ret < 0) { char *gss_err = NULL; if(ret == EDG_WLL_GSS_ERROR_GSS) { edg_wll_gss_get_error(&gss_stat, "get_reply", &gss_err); set_error(IL_DGGSS, ret, gss_err); free(gss_err); } else set_error(IL_DGGSS, ret, "get_reply"); } return(ret); }
static int refresh_gsoap(glite_jpis_context_t ctx, struct soap *soap) { edg_wll_GssCred cred; edg_wll_GssStatus gss_code; char *et; // preventive very long timeout static const struct timeval to = {tv_sec: 7200, tv_usec: 0}; glite_gsplugin_Context plugin_ctx; if (edg_wll_gss_acquire_cred_gsi(ctx->conf->server_cert, ctx->conf->server_key, &cred, &gss_code) != 0) { edg_wll_gss_get_error(&gss_code,"",&et); glite_jpis_stack_error(ctx->jpctx, EINVAL, "can't refresh certificates (%s)", et); free(et); return EINVAL; //printf("[%d] %s: %s\n", getpid(), __FUNCTION__, err.desc); } plugin_ctx = glite_gsplugin_get_context(soap); glite_gsplugin_set_timeout(plugin_ctx, &to); glite_gsplugin_use_credential(plugin_ctx, cred); return 0; }
/* *---------------------------------------------------------------------- * * handle_gss_failures - handle GSS failures on the server side * * Returns: errno * *---------------------------------------------------------------------- */ static int handle_gss_failures(int code, edg_wll_GssStatus *gss_code, const char *text) { const char *func = "edg_wll_log_proto_server()"; int ret = 0; if(code>0) { return(0); } switch(code) { case EDG_WLL_GSS_ERROR_EOF: glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: %s, EOF occured\n", func, text); ret = EAGAIN; break; case EDG_WLL_GSS_ERROR_TIMEOUT: glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: %s, timeout expired\n", func, text); ret = EAGAIN; break; case EDG_WLL_GSS_ERROR_ERRNO: glite_common_log_SYS_ERROR(func); glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: %s, system error occured\n", func, text); ret = EAGAIN; break; case EDG_WLL_GSS_ERROR_GSS: { char *gss_err; edg_wll_gss_get_error(gss_code, "GSS error occured", &gss_err); glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: %s, %s\n", func, text, gss_err); free(gss_err); ret = EAGAIN; break; } default: glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_ERROR,"%s: %s, unknown error occured\n", func, text); break; } return ret; }
/* *---------------------------------------------------------------------- * * doit - do all the dirty work * *---------------------------------------------------------------------- */ static int doit(int socket, edg_wll_GssCred cred_handle, char *file_name_prefix, int noipc, int noparse) { char *subject; int ret,fd,count; struct timeval timeout; edg_wll_GssConnection con; edg_wll_GssStatus gss_stat; edg_wll_GssPrincipal client = NULL; fd_set fdset; struct sockaddr_storage peer; socklen_t alen = sizeof peer; char peerhost[64], peerserv[16]; ret = count = 0; FD_ZERO(&fdset); /* accept */ timeout.tv_sec = ACCEPT_TIMEOUT; timeout.tv_usec = 0; getpeername(socket,(struct sockaddr *) &peer,&alen); glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Accepting connection (remaining timeout %d.%06d sec)\n", (int)timeout.tv_sec, (int) timeout.tv_usec); ret = getnameinfo ((struct sockaddr *) &peer, alen, peerhost, sizeof(peerhost), peerserv, sizeof(peerserv), NI_NUMERICHOST | NI_NUMERICSERV); if (ret) { glite_common_log(LOG_CATEGORY_ACCESS, LOG_PRIORITY_WARN, "getnameinfo: %s", gai_strerror (ret)); strcpy(peerhost, "unknown"); strcpy(peerserv, "unknown"); } /* XXX: ugly workaround, we may detect false expired certificated * probably due to bug in Globus GSS/SSL. */ #define _EXPIRED_CERTIFICATE_MESSAGE "certificate has expired" if ((ret = edg_wll_gss_accept(cred_handle,socket,&timeout,&con, &gss_stat)) < 0) { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_DEBUG,"timeout after gss_accept is %d.%06d sec\n", (int)timeout.tv_sec, (int) timeout.tv_usec); if ( ret == EDG_WLL_GSS_ERROR_TIMEOUT ) { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: Client authentication failed - timeout reached, closing.\n",peerhost); } else if (ret == EDG_WLL_GSS_ERROR_GSS) { char *gss_err; edg_wll_gss_get_error(&gss_stat, "Client authentication failed", &gss_err); if (strstr(gss_err,_EXPIRED_CERTIFICATE_MESSAGE)) { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: false expired certificate: %s\n",peerhost,gss_err); free(gss_err); return -1; } glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: GSS error: %s, closing.\n",peerhost,gss_err); free(gss_err); } else { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: Client authentication failed, closing.\n",peerhost); } return 1; } /* authenticate */ glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_DEBUG,"Processing authentication:\n"); ret = edg_wll_gss_get_client_conn(&con, &client, &gss_stat); if (ret) { char *gss_err; edg_wll_gss_get_error(&gss_stat, "Cannot read client identification", &gss_err); glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN, "%s: %s\n", peerhost,gss_err); free(gss_err); } if (ret || client->flags & EDG_WLL_GSS_FLAG_ANON) { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN," User not authenticated, setting as \"%s\". \n",EDG_WLL_LOG_USER_DEFAULT); subject=strdup(EDG_WLL_LOG_USER_DEFAULT); } else { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_INFO," User successfully authenticated as: %s\n",client->name); subject=strdup(client->name); } if (client) edg_wll_gss_free_princ(client); /* get and process the data */ timeout.tv_sec = CONNECTION_TIMEOUT; timeout.tv_usec = 0; while (timeout.tv_sec > 0) { count++; glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Waiting for data delivery no. %d (remaining timeout %d.%06d sec)\n", count, (int)timeout.tv_sec, (int) timeout.tv_usec); FD_SET(con.sock,&fdset); fd = select(con.sock+1,&fdset,NULL,NULL,&timeout); switch (fd) { case 0: /* timeout */ glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Connection timeout expired\n"); timeout.tv_sec = 0; break; case -1: /* error */ switch(errno) { case EINTR: glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"XXX: Waking up (remaining timeout %d.%06d sec)\n", (int)timeout.tv_sec, (int) timeout.tv_usec); continue; default: glite_common_log_SYS_ERROR("select"); timeout.tv_sec = 0; break; } break; default: glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Waking up (remaining timeout %d.%06d sec)\n", (int)timeout.tv_sec, (int) timeout.tv_usec); break; } if (FD_ISSET(con.sock,&fdset)) { ret = edg_wll_log_proto_server(&con,&timeout,subject,file_name_prefix,noipc,noparse); // TODO: put into edg_wll_log_proto_server? if (ret != 0) { glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"timeout after edg_wll_log_proto_server is %d.%06d sec\n", (int)timeout.tv_sec, (int) timeout.tv_usec); if (ret != EDG_WLL_GSS_ERROR_EOF) glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"edg_wll_log_proto_server(): Error\n"); else if (count == 1) glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"edg_wll_log_proto_server(): Error. EOF occured.\n"); timeout.tv_sec = 0; timeout.tv_usec = 0; break; } else { timeout.tv_sec = CONNECTION_TIMEOUT; timeout.tv_usec = 0; } } } glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG, "Closing descriptor %d.",con.sock); edg_wll_gss_close(&con, NULL); if (subject) free(subject); return ret; }
/* * Returns: 0 - not connected, timeout set, 1 - OK */ int event_queue_connect(struct event_queue *eq, struct queue_thread *me) { int ret; struct timeval tv; edg_wll_GssStatus gss_stat; cred_handle_t *local_cred_handle; assert(eq != NULL); assert(me != NULL); #ifdef LB_PERF if(!nosend) { #endif if(me->gss.context == NULL) { tv.tv_sec = TIMEOUT; tv.tv_usec = 0; /* get pointer to the credentials */ if(pthread_mutex_lock(&cred_handle_lock) < 0) abort(); local_cred_handle = cred_handle; local_cred_handle->counter++; if(pthread_mutex_unlock(&cred_handle_lock) < 0) abort(); glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, " trying to connect to %s:%d", eq->dest_name, eq->dest_port); #if defined(IL_NOTIFICATIONS) ret = edg_wll_gss_connect_name(local_cred_handle->creds, eq->dest_name, eq->dest_port, eq->owner, /* mech */NULL, &tv, &me->gss, &gss_stat); #else ret = edg_wll_gss_connect(local_cred_handle->creds, eq->dest_name, eq->dest_port, &tv, &me->gss, &gss_stat); #endif if(pthread_mutex_lock(&cred_handle_lock) < 0) abort(); /* check if we need to release the credentials */ --local_cred_handle->counter; if(local_cred_handle != cred_handle && local_cred_handle->counter == 0) { edg_wll_gss_release_cred(&local_cred_handle->creds, NULL); free(local_cred_handle); glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, " freed credentials, not used anymore"); } if(pthread_mutex_unlock(&cred_handle_lock) < 0) abort(); if(ret < 0) { char *gss_err = NULL; if (ret == EDG_WLL_GSS_ERROR_GSS) edg_wll_gss_get_error(&gss_stat, "event_queue_connect: edg_wll_gss_connect", &gss_err); set_error(IL_DGGSS, ret, (ret == EDG_WLL_GSS_ERROR_GSS) ? gss_err : "event_queue_connect: edg_wll_gss_connect"); if (gss_err) free(gss_err); me->gss.context = NULL; me->timeout = TIMEOUT; return(0); } me->first_event_sent = 0; } #ifdef LB_PERF } #endif eq->last_connected = time(NULL); return(1); }
int main (int argc, char **argv) { int i; char *p; edg_wll_GssStatus gss_stat; int ret; FILE *pidf; #ifndef IL_NOTIFICATIONS p = strdup(argv[0]); program_name = basename(p); if (strcmp(program_name, "glite-lb-proxy-interlogd") == 0) { file_prefix = DEFAULT_PROXY_PREFIX; socket_path = DEFAULT_PROXY_SOCKET; pidfile = DEFAULT_PROXY_PIDFILE; } free(p); #endif program_name = argv[0]; setlinebuf(stdout); setlinebuf(stderr); if ((p = getenv("EDG_WL_INTERLOG_TIMEOUT"))) TIMEOUT = atoi(p); i = decode_switches (argc, argv); if(glite_common_log_init()) { fprintf(stderr, "glite_common_log_init() failed, exiting.\n"); exit(EXIT_FAILURE); } /* parse config file, if any */ if(conf_file != NULL) { config = load_conf_file(conf_file); } /* check for reasonable queue lengths */ if((queue_size_low == 0 && queue_size_high > 0) || (queue_size_low > queue_size_high)) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "max queue length -Q must be greater than low queue length -q, both or none must be specified!"); exit(EXIT_FAILURE); } /* force -b if we do not have log server */ if(log_server == NULL) { log_server = strdup(DEFAULT_LOG_SERVER); bs_only = 1; } /* initialize error reporting */ if(init_errors()) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to initialize error message subsystem. Exiting."); exit(EXIT_FAILURE); } if (signal(SIGPIPE, SIG_IGN) == SIG_ERR || signal(SIGABRT, handle_signal) == SIG_ERR || signal(SIGTERM, handle_signal) == SIG_ERR || signal(SIGINT, handle_signal) == SIG_ERR) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to setup signal handlers: %s, exiting.", strerror(errno)); exit(EXIT_FAILURE); } /* just try it before deamonizing to be able to complain aloud */ if (!(pidf = fopen(pidfile,"w"))) { perror(pidfile); exit(EXIT_FAILURE); } fclose(pidf); if(!debug && (daemon(0,0) < 0)) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to daemonize itself: %s, exiting.", strerror(errno)); exit(EXIT_FAILURE); } pidf = fopen(pidfile,"w"); assert(pidf); /* XXX */ fprintf(pidf,"%d\n",getpid()); fclose(pidf); umask(S_IRWXG | S_IRWXO); #ifdef LB_PERF /* this must be called after installing signal handlers */ glite_wll_perftest_init(NULL, /* host */ NULL, /* user */ NULL, /* test name */ event_source, njobs); #endif if(input_queue_attach() < 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to initialize input queue: %s", error_get_msg()); exit(EXIT_FAILURE); } glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Initialized input queue."); /* initialize output queues */ if(queue_list_init(log_server) < 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to initialize output event queues: %s", error_get_msg()); exit(EXIT_FAILURE); } glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Initialized event queues."); if(lazy_close) glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, " using lazy mode when closing connections, timeout %d", default_close_timeout); /* get credentials */ if (CAcert_dir) setenv("X509_CERT_DIR", CAcert_dir, 1); if(edg_wll_gss_initialize()) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to initialize GSS."); exit(EXIT_FAILURE); } ret = edg_wll_gss_watch_creds(cert_file,&cert_mtime); if (ret < 0) glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n"); cred_handle = malloc(sizeof(*cred_handle)); if(cred_handle == NULL) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to allocate structure for credentials."); exit(EXIT_FAILURE); } cred_handle->creds = NULL; cred_handle->counter = 0; ret = edg_wll_gss_acquire_cred(cert_file, key_file, GSS_C_INITIATE, &cred_handle->creds, &gss_stat); if (ret) { char *gss_err = NULL; if (ret == EDG_WLL_GSS_ERROR_GSS) edg_wll_gss_get_error(&gss_stat, "edg_wll_gss_acquire_cred_gsi()", &gss_err); glite_common_log(LOG_CATEGORY_SECURITY, LOG_PRIORITY_FATAL, "Failed to load GSI credential: %s", (gss_err) ? gss_err : "edg_wll_gss_acquire_cred_gsi() failed"); if (gss_err) free(gss_err); if(gss_stat.minor_status != 0) { exit(EXIT_FAILURE); } else { glite_common_log(LOG_CATEGORY_SECURITY, LOG_PRIORITY_WARN, "Continuing unauthenticated (yet)."); } } if(cred_handle && cred_handle->creds) { glite_common_log(LOG_CATEGORY_SECURITY, LOG_PRIORITY_INFO, "Using certificate %s", cred_handle->creds->name); } /* parse config, initialize plugins */ glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Initializing plugins:\n"); if(config) { char *s = strstr(config, "[interlogd]"); char *p; char name[MAXPATHLEN+1]; if(s) { /* next line */ s = strchr(s, '\n'); if(s) s++; while(s) { if(*s == 0 || *s == '[') break; /* parse line */ p = strchr(s, '\n'); if(p) { *p = 0; } /* XXX possible overflow by long line in config file */ ret = sscanf(s, " plugin =%s", name); if(p) *p = '\n'; if(ret > 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, " loading plugin %s\n", name); if(plugin_mgr_init(name, config) < 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_ERROR, "Failed to load plugin %s: %s\n", name, error_get_msg()); } } s = p + 1; } } } #ifndef PERF_EMPTY /* find all unsent events waiting in files */ #ifdef LB_PERF if(norecover) { if(event_store_init(file_prefix) < 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to initialize event stores: %s", error_get_msg()); exit(EXIT_FAILURE); } } else #endif { pthread_t rid; if(pthread_create(&rid, NULL, recover_thread, NULL) < 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Failed to start recovery thread: %s", strerror(errno)); exit(EXIT_FAILURE); } pthread_detach(rid); glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Started recovery thread."); } #endif glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Using %d threads for parallel delivery.", parallel); glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Entering main loop."); /* do the work */ if(loop() < 0) { glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "Fatal error: %s", error_get_msg()); if (killflg) { input_queue_detach(); unlink(pidfile); exit(EXIT_FAILURE); } } glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Done!"); input_queue_detach(); unlink(pidfile); exit (0); }