Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/** 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;
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
/** 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;
}
Ejemplo n.º 14
0
// 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();
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
/* 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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
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;
			}
		}
	}
Ejemplo n.º 29
0
/* 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;
}
Ejemplo n.º 30
0
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;
}