diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/CMakeLists.txt | 16 | ||||
-rw-r--r-- | examples/sample.c | 669 | ||||
-rw-r--r-- | examples/samplesshd.c | 152 |
3 files changed, 837 insertions, 0 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3dbf6151..ddc95a77 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -8,6 +8,7 @@ set(examples_SRCS include_directories( ${LIBSSH_PUBLIC_INCLUDE_DIRS} + ${LIBSSH_PRIVATE_INCLUDE_DIRS} ) add_executable(libssh_scp libssh_scp.c ${examples_SRCS}) @@ -16,3 +17,18 @@ add_executable(scp_download scp_download.c ${examples_SRCS}) target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY}) +include_directories( + ${LIBSSH_PUBLIC_INCLUDE_DIRS} + ${LIBSSH_PRIVATE_INCLUDE_DIRS} +) + +if (WITH_SFTP) + add_executable(samplessh sample.c) + target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY}) +endif (WITH_SFTP) + +if (WITH_SERVER) + add_executable(samplesshd samplesshd.c) + target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY}) +endif (WITH_SERVER) + diff --git a/examples/sample.c b/examples/sample.c new file mode 100644 index 00000000..c2aaa66e --- /dev/null +++ b/examples/sample.c @@ -0,0 +1,669 @@ +/* client.c */ +/* +Copyright 2003-2009 Aris Adamantiadis + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +The goal is to show the API in action. It's not a reference on how terminal +clients must be made or how a client should react. +*/ + +#include "config.h" +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> + +#include <sys/select.h> +#include <sys/time.h> +#include <sys/statvfs.h> +#ifdef HAVE_PTY_H +#include <pty.h> +#endif +#include <sys/ioctl.h> +#include <signal.h> +#include <errno.h> +#include <libssh/libssh.h> +#include <libssh/sftp.h> + +#include <fcntl.h> + +#define MAXCMD 10 +char *host; +char *user; +int sftp; +char *cmds[MAXCMD]; +struct termios terminal; +void do_sftp(ssh_session session); + +static void add_cmd(char *cmd){ + int n; + for(n=0;cmds[n] && (n<MAXCMD);n++); + if(n==MAXCMD) + return; + cmds[n]=strdup(cmd); +} + +static void usage(){ + fprintf(stderr,"Usage : ssh [options] [login@]hostname\n" + "sample client - libssh-%s\n" + "Options :\n" + " -l user : log in as user\n" + " -p port : connect to port\n" + " -d : use DSS to verify host public key\n" + " -r : use RSA to verify host public key\n", + ssh_version(0)); + exit(0); +} + +static int opts(int argc, char **argv){ + int i; + if(strstr(argv[0],"sftp")) + sftp=1; +// for(i=0;i<argc;i++) +// printf("%d : %s\n",i,argv[i]); + /* insert your own arguments here */ + while((i=getopt(argc,argv,""))!=-1){ + switch(i){ + default: + fprintf(stderr,"unknown option %c\n",optopt); + usage(); + } + } + if(optind < argc) + host=argv[optind++]; + while(optind < argc) + add_cmd(argv[optind++]); + if(host==NULL) + usage(); + return 0; +} + +#ifndef HAVE_CFMAKERAW +static void cfmakeraw(struct termios *termios_p){ + termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + termios_p->c_oflag &= ~OPOST; + termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + termios_p->c_cflag &= ~(CSIZE|PARENB); + termios_p->c_cflag |= CS8; +} +#endif + + +static void do_cleanup(int i) { + /* unused variable */ + (void) i; + + tcsetattr(0,TCSANOW,&terminal); +} + +static void do_exit(int i) { + /* unused variable */ + (void) i; + + do_cleanup(0); + exit(0); +} + +ssh_channel chan; +int signal_delayed=0; + +static void sigwindowchanged(int i){ + (void) i; + signal_delayed=1; +} + +static void setsignal(void){ + signal(SIGWINCH, sigwindowchanged); + signal_delayed=0; +} + +static void sizechanged(void){ + struct winsize win = { 0, 0, 0, 0 }; + ioctl(1, TIOCGWINSZ, &win); + channel_change_pty_size(chan,win.ws_col, win.ws_row); +// printf("Changed pty size\n"); + setsignal(); +} +static void select_loop(ssh_session session,ssh_channel channel){ + fd_set fds; + struct timeval timeout; + char buffer[10]; + ssh_buffer readbuf=buffer_new(); + ssh_channel channels[2]; + int lus; + int eof=0; + int maxfd; + int ret; + while(channel){ + /* when a signal is caught, ssh_select will return + * with SSH_EINTR, which means it should be started + * again. It lets you handle the signal the faster you + * can, like in this window changed example. Of course, if + * your signal handler doesn't call libssh at all, you're + * free to handle signals directly in sighandler. + */ + do{ + FD_ZERO(&fds); + if(!eof) + FD_SET(0,&fds); + timeout.tv_sec=30; + timeout.tv_usec=0; + FD_SET(ssh_get_fd(session),&fds); + maxfd=ssh_get_fd(session)+1; + ret=select(maxfd,&fds,NULL,NULL,&timeout); + if(ret==EINTR) + continue; + if(FD_ISSET(0,&fds)){ + lus=read(0,buffer,10); + if(lus) + channel_write(channel,buffer,lus); + else { + eof=1; + channel_send_eof(channel); + } + } + if(FD_ISSET(ssh_get_fd(session),&fds)){ + ssh_set_fd_toread(session); + } + channels[0]=channel; // set the first channel we want to read from + channels[1]=NULL; + ret=channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll + if(signal_delayed) + sizechanged(); + } while (ret==EINTR || ret==SSH_EINTR); + + // we already looked for input from stdin. Now, we are looking for input from the channel + + if(channel && channel_is_closed(channel)){ + ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel)); + + channel_free(channel); + channel=NULL; + channels[0]=NULL; + } + if(channels[0]){ + while(channel && channel_is_open(channel) && channel_poll(channel,0)){ + lus=channel_read_buffer(channel,readbuf,0,0); + if(lus==-1){ + fprintf(stderr, "Error reading channel: %s\n", + ssh_get_error(session)); + return; + } + if(lus==0){ + ssh_log(session,SSH_LOG_RARE,"EOF received\n"); + ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel)); + + channel_free(channel); + channel=channels[0]=NULL; + } else + write(1,buffer_get(readbuf),lus); + } + while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */ + lus=channel_read_buffer(channel,readbuf,0,1); + if(lus==-1){ + fprintf(stderr, "Error reading channel: %s\n", + ssh_get_error(session)); + return; + } + if(lus==0){ + ssh_log(session,SSH_LOG_RARE,"EOF received\n"); + ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel)); + channel_free(channel); + channel=channels[0]=NULL; + } else + write(2,buffer_get(readbuf),lus); + } + } + if(channel && channel_is_closed(channel)){ + channel_free(channel); + channel=NULL; + } + } + buffer_free(readbuf); +} + + +static void shell(ssh_session session){ + ssh_channel channel; + struct termios terminal_local; + int interactive=isatty(0); + channel = channel_new(session); + if(interactive){ + tcgetattr(0,&terminal_local); + memcpy(&terminal,&terminal_local,sizeof(struct termios)); + } + if(channel_open_session(channel)){ + printf("error opening channel : %s\n",ssh_get_error(session)); + return; + } + chan=channel; + if(interactive){ + channel_request_pty(channel); + sizechanged(); + } + if(channel_request_shell(channel)){ + printf("Requesting shell : %s\n",ssh_get_error(session)); + return; + } + if(interactive){ + cfmakeraw(&terminal_local); + tcsetattr(0,TCSANOW,&terminal_local); + setsignal(); + } + signal(SIGTERM,do_cleanup); + select_loop(session,channel); +} + +static void batch_shell(ssh_session session){ + ssh_channel channel; + char buffer[1024]; + int i,s=0; + for(i=0;i<MAXCMD && cmds[i];++i) + s+=snprintf(buffer+s,sizeof(buffer)-s,"%s ",cmds[i]); + channel=channel_new(session); + channel_open_session(channel); + if(channel_request_exec(channel,buffer)){ + printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session)); + return; + } + select_loop(session,channel); +} + +#ifdef WITH_SFTP +/* it's just a proof of concept code for sftp, till i write a real documentation about it */ +void do_sftp(ssh_session session){ + SFTP_SESSION *sftp_session=sftp_new(session); + SFTP_DIR *dir; + SFTP_ATTRIBUTES *file; + SFTP_STATVFS *sftpstatvfs; + struct statvfs sysstatvfs; + SFTP_FILE *fichier; + SFTP_FILE *to; + int len=1; + unsigned int i; + char data[8000]={0}; + char *lnk; + + unsigned int count; + + if(!sftp_session){ + fprintf(stderr, "sftp error initialising channel: %s\n", + ssh_get_error(session)); + return; + } + if(sftp_init(sftp_session)){ + fprintf(stderr, "error initialising sftp: %s\n", + ssh_get_error(session)); + return; + } + + printf("Additional SFTP extensions provided by the server:\n"); + count = sftp_extensions_get_count(sftp_session); + for (i = 0; i < count; i++) { + printf("\t%s, version: %s\n", + sftp_extensions_get_name(sftp_session, i), + sftp_extensions_get_data(sftp_session, i)); + } + + /* test symlink and readlink */ + if (sftp_symlink(sftp_session, "/tmp/this_is_the_link", + "/tmp/sftp_symlink_test") < 0) { + fprintf(stderr, "Could not create link (%s)\n", ssh_get_error(session)); + return; + } + + lnk = sftp_readlink(sftp_session, "/tmp/sftp_symlink_test"); + if (lnk == NULL) { + fprintf(stderr, "Could not read link (%s)\n", ssh_get_error(session)); + return; + } + printf("readlink /tmp/sftp_symlink_test: %s\n", lnk); + + sftp_unlink(sftp_session, "/tmp/sftp_symlink_test"); + + if (sftp_extension_supported(sftp_session, "statvfs@openssh.com", "2")) { + sftpstatvfs = sftp_statvfs(sftp_session, "/tmp"); + if (sftpstatvfs == NULL) { + fprintf(stderr, "statvfs failed (%s)\n", ssh_get_error(session)); + return; + } + + printf("sftp statvfs:\n" + "\tfile system block size: %llu\n" + "\tfundamental fs block size: %llu\n" + "\tnumber of blocks (unit f_frsize): %llu\n" + "\tfree blocks in file system: %llu\n" + "\tfree blocks for non-root: %llu\n" + "\ttotal file inodes: %llu\n" + "\tfree file inodes: %llu\n" + "\tfree file inodes for to non-root: %llu\n" + "\tfile system id: %llu\n" + "\tbit mask of f_flag values: %llu\n" + "\tmaximum filename length: %llu\n", + (unsigned long long) sftpstatvfs->f_bsize, + (unsigned long long) sftpstatvfs->f_frsize, + (unsigned long long) sftpstatvfs->f_blocks, + (unsigned long long) sftpstatvfs->f_bfree, + (unsigned long long) sftpstatvfs->f_bavail, + (unsigned long long) sftpstatvfs->f_files, + (unsigned long long) sftpstatvfs->f_ffree, + (unsigned long long) sftpstatvfs->f_favail, + (unsigned long long) sftpstatvfs->f_fsid, + (unsigned long long) sftpstatvfs->f_flag, + (unsigned long long) sftpstatvfs->f_namemax); + + sftp_statvfs_free(sftpstatvfs); + + if (statvfs("/tmp", &sysstatvfs) < 0) { + fprintf(stderr, "statvfs failed (%s)\n", strerror(errno)); + return; + } + + printf("sys statvfs:\n" + "\tfile system block size: %llu\n" + "\tfundamental fs block size: %llu\n" + "\tnumber of blocks (unit f_frsize): %llu\n" + "\tfree blocks in file system: %llu\n" + "\tfree blocks for non-root: %llu\n" + "\ttotal file inodes: %llu\n" + "\tfree file inodes: %llu\n" + "\tfree file inodes for to non-root: %llu\n" + "\tfile system id: %llu\n" + "\tbit mask of f_flag values: %llu\n" + "\tmaximum filename length: %llu\n", + (unsigned long long) sysstatvfs.f_bsize, + (unsigned long long) sysstatvfs.f_frsize, + (unsigned long long) sysstatvfs.f_blocks, + (unsigned long long) sysstatvfs.f_bfree, + (unsigned long long) sysstatvfs.f_bavail, + (unsigned long long) sysstatvfs.f_files, + (unsigned long long) sysstatvfs.f_ffree, + (unsigned long long) sysstatvfs.f_favail, + (unsigned long long) sysstatvfs.f_fsid, + (unsigned long long) sysstatvfs.f_flag, + (unsigned long long) sysstatvfs.f_namemax); + } + + /* the connection is made */ + /* opening a directory */ + dir=sftp_opendir(sftp_session,"./"); + if(!dir) { + fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session)); + return ; + } + /* reading the whole directory, file by file */ + while((file=sftp_readdir(sftp_session,dir))){ + fprintf(stderr, "%30s(%.8o) : %.5d.%.5d : %.10llu bytes\n", + file->name, + file->permissions, + file->uid, + file->gid, + (long long unsigned int) file->size); + sftp_attributes_free(file); + } + /* when file=NULL, an error has occured OR the directory listing is end of file */ + if(!sftp_dir_eof(dir)){ + fprintf(stderr, "Error: %s\n", ssh_get_error(session)); + return; + } + if(sftp_closedir(dir)){ + fprintf(stderr, "Error: %s\n", ssh_get_error(session)); + return; + } + /* this will open a file and copy it into your /home directory */ + /* the small buffer size was intended to stress the library. of course, you can use a buffer till 20kbytes without problem */ + + fichier=sftp_open(sftp_session,"/usr/bin/ssh",O_RDONLY, 0); + if(!fichier){ + fprintf(stderr, "Error opening /usr/bin/ssh: %s\n", + ssh_get_error(session)); + return; + } + /* open a file for writing... */ + to=sftp_open(sftp_session,"ssh-copy",O_WRONLY | O_CREAT, 0700); + if(!to){ + fprintf(stderr, "Error opening ssh-copy for writing: %s\n", + ssh_get_error(session)); + return; + } + while((len=sftp_read(fichier,data,4096)) > 0){ + if(sftp_write(to,data,len)!=len){ + fprintf(stderr, "Error writing %d bytes: %s\n", + len, ssh_get_error(session)); + return; + } + } + printf("finished\n"); + if(len<0) + fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session)); + sftp_close(fichier); + sftp_close(to); + printf("fichiers ferm\n"); + to=sftp_open(sftp_session,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644); + for(i=0;i<1000;++i){ + len=sftp_write(to,data,8000); + printf("wrote %d bytes\n",len); + if(len != 8000){ + printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session)); + } + } + sftp_close(to); + + /* close the sftp session */ + sftp_free(sftp_session); + printf("sftp session terminated\n"); +} +#endif + +static int auth_kbdint(ssh_session session){ + int err=ssh_userauth_kbdint(session,NULL,NULL); + const char *name, *instruction, *prompt; + char *ptr; + char buffer[128]; + int i,n; + char echo; + while (err==SSH_AUTH_INFO){ + name=ssh_userauth_kbdint_getname(session); + instruction=ssh_userauth_kbdint_getinstruction(session); + n=ssh_userauth_kbdint_getnprompts(session); + if(strlen(name)>0) + printf("%s\n",name); + if(strlen(instruction)>0) + printf("%s\n",instruction); + for(i=0;i<n;++i){ + prompt=ssh_userauth_kbdint_getprompt(session,i,&echo); + if(echo){ + printf("%s",prompt); + fgets(buffer,sizeof(buffer),stdin); + buffer[sizeof(buffer)-1]=0; + if((ptr=strchr(buffer,'\n'))) + *ptr=0; + if (ssh_userauth_kbdint_setanswer(session,i,buffer) < 0) { + return SSH_AUTH_ERROR; + } + memset(buffer,0,strlen(buffer)); + } else { + ptr=getpass(prompt); + if (ssh_userauth_kbdint_setanswer(session,i,ptr) < 0) { + return SSH_AUTH_ERROR; + } + } + } + err=ssh_userauth_kbdint(session,NULL,NULL); + } + return err; +} + +int main(int argc, char **argv){ + ssh_session session; + int auth=0; + char *password; + char *banner; + char *hexa; + int state; + char buf[10]; + unsigned char *hash = NULL; + int hlen; + + session = ssh_new(); + + if(ssh_options_getopt(session, &argc, argv)) { + fprintf(stderr, "error parsing command line :%s\n", + ssh_get_error(session)); + usage(); + } + opts(argc,argv); + signal(SIGTERM, do_exit); + + if (user) { + if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) { + ssh_disconnect(session); + return 1; + } + } + + if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) { + ssh_disconnect(session); + return 1; + } + + ssh_options_parse_config(session, NULL); + + if(ssh_connect(session)){ + fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session)); + ssh_disconnect(session); + ssh_finalize(); + return 1; + } + state=ssh_is_server_known(session); + + hlen = ssh_get_pubkey_hash(session, &hash); + if (hlen < 0) { + ssh_disconnect(session); + ssh_finalize(); + return 1; + } + switch(state){ + case SSH_SERVER_KNOWN_OK: + break; /* ok */ + case SSH_SERVER_KNOWN_CHANGED: + fprintf(stderr,"Host key for server changed : server's one is now :\n"); + ssh_print_hexa("Public key hash",hash, hlen); + free(hash); + fprintf(stderr,"For security reason, connection will be stopped\n"); + ssh_disconnect(session); + ssh_finalize(); + exit(-1); + case SSH_SERVER_FOUND_OTHER: + fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n"); + fprintf(stderr,"An attacker might change the default server key to confuse your client" + "into thinking the key does not exist\n" + "We advise you to rerun the client with -d or -r for more safety.\n"); + ssh_disconnect(session); + ssh_finalize(); + exit(-1); + case SSH_SERVER_FILE_NOT_FOUND: + fprintf(stderr,"Could not find known host file. If you accept the host key here,\n"); + fprintf(stderr,"the file will be automatically created.\n"); + /* fallback to SSH_SERVER_NOT_KNOWN behavior */ + case SSH_SERVER_NOT_KNOWN: + hexa = ssh_get_hexa(hash, hlen); + fprintf(stderr,"The server is unknown. Do you trust the host key ?\n"); + fprintf(stderr, "Public key hash: %s\n", hexa); + free(hexa); + fgets(buf,sizeof(buf),stdin); + if(strncasecmp(buf,"yes",3)!=0){ + ssh_disconnect(session); + exit(-1); + } + fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n"); + fgets(buf,sizeof(buf),stdin); + if(strncasecmp(buf,"yes",3)==0){ + if (ssh_write_knownhost(session) < 0) { + free(hash); + fprintf(stderr, "error %s\n", strerror(errno)); + exit(-1); + } + } + + break; + case SSH_SERVER_ERROR: + free(hash); + fprintf(stderr,"%s",ssh_get_error(session)); + ssh_disconnect(session); + ssh_finalize(); + exit(-1); + } + free(hash); + + ssh_userauth_none(session, NULL); + + auth = ssh_auth_list(session); + printf("supported auth methods: "); + if (auth & SSH_AUTH_METHOD_PUBLICKEY) { + printf("publickey"); + } + if (auth & SSH_AUTH_METHOD_INTERACTIVE) { + printf(", keyboard-interactive"); + } + printf("\n"); + + /* no ? you should :) */ + auth=ssh_userauth_autopubkey(session, NULL); + if(auth==SSH_AUTH_ERROR){ + fprintf(stderr,"Authenticating with pubkey: %s\n",ssh_get_error(session)); + ssh_finalize(); + return -1; + } + banner=ssh_get_issue_banner(session); + if(banner){ + printf("%s\n",banner); + free(banner); + } + if(auth!=SSH_AUTH_SUCCESS){ + auth=auth_kbdint(session); + if(auth==SSH_AUTH_ERROR){ + fprintf(stderr,"authenticating with keyb-interactive: %s\n", + ssh_get_error(session)); + ssh_finalize(); + return -1; + } + } + if(auth!=SSH_AUTH_SUCCESS){ + password=getpass("Password: "); + if(ssh_userauth_password(session,NULL,password) != SSH_AUTH_SUCCESS){ + fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session)); + ssh_disconnect(session); + ssh_finalize(); + return -1; + } + memset(password,0,strlen(password)); + } + ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success"); + if(strstr(argv[0],"sftp")){ + sftp=1; + ssh_log(session, SSH_LOG_FUNCTIONS, "Doing sftp instead"); + } + if(!sftp){ + if(!cmds[0]) + shell(session); + else + batch_shell(session); + } +#ifdef WITH_SFTP + else + do_sftp(session); +#endif + if(!sftp && !cmds[0]) + do_cleanup(0); + ssh_disconnect(session); + ssh_finalize(); + + return 0; +} diff --git a/examples/samplesshd.c b/examples/samplesshd.c new file mode 100644 index 00000000..4c8a5bc9 --- /dev/null +++ b/examples/samplesshd.c @@ -0,0 +1,152 @@ +/* This is a sample implementation of a libssh based SSH server */ +/* +Copyright 2003-2009 Aris Adamantiadis + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +The goal is to show the API in action. It's not a reference on how terminal +clients must be made or how a client should react. +*/ + +#include <libssh/libssh.h> +#include <libssh/server.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#ifndef KEYS_FOLDER +#ifdef _WIN32 +#define KEYS_FOLDER +#else +#define KEYS_FOLDER "/etc/ssh/" +#endif +#endif + +static int auth_password(char *user, char *password){ + if(strcmp(user,"aris")) + return 0; + if(strcmp(password,"lala")) + return 0; + return 1; // authenticated +} + +int main(int argc, char **argv){ + ssh_session session; + ssh_bind sshbind; + ssh_message message; + ssh_channel chan=0; + ssh_buffer buf; + int auth=0; + int sftp=0; + int i; + int r; + + sshbind=ssh_bind_new(); + session=ssh_new(); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key"); + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key"); + + if(ssh_bind_listen(sshbind)<0){ + printf("Error listening to socket: %s\n",ssh_get_error(sshbind)); + return 1; + } + r=ssh_bind_accept(sshbind,session); + if(r==SSH_ERROR){ + printf("error accepting a connection : %s\n",ssh_get_error(sshbind)); + return 1; + } + if(ssh_accept(session)){ + printf("ssh_accept: %s\n",ssh_get_error(session)); + return 1; + } + do { + message=ssh_message_get(session); + if(!message) + break; + switch(ssh_message_type(message)){ + case SSH_REQUEST_AUTH: + switch(ssh_message_subtype(message)){ + case SSH_AUTH_METHOD_PASSWORD: + printf("User %s wants to auth with pass %s\n", + ssh_message_auth_user(message), + ssh_message_auth_password(message)); + if(auth_password(ssh_message_auth_user(message), + ssh_message_auth_password(message))){ + auth=1; + ssh_message_auth_reply_success(message,0); + break; + } + // not authenticated, send default message + case SSH_AUTH_METHOD_NONE: + default: + ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD); + ssh_message_reply_default(message); + break; + } + break; + default: + ssh_message_reply_default(message); + } + ssh_message_free(message); + } while (!auth); + if(!auth){ + printf("auth error: %s\n",ssh_get_error(session)); + ssh_disconnect(session); + return 1; + } + do { + message=ssh_message_get(session); + if(message){ + switch(ssh_message_type(message)){ + case SSH_REQUEST_CHANNEL_OPEN: + if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){ + chan=ssh_message_channel_request_open_reply_accept(message); + break; + } + default: + ssh_message_reply_default(message); + } + ssh_message_free(message); + } + } while(message && !chan); + if(!chan){ + printf("error : %s\n",ssh_get_error(session)); + ssh_finalize(); + return 1; + } + do { + message=ssh_message_get(session); + if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL && + ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){ +// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){ + sftp=1; + ssh_message_channel_request_reply_success(message); + break; + // } + } + if(!sftp){ + ssh_message_reply_default(message); + } + ssh_message_free(message); + } while (message && !sftp); + if(!sftp){ + printf("error : %s\n",ssh_get_error(session)); + return 1; + } + printf("it works !\n"); + buf=buffer_new(); + do{ + i=channel_read_buffer(chan,buf,0,0); + if(i>0) + write(1,buffer_get(buf),buffer_get_len(buf)); + } while (i>0); + buffer_free(buf); + ssh_disconnect(session); + ssh_bind_free(sshbind); + ssh_finalize(); + return 0; +} + |