mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-12 11:10:28 +09:00
Compare commits
23 Commits
release-0-
...
release-0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82eb0427f7 | ||
|
|
7cd327a795 | ||
|
|
77a757c728 | ||
|
|
9ef0837c80 | ||
|
|
2f66b3be13 | ||
|
|
32d5293318 | ||
|
|
e0c969bb41 | ||
|
|
cecd5f0f78 | ||
|
|
9bef81c769 | ||
|
|
1093fb43ca | ||
|
|
add2aa5f45 | ||
|
|
26cdf0d994 | ||
|
|
3cf2c3639e | ||
|
|
a501d63c8a | ||
|
|
160053bc39 | ||
|
|
d672dde342 | ||
|
|
86f983962c | ||
|
|
b0d6307d41 | ||
|
|
10920fc678 | ||
|
|
c87b247e01 | ||
|
|
9abdc5ae2a | ||
|
|
e8e874909f | ||
|
|
74eff86a6b |
@@ -6,13 +6,13 @@ cmake_minimum_required(VERSION 2.6.0)
|
|||||||
# global needed variables
|
# global needed variables
|
||||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
|
|
||||||
set(APPLICATION_VERSION "0.3.2")
|
set(APPLICATION_VERSION "0.3.4")
|
||||||
|
|
||||||
set(APPLICATION_VERSION_MAJOR "0")
|
set(APPLICATION_VERSION_MAJOR "0")
|
||||||
set(APPLICATION_VERSION_MINOR "3")
|
set(APPLICATION_VERSION_MINOR "3")
|
||||||
set(APPLICATION_VERSION_PATCH "2")
|
set(APPLICATION_VERSION_PATCH "4")
|
||||||
|
|
||||||
set(LIBRARY_VERSION "3.2.0")
|
set(LIBRARY_VERSION "3.4.0")
|
||||||
set(LIBRARY_SOVERSION "3")
|
set(LIBRARY_SOVERSION "3")
|
||||||
|
|
||||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
|||||||
### versions
|
### versions
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "2")
|
set(CPACK_PACKAGE_VERSION_PATCH "4")
|
||||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
19
ChangeLog
19
ChangeLog
@@ -1,6 +1,25 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
version 0.3.4 (released 2009-09-14)
|
||||||
|
* Added ssh_basename and ssh_dirname.
|
||||||
|
* Added a portable ssh_mkdir function.
|
||||||
|
* Added a sftp_tell64() function.
|
||||||
|
* Added missing NULL pointer checks to crypt_set_algorithms_server.
|
||||||
|
* Fixed ssh_write_knownhost if ~/.ssh doesn't exist.
|
||||||
|
* Fixed a possible integer overflow in buffer_get_data().
|
||||||
|
* Fixed possible security bug in packet_decrypt().
|
||||||
|
* Fixed a possible stack overflow in agent code.
|
||||||
|
|
||||||
|
version 0.3.3 (released 2009-08-18)
|
||||||
|
* Fixed double free pointer crash in dsa_public_to_string.
|
||||||
|
* Fixed channel_get_exit_status bug.
|
||||||
|
* Fixed ssh_finalize which didn't clear the flag.
|
||||||
|
* Fixed memory leak introduced by previous bugfix.
|
||||||
|
* Fixed channel_poll broken when delayed EOF recvd.
|
||||||
|
* Fixed stupid "can't parse known host key" bug.
|
||||||
|
* Fixed possible memory corruption (ticket #14).
|
||||||
|
|
||||||
version 0.3.2 (released 2009-08-05)
|
version 0.3.2 (released 2009-08-05)
|
||||||
* Added ssh_init() function.
|
* Added ssh_init() function.
|
||||||
* Added sftp_readlink() function.
|
* Added sftp_readlink() function.
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ typedef unsigned long long uint64_t;
|
|||||||
/* libssh version */
|
/* libssh version */
|
||||||
#define LIBSSH_VERSION_MAJOR 0
|
#define LIBSSH_VERSION_MAJOR 0
|
||||||
#define LIBSSH_VERSION_MINOR 3
|
#define LIBSSH_VERSION_MINOR 3
|
||||||
#define LIBSSH_VERSION_MICRO 1
|
#define LIBSSH_VERSION_MICRO 4
|
||||||
|
|
||||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||||
LIBSSH_VERSION_MINOR, \
|
LIBSSH_VERSION_MINOR, \
|
||||||
@@ -373,6 +373,10 @@ const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i,
|
|||||||
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
|
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
|
||||||
const char *answer);
|
const char *answer);
|
||||||
|
|
||||||
|
/* misc.c */
|
||||||
|
int ssh_mkdir (const char *pathname, mode_t mode);
|
||||||
|
char *ssh_dirname (const char *path);
|
||||||
|
char *ssh_basename (const char *path);
|
||||||
|
|
||||||
/* init.c */
|
/* init.c */
|
||||||
int ssh_init(void);
|
int ssh_init(void);
|
||||||
|
|||||||
@@ -469,6 +469,17 @@ int sftp_seek64(SFTP_FILE *file, u64 new_offset);
|
|||||||
*/
|
*/
|
||||||
unsigned long sftp_tell(SFTP_FILE *file);
|
unsigned long sftp_tell(SFTP_FILE *file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Report current byte position in file.
|
||||||
|
*
|
||||||
|
* @param file Open sftp file handle.
|
||||||
|
*
|
||||||
|
* @return The offset of the current byte relative to the beginning
|
||||||
|
* of the file associated with the file descriptor. < 0 on
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
|
u64 sftp_tell64(SFTP_FILE *file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Rewinds the position of the file pointer to the beginning of the
|
* @brief Rewinds the position of the file pointer to the beginning of the
|
||||||
* file.
|
* file.
|
||||||
|
|||||||
@@ -210,10 +210,7 @@ static int agent_talk(struct ssh_session *session,
|
|||||||
|
|
||||||
/* send length and then the request packet */
|
/* send length and then the request packet */
|
||||||
if (atomicio(session->agent->sock, payload, 4, 0) == 4) {
|
if (atomicio(session->agent->sock, payload, 4, 0) == 4) {
|
||||||
buffer_get_data(request, payload, len);
|
if (atomicio(session->agent->sock, buffer_get_rest(request), len, 0)
|
||||||
ssh_log(session, SSH_LOG_PACKET,
|
|
||||||
"agent_talk - sending request, payload[0] = %u", payload[0]);
|
|
||||||
if (atomicio(session->agent->sock, payload, len, 0)
|
|
||||||
!= len) {
|
!= len) {
|
||||||
ssh_log(session, SSH_LOG_PACKET, "atomicio sending request failed: %s",
|
ssh_log(session, SSH_LOG_PACKET, "atomicio sending request failed: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -327,7 +324,7 @@ int agent_get_ident_count(struct ssh_session *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->agent->ident) {
|
if (session->agent->ident) {
|
||||||
buffer_free(session->agent->ident);
|
buffer_reinit(session->agent->ident);
|
||||||
}
|
}
|
||||||
session->agent->ident = reply;
|
session->agent->ident = reply;
|
||||||
|
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ int ssh_userauth_none(SSH_SESSION *session, const char *username) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
@@ -382,7 +382,7 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
@@ -503,7 +503,7 @@ int ssh_userauth_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
@@ -627,7 +627,7 @@ int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(sign);
|
string_free(sign);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
@@ -739,7 +739,7 @@ int ssh_userauth_password(SSH_SESSION *session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
@@ -1123,7 +1123,7 @@ static int kbdauth_init(SSH_SESSION *session, const char *user,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(usr);
|
string_free(usr);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
@@ -1290,7 +1290,7 @@ static int kbdauth_send(SSH_SESSION *session) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_burn(answer);
|
string_burn(answer);
|
||||||
string_free(answer);
|
string_free(answer);
|
||||||
|
|
||||||
|
|||||||
@@ -298,8 +298,13 @@ u32 buffer_pass_bytes_end(struct buffer_struct *buffer, u32 len){
|
|||||||
* \returns len otherwise.
|
* \returns len otherwise.
|
||||||
*/
|
*/
|
||||||
u32 buffer_get_data(struct buffer_struct *buffer, void *data, u32 len){
|
u32 buffer_get_data(struct buffer_struct *buffer, void *data, u32 len){
|
||||||
if(buffer->pos+len>buffer->used)
|
/*
|
||||||
return 0; /*no enough data in buffer */
|
* Check for a integer overflow first, then check if not enough data is in
|
||||||
|
* the buffer.
|
||||||
|
*/
|
||||||
|
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
memcpy(data,buffer->data+buffer->pos,len);
|
memcpy(data,buffer->data+buffer->pos,len);
|
||||||
buffer->pos+=len;
|
buffer->pos+=len;
|
||||||
return len; /* no yet support for partial reads (is it really needed ?? ) */
|
return len; /* no yet support for partial reads (is it really needed ?? ) */
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ static int grow_window(SSH_SESSION *session, CHANNEL *channel, int minimumsize)
|
|||||||
leave_function();
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
@@ -791,7 +791,7 @@ int channel_send_eof(CHANNEL *channel){
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -844,7 +844,7 @@ int channel_close(CHANNEL *channel){
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -938,7 +938,7 @@ int channel_write(CHANNEL *channel, const void *data, u32 len) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return origlen;
|
return origlen;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@@ -1060,7 +1060,7 @@ static int channel_request(CHANNEL *channel, const char *request,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(req);
|
string_free(req);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -1618,6 +1618,9 @@ int channel_poll(CHANNEL *channel, int is_stderr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buffer_get_rest_len(stdbuf) > 0)
|
||||||
|
return buffer_get_rest_len(stdbuf);
|
||||||
|
|
||||||
if (channel->remote_eof) {
|
if (channel->remote_eof) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_EOF;
|
return SSH_EOF;
|
||||||
@@ -1658,7 +1661,9 @@ int channel_get_exit_status(CHANNEL *channel) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (channel->open == 0) {
|
if (channel->open == 0) {
|
||||||
return -1;
|
/* When a channel is closed, no exit status message can
|
||||||
|
* come anymore */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,10 @@ u32 packet_decrypt_len(SSH_SESSION *session, char *crypted){
|
|||||||
int packet_decrypt(SSH_SESSION *session, void *data,u32 len) {
|
int packet_decrypt(SSH_SESSION *session, void *data,u32 len) {
|
||||||
struct crypto_struct *crypto = session->current_crypto->in_cipher;
|
struct crypto_struct *crypto = session->current_crypto->in_cipher;
|
||||||
char *out = NULL;
|
char *out = NULL;
|
||||||
|
if(len % session->current_crypto->in_cipher->blocksize != 0){
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
out = malloc(len);
|
out = malloc(len);
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -100,7 +103,10 @@ unsigned char *packet_encrypt(SSH_SESSION *session, void *data, u32 len) {
|
|||||||
if (!session->current_crypto) {
|
if (!session->current_crypto) {
|
||||||
return NULL; /* nothing to do here */
|
return NULL; /* nothing to do here */
|
||||||
}
|
}
|
||||||
|
if(len % session->current_crypto->in_cipher->blocksize != 0){
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
out = malloc(len);
|
out = malloc(len);
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
11
libssh/dh.c
11
libssh/dh.c
@@ -149,6 +149,7 @@ void ssh_crypto_finalize(void) {
|
|||||||
g = NULL;
|
g = NULL;
|
||||||
bignum_free(p);
|
bignum_free(p);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
|
ssh_crypto_initialized=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,20 +627,20 @@ int hashbufout_add_cookie(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
|
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->server) {
|
if (session->server) {
|
||||||
if (buffer_add_data(session->out_hashbuf,
|
if (buffer_add_data(session->out_hashbuf,
|
||||||
session->server_kex.cookie, 16) < 0) {
|
session->server_kex.cookie, 16) < 0) {
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (buffer_add_data(session->out_hashbuf,
|
if (buffer_add_data(session->out_hashbuf,
|
||||||
session->client_kex.cookie, 16) < 0) {
|
session->client_kex.cookie, 16) < 0) {
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -654,11 +655,11 @@ int hashbufin_add_cookie(SSH_SESSION *session, unsigned char *cookie) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
|
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
|
||||||
buffer_free(session->in_hashbuf);
|
buffer_reinit(session->in_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
|
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
|
||||||
buffer_free(session->in_hashbuf);
|
buffer_reinit(session->in_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -421,8 +421,8 @@ int ssh_send_kex(SSH_SESSION *session, int server_kex) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
string_free(str);
|
string_free(str);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
|
|||||||
@@ -22,13 +22,15 @@
|
|||||||
* MA 02111-1307, USA.
|
* MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -1074,6 +1076,7 @@ static char **ssh_get_knownhost_line(SSH_SESSION *session, FILE **file,
|
|||||||
while (fgets(buffer, sizeof(buffer), *file)) {
|
while (fgets(buffer, sizeof(buffer), *file)) {
|
||||||
ptr = strchr(buffer, '\n');
|
ptr = strchr(buffer, '\n');
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
*ptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = strchr(buffer,'\r');
|
ptr = strchr(buffer,'\r');
|
||||||
@@ -1446,6 +1449,7 @@ int ssh_write_knownhost(SSH_SESSION *session) {
|
|||||||
unsigned char *pubkey_64;
|
unsigned char *pubkey_64;
|
||||||
char buffer[4096] = {0};
|
char buffer[4096] = {0};
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
char *dir;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (ssh_options_default_known_hosts_file(session->options) < 0) {
|
if (ssh_options_default_known_hosts_file(session->options) < 0) {
|
||||||
@@ -1459,6 +1463,22 @@ int ssh_write_knownhost(SSH_SESSION *session) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if ~/.ssh exists and create it if not */
|
||||||
|
dir = ssh_dirname(session->options->known_hosts_file);
|
||||||
|
if (dir == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (! ssh_file_readaccess_ok(dir)) {
|
||||||
|
if (ssh_mkdir(dir, 0700) < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"Cannot create %s directory.", dir);
|
||||||
|
SAFE_FREE(dir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SAFE_FREE(dir);
|
||||||
|
|
||||||
file = fopen(session->options->known_hosts_file, "a");
|
file = fopen(session->options->known_hosts_file, "a");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
|||||||
@@ -540,7 +540,6 @@ static int dsa_public_to_string(DSA *key, BUFFER *buffer) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
string_fill(n, (char *) tmp, size);
|
string_fill(n, (char *) tmp, size);
|
||||||
gcry_sexp_release(sexp);
|
|
||||||
|
|
||||||
#elif defined HAVE_LIBCRYPTO
|
#elif defined HAVE_LIBCRYPTO
|
||||||
p = make_bignum_string(key->p);
|
p = make_bignum_string(key->p);
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ SSH_0.3 {
|
|||||||
ssh_get_random;
|
ssh_get_random;
|
||||||
ssh_get_status;
|
ssh_get_status;
|
||||||
ssh_get_version;
|
ssh_get_version;
|
||||||
|
ssh_mkdir;
|
||||||
|
ssh_basename;
|
||||||
|
ssh_dirname;
|
||||||
ssh_init;
|
ssh_init;
|
||||||
ssh_is_server_known;
|
ssh_is_server_known;
|
||||||
ssh_log;
|
ssh_log;
|
||||||
|
|||||||
134
libssh/misc.c
134
libssh/misc.c
@@ -27,6 +27,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
#define _WIN32_IE 0x0400 //SHGetSpecialFolderPath
|
#define _WIN32_IE 0x0400 //SHGetSpecialFolderPath
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <direct.h>
|
||||||
#else
|
#else
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -149,5 +151,137 @@ const char *ssh_version(int req_version) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse directory component.
|
||||||
|
*
|
||||||
|
* dirname breaks a null-terminated pathname string into a directory component.
|
||||||
|
* In the usual case, ssh_dirname() returns the string up to, but not including,
|
||||||
|
* the final '/'. Trailing '/' characters are not counted as part of the
|
||||||
|
* pathname. The caller must free the memory.
|
||||||
|
*
|
||||||
|
* @param path The path to parse.
|
||||||
|
*
|
||||||
|
* @return The dirname of path or NULL if we can't allocate memory. If path
|
||||||
|
* does not contain a slash, c_dirname() returns the string ".". If
|
||||||
|
* path is the string "/", it returns the string "/". If path is
|
||||||
|
* NULL or an empty string, "." is returned.
|
||||||
|
*/
|
||||||
|
char *ssh_dirname (const char *path) {
|
||||||
|
char *new = NULL;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
if (path == NULL || *path == '\0') {
|
||||||
|
return strdup(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(path);
|
||||||
|
|
||||||
|
/* Remove trailing slashes */
|
||||||
|
while(len > 0 && path[len - 1] == '/') --len;
|
||||||
|
|
||||||
|
/* We have only slashes */
|
||||||
|
if (len == 0) {
|
||||||
|
return strdup("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* goto next slash */
|
||||||
|
while(len > 0 && path[len - 1] != '/') --len;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
return strdup(".");
|
||||||
|
} else if (len == 1) {
|
||||||
|
return strdup("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove slashes again */
|
||||||
|
while(len > 0 && path[len - 1] == '/') --len;
|
||||||
|
|
||||||
|
new = malloc(len + 1);
|
||||||
|
if (new == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(new, path, len);
|
||||||
|
new[len] = '\0';
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief basename - parse filename component.
|
||||||
|
*
|
||||||
|
* basename breaks a null-terminated pathname string into a filename component.
|
||||||
|
* ssh_basename() returns the component following the final '/'. Trailing '/'
|
||||||
|
* characters are not counted as part of the pathname.
|
||||||
|
*
|
||||||
|
* @param path The path to parse.
|
||||||
|
*
|
||||||
|
* @return The filename of path or NULL if we can't allocate memory. If path
|
||||||
|
* is a the string "/", basename returns the string "/". If path is
|
||||||
|
* NULL or an empty string, "." is returned.
|
||||||
|
*/
|
||||||
|
char *ssh_basename (const char *path) {
|
||||||
|
char *new = NULL;
|
||||||
|
const char *s;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
if (path == NULL || *path == '\0') {
|
||||||
|
return strdup(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(path);
|
||||||
|
/* Remove trailing slashes */
|
||||||
|
while(len > 0 && path[len - 1] == '/') --len;
|
||||||
|
|
||||||
|
/* We have only slashes */
|
||||||
|
if (len == 0) {
|
||||||
|
return strdup("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
while(len > 0 && path[len - 1] != '/') --len;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
s = path + len;
|
||||||
|
len = strlen(s);
|
||||||
|
|
||||||
|
while(len > 0 && s[len - 1] == '/') --len;
|
||||||
|
} else {
|
||||||
|
return strdup(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
new = malloc(len + 1);
|
||||||
|
if (new == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(new, s, len);
|
||||||
|
new[len] = '\0';
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attempts to create a directory with the given pathname.
|
||||||
|
*
|
||||||
|
* This is the portable version of mkdir, mode is ignored on Windows systems.
|
||||||
|
*
|
||||||
|
* @param pathname The path name to create the directory.
|
||||||
|
*
|
||||||
|
* @param mode The permissions to use.
|
||||||
|
*
|
||||||
|
* @return 0 on success, < 0 on error with errno set.
|
||||||
|
*/
|
||||||
|
int ssh_mkdir(const char *pathname, mode_t mode) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
r = _mkdir(pathname);
|
||||||
|
#else
|
||||||
|
r = mkdir(pathname, mode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/* vim: set ts=2 sw=2 et cindent: */
|
/* vim: set ts=2 sw=2 et cindent: */
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ static int dh_handshake_server(SSH_SESSION *session) {
|
|||||||
buffer_add_ssh_string(session->out_buffer, f) < 0 ||
|
buffer_add_ssh_string(session->out_buffer, f) < 0 ||
|
||||||
buffer_add_ssh_string(session->out_buffer, sign) < 0) {
|
buffer_add_ssh_string(session->out_buffer, sign) < 0) {
|
||||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(f);
|
string_free(f);
|
||||||
string_free(sign);
|
string_free(sign);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -437,7 +437,7 @@ static int dh_handshake_server(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ void ssh_cleanup(SSH_SESSION *session) {
|
|||||||
SAFE_FREE(session->banner);
|
SAFE_FREE(session->banner);
|
||||||
buffer_free(session->in_buffer);
|
buffer_free(session->in_buffer);
|
||||||
buffer_free(session->out_buffer);
|
buffer_free(session->out_buffer);
|
||||||
|
session->in_buffer=session->out_buffer=NULL;
|
||||||
crypto_free(session->current_crypto);
|
crypto_free(session->current_crypto);
|
||||||
crypto_free(session->next_crypto);
|
crypto_free(session->next_crypto);
|
||||||
ssh_socket_free(session->socket);
|
ssh_socket_free(session->socket);
|
||||||
|
|||||||
@@ -1777,7 +1777,11 @@ int sftp_seek64(SFTP_FILE *file, u64 new_offset) {
|
|||||||
|
|
||||||
/* Report current byte position in file. */
|
/* Report current byte position in file. */
|
||||||
unsigned long sftp_tell(SFTP_FILE *file) {
|
unsigned long sftp_tell(SFTP_FILE *file) {
|
||||||
return file->offset;
|
return (unsigned long)file->offset;
|
||||||
|
}
|
||||||
|
/* Report current byte position in file. */
|
||||||
|
u64 sftp_tell64(SFTP_FILE *file) {
|
||||||
|
return (u64)file->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rewinds the position of the file pointer to the beginning of the file.*/
|
/* Rewinds the position of the file pointer to the beginning of the file.*/
|
||||||
|
|||||||
@@ -901,7 +901,7 @@ int crypt_set_algorithms_server(SSH_SESSION *session){
|
|||||||
/* out */
|
/* out */
|
||||||
server = session->server_kex.methods[SSH_CRYPT_S_C];
|
server = session->server_kex.methods[SSH_CRYPT_S_C];
|
||||||
client = session->client_kex.methods[SSH_CRYPT_S_C];
|
client = session->client_kex.methods[SSH_CRYPT_S_C];
|
||||||
match = ssh_find_matching(client,server);
|
match = ssh_find_matching(client, server);
|
||||||
|
|
||||||
if(!match){
|
if(!match){
|
||||||
ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server : no matching algorithm function found for %s",server);
|
ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server : no matching algorithm function found for %s",server);
|
||||||
@@ -963,7 +963,7 @@ int crypt_set_algorithms_server(SSH_SESSION *session){
|
|||||||
ssh_log(session,SSH_LOG_PACKET,"enabling C->S compression");
|
ssh_log(session,SSH_LOG_PACKET,"enabling C->S compression");
|
||||||
session->next_crypto->do_compress_in=1;
|
session->next_crypto->do_compress_in=1;
|
||||||
}
|
}
|
||||||
free(match);
|
SAFE_FREE(match);
|
||||||
|
|
||||||
client=session->client_kex.methods[SSH_CRYPT_S_C];
|
client=session->client_kex.methods[SSH_CRYPT_S_C];
|
||||||
server=session->server_kex.methods[SSH_CRYPT_S_C];
|
server=session->server_kex.methods[SSH_CRYPT_S_C];
|
||||||
@@ -972,22 +972,23 @@ int crypt_set_algorithms_server(SSH_SESSION *session){
|
|||||||
ssh_log(session,SSH_LOG_PACKET,"enabling S->C compression\n");
|
ssh_log(session,SSH_LOG_PACKET,"enabling S->C compression\n");
|
||||||
session->next_crypto->do_compress_out=1;
|
session->next_crypto->do_compress_out=1;
|
||||||
}
|
}
|
||||||
free(match);
|
SAFE_FREE(match);
|
||||||
|
|
||||||
server=session->server_kex.methods[SSH_HOSTKEYS];
|
server=session->server_kex.methods[SSH_HOSTKEYS];
|
||||||
client=session->client_kex.methods[SSH_HOSTKEYS];
|
client=session->client_kex.methods[SSH_HOSTKEYS];
|
||||||
match=ssh_find_matching(client,server);
|
match=ssh_find_matching(client,server);
|
||||||
if(!strcmp(match,"ssh-dss"))
|
if(match && !strcmp(match,"ssh-dss"))
|
||||||
session->hostkeys=TYPE_DSS;
|
session->hostkeys=TYPE_DSS;
|
||||||
else if(!strcmp(match,"ssh-rsa"))
|
else if(match && !strcmp(match,"ssh-rsa"))
|
||||||
session->hostkeys=TYPE_RSA;
|
session->hostkeys=TYPE_RSA;
|
||||||
else {
|
else {
|
||||||
ssh_set_error(session,SSH_FATAL,"cannot know what %s is into %s",match,server);
|
ssh_set_error(session, SSH_FATAL, "Cannot know what %s is into %s",
|
||||||
free(match);
|
match ? match : NULL, server);
|
||||||
|
SAFE_FREE(match);
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
free(match);
|
SAFE_FREE(match);
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user