static int run_bridge (const gchar *interactive) { CockpitTransport *transport; CockpitBridge *bridge; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; gboolean init_received = FALSE; guint sig_term; guint sig_int; int outfd; cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2)); /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); cockpit_dbus_json_allow_external = FALSE; packages = cockpit_packages_new (); cockpit_dbus_internal_startup (interactive != NULL); if (interactive) { /* Allow skipping the init message when interactive */ init_received = TRUE; transport = cockpit_interact_transport_new (0, outfd, interactive); } else { transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); } g_resources_register (cockpitassets_get_resource ()); cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html"; bridge = cockpit_bridge_new (transport, payload_types, init_received); cockpit_dbus_environment_startup (); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); g_object_unref (bridge); g_object_unref (transport); cockpit_packages_free (packages); packages = NULL; g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }
int main (int argc, char **argv) { CockpitTransport *transport; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; GOptionContext *context; GError *error = NULL; guint sig_term; guint sig_int; int outfd; static GOptionEntry entries[] = { { "lower", 0, 0, G_OPTION_ARG_NONE, &opt_lower, "Lower case channel type", NULL }, { "upper", 0, 0, G_OPTION_ARG_NONE, &opt_upper, "Upper case channel type", NULL }, { NULL } }; signal (SIGPIPE, SIG_IGN); g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); g_setenv ("GIO_USE_VFS", "local", TRUE); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, NULL); g_option_context_set_description (context, "mock-bridge as used in tests\n"); g_option_context_parse (context, &argc, &argv, &error); g_option_context_free (context); if (error) { g_printerr ("mock-bridge: %s\n", error->message); g_error_free (error); return 1; } outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); g_signal_connect (transport, "control", G_CALLBACK (on_transport_control), NULL); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport); /* Owns the channels */ channels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); g_object_unref (transport); g_hash_table_destroy (channels); g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }
static int run_bridge (const gchar *interactive) { CockpitTransport *transport; CockpitRouter *router; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; guint sig_term; guint sig_int; int outfd; cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2)); /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); if (outfd > -1) close (outfd); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); cockpit_dbus_json_allow_external = FALSE; cockpit_dbus_internal_startup (interactive != NULL); if (interactive) { transport = cockpit_interact_transport_new (0, outfd, interactive); } else { transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); } g_resources_register (cockpitassets_get_resource ()); cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html"; /* Set a path if nothing is set */ g_setenv ("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0); router = setup_router (transport); cockpit_dbus_process_startup (); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport, interactive ? TRUE : FALSE); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); g_object_unref (router); g_object_unref (transport); g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }
static int run_bridge (const gchar *interactive, gboolean privileged_slave) { CockpitTransport *transport; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; CockpitPortal *super = NULL; CockpitPortal *pcp = NULL; gpointer polkit_agent = NULL; const gchar *directory; struct passwd *pwd; GPid daemon_pid = 0; GPid agent_pid = 0; guint sig_term; guint sig_int; int outfd; uid_t uid; cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2)); /* * The bridge always runs from within $XDG_RUNTIME_DIR * This makes it easy to create user sockets and/or files. */ if (!privileged_slave) { directory = g_get_user_runtime_dir (); if (g_mkdir_with_parents (directory, 0700) < 0) g_warning ("couldn't create runtime dir: %s: %s", directory, g_strerror (errno)); else if (g_chdir (directory) < 0) g_warning ("couldn't change to runtime dir: %s: %s", directory, g_strerror (errno)); } /* Always set environment variables early */ uid = geteuid(); pwd = getpwuid_a (uid); if (pwd == NULL) { g_message ("couldn't get user info: %s", g_strerror (errno)); } else { g_setenv ("USER", pwd->pw_name, TRUE); g_setenv ("HOME", pwd->pw_dir, TRUE); g_setenv ("SHELL", pwd->pw_shell, TRUE); } /* Reset the umask, typically this is done in .bashrc for a login shell */ umask (022); /* * This process talks on stdin/stdout. However lots of stuff wants to write * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that * it goes to stderr, and use another fd for stdout. */ outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); outfd = 1; } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); /* Start daemons if necessary */ if (!interactive && !privileged_slave) { if (!have_env ("DBUS_SESSION_BUS_ADDRESS")) daemon_pid = start_dbus_daemon (); if (!have_env ("SSH_AUTH_SOCK")) agent_pid = start_ssh_agent (); } packages = cockpit_packages_new (); cockpit_dbus_internal_startup (interactive != NULL); if (interactive) { /* Allow skipping the init message when interactive */ init_received = TRUE; transport = cockpit_interact_transport_new (0, outfd, interactive); } else { transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); } if (uid != 0) { if (!interactive) polkit_agent = cockpit_polkit_agent_register (transport, NULL); super = cockpit_portal_new_superuser (transport); } g_resources_register (cockpitassets_get_resource ()); cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html"; pcp = cockpit_portal_new_pcp (transport); cockpit_dbus_time_startup (); cockpit_dbus_user_startup (pwd); cockpit_dbus_setup_startup (); g_free (pwd); pwd = NULL; g_signal_connect (transport, "control", G_CALLBACK (on_transport_control), NULL); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); send_init_command (transport); /* Owns the channels */ channels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); if (polkit_agent) cockpit_polkit_agent_unregister (polkit_agent); if (super) g_object_unref (super); g_object_unref (pcp); g_object_unref (transport); g_hash_table_destroy (channels); cockpit_dbus_internal_cleanup (); cockpit_packages_free (packages); packages = NULL; if (daemon_pid) kill (daemon_pid, SIGTERM); if (agent_pid) kill (agent_pid, SIGTERM); g_source_remove (sig_term); g_source_remove (sig_int); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return 0; }
int main (int argc, char **argv) { CockpitTransport *transport; gboolean terminated = FALSE; gboolean interupted = FALSE; gboolean closed = FALSE; GError *error = NULL; guint sig_term; guint sig_int; int ret = 0; int outfd; const gchar *ssh_auth_sock = BUILDDIR "/test-agent.sock"; int agent = 0; gchar *agent_output = NULL; gchar *agent_error = NULL; gchar *pid_line = NULL; gint status = 0; const gchar *agent_argv[] = { "/usr/bin/ssh-agent", "-a", ssh_auth_sock, NULL }; signal (SIGPIPE, SIG_IGN); g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); g_setenv ("GIO_USE_VFS", "local", TRUE); outfd = dup (1); if (outfd < 0 || dup2 (2, 1) < 1) { g_warning ("bridge couldn't redirect stdout to stderr"); outfd = 1; } g_setenv ("SSH_AUTH_SOCK", ssh_auth_sock, TRUE); if (!g_spawn_sync (BUILDDIR, (gchar **)agent_argv, NULL, G_SPAWN_DEFAULT, NULL, NULL, &agent_output, &agent_error, &status, &error)) { g_warning ("bridge couldn't spawn agent %s\n", error->message); ret = 1; goto out; } if (!g_spawn_check_exit_status (status, &error)) { g_warning ("bridge couldn't spawn agent %s: %s\n", error->message, agent_error); ret = 1; goto out; } pid_line = strstr(agent_output, "SSH_AGENT_PID="); if (pid_line) { if (sscanf (pid_line, "SSH_AGENT_PID=%d;", &agent) != 1) g_warning ("couldn't find pid in %s", pid_line); } if (agent < 1) { g_warning ("couldn't get agent pid: %s", agent_output); ret = 1; goto out; } if (argc > 1) { const gchar *agent_add_argv[] = { "/usr/bin/ssh-add", argv[1], NULL }; gchar **agent_add_env = g_get_environ (); agent_add_env = g_environ_setenv (agent_add_env, "SSH_AUTH_SOCK", g_strdup (ssh_auth_sock), TRUE); g_spawn_sync (BUILDDIR, (gchar **)agent_add_argv, agent_add_env, G_SPAWN_DEFAULT, NULL, NULL, NULL, NULL, NULL, &error); g_strfreev (agent_add_env); if (error) { g_warning ("couldn't add key %s\n", error->message); ret = 1; goto out; } } sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated); sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted); g_type_init (); transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd); g_signal_connect (transport, "control", G_CALLBACK (on_transport_control), NULL); g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed); /* Owns the channels */ channels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); send_init_command (transport); while (!terminated && !closed && !interupted) g_main_context_iteration (NULL, TRUE); g_object_unref (transport); g_hash_table_destroy (channels); g_source_remove (sig_term); g_source_remove (sig_int); out: g_free (agent_output); g_free (agent_error); if (error) g_error_free (error); if (agent) kill (agent, SIGTERM); /* So the caller gets the right signal */ if (terminated) raise (SIGTERM); return ret; }