Update libssh

This commit is contained in:
Nicolas Viennot 2013-07-11 03:46:02 -04:00
parent 7be65e79db
commit 2e3661a0f6
28 changed files with 347 additions and 132 deletions

View File

@ -174,12 +174,16 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
char buffer[16384];
int total=0;
int mode;
char *filename;
char *filename = NULL;
/* recursive mode doesn't work yet */
(void)recursive;
/* Get the file name and size*/
if(!src->is_ssh){
fd=fileno(src->file);
fd = fileno(src->file);
if (fd < 0) {
fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno));
return -1;
}
fstat(fd,&s);
size=s.st_size;
mode = s.st_mode & ~S_IFMT;
@ -201,6 +205,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
}
if(r==SSH_ERROR){
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
} while(r != SSH_SCP_REQUEST_NEWFILE);
@ -211,6 +216,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
if(r==SSH_ERROR){
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
ssh_string_free_char(filename);
ssh_scp_free(dest->scp);
return -1;
}
@ -221,6 +227,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
if(src->is_ssh)
ssh_scp_deny_request(src->scp,"Cannot open local file");
ssh_string_free_char(filename);
return -1;
}
}
@ -233,6 +240,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
if(r==SSH_ERROR){
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
if(r==0)
@ -243,6 +251,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
break;
if(r<0){
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
@ -252,18 +261,21 @@ static int do_copy(struct location *src, struct location *dest, int recursive){
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp=NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w=fwrite(buffer,r,1,dest->file);
if(w<=0){
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total+=r;
} while(total < size);
ssh_string_free_char(filename);
printf("wrote %d bytes\n",total);
return 0;
}
@ -286,7 +298,7 @@ int main(int argc, char **argv){
break;
}
}
if(dest->is_ssh){
if (dest->is_ssh && dest->scp != NULL) {
r=ssh_scp_close(dest->scp);
if(r == SSH_ERROR){
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));

View File

@ -60,9 +60,12 @@ struct ssh_callbacks_struct cb = {
static void add_cmd(char *cmd){
int n;
for(n=0;cmds[n] && (n<MAXCMD);n++);
if(n==MAXCMD)
for (n = 0; (n < MAXCMD) && cmds[n] != NULL; n++);
if (n == MAXCMD) {
return;
}
cmds[n]=strdup(cmd);
}

View File

@ -307,10 +307,13 @@ static int main_loop(ssh_channel chan) {
}
if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) {
printf("Couldn't add an fd to the event\n");
ssh_event_free(event);
return -1;
}
if(ssh_event_add_session(event, session) != SSH_OK) {
printf("Couldn't add the session to the event\n");
ssh_event_remove_fd(event, fd);
ssh_event_free(event);
return -1;
}

View File

@ -58,6 +58,8 @@ static int opts(int argc, char **argv){
static void create_files(ssh_session session){
ssh_channel channel=ssh_channel_new(session);
char buffer[1];
int rc;
if(channel == NULL){
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
exit(EXIT_FAILURE);
@ -74,8 +76,16 @@ static void create_files(ssh_session session){
exit(EXIT_FAILURE);
}
while(!ssh_channel_is_eof(channel)){
ssh_channel_read(channel,buffer,1,1);
if (write(1,buffer,1) < 0) {
rc = ssh_channel_read(channel,buffer,1,1);
if (rc != 1) {
fprintf(stderr, "Error reading from channel\n");
ssh_channel_close(channel);
ssh_channel_free(channel);
return;
}
rc = write(1, buffer, 1);
if (rc < 0) {
fprintf(stderr, "Error writing to buffer\n");
ssh_channel_close(channel);
ssh_channel_free(channel);

View File

@ -31,6 +31,7 @@
#include "libssh/crypto.h"
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
#define SSH_KEY_FLAG_EMPTY 0x0
#define SSH_KEY_FLAG_PUBLIC 0x0001

View File

@ -379,6 +379,8 @@ LIBSSH_API int ssh_channel_write_stderr(ssh_channel channel,
const void *data,
uint32_t len);
LIBSSH_API int ssh_send_keepalive(ssh_session session);
/* deprecated functions */
SSH_DEPRECATED LIBSSH_API int ssh_accept(ssh_session session);
SSH_DEPRECATED LIBSSH_API int channel_write_stderr(ssh_channel channel,

View File

@ -55,8 +55,8 @@ int ssh_socket_get_status(ssh_socket s);
int ssh_socket_buffered_write_bytes(ssh_socket s);
int ssh_socket_data_available(ssh_socket s);
int ssh_socket_data_writable(ssh_socket s);
void ssh_socket_set_nonblocking(socket_t fd);
void ssh_socket_set_blocking(socket_t fd);
int ssh_socket_set_nonblocking(socket_t fd);
int ssh_socket_set_blocking(socket_t fd);
void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);

View File

@ -271,6 +271,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
unsigned int type = 0;
unsigned int c1 = 0, c2 = 0;
uint8_t buf[4] = {0};
int rc;
switch (session->version) {
case 1:
@ -287,9 +288,14 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
/* send message to the agent requesting the list of identities */
request = ssh_buffer_new();
if (request == NULL) {
ssh_set_error_oom(request);
return -1;
}
if (buffer_add_u8(request, c1) < 0) {
ssh_set_error(session, SSH_FATAL, "Not enough space");
return -1;
ssh_set_error_oom(request);
ssh_buffer_free(request);
return -1;
}
reply = ssh_buffer_new();
@ -307,16 +313,26 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
ssh_buffer_free(request);
/* get message type and verify the answer */
buffer_get_u8(reply, (uint8_t *) &type);
rc = buffer_get_u8(reply, (uint8_t *) &type);
if (rc != sizeof(uint8_t)) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply size: %d", rc);
ssh_buffer_free(reply);
return -1;
}
SSH_LOG(session, SSH_LOG_WARN,
"Answer type: %d, expected answer: %d",
type, c2);
if (agent_failed(type)) {
return 0;
ssh_buffer_free(reply);
return 0;
} else if (type != c2) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %d", type);
return -1;
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %d", type);
ssh_buffer_free(reply);
return -1;
}
buffer_get_u32(reply, (uint32_t *) buf);

View File

@ -1107,12 +1107,9 @@ int ssh_userauth_publickey_auto(ssh_session session,
state = session->auth_auto_state;
if (state->state == SSH_AUTH_AUTO_STATE_NONE) {
#ifndef _WIN32
/* Try authentication with ssh-agent first */
/* Try authentication with ssh-agent first */
rc = ssh_userauth_agent(session, username);
if (rc == SSH_AUTH_SUCCESS) {
return rc;
}
if (rc == SSH_AUTH_AGAIN)
if (rc == SSH_AUTH_SUCCESS)
return rc;
#endif
state->state = SSH_AUTH_AUTO_STATE_PUBKEY;

View File

@ -288,6 +288,8 @@ SSH_PACKET_CALLBACK(ssh_packet_data1){
SSH_PACKET_CALLBACK(ssh_packet_close1){
ssh_channel channel = ssh_get_channel1(session);
uint32_t status;
int rc;
(void)type;
(void)user;
@ -305,7 +307,10 @@ SSH_PACKET_CALLBACK(ssh_packet_close1){
channel->state = SSH_CHANNEL_STATE_CLOSED;
channel->remote_eof = 1;
buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION);
rc = buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION);
if (rc < 0) {
return SSH_PACKET_NOT_USED;
}
packet_send(session);
return SSH_PACKET_USED;

View File

@ -405,6 +405,7 @@ static void ssh_client_connection_callback(ssh_session session){
if (dh_handshake(session) == SSH_ERROR) {
goto error;
}
/* FALL THROUGH */
case SSH_SESSION_STATE_DH:
if(session->dh_handshake_state==DH_STATE_FINISHED){
set_status(session,1.0f);
@ -617,7 +618,7 @@ void ssh_disconnect(ssh_session session) {
enter_function();
if (ssh_socket_is_open(session->socket)) {
if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
goto error;
}
@ -642,7 +643,7 @@ void ssh_disconnect(ssh_session session) {
}
error:
session->alive = 0;
if(session->socket){
if (session->socket != NULL){
ssh_socket_reset(session->socket);
}
session->opts.fd = SSH_INVALID_SOCKET;

View File

@ -139,6 +139,7 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
int timeout_ms;
ssh_pollfd_t fds;
int rc = 0;
int ret;
socklen_t len = sizeof(rc);
enter_function();
@ -148,7 +149,13 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
*/
timeout_ms=timeout * 1000 + usec / 1000;
ssh_socket_set_nonblocking(s);
rc = ssh_socket_set_nonblocking(s);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket non-blocking for %s:%d", host, port);
ssh_connect_socket_close(s);
return -1;
}
ssh_log(session, SSH_LOG_RARE, "Trying to connect to host: %s:%d with "
"timeout %d ms", host, port, timeout_ms);
@ -181,11 +188,11 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
leave_function();
return -1;
}
rc = 0;
rc = -1;
/* Get connect(2) return code. Zero means no error */
getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len);
if (rc != 0) {
ret = getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len);
if (ret < 0 || rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Connect to %s:%d failed: %s", host, port, strerror(rc));
ssh_connect_socket_close(s);
@ -195,7 +202,14 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
/* s is connected ? */
ssh_log(session, SSH_LOG_PACKET, "Socket connected with timeout\n");
ssh_socket_set_blocking(s);
ret = ssh_socket_set_blocking(s);
if (ret < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket as blocking connecting to %s:%d failed: %s",
host, port, strerror(errno));
ssh_connect_socket_close(s);
return -1;
}
leave_function();
return s;
@ -344,7 +358,7 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
"Failed to resolve bind address %s (%s)",
bind_addr,
gai_strerror(rc));
close(s);
ssh_connect_socket_close(s);
s=-1;
break;
}
@ -367,7 +381,15 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
continue;
}
}
ssh_socket_set_nonblocking(s);
rc = ssh_socket_set_nonblocking(s);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket non-blocking for %s:%d", host, port);
ssh_connect_socket_close(s);
s = -1;
continue;
}
connect(s, itr->ai_addr, itr->ai_addrlen);
break;

View File

@ -765,8 +765,14 @@ int make_sessionid(ssh_session session) {
ssh_log(session,SSH_LOG_WARNING,"ECDH parameted missing");
goto error;
}
buffer_add_ssh_string(buf,session->next_crypto->ecdh_client_pubkey);
buffer_add_ssh_string(buf,session->next_crypto->ecdh_server_pubkey);
rc = buffer_add_ssh_string(buf,session->next_crypto->ecdh_client_pubkey);
if (rc < 0) {
goto error;
}
rc = buffer_add_ssh_string(buf,session->next_crypto->ecdh_server_pubkey);
if (rc < 0) {
goto error;
}
#endif
}
num = make_bignum_string(session->next_crypto->k);

View File

@ -38,37 +38,57 @@
* @brief Starts ecdh-sha2-nistp256 key exchange
*/
int ssh_client_ecdh_init(ssh_session session){
EC_KEY *key=NULL;
EC_KEY *key;
const EC_GROUP *group;
const EC_POINT *pubkey;
ssh_string client_pubkey;
int len;
int rc;
bignum_CTX ctx=BN_CTX_new();
enter_function();
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT) < 0) {
goto error;
bignum_CTX ctx = BN_CTX_new();
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
if (rc < 0) {
BN_CTX_free(ctx);
return SSH_ERROR;
}
key = EC_KEY_new_by_curve_name(NISTP256);
if (key == NULL) {
BN_CTX_free(ctx);
return SSH_ERROR;
}
group = EC_KEY_get0_group(key);
EC_KEY_generate_key(key);
pubkey=EC_KEY_get0_public_key(key);
len = EC_POINT_point2oct(group,pubkey,POINT_CONVERSION_UNCOMPRESSED,
NULL,0,ctx);
client_pubkey=ssh_string_new(len);
client_pubkey = ssh_string_new(len);
if (client_pubkey == NULL) {
BN_CTX_free(ctx);
EC_KEY_free(key);
return SSH_ERROR;
}
EC_POINT_point2oct(group,pubkey,POINT_CONVERSION_UNCOMPRESSED,
ssh_string_data(client_pubkey),len,ctx);
buffer_add_ssh_string(session->out_buffer,client_pubkey);
BN_CTX_free(ctx);
rc = buffer_add_ssh_string(session->out_buffer,client_pubkey);
if (rc < 0) {
EC_KEY_free(key);
ssh_string_free(client_pubkey);
return SSH_ERROR;
}
session->next_crypto->ecdh_privkey = key;
session->next_crypto->ecdh_client_pubkey = client_pubkey;
rc = packet_send(session);
leave_function();
return rc;
error:
leave_function();
return SSH_ERROR;
}
static void ecdh_import_pubkey(ssh_session session, ssh_string pubkey_string) {
@ -180,9 +200,9 @@ error:
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
/* ECDH keys */
ssh_string q_c_string = NULL;
ssh_string q_s_string = NULL;
EC_KEY *ecdh_key=NULL;
ssh_string q_c_string;
ssh_string q_s_string;
EC_KEY *ecdh_key;
const EC_GROUP *group;
const EC_POINT *ecdh_pubkey;
bignum_CTX ctx;
@ -192,14 +212,11 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
int len;
int rc;
enter_function();
/* Extract the client pubkey from the init packet */
q_c_string = buffer_get_ssh_string(packet);
if (q_c_string == NULL) {
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
goto error;
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
return SSH_ERROR;
}
session->next_crypto->ecdh_client_pubkey = q_c_string;
@ -207,45 +224,94 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
ctx = BN_CTX_new();
ecdh_key = EC_KEY_new_by_curve_name(NISTP256);
if (ecdh_key == NULL) {
ssh_set_error_oom(session);
BN_CTX_free(ctx);
return SSH_ERROR;
}
group = EC_KEY_get0_group(ecdh_key);
EC_KEY_generate_key(ecdh_key);
ecdh_pubkey=EC_KEY_get0_public_key(ecdh_key);
len = EC_POINT_point2oct(group,ecdh_pubkey,POINT_CONVERSION_UNCOMPRESSED,
NULL,0,ctx);
q_s_string=ssh_string_new(len);
EC_POINT_point2oct(group,ecdh_pubkey,POINT_CONVERSION_UNCOMPRESSED,
ssh_string_data(q_s_string),len,ctx);
ecdh_pubkey = EC_KEY_get0_public_key(ecdh_key);
len = EC_POINT_point2oct(group,
ecdh_pubkey,
POINT_CONVERSION_UNCOMPRESSED,
NULL,
0,
ctx);
q_s_string = ssh_string_new(len);
if (q_s_string == NULL) {
EC_KEY_free(ecdh_key);
BN_CTX_free(ctx);
return SSH_ERROR;
}
EC_POINT_point2oct(group,
ecdh_pubkey,
POINT_CONVERSION_UNCOMPRESSED,
ssh_string_data(q_s_string),
len,
ctx);
BN_CTX_free(ctx);
session->next_crypto->ecdh_privkey = ecdh_key;
session->next_crypto->ecdh_server_pubkey = q_s_string;
buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY);
/* build k and session_id */
if (ecdh_build_k(session) < 0) {
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
goto error;
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
if (ssh_get_key_params(session, &privkey) == SSH_ERROR)
goto error;
if (make_sessionid(session) != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
goto error;
/* build k and session_id */
rc = ecdh_build_k(session);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
return SSH_ERROR;
}
/* privkey is not allocated */
rc = ssh_get_key_params(session, &privkey);
if (rc == SSH_ERROR) {
return SSH_ERROR;
}
rc = make_sessionid(session);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
return SSH_ERROR;
}
/* add host's public key */
buffer_add_ssh_string(session->out_buffer, session->next_crypto->server_pubkey);
rc = buffer_add_ssh_string(session->out_buffer,
session->next_crypto->server_pubkey);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
/* add ecdh public key */
buffer_add_ssh_string(session->out_buffer,q_s_string);
rc = buffer_add_ssh_string(session->out_buffer, q_s_string);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
/* add signature blob */
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
if (sig_blob == NULL) {
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
goto error;
return SSH_ERROR;
}
buffer_add_ssh_string(session->out_buffer, sig_blob);
rc = buffer_add_ssh_string(session->out_buffer, sig_blob);
ssh_string_free(sig_blob);
if (rc < 0) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
/* Free private keys as they should not be readable after this point */
if (session->srv.rsa_key) {
ssh_key_free(session->srv.rsa_key);
@ -258,19 +324,21 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
ssh_log(session,SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent");
rc = packet_send(session);
if (rc == SSH_ERROR)
goto error;
if (rc == SSH_ERROR) {
return SSH_ERROR;
}
/* Send the MSG_NEWKEYS */
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
goto error;
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
if (rc < 0) {
return SSH_ERROR;;
}
session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
rc=packet_send(session);
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
rc = packet_send(session);
ssh_log(session, SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
return rc;
error:
return SSH_ERROR;
}
#endif /* WITH_SERVER */

View File

@ -460,6 +460,7 @@ int ssh_send_kex(ssh_session session, int server_kex) {
goto error;
}
ssh_string_free(str);
str = NULL;
}
if (buffer_add_u8(session->out_buffer, 0) < 0) {

View File

@ -47,6 +47,9 @@ static ssh_string make_rsa1_string(ssh_string e, ssh_string n){
buffer = ssh_buffer_new();
rsa = ssh_string_from_char("ssh-rsa1");
if (rsa == NULL) {
goto error;
}
if (buffer_add_ssh_string(buffer, rsa) < 0) {
goto error;
@ -375,7 +378,7 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
goto error;
}
hostkey = make_rsa1_string(host_exp,host_mod);
if (serverkey == NULL) {
if (hostkey == NULL) {
goto error;
}
if (build_session_id1(session, server_mod, host_mod) < 0) {

View File

@ -133,7 +133,7 @@ static char **ssh_get_knownhost_line(ssh_session session, FILE **file,
*ptr = '\0';
}
if (!buffer[0] || buffer[0] == '#') {
if (buffer[0] == '\0' || buffer[0] == '#') {
continue; /* skip empty lines */
}

View File

@ -135,7 +135,9 @@ void ssh_message_queue(ssh_session session, ssh_message message){
}
session->ssh_message_list = ssh_list_new();
}
ssh_list_append(session->ssh_message_list, message);
if (session->ssh_message_list != NULL) {
ssh_list_append(session->ssh_message_list, message);
}
}
}
@ -1252,6 +1254,7 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){
msg = ssh_message_new(session);
if (msg == NULL) {
ssh_string_free_char(request);
return SSH_PACKET_NOT_USED;
}
msg->type = SSH_REQUEST_GLOBAL;

View File

@ -187,6 +187,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
/* saves the status of the current operations */
session->in_packet.len = len;
session->packet_state = PACKET_STATE_SIZEREAD;
/* FALL TROUGH */
case PACKET_STATE_SIZEREAD:
len = session->in_packet.len;
to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize;
@ -305,10 +306,12 @@ void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s){
* @brief sets the callbacks for the packet layer
*/
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks){
if(session->packet_callbacks == NULL){
session->packet_callbacks = ssh_list_new();
}
ssh_list_append(session->packet_callbacks, callbacks);
if(session->packet_callbacks == NULL){
session->packet_callbacks = ssh_list_new();
}
if (session->packet_callbacks != NULL) {
ssh_list_append(session->packet_callbacks, callbacks);
}
}
/** @internal
@ -526,6 +529,3 @@ int packet_send(ssh_session session) {
#endif
return packet_send2(session);
}
/* vim: set ts=2 sw=2 et cindent: */

View File

@ -144,6 +144,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
session->in_packet.len = len;
session->packet_state = PACKET_STATE_SIZEREAD;
/* FALL THROUGH */
case PACKET_STATE_SIZEREAD:
len = session->in_packet.len;
/* SSH-1 has a fixed padding lenght */
@ -158,7 +159,6 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
packet = (char *)data + processed;
if (buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
SAFE_FREE(packet);
goto error;
}
processed += to_be_read;

View File

@ -421,8 +421,16 @@ int ssh_pki_import_privkey_file(const char *filename,
return SSH_ERROR;
}
rc = stat(filename, &sb);
file = fopen(filename, "rb");
if (file == NULL) {
ssh_pki_log("Error opening %s: %s",
filename, strerror(errno));
return SSH_EOF;
}
rc = fstat(fileno(file), &sb);
if (rc < 0) {
fclose(file);
ssh_pki_log("Error getting stat of %s: %s",
filename, strerror(errno));
switch (errno) {
@ -434,11 +442,10 @@ int ssh_pki_import_privkey_file(const char *filename,
return SSH_ERROR;
}
file = fopen(filename, "rb");
if (file == NULL) {
ssh_pki_log("Error opening %s: %s",
filename, strerror(errno));
return SSH_EOF;
if (sb.st_size > MAX_PRIVKEY_SIZE) {
ssh_pki_log("Private key is bigger than 4M.");
fclose(file);
return SSH_ERROR;
}
key_buf = malloc(sb.st_size + 1);
@ -804,8 +811,16 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey)
return SSH_ERROR;
}
rc = stat(filename, &sb);
file = fopen(filename, "r");
if (file == NULL) {
ssh_pki_log("Error opening %s: %s",
filename, strerror(errno));
return SSH_EOF;
}
rc = fstat(fileno(file), &sb);
if (rc < 0) {
fclose(file);
ssh_pki_log("Error gettint stat of %s: %s",
filename, strerror(errno));
switch (errno) {
@ -817,16 +832,10 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey)
}
if (sb.st_size > MAX_PUBKEY_SIZE) {
fclose(file);
return SSH_ERROR;
}
file = fopen(filename, "r");
if (file == NULL) {
ssh_pki_log("Error opening %s: %s",
filename, strerror(errno));
return SSH_EOF;
}
key_buf = malloc(sb.st_size + 1);
if (key_buf == NULL) {
fclose(file);

View File

@ -411,8 +411,10 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
switch (parameter) {
case 384:
nid = NID_secp384r1;
break;
case 512:
nid = NID_secp521r1;
break;
case 256:
default:
nid = NID_X9_62_prime256v1;
@ -850,6 +852,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
e = make_ecpoint_string(EC_KEY_get0_group(key->ecdsa),
EC_KEY_get0_public_key(key->ecdsa));
if (e == NULL) {
ssh_buffer_free(buffer);
return NULL;
}

View File

@ -927,7 +927,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
ssh_string_free(tmp);
if (r < 0) {
goto error;
return SSH_ERROR;
}
/* echo[i] */
@ -1003,9 +1003,6 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
}
return r;
error:
if(tmp) ssh_string_free(tmp);
return SSH_ERROR;
}
int ssh_message_auth_reply_success(ssh_message msg, int partial) {
@ -1200,6 +1197,41 @@ int ssh_execute_message_callbacks(ssh_session session){
return SSH_OK;
}
int ssh_send_keepalive(ssh_session session)
{
/* TODO check the reply and all that */
struct ssh_string_struct *req;
int reply = 1;
int rc = SSH_ERROR;
enter_function();
req = ssh_string_from_char("keepalive@openssh.com");
if (req == NULL) {
ssh_set_error_oom(session);
goto out;
}
if (buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST) < 0 ||
buffer_add_ssh_string(session->out_buffer, req) < 0 ||
buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
ssh_set_error_oom(session);
goto out;
}
if (packet_send(session) == SSH_ERROR)
goto out;
ssh_handle_packets(session, 0);
ssh_log(session, SSH_LOG_PACKET, "Sent a keepalive");
rc = SSH_OK;
out:
ssh_string_free(req);
leave_function();
return rc;
}
/** @} */
/* vim: set ts=4 sw=4 et cindent: */

View File

@ -230,7 +230,10 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int r
/* Check if we are in a connecting state */
if(s->state==SSH_SOCKET_CONNECTING){
s->state=SSH_SOCKET_ERROR;
getsockopt(fd,SOL_SOCKET,SO_ERROR,(char *)&err,&errlen);
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
if (r < 0) {
err = errno;
}
s->last_errno=err;
ssh_socket_close(s);
if(s->callbacks && s->callbacks->connected)
@ -305,7 +308,10 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int r
ssh_log(s->session,SSH_LOG_PACKET,"Received POLLOUT in connecting state");
s->state = SSH_SOCKET_CONNECTED;
ssh_poll_set_events(p,POLLOUT | POLLIN);
ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
r = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
if (r < 0) {
return -1;
}
if(s->callbacks && s->callbacks->connected)
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata);
return 0;
@ -711,23 +717,23 @@ int ssh_socket_get_status(ssh_socket s) {
}
#ifdef _WIN32
void ssh_socket_set_nonblocking(socket_t fd) {
int ssh_socket_set_nonblocking(socket_t fd) {
u_long nonblocking = 1;
ioctlsocket(fd, FIONBIO, &nonblocking);
return ioctlsocket(fd, FIONBIO, &nonblocking);
}
void ssh_socket_set_blocking(socket_t fd) {
int ssh_socket_set_blocking(socket_t fd) {
u_long nonblocking = 0;
ioctlsocket(fd, FIONBIO, &nonblocking);
return ioctlsocket(fd, FIONBIO, &nonblocking);
}
#else /* _WIN32 */
void ssh_socket_set_nonblocking(socket_t fd) {
fcntl(fd, F_SETFL, O_NONBLOCK);
int ssh_socket_set_nonblocking(socket_t fd) {
return fcntl(fd, F_SETFL, O_NONBLOCK);
}
void ssh_socket_set_blocking(socket_t fd) {
fcntl(fd, F_SETFL, 0);
int ssh_socket_set_blocking(socket_t fd) {
return fcntl(fd, F_SETFL, 0);
}
#endif /* _WIN32 */

View File

@ -83,7 +83,8 @@ static void torture_channel_read_error(void **state) {
assert_true(rc == SSH_OK);
/* send crap and for server to send us a disconnect */
write(ssh_get_fd(session),"AAAA", 4);
rc = write(ssh_get_fd(session),"AAAA", 4);
assert_int_equal(rc, 4);
for (i=0;i<20;++i){
rc = ssh_channel_read(channel,buffer,sizeof(buffer),0);

View File

@ -110,6 +110,7 @@ int torture_rmdirs(const char *path) {
len = strlen(path) + strlen(dp->d_name) + 2;
fname = malloc(len);
if (fname == NULL) {
closedir(d);
return -1;
}
snprintf(fname, len, "%s/%s", path, dp->d_name);

View File

@ -66,22 +66,25 @@ static void torture_buffer_prepend(void **state) {
buffer_add_data(buffer,"abcdef",6);
buffer_prepend_data(buffer,"xyz",3);
assert_int_equal(buffer_get_rest_len(buffer),9);
assert_int_equal(memcmp(buffer_get_rest(buffer), "xyzabcdef", 9), 0);
// Now remove 4 bytes and see if we can replace them
assert_memory_equal(buffer_get_rest(buffer), "xyzabcdef", 9);
/* Now remove 4 bytes and see if we can replace them */
buffer_get_u32(buffer,&v);
assert_int_equal(buffer_get_rest_len(buffer),5);
assert_int_equal(memcmp(buffer_get_rest(buffer), "bcdef", 5), 0);
assert_memory_equal(buffer_get_rest(buffer), "bcdef", 5);
buffer_prepend_data(buffer,"aris",4);
assert_int_equal(buffer_get_rest_len(buffer),9);
assert_int_equal(memcmp(buffer_get_rest(buffer), "arisbcdef", 9), 0);
assert_memory_equal(buffer_get_rest(buffer), "arisbcdef", 9);
/* same thing but we add 5 bytes now */
buffer_get_u32(buffer,&v);
assert_int_equal(buffer_get_rest_len(buffer),5);
assert_int_equal(memcmp(buffer_get_rest(buffer), "bcdef", 5), 0);
assert_memory_equal(buffer_get_rest(buffer), "bcdef", 5);
buffer_prepend_data(buffer,"12345",5);
assert_int_equal(buffer_get_rest_len(buffer),10);
assert_int_equal(memcmp(buffer_get_rest(buffer), "12345bcdef", 10), 0);
assert_memory_equal(buffer_get_rest(buffer), "12345bcdef", 10);
}
/*
@ -89,7 +92,7 @@ static void torture_buffer_prepend(void **state) {
*/
static void torture_buffer_get_ssh_string(void **state) {
ssh_buffer buffer;
int i,j,k,l;
int i,j,k,l, rc;
/* some values that can go wrong */
uint32_t values[] = {0xffffffff, 0xfffffffe, 0xfffffffc, 0xffffff00,
0x80000000, 0x80000004, 0x7fffffff};
@ -100,13 +103,18 @@ static void torture_buffer_get_ssh_string(void **state) {
for(j=0; j< (int)sizeof(data);++j){
for(k=1;k<5;++k){
buffer=buffer_new();
assert_non_null(buffer);
for(l=0;l<k;++l){
buffer_add_u32(buffer,htonl(values[i]));
rc = buffer_add_u32(buffer,htonl(values[i]));
assert_int_equal(rc, 0);
}
buffer_add_data(buffer,data,j);
rc = buffer_add_data(buffer,data,j);
assert_int_equal(rc, 0);
for(l=0;l<k;++l){
ssh_string str = buffer_get_ssh_string(buffer);
assert_true(str==NULL);
assert_null(str);
ssh_string_free(str);
}
buffer_free(buffer);
}

View File

@ -85,12 +85,14 @@ static char *read_file(const char *filename) {
char *key;
int fd;
int size;
int rc;
struct stat buf;
assert_true(filename != NULL);
assert_true(*filename != '\0');
stat(filename, &buf);
rc = stat(filename, &buf);
assert_int_equal(rc, 0);
key = malloc(buf.st_size + 1);
assert_true(key != NULL);