示例#1
0
/*
 * This function will be called when our CGI is accessed.
 */
static void
request_handler(const gchar *path,
        const gchar *method,
        const gchar *query,
        GHashTable *params,
        GOutputStream *output_stream,
        gpointer user_data)
{
    GDataOutputStream *dos;
    guint *timer = (guint*) user_data;
    gchar msg[128];

    dos = g_data_output_stream_new(output_stream);

    /* Send out the HTTP response status code */
    g_data_output_stream_put_string(dos,"Content-Type: text/plain\r\n", NULL, NULL);
    g_data_output_stream_put_string(dos,"Status: 200 OK\r\n\r\n", NULL, NULL);

    /* Our custom message */
    g_snprintf(msg, sizeof(msg),"You have accessed '%s'\n", path ? path:"(NULL)");
    g_data_output_stream_put_string(dos, msg, NULL, NULL);

    g_snprintf(msg, sizeof(msg), "\n%s() [%s:%d] \n\n"
                                                             "-  Hello World! -\n"
                                                             "I've been running for %d seconds\n",
                                                             __FUNCTION__, __FILE__, __LINE__, *timer );
    g_data_output_stream_put_string(dos, msg, NULL, NULL);

    g_object_unref(dos);
}
示例#2
0
static void
gspeechd_client_read_speak_data_cb (GInputStream *stream,
                       				GAsyncResult *res,
                       				gpointer user_data)
{
	GSpeechdClient *client = user_data;
	gchar *s, *response;
	gsize len;
	SsipStatus status;
	gboolean ret;
	GError *error = NULL;

	s = g_data_input_stream_read_line_finish (G_DATA_INPUT_STREAM(stream),
	                                          res,
                                              &len,
	                                          &error);
	g_printf ("--->%s\n",s);

#define END_SPEAK_DATA_STR ".\xD"
#define END_SPEAK_DATA_RESPONSE "225-1\r\n"
	if (g_strcmp0 (s, END_SPEAK_DATA_STR) != 0) {
		g_data_input_stream_read_line_async(client->input,
								G_PRIORITY_DEFAULT,
								client->cancellable,
								(GAsyncReadyCallback)gspeechd_client_read_speak_data_cb,
								gspeechd_client_ref (client));
		return;
	}

	ret = g_data_output_stream_put_string (client->output,
	                                       END_SPEAK_DATA_RESPONSE,
					                       client->cancellable,
					                       NULL);
	g_printf ("%d %s\n", ret, END_SPEAK_DATA_RESPONSE);

	status = OK_MESSAGE_QUEUED;
	response = ssip_response (status);
	ret = g_data_output_stream_put_string (client->output,
	                                       response,
					                       client->cancellable,
					                       NULL);
	g_printf ("%d %s\n", ret, response);

	/* parse commands again */
	g_data_input_stream_read_line_async(client->input,
							G_PRIORITY_DEFAULT,
							client->cancellable,
							(GAsyncReadyCallback)gspeechd_client_read_line_cb,
							gspeechd_client_ref (client));
}
示例#3
0
文件: io.c 项目: SteveJones/j4status
static gboolean
_j4status_io_stream_put_string(J4statusIOStream *self, const gchar *string)
{
    if ( string == NULL )
        return TRUE;
    if ( self->out == NULL )
        return FALSE;

    GError *error = NULL;
    if ( g_data_output_stream_put_string(self->out, string, NULL, &error) )
        return TRUE;

    /*
     * We do not output on broken pipe
     * because this is what we get on disconnect.
     * Too frequent to warrant a warning.
     */
    if ( ! g_error_matches(error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) )
        g_warning("Couldn't write line: %s", error->message);
    g_clear_error(&error);

    _j4status_io_stream_reconnect_maybe(self);

    return FALSE;
}
static gboolean
write_escaped (GDataOutputStream   *stream,
               const char          *str,
               GError             **error)
{
  gboolean ret;
  char *quoted = g_markup_escape_text (str, -1);
  ret = g_data_output_stream_put_string (stream, quoted, NULL, error);
  g_free (quoted);
  return ret;
}
示例#5
0
static VALUE
stream_put_string(int argc, VALUE *argv, VALUE self)
{
        VALUE value, cancellable;
        GError *error = NULL;

        rb_scan_args(argc, argv, "11", &value, &cancellable);
        if (!g_data_output_stream_put_string(_SELF(self), RVAL2CSTR(value),
                                             RVAL2GCANCELLABLE(cancellable), &error))
                rbgio_raise_io_error(error);

        return self;
}
示例#6
0
static void
disabled_repos_free (GHashTable *disabled)
{
	GHashTableIter iter;
	GFile *file;

	GFileOutputStream *file_stream;
	GDataOutputStream *data_stream;

	const gchar *line = PACMAN_REPO_LIST_HEADER "\n";

	g_return_if_fail (disabled != NULL);

	g_debug ("pacman: storing disabled repos in %s", PACMAN_REPO_LIST);
	file = g_file_new_for_path (PACMAN_REPO_LIST);
	file_stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL);

	if (file_stream == NULL) {
		g_object_unref (file);
		g_hash_table_unref (disabled);
		return;
	}

	g_hash_table_iter_init (&iter, disabled);
	data_stream = g_data_output_stream_new (G_OUTPUT_STREAM (file_stream));

	/* write header, then all disabled repos line by line */
	if (g_data_output_stream_put_string (data_stream, line, NULL, NULL)) {
		while (g_hash_table_iter_next (&iter, (gpointer *) &line, NULL) &&
			g_data_output_stream_put_string (data_stream, line, NULL, NULL) &&
			g_data_output_stream_put_string (data_stream, "\n", NULL, NULL));
	}

	g_object_unref (data_stream);
	g_object_unref (file_stream);
	g_object_unref (file);
	g_hash_table_unref (disabled);
}
示例#7
0
static VALUE
put_value(int argc, VALUE *argv, VALUE self)
{
        VALUE value,
              cancellable;
        gboolean success;
        GError *error = NULL;

        rb_scan_args(argc, argv, "11", &value, &cancellable);

        /* TODO: How do we convert from a Number to uint64 through byte in a
         * reliable manner?  Is it even sane to do so? */
        switch (TYPE(value)) {
        case T_STRING:
                success = g_data_output_stream_put_string(_SELF(self),
                                                          RVAL2CSTR(value),
                                                          cancellable,
                                                          &error);
                break;

        if (!success)
                rbgio_raise_io_error(error);

        return self;
}
#endif

void
Init_gdataoutputstream(VALUE glib)
{
        VALUE dataoutputstream = G_DEF_CLASS(G_TYPE_DATA_OUTPUT_STREAM, "DataOutputStream", glib);

        rb_define_method(dataoutputstream, "initialize", stream_initialize, -1);
        rb_define_method(dataoutputstream, "byte_order", stream_byte_order, 0);
	rb_define_method(dataoutputstream, "set_byte_order", stream_set_byte_order, 1);
	G_DEF_SETTER(dataoutputstream, "byte_order");
        rb_define_method(dataoutputstream, "put_byte", stream_put_byte, -1);
        rb_define_method(dataoutputstream, "put_int16", stream_put_int16, -1);
        rb_define_method(dataoutputstream, "put_uint16", stream_put_uint16, -1);
        rb_define_method(dataoutputstream, "put_int32", stream_put_int32, -1);
        rb_define_method(dataoutputstream, "put_uint32", stream_put_uint32, -1);
        rb_define_method(dataoutputstream, "put_int64", stream_put_int64, -1);
        rb_define_method(dataoutputstream, "put_uint64", stream_put_uint64, -1);
        rb_define_method(dataoutputstream, "put_string", stream_put_string, -1);
        rb_define_alias(dataoutputstream, "<<", "put_string");
        rb_define_alias(dataoutputstream, "write", "put_string");

        /* TODO: Should we add #put_value/#put? */
}
static gboolean
write_attribute_string (GDataOutputStream *stream,
                        const char        *elt_name,
                        const char        *str,
                        GError           **error)
{
  gboolean ret = FALSE;
  char *elt;

  elt = g_strdup_printf (" %s=\"", elt_name);
  ret = g_data_output_stream_put_string (stream, elt, NULL, error);
  g_free (elt);
  if (!ret)
    goto out;

  ret = write_escaped (stream, str, error);
  if (!ret)
    goto out;

  ret = g_data_output_stream_put_string (stream, "\"", NULL, error);

out:
  return ret;
}
示例#9
0
static void
put_string (GDataOutputStream *out,
	    const char *str)
{
  gsize len;

  len = strlen (str);
  if (len > G_MAXUINT16)
    {
      g_warning ("GFileInfo string to large, (%d bytes)\n", (int)len);
      len = 0;
      str = "";
    }
  
  g_data_output_stream_put_uint16 (out, len,
				   NULL, NULL);
  g_data_output_stream_put_string (out, str, NULL, NULL);
}
示例#10
0
static void
disabled_repos_free (GHashTable *table)
{
	GHashTableIter iter;
	GFile *file;

	GFileOutputStream *os;
	GDataOutputStream *output;

	const gchar *line;

	g_return_if_fail (table != NULL);

	g_debug ("storing disabled repos in %s", PK_BACKEND_REPO_FILE);
	file = g_file_new_for_path (PK_BACKEND_REPO_FILE);
	os = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL);

	if (os == NULL) {
		g_object_unref (file);
		g_hash_table_unref (table);
		return;
	}

	g_hash_table_iter_init (&iter, table);
	output = g_data_output_stream_new (G_OUTPUT_STREAM (os));

	/* write all disabled repos line by line */
	while (g_hash_table_iter_next (&iter, (gpointer *) &line, NULL) &&
	       g_data_output_stream_put_string (output, line, NULL, NULL) &&
	       g_data_output_stream_put_byte (output, '\n', NULL, NULL));

	g_object_unref (output);
	g_object_unref (os);
	g_object_unref (file);

	g_hash_table_unref (table);
}
示例#11
0
static gboolean
test_client_do (TestClient *client,
                GError    **error,
                ...)
{
  GString *command = g_string_new (NULL);
  char *line = NULL;

  va_list vap;
  va_start (vap, error);

  while (TRUE)
    {
      char *word = va_arg (vap, char *);
      if (word == NULL)
        break;

      if (command->len > 0)
        g_string_append_c (command, ' ');

      char *quoted = g_shell_quote (word);
      g_string_append (command, quoted);
      g_free (quoted);
    }

  va_end (vap);

  g_string_append_c (command, '\n');

  if (!g_data_output_stream_put_string (client->in, command->str,
                                        client->cancellable, error))
    goto out;

  g_data_input_stream_read_line_async (client->out,
                                       G_PRIORITY_DEFAULT,
                                       client->cancellable,
                                       test_client_line_read,
                                       client);

  client->error = error;
  g_main_loop_run (client->loop);
  line = client->line;
  client->line = NULL;
  client->error = NULL;

  if (!line)
    {
      if (*error == NULL)
        g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_RUNTIME_ERROR,
                     "test client exited");
      goto out;
    }

  if (strcmp (line, "OK") != 0)
    {
      g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_RUNTIME_ERROR,
                   "%s", line);
      goto out;
    }

 out:
  g_string_free (command, TRUE);
  g_free (line);

  return *error == NULL;
}
示例#12
0
static void
_j4status_core_debug_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
{
    GDataOutputStream *stream = user_data;

    g_log_default_handler(log_domain, log_level, message, NULL);

    const gchar *prg_name;
    gchar pid[128];
    prg_name = g_get_prgname();
    g_sprintf(pid, "%lu", (gulong) getpid());

    g_data_output_stream_put_string(stream, "(", NULL, NULL);
    if ( prg_name != NULL )
    {
        g_data_output_stream_put_string(stream, prg_name, NULL, NULL);
        g_data_output_stream_put_string(stream, ":", NULL, NULL);
    }
    else
        g_data_output_stream_put_string(stream, "process:", NULL, NULL);
    g_data_output_stream_put_string(stream, pid, NULL, NULL);
    g_data_output_stream_put_string(stream, ") ", NULL, NULL);

    const gchar *log_level_message = "";
    switch ( log_level & G_LOG_LEVEL_MASK )
    {
        case G_LOG_LEVEL_ERROR:
            log_level_message = "ERROR";
        break;
        case G_LOG_LEVEL_CRITICAL:
            log_level_message = "CRITICAL";
        break;
        case G_LOG_LEVEL_WARNING:
            log_level_message = "WARNING";
        break;
        case G_LOG_LEVEL_MESSAGE:
            log_level_message = "MESSAGE";
        break;
        case G_LOG_LEVEL_INFO:
            log_level_message = "INFO";
        break;
        case G_LOG_LEVEL_DEBUG:
            log_level_message = "DEBUG";
        break;
    }
    g_data_output_stream_put_string(stream, log_level_message, NULL, NULL);

    if ( log_domain != NULL )
    {
        g_data_output_stream_put_string(stream, " [", NULL, NULL);
        g_data_output_stream_put_string(stream, log_domain, NULL, NULL);
        g_data_output_stream_put_string(stream, "]", NULL, NULL);
    }

    g_data_output_stream_put_string(stream, ": ", NULL, NULL);
    g_data_output_stream_put_string(stream, message, NULL, NULL);
    g_data_output_stream_put_byte(stream, '\n', NULL, NULL);
}
static gboolean
goa_smtp_auth_starttls_sync (GoaMailAuth         *auth,
                             GCancellable        *cancellable,
                             GError             **error)
{
  GoaSmtpAuth *self = GOA_SMTP_AUTH (auth);
  GDataInputStream *input;
  GDataOutputStream *output;
  gboolean ret;
  gboolean starttls_supported;
  gchar *domain;
  gchar *request;
  gchar *response;

  starttls_supported = FALSE;
  domain = NULL;
  request = NULL;
  response = NULL;

  ret = FALSE;

  domain = smtp_auth_get_domain (self, error);
  if (domain == NULL)
    goto out;

  input = goa_mail_auth_get_input (auth);
  output = goa_mail_auth_get_output (auth);

  /* Check the greeting */

  if (!smtp_auth_check_greeting (input, cancellable, error))
    goto out;

  /* Send EHLO */

  request = g_strdup_printf ("EHLO %s\r\n", domain);
  g_debug ("> %s", request);
  if (!g_data_output_stream_put_string (output, request, cancellable, error))
    goto out;
  g_clear_pointer (&request, g_free);

  /* Check if STARTTLS is supported or not */

 ehlo_again:
  response = goa_utils_data_input_stream_read_line (input, NULL, cancellable, error);
  if (response == NULL)
    goto out;
  g_debug ("< %s", response);
  if (smtp_auth_check_421 (response, error))
    goto out;
  if (smtp_auth_check_not_250 (response, error))
    goto out;

  if (g_str_has_prefix (response + 4, "STARTTLS"))
    starttls_supported = TRUE;

  if (response[3] == '-')
    {
      g_free (response);
      goto ehlo_again;
    }
  else if (!starttls_supported)
    {
      g_set_error (error,
                   GOA_ERROR,
                   GOA_ERROR_NOT_SUPPORTED,
                   _("Server does not support STARTTLS"));
      goto out;
    }
  g_clear_pointer (&response, g_free);

  /* Send STARTTLS */

  request = g_strdup ("STARTTLS\r\n");
  g_debug ("> %s", request);
  if (!g_data_output_stream_put_string (output, request, cancellable, error))
    goto out;
  g_clear_pointer (&request, g_free);

  response = goa_utils_data_input_stream_read_line (input, NULL, cancellable, error);
  if (response == NULL)
    goto out;
  g_debug ("< %s", response);
  if (smtp_auth_check_454 (response, error))
    goto out;
  if (smtp_auth_check_not_220 (response, error))
    goto out;
  g_clear_pointer (&response, g_free);

  /* There won't be a greeting after this */
  self->greeting_absent = TRUE;

  ret = TRUE;

 out:
  g_free (domain);
  g_free (response);
  g_free (request);
  return ret;
}
static gboolean
goa_smtp_auth_run_sync (GoaMailAuth         *auth,
                        GCancellable        *cancellable,
                        GError             **error)
{
  GoaSmtpAuth *self = GOA_SMTP_AUTH (auth);
  GDataInputStream *input;
  GDataOutputStream *output;
  gboolean ret;
  gchar *auth_arg_base64;
  gchar *auth_arg_plain;
  gchar *domain;
  gchar *password;
  gchar *request;
  gchar *response;
  gsize auth_arg_plain_len;

  auth_arg_base64 = NULL;
  auth_arg_plain = NULL;
  domain = NULL;
  password = NULL;
  request = NULL;
  response = NULL;

  ret = FALSE;

  password = smtp_auth_get_password (self, cancellable, error);
  if (password == NULL)
    goto out;

  domain = smtp_auth_get_domain (self, error);
  if (domain == NULL)
    goto out;

  input = goa_mail_auth_get_input (auth);
  output = goa_mail_auth_get_output (auth);

  /* Check the greeting, if there is one */

  if (!self->greeting_absent)
    {
      if (!smtp_auth_check_greeting (input, cancellable, error))
        goto out;
    }

  /* Send EHLO */

  request = g_strdup_printf ("EHLO %s\r\n", domain);
  g_debug ("> %s", request);
  if (!g_data_output_stream_put_string (output, request, cancellable, error))
    goto out;
  g_clear_pointer (&request, g_free);

  /* Check which SASL mechanisms are supported */

 ehlo_again:
  response = goa_utils_data_input_stream_read_line (input, NULL, cancellable, error);
  if (response == NULL)
    goto out;
  g_debug ("< %s", response);
  if (smtp_auth_check_421 (response, error))
    goto out;
  if (smtp_auth_check_not_250 (response, error))
    goto out;

  if (g_str_has_prefix (response + 4, "AUTH"))
    {
      self->auth_supported = TRUE;
      if (strstr (response, "PLAIN") != NULL)
        self->plain_supported = TRUE;
      else if (strstr (response, "LOGIN") != NULL)
        self->login_supported = TRUE;
    }

  if (response[3] == '-')
    {
      g_free (response);
      goto ehlo_again;
    }
  else if (!self->auth_supported)
    {
      ret = TRUE;
      goto out;
    }
  else if (!self->login_supported && !self->plain_supported)
    {
      g_set_error (error,
                   GOA_ERROR,
                   GOA_ERROR_NOT_SUPPORTED,
                   _("Unknown authentication mechanism"));
      goto out;
    }
  g_clear_pointer (&response, g_free);

  /* Try different SASL mechanisms */

  if (self->plain_supported)
    {
      /* AUTH PLAIN */

      auth_arg_plain = g_strdup_printf ("%s%c%s%c%s", self->username, '\0', self->username, '\0', password);
      auth_arg_plain_len = 2 * strlen (self->username) + 2 + strlen (password);
      auth_arg_base64 = g_base64_encode ((guchar *) auth_arg_plain, auth_arg_plain_len);

      request = g_strdup_printf ("AUTH PLAIN %s\r\n", auth_arg_base64);
      g_debug ("> AUTH PLAIN ********************");
      if (!g_data_output_stream_put_string (output, request, cancellable, error))
        goto out;
      g_clear_pointer (&request, g_free);
    }
  else
    {
      /* AUTH LOGIN */

      auth_arg_plain = g_strdup (self->username);
      auth_arg_plain_len = strlen (self->username);
      auth_arg_base64 = g_base64_encode ((guchar *) auth_arg_plain, auth_arg_plain_len);

      request = g_strdup_printf ("AUTH LOGIN %s\r\n", auth_arg_base64);
      g_debug ("> AUTH LOGIN ********************");
      if (!g_data_output_stream_put_string (output, request, cancellable, error))
        goto out;
      g_clear_pointer (&request, g_free);

      response = goa_utils_data_input_stream_read_line (input, NULL, cancellable, error);
      if (response == NULL)
        goto out;
      g_debug ("< %s", response);
      if (smtp_auth_check_not_334_login_password (response, error))
        goto out;

      g_free (auth_arg_plain);
      g_free (auth_arg_base64);

      auth_arg_plain = g_strdup (password);
      auth_arg_plain_len = strlen (password);
      auth_arg_base64 = g_base64_encode ((guchar *) auth_arg_plain, auth_arg_plain_len);

      request = g_strdup_printf ("%s\r\n", auth_arg_base64);
      g_debug ("> ********************");
      if (!g_data_output_stream_put_string (output, request, cancellable, error))
        goto out;
      g_clear_pointer (&request, g_free);
    }

  response = goa_utils_data_input_stream_read_line (input, NULL, cancellable, error);
  if (response == NULL)
    goto out;
  g_debug ("< %s", response);
  if (smtp_auth_check_not_235 (response, error))
    goto out;
  g_clear_pointer (&response, g_free);

  ret = TRUE;

 out:
  g_free (auth_arg_base64);
  g_free (auth_arg_plain);
  g_free (domain);
  g_free (password);
  g_free (response);
  g_free (request);
  return ret;
}
示例#15
0
文件: gdbusauth.c 项目: Andais/glib
gchar *
_g_dbus_auth_run_client (GDBusAuth     *auth,
                         GDBusCapabilityFlags offered_capabilities,
                         GDBusCapabilityFlags *out_negotiated_capabilities,
                         GCancellable  *cancellable,
                         GError       **error)
{
  gchar *s;
  GDataInputStream *dis;
  GDataOutputStream *dos;
  GCredentials *credentials;
  gchar *ret_guid;
  gchar *line;
  gsize line_length;
  gchar **supported_auth_mechs;
  GPtrArray *attempted_auth_mechs;
  GDBusAuthMechanism *mech;
  ClientState state;
  GDBusCapabilityFlags negotiated_capabilities;

  debug_print ("CLIENT: initiating");

  ret_guid = NULL;
  supported_auth_mechs = NULL;
  attempted_auth_mechs = g_ptr_array_new ();
  mech = NULL;
  negotiated_capabilities = 0;
  credentials = NULL;

  dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream)));
  dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream)));
  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE);
  g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE);

  g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);

#ifdef G_OS_UNIX
  if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ())
    {
      credentials = g_credentials_new ();
      if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (auth->priv->stream),
                                               cancellable,
                                               error))
        goto out;
    }
  else
    {
      if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error))
        goto out;
    }
#else
  if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error))
    goto out;
#endif

  if (credentials != NULL)
    {
      if (G_UNLIKELY (_g_dbus_debug_authentication ()))
        {
          s = g_credentials_to_string (credentials);
          debug_print ("CLIENT: sent credentials `%s'", s);
          g_free (s);
        }
    }
  else
    {
      debug_print ("CLIENT: didn't send any credentials");
    }

  /* TODO: to reduce roundtrips, try to pick an auth mechanism to start with */

  /* Get list of supported authentication mechanisms */
  s = "AUTH\r\n";
  debug_print ("CLIENT: writing `%s'", s);
  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
    goto out;
  state = CLIENT_STATE_WAITING_FOR_REJECT;

  while (TRUE)
    {
      switch (state)
        {
        case CLIENT_STATE_WAITING_FOR_REJECT:
          debug_print ("CLIENT: WaitingForReject");
          line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
          if (line == NULL)
            goto out;
          debug_print ("CLIENT: WaitingForReject, read '%s'", line);
        foobar:
          if (!g_str_has_prefix (line, "REJECTED "))
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           "In WaitingForReject: Expected `REJECTED am1 am2 ... amN', got `%s'",
                           line);
              g_free (line);
              goto out;
            }
          if (supported_auth_mechs == NULL)
            {
              supported_auth_mechs = g_strsplit (line + sizeof ("REJECTED ") - 1, " ", 0);
#if 0
              for (n = 0; supported_auth_mechs != NULL && supported_auth_mechs[n] != NULL; n++)
                g_printerr ("supported_auth_mechs[%d] = `%s'\n", n, supported_auth_mechs[n]);
#endif
            }
          g_free (line);
          mech = client_choose_mech_and_send_initial_response (auth,
                                                               credentials,
                                                               (const gchar* const *) supported_auth_mechs,
                                                               attempted_auth_mechs,
                                                               dos,
                                                               cancellable,
                                                               error);
          if (mech == NULL)
            goto out;
          if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA)
            state = CLIENT_STATE_WAITING_FOR_DATA;
          else
            state = CLIENT_STATE_WAITING_FOR_OK;
          break;

        case CLIENT_STATE_WAITING_FOR_OK:
          debug_print ("CLIENT: WaitingForOK");
          line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
          if (line == NULL)
            goto out;
          debug_print ("CLIENT: WaitingForOK, read `%s'", line);
          if (g_str_has_prefix (line, "OK "))
            {
              if (!g_dbus_is_guid (line + 3))
                {
                  g_set_error (error,
                               G_IO_ERROR,
                               G_IO_ERROR_FAILED,
                               "Invalid OK response `%s'",
                               line);
                  g_free (line);
                  goto out;
                }
              ret_guid = g_strdup (line + 3);
              g_free (line);

              if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
                {
                  s = "NEGOTIATE_UNIX_FD\r\n";
                  debug_print ("CLIENT: writing `%s'", s);
                  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                    goto out;
                  state = CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD;
                }
              else
                {
                  s = "BEGIN\r\n";
                  debug_print ("CLIENT: writing `%s'", s);
                  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                    goto out;
                  /* and we're done! */
                  goto out;
                }
            }
          else if (g_str_has_prefix (line, "REJECTED "))
            {
              goto foobar;
            }
          else
            {
              /* TODO: handle other valid responses */
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           "In WaitingForOk: unexpected response `%s'",
                           line);
              g_free (line);
              goto out;
            }
          break;

        case CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD:
          debug_print ("CLIENT: WaitingForAgreeUnixFD");
          line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
          if (line == NULL)
            goto out;
          debug_print ("CLIENT: WaitingForAgreeUnixFD, read=`%s'", line);
          if (g_strcmp0 (line, "AGREE_UNIX_FD") == 0)
            {
              g_free (line);
              negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING;
              s = "BEGIN\r\n";
              debug_print ("CLIENT: writing `%s'", s);
              if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                goto out;
              /* and we're done! */
              goto out;
            }
          else if (g_str_has_prefix (line, "ERROR") && (line[5] == 0 || g_ascii_isspace (line[5])))
            {
              //g_strstrip (line + 5); g_debug ("bah, no unix_fd: `%s'", line + 5);
              g_free (line);
              s = "BEGIN\r\n";
              debug_print ("CLIENT: writing `%s'", s);
              if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                goto out;
              /* and we're done! */
              goto out;
            }
          else
            {
              /* TODO: handle other valid responses */
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           "In WaitingForAgreeUnixFd: unexpected response `%s'",
                           line);
              g_free (line);
              goto out;
            }
          break;

        case CLIENT_STATE_WAITING_FOR_DATA:
          debug_print ("CLIENT: WaitingForData");
          line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
          if (line == NULL)
            goto out;
          debug_print ("CLIENT: WaitingForData, read=`%s'", line);
          if (g_str_has_prefix (line, "DATA "))
            {
              gchar *encoded;
              gchar *decoded_data;
              gsize decoded_data_len;

              encoded = g_strdup (line + 5);
              g_free (line);
              g_strstrip (encoded);
              decoded_data = hexdecode (encoded, &decoded_data_len, error);
              g_free (encoded);
              if (decoded_data == NULL)
                {
                  g_prefix_error (error, "DATA response is malformed: ");
                  /* invalid encoding, disconnect! */
                  goto out;
                }
              _g_dbus_auth_mechanism_client_data_receive (mech, decoded_data, decoded_data_len);
              g_free (decoded_data);

              if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND)
                {
                  gchar *data;
                  gsize data_len;
                  gchar *encoded_data;
                  data = _g_dbus_auth_mechanism_client_data_send (mech, &data_len);
                  encoded_data = hexencode (data);
                  s = g_strdup_printf ("DATA %s\r\n", encoded_data);
                  g_free (encoded_data);
                  g_free (data);
                  debug_print ("CLIENT: writing `%s'", s);
                  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                    {
                      g_free (s);
                      goto out;
                    }
                  g_free (s);
                }
              state = CLIENT_STATE_WAITING_FOR_OK;
            }
          else
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           "In WaitingForData: unexpected response `%s'",
                           line);
              g_free (line);
              goto out;
            }
          break;

        default:
          g_assert_not_reached ();
          break;
        }

    }; /* main authentication client loop */

 out:
  if (mech != NULL)
    g_object_unref (mech);
  g_ptr_array_unref (attempted_auth_mechs);
  g_strfreev (supported_auth_mechs);
  g_object_unref (dis);
  g_object_unref (dos);

  /* ensure return value is NULL if error is set */
  if (error != NULL && *error != NULL)
    {
      g_free (ret_guid);
      ret_guid = NULL;
    }

  if (ret_guid != NULL)
    {
      if (out_negotiated_capabilities != NULL)
        *out_negotiated_capabilities = negotiated_capabilities;
    }

  if (credentials != NULL)
    g_object_unref (credentials);

  debug_print ("CLIENT: Done, authenticated=%d", ret_guid != NULL);

  return ret_guid;
}
示例#16
0
static void
gspeechd_client_read_line_cb (GInputStream *stream,
                       GAsyncResult *res,
                       gpointer user_data)
{
	GSpeechdClient *client = user_data;
	gchar *s, *response;
	gsize len;
	gboolean ret;
	GError *error = NULL;
	SsipCommand *cmd;
	SsipStatus status;

	/* read lines and removes newline */
	s = g_data_input_stream_read_line_finish (G_DATA_INPUT_STREAM(stream),
	                                          res,
                                              &len,
	                                          &error);
	if (error != NULL ) {
		g_printf ("-->%s\n", error->message);
		g_error_free (error);
		return;
	}

	if (s == NULL) {
		/* client has closed a connection */
		g_printf ("-->connection closed\n");
		return; 
	}

	g_printf ("-->%s\n", s);

	/* parse SSIP command */
	cmd = ssip_command_new (s);
	/* TODO remove history */
	client->history = g_list_append (client->history, s);

	/* process command */
	switch (ssip_cmd_get (cmd)) {
		case SSIP_CMD_SET:
			switch (ssip_set_param_get (cmd)) {
				case SSIP_SET_PARAM_CLIENT_NAME:
					/* TODO free previous name before */
					client->name = g_strdup (ssip_set_param_value_get (cmd));
					/* TODO emit event to the server */
					status = OK_CLIENT_NAME_SET;
					break;
				case SSIP_SET_PARAM_PRIORITY:
					status = OK_PRIORITY_SET;
					break;
				default:
					break;
			}
			break;
		case SSIP_CMD_SPEAK:
			status = OK_RECEIVE_DATA;
			response = ssip_response (status);
			ret = g_data_output_stream_put_string (client->output,
	        		                               response,
							                       client->cancellable,
					        		               NULL);
			g_printf ("%d %s\n", ret, response);
			g_data_input_stream_read_line_async(client->input,
									G_PRIORITY_DEFAULT,
									client->cancellable,
									(GAsyncReadyCallback)gspeechd_client_read_speak_data_cb,
									gspeechd_client_ref (client));
			return;
		case SSIP_CMD_HELP:
		default:
			break;
	}

	response = ssip_response (status);
	ret = g_data_output_stream_put_string (client->output,
	                                       response,
					                       client->cancellable,
					                       NULL);
	g_printf ("%d %s\n", ret, response);

	/* when QUIT received, send an event connection_closed */

	g_data_input_stream_read_line_async(client->input,
							G_PRIORITY_DEFAULT,
							client->cancellable,
							(GAsyncReadyCallback)gspeechd_client_read_line_cb,
							gspeechd_client_ref (client));
}
示例#17
0
文件: gdbusauth.c 项目: Andais/glib
gboolean
_g_dbus_auth_run_server (GDBusAuth              *auth,
                         GDBusAuthObserver      *observer,
                         const gchar            *guid,
                         gboolean                allow_anonymous,
                         GDBusCapabilityFlags    offered_capabilities,
                         GDBusCapabilityFlags   *out_negotiated_capabilities,
                         GCredentials          **out_received_credentials,
                         GCancellable           *cancellable,
                         GError                **error)
{
  gboolean ret;
  ServerState state;
  GDataInputStream *dis;
  GDataOutputStream *dos;
  GError *local_error;
  guchar byte;
  gchar *line;
  gsize line_length;
  GDBusAuthMechanism *mech;
  gchar *s;
  GDBusCapabilityFlags negotiated_capabilities;
  GCredentials *credentials;

  debug_print ("SERVER: initiating");

  ret = FALSE;
  dis = NULL;
  dos = NULL;
  mech = NULL;
  negotiated_capabilities = 0;
  credentials = NULL;

  if (!g_dbus_is_guid (guid))
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_FAILED,
                   "The given guid `%s' is not valid",
                   guid);
      goto out;
    }

  dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream)));
  dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream)));
  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE);
  g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE);

  g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);

  /* first read the NUL-byte (TODO: read credentials if using a unix domain socket) */
#ifdef G_OS_UNIX
  if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ())
    {
      local_error = NULL;
      credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream),
                                                           cancellable,
                                                           &local_error);
      if (credentials == NULL)
        {
          g_propagate_error (error, local_error);
          goto out;
        }
    }
  else
    {
      local_error = NULL;
      byte = g_data_input_stream_read_byte (dis, cancellable, &local_error);
      if (local_error != NULL)
        {
          g_propagate_error (error, local_error);
          goto out;
        }
    }
#else
  local_error = NULL;
  byte = g_data_input_stream_read_byte (dis, cancellable, &local_error);
  if (local_error != NULL)
    {
      g_propagate_error (error, local_error);
      goto out;
    }
#endif
  if (credentials != NULL)
    {
      if (G_UNLIKELY (_g_dbus_debug_authentication ()))
        {
          s = g_credentials_to_string (credentials);
          debug_print ("SERVER: received credentials `%s'", s);
          g_free (s);
        }
    }
  else
    {
      debug_print ("SERVER: didn't receive any credentials");
    }

  state = SERVER_STATE_WAITING_FOR_AUTH;
  while (TRUE)
    {
      switch (state)
        {
        case SERVER_STATE_WAITING_FOR_AUTH:
          debug_print ("SERVER: WaitingForAuth");
          line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
          debug_print ("SERVER: WaitingForAuth, read `%s'", line);
          if (line == NULL)
            goto out;
          if (g_strcmp0 (line, "AUTH") == 0)
            {
              s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " ");
              debug_print ("SERVER: writing `%s'", s);
              if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                {
                  g_free (s);
                  goto out;
                }
              g_free (s);
              g_free (line);
            }
          else if (g_str_has_prefix (line, "AUTH "))
            {
              gchar **tokens;
              const gchar *encoded;
              const gchar *mech_name;
              GType auth_mech_to_use_gtype;

              tokens = g_strsplit (line, " ", 0);
              g_free (line);

              switch (g_strv_length (tokens))
                {
                case 2:
                  /* no initial response */
                  mech_name = tokens[1];
                  encoded = NULL;
                  break;

                case 3:
                  /* initial response */
                  mech_name = tokens[1];
                  encoded = tokens[2];
                  break;

                default:
                  g_set_error (error,
                               G_IO_ERROR,
                               G_IO_ERROR_FAILED,
                               "Unexpected line `%s' while in WaitingForAuth state",
                               line);
                  g_strfreev (tokens);
                  goto out;
                }

              /* TODO: record that the client has attempted to use this mechanism */
              //g_debug ("client is trying `%s'", mech_name);

              auth_mech_to_use_gtype = find_mech_by_name (auth, mech_name);
              if ((auth_mech_to_use_gtype == (GType) 0) ||
                  (!allow_anonymous && g_strcmp0 (mech_name, "ANONYMOUS") == 0))
                {
                  /* We don't support this auth mechanism */
                  g_strfreev (tokens);
                  s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " ");
                  debug_print ("SERVER: writing `%s'", s);
                  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                    {
                      g_free (s);
                      goto out;
                    }
                  g_free (s);

                  /* stay in WAITING FOR AUTH */
                  state = SERVER_STATE_WAITING_FOR_AUTH;
                }
              else
                {
                  gchar *initial_response;
                  gsize initial_response_len;

                  mech = g_object_new (auth_mech_to_use_gtype,
                                       "stream", auth->priv->stream,
                                       "credentials", credentials,
                                       NULL);

                  initial_response = NULL;
                  initial_response_len = 0;
                  if (encoded != NULL)
                    {
                      initial_response = hexdecode (encoded, &initial_response_len, error);
                      if (initial_response == NULL)
                        {
                          g_prefix_error (error, "Initial response is malformed: ");
                          /* invalid encoding, disconnect! */
                          g_strfreev (tokens);
                          goto out;
                        }
                    }

                  _g_dbus_auth_mechanism_server_initiate (mech,
                                                          initial_response,
                                                          initial_response_len);
                  g_free (initial_response);
                  g_strfreev (tokens);

                change_state:
                  switch (_g_dbus_auth_mechanism_server_get_state (mech))
                    {
                    case G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED:
                      if (observer != NULL &&
                          !g_dbus_auth_observer_authorize_authenticated_peer (observer,
                                                                              auth->priv->stream,
                                                                              credentials))
                        {
                          /* disconnect */
                          g_set_error_literal (error,
                                               G_IO_ERROR,
                                               G_IO_ERROR_FAILED,
                                               _("Cancelled via GDBusAuthObserver::authorize-authenticated-peer"));
                          goto out;
                        }
                      else
                        {
                          s = g_strdup_printf ("OK %s\r\n", guid);
                          debug_print ("SERVER: writing `%s'", s);
                          if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                            {
                              g_free (s);
                              goto out;
                            }
                          g_free (s);
                          state = SERVER_STATE_WAITING_FOR_BEGIN;
                        }
                      break;

                    case G_DBUS_AUTH_MECHANISM_STATE_REJECTED:
                      s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " ");
                      debug_print ("SERVER: writing `%s'", s);
                      if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                        {
                          g_free (s);
                          goto out;
                        }
                      g_free (s);
                      state = SERVER_STATE_WAITING_FOR_AUTH;
                      break;

                    case G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA:
                      state = SERVER_STATE_WAITING_FOR_DATA;
                      break;

                    case G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND:
                      {
                        gchar *data;
                        gsize data_len;
                        gchar *encoded_data;
                        data = _g_dbus_auth_mechanism_server_data_send (mech, &data_len);
                        encoded_data = hexencode (data);
                        s = g_strdup_printf ("DATA %s\r\n", encoded_data);
                        g_free (encoded_data);
                        g_free (data);
                        debug_print ("SERVER: writing `%s'", s);
                        if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                          {
                            g_free (s);
                            goto out;
                          }
                        g_free (s);
                      }
                      goto change_state;
                      break;

                    default:
                      /* TODO */
                      g_assert_not_reached ();
                      break;
                    }
                }
            }
          else
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           "Unexpected line `%s' while in WaitingForAuth state",
                           line);
              g_free (line);
              goto out;
            }
          break;

        case SERVER_STATE_WAITING_FOR_DATA:
          debug_print ("SERVER: WaitingForData");
          line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
          debug_print ("SERVER: WaitingForData, read `%s'", line);
          if (line == NULL)
            goto out;
          if (g_str_has_prefix (line, "DATA "))
            {
              gchar *encoded;
              gchar *decoded_data;
              gsize decoded_data_len;

              encoded = g_strdup (line + 5);
              g_free (line);
              g_strstrip (encoded);
              decoded_data = hexdecode (encoded, &decoded_data_len, error);
              g_free (encoded);
              if (decoded_data == NULL)
                {
                  g_prefix_error (error, "DATA response is malformed: ");
                  /* invalid encoding, disconnect! */
                  goto out;
                }
              _g_dbus_auth_mechanism_server_data_receive (mech, decoded_data, decoded_data_len);
              g_free (decoded_data);
              /* oh man, this goto-crap is so ugly.. really need to rewrite the state machine */
              goto change_state;
            }
          else
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           "Unexpected line `%s' while in WaitingForData state",
                           line);
              g_free (line);
            }
          goto out;

        case SERVER_STATE_WAITING_FOR_BEGIN:
          debug_print ("SERVER: WaitingForBegin");
          /* Use extremely slow (but reliable) line reader - this basically
           * does a recvfrom() system call per character
           *
           * (the problem with using GDataInputStream's read_line is that because of
           * buffering it might start reading into the first D-Bus message that
           * appears after "BEGIN\r\n"....)
           */
          line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream),
                                                    &line_length,
                                                    cancellable,
                                                    error);
          debug_print ("SERVER: WaitingForBegin, read `%s'", line);
          if (line == NULL)
            goto out;
          if (g_strcmp0 (line, "BEGIN") == 0)
            {
              /* YAY, done! */
              ret = TRUE;
              g_free (line);
              goto out;
            }
          else if (g_strcmp0 (line, "NEGOTIATE_UNIX_FD") == 0)
            {
              g_free (line);
              if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
                {
                  negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING;
                  s = "AGREE_UNIX_FD\r\n";
                  debug_print ("SERVER: writing `%s'", s);
                  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                    goto out;
                }
              else
                {
                  s = "ERROR \"fd passing not offered\"\r\n";
                  debug_print ("SERVER: writing `%s'", s);
                  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                    goto out;
                }
            }
          else
            {
              g_debug ("Unexpected line `%s' while in WaitingForBegin state", line);
              g_free (line);
              s = "ERROR \"Unknown Command\"\r\n";
              debug_print ("SERVER: writing `%s'", s);
              if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                goto out;
            }
          break;

        default:
          g_assert_not_reached ();
          break;
        }
    }


  g_set_error_literal (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       "Not implemented (server)");

 out:
  if (mech != NULL)
    g_object_unref (mech);
  if (dis != NULL)
    g_object_unref (dis);
  if (dos != NULL)
    g_object_unref (dos);

  /* ensure return value is FALSE if error is set */
  if (error != NULL && *error != NULL)
    {
      ret = FALSE;
    }

  if (ret)
    {
      if (out_negotiated_capabilities != NULL)
        *out_negotiated_capabilities = negotiated_capabilities;
      if (out_received_credentials != NULL)
        *out_received_credentials = credentials != NULL ? g_object_ref (credentials) : NULL;
    }

  if (credentials != NULL)
    g_object_unref (credentials);

  debug_print ("SERVER: Done, authenticated=%d", ret);

  return ret;
}
示例#18
0
/* Save app data lists to file */
static gboolean
idle_save_application_usage (gpointer data)
{
  ShellAppUsage *self = SHELL_APP_USAGE (data);
  UsageIterator iter;
  const char *current_context;
  const char *context;
  const char *id;
  UsageData *usage;
  GFileOutputStream *output;
  GOutputStream *buffered_output;
  GDataOutputStream *data_output;
  GError *error = NULL;

  self->save_id = 0;

  /* Parent directory is already created by shell-global */
  output = g_file_replace (self->configfile, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
  if (!output)
    {
      g_debug ("Could not save applications usage data: %s", error->message);
      g_error_free (error);
      return FALSE;
    }
  buffered_output = g_buffered_output_stream_new (G_OUTPUT_STREAM (output));
  g_object_unref (output);
  data_output = g_data_output_stream_new (G_OUTPUT_STREAM (buffered_output));
  g_object_unref (buffered_output);

  if (!g_data_output_stream_put_string (data_output, "<?xml version=\"1.0\"?>\n<application-state>\n", NULL, &error))
    goto out;

  usage_iterator_init (self, &iter);

  current_context = NULL;
  while (usage_iterator_next (self, &iter, &context, &id, &usage))
    {
      ShellApp *app;

      app = shell_app_system_lookup_app (shell_app_system_get_default(), id);

      if (!app)
        continue;

      if (context != current_context)
        {
          if (current_context != NULL)
            {
              if (!g_data_output_stream_put_string (data_output, "  </context>", NULL, &error))
                goto out;
            }
          current_context = context;
          if (!g_data_output_stream_put_string (data_output, "  <context", NULL, &error))
            goto out;
          if (!write_attribute_string (data_output, "id", context, &error))
            goto out;
          if (!g_data_output_stream_put_string (data_output, ">\n", NULL, &error))
            goto out;
        }
      if (!g_data_output_stream_put_string (data_output, "    <application", NULL, &error))
        goto out;
      if (!write_attribute_string (data_output, "id", id, &error))
        goto out;
      if (!write_attribute_uint (data_output, "open-window-count", shell_app_get_n_windows (app), &error))
        goto out;

      if (!write_attribute_double (data_output, "score", usage->score, &error))
        goto out;
      if (!write_attribute_uint (data_output, "last-seen", usage->last_seen, &error))
        goto out;
      if (!g_data_output_stream_put_string (data_output, "/>\n", NULL, &error))
        goto out;
    }
  if (current_context != NULL)
    {
      if (!g_data_output_stream_put_string (data_output, "  </context>\n", NULL, &error))
        goto out;
    }
  if (!g_data_output_stream_put_string (data_output, "</application-state>\n", NULL, &error))
    goto out;

out:
  if (!error)
    g_output_stream_close_async (G_OUTPUT_STREAM (data_output), 0, NULL, NULL, NULL);
  g_object_unref (data_output);
  if (error)
    {
      g_debug ("Could not save applications usage data: %s", error->message);
      g_error_free (error);
    }
  return FALSE;
}
示例#19
0
文件: gdbusauth.c 项目: Andais/glib
static GDBusAuthMechanism *
client_choose_mech_and_send_initial_response (GDBusAuth           *auth,
                                              GCredentials        *credentials_that_were_sent,
                                              const gchar* const  *supported_auth_mechs,
                                              GPtrArray           *attempted_auth_mechs,
                                              GDataOutputStream   *dos,
                                              GCancellable        *cancellable,
                                              GError             **error)
{
  GDBusAuthMechanism *mech;
  GType auth_mech_to_use_gtype;
  guint n;
  guint m;
  gchar *initial_response;
  gsize initial_response_len;
  gchar *encoded;
  gchar *s;

 again:
  mech = NULL;

  debug_print ("CLIENT: Trying to choose mechanism");

  /* find an authentication mechanism to try, if any */
  auth_mech_to_use_gtype = (GType) 0;
  for (n = 0; supported_auth_mechs[n] != NULL; n++)
    {
      gboolean attempted_already;
      attempted_already = FALSE;
      for (m = 0; m < attempted_auth_mechs->len; m++)
        {
          if (g_strcmp0 (supported_auth_mechs[n], attempted_auth_mechs->pdata[m]) == 0)
            {
              attempted_already = TRUE;
              break;
            }
        }
      if (!attempted_already)
        {
          auth_mech_to_use_gtype = find_mech_by_name (auth, supported_auth_mechs[n]);
          if (auth_mech_to_use_gtype != (GType) 0)
            break;
        }
    }

  if (auth_mech_to_use_gtype == (GType) 0)
    {
      guint n;
      gchar *available;
      GString *tried_str;

      debug_print ("CLIENT: Exhausted all available mechanisms");

      available = g_strjoinv (", ", (gchar **) supported_auth_mechs);

      tried_str = g_string_new (NULL);
      for (n = 0; n < attempted_auth_mechs->len; n++)
        {
          if (n > 0)
            g_string_append (tried_str, ", ");
          g_string_append (tried_str, attempted_auth_mechs->pdata[n]);
        }
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_FAILED,
                   _("Exhausted all available authentication mechanisms (tried: %s) (available: %s)"),
                   tried_str->str,
                   available);
      g_string_free (tried_str, TRUE);
      g_free (available);
      goto out;
    }

  /* OK, decided on a mechanism - let's do this thing */
  mech = g_object_new (auth_mech_to_use_gtype,
                       "stream", auth->priv->stream,
                       "credentials", credentials_that_were_sent,
                       NULL);
  debug_print ("CLIENT: Trying mechanism `%s'", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
  g_ptr_array_add (attempted_auth_mechs, (gpointer) _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));

  /* the auth mechanism may not be supported
   * (for example, EXTERNAL only works if credentials were exchanged)
   */
  if (!_g_dbus_auth_mechanism_is_supported (mech))
    {
      debug_print ("CLIENT: Mechanism `%s' says it is not supported", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
      g_object_unref (mech);
      mech = NULL;
      goto again;
    }

  initial_response_len = -1;
  initial_response = _g_dbus_auth_mechanism_client_initiate (mech,
                                                             &initial_response_len);
#if 0
  g_printerr ("using auth mechanism with name `%s' of type `%s' with initial response `%s'\n",
              _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype),
              g_type_name (G_TYPE_FROM_INSTANCE (mech)),
              initial_response);
#endif
  if (initial_response != NULL)
    {
      //g_printerr ("initial_response = `%s'\n", initial_response);
      encoded = hexencode (initial_response);
      s = g_strdup_printf ("AUTH %s %s\r\n",
                           _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype),
                           encoded);
      g_free (initial_response);
      g_free (encoded);
    }
  else
    {
      s = g_strdup_printf ("AUTH %s\r\n", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
    }
  debug_print ("CLIENT: writing `%s'", s);
  if (!g_data_output_stream_put_string (dos, s, cancellable, error))
    {
      g_object_unref (mech);
      mech = NULL;
      g_free (s);
      goto out;
    }
  g_free (s);

 out:
  return mech;
}