Exemple #1
0
/** @brief  Initialize the option parser
 *
 * @param   option_list list of options available
 * @param   name        program name for use in messages
 * @param   version     program version for use in messages
 *
 * @return  bool
 */
int optparse_init(option_decl_t *option_list,
                   const char *name,
                   const char *version)
{
    int result;
    options = option_list;
    prg_name = name;
    prg_version = version;

#ifdef OPTPARSE_DEBUG
    printf("%s:%d: initializing argument list .. ", __FILE__, __LINE__);
#endif
    result = arglist_init();
#ifdef OPTPARSE_DEBUG
    if (result) {
        printf("OK\n");
    } else {
        printf("failed\n");
    }
#endif
    return result;
}
Exemple #2
0
static void
lshd_service_request_handler(struct transport_forward *self,
			     uint32_t length, const uint8_t *packet)
{
  struct simple_buffer buffer;
  unsigned msg_number;

  const uint8_t *name;
  uint32_t name_length;

  simple_buffer_init(&buffer, length, packet);

  if (parse_uint8(&buffer, &msg_number)
      && (msg_number == SSH_MSG_SERVICE_REQUEST)
      && parse_string(&buffer, &name_length, &name)
      && parse_eod(&buffer))
    {
      CAST(lshd_context, ctx, self->super.ctx);
      const struct service_entry *service
	= service_config_lookup(ctx->service_config,
				name_length, name);
      
      if (service)
	{
	  int pipe[2];
	  pid_t child;

	  if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) < 0)
	    {
	      werror("lshd_service_request_handler: socketpair failed: %e.\n",
		     errno);
	      transport_disconnect(&self->super,
				   SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
				   "Service could not be started");
	      return;
	    }

	  child = fork();
	  if (child < 0)
	    {
	      werror("lshd_service_request_handler: fork failed: %e.\n",
		     errno);
	      close(pipe[0]);
	      close(pipe[1]);
	      transport_disconnect(&self->super,
				   SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
				   "Service could not be started");
	      return;
	    }
	  if (child)
	    {
	      /* Parent process */
	      close(pipe[1]);

	      transport_send_packet(&self->super, TRANSPORT_WRITE_FLAG_PUSH,
				    format_service_accept(name_length, name));

	      /* Setup forwarding. Replaces event_handler and packet_handler. */
	      transport_forward_setup(self, pipe[0], pipe[0]);
	    }
	  else
	    {
	      /* Child process */
	      struct arglist args;
	      const char *program;
	      unsigned i;

	      close(pipe[0]);
	      dup2(pipe[1], STDIN_FILENO);
	      dup2(pipe[1], STDOUT_FILENO);
	      close(pipe[1]);

	      /* FIXME: Pass sufficient information so that
		 $SSH_CLIENT can be set properly. */
	      arglist_init (&args);

	      program = service->args.argv[0];
	      arglist_push (&args, program);

	      /* If not absolute, interpret it relative to
		 libexecdir. */
	      if (program[0] != '/')
		program = lsh_get_cstring(ssh_format("%lz/%lz",
						     ctx->service_config->libexec_dir,
						     program));
	      
	      for (i = 1; i < service->args.argc; i++)
		{
		  const char *arg = service->args.argv[i];
		  if (arg[0] == '$')
		    {
		      if (!strcmp(arg+1, "(session_id)"))
			arg = lsh_get_cstring(ssh_format("%lxS",
							 self->super.session_id));
		    }
		  arglist_push (&args, arg);
		}
	      debug("exec of service %s, program %z. Argument list:\n",
		    name_length, name, program);
	      for (i = 0; i < args.argc; i++)
		debug("  %z\n", args.argv[i]);

	      execv(program, (char **) args.argv);

	      werror("lshd_service_request_handler: exec of %z failed: %e.\n",
		     args.argv[0], errno);
	      _exit(EXIT_FAILURE);
	    }
	}
      else
	transport_disconnect(&self->super,
			     SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
			      "Service not available");
    }
  else
    transport_protocol_error(&self->super, "Invalid SERVICE_REQUEST");
}