int handleSSHCommands( SSHSession *sess, const char *buf, const int len ) { char outbuf[ 2048 ]; if( strncmp( buf, "help", 4 ) == 0 ) { strcpy( outbuf, "Main commands:\n" \ " logout - logout user from current session\n" \ " cd - change current directory\n" \ ); ssh_channel_write( sess->sshs_Chan, outbuf, strlen( buf ) ); }else if( strncmp( buf, "logout", 6 ) == 0 ) { sess->sshs_Quit = TRUE; }else if( strncmp( buf, "cd", 2 ) == 0 ) { }else{ // command not found ssh_channel_write( sess->sshs_Chan, "Command not found\n", 18 ); //ssh_channel_write( chan, buf, i ); //if( write( 1, buf, i ) < 0 ) //{ // ERROR("error writing to buffer\n"); // break; //} } return 0; }
/** * @brief Write into a remote scp file. * * @param[in] scp The scp handle. * * @param[in] buffer The buffer to write. * * @param[in] len The number of bytes to write. * * @returns SSH_OK if the write was successful, SSH_ERROR an error * occured while writing. */ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ int w; int r; uint8_t code; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_WRITING){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state"); return SSH_ERROR; } if(scp->processed + len > scp->filelen) len = (size_t) (scp->filelen - scp->processed); /* hack to avoid waiting for window change */ r = ssh_channel_poll(scp->channel, 0); if (r == SSH_ERROR) { scp->state = SSH_SCP_ERROR; return SSH_ERROR; } w=ssh_channel_write(scp->channel,buffer,len); if(w != SSH_ERROR) scp->processed += w; else { scp->state=SSH_SCP_ERROR; //return=channel_get_exit_status(scp->channel); return SSH_ERROR; } /* Far end sometimes send a status message, which we need to read * and handle */ r = ssh_channel_poll(scp->channel,0); if(r > 0){ r = ssh_channel_read(scp->channel, &code, 1, 0); if(r == SSH_ERROR){ return SSH_ERROR; } if(code == 1 || code == 2){ ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Error: status code %i received", code); return SSH_ERROR; } } /* Check if we arrived at end of file */ if(scp->processed == scp->filelen) { code = 0; w = ssh_channel_write(scp->channel, &code, 1); if(w == SSH_ERROR){ scp->state = SSH_SCP_ERROR; return SSH_ERROR; } scp->processed=scp->filelen=0; scp->state=SSH_SCP_WRITE_INITED; } return SSH_OK; }
/** * @brief Create a directory in a scp in sink mode. * * @param[in] scp The scp handle. * * @param[in] dirname The name of the directory being created. * * @param[in] mode The UNIX permissions for the new directory, e.g. 0755. * * @returns SSH_OK if the directory has been created, SSH_ERROR if * an error occured. * * @see ssh_scp_leave_directory() */ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){ char buffer[1024]; int r; uint8_t code; char *dir; char *perms; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_INITED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_directory called under invalid state"); return SSH_ERROR; } dir=ssh_basename(dirname); perms=ssh_scp_string_mode(mode); snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir); SAFE_FREE(dir); SAFE_FREE(perms); r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r=ssh_channel_read(scp->channel,&code,1,0); if(r<=0){ ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } return SSH_OK; }
/** * @brief Leave a directory. * * @returns SSH_OK if the directory has been left,SSH_ERROR if an * error occured. * * @see ssh_scp_push_directory() */ int ssh_scp_leave_directory(ssh_scp scp){ char buffer[]="E\n"; int r; uint8_t code; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_INITED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_leave_directory called under invalid state"); return SSH_ERROR; } r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r=ssh_channel_read(scp->channel,&code,1,0); if(r<=0){ ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } return SSH_OK; }
static void on_pty_event(struct tmate_session *session) { ssize_t len, written; char buf[4096]; for (;;) { len = read(session->pty, buf, sizeof(buf)); if (len < 0) { if (errno == EAGAIN) return; tmate_fatal("pty read error"); } if (len == 0) tmate_fatal("pty reached EOF"); written = ssh_channel_write(session->ssh_client.channel, buf, len); if (written < 0) tmate_fatal("Error writing to channel: %s", ssh_get_error(session->ssh_client.session)); if (len != written) tmate_fatal("Cannot write %d bytes, wrote %d", (int)len, (int)written); } }
static int check_ios_version(ssh_channel channel) { gchar* cmdline = "show version | include Cisco IOS\n"; gchar version[255]; guint major = 0; guint minor = 0; gchar* cur; memset(version, 0x0, 255); if (ssh_channel_write(channel, cmdline, (guint32)strlen(cmdline)) == SSH_ERROR) return FALSE; if (read_output_bytes(channel, (int)strlen(cmdline), NULL) == EXIT_FAILURE) return FALSE; if (read_output_bytes(channel, 255, version) == EXIT_FAILURE) return FALSE; cur = g_strstr_len(version, strlen(version), "Version"); if (cur) { cur += strlen("Version "); if (sscanf(cur, "%u.%u", &major, &minor) != 2) return FALSE; if ((major > MINIMUM_IOS_MAJOR) || (major == MINIMUM_IOS_MAJOR && minor >= MINIMUM_IOS_MINOR)) { g_debug("Current IOS Version: %u.%u", major, minor); if (read_output_bytes(channel, -1, NULL) == EXIT_FAILURE) return FALSE; return TRUE; } } g_warning("Invalid IOS version. Minimum version: 12.4, current: %u.%u", major, minor); return FALSE; }
/** * @brief Initialize the scp channel. * * @param[in] scp The scp context to initialize. * * @return SSH_OK on success or an SSH error code. * * @see ssh_scp_new() */ int ssh_scp_init(ssh_scp scp) { int r; char execbuffer[1024]; uint8_t code; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_NEW){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state"); return SSH_ERROR; } SSH_LOG(SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'", scp->mode==SSH_SCP_WRITE?"write":"read", scp->recursive?"recursive ":"", scp->location); scp->channel=ssh_channel_new(scp->session); if(scp->channel == NULL){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r= ssh_channel_open_session(scp->channel); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(scp->mode == SSH_SCP_WRITE) snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s", scp->recursive ? "-r":"", scp->location); else snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s", scp->recursive ? "-r":"", scp->location); if(ssh_channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(scp->mode == SSH_SCP_WRITE){ r=ssh_channel_read(scp->channel,&code,1,0); if(r<=0){ ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } } else { ssh_channel_write(scp->channel,"",1); } if(scp->mode == SSH_SCP_WRITE) scp->state=SSH_SCP_WRITE_INITED; else scp->state=SSH_SCP_READ_INITED; return SSH_OK; }
/* returns 0 on any errors, length sent on success */ int SSH_Socket::sendSocket(unsigned char *buf, Uint32 len) { Uint32 result = 0; result = ssh_channel_write(sshChannel, buf, len); if(result < strlen((char *)buf)) { return SSH_ERROR; // or Zero. } return(result); }
void clSSH::ExecuteShellCommand(wxEvtHandler* owner, const wxString& command) { DoOpenChannel(); m_owner = owner; if(!m_owner) { throw clException(wxString() << "No owner specified for output"); } wxCharBuffer buffer = command.mb_str(wxConvUTF8); int rc = ssh_channel_write(m_channel, buffer.data(), buffer.length()); if(rc != (int)buffer.length()) { throw clException("SSH Socket error"); } // Start a timer to check for the output on 10ms intervals if(!m_timer->IsRunning()) { m_timer->Start(50); } }
static int process_stdout(socket_t fd, int revents, void *userdata) { char buf[BUF_SIZE]; int n = -1; ssh_channel channel = (ssh_channel) userdata; if (channel != NULL && (revents & POLLIN) != 0) { n = read(fd, buf, BUF_SIZE); if (n > 0) { ssh_channel_write(channel, buf, n); } } return n; }
/* Write data to the channel. Throw `guile-ssh-error' on a libssh error, or signal a system error if amount of data written is smaller than size SZ. */ static void ptob_write (SCM channel, const void *data, size_t sz) #define FUNC_NAME "ptob_write" { struct channel_data *channel_data = _scm_to_channel_data (channel); int res = ssh_channel_write (channel_data->ssh_channel, data, sz); if (res == SSH_ERROR) { ssh_session session = ssh_channel_get_session (channel_data->ssh_channel); guile_ssh_session_error1 (FUNC_NAME, session, channel); } if (res < sz) scm_syserror (FUNC_NAME); }
static size_t write_to_channel_port (SCM channel, SCM src, size_t start, size_t count) #define FUNC_NAME "write_to_channel_port" { char *data = (char *) SCM_BYTEVECTOR_CONTENTS (src) + start; struct channel_data *channel_data = _scm_to_channel_data (channel); int res = ssh_channel_write (channel_data->ssh_channel, data, count); if (res == SSH_ERROR) { ssh_session session = ssh_channel_get_session (channel_data->ssh_channel); guile_ssh_session_error1 (FUNC_NAME, session, channel); } assert (res >= 0); return res; }
/** * @brief Accepts transfer of a file or creation of a directory coming from the * remote party. * * @param[in] scp The scp handle. * * @returns SSH_OK if the message was sent, SSH_ERROR if sending the * message failed, or sending it in a bad state. */ int ssh_scp_accept_request(ssh_scp scp){ char buffer[]={0x00}; int err; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_READ_REQUESTED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state"); return SSH_ERROR; } err=ssh_channel_write(scp->channel,buffer,1); if(err==SSH_ERROR) { return SSH_ERROR; } if(scp->request_type==SSH_SCP_REQUEST_NEWFILE) scp->state=SSH_SCP_READ_READING; else scp->state=SSH_SCP_READ_INITED; return SSH_OK; }
/** * @brief Deny the transfer of a file or creation of a directory coming from the * remote party. * * @param[in] scp The scp handle. * @param[in] reason A nul-terminated string with a human-readable * explanation of the deny. * * @returns SSH_OK if the message was sent, SSH_ERROR if the sending * the message failed, or sending it in a bad state. */ int ssh_scp_deny_request(ssh_scp scp, const char *reason){ char buffer[MAX_BUF_SIZE]; int err; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_READ_REQUESTED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state"); return SSH_ERROR; } snprintf(buffer,sizeof(buffer),"%c%s\n",2,reason); err=ssh_channel_write(scp->channel,buffer,strlen(buffer)); if(err==SSH_ERROR) { return SSH_ERROR; } else { scp->state=SSH_SCP_READ_INITED; return SSH_OK; } }
/** @brief Read from a remote scp file * @param[in] scp The scp handle. * * @param[in] buffer The destination buffer. * * @param[in] size The size of the buffer. * * @returns The nNumber of bytes read, SSH_ERROR if an error occured * while reading. */ int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){ int r; int code; if(scp==NULL) return SSH_ERROR; if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){ r=ssh_scp_accept_request(scp); if(r==SSH_ERROR) return r; } if(scp->state != SSH_SCP_READ_READING){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_read called under invalid state"); return SSH_ERROR; } if(scp->processed + size > scp->filelen) size = (size_t) (scp->filelen - scp->processed); if(size > 65536) size=65536; /* avoid too large reads */ r=ssh_channel_read(scp->channel,buffer,size,0); if(r != SSH_ERROR) scp->processed += r; else { scp->state=SSH_SCP_ERROR; return SSH_ERROR; } /* Check if we arrived at end of file */ if(scp->processed == scp->filelen) { scp->processed=scp->filelen=0; ssh_channel_write(scp->channel,"",1); code=ssh_scp_response(scp,NULL); if(code == 0){ scp->state=SSH_SCP_READ_INITED; return r; } if(code==1){ scp->state=SSH_SCP_READ_INITED; return SSH_ERROR; } scp->state=SSH_SCP_ERROR; return SSH_ERROR; } return r; }
/* Complete the processing of buffered output data. Currently this callback makes no effect because the channel CHANNEL uses unbuffered output. */ static void ptob_flush (SCM channel) #define FUNC_NAME "ptob_flush" { scm_port *pt = SCM_PTAB_ENTRY (channel); struct channel_data *cd = _scm_to_channel_data (channel); size_t wrsize = pt->write_pos - pt->write_buf; if (wrsize) { int res = ssh_channel_write (cd->ssh_channel, pt->write_buf, wrsize); if (res == SSH_ERROR) { ssh_session session = ssh_channel_get_session (cd->ssh_channel); guile_ssh_session_error1 (FUNC_NAME, session, channel); } } pt->write_pos = pt->write_buf; }
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) { ssh_channel chan = (ssh_channel)userdata; char buf[2048]; int sz = 0; if(!chan) { close(fd); return -1; } if(revents & POLLIN) { sz = read(fd, buf, 2048); if(sz > 0) { ssh_channel_write(chan, buf, sz); } } if(revents & POLLHUP) { ssh_channel_close(chan); sz = -1; } return sz; }
/** * @brief Write into a remote scp file. * * @param[in] scp The scp handle. * * @param[in] buffer The buffer to write. * * @param[in] len The number of bytes to write. * * @returns SSH_OK if the write was successful, SSH_ERROR an error * occured while writing. */ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ int w; //int r; //uint8_t code; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_WRITING){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state"); return SSH_ERROR; } if(scp->processed + len > scp->filelen) len = scp->filelen - scp->processed; /* hack to avoid waiting for window change */ ssh_channel_poll(scp->channel,0); w=ssh_channel_write(scp->channel,buffer,len); if(w != SSH_ERROR) scp->processed += w; else { scp->state=SSH_SCP_ERROR; //return=channel_get_exit_status(scp->channel); return SSH_ERROR; } /* Check if we arrived at end of file */ if(scp->processed == scp->filelen) { /* r=channel_read(scp->channel,&code,1,0); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } */ scp->processed=scp->filelen=0; scp->state=SSH_SCP_WRITE_INITED; } return SSH_OK; }
/** * @brief Initialize the sending of a file to a scp in sink mode, using a 64-bit size. * * @param[in] scp The scp handle. * * @param[in] filename The name of the file being sent. It should not contain * any path indicator * * @param[in] size Exact size in bytes of the file being sent. * * @param[in] mode The UNIX permissions for the new file, e.g. 0644. * * @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an * error occured. * * @see ssh_scp_push_file() */ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int mode){ char buffer[1024]; int r; uint8_t code; char *file; char *perms; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_INITED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state"); return SSH_ERROR; } file=ssh_basename(filename); perms=ssh_scp_string_mode(mode); SSH_LOG(SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIu64 " with permissions '%s'",file,size,perms); snprintf(buffer, sizeof(buffer), "C%s %" PRIu64 " %s\n", perms, size, file); SAFE_FREE(file); SAFE_FREE(perms); r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r=ssh_channel_read(scp->channel,&code,1,0); if(r<=0){ ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } scp->filelen = size; scp->processed = 0; scp->state=SSH_SCP_WRITE_WRITING; return SSH_OK; }
static gboolean dispatch_queue (CockpitSshTransport *self) { GBytes *block; const guchar *data; gsize length; gsize want; int rc; if (self->sent_eof) return FALSE; if (self->received_close) return FALSE; for (;;) { block = g_queue_peek_head (self->queue); if (!block) return FALSE; data = g_bytes_get_data (block, &length); g_assert (self->partial <= length); want = length - self->partial; rc = ssh_channel_write (self->data->channel, data + self->partial, want); if (rc < 0) { if (ssh_get_error_code (self->data->session) == SSH_REQUEST_DENIED) { g_debug ("%s: couldn't write: %s", self->logname, ssh_get_error (self->data->session)); return FALSE; } else { g_warning ("%s: couldn't write: %s", self->logname, ssh_get_error (self->data->session)); close_immediately (self, "internal-error"); } break; } if (rc == want) { g_debug ("%s: wrote %d bytes", self->logname, rc); g_queue_pop_head (self->queue); g_bytes_unref (block); self->partial = 0; } else { g_debug ("%s: wrote %d of %d bytes", self->logname, rc, (int)want); g_return_val_if_fail (rc < want, FALSE); self->partial += rc; if (rc == 0) break; } } return TRUE; }
/** * @brief Wait for a scp request (file, directory). * * @returns SSH_SCP_REQUEST_NEWFILE: The other side is sending * a file * SSH_SCP_REQUEST_NEWDIR: The other side is sending * a directory * SSH_SCP_REQUEST_ENDDIR: The other side has * finished with the current * directory * SSH_SCP_REQUEST_WARNING: The other side sent us a warning * SSH_SCP_REQUEST_EOF: The other side finished sending us * files and data. * SSH_ERROR: Some error happened * * @see ssh_scp_read() * @see ssh_scp_deny_request() * @see ssh_scp_accept_request() * @see ssh_scp_request_get_warning() */ int ssh_scp_pull_request(ssh_scp scp){ char buffer[MAX_BUF_SIZE] = {0}; char *mode=NULL; char *p,*tmp; uint64_t size; char *name=NULL; int err; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_READ_INITED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state"); return SSH_ERROR; } err=ssh_scp_read_string(scp,buffer,sizeof(buffer)); if(err==SSH_ERROR){ if(ssh_channel_is_eof(scp->channel)){ scp->state=SSH_SCP_TERMINATED; return SSH_SCP_REQUEST_EOF; } return err; } p=strchr(buffer,'\n'); if(p!=NULL) *p='\0'; SSH_LOG(SSH_LOG_PROTOCOL,"Received SCP request: '%s'",buffer); switch(buffer[0]){ case 'C': /* File */ case 'D': /* Directory */ p=strchr(buffer,' '); if(p==NULL) goto error; *p='\0'; p++; //mode=strdup(&buffer[1]); scp->request_mode=ssh_scp_integer_mode(&buffer[1]); tmp=p; p=strchr(p,' '); if(p==NULL) goto error; *p=0; size = strtoull(tmp,NULL,10); p++; name=strdup(p); SAFE_FREE(scp->request_name); scp->request_name=name; if(buffer[0]=='C'){ scp->filelen=size; scp->request_type=SSH_SCP_REQUEST_NEWFILE; } else { scp->filelen='0'; scp->request_type=SSH_SCP_REQUEST_NEWDIR; } scp->state=SSH_SCP_READ_REQUESTED; scp->processed = 0; return scp->request_type; break; case 'E': scp->request_type=SSH_SCP_REQUEST_ENDDIR; ssh_channel_write(scp->channel,"",1); return scp->request_type; case 0x1: ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]); scp->request_type=SSH_SCP_REQUEST_WARNING; SAFE_FREE(scp->warning); scp->warning=strdup(&buffer[1]); return scp->request_type; case 0x2: ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]); return SSH_ERROR; case 'T': /* Timestamp */ default: ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer); return SSH_ERROR; } /* a parsing error occured */ error: SAFE_FREE(name); SAFE_FREE(mode); ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer); return SSH_ERROR; }
static void *nogvl_write(void *ptr) { struct nogvl_write_args *args = ptr; args->rc = ssh_channel_write(args->channel, args->data, args->len); return NULL; }
int SSHThread( void *data ) { // TODO: Hogne was here, disabling this problem child.. :) return 0; #ifdef ENABLE_SSH ssh_session session = NULL; ssh_bind sshbind = NULL; ssh_event mainloop; struct ssh_server_callbacks_struct cb = { .userdata = NULL, .auth_password_function = auth_password, .auth_gssapi_mic_function = auth_gssapi_mic, .channel_open_request_session_function = new_session_channel }; char buf[2048]; int i; int r; DEBUG("Starting SSH Process\n"); SSHServer *ts = (SSHServer *)data; if( !ts ) return 0; ts->sshs_FriendHome = getenv( "FRIEND_HOME" ); int len = strlen( ts->sshs_FriendHome ); ts->sshs_RSAKeyHome = calloc( len+64, sizeof(char) ); ts->sshs_DSAKeyHome = calloc( len+64, sizeof(char) ); strcpy( ts->sshs_RSAKeyHome, ts->sshs_FriendHome ); strcpy( ts->sshs_DSAKeyHome, ts->sshs_FriendHome ); strcat( ts->sshs_RSAKeyHome, "keys/ssh_host_rsa_key" ); strcat( ts->sshs_DSAKeyHome, "keys/ssh_host_dsa_key" ); //DEBUG("SSH sshs_RSAKeyHome set to %s\n", ts->sshs_RSAKeyHome ); sshbind = ssh_bind_new(); BOOL welcomeMessage = FALSE; ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_DSAKEY, ts->sshs_DSAKeyHome ); ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_RSAKEY, ts->sshs_RSAKeyHome ); //ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg); //DEBUG("IMPORT RSA KEY %s\n", ts->sshs_RSAKeyHome ); ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, SSH_SERVER_PORT ); //verbose ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "2" ); ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_BINDADDR, "127.0.0.1" ); if( ts->sshs_RSAKeyHome ) free( ts->sshs_RSAKeyHome ); if( ts->sshs_DSAKeyHome ) free( ts->sshs_DSAKeyHome ); // TODO: ts->sshs_Quit sometimes can not be read! while( ts != NULL && !ts->sshs_Quit ) { DEBUG("Server options set\n"); #ifdef WITH_PCAP set_pcap(session); #endif DEBUG("Server before bind\n"); if( ssh_bind_listen( sshbind )<0 ) { ERROR("Error listening to socket: %s\n",ssh_get_error(sshbind) ); break; } DEBUG("Server before accept\n"); session=ssh_new(); r = ssh_bind_accept( sshbind , session ); if( r==SSH_ERROR ) { ERROR("error accepting a connection : %s\n",ssh_get_error(sshbind)); break; } ssh_callbacks_init( &cb ); SSHSession *sess = calloc( 1, sizeof( SSHSession ) ); sess->sshs_Session = session; cb.userdata = sess; DEBUG("User data set\n"); ssh_set_server_callbacks( session, &cb ); if ( ssh_handle_key_exchange( session ) ) { ERROR("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); continue; //goto disconnect; } DEBUG("Connection accepted\n"); ssh_set_auth_methods( session,SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC ); // // New session/connection put it into thread // switch( fork() ) { case 0: // Remove the SIGCHLD handler inherited from parent signal(SIGCHLD, SIG_DFL); mainloop = ssh_event_new(); ssh_event_add_session( mainloop, session ); while( !(sess->sshs_Authenticated && sess->sshs_Chan != NULL) ) { if( sess->sshs_Error ) { ERROR("SSHSession error %d\n", sess->sshs_Error ); break; } r = ssh_event_dopoll( mainloop, -1 ); if( r == SSH_ERROR ) { ERROR("Error : %s\n",ssh_get_error( session ) ); ssh_disconnect( session ); return 1; } strcpy( buf, "------------------------------------------------------\n\r" \ "--- Welcome in FC server, use help to work with me ---\n\r" \ "------------------------------------------------------\n\r" ); ssh_channel_write( sess->sshs_Chan, buf, strlen( buf ) ); if( sess->sshs_Path == NULL ) { sess->sshs_Path = calloc( 1024, sizeof(char) ); sess->sshs_DispText = calloc( 1024+48, sizeof(char) ); } strcpy( sess->sshs_Path, "/" ); if( sess->sshs_Usr ) { sprintf( sess->sshs_DispText, "%s:%s ", sess->sshs_Usr->u_Name, sess->sshs_Path ); }else{ sprintf( sess->sshs_DispText, ":%s ", sess->sshs_Path ); } int i = 0; do { ssh_channel_write( sess->sshs_Chan, sess->sshs_DispText, strlen( sess->sshs_DispText ) ); i = ssh_channel_read( sess->sshs_Chan, buf, 2048, 0 ); if( i > 0 ) { DEBUG("READING FROM CHANNEL %d - size %d %d %c -n %d\n", i, strlen( buf ), buf[0], buf[0], '\n' ); //ssh_channel_write( sess->sshs_Chan, buf, 1 ); handleSSHCommands( sess, buf, i ); } if( sess->sshs_Quit ) { break; } } while( i>0 ); if( sess->sshs_Quit ) break; } DEBUG("Closing ssh connection\n"); ssh_event_free( mainloop ); ssh_disconnect( session ); ssh_free( session ); if( sess->sshs_DispText ) { FFree( sess->sshs_DispText ); } if( sess->sshs_Path ) { FFree( sess->sshs_Path ); } DEBUG("Connection released\n"); FFree( sess ); abort(); DEBUG("AUTH\n"); break; case -1: ERROR("Cannot create fork!\n"); break; } #ifdef WITH_PCAP cleanup_pcap(); #endif } // main loop disconnect: DEBUG("DISCONNECTED\n"); #endif // ENABLE_SSH return 0; }
static ssh_channel run_capture(ssh_session sshs, const char* iface, const char* cfilter, const guint32 count) { char* cmdline = NULL; ssh_channel channel; int ret = 0; channel = ssh_channel_new(sshs); if (!channel) return NULL; if (ssh_channel_open_session(channel) != SSH_OK) goto error; if (ssh_channel_request_pty(channel) != SSH_OK) goto error; if (ssh_channel_change_pty_size(channel, 80, 24) != SSH_OK) goto error; if (ssh_channel_request_shell(channel) != SSH_OK) goto error; if (!check_ios_version(channel)) goto error; if (ssh_channel_printf(channel, "terminal length 0\n") == EXIT_FAILURE) goto error; if (ssh_channel_printf(channel, "monitor capture buffer %s max-size 9500\n", WIRESHARK_CAPTURE_BUFFER) == EXIT_FAILURE) goto error; if (ssh_channel_printf(channel, "monitor capture buffer %s limit packet-count %u\n", WIRESHARK_CAPTURE_BUFFER, count) == EXIT_FAILURE) goto error; if (cfilter) { gchar* multiline_filter; gchar* chr; if (ssh_channel_printf(channel, "configure terminal\n") == EXIT_FAILURE) goto error; if (ssh_channel_printf(channel, "ip access-list ex %s\n", WIRESHARK_CAPTURE_ACCESSLIST) == EXIT_FAILURE) goto error; multiline_filter = g_strdup(cfilter); chr = multiline_filter; while((chr = g_strstr_len(chr, strlen(chr), ",")) != NULL) { chr[0] = '\n'; g_debug("Splitting filter into multiline"); } ret = ssh_channel_write(channel, multiline_filter, (uint32_t)strlen(multiline_filter)); g_free(multiline_filter); if (ret == SSH_ERROR) goto error; if (ssh_channel_printf(channel, "\nend\n") == EXIT_FAILURE) goto error; if (ssh_channel_printf(channel, "monitor capture buffer %s filter access-list %s\n", WIRESHARK_CAPTURE_BUFFER, WIRESHARK_CAPTURE_ACCESSLIST) == EXIT_FAILURE) goto error; } if (ssh_channel_printf(channel, "monitor capture point ip cef %s %s both\n", WIRESHARK_CAPTURE_POINT, iface) == EXIT_FAILURE) goto error; if (ssh_channel_printf(channel, "monitor capture point associate %s %s \n", WIRESHARK_CAPTURE_POINT, WIRESHARK_CAPTURE_BUFFER) == EXIT_FAILURE) goto error; if (ssh_channel_printf(channel, "monitor capture point start %s\n", WIRESHARK_CAPTURE_POINT) == EXIT_FAILURE) goto error; if (read_output_bytes(channel, -1, NULL) == EXIT_FAILURE) goto error; if (wait_until_data(channel, count) == EXIT_FAILURE) goto error; if (read_output_bytes(channel, -1, NULL) == EXIT_FAILURE) goto error; cmdline = g_strdup_printf("show monitor capture buffer %s dump\n", WIRESHARK_CAPTURE_BUFFER); if (ssh_channel_printf(channel, cmdline) == EXIT_FAILURE) goto error; if (read_output_bytes(channel, (int)strlen(cmdline), NULL) == EXIT_FAILURE) goto error; g_free(cmdline); return channel; error: g_free(cmdline); g_warning("Error running ssh remote command"); read_output_bytes(channel, -1, NULL); ssh_channel_close(channel); ssh_channel_free(channel); return NULL; }
static int pkd_exec_hello(int fd, struct pkd_daemon_args *args) { int rc = -1; ssh_bind b = NULL; ssh_session s = NULL; ssh_event e = NULL; ssh_channel c = NULL; enum ssh_bind_options_e opts = -1; int level = args->opts.libssh_log_level; enum pkd_hostkey_type_e type = args->type; const char *hostkeypath = args->hostkeypath; pkd_state.eof_received = 0; pkd_state.close_received = 0; pkd_state.req_exec_received = 0; b = ssh_bind_new(); if (b == NULL) { pkderr("ssh_bind_new\n"); goto outclose; } if (type == PKD_RSA) { opts = SSH_BIND_OPTIONS_RSAKEY; } else if (type == PKD_ED25519) { opts = SSH_BIND_OPTIONS_HOSTKEY; #ifdef HAVE_DSA } else if (type == PKD_DSA) { opts = SSH_BIND_OPTIONS_DSAKEY; #endif } else if (type == PKD_ECDSA) { opts = SSH_BIND_OPTIONS_ECDSAKEY; } else { pkderr("unknown kex algorithm: %d\n", type); rc = -1; goto outclose; } rc = ssh_bind_options_set(b, opts, hostkeypath); if (rc != 0) { pkderr("ssh_bind_options_set: %s\n", ssh_get_error(b)); goto outclose; } rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY, &level); if (rc != 0) { pkderr("ssh_bind_options_set log verbosity: %s\n", ssh_get_error(b)); goto outclose; } s = ssh_new(); if (s == NULL) { pkderr("ssh_new\n"); goto outclose; } /* * ssh_bind_accept loads host key as side-effect. If this * succeeds, the given 'fd' will be closed upon 'ssh_free(s)'. */ rc = ssh_bind_accept_fd(b, s, fd); if (rc != SSH_OK) { pkderr("ssh_bind_accept_fd: %s\n", ssh_get_error(b)); goto outclose; } /* accept only publickey-based auth */ ssh_set_auth_methods(s, SSH_AUTH_METHOD_PUBLICKEY); /* initialize callbacks */ ssh_callbacks_init(&pkd_server_cb); pkd_server_cb.userdata = &c; rc = ssh_set_server_callbacks(s, &pkd_server_cb); if (rc != SSH_OK) { pkderr("ssh_set_server_callbacks: %s\n", ssh_get_error(s)); goto out; } /* first do key exchange */ rc = ssh_handle_key_exchange(s); if (rc != SSH_OK) { pkderr("ssh_handle_key_exchange: %s\n", ssh_get_error(s)); goto out; } /* setup and pump event to carry out exec channel */ e = ssh_event_new(); if (e == NULL) { pkderr("ssh_event_new\n"); goto out; } rc = ssh_event_add_session(e, s); if (rc != SSH_OK) { pkderr("ssh_event_add_session\n"); goto out; } /* poll until exec channel established */ while ((ctx.keep_going != 0) && (rc != SSH_ERROR) && (pkd_state.req_exec_received == 0)) { rc = ssh_event_dopoll(e, -1 /* infinite timeout */); } if (rc == SSH_ERROR) { pkderr("ssh_event_dopoll\n"); goto out; } else if (c == NULL) { pkderr("poll loop exited but exec channel not ready\n"); rc = -1; goto out; } rc = ssh_channel_write(c, "hello\n", 6); /* XXX: customizable payloads */ if (rc != 6) { pkderr("ssh_channel_write partial (%d)\n", rc); } rc = ssh_channel_request_send_exit_status(c, 0); if (rc != SSH_OK) { pkderr("ssh_channel_request_send_exit_status: %s\n", ssh_get_error(s)); goto out; } rc = ssh_channel_send_eof(c); if (rc != SSH_OK) { pkderr("ssh_channel_send_eof: %s\n", ssh_get_error(s)); goto out; } rc = ssh_channel_close(c); if (rc != SSH_OK) { pkderr("ssh_channel_close: %s\n", ssh_get_error(s)); goto out; } while ((ctx.keep_going != 0) && (pkd_state.eof_received == 0) && (pkd_state.close_received == 0)) { rc = ssh_event_dopoll(e, 1000 /* milliseconds */); if (rc == SSH_ERROR) { /* log, but don't consider this fatal */ pkdout("ssh_event_dopoll for eof + close: %s\n", ssh_get_error(s)); rc = 0; break; } else { rc = 0; } } while ((ctx.keep_going != 0) && (ssh_is_connected(s))) { rc = ssh_event_dopoll(e, 1000 /* milliseconds */); if (rc == SSH_ERROR) { /* log, but don't consider this fatal */ pkdout("ssh_event_dopoll for session connection: %s\n", ssh_get_error(s)); rc = 0; break; } else { rc = 0; } } goto out; outclose: close(fd); out: if (c != NULL) { ssh_channel_free(c); } if (e != NULL) { ssh_event_remove_session(e, s); ssh_event_free(e); } if (s != NULL) { ssh_disconnect(s); ssh_free(s); } if (b != NULL) { ssh_bind_free(b); } return rc; }
/* channel_select base main loop, with a standard select(2) */ static void select_loop(ssh_session session,ssh_channel channel){ fd_set fds; struct timeval timeout; char buffer[4096]; ssh_buffer readbuf=ssh_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,sizeof(buffer)); if(lus) ssh_channel_write(channel,buffer,lus); else { eof=1; ssh_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=ssh_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 && ssh_channel_is_closed(channel)){ ssh_channel_free(channel); channel=NULL; channels[0]=NULL; } if(channels[0]){ while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)>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_channel_free(channel); channel=channels[0]=NULL; } else if (write(1,ssh_buffer_get_begin(readbuf),lus) < 0) { fprintf(stderr, "Error writing to buffer\n"); return; } } while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)>0){ /* 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_channel_free(channel); channel=channels[0]=NULL; } else if (write(2,ssh_buffer_get_begin(readbuf),lus) < 0) { fprintf(stderr, "Error writing to buffer\n"); return; } } } if(channel && ssh_channel_is_closed(channel)){ ssh_channel_free(channel); channel=NULL; } } ssh_buffer_free(readbuf); }
static void select_loop(ssh_session_t *session,ssh_channel_t *channel) { fd_set fds; struct timeval timeout; char buffer[4096]; /* channels will be set to the channels to poll. * outchannels will contain the result of the poll */ ssh_channel_t *channels[2], *outchannels[2]; int lus; int eof=0; int maxfd; unsigned int r; int ret; while(channel) { 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; channels[0] = channel; // set the first channel we want to read from channels[1] = NULL; ret = ssh_select(channels, outchannels, maxfd, &fds, &timeout); if(signal_delayed) { sizechanged(); } if(ret == EINTR) { continue; } if(FD_ISSET(0, &fds)) { lus = read(0, buffer, sizeof(buffer)); if(lus) ssh_channel_write(channel, buffer, lus); else { eof = 1; ssh_channel_send_eof(channel); } } if(channel && ssh_channel_is_closed(channel)) { ssh_channel_free(channel); channel=NULL; channels[0]=NULL; } if(outchannels[0]) { while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,0))!=0) { lus = ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),0); if(lus == -1) { fprintf(stderr, "Error reading channel: %s\n", ssh_get_error(session)); return; } if(lus == 0) { ssh_channel_free(channel); channel=channels[0]=NULL; } else { if (write(1,buffer,lus) < 0) { fprintf(stderr, "Error writing to buffer\n"); return; } } } while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,1))!=0) /* stderr */ { lus = ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),1); if(lus == -1) { fprintf(stderr, "Error reading channel: %s\n", ssh_get_error(session)); return; } if(lus == 0) { ssh_channel_free(channel); channel = channels[0] = NULL; } else { if (write(2, buffer, lus) < 0) { fprintf(stderr, "Error writing to buffer\n"); return; } } } } if(channel && ssh_channel_is_closed(channel)) { ssh_channel_free(channel); channel=NULL; } } while (ret == EINTR || ret == SSH_EINTR); } }
static int fd_data (socket_t fd, int revents, gpointer user_data) { ssh_channel chan = (ssh_channel)user_data; guint8 buf[BUFSIZE]; gint sz = 0; gint bytes = 0; gint status; gint written; pid_t pid = 0; gboolean end = FALSE; gint ret; if (revents & POLLIN) { int ws; do { ws = ssh_channel_window_size (chan); ws = ws < BUFSIZE ? ws : BUFSIZE; if (ws == 0) break; bytes = read (fd, buf, ws); if (bytes < 0) { if (errno == EAGAIN) break; if (errno != ECONNRESET && errno != EBADF) g_critical ("couldn't read from process: %m"); end = TRUE; break; } else if (bytes == 0) { end = TRUE; } else { sz += bytes; written = ssh_channel_write (chan, buf, bytes); if (written != bytes) g_assert_not_reached (); } } while (bytes == ws); } if ((revents & POLLOUT)) { if (state.buffer->len > 0) { written = write (fd, state.buffer->data, state.buffer->len); if (written < 0 && errno != EAGAIN) g_critical ("couldn't write: %s", g_strerror (errno)); if (written > 0) g_byte_array_remove_range (state.buffer, 0, written); } if (state.buffer_eof && state.buffer->len == 0) { if (shutdown (fd, SHUT_WR) < 0) { if (errno != EAGAIN && errno != EBADF) g_critical ("couldn't shutdown: %s", g_strerror (errno)); } else { state.buffer_eof = FALSE; } } } if (end || (revents & (POLLHUP | POLLERR | POLLNVAL))) { ssh_channel_send_eof (chan); pid = waitpid (state.childpid, &status, 0); if (pid < 0) { g_critical ("couldn't wait on child process: %m"); } else { if (WIFSIGNALED (status)) ssh_channel_request_send_exit_signal (chan, strsignal (WTERMSIG (status)), 0, "", ""); else ssh_channel_request_send_exit_status (chan, WEXITSTATUS (status)); } ret = ssh_blocking_flush (state.session, -1); if (ret != SSH_OK && ret != SSH_CLOSED) g_message ("ssh_blocking_flush() failed: %d", ret); ssh_channel_close (chan); ssh_channel_free (chan); ret = ssh_blocking_flush (state.session, -1); if (ret != SSH_OK && ret != SSH_CLOSED) g_message ("ssh_blocking_flush() failed: %d", ret); state.channel = NULL; ssh_event_remove_fd (state.event, fd); sz = -1; } return sz; }
int main(int argc, char **argv){ ssh_session session; ssh_bind sshbind; ssh_message message; ssh_channel chan=0; char buf[2048]; int auth=0; int shell=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"); #ifdef HAVE_ARGP_H /* * Parse our arguments; every option seen by parse_opt will * be reflected in arguments. */ argp_parse (&argp, argc, argv, 0, 0, sshbind); #else (void) argc; (void) argv; #endif #ifdef WITH_PCAP set_pcap(session); #endif if(ssh_bind_listen(sshbind)<0){ printf("Error listening to socket: %s\n", ssh_get_error(sshbind)); return 1; } printf("Started sample libssh sshd on port %d\n", port); printf("You can login as the user %s with the password %s\n", SSHD_USER, SSHD_PASSWORD); 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_handle_key_exchange(session)) { printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); return 1; } /* proceed to authentication */ auth = authenticate(session); if (!auth || !authenticated) { printf("Authentication error: %s\n", ssh_get_error(session)); ssh_disconnect(session); return 1; } /* wait for a channel session */ do { message = ssh_message_get(session); if(message){ if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN && ssh_message_subtype(message) == SSH_CHANNEL_SESSION) { chan = ssh_message_channel_request_open_reply_accept(message); ssh_message_free(message); break; } else { ssh_message_reply_default(message); ssh_message_free(message); } } else { break; } } while(!chan); if(!chan) { printf("Error: cleint did not ask for a channel session (%s)\n", ssh_get_error(session)); ssh_finalize(); return 1; } /* wait for a shell */ do { message = ssh_message_get(session); if(message != NULL) { if(ssh_message_type(message) == SSH_REQUEST_CHANNEL && ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) { shell = 1; ssh_message_channel_request_reply_success(message); ssh_message_free(message); break; } ssh_message_reply_default(message); ssh_message_free(message); } else { break; } } while(!shell); if(!shell) { printf("Error: No shell requested (%s)\n", ssh_get_error(session)); return 1; } printf("it works !\n"); do{ i=ssh_channel_read(chan,buf, 2048, 0); if(i>0) { if(*buf == '' || *buf == '') break; if(i == 1 && *buf == '\r') ssh_channel_write(chan, "\r\n", 2); else ssh_channel_write(chan, buf, i); if (write(1,buf,i) < 0) { printf("error writing to buffer\n"); return 1; } } } while (i>0); ssh_channel_close(chan); ssh_disconnect(session); ssh_bind_free(sshbind); #ifdef WITH_PCAP cleanup_pcap(); #endif ssh_finalize(); return 0; }
int main(int argc, char **argv){ ssh_session session; ssh_bind sshbind; ssh_message message; ssh_channel chan=0; char buf[2048]; 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"); #ifdef HAVE_ARGP_H /* * Parse our arguments; every option seen by parse_opt will * be reflected in arguments. */ argp_parse (&argp, argc, argv, 0, 0, sshbind); #else (void) argc; (void) argv; #endif #ifdef WITH_PCAP set_pcap(session); #endif 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_handle_key_exchange(session)) { printf("ssh_handle_key_exchange: %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"); do{ i=ssh_channel_read(chan,buf, 2048, 0); if(i>0) { ssh_channel_write(chan, buf, i); if (write(1,buf,i) < 0) { printf("error writing to buffer\n"); return 1; } } } while (i>0); ssh_disconnect(session); ssh_bind_free(sshbind); #ifdef WITH_PCAP cleanup_pcap(); #endif ssh_finalize(); return 0; }