1
1

Add error checking to SSHv1 auth functions.

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@427 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
Andreas Schneider 2009-04-08 10:45:30 +00:00
родитель 4f6fd0c451
Коммит 83f481981d

Просмотреть файл

@ -23,57 +23,76 @@
* vim: ts=2 sw=2 et cindent * vim: ts=2 sw=2 et cindent
*/ */
#include "libssh/priv.h"
#include "libssh/ssh1.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
/* #include "libssh/priv.h"
static void burn(char *ptr){ #include "libssh/ssh1.h"
if(ptr)
memset(ptr,'X',strlen(ptr));
}
*/
#ifdef HAVE_SSH1 #ifdef HAVE_SSH1
static int wait_auth1_status(SSH_SESSION *session) { static int wait_auth1_status(SSH_SESSION *session) {
/* wait for a packet */ /* wait for a packet */
if(packet_read(session)) if (packet_read(session)) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
if(packet_translate(session)) }
if(packet_translate(session)) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
}
switch(session->in_packet.type) { switch(session->in_packet.type) {
case SSH_SMSG_SUCCESS: case SSH_SMSG_SUCCESS:
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
case SSH_SMSG_FAILURE: case SSH_SMSG_FAILURE:
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
ssh_set_error(session, SSH_FATAL, "Was waiting for a SUCCESS or " ssh_set_error(session, SSH_FATAL, "Was waiting for a SUCCESS or "
"FAILURE, got %d", session->in_packet.type); "FAILURE, got %d", session->in_packet.type);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
static int send_username(SSH_SESSION *session, const char *username) { static int send_username(SSH_SESSION *session, const char *username) {
STRING *user; STRING *user = NULL;
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */ /* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
if(session->auth_service_asked) if(session->auth_service_asked) {
return session->auth_service_asked; return session->auth_service_asked;
buffer_add_u8(session->out_buffer,SSH_CMSG_USER); }
if(!username)
if (!username) {
if(!(username = session->options->username)) { if(!(username = session->options->username)) {
if(ssh_options_default_username(session->options)) if(ssh_options_default_username(session->options)) {
return session->auth_service_asked = SSH_AUTH_ERROR; return session->auth_service_asked = SSH_AUTH_ERROR;
else } else {
username = session->options->username; username = session->options->username;
} }
}
}
user = string_from_char(username); user = string_from_char(username);
buffer_add_ssh_string(session->out_buffer,user); if (user == NULL) {
free(user); return SSH_AUTH_ERROR;
packet_send(session); }
if (buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) {
string_free(user);
return SSH_AUTH_ERROR;
}
if (buffer_add_ssh_string(session->out_buffer, user) < 0) {
string_free(user);
return SSH_AUTH_ERROR;
}
string_free(user);
if (packet_send(session) != SSH_OK) {
return SSH_AUTH_ERROR;
}
session->auth_service_asked = wait_auth1_status(session); session->auth_service_asked = wait_auth1_status(session);
return session->auth_service_asked; return session->auth_service_asked;
} }
/* use the "none" authentication question */ /* use the "none" authentication question */
int ssh_userauth1_none(SSH_SESSION *session, const char *username){ int ssh_userauth1_none(SSH_SESSION *session, const char *username){
return send_username(session, username); return send_username(session, username);
} }
@ -119,8 +138,8 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,int type, STR
/** \internal /** \internal
* \todo implement ssh1 public key * \todo implement ssh1 public key
*/ */
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username, int type, int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
STRING *pubkey){ int type, STRING *pubkey) {
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
@ -171,21 +190,29 @@ int ssh_userauth_pubkey(SSH_SESSION *session, char *username, STRING *publickey,
} }
*/ */
int ssh_userauth1_password(SSH_SESSION *session,const char *username,const char *password){ int ssh_userauth1_password(SSH_SESSION *session, const char *username,
STRING *password_s; const char *password) {
int err; STRING *pwd = NULL;
err=send_username(session,username); int rc;
if(err!=SSH_AUTH_DENIED)
return err; rc = send_username(session, username);
if (rc != SSH_AUTH_DENIED) {
return rc;
}
/* we trick a bit here. A known flaw in SSH1 protocol is that it's /* we trick a bit here. A known flaw in SSH1 protocol is that it's
* easy to guess password sizes. * easy to guess password sizes.
* not that sure ... * not that sure ...
*/ */
/* XXX fix me here ! */ /* XXX fix me here ! */
/* cisco IOS doesn't like when a password is followed by zeroes and random pad. */ /* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
if(1 || strlen(password) >= 128) { if(1 || strlen(password) >= 128) {
/* not risky to disclose the size of such a big password .. */ /* not risky to disclose the size of such a big password .. */
password_s=string_from_char(password); pwd = string_from_char(password);
if (pwd == NULL) {
return SSH_AUTH_ERROR;
}
} else { } else {
/* fill the password string from random things. the strcpy /* fill the password string from random things. the strcpy
* ensure there is at least a nul byte after the password. * ensure there is at least a nul byte after the password.
@ -193,16 +220,32 @@ int ssh_userauth1_password(SSH_SESSION *session,const char *username,const char
* why garbage ? because nul bytes will be compressed by * why garbage ? because nul bytes will be compressed by
* gzip and disclose password len. * gzip and disclose password len.
*/ */
password_s=string_new(128); pwd = string_new(128);
ssh_get_random(password_s->string,128,0); if (pwd == NULL) {
strcpy((char *)password_s->string,password); return SSH_AUTH_ERROR;
}
ssh_get_random( pwd->string, 128, 0);
strcpy((char *) pwd->string, password);
}
if (buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) {
string_burn(pwd);
string_free(pwd);
return SSH_AUTH_ERROR;
}
if (buffer_add_ssh_string(session->out_buffer, pwd) < 0) {
string_burn(pwd);
string_free(pwd);
return SSH_AUTH_ERROR;
}
string_burn(pwd);
string_free(pwd);
if (packet_send(session) != SSH_OK) {
return SSH_AUTH_ERROR;
} }
buffer_add_u8(session->out_buffer,SSH_CMSG_AUTH_PASSWORD);
buffer_add_ssh_string(session->out_buffer,password_s);
string_burn(password_s);
free(password_s);
packet_send(session);
return wait_auth1_status(session); return wait_auth1_status(session);
} }