コード例 #1
0
ファイル: gvfsftpconnection.c プロジェクト: BATYakhkhkh/gvfs
GVfsFtpConnection *
g_vfs_ftp_connection_new (GSocketConnectable *addr,
                          GCancellable *      cancellable,
                          GError **           error)
{
  GVfsFtpConnection *conn;

  g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (addr), NULL);

  conn = g_slice_new0 (GVfsFtpConnection);
  conn->client = g_socket_client_new ();
  conn->debug_id = g_atomic_int_exchange_and_add (&debug_id, 1);
  conn->commands = G_IO_STREAM (g_socket_client_connect (conn->client,
                                                         addr,
                                                         cancellable,
                                                         error));
  if (conn->commands == NULL)
    {
      g_object_unref (conn->client);
      g_slice_free (GVfsFtpConnection, conn);
      return NULL;
    }

  enable_keepalive (G_SOCKET_CONNECTION (conn->commands));
  conn->commands_in = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (conn->commands)));
  g_data_input_stream_set_newline_type (conn->commands_in, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
  /* The first thing that needs to happen is receiving the welcome message */
  conn->waiting_for_reply = TRUE;

  return conn;
}
コード例 #2
0
ファイル: connections.c プロジェクト: AdKwiatkos/ekg2
GDataOutputStream *ekg_connection_add(
		GSocketConnection *conn,
		GInputStream *raw_instream,
		GOutputStream *raw_outstream,
		ekg_input_callback_t callback,
		ekg_failure_callback_t failure_callback,
		gpointer priv_data)
{
	struct ekg_connection *c = g_slice_new(struct ekg_connection);
	GOutputStream *bout = g_buffered_output_stream_new(raw_outstream);

	c->conn = conn;
	c->instream = g_data_input_stream_new(raw_instream);
	c->outstream = g_data_output_stream_new(bout);
	c->cancellable = g_cancellable_new();
	c->wr_buffer = g_string_new("");

	c->callback = callback;
	c->failure_callback = failure_callback;
	c->priv_data = priv_data;

#if NEED_SLAVERY
	c->master = get_slave_connection_by_conn(conn);
	c->slave = NULL;

		/* be a good slave.. er, servant */
	if (G_UNLIKELY(c->master)) {
		struct ekg_connection *ci;
		c->master->slave = c;

		/* shift flush handlers (if set)
		 * this is required in order to be able to easily set flush
		 * handlers for future slaves */
		for (ci = c;
				ci->master && (ci->master->flush_handler != setup_async_write);
				ci = ci->master)
			ci->flush_handler = ci->master->flush_handler;
		ci->flush_handler = setup_async_write;
	} else
#endif
		c->flush_handler = setup_async_write;

		/* LF works fine for CRLF */
	g_data_input_stream_set_newline_type(c->instream, G_DATA_STREAM_NEWLINE_TYPE_LF);
		/* disallow any blocking writes */
	g_buffered_output_stream_set_auto_grow(G_BUFFERED_OUTPUT_STREAM(bout), TRUE);

	connections = g_slist_prepend(connections, c);
#if NEED_SLAVERY
	if (G_LIKELY(!c->master))
#endif
		setup_async_read(c);

	return c->outstream;
}
コード例 #3
0
ファイル: gvfsftpconnection.c プロジェクト: gicmo/gvfs
static void
create_input_stream (GVfsFtpConnection *conn)
{
  if (conn->commands_in)
    {
      g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (conn->commands_in), FALSE);
      g_object_unref (conn->commands_in);
    }

  conn->commands_in = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (conn->commands)));
  g_data_input_stream_set_newline_type (conn->commands_in, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
}
コード例 #4
0
int main(void)
{
    pid_t parent_pid;
    GInputStream *stdin_unix_stream;

  /* Nuke the environment to get a well-known and sanitized
   * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS
   * environment variable and similar.
   */
    if (clearenv () != 0) {
        FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno));
        return 1;
    }

#if !GLIB_CHECK_VERSION(2,36,0)
    g_type_init();
#endif

    loop = g_main_loop_new(NULL, FALSE);

    authority = polkit_authority_get_sync(NULL, NULL);
    parent_pid = getppid ();
    if (parent_pid == 1) {
            FATAL_ERROR("Parent process was reaped by init(1)\n");
            return 1;
    }
    /* Do what pkexec does */
    subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ());

    stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0);
    stdin_stream = g_data_input_stream_new(stdin_unix_stream);
    g_data_input_stream_set_newline_type(stdin_stream,
                                         G_DATA_STREAM_NEWLINE_TYPE_LF);
    g_clear_object(&stdin_unix_stream);
    g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL,
                                        stdin_read_complete, NULL);

    g_main_loop_run(loop);

    if (polkit_cancellable)
        g_clear_object(&polkit_cancellable);
    g_object_unref(stdin_stream);
    g_object_unref(authority);
    g_object_unref(subject);
    g_main_loop_unref(loop);

    return exit_status;
}
コード例 #5
0
ファイル: mega-http-client.c プロジェクト: crass/megatools
static gboolean do_connect(MegaHttpClient* http_client, GCancellable* cancellable, GError** err)
{
  GError* local_err = NULL;

  g_return_val_if_fail(MEGA_IS_HTTP_CLIENT(http_client), FALSE);
  g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

  MegaHttpClientPrivate* priv = http_client->priv;

  do_disconnect(http_client);

  // enable/disable TLS
  if (priv->https)
  {
    if (!g_tls_backend_supports_tls(g_tls_backend_get_default())) 
    {
      g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "TLS backend not found, please install glib-networking.");
      return FALSE;
    }

    g_socket_client_set_tls(priv->client, TRUE);
  }
  else
  {
    g_socket_client_set_tls(priv->client, FALSE);
  }


  priv->conn = g_socket_client_connect_to_host(priv->client, priv->host, priv->port, cancellable, &local_err);
  if (!priv->conn)
  {
    g_propagate_prefixed_error(err, local_err, "Connection failed: ");
    return FALSE;
  }
  
  GDataInputStream* data_stream = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(http_client->priv->conn)));
  g_data_input_stream_set_newline_type(data_stream, G_DATA_STREAM_NEWLINE_TYPE_ANY);

  priv->istream = G_INPUT_STREAM(data_stream);
  priv->ostream = g_object_ref(g_io_stream_get_output_stream(G_IO_STREAM(http_client->priv->conn)));

  return TRUE;
}
コード例 #6
0
ファイル: plugin-identd.c プロジェクト: Cynede/hexchat
static gboolean
identd_incoming_cb (GSocketService *service, GSocketConnection *conn,
					GObject *source, gpointer userdata)
{
	GDataInputStream *data_stream;
	GInputStream *stream;
	ident_info *info;

	info = g_new0 (ident_info, 1);

	info->conn = conn;
	g_object_ref (conn);

	stream = g_io_stream_get_input_stream (G_IO_STREAM (conn));
	data_stream = g_data_input_stream_new (stream);
	g_data_input_stream_set_newline_type (data_stream, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
	g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT,
										NULL, (GAsyncReadyCallback)identd_read_ready, info);

	return TRUE;
}
コード例 #7
0
ファイル: httppackage.c プロジェクト: ramirojgm/gcontable
GDataInputStream *
http_data_input_stream(GInputStream * stream,gsize * length,GCancellable * cancellable,GError ** error)
{
	GMemoryOutputStream
	* out = G_MEMORY_OUTPUT_STREAM(g_memory_output_stream_new_resizable());
	gchar * content = NULL;
	guint8 byte = 0;
	while(g_input_stream_read(stream,&byte,1,cancellable,error))
	{
		if(g_memory_output_stream_get_data_size(out) > 2048)
		{
			g_output_stream_close(G_OUTPUT_STREAM(out),NULL,NULL);
			g_free(g_memory_output_stream_steal_data(out));
			g_object_unref(out);
			return NULL;
		}
		g_output_stream_write_all(G_OUTPUT_STREAM(out),&byte,1,NULL,NULL,NULL);
		if(g_memory_output_stream_get_data_size(out) >= 4)
		{
			content = g_memory_output_stream_get_data(out);
			if(strncmp((content + g_memory_output_stream_get_data_size(out) - 4),"\r\n\r\n",4) == 0)
				break;
		}
	}
	g_output_stream_close(G_OUTPUT_STREAM(out),NULL,NULL);
	GMemoryInputStream
	* result = G_MEMORY_INPUT_STREAM(g_memory_input_stream_new_from_data(
				g_memory_output_stream_steal_data(out),
				g_memory_output_stream_get_data_size(out),
				g_free
			));
	g_object_unref(out);
	GDataInputStream
	* dis = g_data_input_stream_new(G_INPUT_STREAM(result));
	g_data_input_stream_set_newline_type(dis,G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
	return dis;
}
コード例 #8
0
ファイル: rclib-lyric.c プロジェクト: horc-fn/RhythmCat2
gboolean rclib_lyric_load_file(const gchar *filename, guint index)
{
    RCLibLyricParsedData *parsed_data;
    gchar *line;
    GFile *file;
    GFileInputStream *input_stream;
    GDataInputStream *data_stream;
    gsize line_len;
    gint64 time = -1;
    RCLibLyricPrivate *priv;
    GSequenceIter *iter;
    RCLibLyricData *lyric_data;
    rclib_lyric_clean(index);
    if(lyric_instance==NULL) return FALSE;
    if(filename==NULL) return FALSE;
    priv = RCLIB_LYRIC(lyric_instance)->priv;
    if(priv==NULL) return FALSE;
    file = g_file_new_for_path(filename);
    if(file==NULL) return FALSE;
    if(!g_file_query_exists(file, NULL))
    {
        g_object_unref(file);
        return FALSE;
    }
    input_stream = g_file_read(file, NULL, NULL);
    g_object_unref(file);
    if(input_stream==NULL) return FALSE;
    data_stream = g_data_input_stream_new(G_INPUT_STREAM(input_stream));
    g_object_unref(input_stream);
    if(data_stream==NULL) return FALSE;
    g_data_input_stream_set_newline_type(data_stream,
        G_DATA_STREAM_NEWLINE_TYPE_ANY);
    if(index==1)
        parsed_data = &(priv->parsed_data2);
    else
        parsed_data = &(priv->parsed_data1);
    if(index!=1) index = 0;
    while((line=g_data_input_stream_read_line(data_stream, &line_len,
        NULL, NULL))!=NULL)
    {
        rclib_lyric_add_line(parsed_data, priv->regex, priv->encoding,
            line, line_len);
        g_free(line);
    }
    g_object_unref(data_stream);
    for(iter = g_sequence_get_end_iter(parsed_data->seq);
        !g_sequence_iter_is_begin(iter);)
    {
        iter = g_sequence_iter_prev(iter);
        lyric_data = g_sequence_get(iter);
        if(lyric_data==NULL) continue;
        if(time>=0)
        {
            lyric_data->length = time - lyric_data->time;
        }
        time = lyric_data->time;
    }
    parsed_data->filename = g_strdup(filename);
    g_signal_emit(lyric_instance, lyric_signals[SIGNAL_LYRIC_READY], 0,
        index);
    return TRUE;
}
コード例 #9
0
static gboolean on_incoming_connection(GThreadedSocketService *service,
    GSocketConnection *connection, GObject *source_object, OwrImageServer *image_server)
{
    GOutputStream *bos;
    GDataInputStream *dis;
    gchar *error_body, *error_header = NULL, *response_header = NULL;
    gchar *line, *tag;
    gsize line_length, i;
    guint content_length = 0;
    OwrImageRenderer *image_renderer;
    GBytes *image;
    gconstpointer image_data;
    gsize image_data_size = 0;

    OWR_UNUSED(service);
    OWR_UNUSED(source_object);

    g_return_val_if_fail(OWR_IS_IMAGE_SERVER(image_server), TRUE);

    bos = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(connection)));
    dis = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(connection)));
    g_data_input_stream_set_newline_type(dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);

    error_body = "404 Not Found";
    error_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 404, "Not Found",
        "text/plain", (guint)strlen(error_body));

    while (TRUE) {
        line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL);
        if (!line)
            break;

        if (line_length > 6) {
            tag = g_strdup(line + 7);
            for (i = 0; i < strlen(tag); i++) {
                if (tag[i] == '-') {
                    tag[i] = '\0';
                    break;
                }
            }
        } else
            tag = NULL;

        g_free(line);

        while ((line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL))) {
            g_free(line);

            if (!line_length) {
                /* got all request headers */
                break;
            }
        }

        if (!line)
            break;

        g_mutex_lock(&image_server->priv->image_renderers_mutex);
        image_renderer = tag ? g_hash_table_lookup(image_server->priv->image_renderers, tag) : NULL;
        g_mutex_unlock(&image_server->priv->image_renderers_mutex);

        image = image_renderer ? _owr_image_renderer_pull_bmp_image(image_renderer) : NULL;

        if (!image) {
            g_output_stream_write(bos, error_header, strlen(error_header), NULL, NULL);
            g_output_stream_write(bos, error_body, strlen(error_body), NULL, NULL);
            break;
        }

        image_data = g_bytes_get_data(image, &image_data_size);

        if (content_length != image_data_size) {
            content_length = image_data_size;
            g_free(response_header);
            response_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 200, "OK",
                "image/bmp", content_length);
            g_buffered_output_stream_set_buffer_size(G_BUFFERED_OUTPUT_STREAM(bos),
                strlen(response_header) + content_length);
        }
        g_output_stream_write(bos, response_header, strlen(response_header), NULL, NULL);
        g_output_stream_write(bos, image_data, image_data_size, NULL, NULL);
        g_output_stream_flush(bos, NULL, NULL);

        g_bytes_unref(image);
    }

    g_free(response_header);
    g_free(error_header);
    g_object_unref(dis);
    g_object_unref(bos);

    return FALSE;
}
コード例 #10
0
ファイル: text.c プロジェクト: Cynede/hexchat
void
scrollback_load (session *sess)
{
	GInputStream *stream;
	GDataInputStream *istream;
	gchar *buf, *text;
	gint lines = 0;
	time_t stamp = 0;

	if (sess->text_scrollback == SET_DEFAULT)
	{
		if (!prefs.hex_text_replay)
			return;
	}
	else
	{
		if (sess->text_scrollback != SET_ON)
			return;
	}

	if (!sess->scrollfile)
	{
		if ((buf = scrollback_get_filename (sess)) == NULL)
			return;

		sess->scrollfile = g_file_new_for_path (buf);
		g_free (buf);
	}

	stream = G_INPUT_STREAM(g_file_read (sess->scrollfile, NULL, NULL));
	if (!stream)
		return;

	istream = g_data_input_stream_new (stream);
	/*
	 * This is to avoid any issues moving between windows/unix
	 * but the docs mention an invalid \r without a following \n
	 * can lock up the program... (Our write() always adds \n)
	 */
	g_data_input_stream_set_newline_type (istream, G_DATA_STREAM_NEWLINE_TYPE_ANY);
	g_object_unref (stream);

	while (1)
	{
		GError *err = NULL;
		gsize n_bytes;

		buf = g_data_input_stream_read_line_utf8 (istream, &n_bytes, NULL, &err);

		if (!err && buf)
		{
			/*
			 * Some scrollback lines have three blanks after the timestamp and a newline
			 * Some have only one blank and a newline
			 * Some don't even have a timestamp
			 * Some don't have any text at all
			 */
			if (buf[0] == 'T' && buf[1] == ' ')
			{
				if (sizeof (time_t) == 4)
					stamp = strtoul (buf + 2, NULL, 10);
				else
					stamp = g_ascii_strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */

				if (G_UNLIKELY(stamp == 0))
				{
					g_warning ("Invalid timestamp in scrollback file");
					continue;
				}

				text = strchr (buf + 3, ' ');
				if (text && text[1])
				{
					if (prefs.hex_text_stripcolor_replay)
					{
						text = strip_color (text + 1, -1, STRIP_COLOR);
					}

					fe_print_text (sess, text, stamp, TRUE);

					if (prefs.hex_text_stripcolor_replay)
					{
						g_free (text);
					}
				}
				else
				{
					fe_print_text (sess, "  ", stamp, TRUE);
				}
			}
			else
			{
				if (strlen (buf))
					fe_print_text (sess, buf, 0, TRUE);
				else
					fe_print_text (sess, "  ", 0, TRUE);
			}
			lines++;

			g_free (buf);
		}
		else if (err)
		{
			/* If its only an encoding error it may be specific to the line */
			if (g_error_matches (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE))
			{
				g_warning ("Invalid utf8 in scrollback file");
				g_clear_error (&err);
				continue;
			}

			/* For general errors just give up */
			g_clear_error (&err);
			break;
		}
		else /* No new line */
		{
			break;
		}
	}

	g_object_unref (istream);

	sess->scrollwritten = lines;

	if (lines)
	{
		text = ctime (&stamp);
		buf = g_strdup_printf ("\n*\t%s %s\n", _("Loaded log from"), text);
		fe_print_text (sess, buf, 0, TRUE);
		g_free (buf);
		/*EMIT_SIGNAL (XP_TE_GENMSG, sess, "*", buf, NULL, NULL, NULL, 0);*/
	}
}
コード例 #11
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;
}
コード例 #12
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;
}
コード例 #13
0
static void
on_epg_dat_received (MexDownloadQueue *queue,
                     const char       *uri,
                     const char       *buffer,
                     gsize             count,
                     const GError     *dq_error,
                     gpointer          user_data)
{
  Request *req = user_data;
  GInputStream *input;
  GDataInputStream *data;
  GError *error = NULL;
  GPtrArray *events;
  gchar *line;

  if (dq_error)
    {
      g_warning ("Could not download %s: %s", uri, dq_error->message);
      return;
    }

  MEX_NOTE (EPG, "received %s, size %"G_GSIZE_FORMAT, uri, count);

  events = g_ptr_array_new_with_free_func (g_object_unref);

  /* parse the date line by line */
  input = g_memory_input_stream_new_from_data (buffer, count, NULL);
  data = g_data_input_stream_new (input);
  g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);

  /* The first line is empty */
  line = g_data_input_stream_read_line (data, NULL, NULL, &error);
  g_free (line);

  /* The second line is the disclamer*/
  line = g_data_input_stream_read_line (data, NULL, NULL, &error);
  g_free (line);

  line = g_data_input_stream_read_line (data, NULL, NULL, &error);
  while (line)
    {
      parse_epg_dat_line (req, line, events);
      g_free (line);
      line = g_data_input_stream_read_line (data, NULL, NULL, &error);
    }
  if (G_UNLIKELY (error))
    {
      g_warning ("Could not read line: %s", error->message);
      g_clear_error (&error);
    }

  g_object_unref (data);
  g_object_unref (input);

  req->callback (req->provider, req->channel, events, req->user_data);

  g_date_time_unref (req->start_date);
  g_date_time_unref (req->end_date);
  g_ptr_array_unref (events);
  g_slice_free (Request, req);
}
コード例 #14
0
ファイル: gvfsftpdircache.c プロジェクト: BATYakhkhkh/gvfs
static gboolean
g_vfs_ftp_dir_cache_funcs_process (GInputStream *        stream,
                                   int                   debug_id,
                                   const GVfsFtpFile *   dir,
                                   GVfsFtpDirCacheEntry *entry,
                                   gboolean              is_unix,
                                   GCancellable *        cancellable,
                                   GError **             error)
{
  struct list_state state = { NULL, };
  GDataInputStream *data;
  GFileInfo *info;
  int type;
  GVfsFtpFile *file;
  char *line, *s;
  gsize length;

  /* protect against code reorg - in current code, error never is NULL */
  g_assert (error != NULL);
  g_assert (*error == NULL);

  data = g_data_input_stream_new (stream);
  /* we use LF only, because the mozilla code can handle lines ending in CR */
  g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_LF);
  while ((line = g_data_input_stream_read_line (data, &length, cancellable, error)))
    {
      struct list_result result = { 0, };
      GFileType file_type = G_FILE_TYPE_UNKNOWN;
      GTimeVal tv = { 0, 0 };

      /* strip trailing \r - ParseFTPList only removes it if the line ends in \r\n,
       * but we stripped the \n already.
       */
      if (length > 0 && line[length - 1] == '\r')
        line[--length] = '\0';

      g_debug ("<<%2d <<  %s\n", debug_id, line);
      type = ParseFTPList (line, &state, &result);
      if (type != 'd' && type != 'f' && type != 'l')
        {
          g_free (line);
          continue;
        }

      /* don't list . and .. directories
       * Let's hope they're not important files on some ftp servers
       */
      if (result.fe_fnlen == 1 &&
          result.fe_fname[0] == '.')
        {
          g_free (line);
          continue;
        }
      if (result.fe_fnlen == 2 &&
          result.fe_fname[0] == '.' &&
          result.fe_fname[1] == '.')
        {
          g_free (line);
          continue;
        }

      s = g_strndup (result.fe_fname, result.fe_fnlen);
      file = g_vfs_ftp_file_new_child  (dir, s, NULL);
      g_free (s);
      if (file == NULL)
        {
          g_debug ("# invalid filename, skipping");
          g_free (line);
          continue;
        }

      info = g_file_info_new ();

      s = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, s);
      g_free (s);

      if (type == 'l')
        {
          char *link;

          link = g_strndup (result.fe_lname, result.fe_lnlen);
          g_file_info_set_symlink_target (info, link);
          g_file_info_set_is_symlink (info, TRUE);
          g_free (link);
        }

      g_file_info_set_size (info, g_ascii_strtoull (result.fe_size, NULL, 10));

      /* If unix format then parse the attributes */
      if (state.lstyle == 'U')
        {
          char file_mode[10], uid[64], gid[64];
          guint32 mode;

          /* POSIX ls -l form: mode, links, owner, group */
          if (sscanf(line, "%10c %*u %63s %63s", file_mode, uid, gid) == 3)
            {
              if (g_vfs_ftp_parse_mode (file_mode, &mode, &file_type))
                {
                  g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, mode);
                  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER, uid);
                  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP, gid);
                }
            }
          else
            g_debug ("# unknown listing format\n");
        }

      if (file_type == G_FILE_TYPE_UNKNOWN)
        {
          file_type = type == 'f' ? G_FILE_TYPE_REGULAR :
                      type == 'l' ? G_FILE_TYPE_SYMBOLIC_LINK :
                      G_FILE_TYPE_DIRECTORY;
        }

      gvfs_file_info_populate_default (info,
                                       g_vfs_ftp_file_get_gvfs_path (file),
                                       file_type);

      if (is_unix)
        g_file_info_set_is_hidden (info, result.fe_fnlen > 0 &&
                                         result.fe_fname[0] == '.');

      /* Workaround:
       * result.fetime.tm_year contains actual year instead of offset-from-1900,
       * which mktime expects.
       */
      if (result.fe_time.tm_year >= 1900)
              result.fe_time.tm_year -= 1900;

      tv.tv_sec = mktime (&result.fe_time);
      if (tv.tv_sec != -1)
        g_file_info_set_modification_time (info, &tv);

      g_vfs_ftp_dir_cache_entry_add (entry, file, info);
      g_free (line);
    }

  g_object_unref (data);
  return *error != NULL;
}