1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-08 19:02:06 +03:00

TODO server: Fixed server support.

This commit is contained in:
Andreas Schneider
2010-12-18 14:02:53 +01:00
parent f5d0f232c8
commit 48e4df4ac0
3 changed files with 208 additions and 195 deletions

View File

@@ -232,6 +232,12 @@ char *string_to_char(ssh_string str){
return ssh_string_to_char(str); return ssh_string_to_char(str);
} }
/****************************************************************************
* SERVER SUPPORT
****************************************************************************/
#ifdef WITH_SERVER
int ssh_accept(ssh_session session) { int ssh_accept(ssh_session session) {
return ssh_handle_key_exchange(session); return ssh_handle_key_exchange(session);
} }
#endif /* WITH_SERVER */

View File

@@ -67,83 +67,142 @@ static ssh_message ssh_message_new(ssh_session session){
return msg; return msg;
} }
SSH_PACKET_CALLBACK(ssh_packet_global_request){ /**
ssh_message msg = NULL; * @internal
ssh_string request_s=NULL; *
char *request=NULL; * @brief Add a message to the current queue of messages to be parsed.
ssh_string bind_addr_s=NULL; *
char *bind_addr=NULL; * @param[in] session The SSH session to add the message.
uint32_t bind_port; *
uint8_t want_reply; * @param[in] message The message to add to the queue.
(void)user; */
(void)type; void ssh_message_queue(ssh_session session, ssh_message message){
(void)packet; if(message){
if(session->ssh_message_list == NULL){
request_s = buffer_get_ssh_string(packet); session->ssh_message_list=ssh_list_new();
if (request_s != NULL) {
request = ssh_string_to_char(request_s);
ssh_string_free(request_s);
} }
ssh_list_append(session->ssh_message_list, message);
}
}
buffer_get_u8(packet, &want_reply); /**
* @internal
*
* @brief Pop a message from the message list and dequeue it.
*
* @param[in] session The SSH session to pop the message.
*
* @returns The head message or NULL if it doesn't exist.
*/
ssh_message ssh_message_pop_head(ssh_session session){
ssh_message msg=NULL;
struct ssh_iterator *i;
if(session->ssh_message_list == NULL)
return NULL;
i=ssh_list_get_iterator(session->ssh_message_list);
if(i != NULL){
msg=ssh_iterator_value(ssh_message,i);
ssh_list_remove(session->ssh_message_list,i);
}
return msg;
}
ssh_log(session,SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet"); /**
* @brief Retrieve a SSH message from a SSH session.
*
* @param[in] session The SSH session to get the message.
*
* @returns The SSH message received, NULL in case of error.
*
* @warning This function blocks until a message has been received. Betterset up
* a callback if this behavior is unwanted.
*/
ssh_message ssh_message_get(ssh_session session) {
ssh_message msg = NULL;
enter_function();
msg = ssh_message_new(session); msg=ssh_message_pop_head(session);
msg->type = SSH_REQUEST_GLOBAL; if(msg) {
leave_function();
if(!strcmp(request, "tcpip-forward")) { return msg;
bind_addr_s = buffer_get_ssh_string(packet); }
if (bind_addr_s != NULL) { if(session->ssh_message_list == NULL) {
bind_addr = ssh_string_to_char(bind_addr_s); session->ssh_message_list = ssh_list_new();
ssh_string_free(bind_addr_s); }
} do {
if (ssh_handle_packets(session,-1) == SSH_ERROR) {
buffer_get_u32(packet, &bind_port); leave_function();
bind_port = ntohl(bind_port); return NULL;
msg->global_request.type = SSH_GLOBAL_REQUEST_TCPIP_FORWARD;
msg->global_request.want_reply = want_reply;
msg->global_request.bind_address = bind_addr;
msg->global_request.bind_port = bind_port;
ssh_log(session, SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
if(ssh_callbacks_exists(session->callbacks, global_request_function)) {
ssh_log(session, SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
session->callbacks->global_request_function(session, msg, session->callbacks->userdata);
} else {
ssh_message_reply_default(msg);
}
} else if(!strcmp(request, "cancel-tcpip-forward")) {
bind_addr_s = buffer_get_ssh_string(packet);
if (bind_addr_s != NULL) {
bind_addr = ssh_string_to_char(bind_addr_s);
ssh_string_free(bind_addr_s);
}
buffer_get_u32(packet, &bind_port);
bind_port = ntohl(bind_port);
msg->global_request.type = SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD;
msg->global_request.want_reply = want_reply;
msg->global_request.bind_address = bind_addr;
msg->global_request.bind_port = bind_port;
ssh_log(session, SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
if(ssh_callbacks_exists(session->callbacks, global_request_function)) {
session->callbacks->global_request_function(session, msg, session->callbacks->userdata);
} else {
ssh_message_reply_default(msg);
}
} else {
ssh_log(session, SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s %d", request, want_reply);
} }
msg=ssh_list_pop_head(ssh_message, session->ssh_message_list);
} while(msg==NULL);
leave_function();
return msg;
}
SAFE_FREE(msg); int ssh_message_type(ssh_message msg) {
SAFE_FREE(request); if (msg == NULL) {
SAFE_FREE(bind_addr); return -1;
return SSH_PACKET_USED; }
return msg->type;
}
int ssh_message_subtype(ssh_message msg) {
if (msg == NULL) {
return -1;
}
switch(msg->type) {
case SSH_REQUEST_AUTH:
return msg->auth_request.method;
case SSH_REQUEST_CHANNEL_OPEN:
return msg->channel_request_open.type;
case SSH_REQUEST_CHANNEL:
return msg->channel_request.type;
case SSH_REQUEST_GLOBAL:
return msg->global_request.type;
}
return -1;
}
void ssh_message_free(ssh_message msg){
if (msg == NULL) {
return;
}
switch(msg->type) {
case SSH_REQUEST_AUTH:
SAFE_FREE(msg->auth_request.username);
if (msg->auth_request.password) {
memset(msg->auth_request.password, 0,
strlen(msg->auth_request.password));
SAFE_FREE(msg->auth_request.password);
}
publickey_free(msg->auth_request.public_key);
break;
case SSH_REQUEST_CHANNEL_OPEN:
SAFE_FREE(msg->channel_request_open.originator);
SAFE_FREE(msg->channel_request_open.destination);
break;
case SSH_REQUEST_CHANNEL:
SAFE_FREE(msg->channel_request.TERM);
SAFE_FREE(msg->channel_request.modes);
SAFE_FREE(msg->channel_request.var_name);
SAFE_FREE(msg->channel_request.var_value);
SAFE_FREE(msg->channel_request.command);
SAFE_FREE(msg->channel_request.subsystem);
break;
case SSH_REQUEST_SERVICE:
SAFE_FREE(msg->service_request.service);
break;
case SSH_REQUEST_GLOBAL:
SAFE_FREE(msg->global_request.bind_address);
break;
}
ZERO_STRUCTP(msg);
SAFE_FREE(msg);
} }
SSH_PACKET_CALLBACK(ssh_packet_service_request){ SSH_PACKET_CALLBACK(ssh_packet_service_request){
@@ -792,143 +851,87 @@ int ssh_message_channel_request_reply_success(ssh_message msg) {
return SSH_OK; return SSH_OK;
} }
/** #ifdef WITH_SERVER
* @brief Retrieve a SSH message from a SSH session. SSH_PACKET_CALLBACK(ssh_packet_global_request){
* ssh_message msg = NULL;
* @param[in] session The SSH session to get the message. ssh_string request_s=NULL;
* char *request=NULL;
* @returns The SSH message received, NULL in case of error. ssh_string bind_addr_s=NULL;
* char *bind_addr=NULL;
* @warning This function blocks until a message has been received. Betterset up uint32_t bind_port;
* a callback if this behavior is unwanted. uint8_t want_reply;
*/ (void)user;
ssh_message ssh_message_get(ssh_session session) { (void)type;
ssh_message msg = NULL; (void)packet;
enter_function();
msg=ssh_message_pop_head(session); request_s = buffer_get_ssh_string(packet);
if(msg) { if (request_s != NULL) {
leave_function(); request = ssh_string_to_char(request_s);
return msg; ssh_string_free(request_s);
}
if(session->ssh_message_list == NULL) {
session->ssh_message_list = ssh_list_new();
}
do {
if (ssh_handle_packets(session,-1) == SSH_ERROR) {
leave_function();
return NULL;
} }
msg=ssh_list_pop_head(ssh_message, session->ssh_message_list);
} while(msg==NULL);
leave_function();
return msg;
}
int ssh_message_type(ssh_message msg) { buffer_get_u8(packet, &want_reply);
if (msg == NULL) {
return -1;
}
return msg->type; ssh_log(session,SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet");
}
int ssh_message_subtype(ssh_message msg) { msg = ssh_message_new(session);
if (msg == NULL) { msg->type = SSH_REQUEST_GLOBAL;
return -1;
}
switch(msg->type) { if(!strcmp(request, "tcpip-forward")) {
case SSH_REQUEST_AUTH: bind_addr_s = buffer_get_ssh_string(packet);
return msg->auth_request.method; if (bind_addr_s != NULL) {
case SSH_REQUEST_CHANNEL_OPEN: bind_addr = ssh_string_to_char(bind_addr_s);
return msg->channel_request_open.type; ssh_string_free(bind_addr_s);
case SSH_REQUEST_CHANNEL: }
return msg->channel_request.type;
case SSH_REQUEST_GLOBAL:
return msg->global_request.type;
}
return -1; buffer_get_u32(packet, &bind_port);
} bind_port = ntohl(bind_port);
void ssh_message_free(ssh_message msg){ msg->global_request.type = SSH_GLOBAL_REQUEST_TCPIP_FORWARD;
if (msg == NULL) { msg->global_request.want_reply = want_reply;
return; msg->global_request.bind_address = bind_addr;
} msg->global_request.bind_port = bind_port;
switch(msg->type) { ssh_log(session, SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
case SSH_REQUEST_AUTH:
SAFE_FREE(msg->auth_request.username);
if (msg->auth_request.password) {
memset(msg->auth_request.password, 0,
strlen(msg->auth_request.password));
SAFE_FREE(msg->auth_request.password);
}
publickey_free(msg->auth_request.public_key);
break;
case SSH_REQUEST_CHANNEL_OPEN:
SAFE_FREE(msg->channel_request_open.originator);
SAFE_FREE(msg->channel_request_open.destination);
break;
case SSH_REQUEST_CHANNEL:
SAFE_FREE(msg->channel_request.TERM);
SAFE_FREE(msg->channel_request.modes);
SAFE_FREE(msg->channel_request.var_name);
SAFE_FREE(msg->channel_request.var_value);
SAFE_FREE(msg->channel_request.command);
SAFE_FREE(msg->channel_request.subsystem);
break;
case SSH_REQUEST_SERVICE:
SAFE_FREE(msg->service_request.service);
break;
case SSH_REQUEST_GLOBAL:
SAFE_FREE(msg->global_request.bind_address);
break;
}
ZERO_STRUCTP(msg);
SAFE_FREE(msg);
}
/** if(ssh_callbacks_exists(session->callbacks, global_request_function)) {
* @internal ssh_log(session, SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
* session->callbacks->global_request_function(session, msg, session->callbacks->userdata);
* @brief Add a message to the current queue of messages to be parsed. } else {
* ssh_message_reply_default(msg);
* @param[in] session The SSH session to add the message. }
* } else if(!strcmp(request, "cancel-tcpip-forward")) {
* @param[in] message The message to add to the queue. bind_addr_s = buffer_get_ssh_string(packet);
*/ if (bind_addr_s != NULL) {
void ssh_message_queue(ssh_session session, ssh_message message){ bind_addr = ssh_string_to_char(bind_addr_s);
if(message){ ssh_string_free(bind_addr_s);
if(session->ssh_message_list == NULL){ }
session->ssh_message_list=ssh_list_new(); buffer_get_u32(packet, &bind_port);
bind_port = ntohl(bind_port);
msg->global_request.type = SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD;
msg->global_request.want_reply = want_reply;
msg->global_request.bind_address = bind_addr;
msg->global_request.bind_port = bind_port;
ssh_log(session, SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
if(ssh_callbacks_exists(session->callbacks, global_request_function)) {
session->callbacks->global_request_function(session, msg, session->callbacks->userdata);
} else {
ssh_message_reply_default(msg);
}
} else {
ssh_log(session, SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s %d", request, want_reply);
} }
ssh_list_append(session->ssh_message_list, message);
} SAFE_FREE(msg);
SAFE_FREE(request);
SAFE_FREE(bind_addr);
return SSH_PACKET_USED;
} }
/** #endif /* WITH_SERVER */
* @internal
*
* @brief Pop a message from the message list and dequeue it.
*
* @param[in] session The SSH session to pop the message.
*
* @returns The head message or NULL if it doesn't exist.
*/
ssh_message ssh_message_pop_head(ssh_session session){
ssh_message msg=NULL;
struct ssh_iterator *i;
if(session->ssh_message_list == NULL)
return NULL;
i=ssh_list_get_iterator(session->ssh_message_list);
if(i != NULL){
msg=ssh_iterator_value(ssh_message,i);
ssh_list_remove(session->ssh_message_list,i);
}
return msg;
}
/** @} */ /** @} */

View File

@@ -85,7 +85,11 @@ ssh_packet_callback default_packet_handlers[]= {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, // 62-79 NULL, NULL, NULL, NULL, // 62-79
#ifdef WITH_SERVER
ssh_packet_global_request, // SSH2_MSG_GLOBAL_REQUEST 80 ssh_packet_global_request, // SSH2_MSG_GLOBAL_REQUEST 80
#else /* WITH_SERVER */
NULL,
#endif /* WITH_SERVER */
ssh_request_success, // SSH2_MSG_REQUEST_SUCCESS 81 ssh_request_success, // SSH2_MSG_REQUEST_SUCCESS 81
ssh_request_denied, // SSH2_MSG_REQUEST_FAILURE 82 ssh_request_denied, // SSH2_MSG_REQUEST_FAILURE 82
NULL, NULL, NULL, NULL, NULL, NULL, NULL,// 83-89 NULL, NULL, NULL, NULL, NULL, NULL, NULL,// 83-89