update ssh error reporting

This commit is contained in:
Daniel Larimer 2013-02-03 21:10:43 -05:00
parent ecd5fd4b96
commit 178dcea0c2

View file

@ -1,3 +1,6 @@
#include <fc/filesystem.hpp>
#include <fc/value_cast.hpp>
#include <boost/filesystem.hpp>
#include <fc/ssh/client.hpp> #include <fc/ssh/client.hpp>
#include <fc/ssh/process.hpp> #include <fc/ssh/process.hpp>
#include <fc/exception.hpp> #include <fc/exception.hpp>
@ -8,6 +11,7 @@
#include <fc/interprocess/file_mapping.hpp> #include <fc/interprocess/file_mapping.hpp>
#include <fc/unique_lock.hpp> #include <fc/unique_lock.hpp>
#include <fc/mutex.hpp> #include <fc/mutex.hpp>
#include <fc/error_report.hpp>
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <memory> #include <memory>
@ -146,11 +150,11 @@ namespace fc { namespace ssh {
void connect() { void connect() {
try { try {
if( libssh2_init(0) < 0 ) { FC_THROW_MSG( "Unable to init libssh2" ); } if( libssh2_init(0) < 0 ) { FC_THROW_REPORT( "Unable to init libssh2" ); }
auto eps = fc::asio::tcp::resolve( hostname, fc::lexical_cast<fc::string>(port) ); auto eps = fc::asio::tcp::resolve( hostname, fc::lexical_cast<fc::string>(port) );
if( eps.size() == 0 ) { if( eps.size() == 0 ) {
FC_THROW_MSG( "Unable to resolve '%s'", hostname ); FC_THROW_REPORT( "Unable to resolve host '${host}'", fc::value().set("host",hostname) );
} }
sock.reset( new boost::asio::ip::tcp::socket( fc::asio::default_io_service() ) ); sock.reset( new boost::asio::ip::tcp::socket( fc::asio::default_io_service() ) );
@ -173,15 +177,16 @@ namespace fc { namespace ssh {
if( ec < 0 ) { if( ec < 0 ) {
char* msg; char* msg;
libssh2_session_last_error( session, &msg, 0, 0 ); libssh2_session_last_error( session, &msg, 0, 0 );
FC_THROW_MSG( "Handshake error: %s - %s", ec, msg ); FC_THROW_REPORT( "SSH Handshake error: ${code} - ${message}",
fc::value().set("code",ec).set("message", msg) );
} }
/*const char* fingerprint = */libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); /*const char* fingerprint = */libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
// try to authenticate, throw on error. // try to authenticate, throw on error.
authenticate(); authenticate();
} catch (...) { } catch ( error_report& er ) {
close(); close();
throw; throw FC_REPORT_PUSH( er, "Unable to connect to ssh server" );;
} }
} }
@ -238,6 +243,7 @@ namespace fc { namespace ssh {
} }
void authenticate() { void authenticate() {
try {
char * alist = libssh2_userauth_list(session, uname.c_str(),uname.size()); char * alist = libssh2_userauth_list(session, uname.c_str(),uname.size());
char * msg = 0; char * msg = 0;
int ec = 0; int ec = 0;
@ -254,7 +260,8 @@ namespace fc { namespace ssh {
ec = libssh2_session_last_error(session,&msg,NULL,0); ec = libssh2_session_last_error(session,&msg,NULL,0);
} }
if( !alist ) { if( !alist ) {
FC_THROW_MSG( "Error getting authorization list: %s - %s", ec, msg ); FC_THROW_REPORT( "Error getting authorization list: ${code} - ${message}",
fc::value().set("code",ec).set("message",msg));
} }
} }
@ -290,7 +297,10 @@ namespace fc { namespace ssh {
if( try_keyboard() ) if( try_keyboard() )
return; return;
} }
FC_THROW_MSG( "Unable to authenticate" ); } catch ( error_report er ) {
throw FC_REPORT_PUSH( er, "Unable to authenticate ssh connection" );
}
FC_THROW_REPORT( "Unable to authenticate ssh connection" );
} // authenticate() } // authenticate()
bool try_pass() { bool try_pass() {
@ -386,10 +396,14 @@ namespace fc { namespace ssh {
} }
} else if( rprom ) { } else if( rprom ) {
if( rprom->wait() ) { if( rprom->wait() ) {
FC_THROW( boost::system::system_error(rprom->wait() ) ); FC_THROW_REPORT( "Socket Error ${message}",
fc::value().set( "message", boost::system::system_error(rprom->wait() ).what() ) );
} }
} else if( wprom ) { } else if( wprom ) {
if( wprom->wait() ) { FC_THROW( boost::system::system_error(wprom->wait() ) ); } if( wprom->wait() ) {
FC_THROW_REPORT( "Socket Error ${message}",
fc::value().set( "message", boost::system::system_error(wprom->wait() ).what() ) );
}
} }
} }
void init_sftp() { void init_sftp() {
@ -402,7 +416,7 @@ namespace fc { namespace ssh {
wait_on_socket(); wait_on_socket();
sftp = libssh2_sftp_init(session); sftp = libssh2_sftp_init(session);
} else { } else {
FC_THROW_MSG( "init sftp error %s: %s", ec, msg ); FC_THROW_REPORT( "init sftp error ${code} - ${message}", fc::value().set("code",ec).set("message",msg) );
} }
} }
} }
@ -450,10 +464,10 @@ namespace fc { namespace ssh {
// using namespace boost::filesystem; // using namespace boost::filesystem;
if( !fc::exists(local_path) ) { if( !fc::exists(local_path) ) {
FC_THROW_MSG( "Source file '%s' does not exist", local_path.string() ); FC_THROW_REPORT( "Source file '${file}' does not exist", fc::value().set("file",local_path) ) ;
} }
if( is_directory( local_path ) ) { if( is_directory( local_path ) ) {
FC_THROW_MSG( "Source path '%s' is a directory, expected a file.", local_path.string()); FC_THROW_REPORT( "Source file '${file}' is a directory, expected a file", fc::value().set("file",local_path) ) ;
} }
// memory map the file // memory map the file
@ -474,7 +488,8 @@ namespace fc { namespace ssh {
my->wait_on_socket(); my->wait_on_socket();
chan = libssh2_scp_send64( my->session, local_path.generic_string().c_str(), 0700, fsize, now, now ); chan = libssh2_scp_send64( my->session, local_path.generic_string().c_str(), 0700, fsize, now, now );
} else { } else {
FC_THROW_MSG( "scp %s to %s failed %s - %s",local_path.string(), remote_path.string(), ec, msg ); FC_THROW_REPORT( "scp ${local_file} to ${remote_file} failed ${code} - ${message}",
fc::value().set("local_file", local_path).set("remote_file",remote_path).set("code",ec).set("message",msg) );
} }
} }
try { try {
@ -489,7 +504,8 @@ namespace fc { namespace ssh {
if( r < 0 ) { if( r < 0 ) {
char* msg = 0; char* msg = 0;
int ec = libssh2_session_last_error( my->session, &msg, 0, 0 ); int ec = libssh2_session_last_error( my->session, &msg, 0, 0 );
FC_THROW_MSG( "scp failed %s - %s", ec, msg ); FC_THROW_REPORT( "scp failed ${code} - ${message}",
fc::value().set("code",ec).set("message",msg) );
} }
wrote += r; wrote += r;
pos += r; pos += r;
@ -511,16 +527,18 @@ namespace fc { namespace ssh {
if( ec < 0 ) { if( ec < 0 ) {
char* msg = 0; char* msg = 0;
int ec = libssh2_session_last_error( my->session, &msg, 0, 0 ); int ec = libssh2_session_last_error( my->session, &msg, 0, 0 );
FC_THROW_MSG( "scp failed %s - %s", ec, msg ); FC_THROW_REPORT( "scp failed ${code} - ${message}",
fc::value().set("code",ec).set("message",msg) );
} }
} }
void client::rm( const fc::path& remote_path ) { void client::rm( const fc::path& remote_path ) {
try {
auto s = stat(remote_path); auto s = stat(remote_path);
if( s.is_directory() ) { if( s.is_directory() ) {
FC_THROW_MSG( "Directory exists at path %s", remote_path.string() ); FC_THROW_REPORT( "sftp cannot remove directory ${path}", fc::value().set("path",remote_path) );
} }
else if( !s.exists() ) { else if( !s.exists() ) {
return; // nothing to do return; // nothing to do
@ -533,7 +551,10 @@ namespace fc { namespace ssh {
} }
if( 0 != rc ) { if( 0 != rc ) {
rc = libssh2_sftp_last_error(my->sftp); rc = libssh2_sftp_last_error(my->sftp);
FC_THROW_MSG( "rm error %s", rc ); FC_THROW_REPORT( "sftp rm failed ${code}", fc::value().set("code",rc) );
}
} catch ( error_report& er ) {
throw FC_REPORT_PUSH( er, "sftp remove '${remote_path}' failed", fc::value().set("remote_path",remote_path) );
} }
} }
@ -553,12 +574,25 @@ namespace fc { namespace ssh {
ft.permissions = att.permissions; ft.permissions = att.permissions;
return ft; return ft;
} }
void client::create_directories( const fc::path& rdir, int mode ) {
boost::filesystem::path dir = rdir;
boost::filesystem::path p;
auto pitr = dir.begin();
while( pitr != dir.end() ) {
p /= *pitr;
if( !stat( p ).exists() ) {
mkdir(p,mode);
}
++pitr;
}
}
void client::mkdir( const fc::path& rdir, int mode ) { void client::mkdir( const fc::path& rdir, int mode ) {
try {
auto s = stat(rdir); auto s = stat(rdir);
if( s.is_directory() ) return; if( s.is_directory() ) return;
else if( s.exists() ) { else if( s.exists() ) {
FC_THROW_MSG( "Non directory exists at path %s", rdir.generic_string().c_str() ); FC_THROW_REPORT( "File already exists at path ${path}", fc::value().set("path",rdir) );
} }
int rc = libssh2_sftp_mkdir(my->sftp, rdir.generic_string().c_str(), mode ); int rc = libssh2_sftp_mkdir(my->sftp, rdir.generic_string().c_str(), mode );
@ -568,7 +602,10 @@ namespace fc { namespace ssh {
} }
if( 0 != rc ) { if( 0 != rc ) {
rc = libssh2_sftp_last_error(my->sftp); rc = libssh2_sftp_last_error(my->sftp);
FC_THROW_MSG( "mkdir error %s", rc ); FC_THROW_REPORT( "sftp mkdir error", fc::value().set("code",rc) );
}
} catch ( error_report& er ) {
throw FC_REPORT_PUSH( er, "sftp failed to create directory '${directory}'", fc::value().set( "directory", rdir ) );
} }
} }
@ -693,11 +730,11 @@ namespace fc { namespace ssh {
ec = libssh2_channel_flush_ex( chan, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA ); ec = libssh2_channel_flush_ex( chan, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA );
} }
if( ec < 0 ) { if( ec < 0 ) {
FC_THROW_MSG( "flush failed: channel error %d", ec ); FC_THROW_REPORT( "ssh flush failed", fc::value().set( "channel_error", ec) );
} }
} }
int detail::process_impl::read_some( char* data, size_t len, int stream_id ){ int detail::process_impl::read_some( char* data, size_t len, int stream_id ){
if( !sshc.my->session ) { FC_THROW_MSG( "Session closed" ); } if( !sshc.my->session ) { FC_THROW_REPORT( "Session closed" ); }
int rc; int rc;
char* buf = data; char* buf = data;
@ -725,16 +762,16 @@ namespace fc { namespace ssh {
} }
} else { } else {
char* msg; char* msg;
if( !sshc.my || !sshc.my->session ) { FC_THROW_MSG( "Session closed" ); } if( !sshc.my || !sshc.my->session ) { FC_THROW_REPORT( "Session closed" ); }
rc = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 ); rc = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 );
FC_THROW_MSG( "read failed: %s - %s", rc, msg ); return buf-data; FC_THROW_REPORT( "read failed: ${message}", fc::value().set("message", msg).set("code", rc) );
} }
} }
} while( rc >= 0 && buflen); } while( rc >= 0 && buflen);
return buf-data; return buf-data;
} }
int detail::process_impl::write_some( const char* data, size_t len, int stream_id ) { int detail::process_impl::write_some( const char* data, size_t len, int stream_id ) {
if( !sshc.my->session ) { FC_THROW_MSG( "Session closed" ); } if( !sshc.my->session ) { FC_THROW_REPORT( "Session closed" ); }
int rc; int rc;
const char* buf = data; const char* buf = data;
@ -747,8 +784,7 @@ namespace fc { namespace ssh {
return buf-data; return buf-data;
} else if( rc == 0 ) { } else if( rc == 0 ) {
if( libssh2_channel_eof( chan ) ) { if( libssh2_channel_eof( chan ) ) {
elog( "return %1%", -1 ); FC_THROW_REPORT( "EOF" );
FC_THROW_MSG( "EOF" );
//return -1; // eof //return -1; // eof
} }
} else { } else {
@ -765,7 +801,7 @@ namespace fc { namespace ssh {
} else { } else {
char* msg; char* msg;
rc = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 ); rc = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 );
FC_THROW_MSG( "write failed: %s - %s", rc, msg ); FC_THROW_REPORT( "write failed: ${message}", fc::value().set("message",msg).set("code",rc) );
return buf-data; return buf-data;
} }
} }
@ -782,7 +818,7 @@ namespace fc { namespace ssh {
if( ec ) { if( ec ) {
char* msg = 0; char* msg = 0;
ec = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 ); ec = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 );
FC_THROW_MSG( "send eof failed: %s - %s", ec, msg ); FC_THROW_REPORT( "send eof failed: ${message}", fc::value().set("message",msg).set("code",ec) );
} }
} }
} }
@ -854,7 +890,7 @@ namespace fc { namespace ssh {
if( ec ) { if( ec ) {
char* msg = 0; char* msg = 0;
ec = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 ); ec = libssh2_session_last_error( sshc.my->session, &msg, 0, 0 );
FC_THROW_MSG( "libssh2_channel_exec failed: %s - %s", ec, msg ); FC_THROW_REPORT( "exec failed: ${message}", fc::value().set("message",msg).set("code",ec) );
} }
} }
LIBSSH2_CHANNEL* detail::client_impl::open_channel( const fc::string& pty_type ) { LIBSSH2_CHANNEL* detail::client_impl::open_channel( const fc::string& pty_type ) {
@ -869,7 +905,7 @@ namespace fc { namespace ssh {
ec = libssh2_session_last_error( session, &msg, 0, 0 ); ec = libssh2_session_last_error( session, &msg, 0, 0 );
} }
if( !chan ) { if( !chan ) {
FC_THROW_MSG( "libssh2_channel_open_session failed: %s - %s", ec, msg ); FC_THROW_REPORT( "libssh2_channel_open_session failed: ${message}", fc::value().set("message",msg).set("code",ec) );
} }
} }
@ -882,10 +918,14 @@ namespace fc { namespace ssh {
if( 0 != ec ) { if( 0 != ec ) {
char* msg; char* msg;
ec = libssh2_session_last_error( session, &msg, 0, 0 ); ec = libssh2_session_last_error( session, &msg, 0, 0 );
FC_THROW_MSG( "libssh2_channel_req_pty failed: %s - %s", ec, msg ); FC_THROW_REPORT( "libssh2_channel_req_pty failed: ${message}", fc::value().set("message",msg).set("code",ec) );
} }
} }
return chan; return chan;
} }
process& process::operator=( const process& p ) {
my = p.my;
return *this;
}
} } } }