Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
0
/*
 *----------------------------------------------------------------------
 *
 * 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;
}
Пример #6
0
/*
 *  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);
}
Пример #7
0
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);
}