Пример #1
0
static mach_port_t checkin(char *service_name)
	{
	kern_return_t kr = KERN_SUCCESS;
	mach_port_t port = MACH_PORT_NULL;
	launch_data_t msg = NULL, reply = NULL, datum = NULL;

	if (NULL == (msg = launch_data_new_string(LAUNCH_KEY_CHECKIN)))
		{ helplog(ASL_LEVEL_ERR, "Could not create checkin message for launchd."); goto fin; }
	if (NULL == (reply = launch_msg(msg)))
		{ helplog(ASL_LEVEL_ERR, "Could not message launchd."); goto fin; }
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(reply))
		{
		if (launch_data_get_errno(reply) == EACCES) { launch_data_free(msg); launch_data_free(reply); return(MACH_PORT_NULL); }
		helplog(ASL_LEVEL_ERR, "Launchd checkin failed: %s.", strerror(launch_data_get_errno(reply))); goto fin;
		}
	if (NULL == (datum = launch_data_dict_lookup(reply, LAUNCH_JOBKEY_MACHSERVICES)) || LAUNCH_DATA_DICTIONARY != launch_data_get_type(datum))
		{ helplog(ASL_LEVEL_ERR, "Launchd reply does not contain %s dictionary.", LAUNCH_JOBKEY_MACHSERVICES); goto fin; }
	if (NULL == (datum = launch_data_dict_lookup(datum, service_name)) || LAUNCH_DATA_MACHPORT != launch_data_get_type(datum))
		{ helplog(ASL_LEVEL_ERR, "Launchd reply does not contain %s Mach port.", service_name); goto fin; }
	if (MACH_PORT_NULL == (port = launch_data_get_machport(datum)))
		{ helplog(ASL_LEVEL_ERR, "Launchd gave me a null Mach port."); goto fin; }
	if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto fin; }

fin:
	if (NULL != msg)   launch_data_free(msg);
	if (NULL != reply) launch_data_free(reply);
	if (MACH_PORT_NULL == port) exit(EXIT_FAILURE);
	return port;
	}
Пример #2
0
int getSocketFromLaunchd()
{
	// check-in
	launch_data_t checkinRequest = launch_data_new_string(LAUNCH_KEY_CHECKIN);
	launch_data_t checkinResponse = launch_msg(checkinRequest);
	if (!checkinResponse) {
		fprintf(stderr, "launch_msg(checkin_request) failed.\n");
		return -1;
	}
	
	// test if check-in was successful
	launch_data_type_t responseType = launch_data_get_type(checkinResponse);
	if (responseType == LAUNCH_DATA_ERRNO) {
		errno = launch_data_get_errno(checkinResponse);
		fprintf(stderr, "Check-in with launchd failed, error %i.\n", errno);
		return -1;
	} else if (responseType != LAUNCH_DATA_DICTIONARY) {
		fprintf(stderr, "Unknown error, aborting.");
		return -1;
	}
	
	// get socket
	launch_data_t sockets = launch_data_dict_lookup(checkinResponse, LAUNCH_JOBKEY_SOCKETS);
	launch_data_t ipcSocket = launch_data_dict_lookup(sockets, "IPC");
	launch_data_t socket = launch_data_array_get_index(ipcSocket, 0);
	
	int fd = launch_data_get_fd(socket);
	
	// we're done with launchd, free all resources
	launch_data_free(checkinRequest);
    launch_data_free(checkinResponse);

	return fd;
}
Пример #3
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;
}
int main(void)
{
	launch_data_t resp, tmp, msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);

	resp = launch_msg(msg);

	if (resp == NULL) {
		fprintf(stderr, "launch_msg(): %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
		errno = launch_data_get_errno(resp);
		fprintf(stderr, "launch_msg() response: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_MACHSERVICES);

	if (tmp == NULL) {
		fprintf(stderr, "no mach services found!\n");
		exit(EXIT_FAILURE);
	}

	launch_data_dict_iterate(tmp, print_mach_service, NULL);

	sleep(1);
	exit(EXIT_SUCCESS);
}
Пример #5
0
/*
 * Lookup the audit mach port in the launchd dictionary.
 */
static mach_port_t
lookup_machport(const char *label)
{
	launch_data_t msg, msd, ld, cdict, to;
	mach_port_t mp = MACH_PORT_NULL;

	msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);

	cdict = launch_msg(msg);
	if (cdict == NULL) {
		auditd_log_err("launch_msg(\"" LAUNCH_KEY_CHECKIN
		    "\") IPC failure: %m");
                return (MACH_PORT_NULL);
        }

	if (launch_data_get_type(cdict) == LAUNCH_DATA_ERRNO) {
		errno = launch_data_get_errno(cdict);
		auditd_log_err("launch_data_get_type() can't get dict: %m");
		return (MACH_PORT_NULL);
	}

	to = launch_data_dict_lookup(cdict, LAUNCH_JOBKEY_TIMEOUT);
	if (to) {
		max_idletime = launch_data_get_integer(to);
		auditd_log_debug("launchd timeout set to %d", max_idletime);
	} else {
		auditd_log_debug("launchd timeout not set, setting to 60");
		max_idletime = 60;
	}

	msd = launch_data_dict_lookup(cdict, LAUNCH_JOBKEY_MACHSERVICES);
	if (msd == NULL) {
		auditd_log_err(
		    "launch_data_dict_lookup() can't get mach services");
		return (MACH_PORT_NULL);
	}

	ld = launch_data_dict_lookup(msd, label);
	if (ld == NULL) {
		auditd_log_err("launch_data_dict_lookup can't find %s", label);
		return (MACH_PORT_NULL);
	}

	mp = launch_data_get_machport(ld);

	return (mp);
}
static void launch_msg_getmsgs(launch_data_t m, void *context)
{
	launch_data_t async_resp, *sync_resp = context;
	
	if ((LAUNCH_DATA_DICTIONARY == launch_data_get_type(m)) && (async_resp = launch_data_dict_lookup(m, "_AsyncMessage"))) {
		launch_data_array_set_index(_lc->async_resp, launch_data_copy(async_resp), launch_data_array_get_count(_lc->async_resp));
	} else {
		*sync_resp = launch_data_copy(m);
	}
}
Пример #7
0
static int get_listener_socket_from_launchd(void)
{
  launch_data_t req, resp, socks;

  req = launch_data_new_string(LAUNCH_KEY_CHECKIN);
  if (req == NULL) {
    w_log(W_LOG_ERR, "unable to create LAUNCH_KEY_CHECKIN\n");
    return -1;
  }

  resp = launch_msg(req);
  launch_data_free(req);

  if (resp == NULL) {
    w_log(W_LOG_ERR, "launchd checkin failed %s\n", strerror(errno));
    return -1;
  }

  if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
    w_log(W_LOG_ERR, "launchd checkin failed: %s\n",
        strerror(launch_data_get_errno(resp)));
    launch_data_free(resp);
    return -1;
  }

  socks = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS);
  if (socks == NULL) {
    w_log(W_LOG_ERR, "launchd didn't provide any sockets\n");
    launch_data_free(resp);
    return -1;
  }

  // the "sock" name here is coupled with the plist in main.c
  socks = launch_data_dict_lookup(socks, "sock");
  if (socks == NULL) {
    w_log(W_LOG_ERR, "launchd: \"sock\" wasn't present in Sockets\n");
    launch_data_free(resp);
    return -1;
  }

  return launch_data_get_fd(launch_data_array_get_index(socks, 0));
}
Пример #8
0
int listen_to_launchd_sockets() {
    //check-in with launchd
    launch_data_t checkin_message = launch_data_new_string(LAUNCH_KEY_CHECKIN);
    if (checkin_message == NULL) {
        exit_error("couldn't create launchd checkin message", errno);
    }
    launch_data_t checkin_result = launch_msg(checkin_message);
    if (checkin_result == NULL) {
        exit_error("couldn't check in with launchd", errno);
    }
    if (launch_data_get_type(checkin_result) == LAUNCH_DATA_ERRNO) {
        exit_error("error on launchd checkin",launch_data_get_errno(checkin_result));
        return EX_OSERR;
    }
    launch_data_t socket_info = launch_data_dict_lookup(checkin_result, LAUNCH_JOBKEY_SOCKETS);
    if (socket_info == NULL) {
        exit_error("couldn't find socket information", 0);
    }
    launch_data_t listening_sockets = launch_data_dict_lookup(socket_info, "Listener");
    if (listening_sockets == NULL) {
        exit_error("couldn't find my socket", 0);
    }
    //set up a kevent for our socket
    int kernel_queue = kqueue();
    if (kernel_queue == -1) {
        exit_error("couldn't create kernel queue", errno);
    }
    for (int i = 0; i < launch_data_array_get_count(listening_sockets); i++) {
        launch_data_t this_socket = launch_data_array_get_index(listening_sockets, i);
        struct kevent kev_init;
        EV_SET(&kev_init, launch_data_get_fd(this_socket), EVFILT_READ, EV_ADD, 0, 0, NULL);
        if (kevent(kernel_queue, &kev_init, 1, NULL, 0, NULL) == -1) {
            exit_error("couldn't create kernel event", errno);
        }
    }
    launch_data_free(checkin_result);
    return kernel_queue;
}
Пример #9
0
bool launchd_checkin(unsigned * idle_timeout_secs)
{
	launch_data_t msg;
	launch_data_t resp;
	launch_data_t item;
	bool is_launchd = true;

	msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
	resp = launch_msg(msg);
	if (resp == NULL) {
		/* IPC to launchd failed. */
		LAUNCHD_MSG_ERR("checkin", LAUNCH_KEY_CHECKIN);
		launch_data_free(msg);
		return false;
	}

	if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
		errno = launch_data_get_errno(resp);
		goto done;
	}

	/* At this point, we know we are running under launchd. */
	is_launchd = true;

	if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
		long long val = launch_data_get_integer(item);

		*idle_timeout_secs =
			(val < 0) ? 0 : ((val > UINT_MAX) ?  UINT_MAX : val);
	}

done:
	launch_data_free(msg);
	launch_data_free(resp);
	return is_launchd;
}
Пример #10
0
static void
launchd_checkin(void)
{
  size_t		i,		/* Looping var */
			count;		/* Number of listeners */
  launch_data_t		ld_msg,		/* Launch data message */
			ld_resp,	/* Launch data response */
			ld_array,	/* Launch data array */
			ld_sockets,	/* Launch data sockets dictionary */
			tmp;		/* Launch data */
  cupsd_listener_t	*lis;		/* Listeners array */
  http_addr_t		addr;		/* Address variable */
  socklen_t		addrlen;	/* Length of address */
  int			fd;		/* File descriptor */
  char			s[256];		/* String addresss */


  cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid());

 /*
  * Check-in with launchd...
  */

  ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
  if ((ld_resp = launch_msg(ld_msg)) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
		    "launchd_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
		    "\") IPC failure");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

  if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
  {
    errno = launch_data_get_errno(ld_resp);
    cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Check-in failed: %s",
                    strerror(errno));
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Get the sockets dictionary...
  */

  if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
          == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "launchd_checkin: No sockets found to answer requests on!");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Get the array of listener sockets...
  */

  if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "launchd_checkin: No sockets found to answer requests on!");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Add listening fd(s) to the Listener array...
  */

  if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
  {
    count = launch_data_array_get_count(ld_array);

    for (i = 0; i < count; i ++)
    {
     /*
      * Get the launchd file descriptor and address...
      */

      if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
      {
	fd      = launch_data_get_fd(tmp);
	addrlen = sizeof(addr);

	if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "launchd_checkin: Unable to get local address - %s",
			  strerror(errno));
	  continue;
	}

       /*
	* Try to match the launchd socket address to one of the listeners...
	*/

	for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
	     lis;
	     lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
	  if (httpAddrEqual(&lis->address, &addr))
	    break;

       /*
	* Add a new listener If there's no match...
	*/

	if (lis)
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
		  "launchd_checkin: Matched existing listener %s with fd %d...",
		  httpAddrString(&(lis->address), s, sizeof(s)), fd);
	}
	else
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
		  "launchd_checkin: Adding new listener %s with fd %d...",
		  httpAddrString(&addr, s, sizeof(s)), fd);

	  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "launchd_checkin: Unable to allocate listener - "
			    "%s.", strerror(errno));
	    exit(EXIT_FAILURE);
	  }

	  cupsArrayAdd(Listeners, lis);

	  memcpy(&lis->address, &addr, sizeof(lis->address));
	}

	lis->fd = fd;

#  ifdef HAVE_SSL
	if (_httpAddrPort(&(lis->address)) == 443)
	  lis->encryption = HTTP_ENCRYPT_ALWAYS;
#  endif /* HAVE_SSL */
      }
    }
  }

  launch_data_free(ld_msg);
  launch_data_free(ld_resp);
}
Пример #11
0
/* Get the Mach port upon which we'll receive requests from our parent */
static mach_port_t get_hex_fiend_receive_port(void) {
    mach_port_t launchdReceivePort = MACH_PORT_NULL, hexFiendReceivePort = MACH_PORT_NULL;
    launch_data_t resp = NULL, machServices = NULL, msg = NULL, service = NULL;
    int err = 0;
    
    /* Check in with launchd */
    msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
	resp = launch_msg(msg);
	if (resp == NULL) {
		if (ERR_FILE) fprintf(ERR_FILE, "launch_msg(): %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
    
    /* Guard against errors */
	if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
		errno = launch_data_get_errno(resp);
		if (ERR_FILE) fprintf(ERR_FILE, "launch_msg() response: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
    
    /* Get our MachServices dictioanry */
	machServices = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_MACHSERVICES);
    
    /* Die if it's not there */
	if (machServices == NULL) {
		if (ERR_FILE) fprintf(ERR_FILE, "No mach services found!\n");
		exit(EXIT_FAILURE);
	}
    
    /* Get the one we care about */
    service = launch_data_dict_lookup(machServices, kPrivilegedHelperLaunchdLabel);
    if (service == NULL) {
		if (ERR_FILE) fprintf(ERR_FILE, "Mach service %s not found!\n", kPrivilegedHelperLaunchdLabel);
		exit(EXIT_FAILURE);
    }
    
    /* Make sure we've got a mach port */
    if (launch_data_get_type(service) != LAUNCH_DATA_MACHPORT) {
        if (ERR_FILE) fprintf(ERR_FILE, "%s: not a mach port\n", kPrivilegedHelperLaunchdLabel);
        exit(EXIT_FAILURE);
    }
    
    /* Now get the launchd mach port */
    launchdReceivePort = launch_data_get_machport(service);
    
    /* We don't want to use launchd's port - we want one from Hex Fiend (so we can get a no senders notification). So receive a port from Hex Fiend on our launchd port. */
    hexFiendReceivePort = MACH_PORT_NULL;
    if ((err = recv_port(launchdReceivePort, &hexFiendReceivePort))) {
        if (ERR_FILE) fprintf(ERR_FILE, "recv_port() failed with Mach error %d\n", err);
        exit(EXIT_FAILURE);
    }
    
    /* Make sure we got something back */
    if (hexFiendReceivePort == MACH_PORT_NULL) {
        if (ERR_FILE) fprintf(ERR_FILE, "recv_port() returned a null Mach port\n");
        exit(EXIT_FAILURE);
    }
    
    /* Clean up */
    if (msg) launch_data_free(msg);
    if (resp) launch_data_free(resp);
    
    return hexFiendReceivePort;
}
Пример #12
0
/** 
 * create socket data_source for socket specified by launchd configuration
 */
int socket_connection_create_launchd(){
    
    launch_data_t sockets_dict, checkin_response;
	launch_data_t checkin_request;
    launch_data_t listening_fd_array;
    
	/*
	 * Register ourselves with launchd.
	 * 
	 */
	if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
		log_error( "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string.");
		return -1;
	}
    
	if ((checkin_response = launch_msg(checkin_request)) == NULL) {
		log_error( "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %u", errno);
		return -1;
	}
    
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
		errno = launch_data_get_errno(checkin_response);
		log_error( "Check-in failed: %u", errno);
		return -1;
	}
    
    launch_data_t the_label = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL);
	if (NULL == the_label) {
		log_error( "No label found");
		return -1;
	}
	
	/*
	 * Retrieve the dictionary of Socket entries in the config file
	 */
	sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
	if (NULL == sockets_dict) {
		log_error("No sockets found to answer requests on!");
		return -1;
	}
    
	// if (launch_data_dict_get_count(sockets_dict) > 1) {
	// 	log_error("Some sockets will be ignored!");
	// }
    
	/*
	 * Get the dictionary value from the key "Listeners"
	 */
	listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners");
	if (listening_fd_array) {
        // log_error("Listeners...\n");
        socket_connection_launchd_register_fd_array( listening_fd_array );
    }
    
	/*
	 * Get the dictionary value from the key "Listeners"
	 */
	listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners2");
	if (listening_fd_array) {
        // log_error("Listeners2...\n");
        socket_connection_launchd_register_fd_array( listening_fd_array );
    }
    
    // although used in Apple examples, it creates a malloc warning
	// launch_data_free(checkin_response);
    return 0;
}
Пример #13
0
DBusServer *
_dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
  {
#ifdef DBUS_ENABLE_LAUNCHD
    DBusServer *server;
    DBusString address;
    int launchd_fd;
    launch_data_t sockets_dict, checkin_response;
    launch_data_t checkin_request;
    launch_data_t listening_fd_array, listening_fd;
    launch_data_t environment_dict, environment_param;
    const char *launchd_socket_path, *display;

    launchd_socket_path = _dbus_getenv (launchd_env_var);
    display = _dbus_getenv ("DISPLAY");

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (launchd_socket_path == NULL || *launchd_socket_path == '\0')
      {
        dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                        "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var);
        return NULL;
      }

    if (!_dbus_string_init (&address))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        return NULL;
      }
    if (!_dbus_string_append (&address, "unix:path="))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }
    if (!_dbus_string_append (&address, launchd_socket_path))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }

    if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
                        "launch_data_new_string(\"%s\") Unable to create string.\n",
                        LAUNCH_KEY_CHECKIN);
        goto l_failed_0;
      }

    if ((checkin_response = launch_msg (checkin_request)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "launch_msg(\"%s\") IPC failure: %s\n",
                        LAUNCH_KEY_CHECKIN, strerror (errno));
        goto l_failed_0;
      }

    if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response))
      {
        dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n",
                        strerror (launch_data_get_errno (checkin_response)));
        goto l_failed_0;
      }

    sockets_dict =
      launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (NULL == sockets_dict)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    listening_fd_array =
      launch_data_dict_lookup (sockets_dict, "unix_domain_listener");
    if (NULL == listening_fd_array)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No known sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    if (launch_data_array_get_count (listening_fd_array) != 1)
      {
        dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                        "Expected 1 socket from launchd, got %d.\n",
                        launch_data_array_get_count (listening_fd_array));
        goto l_failed_0;
      }

    listening_fd = launch_data_array_get_index (listening_fd_array, 0);
    launchd_fd = launch_data_get_fd (listening_fd);

    _dbus_fd_set_close_on_exec (launchd_fd);

    if (launchd_fd < 0)
      {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        goto l_failed_0;
  if (display == NULL || *display == '\0')
    {
      environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES);
      if (NULL == environment_dict)
        {
          _dbus_warn ("Unable to retrieve user environment from launchd.");
        }
      else
        {
          environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY");
          if (NULL == environment_param)
            {
              _dbus_warn ("Unable to retrieve DISPLAY from launchd.");
            }
          else
            {
              display = launch_data_get_string(environment_param);
              dbus_setenv ("DISPLAY", display);
            }
        }
    }

      }

    server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0);
    if (server == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_SERVER,
                        "Unable to listen on launchd fd %d.", launchd_fd);
        goto l_failed_0;
      }

    _dbus_string_free (&address);

    return server;

  l_failed_0:
    _dbus_string_free (&address);

    return NULL;
#else /* DBUS_ENABLE_LAUNCHD */
    dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                    "address type 'launchd' requested, but launchd support not compiled in");
    return NULL;
#endif
  }
Пример #14
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 */
                                       });
Пример #15
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;
}
Пример #16
0
/*! iSCSI daemon entry point. */
int main(void)
{
    // Connect to the preferences .plist file associated with "iscsid" and
    // read configuration parameters for the initiator
    iSCSIPLSynchronize();

    CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN();

    if(initiatorIQN) {
        iSCSISetInitiatiorName(initiatorIQN);
        CFRelease(initiatorIQN);
    }

    CFStringRef initiatorAlias = iSCSIPLCopyInitiatorAlias();

    if(initiatorAlias) {
        iSCSISetInitiatiorName(initiatorAlias);
        CFRelease(initiatorAlias);
    }

    // Register with launchd so it can manage this daemon
    launch_data_t reg_request = launch_data_new_string(LAUNCH_KEY_CHECKIN);

    // Quit if we are unable to checkin...
    if(!reg_request) {
        fprintf(stderr,"Failed to checkin with launchd.\n");
        goto ERROR_LAUNCH_DATA;
    }

    launch_data_t reg_response = launch_msg(reg_request);

    // Ensure registration was successful
    if((launch_data_get_type(reg_response) == LAUNCH_DATA_ERRNO)) {
        fprintf(stderr,"Failed to checkin with launchd.\n");
        goto ERROR_NO_SOCKETS;
    }

    // Grab label and socket dictionary from daemon's property list
    launch_data_t label = launch_data_dict_lookup(reg_response,LAUNCH_JOBKEY_LABEL);
    launch_data_t sockets = launch_data_dict_lookup(reg_response,LAUNCH_JOBKEY_SOCKETS);

    if(!label || !sockets) {
        fprintf(stderr,"Could not find socket ");
        goto ERROR_NO_SOCKETS;
    }

    launch_data_t listen_socket_array = launch_data_dict_lookup(sockets,"iscsid");

    if(!listen_socket_array || launch_data_array_get_count(listen_socket_array) == 0)
        goto ERROR_NO_SOCKETS;

    // Grab handle to socket we want to listen on...
    launch_data_t listen_socket = launch_data_array_get_index(listen_socket_array,0);

    if(!iSCSIDRegisterForPowerEvents())
        goto ERROR_PWR_MGMT_FAIL;

    // Create a socket that will
    CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault,
                         launch_data_get_fd(listen_socket),
                         kCFSocketReadCallBack,
                         iSCSIDProcessIncomingRequest,0);

    // Runloop sources associated with socket events of connected clients
    CFRunLoopSourceRef clientSockSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault,socket,0);
    CFRunLoopAddSource(CFRunLoopGetMain(),clientSockSource,kCFRunLoopDefaultMode);

    CFRunLoopRun();

    // Deregister for power
    iSCSIDDeregisterForPowerEvents();

    launch_data_free(reg_response);
    return 0;

    // TODO: verify that launch data is freed under all possible execution paths

ERROR_PWR_MGMT_FAIL:
ERROR_NO_SOCKETS:
    launch_data_free(reg_response);

ERROR_LAUNCH_DATA:

    return ENOTSUP;
}