mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-06 18:29:50 +09:00
patches from Norbert merged in. I have made some little changes here and there.
It still doesn't compile because of the O1 thing passed to ld. git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@41 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
@@ -311,11 +311,15 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
||||
free(id);
|
||||
}
|
||||
free(pubkey);
|
||||
free(privkeyfile);
|
||||
return err;
|
||||
} else
|
||||
if(err != SSH_AUTH_SUCCESS){
|
||||
ssh_say(2,"Public key refused by server\n");
|
||||
free(pubkey);
|
||||
pubkey=NULL;
|
||||
free(privkeyfile);
|
||||
privkeyfile=NULL;
|
||||
continue;
|
||||
}
|
||||
/* pubkey accepted by server ! */
|
||||
@@ -323,6 +327,9 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
||||
if(!privkey){
|
||||
ssh_say(0,"Reading private key %s failed (bad passphrase ?)\n",privkeyfile);
|
||||
free(pubkey);
|
||||
pubkey=NULL;
|
||||
free(privkeyfile);
|
||||
privkeyfile=NULL;
|
||||
continue; /* continue the loop with other pubkey */
|
||||
}
|
||||
err=ssh_userauth_pubkey(session,NULL,pubkey,privkey);
|
||||
@@ -333,12 +340,16 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
||||
free(id);
|
||||
}
|
||||
free(pubkey);
|
||||
free(privkeyfile);
|
||||
private_key_free(privkey);
|
||||
return err;
|
||||
} else
|
||||
if(err != SSH_AUTH_SUCCESS){
|
||||
ssh_say(0,"Weird : server accepted our public key but refused the signature\nit might be a bug of libssh\n");
|
||||
free(pubkey);
|
||||
pubkey=NULL;
|
||||
free(privkeyfile);
|
||||
privkeyfile=NULL;
|
||||
private_key_free(privkey);
|
||||
continue;
|
||||
}
|
||||
@@ -354,6 +365,7 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
||||
}
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
/* at this point, pubkey is NULL and so is privkeyfile */
|
||||
ssh_say(1,"Tried every public key, none matched\n");
|
||||
ssh_set_error(session,SSH_NO_ERROR,"no public key matched");
|
||||
if(id){
|
||||
|
||||
@@ -176,7 +176,9 @@ int ssh_userauth1_password(SSH_SESSION *session,char *username,char *password){
|
||||
* easy to guess password sizes.
|
||||
* not that sure ...
|
||||
*/
|
||||
if(strlen(password)>=128){
|
||||
/* XXX fix me here ! */
|
||||
/* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
|
||||
if(strlen(password)>=0){
|
||||
/* not risky to disclose the size of such a big password .. */
|
||||
password_s=string_from_char(password);
|
||||
} else {
|
||||
|
||||
@@ -474,11 +474,11 @@ int channel_write(CHANNEL *channel ,void *data,int len){
|
||||
}
|
||||
|
||||
int channel_is_open(CHANNEL *channel){
|
||||
return (channel->open!=0);
|
||||
return (channel->open!=0 && channel->session->alive);
|
||||
}
|
||||
|
||||
int channel_is_closed(CHANNEL *channel){
|
||||
return (channel->open==0);
|
||||
return (channel->open==0 || !channel->session->alive);
|
||||
}
|
||||
|
||||
int channel_is_eof(CHANNEL *channel){
|
||||
@@ -749,7 +749,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL *
|
||||
++j;
|
||||
}
|
||||
}
|
||||
wout[j]=NULL;
|
||||
eout[j]=NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
118
libssh/connect.c
118
libssh/connect.c
@@ -22,6 +22,7 @@ MA 02111-1307, USA. */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
@@ -33,11 +34,6 @@ MA 02111-1307, USA. */
|
||||
#include <fcntl.h>
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME
|
||||
#ifndef HAVE_GETHOSTBYADDR
|
||||
#error "your system doesn't have gethostbyname nor gethostbyaddr"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HAVE_SELECT
|
||||
#error "Your system must have select()"
|
||||
#endif
|
||||
@@ -49,71 +45,67 @@ static void sock_set_blocking(int sock){
|
||||
fcntl(sock,F_SETFL,0);
|
||||
}
|
||||
|
||||
static int getai(const char *host, int port, struct addrinfo **ai)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
char *service=NULL;
|
||||
char s_port[10];
|
||||
|
||||
memset(&hints,0,sizeof(hints));
|
||||
hints.ai_protocol=IPPROTO_TCP;
|
||||
hints.ai_socktype=SOCK_STREAM;
|
||||
if(port==0){
|
||||
hints.ai_flags=AI_PASSIVE;
|
||||
} else {
|
||||
snprintf(s_port,sizeof(s_port),"%hu",port);
|
||||
service=s_port;
|
||||
}
|
||||
return getaddrinfo(host,service,&hints,ai);
|
||||
}
|
||||
|
||||
/* connect_host connects to an IPv4 (or IPv6) host */
|
||||
/* specified by its IP address or hostname. */
|
||||
/* output is the file descriptor, <0 if failed. */
|
||||
|
||||
int ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
||||
*bind_addr, int port,long timeout, long usec){
|
||||
struct sockaddr_in sa;
|
||||
struct sockaddr_in bindsa;
|
||||
struct hostent *hp=NULL;
|
||||
static int count=0; /* for reentrencity */
|
||||
int s;
|
||||
while(++count>1)
|
||||
--count;
|
||||
int my_errno;
|
||||
struct addrinfo *ai;
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME
|
||||
hp=gethostbyname(host);
|
||||
#endif
|
||||
if(!hp){
|
||||
--count;
|
||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,hstrerror(h_errno));
|
||||
my_errno=getai(host, port, &ai);
|
||||
if (my_errno){
|
||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%d)",host,my_errno);
|
||||
return -1;
|
||||
}
|
||||
memset(&sa,0,sizeof(sa));
|
||||
memcpy(&sa.sin_addr,hp->h_addr,hp->h_length);
|
||||
sa.sin_family=hp->h_addrtype;
|
||||
sa.sin_port=htons((unsigned short)port);
|
||||
--count;
|
||||
|
||||
if(bind_addr){
|
||||
ssh_say(2,"resolving %s\n",bind_addr);
|
||||
hp=NULL;
|
||||
while(++count>1)
|
||||
--count;
|
||||
#ifdef HAVE_GETHOSTBYADDR
|
||||
hp=gethostbyaddr(bind_addr,4,AF_INET);
|
||||
#endif
|
||||
#ifdef HAVE_GETHOSTBYNAME
|
||||
if(!hp)
|
||||
hp=gethostbyname(bind_addr);
|
||||
#endif
|
||||
if(!hp){
|
||||
--count;
|
||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,hstrerror(h_errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
memset(&bindsa,0,sizeof(bindsa));
|
||||
/* create socket */
|
||||
s=socket(sa.sin_family,SOCK_STREAM,0);
|
||||
s=socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol);
|
||||
if(s<0){
|
||||
if(bind_addr)
|
||||
--count;
|
||||
ssh_set_error(session,SSH_FATAL,"socket : %s",strerror(errno));
|
||||
freeaddrinfo(ai);
|
||||
return s;
|
||||
}
|
||||
|
||||
if(bind_addr){
|
||||
memcpy(&bindsa.sin_addr,hp->h_addr,hp->h_length);
|
||||
bindsa.sin_family=hp->h_addrtype;
|
||||
--count;
|
||||
if(bind(s,(struct sockaddr *)&bindsa,sizeof(bindsa))<0){
|
||||
struct addrinfo *bind_ai;
|
||||
|
||||
ssh_say(2,"resolving %s\n",bind_addr);
|
||||
my_errno=getai(host,0,&bind_ai);
|
||||
if (my_errno){
|
||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%d)",bind_addr,my_errno);
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(bind(s,bind_ai->ai_addr,bind_ai->ai_addrlen)<0){
|
||||
ssh_set_error(session,SSH_FATAL,"Binding local address : %s",strerror(errno));
|
||||
freeaddrinfo(ai);
|
||||
freeaddrinfo(bind_ai);
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
freeaddrinfo(bind_ai);
|
||||
}
|
||||
if(timeout){
|
||||
struct timeval to;
|
||||
@@ -123,7 +115,8 @@ int ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
||||
to.tv_sec=timeout;
|
||||
to.tv_usec=usec;
|
||||
sock_set_nonblocking(s);
|
||||
connect(s,(struct sockaddr* )&sa,sizeof(sa));
|
||||
connect(s,ai->ai_addr,ai->ai_addrlen);
|
||||
freeaddrinfo(ai);
|
||||
FD_ZERO(&set);
|
||||
FD_SET(s,&set);
|
||||
ret=select(s+1,NULL,&set,NULL,&to);
|
||||
@@ -150,11 +143,12 @@ int ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
||||
sock_set_blocking(s);
|
||||
return s;
|
||||
}
|
||||
if(connect(s,(struct sockaddr *)&sa,sizeof(sa))< 0){
|
||||
close(s);
|
||||
if(connect(s,ai->ai_addr,ai->ai_addrlen)<0){
|
||||
ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
|
||||
return -1;
|
||||
close(s);
|
||||
s=-1;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -220,13 +214,15 @@ int ssh_select(CHANNEL **channels,CHANNEL **outchannels, int maxfd, fd_set *read
|
||||
j=0;
|
||||
// polls every channel.
|
||||
for(i=0;channels[i];i++){
|
||||
if(channel_poll(channels[i],0)>0){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
} else
|
||||
if(channel_poll(channels[i],1)>0){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
if(channels[i]->session->alive){
|
||||
if(channel_poll(channels[i],0)>0){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
} else
|
||||
if(channel_poll(channels[i],1)>0){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
outchannels[j]=NULL;
|
||||
@@ -261,13 +257,13 @@ int ssh_select(CHANNEL **channels,CHANNEL **outchannels, int maxfd, fd_set *read
|
||||
}
|
||||
/* set the data_to_read flag on each session */
|
||||
for(i=0;channels[i];i++)
|
||||
if(FD_ISSET(channels[i]->session->fd,&localset))
|
||||
if(channels[i]->session->alive && FD_ISSET(channels[i]->session->fd,&localset))
|
||||
channels[i]->session->data_to_read=1;
|
||||
|
||||
/* now, test each channel */
|
||||
j=0;
|
||||
for(i=0;channels[i];i++){
|
||||
if(FD_ISSET(channels[i]->session->fd,&localset))
|
||||
if(channels[i]->session->alive && FD_ISSET(channels[i]->session->fd,&localset))
|
||||
if((channel_poll(channels[i],0)>0) || (channel_poll(channels[i],1)>0)){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
|
||||
@@ -3,7 +3,8 @@ SSH_0.2 {
|
||||
ssh_get_error; ssh_get_error_code; ssh_say; ssh_set_verbosity;
|
||||
ssh_new; ssh_set_options; ssh_get_fd; ssh_silent_disconnect;
|
||||
ssh_connect; ssh_disconnect; ssh_service_request; ssh_get_issue_banner;
|
||||
ssh_copyright;
|
||||
ssh_copyright; ssh_get_version;
|
||||
ssh_set_fd_toread; ssh_set_fd_towrite; ssh_set_fd_except;
|
||||
string_from_char; string_len; string_new; string_fill; string_to_char;
|
||||
string_copy; string_burn; string_data;
|
||||
ssh_crypto_init;
|
||||
@@ -19,6 +20,7 @@ SSH_0.2 {
|
||||
channel_request_exec; channel_request_sftp; channel_write;
|
||||
channel_send_eof; channel_read; channel_poll; channel_close;
|
||||
channel_read_nonblocking; channel_is_open;
|
||||
channel_is_closed; channel_is_eof; channel_select;
|
||||
ssh_options_new; ssh_options_copy; ssh_options_set_wanted_algos;
|
||||
ssh_options_set_username; ssh_options_set_port; ssh_options_getopt;
|
||||
ssh_options_set_host; ssh_options_set_fd; ssh_options_set_bind;
|
||||
|
||||
@@ -138,3 +138,6 @@ const char *ssh_get_disconnect_message(SSH_SESSION *session){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ssh_get_version(SSH_SESSION *session){
|
||||
return session->version;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user