从SSH服务器发送通道请求,使SSH客户端上的`ssh_channel_accept_forward()`返回?

时间:2017-08-04 09:22:49

标签: c linux networking network-programming libssh

我使用客户端代码从官方教程http://api.libssh.org/master/libssh_tutor_forwarding.html

进行直接和反向端口转发

在Ubuntu 16.10上将客户端连接到OpenSSH服务器时,此代码非常有效,即实现了直接和反向端口转发。

但是,请考虑反向端口转发的客户端代码(web_server()),它使用以下调用:

ssh_channel_listen_forward()

ssh_channel_accept_forward()

使用我自己的libssh服务器,问题是客户端在调用ssh_channel_accept_forward()时超时,并显示以下错误消息:

"No channel request of this type from server"

也就是说,等待1分钟后,以下客户端代码会打印错误消息:

  channel = ssh_channel_accept_forward(session, 60000, &port);
  if (channel == NULL)
  {
    fprintf(stderr, "Error waiting for incoming connection: %s\n",
            ssh_get_error(session));
    return SSH_ERROR;
  }

如何在服务器端构建频道请求,以便客户端不会在ssh_channel_forward_accept()中超时并创建新的前向频道?我没有运气就尝试了大部分API函数......

是否有用于发送此类频道请求的特定API函数?如果没有,我如何完成请求频道的任务?

我在服务器端的代码沿着以下行,其中ssh_channel_listen_forward()请求被以下回调函数捕获:

void global_request(ssh_session session, ssh_message message, void *userdata) {
    #ifdef DEBUG
    printf("[Debug] global_request()\n");
    #endif
    struct session_data_struct *session_data = (struct session_data_struct*) userdata;
    ssh_message_global_request_reply_success(message, 8080);
    const char *addr = ssh_message_global_request_address(message);
    int port = ssh_message_global_request_port(message);
    printf("Received global request: %s:%d\n", addr, port);
    session_data->channel = ssh_channel_new(session);
    ssh_channel ch = ssh_message_channel_request_channel(message);
    if (ssh_channel_is_open(session_data->channel)) {
        printf("Channel is open!\n");
    }
}

但是,如上所述,服务器并未让客户端在ssh_channel_accept_forward()的调用中接受新的转发频道。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

Your server code don't send request to open reverse tunnel to client side. This channel: session_data->channel created not bound at server side. You can try to connect it, but in this case you should set subtype "forwarded-tcpip" manually.

This request: ssh_message_channel_request_channel(message); returns NULL because port forwarding request has no channel field.

For initiation of reverse tunnel, that you can accept with ssh_channel_accept_forward() - you should connect to the bound listening port at the server side. (port number from ssh_channel_listen_forward() you know).

P.S. And don't use server callbacks to accept this request. Libssh still filter this message subtype from callback processing.

P.P.S. Read RFC (https://tools.ietf.org/html/rfc4254#page-7) and library source. It's completely readable and not that big