sample sshd server accepts a client and sends a banner.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@4 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
родитель
55846a4c7b
Коммит
636432e475
@ -300,6 +300,9 @@ struct ssh_kbdint {
|
||||
|
||||
void ssh_cleanup(SSH_SESSION *session);
|
||||
|
||||
/* client.c */
|
||||
|
||||
int ssh_send_banner(SSH_SESSION *session, int is_server);
|
||||
|
||||
/* errors.c */
|
||||
void ssh_set_error(void *error,int code,char *descr,...);
|
||||
|
@ -49,14 +49,14 @@ char *ssh_get_banner(SSH_SESSION *session){
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ssh_set_error(NULL,SSH_FATAL,"Too large banner");
|
||||
ssh_set_error(session,SSH_FATAL,"Too large banner");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2){
|
||||
char *banner=session->serverbanner;
|
||||
if(strncmp(banner,"SSH-",4)!=0){
|
||||
ssh_set_error(NULL,SSH_FATAL,"Protocol mismatch: %s",banner);
|
||||
ssh_set_error(session,SSH_FATAL,"Protocol mismatch: %s",banner);
|
||||
return -1;
|
||||
}
|
||||
/* a typical banner is :
|
||||
@ -77,7 +77,7 @@ int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2){
|
||||
*ssh2=1;
|
||||
break;
|
||||
default:
|
||||
ssh_set_error(NULL,SSH_FATAL,"Protocol mismatch: %s",banner);
|
||||
ssh_set_error(session,SSH_FATAL,"Protocol mismatch: %s",banner);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -88,15 +88,19 @@ int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2){
|
||||
/* switch SSH1/1.5/2 */
|
||||
/* and quit when the server is SSH1 only */
|
||||
|
||||
void ssh_send_banner(SSH_SESSION *session){
|
||||
char *banner;
|
||||
int ssh_send_banner(SSH_SESSION *session,int server){
|
||||
char *banner;
|
||||
char buffer[128];
|
||||
banner=session->version==1?CLIENTBANNER1:CLIENTBANNER2;
|
||||
if(session->options->banner)
|
||||
banner=session->options->banner;
|
||||
session->clientbanner=strdup(banner);
|
||||
snprintf(buffer,128,"%s\r\n",session->clientbanner);
|
||||
if(server)
|
||||
session->serverbanner=strdup(banner);
|
||||
else
|
||||
session->clientbanner=strdup(banner);
|
||||
snprintf(buffer,128,"%s\r\n",banner);
|
||||
write(session->fd,buffer,strlen(buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -114,19 +118,19 @@ int dh_handshake(SSH_SESSION *session){
|
||||
return -1;
|
||||
pubkey=buffer_get_ssh_string(session->in_buffer);
|
||||
if(!pubkey){
|
||||
ssh_set_error(NULL,SSH_FATAL,"No public key in packet");
|
||||
ssh_set_error(session,SSH_FATAL,"No public key in packet");
|
||||
return -1;
|
||||
}
|
||||
dh_import_pubkey(session,pubkey);
|
||||
f=buffer_get_ssh_string(session->in_buffer);
|
||||
if(!f){
|
||||
ssh_set_error(NULL,SSH_FATAL,"No F number in packet");
|
||||
ssh_set_error(session,SSH_FATAL,"No F number in packet");
|
||||
return -1;
|
||||
}
|
||||
dh_import_f(session,f);
|
||||
free(f);
|
||||
if(!(signature=buffer_get_ssh_string(session->in_buffer))){
|
||||
ssh_set_error(NULL,SSH_FATAL,"No signature in packet");
|
||||
ssh_set_error(session,SSH_FATAL,"No signature in packet");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -222,7 +226,7 @@ int ssh_connect(SSH_SESSION *session){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ssh_send_banner(session);
|
||||
ssh_send_banner(session,0);
|
||||
set_status(options,0.5);
|
||||
switch(session->version){
|
||||
case 2:
|
||||
|
@ -368,6 +368,7 @@ int ssh_options_getopt(SSH_OPTIONS *options, int *argcptr, char **argv){
|
||||
if(cont && localaddr)
|
||||
ssh_options_set_bind(options,localaddr,0);
|
||||
ssh_options_set_port(options,port);
|
||||
options->bindport=port;
|
||||
if(ssh1){
|
||||
ssh_options_allow_ssh1(options,1);
|
||||
ssh_options_allow_ssh2(options,0);
|
||||
|
@ -35,7 +35,7 @@ MA 02111-1307, USA. */
|
||||
#include <string.h>
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/server.h"
|
||||
static int bind_socket(char *hostname, int port) {
|
||||
static int bind_socket(SSH_BIND *ssh_bind,char *hostname, int port) {
|
||||
struct sockaddr_in myaddr;
|
||||
int opt = 1;
|
||||
int s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
@ -48,6 +48,7 @@ static int bind_socket(char *hostname, int port) {
|
||||
hp=gethostbyname(hostname);
|
||||
#endif
|
||||
if(!hp){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"resolving %s: %s",hostname,hstrerror(h_errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
@ -58,6 +59,8 @@ static int bind_socket(char *hostname, int port) {
|
||||
myaddr.sin_port = htons(port);
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"Binding to %s:%d : %s",hostname,port,
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
@ -83,11 +86,13 @@ int ssh_bind_listen(SSH_BIND *ssh_bind){
|
||||
host=ssh_bind->options->bindaddr;
|
||||
if(!host)
|
||||
host="0.0.0.0";
|
||||
fd=bind_socket(host,ssh_bind->options->bindport);
|
||||
fd=bind_socket(ssh_bind,host,ssh_bind->options->bindport);
|
||||
if(fd<0)
|
||||
return -1;
|
||||
ssh_bind->bindfd=fd;
|
||||
if(listen(fd,10)<0){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"listening to socket %d: %s",
|
||||
fd,strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
@ -108,41 +113,30 @@ void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind){
|
||||
|
||||
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind){
|
||||
SSH_SESSION *session;
|
||||
if(ssh_bind->bindfd<0)
|
||||
if(ssh_bind->bindfd<0){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"Can't accept new clients on a "
|
||||
"not bound socket.");
|
||||
return NULL;
|
||||
}
|
||||
int fd=accept(ssh_bind->bindfd,NULL,NULL);
|
||||
if(fd<0)
|
||||
if(fd<0){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"Accepting a new connection: %s",
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
session=ssh_new(ssh_options_copy(ssh_bind->options));
|
||||
session->server=1;
|
||||
session->fd=fd;
|
||||
return session;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
SSH_SESSION *getserver(SSH_OPTIONS * options) {
|
||||
int socket;
|
||||
int fd;
|
||||
SSH_SESSION *session;
|
||||
socket = bind_socket();
|
||||
if (socket < 0)
|
||||
return NULL;
|
||||
if (listen_socket(socket) < 0)
|
||||
return NULL;
|
||||
fd = accept_socket(socket);
|
||||
close(socket);
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
session = malloc(sizeof(SSH_SESSION));
|
||||
memset(session, 0, sizeof(SSH_SESSION));
|
||||
session->fd = fd;
|
||||
session->options = options;
|
||||
ssh_send_banner(session);
|
||||
return session;
|
||||
/* do the banner and key exchange */
|
||||
int ssh_accept(SSH_SESSION *session){
|
||||
ssh_send_banner(session,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
extern char *supported_methods[];
|
||||
int server_set_kex(SSH_SESSION * session) {
|
||||
KEX *server = &session->server_kex;
|
||||
|
27
samplesshd.c
27
samplesshd.c
@ -24,13 +24,26 @@ MA 02111-1307, USA. */
|
||||
#include <libssh/server.h>
|
||||
#include <unistd.h>
|
||||
int main(int argc, char **argv){
|
||||
#ifdef WITH_SERVER
|
||||
SSH_OPTIONS *opts=ssh_getopt(&argc,argv);
|
||||
SSH_SESSION *server=getserver(opts);
|
||||
if(!server){
|
||||
printf("pwned : %s\n",ssh_get_error(NULL));
|
||||
exit(-1);
|
||||
SSH_OPTIONS *options=ssh_options_new();
|
||||
SSH_SESSION *session;
|
||||
SSH_BIND *ssh_bind;
|
||||
ssh_options_getopt(options,&argc,argv);
|
||||
ssh_bind=ssh_bind_new();
|
||||
ssh_bind_set_options(ssh_bind,options);
|
||||
if(ssh_bind_listen(ssh_bind)<0){
|
||||
printf("Error listening to socket: %s\n",ssh_get_error(ssh_bind));
|
||||
return 1;
|
||||
}
|
||||
session=ssh_bind_accept(ssh_bind);
|
||||
if(!session){
|
||||
printf("error accepting a connection : %s\n",ssh_get_error(ssh_bind));
|
||||
return 1;
|
||||
}
|
||||
printf("Socket connecté : %d\n",ssh_get_fd(session));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
server->clientbanner=ssh_get_banner(server);
|
||||
if(!server->clientbanner){
|
||||
printf("%s\n",ssh_get_error(NULL));
|
||||
@ -45,6 +58,6 @@ int main(int argc, char **argv){
|
||||
list_kex(&server->client_kex);
|
||||
|
||||
while(1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user