Beispiel #1
0
GIOChannel *
g_io_channel_unix_new (gint fd)
{
  struct stat buffer;
  GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
  GIOChannel *channel = (GIOChannel *)unix_channel;

  g_io_channel_init (channel);
  channel->funcs = &unix_channel_funcs;

  unix_channel->fd = fd;

  /* I'm not sure if fstat on a non-file (e.g., socket) works
   * it should be safe to say if it fails, the fd isn't seekable.
   */
  /* Newer UNIX versions support S_ISSOCK(), fstat() will probably
   * succeed in most cases.
   */
  if (fstat (unix_channel->fd, &buffer) == 0)
    channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
                           || S_ISBLK (buffer.st_mode);
  else /* Assume not seekable */
    channel->is_seekable = FALSE;

  g_io_unix_get_flags (channel); /* Sets is_readable, is_writeable */

  return channel;
}
GIOChannel *g_io_channel_gnutls_new(int fd)
{
	GIOGnuTLSChannel *gnutls_channel;
	GIOChannel *channel;
	int err;

	DBG("");

	gnutls_channel = g_new(GIOGnuTLSChannel, 1);

	channel = (GIOChannel *) gnutls_channel;

	g_io_channel_init(channel);
	channel->funcs = &gnutls_channel_funcs;

	gnutls_channel->fd = fd;

	channel->is_seekable = FALSE;
	channel->is_readable = TRUE;
	channel->is_writeable = TRUE;

	channel->do_encode = FALSE;

	g_io_gnutls_global_init();

        err = gnutls_init(&gnutls_channel->session, GNUTLS_CLIENT);
	if (err < 0) {
		g_free(gnutls_channel);
		return NULL;
	}

	gnutls_transport_set_ptr(gnutls_channel->session, gnutls_channel);
        gnutls_transport_set_push_function(gnutls_channel->session,
						g_io_gnutls_push_func);
        gnutls_transport_set_pull_function(gnutls_channel->session,
						g_io_gnutls_pull_func);
#if GNUTLS_VERSION_NUMBER < 0x020c00
	gnutls_transport_set_lowat(gnutls_channel->session, 0);

	gnutls_priority_set_direct(gnutls_channel->session,
						"NORMAL:%COMPAT", NULL);
#else
	gnutls_priority_set_direct(gnutls_channel->session,
		"NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL);
#endif

	gnutls_certificate_allocate_credentials(&gnutls_channel->cred);
	gnutls_credentials_set(gnutls_channel->session,
				GNUTLS_CRD_CERTIFICATE, gnutls_channel->cred);

	DBG("channel %p", channel);

	return channel;
}
Beispiel #3
0
GIOChannel *
g_io_channel_unix_new (gint fd)
{
  GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
  GIOChannel *channel = (GIOChannel *)unix_channel;

  g_io_channel_init (channel);
  channel->funcs = &unix_channel_funcs;

  unix_channel->fd = fd;
  return channel;
}
GIOChannel *
g_io_channel_win32_new_stream_socket (int socket)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *) win32_channel;

  g_io_channel_init (channel);
  channel->funcs = &win32_channel_sock_funcs;
  win32_channel->fd = socket;
  win32_channel->type = G_IO_STREAM_SOCKET;

  return channel;
}
GIOChannel *
g_io_channel_unix_new (gint fd)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *) win32_channel;

  g_io_channel_init (channel);
  channel->funcs = &win32_channel_fd_funcs;
  win32_channel->fd = fd;
  win32_channel->type = G_IO_FILE_DESC;

  return channel;
}
GIOChannel *
g_io_channel_win32_new_messages (guint hwnd)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *) win32_channel;

  g_io_channel_init (channel);
  channel->funcs = &win32_channel_msg_funcs;
  win32_channel->fd = -1;
  win32_channel->type = G_IO_WINDOWS_MESSAGES;
  win32_channel->hwnd = (HWND) hwnd;

  return channel;
}
GIOChannel *
g_io_channel_win32_new_pipe (int fd)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *) win32_channel;

  g_io_channel_init (channel);
  channel->funcs = &win32_channel_pipe_funcs;
  win32_channel->fd = fd;
  win32_channel->type = G_IO_PIPE;
  win32_channel->offset = 0;
  win32_channel->need_wakeups = FALSE;

  return channel;
}
Beispiel #8
0
static void	ok_connection(t_cnt *cnt)
{
  GtkWidget	*widget;
  GIOChannel	*io;

  debug("ok_connection()");
  connect_btn_dialog(cnt);
  widget = glade_xml_get_widget(GLADE_XML(cnt->xml), LOGIN_WINDOW);
  gtk_widget_hide(widget);
  widget_connected(cnt, DIALOG_WINDOW, DELETE_EVENT, gtk_main_quit);
  widget = glade_xml_get_widget(GLADE_XML(cnt->xml), DIALOG_WINDOW);
  gtk_widget_show(widget);
  init_server(cnt);
  io = g_io_channel_unix_new(cnt->socket);
  g_io_channel_init(io);
  g_io_add_watch(io, G_IO_IN, listen_from_server, cnt);
}
GIOChannel *
g_io_channel_win32_new_fd (gint fd)
{
  GIOWin32Channel *win32_channel;
  GIOChannel *channel;
  struct stat st;

  if (fstat (fd, &st) == -1)
    {
      g_warning (G_STRLOC ": %d isn't a (emulated) file descriptor", fd);
      return NULL;
    }

  win32_channel = g_new (GIOWin32Channel, 1);
  channel = (GIOChannel *)win32_channel;

  g_io_channel_init (channel);
  g_io_channel_win32_init (win32_channel);
  if (win32_channel->debug)
    g_print ("g_io_channel_win32_new_fd: %u\n", fd);
  channel->funcs = &win32_channel_fd_funcs;
  win32_channel->type = G_IO_WIN32_FILE_DESC;
  win32_channel->fd = fd;


  /* fstat doesn't deliver senseful values, but
   * fcntl isn't available, so guess ...
   */
  if (st.st_mode & _S_IFIFO)
    {
      channel->is_readable  = TRUE;
      channel->is_writeable = TRUE;
      channel->is_seekable  = FALSE;
    }
  else
    {
      channel->is_readable  = !!(st.st_mode & _S_IREAD);
      channel->is_writeable = !!(st.st_mode & _S_IWRITE);
      /* XXX What about "device files" (COM1: and the like) */
      channel->is_seekable = TRUE;
    }

  return channel;
}
Beispiel #10
0
GIOChannel *g_at_mux_create_channel(GAtMux *mux)
{
	GAtMuxChannel *mux_channel;
	GIOChannel *channel;
	int i;

	for (i = 0; i < MAX_CHANNELS; i++) {
		if (mux->dlcs[i] == NULL)
			break;
	}

	if (i == MAX_CHANNELS)
		return NULL;

	mux_channel = g_try_new0(GAtMuxChannel, 1);
	if (mux_channel == NULL)
		return NULL;

	if (mux->driver->open_dlc)
		mux->driver->open_dlc(mux, i+1);

	channel = (GIOChannel *) mux_channel;

	g_io_channel_init(channel);
	channel->close_on_unref = TRUE;
	channel->funcs = &channel_funcs;

	channel->is_seekable = FALSE;
	channel->is_readable = TRUE;
	channel->is_writeable = TRUE;

	channel->do_encode = FALSE;

	mux_channel->mux = mux;
	mux_channel->dlc = i+1;
	mux_channel->buffer = ring_buffer_new(MUX_CHANNEL_BUFFER_SIZE);
	mux_channel->throttled = FALSE;

	mux->dlcs[i] = mux_channel;

	debug(mux, "created channel %p, dlc: %d", channel, i+1);

	return channel;
}
Beispiel #11
0
static GIOChannel *
g_io_channel_win32_new_fd_internal (gint         fd,
				    struct stat *st)
{
  GIOWin32Channel *win32_channel;
  GIOChannel *channel;

  win32_channel = g_new (GIOWin32Channel, 1);
  channel = (GIOChannel *)win32_channel;

  g_io_channel_init (channel);
  g_io_channel_win32_init (win32_channel);
  channel->funcs = &win32_channel_fd_funcs;
  win32_channel->type = G_IO_WIN32_FILE_DESC;
  win32_channel->fd = fd;

  g_io_win32_fd_get_flags_internal (channel, st);
  
  return channel;
}
Beispiel #12
0
GIOChannel *
g_io_channel_win32_new_messages (guint hwnd)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *)win32_channel;

  g_io_channel_init (channel);
  g_io_channel_win32_init (win32_channel);
  channel->funcs = &win32_channel_msg_funcs;
  win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
  win32_channel->hwnd = (HWND) hwnd;

  /* XXX: check this. */
  channel->is_readable = IsWindow (win32_channel->hwnd);
  channel->is_writeable = IsWindow (win32_channel->hwnd);

  channel->is_seekable = FALSE;

  return channel;
}
GIOChannel *
g_io_channel_win32_new_socket (int socket)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *)win32_channel;

  g_io_channel_init (channel);
  g_io_channel_win32_init (win32_channel);
  if (win32_channel->debug)
    g_print ("g_io_channel_win32_new_socket: sockfd:%d\n", socket);
  channel->funcs = &win32_channel_sock_funcs;
  win32_channel->type = G_IO_WIN32_SOCKET;
  win32_channel->fd = socket;

  /* XXX: check this */
  channel->is_readable = TRUE;
  channel->is_writeable = TRUE;
  channel->is_seekable = FALSE;

  return channel;
}
GIOChannel *
g_io_channel_win32_new_pipe_with_wakeups (int   fd,
					  guint peer,
					  int   peer_fd)
{
  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
  GIOChannel *channel = (GIOChannel *) win32_channel;

  /* g_print ("g_io_channel_win32_new_pipe_with_wakeups %d %#x %d\n", fd, peer, peer_fd); */

  g_io_channel_init (channel);
  channel->funcs = &win32_channel_pipe_funcs;
  win32_channel->fd = fd;
  win32_channel->type = G_IO_PIPE;
  win32_channel->peer = peer;
  win32_channel->peer_fd = peer_fd;
  win32_channel->offset = 0;
  win32_channel->need_wakeups = TRUE;

  return channel;
}
Beispiel #15
0
GIOChannel *
g_io_channel_new_file (const gchar *filename,
                       const gchar *mode,
                       GError     **error)
{
  int fid, flags;
  mode_t create_mode;
  GIOChannel *channel;
  enum { /* Cheesy hack */
    MODE_R = 1 << 0,
    MODE_W = 1 << 1,
    MODE_A = 1 << 2,
    MODE_PLUS = 1 << 3
  } mode_num;
  struct stat buffer;

  g_return_val_if_fail (filename != NULL, NULL);
  g_return_val_if_fail (mode != NULL, NULL);
  g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);

  switch (mode[0])
    {
      case 'r':
        mode_num = MODE_R;
        break;
      case 'w':
        mode_num = MODE_W;
        break;
      case 'a':
        mode_num = MODE_A;
        break;
      default:
        g_warning ("Invalid GIOFileMode %s.\n", mode);
        return NULL;
    }

  switch (mode[1])
    {
      case '\0':
        break;
      case '+':
        if (mode[2] == '\0')
          {
            mode_num |= MODE_PLUS;
            break;
          }
        /* Fall through */
      default:
        g_warning ("Invalid GIOFileMode %s.\n", mode);
        return NULL;
    }

  switch (mode_num)
    {
      case MODE_R:
        flags = O_RDONLY;
        break;
      case MODE_W:
        flags = O_WRONLY | O_TRUNC | O_CREAT;
        break;
      case MODE_A:
        flags = O_WRONLY | O_APPEND | O_CREAT;
        break;
      case MODE_R | MODE_PLUS:
        flags = O_RDWR;
        break;
      case MODE_W | MODE_PLUS:
        flags = O_RDWR | O_TRUNC | O_CREAT;
        break;
      case MODE_A | MODE_PLUS:
        flags = O_RDWR | O_APPEND | O_CREAT;
        break;
      default:
        g_assert_not_reached ();
        flags = 0;
    }

  create_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  fid = open (filename, flags, create_mode);
  if (fid == -1)
    {
      g_set_error (error, G_FILE_ERROR,
                   g_file_error_from_errno (errno),
                   g_strerror (errno));
      return (GIOChannel *)NULL;
    }

  if (fstat (fid, &buffer) == -1) /* In case someone opens a FIFO */
    {
      close (fid);
      g_set_error (error, G_FILE_ERROR,
                   g_file_error_from_errno (errno),
                   g_strerror (errno));
      return (GIOChannel *)NULL;
    }

  channel = (GIOChannel *) g_new (GIOUnixChannel, 1);

  channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
                         || S_ISBLK (buffer.st_mode);

  switch (mode_num)
    {
      case MODE_R:
        channel->is_readable = TRUE;
        channel->is_writeable = FALSE;
        break;
      case MODE_W:
      case MODE_A:
        channel->is_readable = FALSE;
        channel->is_writeable = TRUE;
        break;
      case MODE_R | MODE_PLUS:
      case MODE_W | MODE_PLUS:
      case MODE_A | MODE_PLUS:
        channel->is_readable = TRUE;
        channel->is_writeable = TRUE;
        break;
      default:
        g_assert_not_reached ();
    }

  g_io_channel_init (channel);
  channel->close_on_unref = TRUE; /* must be after g_io_channel_init () */
  channel->funcs = &unix_channel_funcs;

  ((GIOUnixChannel *) channel)->fd = fid;
  return channel;
}
Beispiel #16
0
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server)
{
	GIOSSLChannel *chan;
	GIOChannel *gchan;
	int fd;
	SSL *ssl;
	SSL_CTX *ctx = NULL;

	const char *mycert = server->connrec->tls_cert;
	const char *mypkey = server->connrec->tls_pkey;
	const char *mypass = server->connrec->tls_pass;
	const char *cafile = server->connrec->tls_cafile;
	const char *capath = server->connrec->tls_capath;
	const char *ciphers = server->connrec->tls_ciphers;
	gboolean verify = server->connrec->tls_verify;

	g_return_val_if_fail(handle != NULL, NULL);

	if(!ssl_inited && !irssi_ssl_init())
		return NULL;

	if(!(fd = g_io_channel_unix_get_fd(handle)))
		return NULL;

	ERR_clear_error();
	ctx = SSL_CTX_new(SSLv23_client_method());
	if (ctx == NULL) {
		g_error("Could not allocate memory for SSL context");
		return NULL;
	}
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback);
	SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass);

	if (ciphers != NULL && ciphers[0] != '\0') {
		if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1)
			g_warning("No valid SSL cipher suite could be selected");
	}

	if (mycert && *mycert) {
		char *scert = NULL, *spkey = NULL;
		FILE *fp;
		scert = convert_home(mycert);
		if (mypkey && *mypkey)
			spkey = convert_home(mypkey);

		if ((fp = fopen(scert, "r"))) {
			X509 *cert;
			/* Let's parse the certificate by hand instead of using
			 * SSL_CTX_use_certificate_file so that we can validate
			 * some parts of it. */
			cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass);
			if (cert != NULL) {
				/* Only the expiration date is checked right now */
				if (X509_cmp_current_time(X509_get_notAfter(cert))  <= 0 ||
				    X509_cmp_current_time(X509_get_notBefore(cert)) >= 0)
					g_warning("The client certificate is expired");

				ERR_clear_error();
				if (! SSL_CTX_use_certificate(ctx, cert))
					g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM))
					g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_check_private_key(ctx))
					g_warning("Private key does not match the certificate");

				X509_free(cert);
			} else
				g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));

			fclose(fp);
		} else
			g_warning("Could not find client certificate '%s'", scert);
		g_free(scert);
		g_free(spkey);
	}

	if ((cafile && *cafile) || (capath && *capath)) {
		char *scafile = NULL;
		char *scapath = NULL;
		if (cafile && *cafile)
			scafile = convert_home(cafile);
		if (capath && *capath)
			scapath = convert_home(capath);
		if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) {
			g_warning("Could not load CA list for verifying TLS server certificate");
			g_free(scafile);
			g_free(scapath);
			SSL_CTX_free(ctx);
			return NULL;
		}
		g_free(scafile);
		g_free(scapath);
		verify = TRUE;
	} else if (store != NULL) {
		/* Make sure to increment the refcount every time the store is
		 * used, that's essential not to get it free'd by OpenSSL when
		 * the SSL_CTX is destroyed. */
		X509_STORE_up_ref(store);
		SSL_CTX_set_cert_store(ctx, store);
	}

	if(!(ssl = SSL_new(ctx)))
	{
		g_warning("Failed to allocate SSL structure");
		SSL_CTX_free(ctx);
		return NULL;
	}

	if(!SSL_set_fd(ssl, fd))
	{
		g_warning("Failed to associate socket to SSL stream");
		SSL_free(ssl);
		SSL_CTX_free(ctx);
		return NULL;
	}

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(ssl, server->connrec->address);
#endif

	SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
			SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

	chan = g_new0(GIOSSLChannel, 1);
	chan->fd = fd;
	chan->giochan = handle;
	chan->ssl = ssl;
	chan->ctx = ctx;
	chan->server = server;
	chan->port = port;
	chan->verify = verify;

	gchan = (GIOChannel *)chan;
	gchan->funcs = &irssi_ssl_channel_funcs;
	g_io_channel_init(gchan);
	gchan->is_readable = gchan->is_writeable = TRUE;
	gchan->use_buffer = FALSE;

	return gchan;
}