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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }