[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reading multiple channels under the same session


Hi,

How can I read multiple new incoming channels under the same session in a
libssh server? I need this since when using dynamic port forwarding and per
every SOCKS5 request it creates a new channel as you can see in this log
(gotten with -vvv):

debug1: Next authentication method: password
> default@localhost's password:
> debug2: we sent a password packet, wait for reply
> debug1: Authentication succeeded (password).
> Authenticated to localhost ([127.0.0.1]:1234).
> debug1: Local connections to 0.0.0.0:11223 forwarded to remote address
> socks:0
> debug3: channel_setup_fwd_listener_tcpip: type 2 wildcard 0 addr 0.0.0.0
> debug1: Local forwarding listening on 0.0.0.0 port 11223.
> debug2: fd 4 setting O_NONBLOCK
> debug3: fd 4 is O_NONBLOCK
> debug1: channel 0: new [port listener]
> debug1: channel 1: new [client-session]
> debug3: ssh_session2_open: channel_new: 1
> debug2: channel 1: send open
> debug1: Entering interactive session.
> debug2: callback start
> debug2: fd 3 setting TCP_NODELAY
> debug3: packet_set_tos: set IP_TOS 0x10
> debug2: client_session2_setup: id 1
> debug2: channel 1: request pty-req confirm 1
> debug1: Sending environment.
> debug3: Ignored env XDG_SESSION_ID
> debug3: Ignored env TERM
> debug3: Ignored env SHELL
> debug3: Ignored env SSH_CLIENT
> debug3: Ignored env SSH_TTY
> debug3: Ignored env USER
> debug3: Ignored env LS_COLORS
> debug3: Ignored env MAIL
> debug3: Ignored env PATH
> debug3: Ignored env PWD
> debug1: Sending env LANG = en_US.UTF-8
> debug2: channel 1: request env confirm 0
> debug3: Ignored env SHLVL
> debug3: Ignored env HOME
> debug3: Ignored env LOGNAME
> debug3: Ignored env SSH_CONNECTION
> debug3: Ignored env XDG_RUNTIME_DIR
> debug3: Ignored env _
> debug2: channel 1: request shell confirm 1
> debug2: callback done
> debug2: channel 1: open confirm rwindow 32000 rmax 35000
> debug1: Connection to port 11223 forwarding to socks port 0 requested.
> debug2: fd 8 setting TCP_NODELAY
> debug2: fd 8 setting O_NONBLOCK
> debug3: fd 8 is O_NONBLOCK
> debug1: channel 2: new [dynamic-tcpip]
> debug2: channel 2: pre_dynamic: have 0
> debug2: channel 2: pre_dynamic: have 4
> debug2: channel 2: decode socks5
> debug2: channel 2: socks5 auth done
> debug2: channel 2: pre_dynamic: need more
> debug2: channel 2: pre_dynamic: have 0
> debug2: channel 2: pre_dynamic: have 10
> debug2: channel 2: decode socks5
> debug2: channel 2: socks5 post auth
> debug2: channel 2: dynamic request: socks5 host 212.85.33.47 port 80
> command 1
> debug1: Connection to port 11223 forwarding to socks port 0 requested.
> debug2: fd 9 setting TCP_NODELAY
> debug2: fd 9 setting O_NONBLOCK
> debug3: fd 9 is O_NONBLOCK
> debug1: channel 3: new [dynamic-tcpip]
> debug2: channel 3: pre_dynamic: have 0
> debug2: channel 3: pre_dynamic: have 4
> debug2: channel 3: decode socks5
> debug2: channel 3: socks5 auth done
> debug2: channel 3: pre_dynamic: need more
> debug2: channel 3: pre_dynamic: have 0
> debug2: channel 3: pre_dynamic: have 10
> debug2: channel 3: decode socks5
> debug2: channel 3: socks5 post auth
> debug2: channel 3: dynamic request: socks5 host 104.254.150.79 port 443
> command 1



As you can see the first channel is created for the shell and the channel 2
and 3 are two socks connections. I want to be able to properly control
those connections.

Here is the code I have:

int SSHServer::sessionHandler(ssh_session session) {
ssh_message message;
ssh_channel chan = 0;
int shell = 0;
int auth = 0;

if (ssh_handle_key_exchange(session)) {
debug("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
return 1;
}

/* proceed to authentication */
auth = SSHServer::authenticate(session);
if (!auth) {
debug("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session);
return 1;
}
while (1) {
chan = 0;
/* wait for a channel session */
do {
message = ssh_message_get(session);
if (message) {
if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
chan = ssh_message_channel_request_open_reply_accept(message);
ssh_message_free(message);
break;
}
else {
ssh_message_reply_default(message);
ssh_message_free(message);
}
}
else {
//break;
}
} while (!chan);

if (!chan) {
debug("Error: client did not ask for a channel session (%s)\n",
ssh_get_error(session));
ssh_finalize();
return 1;
}


/* wait for a shell */
do {
message = ssh_message_get(session);
if (message != NULL) {
if (ssh_message_type(message) == SSH_REQUEST_CHANNEL) {
if (ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
//shell = 1;
ssh_message_channel_request_reply_success(message);
ssh_message_free(message);
std::thread(SSHServer::main_loop, chan).detach();
break;
}
else if (ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_PTY) {
ssh_message_channel_request_reply_success(message);
ssh_message_free(message);
continue;
}
}
ssh_message_reply_default(message);
ssh_message_free(message);
}
else {
break;
}
} while (!shell);

if (!shell) {
/*debug("Error: No shell requested (%s)\n", ssh_get_error(session));
return 1;*/
}
//Sleep(999999);
debug("Connected \n");
}
Sleep(999999);
}


int SSHServer::run(int port) {

   int verbosity = SSH_LOG_FUNCTIONS;

    /* Create and configure the ssh session. */
    ssh_bind sshbind = ssh_bind_new();
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, ip);
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port);
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY,
&verbosity);



    /* Listen on 'port' for connections. */
    if (ssh_bind_listen(sshbind) < 0) {
        debug("Error listening to socket: %s\n", ssh_get_error(sshbind));
        return -1;
    }
    if (true) { debug("Listening on port %d.\n", port); }

    /* Loop forever, waiting for and handling connection attempts. */
    while (1) {
        ssh_session session = ssh_new();

        if (ssh_bind_accept(sshbind, session) == SSH_ERROR) {
            debug("Error accepting a connection: %s'.\n",
ssh_get_error(sshbind));
            return -1;
        }
        if (true) { debug("Accepted a connection.\n"); }

        std::thread(SSHServer::sessionHandler, session).detach();
    }
}


I thought that calling  message = ssh_message_get(session);  should get me
new messages that can be used to  do chan =
ssh_message_channel_request_open_reply_accept(message); and getting the new
channel but it is not working.

Can you help me out?

Thanks

-- 
Alberto García Illera

GPG Public Key <https://goo.gl/yshdwh>

Archive administrator: postmaster@lists.cynapses.org