Ejemplo n.º 1
0
/*
    returns -1 for error, else file descriptor for listener
*/
int get_listener_fd() {
    launch_data_t checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN);
    if (!checkin_request) {
        syslog(LOG_NOTICE, "Unable to create checkin string!");
        return -1;
    }
    launch_data_t checkin_response = launch_msg(checkin_request);
    if (!checkin_response) {
        syslog(LOG_NOTICE, "Unable to do checkin!");
        return -1;
    }
    if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
        errno = launch_data_get_errno(checkin_response);
        syslog(LOG_NOTICE, "Error %d getting type of checkin response!", errno);
        return -1;
    }
    launch_data_t the_label = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL);
    if (!the_label) {
        syslog(LOG_NOTICE, "No Label for job!");
        return -1;
    }    
    launch_data_t sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (!sockets_dict) {
        syslog(LOG_NOTICE, "No socket found to answer requests on!");
        return -1;
    }
    size_t count = launch_data_dict_get_count(sockets_dict);
    if (count < 1) {
        syslog(LOG_NOTICE, "No socket found to answer requests on!");
        return -1;
    }
    if (1 < count) {
        syslog(LOG_NOTICE, "Some socket(s) will be ignored!");
    }
    launch_data_t listening_fd_array = launch_data_dict_lookup(sockets_dict, "MasterSocket");
    if (!listening_fd_array) {
        syslog(LOG_NOTICE, "MasterSocket not found!");
        return -1;
    }
    count = launch_data_array_get_count(listening_fd_array);
    if (count < 1) {
        syslog(LOG_NOTICE, "No socket found to answer requests on!");
        return -1;
    }
    if (1 < count) {
        syslog(LOG_NOTICE, "Some socket(s) will be ignored!");
    }
    launch_data_t this_listening_fd = launch_data_array_get_index(listening_fd_array, 0);
    int listener_fd = launch_data_get_fd(this_listening_fd);
    if ( listener_fd == -1 ) {
        syslog(LOG_NOTICE, "launch_data_get_fd() failed!");
        return -1;
    }
    if (listen(listener_fd, 5)) {
        syslog(LOG_NOTICE, "listen() failed with %i", errno);
        return -1;
    }
    return listener_fd;
}
Ejemplo n.º 2
0
int                     
checklaunchd()                  
{               
	launch_data_t checkin_response = NULL; 
#ifdef LION_TEST
    launch_data_t checkin_request = NULL;
#endif
	launch_data_t sockets_dict, listening_fd_array;
	launch_data_t listening_fd;
	struct sockaddr_storage fdsockaddr;
	socklen_t fdsockaddrlen = sizeof(fdsockaddr);
	int socketct;
	int i;
	int listenerct;
	int returnval = 0;
	int fd;
	
	/* check in with launchd */
#ifdef LION_TEST
    if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
#else
	if ((checkin_response = launch_socket_service_check_in()) == NULL) {
#endif
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_socket_service_check_in.\n");
		goto done;
	}
#ifdef LION_TEST
    if ((checkin_response = launch_msg(checkin_request)) == NULL) {
        plog(ASL_LEVEL_ERR, "failed to launch_msg.\n");
        goto done;
    }
#endif
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
		plog(ASL_LEVEL_ERR, 
			 "launch_data_get_type error %d\n",
			 launch_data_get_errno(checkin_response));
		goto done;
	}
	if ( (sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS)) == NULL){
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_data_dict_lookup.\n");
		goto done;
	}
	if ( !(socketct = launch_data_dict_get_count(sockets_dict))){
		plog(ASL_LEVEL_ERR, 
			 "launch_data_dict_get_count returns no socket defined.\n");
		goto done;
	}
	
	if ( (listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners")) == NULL ){
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_data_dict_lookup.\n");
		goto done;
	}
	listenerct = launch_data_array_get_count(listening_fd_array);
	for (i = 0; i < listenerct; i++) {
		listening_fd = launch_data_array_get_index(listening_fd_array, i);
		fd = launch_data_get_fd( listening_fd );
		if ( getsockname( fd , (struct sockaddr *)&fdsockaddr, &fdsockaddrlen)){
			continue;
		}
		
		/* Is this the VPN control socket? */ 
		if ( fdsockaddr.ss_family == AF_UNIX && 
				(!(strcmp(vpncontrolsock_path, ((struct sockaddr_un *)&fdsockaddr)->sun_path))))
		{       
			plog(ASL_LEVEL_INFO, 
				 "found launchd socket.\n");
			returnval = fd;
			break;
		}
	}
	// TODO: check if we have any leaked fd
	if ( listenerct == i){
		plog(ASL_LEVEL_ERR, 
			 "failed to find launchd socket\n");               
		returnval = 0;
	}
	
done:   
	if (checkin_response)
		launch_data_free(checkin_response);
	return(returnval);
}

		
void
vpncontrol_handler(void *unused)
{
	struct sockaddr_storage from;
	socklen_t fromlen = sizeof(from);
    int sock;

	struct vpnctl_socket_elem *sock_elem;
	
    sock_elem = racoon_malloc(sizeof(struct vpnctl_socket_elem));
	if (sock_elem == NULL) {
		plog(ASL_LEVEL_ERR, 
			"memory error: %s\n", strerror(errno));
		return; //%%%%%% terminate
	}
	LIST_INIT(&sock_elem->bound_addresses);
    
	sock_elem->sock = accept(lcconf->sock_vpncontrol, (struct sockaddr *)&from, &fromlen);
	if (sock_elem->sock < 0) {
		plog(ASL_LEVEL_ERR, 
			"failed to accept vpn_control command: %s\n", strerror(errno));
		racoon_free(sock_elem);
		return; //%%%%% terminate
	}
	LIST_INSERT_HEAD(&lcconf->vpnctl_comm_socks, sock_elem, chain);
    
    sock_elem->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, sock_elem->sock, 0, dispatch_get_main_queue());
    if (sock_elem->source == NULL) {
		plog(ASL_LEVEL_ERR, "could not create comm socket source.");
		racoon_free(sock_elem);
		return; //%%%%% terminate
    }
    dispatch_source_set_event_handler(sock_elem->source, 
                                        ^{
                                                vpncontrol_comm_handler(sock_elem);
                                        });
    sock = sock_elem->sock;
	
    dispatch_source_t the_source = sock_elem->source;
    dispatch_source_set_cancel_handler(sock_elem->source,
                                       ^{
                                           close(sock);
                                           dispatch_release(the_source); /* Release the source on cancel */
                                       });
Ejemplo n.º 3
0
int
TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret, 
				   XtransConnInfo **ciptrs_ret)

{
    char		buffer[256]; /* ??? What size ?? */
    XtransConnInfo	ciptr, temp_ciptrs[NUMTRANS];
    int			status, i, j;
#ifdef HAVE_LAUNCHD
    int                 launchd_fd;
    launch_data_t       sockets_dict, checkin_request, checkin_response;
    launch_data_t       listening_fd_array, listening_fd;
#endif

#if defined(IPv6) && defined(AF_INET6)
    int		ipv6_succ = 0;
#endif
    PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n",
	   port ? port : "NULL", ciptrs_ret, 0);

    *count_ret = 0;

#ifdef HAVE_LAUNCHD
    /* Get launchd fd */
    if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
      fprintf(stderr,"launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string.\n");
	  goto not_launchd;
	  }

    if ((checkin_response = launch_msg(checkin_request)) == NULL) {
       fprintf(stderr,"launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n",strerror(errno));
	   goto not_launchd;
	}

    if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
      // ignore EACCES, which is common if we weren't started by launchd
      if (launch_data_get_errno(checkin_response) != EACCES)
       fprintf(stderr,"launchd check-in failed: %s\n",strerror(launch_data_get_errno(checkin_response)));
	   goto not_launchd;
	} 

	sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (NULL == sockets_dict) {
       fprintf(stderr,"launchd check-in: no sockets found to answer requests on!\n");
	   goto not_launchd;
	}

    if (launch_data_dict_get_count(sockets_dict) > 1) {
       fprintf(stderr,"launchd check-in: some sockets will be ignored!\n");
	   goto not_launchd;
	}

    listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0");
    if (NULL == listening_fd_array) {
       fprintf(stderr,"launchd check-in: No known sockets found to answer requests on!\n");
	   goto not_launchd;
	}

    if (launch_data_array_get_count(listening_fd_array)!=1) {
       fprintf(stderr,"launchd check-in: Expected 1 socket from launchd, got %d)\n",
                       launch_data_array_get_count(listening_fd_array));
	   goto not_launchd;
	}

    listening_fd=launch_data_array_get_index(listening_fd_array, 0);
    launchd_fd=launch_data_get_fd(listening_fd);
    fprintf(stderr,"Xquartz: run by launchd for fd %d\n",launchd_fd);
    if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
                                       launchd_fd, getenv("DISPLAY"))))==NULL)
        fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
        else temp_ciptrs[(*count_ret)++] = ciptr;

not_launchd:
#endif

    for (i = 0; i < NUMTRANS; i++)
    {
	Xtransport *trans = Xtransports[i].transport;
	unsigned int flags = 0;

	if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
	    continue;

	snprintf(buffer, sizeof(buffer), "%s/:%s",
		 trans->TransName, port ? port : "");

	PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n",
	       buffer, 0, 0);

	if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
	{
	    if (trans->flags & TRANS_DISABLED)
		continue;

	    PRMSG (1,
	  "MakeAllCOTSServerListeners: failed to open listener for %s\n",
		  trans->TransName, 0, 0);
	    continue;
	}
#if defined(IPv6) && defined(AF_INET6)
		if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
		     && ipv6_succ))
		    flags |= ADDR_IN_USE_ALLOWED;
#endif

	if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
	{
	    if (status == TRANS_ADDR_IN_USE)
	    {
		/*
		 * We failed to bind to the specified address because the
		 * address is in use.  It must be that a server is already
		 * running at this address, and this function should fail.
		 */

		PRMSG (1,
		"MakeAllCOTSServerListeners: server already running\n",
		  0, 0, 0);

		for (j = 0; j < *count_ret; j++)
		    TRANS(Close) (temp_ciptrs[j]);

		*count_ret = 0;
		*ciptrs_ret = NULL;
		*partial = 0;
		return -1;
	    }
	    else
	    {
		PRMSG (1,
	"MakeAllCOTSServerListeners: failed to create listener for %s\n",
		  trans->TransName, 0, 0);

		continue;
	    }
	}

#if defined(IPv6) && defined(AF_INET6)
	if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
	    ipv6_succ = 1;
#endif
	
	PRMSG (5,
	      "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
	      trans->TransName, ciptr->fd, 0);

	temp_ciptrs[*count_ret] = ciptr;
	(*count_ret)++;
    }

    *partial = (*count_ret < complete_network_count());

    PRMSG (5,
     "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
	*partial, *count_ret, complete_network_count());

    if (*count_ret > 0)
    {
	if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
	    *count_ret * sizeof (XtransConnInfo))) == NULL)
	{
	    return -1;
	}

	for (i = 0; i < *count_ret; i++)
	{
	    (*ciptrs_ret)[i] = temp_ciptrs[i];
	}
    }
    else
	*ciptrs_ret = NULL;
 
    return 0;
}