summaryrefslogtreecommitdiffstats
path: root/libssh/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/src/server.c')
-rw-r--r--libssh/src/server.c306
1 files changed, 123 insertions, 183 deletions
diff --git a/libssh/src/server.c b/libssh/src/server.c
index 8629c8ba..3a38fc7b 100644
--- a/libssh/src/server.c
+++ b/libssh/src/server.c
@@ -3,7 +3,7 @@
*
* This file is part of the SSH Library
*
- * Copyright (c) 2004-2005 by Aris Adamantiadis
+ * Copyright (c) 2004-2013 by Aris Adamantiadis
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -174,6 +174,15 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
SSH_LOG(SSH_LOG_RARE,"Invalid state for SSH_MSG_KEXDH_INIT");
goto error;
}
+
+ /* If first_kex_packet_follows guess was wrong, ignore this message. */
+ if (session->first_kex_follows_guess_wrong != 0) {
+ SSH_LOG(SSH_LOG_RARE, "first_kex_packet_follows guess was wrong, "
+ "ignoring first SSH_MSG_KEXDH_INIT message");
+ session->first_kex_follows_guess_wrong = 0;
+ goto error;
+ }
+
switch(session->next_crypto->kex_type){
case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1:
@@ -217,6 +226,7 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){
*privkey = session->srv.ecdsa_key;
break;
case SSH_KEYTYPE_UNKNOWN:
+ default:
*privkey = NULL;
}
@@ -241,9 +251,9 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){
static int dh_handshake_server(ssh_session session) {
ssh_key privkey;
- //ssh_string pubkey_blob = NULL;
ssh_string sig_blob;
ssh_string f;
+ int rc;
if (dh_generate_y(session) < 0) {
ssh_set_error(session, SSH_FATAL, "Could not create y number");
@@ -284,25 +294,26 @@ static int dh_handshake_server(ssh_session session) {
return -1;
}
- if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 ||
- buffer_add_ssh_string(session->out_buffer,
- session->next_crypto->server_pubkey) < 0 ||
- buffer_add_ssh_string(session->out_buffer, f) < 0 ||
- buffer_add_ssh_string(session->out_buffer, sig_blob) < 0) {
- ssh_set_error(session, SSH_FATAL, "Not enough space");
- buffer_reinit(session->out_buffer);
- ssh_string_free(f);
- ssh_string_free(sig_blob);
- return -1;
- }
+ rc = ssh_buffer_pack(session->out_buffer,
+ "bSSS",
+ SSH2_MSG_KEXDH_REPLY,
+ session->next_crypto->server_pubkey,
+ f,
+ sig_blob);
ssh_string_free(f);
ssh_string_free(sig_blob);
+ if(rc != SSH_OK){
+ ssh_set_error_oom(session);
+ ssh_buffer_reinit(session->out_buffer);
+ return -1;
+ }
+
if (packet_send(session) == SSH_ERROR) {
return -1;
}
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
- buffer_reinit(session->out_buffer);
+ ssh_buffer_reinit(session->out_buffer);
return -1;
}
@@ -581,12 +592,8 @@ int ssh_handle_key_exchange(ssh_session session) {
*/
int ssh_auth_reply_default(ssh_session session,int partial) {
char methods_c[128] = {0};
- ssh_string methods = NULL;
int rc = SSH_ERROR;
- if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_FAILURE) < 0) {
- return rc;
- }
if (session->auth_methods == 0) {
session->auth_methods = SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD;
@@ -622,63 +629,43 @@ int ssh_auth_reply_default(ssh_session session,int partial) {
SSH_LOG(SSH_LOG_PACKET,
"Sending a auth failure. methods that can continue: %s", methods_c);
- methods = ssh_string_from_char(methods_c);
- if (methods == NULL) {
- goto error;
- }
-
- if (buffer_add_ssh_string(session->out_buffer, methods) < 0) {
- goto error;
- }
-
- if (partial) {
- if (buffer_add_u8(session->out_buffer, 1) < 0) {
- goto error;
- }
- } else {
- if (buffer_add_u8(session->out_buffer, 0) < 0) {
- goto error;
- }
+ rc = ssh_buffer_pack(session->out_buffer,
+ "bsb",
+ SSH2_MSG_USERAUTH_FAILURE,
+ methods_c,
+ partial ? 1 : 0);
+ if (rc != SSH_OK){
+ ssh_set_error_oom(session);
+ return SSH_ERROR;
}
-
rc = packet_send(session);
-error:
- ssh_string_free(methods);
-
return rc;
}
static int ssh_message_channel_request_open_reply_default(ssh_message msg) {
- SSH_LOG(SSH_LOG_FUNCTIONS, "Refusing a channel");
+ int rc;
- if (buffer_add_u8(msg->session->out_buffer
- , SSH2_MSG_CHANNEL_OPEN_FAILURE) < 0) {
- goto error;
- }
- if (buffer_add_u32(msg->session->out_buffer,
- htonl(msg->channel_request_open.sender)) < 0) {
- goto error;
- }
- if (buffer_add_u32(msg->session->out_buffer,
- htonl(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) < 0) {
- goto error;
- }
- /* reason is an empty string */
- if (buffer_add_u32(msg->session->out_buffer, 0) < 0) {
- goto error;
- }
- /* language too */
- if (buffer_add_u32(msg->session->out_buffer, 0) < 0) {
- goto error;
- }
+ SSH_LOG(SSH_LOG_FUNCTIONS, "Refusing a channel");
- return packet_send(msg->session);
-error:
- return SSH_ERROR;
+ rc = ssh_buffer_pack(msg->session->out_buffer,
+ "bdddd",
+ SSH2_MSG_CHANNEL_OPEN_FAILURE,
+ msg->channel_request_open.sender,
+ SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
+ 0, /* reason is empty string */
+ 0); /* language string */
+ if (rc != SSH_OK){
+ ssh_set_error_oom(msg->session);
+ return SSH_ERROR;
+ }
+
+ rc = packet_send(msg->session);
+ return rc;
}
static int ssh_message_channel_request_reply_default(ssh_message msg) {
uint32_t channel;
+ int rc;
if (msg->channel_request.want_reply) {
channel = msg->channel_request.channel->remote_channel;
@@ -686,13 +673,14 @@ static int ssh_message_channel_request_reply_default(ssh_message msg) {
SSH_LOG(SSH_LOG_PACKET,
"Sending a default channel_request denied to channel %d", channel);
- if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_CHANNEL_FAILURE) < 0) {
- return SSH_ERROR;
- }
- if (buffer_add_u32(msg->session->out_buffer, htonl(channel)) < 0) {
- return SSH_ERROR;
+ rc = ssh_buffer_pack(msg->session->out_buffer,
+ "bd",
+ SSH2_MSG_CHANNEL_FAILURE,
+ channel);
+ if (rc != SSH_OK){
+ ssh_set_error_oom(msg->session);
+ return SSH_ERROR;
}
-
return packet_send(msg->session);
}
@@ -708,33 +696,32 @@ static int ssh_message_service_request_reply_default(ssh_message msg) {
}
int ssh_message_service_reply_success(ssh_message msg) {
- struct ssh_string_struct *service;
- ssh_session session;
-
- if (msg == NULL) {
- return SSH_ERROR;
- }
- session = msg->session;
+ ssh_session session;
+ int rc;
- SSH_LOG(SSH_LOG_PACKET,
- "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service);
- if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_ACCEPT) < 0) {
- return -1;
- }
- service=ssh_string_from_char(msg->service_request.service);
- if (service == NULL) {
- return -1;
- }
+ if (msg == NULL) {
+ return SSH_ERROR;
+ }
+ session = msg->session;
- if (buffer_add_ssh_string(session->out_buffer, service) < 0) {
- ssh_string_free(service);
- return -1;
- }
- ssh_string_free(service);
- return packet_send(msg->session);
+ SSH_LOG(SSH_LOG_PACKET,
+ "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service);
+
+ rc = ssh_buffer_pack(session->out_buffer,
+ "bs",
+ SSH2_MSG_SERVICE_ACCEPT,
+ msg->service_request.service);
+ if (rc != SSH_OK){
+ ssh_set_error_oom(session);
+ return SSH_ERROR;
+ }
+ rc = packet_send(msg->session);
+ return rc;
}
int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_port) {
+ int rc;
+
SSH_LOG(SSH_LOG_FUNCTIONS, "Accepting a global request");
if (msg->global_request.want_reply) {
@@ -745,7 +732,9 @@ int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_por
if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD
&& msg->global_request.bind_port == 0) {
- if (buffer_add_u32(msg->session->out_buffer, htonl(bound_port)) < 0) {
+ rc = ssh_buffer_pack(msg->session->out_buffer, "d", bound_port);
+ if (rc != SSH_ERROR) {
+ ssh_set_error_oom(msg->session);
goto error;
}
}
@@ -876,9 +865,8 @@ int ssh_message_auth_set_methods(ssh_message msg, int methods) {
int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
const char *instruction, unsigned int num_prompts,
const char **prompts, char *echo) {
- int r;
+ int rc;
unsigned int i = 0;
- ssh_string tmp = NULL;
if(name == NULL || instruction == NULL) {
return SSH_ERROR;
@@ -887,71 +875,30 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
return SSH_ERROR;
}
- if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_USERAUTH_INFO_REQUEST) < 0) {
- return SSH_ERROR;
- }
-
- /* name */
- tmp = ssh_string_from_char(name);
- if (tmp == NULL) {
- return SSH_ERROR;
- }
-
- r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
- ssh_string_free(tmp);
- if (r < 0) {
- return SSH_ERROR;
- }
-
- /* instruction */
- tmp = ssh_string_from_char(instruction);
- if (tmp == NULL) {
- return SSH_ERROR;
- }
-
- r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
- ssh_string_free(tmp);
- if (r < 0) {
- return SSH_ERROR;
- }
-
- /* language tag */
- tmp = ssh_string_from_char("");
- if (tmp == NULL) {
- return SSH_ERROR;
- }
-
- r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
- ssh_string_free(tmp);
- if (r < 0) {
- return SSH_ERROR;
- }
-
- /* num prompts */
- if (buffer_add_u32(msg->session->out_buffer, ntohl(num_prompts)) < 0) {
+ rc = ssh_buffer_pack(msg->session->out_buffer,
+ "bsssd",
+ SSH2_MSG_USERAUTH_INFO_REQUEST,
+ name,
+ instruction,
+ "", /* language tag */
+ num_prompts);
+ if (rc != SSH_OK){
+ ssh_set_error_oom(msg->session);
return SSH_ERROR;
}
for(i = 0; i < num_prompts; i++) {
- /* prompt[i] */
- tmp = ssh_string_from_char(prompts[i]);
- if (tmp == NULL) {
- return SSH_ERROR;
- }
-
- r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
- ssh_string_free(tmp);
- if (r < 0) {
- return SSH_ERROR;
- }
-
- /* echo[i] */
- if (buffer_add_u8(msg->session->out_buffer, echo[i]) < 0) {
+ rc = ssh_buffer_pack(msg->session->out_buffer,
+ "sb",
+ prompts[i],
+ echo[1] ? 1 : 0);
+ if (rc != SSH_OK){
+ ssh_set_error_oom(msg->session);
return SSH_ERROR;
}
}
- r = packet_send(msg->session);
+ rc = packet_send(msg->session);
/* fill in the kbdint structure */
if (msg->session->kbdint == NULL) {
@@ -994,7 +941,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
msg->session->kbdint = NULL;
return SSH_ERROR;
}
- msg->session->kbdint->echo = malloc(num_prompts * sizeof(char));
+ msg->session->kbdint->echo = malloc(num_prompts * sizeof(unsigned char));
if (msg->session->kbdint->echo == NULL) {
ssh_set_error_oom(msg->session);
ssh_kbdint_free(msg->session->kbdint);
@@ -1017,7 +964,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
msg->session->kbdint->echo = NULL;
}
- return r;
+ return rc;
}
int ssh_auth_reply_success(ssh_session session, int partial) {
@@ -1058,17 +1005,23 @@ int ssh_message_auth_reply_success(ssh_message msg, int partial) {
/* Answer OK to a pubkey auth request */
int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey) {
- if (msg == NULL) {
- return SSH_ERROR;
- }
+ int rc;
+ if (msg == NULL) {
+ return SSH_ERROR;
+ }
- if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_USERAUTH_PK_OK) < 0 ||
- buffer_add_ssh_string(msg->session->out_buffer, algo) < 0 ||
- buffer_add_ssh_string(msg->session->out_buffer, pubkey) < 0) {
- return SSH_ERROR;
- }
+ rc = ssh_buffer_pack(msg->session->out_buffer,
+ "bSS",
+ SSH2_MSG_USERAUTH_PK_OK,
+ algo,
+ pubkey);
+ if(rc != SSH_OK){
+ ssh_set_error_oom(msg->session);
+ return SSH_ERROR;
+ }
- return packet_send(msg->session);
+ rc = packet_send(msg->session);
+ return rc;
}
int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) {
@@ -1223,27 +1176,14 @@ int ssh_execute_message_callbacks(ssh_session session){
int ssh_send_keepalive(ssh_session session)
{
- struct ssh_string_struct *req;
int rc;
- rc = buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST);
- if (rc < 0) {
- goto err;
- }
-
- req = ssh_string_from_char("keepalive@openssh.com");
- if (req == NULL) {
- goto err;
- }
-
- rc = buffer_add_ssh_string(session->out_buffer, req);
- ssh_string_free(req);
- if (rc < 0) {
- goto err;
- }
-
- rc = buffer_add_u8(session->out_buffer, 1);
- if (rc < 0) {
+ rc = ssh_buffer_pack(session->out_buffer,
+ "bsb",
+ SSH2_MSG_GLOBAL_REQUEST,
+ "keepalive@openssh.com",
+ 1);
+ if (rc != SSH_OK) {
goto err;
}
@@ -1251,14 +1191,14 @@ int ssh_send_keepalive(ssh_session session)
goto err;
}
- ssh_handle_packets(session, 0);
+ ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
return SSH_OK;
err:
ssh_set_error_oom(session);
- buffer_reinit(session->out_buffer);
+ ssh_buffer_reinit(session->out_buffer);
return SSH_ERROR;
}