Merge branch 'master' of git://git.libssh.org/projects/libssh/libssh

This commit is contained in:
Aris Adamantiadis
2009-10-05 10:01:24 +02:00
24 changed files with 679 additions and 955 deletions

View File

@@ -37,7 +37,6 @@
#include "libssh/keyfiles.h"
#include "libssh/packet.h"
#include "libssh/session.h"
#include "libssh/options.h"
#include "libssh/keys.h"
/** \defgroup ssh_auth SSH Authentication functions
@@ -224,13 +223,13 @@ int ssh_userauth_none(ssh_session session, const char *username) {
#endif
if (username == NULL) {
if (session->options->username == NULL) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if (session->username == NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
leave_function();
return rc;
}
}
user = string_from_char(session->options->username);
user = string_from_char(session->username);
} else {
user = string_from_char(username);
}
@@ -330,13 +329,13 @@ int ssh_userauth_offer_pubkey(ssh_session session, const char *username,
#endif
if (username == NULL) {
if (session->options->username == NULL) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if (session->username == NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
leave_function();
return rc;
}
}
user = string_from_char(session->options->username);
user = string_from_char(session->username);
} else {
user = string_from_char(username);
}
@@ -442,13 +441,13 @@ int ssh_userauth_pubkey(ssh_session session, const char *username,
#endif
if (username == NULL) {
if (session->options->username == NULL) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if (session->username == NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
leave_function();
return rc;
}
}
user = string_from_char(session->options->username);
user = string_from_char(session->username);
} else {
user = string_from_char(username);
}
@@ -560,13 +559,13 @@ int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
}
if (username == NULL) {
if (session->options->username == NULL) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if (session->username == NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
leave_function();
return rc;
}
}
user = string_from_char(session->options->username);
user = string_from_char(session->username);
} else {
user = string_from_char(username);
}
@@ -687,13 +686,13 @@ int ssh_userauth_password(ssh_session session, const char *username,
#endif
if (username == NULL) {
if (session->options->username == NULL) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if (session->username == NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
leave_function();
return rc;
}
}
user = string_from_char(session->options->username);
user = string_from_char(session->username);
} else {
user = string_from_char(username);
}
@@ -903,18 +902,18 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
#endif
size = ARRAY_SIZE(keytab);
if (session->options->identity) {
if (session->identity) {
ssh_log(session, SSH_LOG_RARE,
"Trying identity file %s\n", session->options->identity);
"Trying identity file %s\n", session->identity);
id = malloc(strlen(session->options->identity) + 1 + 4);
id = malloc(strlen(session->identity) + 1 + 4);
if (id == NULL) {
leave_function();
return SSH_AUTH_ERROR;
}
sprintf(id, "%s.pub", session->options->identity);
sprintf(id, "%s.pub", session->identity);
keytab[size - 1].privatekey = session->options->identity;
keytab[size - 1].privatekey = session->identity;
keytab[size - 1].publickey = id;
}
@@ -1369,12 +1368,12 @@ int ssh_userauth_kbdint(ssh_session session, const char *user,
if (session->kbdint == NULL) {
/* first time we call. we must ask for a challenge */
if (user == NULL) {
if ((user = session->options->username) == NULL) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if ((user = session->username) == NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
leave_function();
return SSH_AUTH_ERROR;
} else {
user = session->options->username;
user = session->username;
}
}
}

View File

@@ -21,6 +21,8 @@
* MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <stdlib.h>
@@ -30,7 +32,6 @@
#include "libssh/packet.h"
#include "libssh/session.h"
#include "libssh/string.h"
#include "libssh/options.h"
#ifdef WITH_SSH1
static int wait_auth1_status(ssh_session session) {
@@ -64,11 +65,11 @@ static int send_username(ssh_session session, const char *username) {
}
if (!username) {
if(!(username = session->options->username)) {
if (ssh_options_set(session->options, SSH_OPTIONS_USER, NULL) < 0) {
if(!(username = session->username)) {
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
return session->auth_service_asked = SSH_AUTH_ERROR;
} else {
username = session->options->username;
username = session->username;
}
}
}

View File

@@ -35,12 +35,11 @@
#include "libssh/packet.h"
#include "libssh/socket.h"
#include "libssh/session.h"
#include "libssh/options.h"
#include "libssh/dh.h"
#define set_status(opt,status) do {\
if (opt->callbacks && opt->callbacks->connect_status_function) \
opt->callbacks->connect_status_function(opt->callbacks->userdata, status); \
#define set_status(session, status) do {\
if (session->callbacks && session->callbacks->connect_status_function) \
session->callbacks->connect_status_function(session->callbacks->userdata, status); \
} while (0)
/**
@@ -169,8 +168,8 @@ int ssh_send_banner(ssh_session session, int server) {
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
if (session->options->banner) {
banner = session->options->banner;
if (session->xbanner) {
banner = session->xbanner;
}
if (server) {
@@ -476,7 +475,6 @@ int ssh_service_request(ssh_session session, const char *service) {
* \see ssh_disconnect()
*/
int ssh_connect(ssh_session session) {
ssh_options options = session->options;
int ssh1 = 0;
int ssh2 = 0;
int fd = -1;
@@ -486,12 +484,6 @@ int ssh_connect(ssh_session session) {
return SSH_ERROR;
}
if (session->options == NULL) {
ssh_set_error(session, SSH_FATAL, "No options set");
return SSH_ERROR;
}
options = session->options;
enter_function();
session->alive = 0;
@@ -501,22 +493,22 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
if (options->fd == -1 && options->host == NULL) {
if (session->fd == -1 && session->host == NULL) {
ssh_set_error(session, SSH_FATAL, "Hostname required");
leave_function();
return SSH_ERROR;
}
if (options->fd != -1) {
fd = options->fd;
if (session->fd != -1) {
fd = session->fd;
} else {
fd = ssh_connect_host(session, options->host, options->bindaddr,
options->port, options->timeout, options->timeout_usec);
fd = ssh_connect_host(session, session->host, session->bindaddr,
session->port, session->timeout, session->timeout_usec);
}
if (fd < 0) {
leave_function();
return SSH_ERROR;
}
set_status(options, 0.2);
set_status(session, 0.2);
ssh_socket_set_fd(session->socket, fd);
@@ -528,7 +520,7 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
set_status(options, 0.4);
set_status(session, 0.4);
ssh_log(session, SSH_LOG_RARE,
"SSH server banner: %s", session->serverbanner);
@@ -542,9 +534,9 @@ int ssh_connect(ssh_session session) {
}
/* Here we decide which version of the protocol to use. */
if (ssh2 && options->ssh2allowed) {
if (ssh2 && session->ssh2) {
session->version = 2;
} else if(ssh1 && options->ssh1allowed) {
} else if(ssh1 && session->ssh1) {
session->version = 1;
} else {
ssh_set_error(session, SSH_FATAL,
@@ -563,7 +555,7 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
set_status(options, 0.5);
set_status(session, 0.5);
switch (session->version) {
case 2:
@@ -573,7 +565,7 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
set_status(options,0.6);
set_status(session,0.6);
ssh_list_kex(session, &session->server_kex);
if (set_kex(session) < 0) {
@@ -588,7 +580,7 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
set_status(options,0.8);
set_status(session,0.8);
if (dh_handshake(session) < 0) {
ssh_socket_close(session->socket);
@@ -596,7 +588,7 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
set_status(options,1.0);
set_status(session,1.0);
session->connected = 1;
break;
@@ -607,7 +599,7 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
set_status(options,0.6);
set_status(session,0.6);
session->connected = 1;
break;

View File

@@ -26,7 +26,7 @@
#include <string.h>
#include "libssh/priv.h"
#include "libssh/options.h"
#include "libssh/session.h"
enum ssh_config_opcode_e {
SOC_UNSUPPORTED = -1,
@@ -150,7 +150,7 @@ static int ssh_config_get_yesno(char **str, int notfound) {
return notfound;
}
static int ssh_config_parse_line(ssh_options opt, const char *line,
static int ssh_config_parse_line(ssh_session session, const char *line,
unsigned int count, int *parsing) {
enum ssh_config_opcode_e opcode;
const char *p;
@@ -186,7 +186,7 @@ static int ssh_config_parse_line(ssh_options opt, const char *line,
*parsing = 0;
for (p = ssh_config_get_str(&s, NULL); p && *p;
p = ssh_config_get_str(&s, NULL)) {
if (match_hostname(opt->host, p, strlen(p))) {
if (match_hostname(session->host, p, strlen(p))) {
*parsing = 1;
}
}
@@ -194,43 +194,43 @@ static int ssh_config_parse_line(ssh_options opt, const char *line,
case SOC_HOSTNAME:
p = ssh_config_get_str(&s, NULL);
if (p && *parsing) {
ssh_options_set(opt, SSH_OPTIONS_HOST, p);
ssh_options_set(session, SSH_OPTIONS_HOST, p);
}
break;
case SOC_PORT:
p = ssh_config_get_str(&s, NULL);
if (p && *parsing) {
ssh_options_set(opt, SSH_OPTIONS_PORT_STR, p);
ssh_options_set(session, SSH_OPTIONS_PORT_STR, p);
}
break;
case SOC_USERNAME:
p = ssh_config_get_str(&s, NULL);
if (p && *parsing) {
ssh_options_set(opt, SSH_OPTIONS_USER, p);
ssh_options_set(session, SSH_OPTIONS_USER, p);
}
break;
case SOC_IDENTITY:
p = ssh_config_get_str(&s, NULL);
if (p && *parsing) {
ssh_options_set(opt, SSH_OPTIONS_IDENTITY, p);
ssh_options_set(session, SSH_OPTIONS_IDENTITY, p);
}
break;
case SOC_CIPHERS:
p = ssh_config_get_str(&s, NULL);
if (p && *parsing) {
ssh_options_set(opt, SSH_OPTIONS_CIPHERS_C_S, p);
ssh_options_set(opt, SSH_OPTIONS_CIPHERS_S_C, p);
ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, p);
ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, p);
}
break;
case SOC_COMPRESSION:
i = ssh_config_get_yesno(&s, -1);
if (i >= 0 && *parsing) {
if (i) {
ssh_options_set(opt, SSH_OPTIONS_COMPRESSION_C_S, "zlib");
ssh_options_set(opt, SSH_OPTIONS_COMPRESSION_S_C, "zlib");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "zlib");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "zlib");
} else {
ssh_options_set(opt, SSH_OPTIONS_COMPRESSION_C_S, "none");
ssh_options_set(opt, SSH_OPTIONS_COMPRESSION_S_C, "none");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none");
}
}
break;
@@ -244,18 +244,18 @@ static int ssh_config_parse_line(ssh_options opt, const char *line,
return -1;
}
i = 0;
ssh_options_set(opt, SSH_OPTIONS_SSH1, &i);
ssh_options_set(opt, SSH_OPTIONS_SSH2, &i);
ssh_options_set(session, SSH_OPTIONS_SSH1, &i);
ssh_options_set(session, SSH_OPTIONS_SSH2, &i);
for (a = strtok(b, ","); a; a = strtok(NULL, ",")) {
switch (atoi(a)) {
case 1:
i = 1;
ssh_options_set(opt, SSH_OPTIONS_SSH1, &i);
ssh_options_set(session, SSH_OPTIONS_SSH1, &i);
break;
case 2:
i = 1;
ssh_options_set(opt, SSH_OPTIONS_SSH2, &i);
ssh_options_set(session, SSH_OPTIONS_SSH2, &i);
break;
default:
break;
@@ -267,7 +267,7 @@ static int ssh_config_parse_line(ssh_options opt, const char *line,
case SOC_TIMEOUT:
i = ssh_config_get_int(&s, -1);
if (i >= 0 && *parsing) {
ssh_options_set(opt, SSH_OPTIONS_TIMEOUT, &i);
ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &i);
}
break;
case SOC_UNSUPPORTED:
@@ -285,7 +285,7 @@ static int ssh_config_parse_line(ssh_options opt, const char *line,
}
/* ssh_config_parse_file */
int ssh_config_parse_file(ssh_options opt, const char *filename) {
int ssh_config_parse_file(ssh_session session, const char *filename) {
char line[1024] = {0};
unsigned int count = 0;
FILE *f;
@@ -295,14 +295,14 @@ int ssh_config_parse_file(ssh_options opt, const char *filename) {
return -1;
}
if (opt->log_verbosity) {
if (session->log_verbosity) {
fprintf(stderr, "Reading configuration data from %s\n", filename);
}
parsing = 1;
while (fgets(line, sizeof(line), f)) {
count++;
if (ssh_config_parse_line(opt, line, count, &parsing) < 0) {
if (ssh_config_parse_line(session, line, count, &parsing) < 0) {
fclose(f);
return -1;
}

View File

@@ -53,7 +53,6 @@
#include "libssh/crypto.h"
#include "libssh/buffer.h"
#include "libssh/session.h"
#include "libssh/options.h"
#include "libssh/keys.h"
#include "libssh/dh.h"
@@ -1006,11 +1005,11 @@ int signature_verify(ssh_session session, ssh_string signature) {
return -1;
}
if (session->options->wanted_methods[SSH_HOSTKEYS]) {
if(!match(session->options->wanted_methods[SSH_HOSTKEYS],pubkey->type_c)) {
if (session->wanted_methods[SSH_HOSTKEYS]) {
if(!match(session->wanted_methods[SSH_HOSTKEYS],pubkey->type_c)) {
ssh_set_error(session, SSH_FATAL,
"Public key from server (%s) doesn't match user preference (%s)",
pubkey->type_c, session->options->wanted_methods[SSH_HOSTKEYS]);
pubkey->type_c, session->wanted_methods[SSH_HOSTKEYS]);
publickey_free(pubkey);
leave_function();
return -1;

View File

@@ -41,7 +41,7 @@
*
* @brief Registers an error with a description.
*
* @param error The class of error.
* @param error The place to store the error.
*
* @param code The class of error.
*
@@ -58,6 +58,35 @@ void ssh_set_error(void *error, int code, const char *descr, ...) {
err->error_code = code;
}
/**
* @internal
*
* @brief Registers an out of memory error
*
* @param error The place to store the error.
*
*/
void ssh_set_error_oom(void *error) {
struct error_struct *err = error;
strcpy(err->error_buffer, "Out of memory");
err->error_code = SSH_FATAL;
}
/**
* @internal
*
* @brief Registers an invalid argument error
*
* @param error The place to store the error.
*
* @param function The function the error happened in.
*
*/
void ssh_set_error_invalid(void *error, const char *function) {
ssh_set_error(error, SSH_FATAL, "Invalid argument in %s", function);
}
/**
* @brief Retrieve the error text message from the last error.
*

View File

@@ -38,7 +38,6 @@
#include "libssh/packet.h"
#include "libssh/session.h"
#include "libssh/wrapper.h"
#include "libssh/options.h"
#include "libssh/keys.h"
#include "libssh/dh.h"
@@ -339,7 +338,6 @@ void ssh_list_kex(ssh_session session, KEX *kex) {
int set_kex(ssh_session session){
KEX *server = &session->server_kex;
KEX *client=&session->client_kex;
ssh_options options=session->options;
int i;
const char *wanted;
enter_function();
@@ -352,7 +350,7 @@ int set_kex(ssh_session session){
}
memset(client->methods,0,10*sizeof(char **));
for (i=0;i<10;i++){
if(!(wanted=options->wanted_methods[i]))
if(!(wanted=session->wanted_methods[i]))
wanted=default_methods[i];
client->methods[i]=ssh_find_matching(server->methods[i],wanted);
if(!client->methods[i] && i < SSH_LANG_C_S){

View File

@@ -42,7 +42,6 @@
#include "libssh/keyfiles.h"
#include "libssh/session.h"
#include "libssh/wrapper.h"
#include "libssh/options.h"
#include "libssh/misc.h"
#include "libssh/keys.h"
@@ -599,9 +598,9 @@ static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
ssh_log(session, SSH_LOG_RARE,
"Trying to call external authentication function");
if (session && session->options->callbacks->auth_function) {
if (session->options->callbacks->auth_function("Passphrase for private key:", buf, size, 0, 0,
session->options->callbacks->userdata) < 0) {
if (session && session->callbacks->auth_function) {
if (session->callbacks->auth_function("Passphrase for private key:", buf, size, 0, 0,
session->callbacks->userdata) < 0) {
return 0;
}
@@ -649,13 +648,13 @@ ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
ssh_log(session, SSH_LOG_RARE, "Trying to read %s, passphase=%s, authcb=%s",
filename, passphrase ? "true" : "false",
session->options->callbacks->auth_function ? "true" : "false");
session->callbacks->auth_function ? "true" : "false");
switch (type) {
case TYPE_DSS:
if (passphrase == NULL) {
if (session->options->callbacks->auth_function) {
auth_cb = session->options->callbacks->auth_function;
auth_ud = session->options->callbacks->userdata;
if (session->callbacks->auth_function) {
auth_cb = session->callbacks->auth_function;
auth_ud = session->callbacks->userdata;
#ifdef HAVE_LIBGCRYPT
valid = read_dsa_privatekey(file, &dsa, auth_cb, auth_ud,
@@ -693,9 +692,9 @@ ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
break;
case TYPE_RSA:
if (passphrase == NULL) {
if (session->options->callbacks->auth_function) {
auth_cb = session->options->callbacks->auth_function;
auth_ud = session->options->callbacks->userdata;
if (session->callbacks->auth_function) {
auth_cb = session->callbacks->auth_function;
auth_ud = session->callbacks->userdata;
#ifdef HAVE_LIBGCRYPT
valid = read_rsa_privatekey(file, &rsa, auth_cb, auth_ud,
"Passphrase for private key:");
@@ -1386,21 +1385,21 @@ int ssh_is_server_known(ssh_session session) {
enter_function();
if (ssh_options_set(session->options, SSH_OPTIONS_KNOWNHOSTS, NULL) < 0) {
if (ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, NULL) < 0) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"Can't find a known_hosts file");
leave_function();
return SSH_SERVER_FILE_NOT_FOUND;
}
if (session->options->host == NULL) {
if (session->host == NULL) {
ssh_set_error(session, SSH_FATAL,
"Can't verify host in known hosts if the hostname isn't known");
leave_function();
return SSH_SERVER_ERROR;
}
host = lowercase(session->options->host);
host = lowercase(session->host);
if (host == NULL) {
ssh_set_error(session, SSH_FATAL, "Not enough space!");
leave_function();
@@ -1409,7 +1408,7 @@ int ssh_is_server_known(ssh_session session) {
do {
tokens = ssh_get_knownhost_line(session, &file,
session->options->known_hosts_file, &type);
session->knownhosts, &type);
/* End of file, return the current state */
if (tokens == NULL) {
@@ -1472,19 +1471,19 @@ int ssh_write_knownhost(ssh_session session) {
char *dir;
size_t len = 0;
if (ssh_options_set(session->options, SSH_OPTIONS_KNOWNHOSTS, NULL) < 0) {
if (ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, NULL) < 0) {
ssh_set_error(session, SSH_FATAL, "Cannot find known_hosts file.");
return -1;
}
if (session->options->host == NULL) {
if (session->host == NULL) {
ssh_set_error(session, SSH_FATAL,
"Cannot write host in known hosts if the hostname is unknown");
return -1;
}
/* Check if ~/.ssh exists and create it if not */
dir = ssh_dirname(session->options->known_hosts_file);
dir = ssh_dirname(session->knownhosts);
if (dir == NULL) {
ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
return -1;
@@ -1499,11 +1498,11 @@ int ssh_write_knownhost(ssh_session session) {
}
SAFE_FREE(dir);
file = fopen(session->options->known_hosts_file, "a");
file = fopen(session->knownhosts, "a");
if (file == NULL) {
ssh_set_error(session, SSH_FATAL,
"Couldn't open known_hosts file %s for appending: %s",
session->options->known_hosts_file, strerror(errno));
session->knownhosts, strerror(errno));
return -1;
}
@@ -1583,7 +1582,7 @@ int ssh_write_knownhost(ssh_session session) {
snprintf(buffer, sizeof(buffer),
"%s %d %s %s\n",
session->options->host,
session->host,
rsa_size << 3,
e_string,
n_string);
@@ -1608,7 +1607,7 @@ int ssh_write_knownhost(ssh_session session) {
snprintf(buffer, sizeof(buffer),
"%s %s %s\n",
session->options->host,
session->host,
session->current_crypto->server_pubkey_type,
pubkey_64);

View File

@@ -27,7 +27,6 @@
#include "libssh/priv.h"
#include "libssh/session.h"
#include "libssh/options.h"
/**
* @defgroup ssh_log SSH Logging
@@ -57,9 +56,9 @@ void ssh_log(ssh_session session, int verbosity, const char *format, ...) {
vsnprintf(buffer, sizeof(buffer), format, va);
va_end(va);
if (session->options->callbacks && session->options->callbacks->log_function) {
session->options->callbacks->log_function(session, verbosity, buffer,
session->options->callbacks->userdata);
if (session->callbacks && session->callbacks->log_function) {
session->callbacks->log_function(session, verbosity, buffer,
session->callbacks->userdata);
} else if (verbosity == SSH_LOG_FUNCTIONS) {
if (session->log_indent > 255) {
min = 255;

File diff suppressed because it is too large Load Diff

View File

@@ -45,7 +45,6 @@
#include "libssh/socket.h"
#include "libssh/channels.h"
#include "libssh/session.h"
#include "libssh/options.h"
#include "libssh/misc.h"
#include "libssh/keys.h"
#include "libssh/dh.h"
@@ -74,7 +73,7 @@ static char *hstrerror(int h_errno_val) {
#endif /* _WIN32 */
/* TODO FIXME: must use getaddrinfo */
static socket_t bind_socket(SSH_BIND *ssh_bind, const char *hostname,
static socket_t bind_socket(SSH_BIND *sshbind, const char *hostname,
int port) {
struct sockaddr_in myaddr;
struct hostent *hp=NULL;
@@ -83,7 +82,7 @@ static socket_t bind_socket(SSH_BIND *ssh_bind, const char *hostname,
s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
ssh_set_error(ssh_bind, SSH_FATAL, "%s", strerror(errno));
ssh_set_error(sshbind, SSH_FATAL, "%s", strerror(errno));
return -1;
}
@@ -92,7 +91,7 @@ static socket_t bind_socket(SSH_BIND *ssh_bind, const char *hostname,
#endif
if (hp == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL,
ssh_set_error(sshbind, SSH_FATAL,
"Resolving %s: %s", hostname, hstrerror(h_errno));
close(s);
return -1;
@@ -104,14 +103,14 @@ static socket_t bind_socket(SSH_BIND *ssh_bind, const char *hostname,
myaddr.sin_port = htons(port);
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
ssh_set_error(sshbind, SSH_FATAL,
"Setting socket options failed: %s", hstrerror(h_errno));
close(s);
return -1;
}
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
ssh_set_error(ssh_bind, SSH_FATAL, "Binding to %s:%d: %s",
ssh_set_error(sshbind, SSH_FATAL, "Binding to %s:%d: %s",
hostname,
port,
strerror(errno));
@@ -135,35 +134,27 @@ SSH_BIND *ssh_bind_new(void) {
return ptr;
}
void ssh_bind_set_options(SSH_BIND *ssh_bind, ssh_options options) {
ssh_bind->options = options;
}
int ssh_bind_listen(SSH_BIND *ssh_bind) {
int ssh_bind_listen(SSH_BIND *sshbind) {
const char *host;
int fd;
if (ssh_bind->options == NULL) {
return -1;
}
if (ssh_init() < 0) {
return -1;
}
host = ssh_bind->options->bindaddr;
host = sshbind->bindaddr;
if (host == NULL) {
host = "0.0.0.0";
}
fd = bind_socket(ssh_bind, host, ssh_bind->options->bindport);
fd = bind_socket(sshbind, host, sshbind->bindport);
if (fd < 0) {
return -1;
}
ssh_bind->bindfd = fd;
sshbind->bindfd = fd;
if (listen(fd, 10) < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
ssh_set_error(sshbind, SSH_FATAL,
"Listening to socket %d: %s",
fd, strerror(errno));
close(fd);
@@ -173,58 +164,59 @@ int ssh_bind_listen(SSH_BIND *ssh_bind) {
return 0;
}
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking) {
ssh_bind->blocking = blocking ? 1 : 0;
void ssh_bind_set_blocking(SSH_BIND *sshbind, int blocking) {
sshbind->blocking = blocking ? 1 : 0;
}
socket_t ssh_bind_get_fd(SSH_BIND *ssh_bind) {
return ssh_bind->bindfd;
socket_t ssh_bind_get_fd(SSH_BIND *sshbind) {
return sshbind->bindfd;
}
void ssh_bind_set_fd(SSH_BIND *ssh_bind, socket_t fd) {
ssh_bind->bindfd = fd;
void ssh_bind_set_fd(SSH_BIND *sshbind, socket_t fd) {
sshbind->bindfd = fd;
}
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind) {
ssh_bind->toaccept = 1;
void ssh_bind_fd_toaccept(SSH_BIND *sshbind) {
sshbind->toaccept = 1;
}
ssh_session ssh_bind_accept(SSH_BIND *ssh_bind) {
ssh_session ssh_bind_accept(SSH_BIND *sshbind) {
ssh_session session;
ssh_private_key dsa = NULL;
ssh_private_key rsa = NULL;
int fd = -1;
int i;
if (ssh_bind->bindfd < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
if (sshbind->bindfd < 0) {
ssh_set_error(sshbind, SSH_FATAL,
"Can't accept new clients on a not bound socket.");
return NULL;
}
if (ssh_bind->options->dsakey == NULL || ssh_bind->options->rsakey == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL,
if (sshbind->dsakey == NULL || sshbind->rsakey == NULL) {
ssh_set_error(sshbind, SSH_FATAL,
"DSA or RSA host key file must be set before accept()");
return NULL;
}
if (ssh_bind->options->dsakey) {
dsa = _privatekey_from_file(ssh_bind, ssh_bind->options->dsakey, TYPE_DSS);
if (sshbind->dsakey) {
dsa = _privatekey_from_file(sshbind, sshbind->dsakey, TYPE_DSS);
if (dsa == NULL) {
return NULL;
}
}
if (ssh_bind->options->rsakey) {
rsa = _privatekey_from_file(ssh_bind, ssh_bind->options->rsakey, TYPE_RSA);
if (sshbind->rsakey) {
rsa = _privatekey_from_file(sshbind, sshbind->rsakey, TYPE_RSA);
if (rsa == NULL) {
privatekey_free(dsa);
return NULL;
}
}
fd = accept(ssh_bind->bindfd, NULL, NULL);
fd = accept(sshbind->bindfd, NULL, NULL);
if (fd < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
ssh_set_error(sshbind, SSH_FATAL,
"Accepting a new connection: %s",
strerror(errno));
privatekey_free(dsa);
@@ -234,20 +226,41 @@ ssh_session ssh_bind_accept(SSH_BIND *ssh_bind) {
session = ssh_new();
if (session == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL, "Not enough space");
ssh_set_error(sshbind, SSH_FATAL, "Not enough space");
privatekey_free(dsa);
privatekey_free(rsa);
return NULL;
}
session->server = 1;
session->version = 2;
session->options = ssh_options_copy(ssh_bind->options);
if (session->options == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL, "No space left");
privatekey_free(dsa);
privatekey_free(rsa);
ssh_cleanup(session);
return NULL;
/* TODO: is wanted methods enough? */
#if 0
session->options = ssh_options_copy(sshbind->options);
#endif
/* copy options */
for (i = 0; i < 10; ++i) {
if (sshbind->wanted_methods[i]) {
session->wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
if (session->wanted_methods[i] == NULL) {
privatekey_free(dsa);
privatekey_free(rsa);
ssh_cleanup(session);
return NULL;
}
}
}
if (sshbind->bindaddr == NULL)
session->bindaddr = NULL;
else {
session->bindaddr = strdup(sshbind->bindaddr);
if (session->bindaddr == NULL) {
privatekey_free(dsa);
privatekey_free(rsa);
ssh_cleanup(session);
return NULL;
}
}
session->log_verbosity = session->options->log_verbosity;
ssh_socket_free(session->socket);
@@ -258,53 +271,74 @@ ssh_session ssh_bind_accept(SSH_BIND *ssh_bind) {
ssh_cleanup(session);
return NULL;
}
ssh_socket_set_fd(session->socket,fd);
ssh_socket_set_fd(session->socket, fd);
session->dsa_key = dsa;
session->rsa_key = rsa;
return session;
}
void ssh_bind_free(SSH_BIND *ssh_bind){
if (ssh_bind == NULL) {
void ssh_bind_free(SSH_BIND *sshbind){
int i;
if (sshbind == NULL) {
return;
}
if (ssh_bind->bindfd >= 0) {
close(ssh_bind->bindfd);
if (sshbind->bindfd >= 0) {
close(sshbind->bindfd);
}
ssh_bind->bindfd = -1;
if (ssh_bind->options) {
ssh_options_free(ssh_bind->options);
sshbind->bindfd = -1;
/* options */
SAFE_FREE(sshbind->banner);
SAFE_FREE(sshbind->dsakey);
SAFE_FREE(sshbind->rsakey);
SAFE_FREE(sshbind->bindaddr);
for (i = 0; i < 10; i++) {
if (sshbind->wanted_methods[i]) {
SAFE_FREE(sshbind->wanted_methods[i]);
}
}
SAFE_FREE(ssh_bind);
SAFE_FREE(sshbind);
}
extern char *supported_methods[];
/** @internal
* This functions sets the Key Exchange protocols to be accepted
* by the server. They depend on
* -What the user asked (via options)
* -What is available (keys)
* It should then accept the intersection of what the user asked
* and what is available, and return an error if nothing matches
* @bug To rewrite, it's broken !!
*/
static int server_set_kex(ssh_session session) {
static int server_set_kex(ssh_session session) {
KEX *server = &session->server_kex;
ssh_options options = session->options;
int i, j;
char *wanted;
ZERO_STRUCTP(server);
ssh_get_random(server->cookie, 16, 0);
#if 0
if (session->dsa_key != NULL && session->rsa_key != NULL) {
if (ssh_options_set(options, SSH_OPTIONS_SERVER_HOSTKEY,
if (ssh_bind_options_set(options, SSH_BIND_OPTIONS_HOSTKEY,
"ssh-dss,ssh-rsa") < 0) {
return -1;
}
} else if (session->dsa_key != NULL) {
if (ssh_options_set(options, SSH_OPTIONS_SERVER_HOSTKEY, "ssh-dss") < 0) {
if (ssh_bind_options_set(options, SSH_BIND_OPTIONS_HOSTKEY, "ssh-dss") < 0) {
return -1;
}
} else {
if (ssh_options_set(options, SSH_OPTIONS_SERVER_HOSTKEY, "ssh-rsa") < 0) {
if (ssh_bind_options_set(options, SSH_BIND_OPTIONS_HOSTKEY, "ssh-rsa") < 0) {
return -1;
}
}
#endif
server->methods = malloc(10 * sizeof(char **));
if (server->methods == NULL) {
@@ -312,7 +346,7 @@ static int server_set_kex(ssh_session session) {
}
for (i = 0; i < 10; i++) {
if ((wanted = options->wanted_methods[i]) == NULL) {
if ((wanted = session->wanted_methods[i]) == NULL) {
wanted = supported_methods[i];
}
server->methods[i] = strdup(wanted);

View File

@@ -27,12 +27,10 @@
#include "libssh/libssh.h"
#include "libssh/priv.h"
#include "libssh/server.h"
#include "libssh/callback.h"
#include "libssh/socket.h"
#include "libssh/agent.h"
#include "libssh/packet.h"
#include "libssh/session.h"
#include "libssh/options.h"
#include "libssh/misc.h"
#define FIRST_CHANNEL 42 // why not ? it helps to find bugs.
@@ -60,17 +58,11 @@ ssh_session ssh_new(void) {
goto err;
}
session->maxchannel = FIRST_CHANNEL;
session->socket = ssh_socket_new(session);
if (session->socket == NULL) {
goto err;
}
session->alive = 0;
session->auth_methods = 0;
session->blocking = 1;
session->log_indent = 0;
session->out_buffer = buffer_new();
if (session->out_buffer == NULL) {
goto err;
@@ -81,6 +73,22 @@ ssh_session ssh_new(void) {
goto err;
}
session->alive = 0;
session->auth_methods = 0;
session->blocking = 1;
session->log_indent = 0;
session->maxchannel = FIRST_CHANNEL;
/* options */
session->port = 22;
session->fd = -1;
session->ssh2 = 1;
#ifdef WITH_SSH1
session->ssh1 = 1;
#else
session->ssh1 = 0;
#endif
#ifndef _WIN32
session->agent = agent_new(session);
if (session->agent == NULL) {
@@ -142,12 +150,23 @@ void ssh_cleanup(ssh_session session) {
}
ssh_list_free(session->ssh_message_list);
}
ssh_options_free(session->options);
/* options */
SAFE_FREE(session->username);
SAFE_FREE(session->host);
SAFE_FREE(session->identity);
SAFE_FREE(session->sshdir);
SAFE_FREE(session->knownhosts);
for (i = 0; i < 10; i++) {
if (session->wanted_methods[i]) {
SAFE_FREE(session->wanted_methods[i]);
}
}
/* burn connection, it could hang sensitive datas */
ZERO_STRUCTP(session);
SAFE_FREE(session);
/* FIXME: leave_function(); ??? */
}
/** \brief disconnect impolitely from remote host
@@ -177,8 +196,7 @@ void ssh_set_options(ssh_session session, ssh_options options) {
return;
}
session->options = options;
session->log_verbosity = options->log_verbosity;
return;
}
/** \brief set the session in blocking/nonblocking mode