diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 3a7cbf1b..4b606b70 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -191,7 +191,8 @@ enum ssh_global_requests_e { SSH_GLOBAL_REQUEST_UNKNOWN=0, SSH_GLOBAL_REQUEST_TCPIP_FORWARD, SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD, - SSH_GLOBAL_REQUEST_KEEPALIVE + SSH_GLOBAL_REQUEST_KEEPALIVE, + SSH_GLOBAL_REQUEST_NO_MORE_SESSIONS }; enum ssh_publickey_state_e { diff --git a/include/libssh/session.h b/include/libssh/session.h index 329b5ebd..2882e88a 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -71,10 +71,13 @@ enum ssh_pending_call_e { }; /* libssh calls may block an undefined amount of time */ -#define SSH_SESSION_FLAG_BLOCKING 1 +#define SSH_SESSION_FLAG_BLOCKING 0x0001 /* Client successfully authenticated */ -#define SSH_SESSION_FLAG_AUTHENTICATED 2 +#define SSH_SESSION_FLAG_AUTHENTICATED 0x0002 + +/* Do not accept new session channels (no-more-sessions@openssh.com) */ +#define SSH_SESSION_FLAG_NO_MORE_SESSIONS 0x0004 /* codes to use with ssh_handle_packets*() */ /* Infinite timeout */ diff --git a/src/messages.c b/src/messages.c index 6ec4c75a..be9462ac 100644 --- a/src/messages.c +++ b/src/messages.c @@ -1177,7 +1177,15 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){ goto error; } - if (strcmp(type_c,"session") == 0) { + if (strcmp(type_c, "session") == 0) { + if (session->flags & SSH_SESSION_FLAG_NO_MORE_SESSIONS) { + ssh_session_set_disconnect_message(session, "No more sessions allowed!"); + ssh_set_error(session, SSH_FATAL, "No more sessions allowed!"); + session->session_state = SSH_SESSION_STATE_ERROR; + ssh_disconnect(session); + goto error; + } + msg->channel_request_open.type = SSH_CHANNEL_SESSION; SAFE_FREE(type_c); goto end; @@ -1190,9 +1198,9 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){ &destination_port, &msg->channel_request_open.originator, &originator_port); - if (rc != SSH_OK) { - goto error; - } + if (rc != SSH_OK) { + goto error; + } msg->channel_request_open.destination_port = (uint16_t) destination_port; msg->channel_request_open.originator_port = (uint16_t) originator_port; @@ -1593,6 +1601,15 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ } else { ssh_message_global_request_reply_success(msg, 0); } + } else if (strcmp(request, "no-more-sessions@openssh.com") == 0) { + msg->global_request.type = SSH_GLOBAL_REQUEST_NO_MORE_SESSIONS; + msg->global_request.want_reply = want_reply; + + SSH_LOG(SSH_LOG_PROTOCOL, "Received no-more-sessions@openssh.com %d", want_reply); + + ssh_message_global_request_reply_success(msg, 0); + + session->flags |= SSH_SESSION_FLAG_NO_MORE_SESSIONS; } else { SSH_LOG(SSH_LOG_DEBUG, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s, " "want_reply = %d", request, want_reply);