Example #1
0
static gboolean
lookup_internal (const gchar *name,
                 GSocketConnectable **connectable)
{
  const gchar *env;

  g_assert (name != NULL);
  g_assert (connectable != NULL);

  if (g_str_equal (name, "ssh-agent"))
    {
      *connectable = NULL;
      env = g_getenv ("SSH_AUTH_SOCK");
      if (env != NULL && env[0] != '\0')
        *connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (env));
      else
        *connectable = NULL;
      return TRUE;
    }

  if (internal_addresses)
    {
      return g_hash_table_lookup_extended (internal_addresses, name, NULL,
                                           (gpointer *)connectable);
    }

  return FALSE;
}
Example #2
0
static gboolean
lookup_internal (const gchar *name,
                 GSocketConnectable **connectable)
{
  const gchar *env;
  gboolean ret = FALSE;
  GSocketAddress *address;

  g_assert (name != NULL);
  g_assert (connectable != NULL);

  if (internal_addresses)
    {
      ret = g_hash_table_lookup_extended (internal_addresses, name, NULL,
                                          (gpointer *)connectable);
    }

  if (!ret && g_str_equal (name, "ssh-agent"))
    {
      *connectable = NULL;
      env = g_getenv ("SSH_AUTH_SOCK");
      if (env != NULL && env[0] != '\0')
        {
          address = g_unix_socket_address_new (env);
          *connectable = G_SOCKET_CONNECTABLE (address);
          cockpit_channel_internal_address ("ssh-agent", address);
        }
      ret = TRUE;
    }

  return ret;
}
Example #3
0
/**
 * soup_socket_connect_async:
 * @sock: a client #SoupSocket (which must not already be connected)
 * @cancellable: a #GCancellable, or %NULL
 * @callback: (scope async): callback to call after connecting
 * @user_data: data to pass to @callback
 *
 * Begins asynchronously connecting to @sock's remote address. The
 * socket will call @callback when it succeeds or fails (but not
 * before returning from this function).
 *
 * If @cancellable is non-%NULL, it can be used to cancel the
 * connection. @callback will still be invoked in this case, with a
 * status of %SOUP_STATUS_CANCELLED.
 **/
void
soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
			   SoupSocketCallback callback, gpointer user_data)
{
	SoupSocketPrivate *priv;
	SoupSocketAsyncConnectData *sacd;
	GSocketClient *client;

	g_return_if_fail (SOUP_IS_SOCKET (sock));
	priv = SOUP_SOCKET_GET_PRIVATE (sock);
	g_return_if_fail (priv->remote_addr != NULL);

	sacd = g_slice_new0 (SoupSocketAsyncConnectData);
	sacd->sock = g_object_ref (sock);
	sacd->callback = callback;
	sacd->user_data = user_data;

	priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();

	if (priv->async_context && !priv->use_thread_context)
		g_main_context_push_thread_default (priv->async_context);

	client = new_socket_client (sock);
	g_socket_client_connect_async (client,
				       G_SOCKET_CONNECTABLE (priv->remote_addr),
				       priv->connect_cancel,
				       async_connected, sacd);
	g_object_unref (client);
}
Example #4
0
/**
 * soup_socket_connect_sync:
 * @sock: a client #SoupSocket (which must not already be connected)
 * @cancellable: a #GCancellable, or %NULL
 *
 * Attempt to synchronously connect @sock to its remote address.
 *
 * If @cancellable is non-%NULL, it can be used to cancel the
 * connection, in which case soup_socket_connect_sync() will return
 * %SOUP_STATUS_CANCELLED.
 *
 * Return value: a success or failure code.
 **/
guint
soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
{
	SoupSocketPrivate *priv;
	GSocketClient *client;
	GSocketConnection *conn;
	GError *error = NULL;

	g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
	priv = SOUP_SOCKET_GET_PRIVATE (sock);
	g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
	g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
	g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);

	if (cancellable)
		g_object_ref (cancellable);
	else
		cancellable = g_cancellable_new ();
	priv->connect_cancel = cancellable;

	client = new_socket_client (sock);
	conn = g_socket_client_connect (client,
					G_SOCKET_CONNECTABLE (priv->remote_addr),
					priv->connect_cancel, &error);
	g_object_unref (client);

	return socket_connected (sock, conn, error);
}
Example #5
0
/* TODO: could use dbus, but for portability maybe not..... */
static void
do_connect(SpiceVDAgent *agent)
{
    GError *error = NULL;
    GSocketAddressEnumerator *enumerator;
    GSocketAddress *address;

#ifdef G_OS_UNIX
    agent->socket = g_socket_new(G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error);
    agent->connectable = G_SOCKET_CONNECTABLE(g_unix_socket_address_new(vdagentd_socket));
#endif

    enumerator = g_socket_connectable_enumerate (agent->connectable);
    while (TRUE) {
        address = g_socket_address_enumerator_next (enumerator, agent->cancellable, NULL);
        if (!address) {
            g_error("can't connect to socket");
            exit(1);
        }

        if (g_socket_connect(agent->socket, address, agent->cancellable, &error))
            break;

        g_debug("Connection failed, trying next");
        g_clear_error (&error);
        g_object_unref (address);
    }
    g_object_unref(enumerator);

    agent->connection =
        G_IO_STREAM(g_socket_connection_factory_create_connection(agent->socket));
    g_debug("Connected to %s %p", vdagentd_socket, agent->connection);

    send_xorg_config(agent);
}
Example #6
0
static void
do_connectable (const char *arg, gboolean synchronous)
{
  char **parts;
  GSocketConnectable *connectable;
  GSocketAddressEnumerator *enumerator;

  if (strchr (arg, '/'))
    {
      /* service/protocol/domain */
      parts = g_strsplit (arg, "/", 3);
      if (!parts || !parts[2])
	usage ();

      connectable = g_network_service_new (parts[0], parts[1], parts[2]);
    }
  else
    {
      guint16 port;

      parts = g_strsplit (arg, ":", 2);
      if (parts && parts[1])
	{
	  arg = parts[0];
	  port = strtoul (parts[1], NULL, 10);
	}
      else
	port = 0;

      if (g_hostname_is_ip_address (arg))
	{
	  GInetAddress *addr = g_inet_address_new_from_string (arg);
	  GSocketAddress *sockaddr = g_inet_socket_address_new (addr, port);

	  g_object_unref (addr);
	  connectable = G_SOCKET_CONNECTABLE (sockaddr);
	}
      else
        connectable = g_network_address_new (arg, port);
    }

  enumerator = g_socket_connectable_enumerate (connectable);
  g_object_unref (connectable);

  if (synchronous)
    do_sync_connectable (enumerator);
  else
    do_async_connectable (enumerator);
}
Example #7
0
gboolean
g_vfs_ftp_connection_open_data_connection (GVfsFtpConnection *conn,
                                           GSocketAddress *   addr,
                                           GCancellable *     cancellable,
                                           GError **          error)
{
  g_return_val_if_fail (conn != NULL, FALSE);
  g_return_val_if_fail (conn->data == NULL, FALSE);

  g_vfs_ftp_connection_stop_listening (conn);

  conn->data = G_IO_STREAM (g_socket_client_connect (conn->client,
                                                     G_SOCKET_CONNECTABLE (addr),
                                                     cancellable,
                                                     error));

  return conn->data != NULL;
}
Example #8
0
static void
_j4status_io_stream_connect(J4statusIOStream *self)
{
    if ( self->connection != NULL )
    {
        g_object_unref(self->in);
        g_object_unref(self->out);
        g_object_unref(self->connection);
        self->connection = NULL;
        self->out = NULL;
        self->in = NULL;
    }


    GSocketClient *client;
    client = g_socket_client_new();

    g_socket_client_connect_async(client, G_SOCKET_CONNECTABLE(self->address), NULL, _j4status_io_stream_connect_callback, self);
    g_object_unref(client);
}
Example #9
0
static void
use_inet_address (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *sockaddr;
  GInetAddress *addr = NULL;
  guint port = 0;
  gchar **ip_and_port;

  ip_and_port = g_strsplit (info, ":", 2);

  if (ip_and_port[0])
    {
      addr = g_inet_address_new_from_string (ip_and_port[0]);
      if (ip_and_port [1])
	port = strtoul (ip_and_port [1], NULL, 10);
    }

  g_strfreev (ip_and_port);

  if (addr == NULL || port <= 0 || port >= 65535)
    {
      fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info);
      if (addr)
	g_object_unref (addr);
      return_value = 1;
      return;
    }

  sockaddr = g_inet_socket_address_new (addr, port);
  g_object_unref (addr);

  enumerator =
    g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
  g_object_unref (sockaddr);

  printf ("Proxies for ip and port '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}
Example #10
0
static void
use_unix_address (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *sockaddr;

  sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT);

  if (sockaddr == NULL)
    {
      fprintf (stderr, "Failed to create unix socket with name '%s'\n", info);
      return_value = 1;
      return;
    }

  enumerator =
    g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
  g_object_unref (sockaddr);

  printf ("Proxies for path '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}
Example #11
0
/* TODO: Declare an extension point called GDBusTransport (or similar)
 * and move code below to extensions implementing said extension
 * point. That way we can implement a D-Bus transport over X11 without
 * making libgio link to libX11...
 */
static GIOStream *
g_dbus_address_connect (const gchar   *address_entry,
                        const gchar   *transport_name,
                        GHashTable    *key_value_pairs,
                        GCancellable  *cancellable,
                        GError       **error)
{
  GIOStream *ret;
  GSocketConnectable *connectable;
  const gchar *nonce_file;

  connectable = NULL;
  ret = NULL;
  nonce_file = NULL;

  if (FALSE)
    {
    }
#ifdef G_OS_UNIX
  else if (g_strcmp0 (transport_name, "unix") == 0)
    {
      const gchar *path;
      const gchar *abstract;
      path = g_hash_table_lookup (key_value_pairs, "path");
      abstract = g_hash_table_lookup (key_value_pairs, "abstract");
      if ((path == NULL && abstract == NULL) || (path != NULL && abstract != NULL))
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_INVALID_ARGUMENT,
                       _("Error in address '%s' - the unix transport requires exactly one of the "
                         "keys 'path' or 'abstract' to be set"),
                       address_entry);
        }
      else if (path != NULL)
        {
          connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (path));
        }
      else if (abstract != NULL)
        {
          connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new_with_type (abstract,
                                                                                   -1,
                                                                                   G_UNIX_SOCKET_ADDRESS_ABSTRACT));
        }
      else
        {
          g_assert_not_reached ();
        }
    }
#endif
  else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0)
    {
      const gchar *s;
      const gchar *host;
      glong port;
      gchar *endp;
      gboolean is_nonce;

      is_nonce = (g_strcmp0 (transport_name, "nonce-tcp") == 0);

      host = g_hash_table_lookup (key_value_pairs, "host");
      if (host == NULL)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_INVALID_ARGUMENT,
                       _("Error in address '%s' - the host attribute is missing or malformed"),
                       address_entry);
          goto out;
        }

      s = g_hash_table_lookup (key_value_pairs, "port");
      if (s == NULL)
        s = "0";
      port = strtol (s, &endp, 10);
      if ((*s == '\0' || *endp != '\0') || port < 0 || port >= 65536)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_INVALID_ARGUMENT,
                       _("Error in address '%s' - the port attribute is missing or malformed"),
                       address_entry);
          goto out;
        }


      if (is_nonce)
        {
          nonce_file = g_hash_table_lookup (key_value_pairs, "noncefile");
          if (nonce_file == NULL)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_INVALID_ARGUMENT,
                           _("Error in address '%s' - the noncefile attribute is missing or malformed"),
                           address_entry);
              goto out;
            }
        }

      /* TODO: deal with family key/value-pair */
      connectable = g_network_address_new (host, port);
    }
  else if (g_strcmp0 (address_entry, "autolaunch:") == 0)
    {
      gchar *autolaunch_address;
      autolaunch_address = get_session_address_platform_specific (error);
      if (autolaunch_address != NULL)
        {
          ret = g_dbus_address_try_connect_one (autolaunch_address, NULL, cancellable, error);
          g_free (autolaunch_address);
          goto out;
        }
      else
        {
          g_prefix_error (error, _("Error auto-launching: "));
        }
    }
  else
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Unknown or unsupported transport '%s' for address '%s'"),
                   transport_name,
                   address_entry);
    }

  if (connectable != NULL)
    {
      GSocketClient *client;
      GSocketConnection *connection;

      g_assert (ret == NULL);
      client = g_socket_client_new ();
      connection = g_socket_client_connect (client,
                                            connectable,
                                            cancellable,
                                            error);
      g_object_unref (connectable);
      g_object_unref (client);
      if (connection == NULL)
        goto out;

      ret = G_IO_STREAM (connection);

      if (nonce_file != NULL)
        {
          gchar nonce_contents[16 + 1];
          size_t num_bytes_read;
          FILE *f;

          /* be careful to read only 16 bytes - we also check that the file is only 16 bytes long */
          f = fopen (nonce_file, "rb");
          if (f == NULL)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_INVALID_ARGUMENT,
                           _("Error opening nonce file '%s': %s"),
                           nonce_file,
                           g_strerror (errno));
              g_object_unref (ret);
              ret = NULL;
              goto out;
            }
          num_bytes_read = fread (nonce_contents,
                                  sizeof (gchar),
                                  16 + 1,
                                  f);
          if (num_bytes_read != 16)
            {
              if (num_bytes_read == 0)
                {
                  g_set_error (error,
                               G_IO_ERROR,
                               G_IO_ERROR_INVALID_ARGUMENT,
                               _("Error reading from nonce file '%s': %s"),
                               nonce_file,
                               g_strerror (errno));
                }
              else
                {
                  g_set_error (error,
                               G_IO_ERROR,
                               G_IO_ERROR_INVALID_ARGUMENT,
                               _("Error reading from nonce file '%s', expected 16 bytes, got %d"),
                               nonce_file,
                               (gint) num_bytes_read);
                }
              g_object_unref (ret);
              ret = NULL;
              fclose (f);
              goto out;
            }
          fclose (f);

          if (!g_output_stream_write_all (g_io_stream_get_output_stream (ret),
                                          nonce_contents,
                                          16,
                                          NULL,
                                          cancellable,
                                          error))
            {
              g_prefix_error (error, _("Error writing contents of nonce file '%s' to stream:"), nonce_file);
              g_object_unref (ret);
              ret = NULL;
              goto out;
            }
        }
    }

 out:

  return ret;
}
Example #12
0
/* TODO: Declare an extension point called GDBusTransport (or similar)
 * and move code below to extensions implementing said extension
 * point. That way we can implement a D-Bus transport over X11 without
 * making libgio link to libX11...
 */
static GIOStream *
g_dbus_address_connect (const gchar   *address_entry,
                        const gchar   *transport_name,
                        GHashTable    *key_value_pairs,
                        GCancellable  *cancellable,
                        GError       **error)
{
  GIOStream *ret;
  GSocketConnectable *connectable;
  const gchar *nonce_file;

  connectable = NULL;
  ret = NULL;
  nonce_file = NULL;

  if (FALSE)
    {
    }
#ifdef G_OS_UNIX
  else if (g_strcmp0 (transport_name, "unix") == 0)
    {
      const gchar *path;
      const gchar *abstract;
      path = g_hash_table_lookup (key_value_pairs, "path");
      abstract = g_hash_table_lookup (key_value_pairs, "abstract");
      if ((path == NULL && abstract == NULL) || (path != NULL && abstract != NULL))
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_INVALID_ARGUMENT,
                       _("Error in address `%s' - the unix transport requires exactly one of the "
                         "keys `path' or `abstract' to be set"),
                       address_entry);
        }
      else if (path != NULL)
        {
          connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (path));
        }
      else if (abstract != NULL)
        {
          connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new_with_type (abstract,
                                                                                   -1,
                                                                                   G_UNIX_SOCKET_ADDRESS_ABSTRACT));
        }
      else
        {
          g_assert_not_reached ();
        }
    }
#endif
  else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0)
    {
      const gchar *s;
      const gchar *host;
      guint port;
      gchar *endp;
      gboolean is_nonce;

      is_nonce = (g_strcmp0 (transport_name, "nonce-tcp") == 0);

      host = g_hash_table_lookup (key_value_pairs, "host");
      if (host == NULL)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_INVALID_ARGUMENT,
                       _("Error in address `%s' - the host attribute is missing or malformed"),
                       address_entry);
          goto out;
        }

      s = g_hash_table_lookup (key_value_pairs, "port");
      if (s == NULL)
        s = "0";
      port = strtol (s, &endp, 10);
      if ((*s == '\0' || *endp != '\0') || port < 0 || port >= 65536)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_INVALID_ARGUMENT,
                       _("Error in address `%s' - the port attribute is missing or malformed"),
                       address_entry);
          goto out;
        }


      if (is_nonce)
        {
          nonce_file = g_hash_table_lookup (key_value_pairs, "noncefile");
          if (nonce_file == NULL)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_INVALID_ARGUMENT,
                           _("Error in address `%s' - the noncefile attribute is missing or malformed"),
                           address_entry);
              goto out;
            }
        }

      /* TODO: deal with family */
      connectable = g_network_address_new (host, port);
    }
  else
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Unknown or unsupported transport `%s' for address `%s'"),
                   transport_name,
                   address_entry);
    }

  if (connectable != NULL)
    {
      GSocketClient *client;
      GSocketConnection *connection;

      g_assert (ret == NULL);
      client = g_socket_client_new ();
      connection = g_socket_client_connect (client,
                                            connectable,
                                            cancellable,
                                            error);
      g_object_unref (connectable);
      g_object_unref (client);
      if (connection == NULL)
        goto out;

      ret = G_IO_STREAM (connection);

      if (nonce_file != NULL)
        {
          gchar *nonce_contents;
          gsize nonce_length;

          /* TODO: too dangerous to read the entire file? (think denial-of-service etc.) */
          if (!g_file_get_contents (nonce_file,
                                    &nonce_contents,
                                    &nonce_length,
                                    error))
            {
              g_prefix_error (error, _("Error reading nonce file `%s':"), nonce_file);
              g_object_unref (ret);
              ret = NULL;
              goto out;
            }

          if (nonce_length != 16)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_INVALID_ARGUMENT,
                           _("The nonce-file `%s' was %" G_GSIZE_FORMAT " bytes. Expected 16 bytes."),
                           nonce_file,
                           nonce_length);
              g_free (nonce_contents);
              g_object_unref (ret);
              ret = NULL;
              goto out;
            }

          if (!g_output_stream_write_all (g_io_stream_get_output_stream (ret),
                                          nonce_contents,
                                          nonce_length,
                                          NULL,
                                          cancellable,
                                          error))
            {
              g_prefix_error (error, _("Error write contents of nonce file `%s' to stream:"), nonce_file);
              g_object_unref (ret);
              ret = NULL;
              g_free (nonce_contents);
              goto out;
            }
          g_free (nonce_contents);
        }
    }

 out:

  return ret;
}
Example #13
0
static gboolean
make_connection (const char       *argument,
		 GTlsCertificate  *certificate,
		 GCancellable     *cancellable,
		 GSocket         **socket,
		 GSocketAddress  **address,
		 GIOStream       **connection,
		 GInputStream    **istream,
		 GOutputStream   **ostream,
		 GError          **error)
{
  GSocketType socket_type;
  GSocketFamily socket_family;
  GSocketAddressEnumerator *enumerator;
  GSocketConnectable *connectable;
  GSocketAddress *src_address;
  GTlsInteraction *interaction;
  GError *err = NULL;

  if (use_udp)
    socket_type = G_SOCKET_TYPE_DATAGRAM;
  else
    socket_type = G_SOCKET_TYPE_STREAM;

  if (unix_socket)
    socket_family = G_SOCKET_FAMILY_UNIX;
  else
    socket_family = G_SOCKET_FAMILY_IPV4;

  *socket = g_socket_new (socket_family, socket_type, 0, error);
  if (*socket == NULL)
    return FALSE;

  if (read_timeout)
    g_socket_set_timeout (*socket, read_timeout);

  if (unix_socket)
    {
      GSocketAddress *addr;

      addr = socket_address_from_string (argument);
      if (addr == NULL)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Could not parse '%s' as unix socket name", argument);
          return FALSE;
        }
      connectable = G_SOCKET_CONNECTABLE (addr);
    }
  else
    {
      connectable = g_network_address_parse (argument, 7777, error);
      if (connectable == NULL)
        return FALSE;
    }

  enumerator = g_socket_connectable_enumerate (connectable);
  while (TRUE)
    {
      *address = g_socket_address_enumerator_next (enumerator, cancellable, error);
      if (*address == NULL)
        {
          if (error != NULL && *error == NULL)
            g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                 "No more addresses to try");
          return FALSE;
        }

      if (g_socket_connect (*socket, *address, cancellable, &err))
        break;
      g_message ("Connection to %s failed: %s, trying next", socket_address_to_string (*address), err->message);
      g_clear_error (&err);

      g_object_unref (*address);
    }
  g_object_unref (enumerator);

  g_print ("Connected to %s\n",
           socket_address_to_string (*address));

  src_address = g_socket_get_local_address (*socket, error);
  if (!src_address)
    {
      g_prefix_error (error, "Error getting local address: ");
      return FALSE;
    }

  g_print ("local address: %s\n",
           socket_address_to_string (src_address));
  g_object_unref (src_address);

  if (use_udp)
    {
      *connection = NULL;
      *istream = NULL;
      *ostream = NULL;
    }
  else
    *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket));

  if (tls)
    {
      GIOStream *tls_conn;

      tls_conn = g_tls_client_connection_new (*connection, connectable, error);
      if (!tls_conn)
        {
          g_prefix_error (error, "Could not create TLS connection: ");
          return FALSE;
        }

      g_signal_connect (tls_conn, "accept-certificate",
                        G_CALLBACK (accept_certificate), NULL);

      interaction = g_tls_console_interaction_new ();
      g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction);
      g_object_unref (interaction);

      if (certificate)
        g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate);

      g_object_unref (*connection);
      *connection = G_IO_STREAM (tls_conn);

      if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
                                       cancellable, error))
        {
          g_prefix_error (error, "Error during TLS handshake: ");
          return FALSE;
        }
    }
  g_object_unref (connectable);

  if (*connection)
    {
      *istream = g_io_stream_get_input_stream (*connection);
      *ostream = g_io_stream_get_output_stream (*connection);
    }

  return TRUE;
}
Example #14
0
static void
use_proxy_address (gboolean synchronous)
{
  GSocketAddressEnumerator *enumerator;
  GSocketAddress *sockaddr;
  GInetAddress *addr;
  guint port = 0;
  gchar *protocol;
  gchar *dest_host;
  guint dest_port;
  gchar *username = NULL;
  gchar *password = NULL;
  gchar **split_info;

  split_info = g_strsplit (info, ":", 7);

  if (!split_info[0]
      || !split_info[1]
      || !split_info[2]
      || !split_info[3]
      || !split_info[4])
    {
      fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info);
      return_value = 1;
      return;
    }

  addr = g_inet_address_new_from_string (split_info[0]);
  port = strtoul (split_info [1], NULL, 10);
  protocol = g_strdup (split_info[2]);
  dest_host = g_strdup (split_info[3]);
  dest_port = strtoul (split_info[4], NULL, 10);
 
  if (split_info[5])
    {
      username = g_strdup (split_info[5]);
      if (split_info[6])
        password = g_strdup (split_info[6]);
    }

  g_strfreev (split_info);

  sockaddr = g_proxy_address_new (addr, port,
                                  protocol, dest_host, dest_port,
                                  username, password);
  
  g_object_unref (addr);
  g_free (protocol);
  g_free (dest_host);
  g_free (username);
  g_free (password);

  enumerator =
    g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
  g_object_unref (sockaddr);

  printf ("Proxies for ip and port '%s' are:\n", info);
  run_with_enumerator (synchronous, enumerator);

  g_object_unref (enumerator);
}
Example #15
0
ControllerLIRC::ControllerLIRC( TPContext * context , const char * uds , guint _repeat )
:
    connection( 0 ),
    controller( 0 ),
    timer( 0 ),
    repeat( gdouble( _repeat ) / 1000.0 )
{
    g_assert( context );
    g_assert( uds );

    //.........................................................................
    // Get the address of the Unix Domain Socket

    GSocketAddress * socket_address = g_unix_socket_address_new( uds );

    if ( ! socket_address )
    {
        tpwarn( "FAILED TO CREATE SOCKET ADDRESS WITH '%d'" , uds );
        return;
    }

    //.........................................................................
    // Create a socket client and attempt to connect to the address

    GSocketClient * client = g_socket_client_new();

    connection = g_socket_client_connect( client , G_SOCKET_CONNECTABLE( socket_address ) , NULL , NULL );

    g_object_unref( socket_address );

    g_object_unref( client );

    if ( ! connection )
    {
        tplog( "FAILED TO CONNECT TO LIRC SOCKET" );
        return;
    }

    //.........................................................................
    // Now, get the socket's input stream, create a data input stream from it
    // and start reading lines.

    GDataInputStream * input_stream = g_data_input_stream_new( g_io_stream_get_input_stream( G_IO_STREAM( connection ) ) );

    g_assert( input_stream );

    g_data_input_stream_read_line_async( input_stream , 0 , NULL , line_read , this );

    g_object_unref( input_stream );

    //.........................................................................
    // Add the controller

    TPControllerSpec controller_spec;

    memset( & controller_spec , 0 , sizeof( controller_spec ) );

    controller_spec.capabilities = TP_CONTROLLER_HAS_KEYS;

    controller = tp_context_add_controller( context , "Remote" , & controller_spec , 0 );

    g_assert( controller );

    //.........................................................................
    // Populate the key map

    key_map[ "0"         ] = TP_KEY_0;
    key_map[ "1"         ] = TP_KEY_1;
    key_map[ "2"         ] = TP_KEY_2;
    key_map[ "3"         ] = TP_KEY_3;
    key_map[ "4"         ] = TP_KEY_4;
    key_map[ "5"         ] = TP_KEY_5;
    key_map[ "6"         ] = TP_KEY_6;
    key_map[ "7"         ] = TP_KEY_7;
    key_map[ "8"         ] = TP_KEY_8;
    key_map[ "9"         ] = TP_KEY_9;
    key_map[ "MUTE"      ] = TP_KEY_MUTE;
    key_map[ "CH_UP"     ] = TP_KEY_CHAN_UP;
    key_map[ "VOL_UP"    ] = TP_KEY_VOL_UP;
    key_map[ "CH_DOWN"   ] = TP_KEY_CHAN_DOWN;
    key_map[ "VOL_DOWN"  ] = TP_KEY_VOL_DOWN;
    key_map[ "UP"        ] = TP_KEY_UP;
    key_map[ "LEFT"      ] = TP_KEY_LEFT;
    key_map[ "OK"        ] = TP_KEY_OK;
    key_map[ "RIGHT"     ] = TP_KEY_RIGHT;
    key_map[ "DOWN"      ] = TP_KEY_DOWN;
    key_map[ "MENU"      ] = TP_KEY_MENU;
    key_map[ "EXIT"      ] = TP_KEY_EXIT;
    key_map[ "PLAY"      ] = TP_KEY_PLAY;
    key_map[ "PAUSE"     ] = TP_KEY_PAUSE;
    key_map[ "STOP"      ] = TP_KEY_STOP;
    key_map[ "|<<"       ] = TP_KEY_PREV;
    key_map[ ">>|"       ] = TP_KEY_NEXT;
    key_map[ "RECORD"    ] = TP_KEY_REC;
    key_map[ "<<"        ] = TP_KEY_REW;
    key_map[ ">>"        ] = TP_KEY_FFWD;
    key_map[ "RED"       ] = TP_KEY_RED;
    key_map[ "GREEN"     ] = TP_KEY_GREEN;
    key_map[ "YELLOW"    ] = TP_KEY_YELLOW;
    key_map[ "BLUE"      ] = TP_KEY_BLUE;
    key_map[ "BACK"      ] = TP_KEY_BACK;

    timer = g_timer_new();

    tplog( "READY" );
}
Example #16
0
int
main (int argc,
      char *argv[])
{
  GSocket *socket;
  GSocketAddress *src_address;
  GSocketAddress *address;
  GSocketType socket_type;
  GSocketFamily socket_family;
  GError *error = NULL;
  GOptionContext *context;
  GCancellable *cancellable;
  GSocketAddressEnumerator *enumerator;
  GSocketConnectable *connectable;

  g_thread_init (NULL);

  g_type_init ();

  context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
  g_option_context_add_main_entries (context, cmd_entries, NULL);
  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("%s: %s\n", argv[0], error->message);
      return 1;
    }

  if (argc != 2)
    {
      g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name");
      return 1;
    }

  if (cancel_timeout)
    {
      cancellable = g_cancellable_new ();
      g_thread_create (cancel_thread, cancellable, FALSE, NULL);
    }
  else
    {
      cancellable = NULL;
    }

  loop = g_main_loop_new (NULL, FALSE);

  if (use_udp)
    socket_type = G_SOCKET_TYPE_DATAGRAM;
  else
    socket_type = G_SOCKET_TYPE_STREAM;

  if (unix_socket)
    socket_family = G_SOCKET_FAMILY_UNIX;
  else
    socket_family = G_SOCKET_FAMILY_IPV4;

  socket = g_socket_new (socket_family, socket_type, 0, &error);
  if (socket == NULL)
    {
      g_printerr ("%s: %s\n", argv[0], error->message);
      return 1;
    }

  if (read_timeout)
    g_socket_set_timeout (socket, read_timeout);

  if (unix_socket)
    {
      GSocketAddress *addr;

      addr = socket_address_from_string (argv[1]);
      if (addr == NULL)
	{
	  g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]);
	  return 1;
	}
      connectable = G_SOCKET_CONNECTABLE (addr);
    }
  else
    {
      connectable = g_network_address_parse (argv[1], 7777, &error);
      if (connectable == NULL)
	{
	  g_printerr ("%s: %s\n", argv[0], error->message);
	  return 1;
	}
    }

  enumerator = g_socket_connectable_enumerate (connectable);
  while (TRUE)
    {
      address = g_socket_address_enumerator_next (enumerator, cancellable, &error);
      if (address == NULL)
	{
	  if (error == NULL)
	    g_printerr ("%s: No more addresses to try\n", argv[0]);
	  else
	    g_printerr ("%s: %s\n", argv[0], error->message);
	  return 1;
	}

      if (g_socket_connect (socket, address, cancellable, &error))
	break;
      g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message);
      g_error_free (error);
      error = NULL;

      g_object_unref (address);
    }
  g_object_unref (enumerator);
  g_object_unref (connectable);

  g_print ("Connected to %s\n",
	   socket_address_to_string (address));

  /* TODO: Test non-blocking connect */
  if (non_blocking)
    g_socket_set_blocking (socket, FALSE);

  src_address = g_socket_get_local_address (socket, &error);
  if (!src_address)
    {
      g_printerr ("Error getting local address: %s\n",
		  error->message);
      return 1;
    }
  g_print ("local address: %s\n",
	   socket_address_to_string (src_address));
  g_object_unref (src_address);

  while (TRUE)
    {
      gchar buffer[4096];
      gssize size;
      gsize to_send;

      if (fgets (buffer, sizeof buffer, stdin) == NULL)
	break;

      to_send = strlen (buffer);
      while (to_send > 0)
	{
	  ensure_condition (socket, "send", cancellable, G_IO_OUT);
	  if (use_udp)
	    size = g_socket_send_to (socket, address,
				     buffer, to_send,
				     cancellable, &error);
	  else
	    size = g_socket_send (socket, buffer, to_send,
				  cancellable, &error);

	  if (size < 0)
	    {
	      if (g_error_matches (error,
				   G_IO_ERROR,
				   G_IO_ERROR_WOULD_BLOCK))
		{
		  g_print ("socket send would block, handling\n");
		  g_error_free (error);
		  error = NULL;
		  continue;
		}
	      else
		{
		  g_printerr ("Error sending to socket: %s\n",
			      error->message);
		  return 1;
		}
	    }

	  g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size);

	  if (size == 0)
	    {
	      g_printerr ("Unexpected short write\n");
	      return 1;
	    }

	  to_send -= size;
	}

      ensure_condition (socket, "receive", cancellable, G_IO_IN);
      if (use_udp)
	size = g_socket_receive_from (socket, &src_address,
				      buffer, sizeof buffer,
				      cancellable, &error);
      else
	size = g_socket_receive (socket, buffer, sizeof buffer,
				 cancellable, &error);

      if (size < 0)
	{
	  g_printerr ("Error receiving from socket: %s\n",
		      error->message);
	  return 1;
	}

      if (size == 0)
	break;

      g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size);
      if (use_udp)
	g_print (" from %s", socket_address_to_string (src_address));
      g_print ("\n");

      if (verbose)
	g_print ("-------------------------\n"
		 "%.*s"
		 "-------------------------\n",
		 (int)size, buffer);

    }

  g_print ("closing socket\n");

  if (!g_socket_close (socket, &error))
    {
      g_printerr ("Error closing master socket: %s\n",
		  error->message);
      return 1;
    }

  g_object_unref (G_OBJECT (socket));
  g_object_unref (G_OBJECT (address));

  return 0;
}
Example #17
0
GSocketConnectable *
cockpit_channel_parse_connectable (CockpitChannel *self,
                                   gchar **possible_name)
{
  const gchar *problem = "protocol-error";
  GSocketConnectable *connectable = NULL;
  const gchar *unix_path;
  const gchar *internal;
  JsonObject *options;
  GError *error = NULL;
  const gchar *host;
  gint64 port;

  options = self->priv->open_options;
  if (!cockpit_json_get_string (options, "unix", NULL, &unix_path))
    {
      g_warning ("invalid \"unix\" option in channel");
      goto out;
    }
  if (!cockpit_json_get_int (options, "port", G_MAXINT64, &port))
    {
      g_warning ("invalid \"port\" option in channel");
      goto out;
    }
  if (!cockpit_json_get_string (options, "internal", NULL, &internal))
    {
      g_warning ("invalid \"internal\" option in channel");
      goto out;
    }

  if (port != G_MAXINT64 && unix_path)
    {
      g_warning ("cannot specify both \"port\" and \"unix\" options");
      goto out;
    }
  else if (port != G_MAXINT64)
    {
      if (port <= 0 || port > 65535)
        {
          g_warning ("received invalid \"port\" option");
          goto out;
        }

      if (cockpit_bridge_local_address)
        {
          connectable = g_network_address_parse (cockpit_bridge_local_address, port, &error);
          host = cockpit_bridge_local_address;
        }
      else
        {
          connectable = cockpit_loopback_new (port);
          host = "localhost";
        }
      if (error != NULL)
        {
          g_warning ("couldn't parse local address: %s: %s", host, error->message);
          problem = "internal-error";
          goto out;
        }
      else
        {
          if (possible_name)
            *possible_name = g_strdup_printf ("%s:%d", host, (gint)port);
        }
    }
  else if (unix_path)
    {
      if (possible_name)
        *possible_name = g_strdup (unix_path);
      connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (unix_path));
    }
  else if (internal)
    {
      gboolean reg = FALSE;
      if (internal_addresses)
        {
          reg = g_hash_table_lookup_extended(internal_addresses,
                                             internal,
                                             NULL,
                                             (gpointer *)&connectable);
        }

      if (!connectable)
        {
          if (!reg)
            g_warning ("couldn't find internal address: %s", internal);

          problem = "not-found";
          goto out;
        }

      if (possible_name)
        *possible_name = g_strdup (internal);
      connectable = g_object_ref (connectable);
    }
  else
    {
      g_warning ("no \"port\" or \"unix\" or other address option for channel");
      goto out;
    }

  problem = NULL;

out:
  g_clear_error (&error);
  if (problem)
    {
      cockpit_channel_close (self, problem);
      if (connectable)
        g_object_unref (connectable);
      connectable = NULL;
    }
  return connectable;
}
Example #18
0
static void
dasom_im_init (DasomIM *im)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  GSocketClient  *client;
  GSocketAddress *address;
  GSocket        *socket;
  GError         *error = NULL;

  address = g_unix_socket_address_new_with_type (DASOM_ADDRESS, -1,
                                                 G_UNIX_SOCKET_ADDRESS_ABSTRACT);
  client = g_socket_client_new ();
  im->connection = g_socket_client_connect (client,
                                            G_SOCKET_CONNECTABLE (address),
                                            NULL, &error);
  g_object_unref (address);
  g_object_unref (client);

  if (im->connection == NULL)
  {
    g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message);
    g_clear_error (&error);
    return;
  }

  socket = g_socket_connection_get_socket (im->connection);

  if (!socket)
  {
    g_critical (G_STRLOC ": %s: %s", G_STRFUNC, "Can't get socket");
    return;
  }

  DasomMessage *message;

  DasomConnectionType type = DASOM_CONNECTION_DASOM_IM;

  dasom_send_message (socket, DASOM_MESSAGE_CONNECT, &type, sizeof (DasomConnectionType), NULL);
  g_socket_condition_wait (socket, G_IO_IN, NULL, NULL);
  message = dasom_recv_message (socket);

  if (G_UNLIKELY (message == NULL ||
                  message->header->type != DASOM_MESSAGE_CONNECT_REPLY))
  {
    dasom_message_unref (message);
    g_error ("Couldn't connect to dasom daemon");
  }

  dasom_message_unref (message);

  im->result = g_slice_new0 (DasomResult);
  im->preedit_string = g_strdup ("");

  GMutex mutex;

  g_mutex_init (&mutex);
  g_mutex_lock (&mutex);

  if (G_UNLIKELY (dasom_im_sockets_context == NULL))
  {
    dasom_im_sockets_context = g_main_context_new ();
    dasom_im_sockets_context_ref_count++;
  }
  else
  {
    dasom_im_sockets_context = g_main_context_ref (dasom_im_sockets_context);
    dasom_im_sockets_context_ref_count++;
  }

  g_mutex_unlock (&mutex);

  /* when g_main_context_iteration(), iterate only sockets */
  im->sockets_context_source = g_socket_create_source (socket, G_IO_IN, NULL);
  g_source_set_can_recurse (im->sockets_context_source, TRUE);
  g_source_attach (im->sockets_context_source, dasom_im_sockets_context);
  g_source_set_callback (im->sockets_context_source,
                         (GSourceFunc) on_incoming_message,
                         im, NULL);

  im->default_context_source = g_socket_create_source (socket, G_IO_IN, NULL);
  g_source_set_can_recurse (im->default_context_source, TRUE);
  g_source_set_callback (im->default_context_source,
                         (GSourceFunc) on_incoming_message, im, NULL);
  g_source_attach (im->default_context_source, NULL);
}
Example #19
0
static GSocketConnectable *
parse_address (CockpitChannel *self,
               gchar **possible_name,
               gboolean *local_address)
{
  GSocketConnectable *connectable = NULL;
  const gchar *unix_path;
  const gchar *internal;
  const gchar *address;
  JsonObject *options;
  gboolean local = FALSE;
  GError *error = NULL;
  const gchar *host;
  gint64 port;
  gchar *name = NULL;
  gboolean open = FALSE;

  options = self->priv->open_options;
  if (!cockpit_json_get_string (options, "unix", NULL, &unix_path))
    {
      cockpit_channel_fail (self, "protocol-error", "invalid \"unix\" option in channel");
      goto out;
    }
  if (!cockpit_json_get_int (options, "port", G_MAXINT64, &port))
    {
      cockpit_channel_fail (self, "protocol-error", "invalid \"port\" option in channel");
      goto out;
    }
  if (!cockpit_json_get_string (options, "internal", NULL, &internal))
    {
      cockpit_channel_fail (self, "protocol-error", "invalid \"internal\" option in channel");
      goto out;
    }
  if (!cockpit_json_get_string (options, "address", NULL, &address))
    {
      cockpit_channel_fail (self, "protocol-error", "invalid \"address\" option in channel");
      goto out;
    }

  if (port != G_MAXINT64 && unix_path)
    {
      cockpit_channel_fail (self, "protocol-error", "cannot specify both \"port\" and \"unix\" options");
      goto out;
    }
  else if (port != G_MAXINT64)
    {
      if (port <= 0 || port > 65535)
        {
          cockpit_channel_fail (self, "protocol-error", "received invalid \"port\" option");
          goto out;
        }

      if (address)
        {
          connectable = g_network_address_new (address, port);
          host = address;

          /* This isn't perfect, but matches the use case. Specify address => non-local */
          local = FALSE;
        }
      else if (cockpit_bridge_local_address)
        {
          connectable = g_network_address_parse (cockpit_bridge_local_address, port, &error);
          host = cockpit_bridge_local_address;
          local = TRUE;
        }
      else
        {
          connectable = cockpit_loopback_new (port);
          host = "localhost";
          local = TRUE;
        }

      if (error != NULL)
        {
          cockpit_channel_fail (self, "internal-error",
                                "couldn't parse local address: %s: %s", host, error->message);
          goto out;
        }
      else
        {
          name = g_strdup_printf ("%s:%d", host, (gint)port);
        }
    }
  else if (unix_path)
    {
      name = g_strdup (unix_path);
      connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (unix_path));
      local = FALSE;
    }
  else if (internal)
    {
      gboolean reg = lookup_internal (internal, &connectable);

      if (!connectable)
        {
          if (reg)
            cockpit_channel_close (self, "not-found");
          else
            cockpit_channel_fail (self, "not-found", "couldn't find internal address: %s", internal);
          goto out;
        }

      name = g_strdup (internal);
      connectable = g_object_ref (connectable);
      local = FALSE;
    }
  else
    {
      cockpit_channel_fail (self, "protocol-error",
                            "no \"port\" or \"unix\" or other address option for channel");
      goto out;
    }

  open = TRUE;

out:
  g_clear_error (&error);
  if (open)
    {
      if (possible_name)
          *possible_name = g_strdup (name);
      if (local_address)
        *local_address = local;
    }
  else
    {
      if (connectable)
        g_object_unref (connectable);
      connectable = NULL;
    }

  g_free (name);
  return connectable;
}