static Channel * server_request_tun(void) { Channel *c = NULL; int mode, tun; int sock; mode = packet_get_int(); switch (mode) { case SSH_TUNMODE_POINTOPOINT: case SSH_TUNMODE_ETHERNET: break; default: packet_send_debug("Unsupported tunnel device mode."); return NULL; } if ((options.permit_tun & mode) == 0) { packet_send_debug("Server has rejected tunnel device " "forwarding"); return NULL; } tun = packet_get_int(); if (forced_tun_device != -1) { if (tun != SSH_TUNID_ANY && forced_tun_device != tun) goto done; tun = forced_tun_device; } sock = tun_open(tun, mode); if (sock < 0) goto done; if (options.hpn_disabled) c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); else c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; #if defined(SSH_TUN_FILTER) if (mode == SSH_TUNMODE_POINTOPOINT) channel_register_filter(c->self, sys_tun_infilter, sys_tun_outfilter, NULL, NULL); #endif done: if (c == NULL) packet_send_debug("Failed to open the tunnel device."); return c; }
static Channel * server_request_session(struct ssh *ssh) { Channel *c; int r; debug("input_session_request"); if ((r = sshpkt_get_end(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); if (no_more_sessions) { ssh_packet_disconnect(ssh, "Possible attack: attempt to open a session " "after additional sessions disabled"); } /* * A server session has no fd to read or write until a * CHANNEL_REQUEST for a shell is made, so we set the type to * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all * CHANNEL_REQUEST messages is registered. */ c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); if (session_open(ssh, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); return NULL; } channel_register_cleanup(c->self, session_close_by_channel, 0); return c; }
static GObject * spice_gtk_session_constructor(GType gtype, guint n_properties, GObjectConstructParam *properties) { GObject *obj; SpiceGtkSession *self; SpiceGtkSessionPrivate *s; GList *list; GList *it; { /* Always chain up to the parent constructor */ GObjectClass *parent_class; parent_class = G_OBJECT_CLASS(spice_gtk_session_parent_class); obj = parent_class->constructor(gtype, n_properties, properties); } self = SPICE_GTK_SESSION(obj); s = self->priv; if (!s->session) g_error("SpiceGtKSession constructed without a session"); g_signal_connect(s->session, "channel-new", G_CALLBACK(channel_new), self); g_signal_connect(s->session, "channel-destroy", G_CALLBACK(channel_destroy), self); list = spice_session_get_channels(s->session); for (it = g_list_first(list); it != NULL; it = g_list_next(it)) { channel_new(s->session, it->data, (gpointer*)self); } g_list_free(list); return obj; }
void shell(SSH_SESSION *session){ CHANNEL *channel; struct termios terminal_local; int interactive=isatty(0); channel = channel_new(session); if(interactive){ tcgetattr(0,&terminal_local); memcpy(&terminal,&terminal_local,sizeof(struct termios)); } if(channel_open_session(channel)){ printf("error opening channel : %s\n",ssh_get_error(session)); return; } chan=channel; if(interactive){ channel_request_pty(channel); sizechanged(); } if(channel_request_shell(channel)){ printf("Requesting shell : %s\n",ssh_get_error(session)); return; } if(interactive){ cfmakeraw(&terminal_local); tcsetattr(0,TCSANOW,&terminal_local); setsignal(); } signal(SIGTERM,do_cleanup); select_loop(session,channel); }
/** * spice_display_new: * @session: a #SpiceSession * @id: the display channel ID to associate with #SpiceDisplay * * Returns: a new #SpiceDisplay widget. **/ SpiceDisplay *spice_display_new(SpiceSession *session, int id) { SpiceDisplay *display; SpiceDisplayPrivate *d; GList *list; GList *it; display = g_object_new(SPICE_TYPE_DISPLAY, NULL); d = SPICE_DISPLAY_GET_PRIVATE(display); d->session = g_object_ref(session); d->channel_id = id; SPICE_DEBUG("channel_id:%d",d->channel_id); g_signal_connect(session, "channel-new", G_CALLBACK(channel_new), display); g_signal_connect(session, "channel-destroy", G_CALLBACK(channel_destroy), display); list = spice_session_get_channels(session); for (it = g_list_first(list); it != NULL; it = g_list_next(it)) { channel_new(session, it->data, (gpointer*)display); } g_list_free(list); return display; }
static Channel * server_request_direct_tcpip(char *ctype) { Channel *c; int sock; char *target, *originator; int target_port, originator_port; target = packet_get_string(NULL); target_port = packet_get_int(); originator = packet_get_string(NULL); originator_port = packet_get_int(); packet_check_eom(); debug("server_request_direct_tcpip: originator %s port %d, target %s port %d", originator, originator_port, target, target_port); /* XXX check permission */ sock = channel_connect_to(target, target_port); xfree(target); xfree(originator); if (sock < 0) return NULL; c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1); return c; }
static Channel * server_request_session(void) { Channel *c; debug("input_session_request"); packet_check_eom(); if (no_more_sessions) { packet_disconnect("Possible attack: attempt to open a session " "after additional sessions disabled"); } /* * A server session has no fd to read or write until a * CHANNEL_REQUEST for a shell is made, so we set the type to * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all * CHANNEL_REQUEST messages is registered. */ c = channel_new("session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); return NULL; } channel_register_cleanup(c->self, session_close_by_channel, 0); return c; }
static channel_t * channel_dup(channel_t *chan){ channel_t *chand = channel_new(chan->fun,chan->channel,chan->f_param_count); fun_t ** f_param = chand->f_param; memcpy(chand,chan,sizeof(channel_t)); chand->f_param = f_param; memcpy(chand->f_param,chan->f_param,chan->f_param_count*sizeof(fun_t**)); return chand; }
tcp_connection_t* tcp_connection_new ( loop_t *loop, int fd, on_data_f datacb, on_close_f closecb, void* userdata, const inetaddr_t *peer_addr ) { tcp_connection_t *connection; struct sockaddr_in addr; socklen_t addr_len; struct linger linger_info; int flag; if (NULL == loop || fd < 0 || NULL == datacb || NULL == closecb || NULL == peer_addr) { log_error("tcp_connection_new: bad loop(%p) or bad fd(%d) or bad datacb(%p) or bad closecb(%p) or bad peer_addr(%p)", loop, fd, datacb, closecb, peer_addr); return NULL; } connection = (tcp_connection_t*)malloc(sizeof(*connection)); memset(connection, 0, sizeof(*connection)); flag = 1; setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag)); memset(&linger_info, 0, sizeof(linger_info)); linger_info.l_onoff = 1; linger_info.l_linger = 3; setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_info, sizeof(linger_info)); connection->loop = loop; connection->fd = fd; connection->datacb = datacb; connection->closecb = closecb; connection->userdata = userdata; connection->channel = channel_new(fd, loop, connection_onevent, connection); connection->in_buffer = buffer_new(4096); connection->out_buffer = buffer_new(4096); connection->is_in_callback = 0; connection->is_alive = 1; connection->is_connected = 1; connection->need_closed_after_sent_done = 0; connection->peer_addr = *peer_addr; memset(&addr, 0, sizeof(addr)); addr_len = sizeof(addr); getsockname(fd, (struct sockaddr*)&addr, &addr_len); inetaddr_init(&connection->local_addr, &addr); channel_setevent(connection->channel, EPOLLIN); return connection; }
/** Create a new Channel with the specified callbacks to manage outgoing data. * * \param name name of this object, used for debugging * \param fd file descriptor to consider * \param status_cbk callback function called when the state of the socket changes, can be NULL * \param handle pointer to opaque data passed to callback functions * \return a pointer to the new Channel * * \see o_el_state_socket_callback * \see channel_new */ static Channel* eventloop_on_out_fd( char* name, int fd, o_el_state_socket_callback status_cbk, void* handle ) { Channel* ch = channel_new(name, fd, POLLOUT, status_cbk, handle); return ch; }
static void forwarding(ssh_session session){ ssh_channel channel; int r; channel=channel_new(session); r=channel_open_forward(channel,desthost,atoi(port),"localhost",22); if(r<0) { printf("error forwarding port : %s\n",ssh_get_error(session)); return; } select_loop(session,channel); }
void batch_shell(SSH_SESSION *session){ CHANNEL *channel; char buffer[1024]; int i,s=0; for(i=0;i<MAXCMD && cmds[i];++i) s+=snprintf(buffer+s,sizeof(buffer)-s,"%s ",cmds[i]); channel=channel_new(session); channel_open_session(channel); if(channel_request_exec(channel,buffer)){ printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session)); return; } select_loop(session,channel); }
/** Create a new Channel with the specified callbacks on incoming data. * * \param name name of this object, used for debugging * \param fd file descriptor to consider * \param read_cbk callback function called when there is data to read, can be NULL * \param monitor_cbk callback function called when a new normal event arrives but no read_cbk was registered (e.g., listening socket), can be NULL * \param status_cbk callback function called when the state of the socket changes, can be NULL * \param handle pointer to opaque data passed to callback functions * \return a pointer to the new Channel * * \see o_el_read_socket_callback, o_el_monitor_socket_callback, o_el_state_socket_callback * \see channel_new */ static Channel* eventloop_on_in_fd( char* name, int fd, o_el_read_socket_callback read_cbk, o_el_monitor_socket_callback monitor_cbk, o_el_state_socket_callback status_cbk, void* handle ) { Channel* ch = channel_new(name, fd, POLLIN, status_cbk, handle); ch->read_cbk = read_cbk; ch->monitor_cbk = monitor_cbk; /* status_cbk is already set by channel_new */ return ch; }
// Connect to a SSH server. // When the connection is established, read data from stdin and send it to the server. void client_pipe(char *host, int port) { ssh_session s = ssh_new(); ssh_options_set(s, SSH_OPTIONS_HOST, host); ssh_options_set(s, SSH_OPTIONS_PORT, &port); ssh_options_set(s, SSH_OPTIONS_USER, "xya"); //ssh_options_set(s, SSH_OPTIONS_LOG_VERBOSITY_STR, "5"); if(ssh_connect(s) != SSH_OK) return session_error(s, "connect"); char *hash = pubkey_hash(ssh_get_pubkey(s)); if(authenticate(hash, 0)) { session_event(s, "authenticated", hash); free(hash); } else { free(hash); exit(1); } int keytype; ssh_string pub = publickey_from_file(s, "test-client-key.pub", &keytype); if(!pub) session_error(s, "open-public-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_offer_pubkey(s, NULL, keytype, pub)) session_error(s, "offer-public-key"); ssh_private_key priv = privatekey_from_file(s, "test-client-key", keytype, NULL); if(!priv) session_error(s, "open-private-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_pubkey(s, NULL, pub, priv)) session_error(s, "user-auth"); string_free(pub); privatekey_free(priv); ssh_channel chan = channel_new(s); if(!chan) session_error(s, "create-channel"); if(channel_open_session(chan) < 0) session_error(s, "open-channel"); session_event(s, "channel-opened", NULL); channel_from_file(chan, 0); channel_free(chan); ssh_disconnect(s); ssh_finalize(); }
int ssh_scp_init(ssh_scp scp){ int r; char execbuffer[1024]; uint8_t code; if(scp->state != SSH_SCP_NEW){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state"); return SSH_ERROR; } ssh_log(scp->session,SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'", scp->mode==SSH_SCP_WRITE?"write":"read", scp->recursive?"recursive ":"", scp->location); scp->channel=channel_new(scp->session); if(scp->channel == NULL){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r= channel_open_session(scp->channel); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(scp->mode == SSH_SCP_WRITE) snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s", scp->recursive ? "-r":"", scp->location); else snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s", scp->recursive ? "-r":"", scp->location); if(channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(scp->mode == SSH_SCP_WRITE){ r=channel_read(scp->channel,&code,1,0); if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } } else { channel_write(scp->channel,"",1); } if(scp->mode == SSH_SCP_WRITE) scp->state=SSH_SCP_WRITE_INITED; else scp->state=SSH_SCP_READ_INITED; return SSH_OK; }
ssh_channel SSHClient::openChannel(ssh_session session) { // GNASH_REPORT_FUNCTION; if (session) { _channel = channel_new(session); if (_channel) { if (channel_open_session(_channel) != SSH_OK) { log_error(_("Can't open the SSH channel!")); } } else { log_error(_("Can't allocate memory for new SSH channel!")); } } return _channel; }
/* open new channel for a session */ static int ssh_session2_open(void) { Channel *c; int window, packetmax, in, out, err; if (stdin_null_flag) { in = open(_PATH_DEVNULL, O_RDONLY); } else { in = dup(STDIN_FILENO); } out = dup(STDOUT_FILENO); err = dup(STDERR_FILENO); if (in < 0 || out < 0 || err < 0) fatal("dup() in/out/err failed"); /* enable nonblocking unless tty */ if (!isatty(in)) set_nonblock(in); if (!isatty(out)) set_nonblock(out); if (!isatty(err)) set_nonblock(err); window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { window >>= 1; packetmax >>= 1; } c = channel_new( "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self); if (!no_shell_flag) channel_register_open_confirm(c->self, ssh_session2_setup, NULL); return c->self; }
async_task_queue_t* async_task_queue_create(loop_t* loop) { async_task_queue_t* task_queue = (async_task_queue_t*)malloc(sizeof(async_task_queue_t)); memset(task_queue, 0, sizeof(*task_queue)); task_queue->loop = loop; socketpair(task_queue->fds); task_queue->channel = channel_new(task_queue->fds[0], loop, async_task_event, task_queue); channel_setevent(task_queue->channel, POLLIN); task_queue->async_task = NULL; task_queue->async_task_end = NULL; lock_init(&task_queue->task_lock); return task_queue; }
static inline int at_response_clip (pvt_t* pvt, char* str, size_t len) { struct ast_channel* channel; char* clip; if (pvt->initialized && pvt->has_voice && pvt->needring == 0) { pvt->incoming = 1; if ((clip = at_parse_clip (pvt, str, len)) == NULL) { ast_log (LOG_ERROR, "[%s] Error parsing CLIP: %s\n", pvt->id, str); } // pvt->number ? pvt->number : pvt->exten??? if (!(channel = channel_new (pvt, AST_STATE_RING, clip, pvt->number ? pvt->number : NULL, NULL))) { ast_log (LOG_ERROR, "[%s] Unable to allocate channel for incoming call\n", pvt->id); if (at_send_chup (pvt) || at_fifo_queue_add (pvt, CMD_AT_CHUP, RES_OK)) { ast_log (LOG_ERROR, "[%s] Error sending AT+CHUP command\n", pvt->id); } return -1; } pvt->needchup = 1; pvt->needring = 1; if (ast_pbx_start (channel)) { ast_log (LOG_ERROR, "[%s] Unable to start pbx on incoming call\n", pvt->id); channel_ast_hangup (pvt); return -1; } } return 0; }
static void do_tcp_server_start(void* userdata) { tcp_server_t *server = (tcp_server_t*)userdata; do { server->fd = create_server_socket(server->addr.port, server->addr.ip); if (server->fd < 0) { log_error("do_tcp_server_start: create_server_socket() failed, local addr: %s:%u", server->addr.ip, server->addr.port); break; } server->channel = channel_new(server->fd, server->loop, server_onevent, server); if (listen(server->fd, 512) != 0) { log_error("do_tcp_server_start: listen() failed, errno: %d, local addr: %s:%u", errno, server->addr.ip, server->addr.port); break; } if (channel_setevent(server->channel, EPOLLIN)) { log_error("do_tcp_server_start: channel_setevent() failed, local addr: %s:%u", server->addr.ip, server->addr.port); break; } return; } while(0); if (server->fd >= 0) { close(server->fd); server->fd = -1; } channel_destroy(server->channel); server->channel = NULL; server->is_started = 0; return; }
static Channel * server_request_tun(struct ssh *ssh) { Channel *c = NULL; int r, sock; u_int tun, mode; if ((r = sshpkt_get_u32(ssh, &mode)) != 0 || (r = sshpkt_get_u32(ssh, &tun)) != 0) fatal("%s: %s", __func__, ssh_err(r)); switch (mode) { case SSH_TUNMODE_POINTOPOINT: case SSH_TUNMODE_ETHERNET: break; default: ssh_packet_send_debug(ssh, "Unsupported tunnel device mode."); return NULL; } if ((options.permit_tun & mode) == 0) { ssh_packet_send_debug(ssh, "Server has rejected tunnel device " "forwarding"); return NULL; } if (forced_tun_device >= 0) { if (tun != SSH_TUNID_ANY && (u_int)forced_tun_device != tun) goto done; tun = forced_tun_device; } sock = tun_open(tun, mode); if (sock < 0) goto done; c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; done: if (c == NULL) ssh_packet_send_debug(ssh, "Failed to open the tunnel device."); return c; }
static Channel * server_request_tun(void) { Channel *c = NULL; int mode, tun; int sock; mode = packet_get_int(); switch (mode) { case SSH_TUNMODE_POINTOPOINT: case SSH_TUNMODE_ETHERNET: break; default: packet_send_debug("Unsupported tunnel device mode."); return NULL; } if ((options.permit_tun & mode) == 0) { packet_send_debug("Server has rejected tunnel device " "forwarding"); return NULL; } tun = packet_get_int(); if (forced_tun_device != -1) { if (tun != SSH_TUNID_ANY && forced_tun_device != tun) goto done; tun = forced_tun_device; } sock = tun_open(tun, mode); if (sock < 0) goto done; c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; done: if (c == NULL) packet_send_debug("Failed to open the tunnel device."); return c; }
static void create_files(ssh_session session){ ssh_channel channel=channel_new(session); char buffer[1]; if(channel == NULL){ fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session)); exit(EXIT_FAILURE); } if(channel_open_session(channel) != SSH_OK){ fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session)); exit(EXIT_FAILURE); } if(channel_request_exec(channel,createcommand) != SSH_OK){ fprintf(stderr,"Error executing command: %s\n",ssh_get_error(session)); exit(EXIT_FAILURE); } while(!channel_is_eof(channel)){ channel_read(channel,buffer,1,1); write(1,buffer,1); } channel_close(channel); channel_free(channel); }
udp_peer_t* udp_peer_new(loop_t *loop, const char *ip, unsigned short port, on_message_f messagecb, on_writable_f writecb, void *userdata) { SOCKET fd; udp_peer_t* peer; if (NULL == loop || NULL == ip || 0 == port || NULL == messagecb) { log_error("udp_peer_new: bad loop(%p) or bad ip(%p) or bad port(%p) or bad messagecb(%p)", loop, ip, port, messagecb); return NULL; } fd = create_udp_socket(port, ip); if (INVALID_SOCKET == fd) { log_error("udp_peer_new: create_udp_socket() failed, local addr: %s:%u, errno: %d", ip, port, WSAGetLastError()); return NULL; } peer = (udp_peer_t*)malloc(sizeof(udp_peer_t)); memset(peer, 0, sizeof(*peer)); peer->ref_count = 1; peer->loop = loop; strncpy(peer->ip, ip, 16); peer->port = port; peer->messagecb = messagecb; peer->message_userdata = userdata; peer->writecb = writecb; peer->write_userdata = userdata; peer->fd = fd; peer->channel = channel_new(fd, peer->loop, udp_peer_onevent, peer); loop_run_inloop(peer->loop, init_udp_peer_event, peer); return peer; }
static Channel * server_request_session(char *ctype) { Channel *c; debug("input_session_request"); packet_check_eom(); /* * A server session has no fd to read or write until a * CHANNEL_REQUEST for a shell is made, so we set the type to * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all * CHANNEL_REQUEST messages is registered. */ c = channel_new(ctype, SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); if (session_open(xxx_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); return NULL; } channel_register_cleanup(c->self, session_close_by_channel); return c; }
static int _process_channel(const gchar *channel_directory, GKeyFile *kf, const char *identifier, enum op op, struct channel_configuration *defaults, enclosure_filter *filter) { channel *c; gchar *channel_filename, *channel_file; struct channel_configuration *channel_configuration; enclosure_filter *per_channel_filter = NULL; /* Check channel identifier and read channel configuration. */ if (!g_key_file_has_group(kf, identifier)) { fprintf(stderr, "Unknown channel identifier %s.\n", identifier); return -1; } /* Verify the keys in the channel configuration. */ if (channel_configuration_verify_keys(kf, identifier) < 0) return -1; channel_configuration = channel_configuration_new(kf, identifier, defaults); /* Check that mandatory keys were set. */ if (!channel_configuration->url) { fprintf(stderr, "No feed URL set for channel %s.\n", identifier); channel_configuration_free(channel_configuration); return -1; } if (!channel_configuration->spool_directory) { fprintf(stderr, "No spool directory set for channel %s.\n", identifier); channel_configuration_free(channel_configuration); return -1; } /* Construct channel file name. */ channel_filename = g_strjoin(".", identifier, "xml", NULL); channel_file = g_build_filename(channel_directory, channel_filename, NULL); g_free(channel_filename); if (new_only && access(channel_file, F_OK) == 0) { /* If we are only fetching new channels, skip the channel if there is already a channel file present. */ channel_configuration_free(channel_configuration); return 0; } c = channel_new(channel_configuration->url, channel_file, channel_configuration->spool_directory, resume); g_free(channel_file); if (!c) { fprintf(stderr, "Error parsing channel file for channel %s.\n", identifier); channel_configuration_free(channel_configuration); return -1; } /* Set up per-channel filter unless overridden on the command line. */ if (!filter && channel_configuration->regex_filter) { per_channel_filter = enclosure_filter_new(channel_configuration->regex_filter, FALSE); filter = per_channel_filter; } switch (op) { case OP_UPDATE: channel_update(c, channel_configuration, update_callback, 0, 0, first_only, resume, filter, debug, show_progress_bar); break; case OP_CATCHUP: channel_update(c, channel_configuration, catchup_callback, 1, 0, first_only, 0, filter, debug, show_progress_bar); break; case OP_LIST: channel_update(c, channel_configuration, list_callback, 1, 1, first_only, 0, filter, debug, show_progress_bar); break; } /* Clean-up. */ if (per_channel_filter) enclosure_filter_free(per_channel_filter); channel_free(c); channel_configuration_free(channel_configuration); return 0; }
static gpointer remmina_ssh_tunnel_main_thread_proc (gpointer data) { RemminaSSHTunnel *tunnel = (RemminaSSHTunnel*) data; gchar *ptr; ssize_t len = 0, lenw = 0; fd_set set; struct timeval timeout; GTimeVal t1, t2; glong diff; ssh_channel channel = NULL; gboolean first = TRUE; gboolean disconnected; gint sock; gint maxfd; gint i; gint ret; struct sockaddr_in sin; g_get_current_time (&t1); t2 = t1; switch (tunnel->tunnel_type) { case REMMINA_SSH_TUNNEL_OPEN: /* Accept a local connection */ sock = accept (tunnel->server_sock, NULL, NULL); if (sock < 0) { REMMINA_SSH (tunnel)->error = g_strdup ("Failed to accept local socket"); tunnel->thread = 0; return NULL; } if ((channel = channel_new (tunnel->ssh.session)) == NULL) { close (sock); remmina_ssh_set_error (REMMINA_SSH (tunnel), "Failed to createt channel : %s"); tunnel->thread = 0; return NULL; } /* Request the SSH server to connect to the destination */ if (channel_open_forward (channel, tunnel->dest, tunnel->port, "127.0.0.1", 0) != SSH_OK) { close (sock); channel_close (channel); channel_free (channel); remmina_ssh_set_error (REMMINA_SSH (tunnel), _("Failed to connect to the SSH tunnel destination: %s")); tunnel->thread = 0; return NULL; } remmina_ssh_tunnel_add_channel (tunnel, channel, sock); break; case REMMINA_SSH_TUNNEL_X11: if ((tunnel->x11_channel = channel_new (tunnel->ssh.session)) == NULL) { remmina_ssh_set_error (REMMINA_SSH (tunnel), "Failed to create channel : %s"); tunnel->thread = 0; return NULL; } if (!remmina_public_get_xauth_cookie (tunnel->localdisplay, &ptr)) { remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "%s", ptr); g_free(ptr); tunnel->thread = 0; return NULL; } if (channel_open_session (tunnel->x11_channel) || channel_request_x11 (tunnel->x11_channel, TRUE, NULL, ptr, gdk_screen_get_number (gdk_screen_get_default ()))) { g_free(ptr); remmina_ssh_set_error (REMMINA_SSH (tunnel), "Failed to open channel : %s"); tunnel->thread = 0; return NULL; } g_free(ptr); if (channel_request_exec (tunnel->x11_channel, tunnel->dest)) { ptr = g_strdup_printf(_("Failed to execute %s on SSH server : %%s"), tunnel->dest); remmina_ssh_set_error (REMMINA_SSH (tunnel), ptr); g_free(ptr); tunnel->thread = 0; return NULL; } if (tunnel->init_func && ! (*tunnel->init_func) (tunnel, tunnel->callback_data)) { if (tunnel->disconnect_func) { (*tunnel->disconnect_func) (tunnel, tunnel->callback_data); } tunnel->thread = 0; return NULL; } break; case REMMINA_SSH_TUNNEL_XPORT: /* Detect the next available port starting from 6010 on the server */ for (i = 10; i <= MAX_X_DISPLAY_NUMBER; i++) { if (channel_forward_listen (REMMINA_SSH (tunnel)->session, (tunnel->bindlocalhost ? "localhost" : NULL), 6000 + i, NULL)) { continue; } else { tunnel->remotedisplay = i; break; } } if (tunnel->remotedisplay < 1) { remmina_ssh_set_error (REMMINA_SSH (tunnel), _("Failed to request port forwarding : %s")); if (tunnel->disconnect_func) { (*tunnel->disconnect_func) (tunnel, tunnel->callback_data); } tunnel->thread = 0; return NULL; } if (tunnel->init_func && ! (*tunnel->init_func) (tunnel, tunnel->callback_data)) { if (tunnel->disconnect_func) { (*tunnel->disconnect_func) (tunnel, tunnel->callback_data); } tunnel->thread = 0; return NULL; } break; case REMMINA_SSH_TUNNEL_REVERSE: if (channel_forward_listen (REMMINA_SSH (tunnel)->session, NULL, tunnel->port, NULL)) { remmina_ssh_set_error (REMMINA_SSH (tunnel), _("Failed to request port forwarding : %s")); if (tunnel->disconnect_func) { (*tunnel->disconnect_func) (tunnel, tunnel->callback_data); } tunnel->thread = 0; return NULL; } if (tunnel->init_func && ! (*tunnel->init_func) (tunnel, tunnel->callback_data)) { if (tunnel->disconnect_func) { (*tunnel->disconnect_func) (tunnel, tunnel->callback_data); } tunnel->thread = 0; return NULL; } break; } tunnel->buffer_len = 10240; tunnel->buffer = g_malloc (tunnel->buffer_len); /* Start the tunnel data transmittion */ while (tunnel->running) { if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_XPORT || tunnel->tunnel_type == REMMINA_SSH_TUNNEL_X11 || tunnel->tunnel_type == REMMINA_SSH_TUNNEL_REVERSE) { if (first) { first = FALSE; /* Wait for a period of time for the first incoming connection */ if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_X11) { channel = channel_accept_x11 (tunnel->x11_channel, 15000); } else { channel = channel_forward_accept (REMMINA_SSH (tunnel)->session, 15000); } if (!channel) { remmina_ssh_set_application_error (REMMINA_SSH (tunnel), _("No response from the server.")); if (tunnel->disconnect_func) { (*tunnel->disconnect_func) (tunnel, tunnel->callback_data); } tunnel->thread = 0; return NULL; } if (tunnel->connect_func) { (*tunnel->connect_func) (tunnel, tunnel->callback_data); } if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_REVERSE) { /* For reverse tunnel, we only need one connection. */ channel_forward_cancel (REMMINA_SSH (tunnel)->session, NULL, tunnel->port); } } else if (tunnel->tunnel_type != REMMINA_SSH_TUNNEL_REVERSE) { /* Poll once per some period of time if no incoming connections. * Don't try to poll continuously as it will significantly slow down the loop */ g_get_current_time (&t1); diff = (t1.tv_sec - t2.tv_sec) * 10 + (t1.tv_usec - t2.tv_usec) / 100000; if (diff > 1) { if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_X11) { channel = channel_accept_x11 (tunnel->x11_channel, 0); } else { channel = channel_forward_accept (REMMINA_SSH (tunnel)->session, 0); } if (channel == NULL) { t2 = t1; } } } if (channel) { if (tunnel->tunnel_type == REMMINA_SSH_TUNNEL_REVERSE) { sin.sin_family = AF_INET; sin.sin_port = htons (tunnel->localport); sin.sin_addr.s_addr = inet_addr ("127.0.0.1"); sock = socket (AF_INET, SOCK_STREAM, 0); if (connect (sock, (struct sockaddr *) &sin, sizeof (sin)) < 0) { remmina_ssh_set_application_error (REMMINA_SSH (tunnel), "Cannot connect to local port %i.", tunnel->localport); close (sock); sock = -1; } } else { sock = remmina_public_open_xdisplay (tunnel->localdisplay); } if (sock >= 0) { remmina_ssh_tunnel_add_channel (tunnel, channel, sock); } else { /* Failed to create unix socket. Will this happen? */ channel_close (channel); channel_free (channel); } channel = NULL; } } if (tunnel->num_channels <= 0) { /* No more connections. We should quit */ break; } timeout.tv_sec = 0; timeout.tv_usec = 200000; FD_ZERO (&set); maxfd = 0; for (i = 0; i < tunnel->num_channels; i++) { if (tunnel->sockets[i] > maxfd) { maxfd = tunnel->sockets[i]; } FD_SET (tunnel->sockets[i], &set); } ret = ssh_select (tunnel->channels, tunnel->channels_out, maxfd + 1, &set, &timeout); if (!tunnel->running) break; if (ret == SSH_EINTR) continue; if (ret == -1) break; i = 0; while (tunnel->running && i < tunnel->num_channels) { disconnected = FALSE; if (FD_ISSET (tunnel->sockets[i], &set)) { while (!disconnected && (len = read (tunnel->sockets[i], tunnel->buffer, tunnel->buffer_len)) > 0) { for (ptr = tunnel->buffer, lenw = 0; len > 0; len -= lenw, ptr += lenw) { lenw = channel_write (tunnel->channels[i], (char*) ptr, len); if (lenw <= 0) { disconnected = TRUE; break; } } } if (len == 0) disconnected = TRUE; } if (disconnected) { remmina_ssh_tunnel_remove_channel (tunnel, i); continue; } i++; } if (!tunnel->running) break; i = 0; while (tunnel->running && i < tunnel->num_channels) { disconnected = FALSE; if (!tunnel->socketbuffers[i]) { len = channel_poll (tunnel->channels[i], 0); if (len == SSH_ERROR || len == SSH_EOF) { disconnected = TRUE; } else if (len > 0) { tunnel->socketbuffers[i] = remmina_ssh_tunnel_buffer_new (len); len = channel_read_nonblocking (tunnel->channels[i], tunnel->socketbuffers[i]->data, len, 0); if (len <= 0) { disconnected = TRUE; } else { tunnel->socketbuffers[i]->len = len; } } } if (!disconnected && tunnel->socketbuffers[i]) { for (lenw = 0; tunnel->socketbuffers[i]->len > 0; tunnel->socketbuffers[i]->len -= lenw, tunnel->socketbuffers[i]->ptr += lenw) { lenw = write (tunnel->sockets[i], tunnel->socketbuffers[i]->ptr, tunnel->socketbuffers[i]->len); if (lenw == -1 && errno == EAGAIN && tunnel->running) { /* Sometimes we cannot write to a socket (always EAGAIN), probably because it's internal * buffer is full. We need read the pending bytes from the socket first. so here we simply * break, leave the buffer there, and continue with other data */ break; } if (lenw <= 0) { disconnected = TRUE; break; } } if (tunnel->socketbuffers[i]->len <= 0) { remmina_ssh_tunnel_buffer_free (tunnel->socketbuffers[i]); tunnel->socketbuffers[i] = NULL; } } if (disconnected) { remmina_ssh_tunnel_remove_channel (tunnel, i); continue; } i++; } } remmina_ssh_tunnel_close_all_channels (tunnel); return NULL; }
static gpointer remmina_ssh_shell_thread (gpointer data) { RemminaSSHShell *shell = (RemminaSSHShell*) data; fd_set fds; struct timeval timeout; ssh_channel channel = NULL; ssh_channel ch[2], chout[2]; gchar *buf = NULL; gint buf_len; gint len; gint i, ret; LOCK_SSH (shell) if ((channel = channel_new (REMMINA_SSH (shell)->session)) == NULL || channel_open_session (channel)) { UNLOCK_SSH (shell) remmina_ssh_set_error (REMMINA_SSH (shell), "Failed to open channel : %s"); if (channel) channel_free (channel); shell->thread = 0; return NULL; } channel_request_pty (channel); if (shell->exec && shell->exec[0]) { ret = channel_request_exec (channel, shell->exec); } else { ret = channel_request_shell (channel); } if (ret) { UNLOCK_SSH (shell) remmina_ssh_set_error (REMMINA_SSH (shell), "Failed to request shell : %s"); channel_close (channel); channel_free (channel); shell->thread = 0; return NULL; } shell->channel = channel; UNLOCK_SSH (shell) buf_len = 1000; buf = g_malloc (buf_len + 1); ch[0] = channel; ch[1] = NULL; while (!shell->closed) { timeout.tv_sec = 1; timeout.tv_usec = 0; FD_ZERO (&fds); FD_SET (shell->master, &fds); ret = ssh_select (ch, chout, shell->master + 1, &fds, &timeout); if (ret == SSH_EINTR) continue; if (ret == -1) break; if (FD_ISSET (shell->master, &fds)) { len = read (shell->master, buf, buf_len); if (len <= 0) break; LOCK_SSH (shell) channel_write (channel, buf, len); UNLOCK_SSH (shell) } for (i = 0; i < 2; i++) { LOCK_SSH (shell) len = channel_poll (channel, i); UNLOCK_SSH (shell) if (len == SSH_ERROR || len == SSH_EOF) { shell->closed = TRUE; break; } if (len <= 0) continue; if (len > buf_len) { buf_len = len; buf = (gchar*) g_realloc (buf, buf_len + 1); } LOCK_SSH (shell) len = channel_read_nonblocking (channel, buf, len, i); UNLOCK_SSH (shell) if (len <= 0) { shell->closed = TRUE; break; } while (len > 0) { ret = write (shell->master, buf, len); if (ret <= 0) break; len -= ret; } } }
/* open new channel for a session */ static int ssh_session2_open(void) { Channel *c; int window, packetmax, in, out, err; int sock; int socksize; int socksizelen = sizeof(int); if (stdin_null_flag) { in = open(_PATH_DEVNULL, O_RDONLY); } else { in = dup(STDIN_FILENO); } out = dup(STDOUT_FILENO); err = dup(STDERR_FILENO); if (in < 0 || out < 0 || err < 0) fatal("dup() in/out/err failed"); /* enable nonblocking unless tty */ if (!isatty(in)) set_nonblock(in); if (!isatty(out)) set_nonblock(out); if (!isatty(err)) set_nonblock(err); /* we need to check to see if what they want to do about buffer */ /* sizes here. In a hpn to nonhpn connection we want to limit */ /* the window size to something reasonable in case the far side */ /* has the large window bug. In hpn to hpn connection we want to */ /* use the max window size but allow the user to override it */ /* lastly if they disabled hpn then use the ssh std window size */ /* so why don't we just do a getsockopt() here and set the */ /* ssh window to that? In the case of a autotuning receive */ /* window the window would get stuck at the initial buffer */ /* size generally less than 96k. Therefore we need to set the */ /* maximum ssh window size to the maximum hpn buffer size */ /* unless the user has specifically set the tcprcvbufpoll */ /* to no. In which case we *can* just set the window to the */ /* minimum of the hpn buffer size and tcp receive buffer size */ if (tty_flag) options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; else options.hpn_buffer_size = 2*1024*1024; if (datafellows & SSH_BUG_LARGEWINDOW) { debug("HPN to Non-HPN Connection"); } else { if (options.tcp_rcv_buf_poll <= 0) { sock = socket(AF_INET, SOCK_STREAM, 0); getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen); close(sock); debug("socksize %d", socksize); options.hpn_buffer_size = socksize; debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size); } else { if (options.tcp_rcv_buf > 0) { /*create a socket but don't connect it */ /* we use that the get the rcv socket size */ sock = socket(AF_INET, SOCK_STREAM, 0); /* if they are using the tcp_rcv_buf option */ /* attempt to set the buffer size to that */ if (options.tcp_rcv_buf) setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, sizeof(options.tcp_rcv_buf)); getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen); close(sock); debug("socksize %d", socksize); options.hpn_buffer_size = socksize; debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size); } } } debug("Final hpn_buffer_size = %d", options.hpn_buffer_size); window = options.hpn_buffer_size; channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { window = 4*CHAN_SES_PACKET_DEFAULT; window >>= 1; packetmax >>= 1; } c = channel_new( "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) { c->dynamic_window = 1; debug ("Enabled Dynamic Window Scaling\n"); } debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self); if (!no_shell_flag) channel_register_open_confirm(c->self, ssh_session2_setup, NULL); return c->self; }
gboolean remmina_nx_session_open(RemminaNXSession *nx, const gchar *server, guint port, const gchar *private_key_file, RemminaNXPassphraseCallback passphrase_func, gpointer userdata) { gint ret; ssh_private_key privkey; ssh_public_key pubkey; ssh_string pubkeystr; gint keytype; gboolean encrypted; gchar *passphrase = NULL; gchar tmpfile[L_tmpnam + 1]; nx ->session = ssh_new(); ssh_options_set(nx->session, SSH_OPTIONS_HOST, server); ssh_options_set(nx->session, SSH_OPTIONS_PORT, &port); ssh_options_set(nx->session, SSH_OPTIONS_USER, "nx"); if (private_key_file && private_key_file[0]) { if (!remmina_get_keytype(private_key_file, &keytype, &encrypted)) { remmina_nx_session_set_application_error(nx, "Invalid private key file."); return FALSE; } if (encrypted && !passphrase_func(&passphrase, userdata)) { return FALSE; } privkey = privatekey_from_file(nx->session, private_key_file, keytype, (passphrase ? passphrase : "")); g_free(passphrase); } else { /* Use NoMachine's default nx private key */ if ((tmpnam(tmpfile)) == NULL || !g_file_set_contents(tmpfile, nx_default_private_key, -1, NULL)) { remmina_nx_session_set_application_error(nx, "Failed to create temporary private key file."); return FALSE; } privkey = privatekey_from_file(nx->session, tmpfile, REMMINA_SSH_TYPE_DSS, ""); g_unlink(tmpfile); } if (privkey == NULL) { remmina_nx_session_set_error(nx, "Invalid private key file: %s"); return FALSE; } pubkey = publickey_from_privatekey(privkey); pubkeystr = publickey_to_string(pubkey); publickey_free(pubkey); if (ssh_connect(nx->session)) { string_free(pubkeystr); privatekey_free(privkey); remmina_nx_session_set_error(nx, "Failed to startup SSH session: %s"); return FALSE; } ret = ssh_userauth_pubkey(nx->session, NULL, pubkeystr, privkey); string_free(pubkeystr); privatekey_free(privkey); if (ret != SSH_AUTH_SUCCESS) { remmina_nx_session_set_error(nx, "NX SSH authentication failed: %s"); return FALSE; } if ((nx->channel = channel_new(nx->session)) == NULL || channel_open_session(nx->channel)) { return FALSE; } if (channel_request_shell(nx->channel)) { return FALSE; } /* NX server starts the session with an initial 105 status */ if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; /* Say hello to the NX server */ remmina_nx_session_send_command(nx, "HELLO NXCLIENT - Version %s", nx->version); if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; /* Set the NX session environment */ remmina_nx_session_send_command(nx, "SET SHELL_MODE SHELL"); if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; remmina_nx_session_send_command(nx, "SET AUTH_MODE PASSWORD"); if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; nx->server = g_strdup(server); return TRUE; }