adding basic ssh support, updating wait on any
This commit is contained in:
parent
ca1d78b29f
commit
6b14a176d0
52 changed files with 26570 additions and 1 deletions
|
|
@ -45,6 +45,7 @@ include_directories( ${OPENSSL_INCLUDE_DIR} )
|
||||||
include_directories( include )
|
include_directories( include )
|
||||||
|
|
||||||
set( sources
|
set( sources
|
||||||
|
src/ssh.cpp
|
||||||
src/process.cpp
|
src/process.cpp
|
||||||
src/http_connection.cpp
|
src/http_connection.cpp
|
||||||
src/json_rpc_connection.cpp
|
src/json_rpc_connection.cpp
|
||||||
|
|
@ -82,6 +83,9 @@ set( sources
|
||||||
src/file_mapping.cpp
|
src/file_mapping.cpp
|
||||||
# src/program_options.cpp
|
# src/program_options.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(vendor/libssh2-1.4.2)
|
||||||
|
|
||||||
setup_library( fc SOURCES ${sources} )
|
setup_library( fc SOURCES ${sources} )
|
||||||
|
|
||||||
setup_executable( json_rpc_test SOURCES tests/json_rpc_test.cpp LIBRARIES fc ${pthread_library} ${rt_library} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${rt_library} )
|
setup_executable( json_rpc_test SOURCES tests/json_rpc_test.cpp LIBRARIES fc ${pthread_library} ${rt_library} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${rt_library} )
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,10 @@ namespace fc {
|
||||||
void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2, T3&& a3 ) {
|
void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2, T3&& a3 ) {
|
||||||
throw_exception_( func, file, line, msg, to_string(fc::forward<T1>(a1) ), to_string( fc::forward<T2>(a2) ), to_string( fc::forward<T3>(a3) ) );
|
throw_exception_( func, file, line, msg, to_string(fc::forward<T1>(a1) ), to_string( fc::forward<T2>(a2) ), to_string( fc::forward<T3>(a3) ) );
|
||||||
}
|
}
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4>
|
||||||
|
void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2, T3&& a3, T4&& a4 ) {
|
||||||
|
throw_exception_( func, file, line, msg, to_string(fc::forward<T1>(a1) ), to_string( fc::forward<T2>(a2) ), to_string( fc::forward<T3>(a3) ), to_string( fc::forward<T4>(a4) ) );
|
||||||
|
}
|
||||||
|
|
||||||
fc::string except_str();
|
fc::string except_str();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ namespace fc {
|
||||||
m_prom->on_complete( fc::forward<CompletionHandler>(c) );
|
m_prom->on_complete( fc::forward<CompletionHandler>(c) );
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
friend class thread;
|
||||||
shared_ptr<promise<T>> m_prom;
|
shared_ptr<promise<T>> m_prom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -244,6 +245,7 @@ namespace fc {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class thread;
|
||||||
shared_ptr<promise<void>> m_prom;
|
shared_ptr<promise<void>> m_prom;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
45
include/fc/json_rpc_process_client.hpp
Normal file
45
include/fc/json_rpc_process_client.hpp
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fc/json_rpc_client.hpp>
|
||||||
|
#include <fc/process.hpp>
|
||||||
|
|
||||||
|
namespace fc { namespace json {
|
||||||
|
|
||||||
|
template<typename InterfaceType>
|
||||||
|
class rpc_process_client : public ptr<InterfaceType,fc::json::detail::rpc_member> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
fc::future<int> exec( const fc::path& exe, int opt = fc::process::open_all ) {
|
||||||
|
return exec( exe, fc::path(), opt );
|
||||||
|
}
|
||||||
|
fc::future<int> exec( const fc::path& exe, const fc::path& wd,
|
||||||
|
int opt = fc::process::open_all ) {
|
||||||
|
return exec( exe, fc::vector<fc::string>(), wd, opt );
|
||||||
|
}
|
||||||
|
fc::future<int> exec( const fc::path& exe, fc::vector<fc::string>&& args ,
|
||||||
|
int opt = fc::process::open_all ) {
|
||||||
|
return exec( exe, fc::move(args), fc::path(), opt );
|
||||||
|
}
|
||||||
|
fc::future<int> exec( const fc::path& exe, fc::vector<fc::string>&& args,
|
||||||
|
const fc::path& wd, int opt = fc::process::open_all ) {
|
||||||
|
auto r = _proc.exec( exe, fc::move(args), wd, opt );
|
||||||
|
_con.reset( new fc::json::rpc_stream_connection( _proc.out_stream(), _proc.in_stream() ) );
|
||||||
|
this->_vtable.reset(new fc::detail::vtable<InterfaceType,fc::json::detail::rpc_member>() );
|
||||||
|
this->_vtable->template visit<InterfaceType>( fc::json::detail::vtable_visitor(_con) );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kill() { _con->close(); _proc.kill(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns a stream that reads from the process' stderr
|
||||||
|
*/
|
||||||
|
fc::istream& err_stream() { return _proc.err_stream(); }
|
||||||
|
|
||||||
|
template<typename T&&>
|
||||||
|
void on_close( T&& f) { _con->on_close( fc::forward<T>(f) ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
fc::process _proc;
|
||||||
|
fc::json::rpc_stream_connection::ptr _con;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
@ -80,5 +80,9 @@ namespace fc {
|
||||||
fc::shared_ptr<T> dynamic_pointer_cast( const fc::shared_ptr<O>& t ) {
|
fc::shared_ptr<T> dynamic_pointer_cast( const fc::shared_ptr<O>& t ) {
|
||||||
return fc::shared_ptr<T>( dynamic_cast<T*>(t.get()), true );
|
return fc::shared_ptr<T>( dynamic_cast<T*>(t.get()), true );
|
||||||
}
|
}
|
||||||
|
template<typename T, typename O>
|
||||||
|
fc::shared_ptr<T> static_pointer_cast( const fc::shared_ptr<O>& t ) {
|
||||||
|
return fc::shared_ptr<T>( static_cast<T*>(t.get()), true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
116
include/fc/ssh/client.hpp
Normal file
116
include/fc/ssh/client.hpp
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fc/ssh/process.hpp>
|
||||||
|
#include <fc/function.hpp>
|
||||||
|
#include <fc/filesystem.hpp>
|
||||||
|
|
||||||
|
namespace fc {
|
||||||
|
class path;
|
||||||
|
namespace ssh {
|
||||||
|
namespace detail {
|
||||||
|
struct client_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum sftp_file_type {
|
||||||
|
named_pipe = 0010000,
|
||||||
|
directory = 0040000,
|
||||||
|
regular = 0100000,
|
||||||
|
symlink = 0120000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum sftp_file_mode {
|
||||||
|
owner_mask = 0000700, /* RWX mask for owner */
|
||||||
|
owner_read = 0000400, /* R for owner */
|
||||||
|
owner_write = 0000200, /* W for owner */
|
||||||
|
owner_exec = 0000100, /* X for owner */
|
||||||
|
group_mask = 0000070, /* RWX mask for group */
|
||||||
|
group_read = 0000040, /* R for group */
|
||||||
|
group_write = 0000020, /* W for group */
|
||||||
|
group_exec = 0000010, /* X for group */
|
||||||
|
other_mask = 0000007, /* RWX mask for other */
|
||||||
|
other_read = 0000004, /* R for other */
|
||||||
|
other_write = 0000002, /* W for other */
|
||||||
|
other_exec = 0000001 /* X for other */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct file_attrib {
|
||||||
|
file_attrib();
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
uint32_t uid;
|
||||||
|
uint32_t gid;
|
||||||
|
uint32_t permissions;
|
||||||
|
uint32_t atime;
|
||||||
|
uint32_t mtime;
|
||||||
|
|
||||||
|
bool exists();
|
||||||
|
bool is_file();
|
||||||
|
bool is_directory();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables communication over ssh using libssh2.
|
||||||
|
*
|
||||||
|
* Because the client creates other resources that depend upon
|
||||||
|
* it, it can only be created as a std::shared_ptr<client> (aka client::ptr)
|
||||||
|
* via client::create();
|
||||||
|
*/
|
||||||
|
class client {
|
||||||
|
public:
|
||||||
|
void connect( const fc::string& user, const fc::string& host, uint16_t port = 22);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect via password or keyboard-interactive
|
||||||
|
*/
|
||||||
|
void connect( const fc::string& user, const fc::string& pass, const fc::string& host, uint16_t port = 22);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief execute command on remote machine
|
||||||
|
* @param pty_type - whether or not to request a PTY when executing this process, this is necessary
|
||||||
|
* for interactive (non-buffered) IO with the remote process, if left empty no pty will be
|
||||||
|
* requested
|
||||||
|
*
|
||||||
|
* @note Processes launched in this manner will fully buffer stdin and stdout regardless of whether
|
||||||
|
* the process calls flush(). If you need unbuffered (streaming, realtime) access to standard
|
||||||
|
* out then you must launch the process via a shell.
|
||||||
|
*/
|
||||||
|
ssh::process exec( const fc::string& cmd, const fc::string& pty_type = "" );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief upload a file to remote host
|
||||||
|
* @param progress a callback to report / cancel upload.
|
||||||
|
* The callback takes two parameters, bytes sent and file size. To continue the
|
||||||
|
* transfer, the callback should return true. To cancel the callback should return false.
|
||||||
|
*/
|
||||||
|
void scp_send( const fc::path& local_path, const fc::path& remote_path,
|
||||||
|
fc::function<bool,size_t,size_t> progress = [](size_t,size_t){return true;} );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre remote_path is not a directory
|
||||||
|
* @post remote file is removed from the remote filesystem
|
||||||
|
*/
|
||||||
|
void rm( const fc::path& remote_path );
|
||||||
|
file_attrib stat( const fc::path& remote_path );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre all parent directories already exist.
|
||||||
|
* @pre remote_dir is not exist or is already a directory
|
||||||
|
* @post remote_dir exists.
|
||||||
|
*/
|
||||||
|
void mkdir( const fc::path& remote_dir, int mode = owner_read|owner_write|owner_exec );
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
|
client();
|
||||||
|
~client();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class process;
|
||||||
|
friend class process_impl;
|
||||||
|
fc::shared_ptr<detail::client_impl> my;
|
||||||
|
};
|
||||||
|
|
||||||
|
} } // namespace fc::ssh
|
||||||
25
include/fc/ssh/error.hpp
Normal file
25
include/fc/ssh/error.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef MACE_SSH_ERROR_HPP
|
||||||
|
#define MACE_SSH_ERROR_HPP
|
||||||
|
#include <boost/exception/all.hpp>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
namespace mace { namespace ssh {
|
||||||
|
typedef boost::error_info<struct err_msg_,std::string> err_msg;
|
||||||
|
|
||||||
|
struct exception : public virtual boost::exception, public virtual std::exception {
|
||||||
|
const char* what()const throw() { return "exception"; }
|
||||||
|
virtual void rethrow()const { BOOST_THROW_EXCEPTION(*this); }
|
||||||
|
const std::string& message()const { return *boost::get_error_info<mace::ssh::err_msg>(*this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} } // mace::ssh
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper macro for throwing exceptions with a message: THROW( "Hello World %1%, %2%", %"Hello" %"World" )
|
||||||
|
*/
|
||||||
|
#define MACE_SSH_THROW( MSG, ... ) \
|
||||||
|
do { \
|
||||||
|
BOOST_THROW_EXCEPTION( mace::ssh::exception() << mace::ssh::err_msg( (boost::format( MSG ) __VA_ARGS__ ).str() ) );\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#endif
|
||||||
53
include/fc/ssh/process.hpp
Normal file
53
include/fc/ssh/process.hpp
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fc/shared_ptr.hpp>
|
||||||
|
#include <fc/string.hpp>
|
||||||
|
|
||||||
|
namespace fc {
|
||||||
|
|
||||||
|
class istream;
|
||||||
|
class ostream;
|
||||||
|
class string;
|
||||||
|
|
||||||
|
namespace ssh {
|
||||||
|
|
||||||
|
class client;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
class process_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables communication with a process executed via
|
||||||
|
* client::exec().
|
||||||
|
*
|
||||||
|
* Process can only be created by mace::ssh::client.
|
||||||
|
*/
|
||||||
|
class process : public fc::retainable {
|
||||||
|
public:
|
||||||
|
typedef fc::shared_ptr<process> ptr;
|
||||||
|
|
||||||
|
~process();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks until the result code of the process has been returned.
|
||||||
|
*/
|
||||||
|
int result();
|
||||||
|
/**
|
||||||
|
* @brief returns a stream that writes to the procss' stdin
|
||||||
|
*/
|
||||||
|
fc::ostream& in_stream();
|
||||||
|
/**
|
||||||
|
* @brief returns a stream that reads from the process' stdout
|
||||||
|
*/
|
||||||
|
fc::istream& out_stream();
|
||||||
|
/**
|
||||||
|
* @brief returns a stream that reads from the process' stderr
|
||||||
|
*/
|
||||||
|
fc::istream& err_stream();
|
||||||
|
private:
|
||||||
|
friend class client;
|
||||||
|
process( client& c, const fc::string& cmd, const fc::string& pty_type = fc::string() );
|
||||||
|
|
||||||
|
fc::shared_ptr<detail::process_impl> my;
|
||||||
|
};
|
||||||
|
} } // fc::ssh
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef _FC_THREAD_HPP_
|
#ifndef _FC_THREAD_HPP_
|
||||||
#define _FC_THREAD_HPP_
|
#define _FC_THREAD_HPP_
|
||||||
#include <fc/task.hpp>
|
#include <fc/task.hpp>
|
||||||
#include <fc/vector_fwd.hpp>
|
#include <fc/vector.hpp>
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
class string;
|
class string;
|
||||||
|
|
@ -104,6 +104,13 @@ namespace fc {
|
||||||
priority current_priority()const;
|
priority current_priority()const;
|
||||||
~thread();
|
~thread();
|
||||||
|
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
int wait_any( const fc::future<T1>& f1, const fc::future<T2>& f2) {
|
||||||
|
fc::vector<fc::promise_base::ptr> proms(2);
|
||||||
|
proms[0] = fc::static_pointer_cast<fc::promise_base>(f1.m_prom);
|
||||||
|
proms[1] = fc::static_pointer_cast<fc::promise_base>(f2.m_prom);
|
||||||
|
return wait_any_until(fc::move(proms), fc::time_point::max() );
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
thread( class thread_d* );
|
thread( class thread_d* );
|
||||||
friend class promise_base;
|
friend class promise_base;
|
||||||
|
|
@ -126,6 +133,7 @@ namespace fc {
|
||||||
void async_task( task_base* t, const priority& p, const char* desc );
|
void async_task( task_base* t, const priority& p, const char* desc );
|
||||||
void async_task( task_base* t, const priority& p, const time_point& tp, const char* desc );
|
void async_task( task_base* t, const priority& p, const time_point& tp, const char* desc );
|
||||||
class thread_d* my;
|
class thread_d* my;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -153,6 +161,10 @@ namespace fc {
|
||||||
*
|
*
|
||||||
* @return 0 if f1 is ready, 1 if f2 is ready or throw on error.
|
* @return 0 if f1 is ready, 1 if f2 is ready or throw on error.
|
||||||
*/
|
*/
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
int wait_any( const fc::future<T1>& f1, const fc::future<T2>& f2) {
|
||||||
|
return fc::thread::current().wait_any(f1,f2);
|
||||||
|
}
|
||||||
int wait_any( fc::vector<promise_base::ptr>&& v, const microseconds& timeout_us = microseconds::max() );
|
int wait_any( fc::vector<promise_base::ptr>&& v, const microseconds& timeout_us = microseconds::max() );
|
||||||
int wait_any_until( fc::vector<promise_base::ptr>&& v, const time_point& tp );
|
int wait_any_until( fc::vector<promise_base::ptr>&& v, const time_point& tp );
|
||||||
|
|
||||||
|
|
|
||||||
523
src/ssh.cpp
Normal file
523
src/ssh.cpp
Normal file
|
|
@ -0,0 +1,523 @@
|
||||||
|
#include <fc/ssh/client.hpp>
|
||||||
|
#include <fc/exception.hpp>
|
||||||
|
#include <fc/iostream.hpp>
|
||||||
|
#include <fc/log.hpp>
|
||||||
|
#include <fc/thread.hpp>
|
||||||
|
#include <fc/vector.hpp>
|
||||||
|
#include <fc/interprocess/file_mapping.hpp>
|
||||||
|
#include <fc/unique_lock.hpp>
|
||||||
|
#include <fc/mutex.hpp>
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <fc/asio.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
namespace fc { namespace ssh {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
static int ssh_init = libssh2_init(0);
|
||||||
|
|
||||||
|
class process_impl : public fc::retainable {
|
||||||
|
public:
|
||||||
|
process_impl( const client& c ):sshc(c){}
|
||||||
|
|
||||||
|
client sshc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class client_impl : public fc::retainable {
|
||||||
|
public:
|
||||||
|
LIBSSH2_SESSION* session;
|
||||||
|
LIBSSH2_KNOWNHOSTS* knownhosts;
|
||||||
|
LIBSSH2_SFTP* sftp;
|
||||||
|
|
||||||
|
std::unique_ptr<boost::asio::ip::tcp::socket> sock;
|
||||||
|
boost::asio::ip::tcp::endpoint endpt;
|
||||||
|
|
||||||
|
fc::mutex scp_send_mutex;
|
||||||
|
fc::string uname;
|
||||||
|
fc::string upass;
|
||||||
|
fc::string pubkey;
|
||||||
|
fc::string privkey;
|
||||||
|
fc::string passphrase;
|
||||||
|
fc::string hostname;
|
||||||
|
uint16_t port;
|
||||||
|
bool session_connected;
|
||||||
|
fc::promise<boost::system::error_code>::ptr read_prom;
|
||||||
|
fc::promise<boost::system::error_code>::ptr write_prom;
|
||||||
|
|
||||||
|
static void kbd_callback(const char *name, int name_len,
|
||||||
|
const char *instruction, int instruction_len, int num_prompts,
|
||||||
|
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||||
|
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t n;
|
||||||
|
char buf[1024];
|
||||||
|
client_impl* self = (client_impl*)*abstract;
|
||||||
|
|
||||||
|
// printf("Performing keyboard-interactive authentication.\n");
|
||||||
|
|
||||||
|
// printf("Authentication name: '");
|
||||||
|
// fwrite(name, 1, name_len, stdout);
|
||||||
|
// printf("'\n");
|
||||||
|
|
||||||
|
// printf("Authentication instruction: '");
|
||||||
|
// fwrite(instruction, 1, instruction_len, stdout);
|
||||||
|
// printf("'\n");
|
||||||
|
|
||||||
|
// printf("Number of prompts: %d\n\n", num_prompts);
|
||||||
|
|
||||||
|
for (i = 0; i < num_prompts; i++) {
|
||||||
|
// printf("Prompt %d from server: '", i);
|
||||||
|
fwrite(prompts[i].text, 1, prompts[i].length, stdout);
|
||||||
|
// printf("'\n");
|
||||||
|
|
||||||
|
// printf("Please type response: ");
|
||||||
|
|
||||||
|
if( self->upass.size() == 0 ) {
|
||||||
|
fgets(buf, sizeof(buf), stdin);
|
||||||
|
n = strlen(buf);
|
||||||
|
while (n > 0 && strchr("\r\n", buf[n - 1]))
|
||||||
|
n--;
|
||||||
|
buf[n] = 0;
|
||||||
|
|
||||||
|
#ifdef WIN32 // fix warning
|
||||||
|
#define strdup _strdup
|
||||||
|
#endif
|
||||||
|
responses[i].text = strdup(buf);
|
||||||
|
responses[i].length = n;
|
||||||
|
} else {
|
||||||
|
responses[i].text = strdup(self->upass.c_str());
|
||||||
|
responses[i].length = self->upass.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("Response %d from user is '", i);
|
||||||
|
// fwrite(responses[i].text, 1, responses[i].length, stdout);
|
||||||
|
// printf("'\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("Done. Sending keyboard-interactive responses to server now.\n");
|
||||||
|
} // kbd_callback
|
||||||
|
|
||||||
|
void connect() {
|
||||||
|
try {
|
||||||
|
if( libssh2_init(0) < 0 ) { FC_THROW_MSG( "Unable to init libssh2" ); }
|
||||||
|
|
||||||
|
auto eps = fc::asio::tcp::resolve( hostname, fc::lexical_cast<fc::string>(port) );
|
||||||
|
if( eps.size() == 0 ) {
|
||||||
|
FC_THROW_MSG( "Unable to resolve '%s'", hostname );
|
||||||
|
}
|
||||||
|
sock.reset( new boost::asio::ip::tcp::socket( fc::asio::default_io_service() ) );
|
||||||
|
|
||||||
|
for( uint32_t i = 0; i < eps.size(); ++i ) {
|
||||||
|
try {
|
||||||
|
fc::asio::tcp::connect( *sock, eps[i] );
|
||||||
|
endpt = eps[i];
|
||||||
|
break;
|
||||||
|
} catch ( ... ) {}
|
||||||
|
}
|
||||||
|
session = libssh2_session_init();
|
||||||
|
*libssh2_session_abstract(session) = this;
|
||||||
|
|
||||||
|
libssh2_session_set_blocking( session, 0 );
|
||||||
|
int ec = libssh2_session_handshake( session, sock->native() );
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_session_handshake( session, sock->native() );
|
||||||
|
}
|
||||||
|
if( ec < 0 ) {
|
||||||
|
char* msg;
|
||||||
|
libssh2_session_last_error( session, &msg, 0, 0 );
|
||||||
|
FC_THROW_MSG( "Handshake error: %s - %s", ec, msg );
|
||||||
|
}
|
||||||
|
/*const char* fingerprint = */libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
|
|
||||||
|
// try to authenticate, throw on error.
|
||||||
|
authenticate();
|
||||||
|
} catch (...) {
|
||||||
|
close();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
if( session ) {
|
||||||
|
if( sftp ) {
|
||||||
|
int ec = libssh2_sftp_shutdown(sftp);
|
||||||
|
try {
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_sftp_shutdown(sftp);
|
||||||
|
}
|
||||||
|
}catch(...){
|
||||||
|
elog( "... caught error closing sftp session???" );
|
||||||
|
}
|
||||||
|
sftp = 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int ec = libssh2_session_disconnect(session, "exit cleanly" );
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_session_disconnect(session, "exit cleanly" );
|
||||||
|
}
|
||||||
|
ec = libssh2_session_free(session);
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_session_free(session );
|
||||||
|
}
|
||||||
|
session = 0;
|
||||||
|
} catch ( ... ){
|
||||||
|
elog( "... caught error freeing session???" );
|
||||||
|
session = 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if( sock ) {
|
||||||
|
slog( "closing socket" );
|
||||||
|
sock->close();
|
||||||
|
}
|
||||||
|
} catch ( ... ){
|
||||||
|
elog( "... caught error closing socket???" );
|
||||||
|
}
|
||||||
|
sock.reset(0);
|
||||||
|
try {
|
||||||
|
if( read_prom ) read_prom->wait();
|
||||||
|
} catch ( ... ){
|
||||||
|
wlog( "caught error waiting on read prom" );
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if( write_prom ) write_prom->wait();
|
||||||
|
} catch ( ... ){
|
||||||
|
wlog( "caught error waiting on write prom" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void authenticate() {
|
||||||
|
char * alist = libssh2_userauth_list(session, uname.c_str(),uname.size());
|
||||||
|
char * msg = 0;
|
||||||
|
int ec = 0;
|
||||||
|
|
||||||
|
if(alist==NULL){
|
||||||
|
if(libssh2_userauth_authenticated(session)){
|
||||||
|
return; // CONNECTED!
|
||||||
|
}
|
||||||
|
ec = libssh2_session_last_error(session,&msg,NULL,0);
|
||||||
|
|
||||||
|
while( !alist && (ec == LIBSSH2_ERROR_EAGAIN) ) {
|
||||||
|
wait_on_socket();
|
||||||
|
alist = libssh2_userauth_list(session, uname.c_str(), uname.size());
|
||||||
|
ec = libssh2_session_last_error(session,&msg,NULL,0);
|
||||||
|
}
|
||||||
|
if( !alist ) {
|
||||||
|
FC_THROW_MSG( "Error getting authorization list: %s - %s", ec, msg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split_alist;
|
||||||
|
bool pubkey = false;
|
||||||
|
bool pass = false;
|
||||||
|
bool keybd = false;
|
||||||
|
boost::split( split_alist, alist, boost::is_any_of(",") );
|
||||||
|
std::for_each( split_alist.begin(), split_alist.end(), [&](const std::string& s){
|
||||||
|
if( s == "publickey" ) {
|
||||||
|
pubkey = true;
|
||||||
|
}
|
||||||
|
else if( s == "password" ) {
|
||||||
|
pass = true;
|
||||||
|
}
|
||||||
|
else if( s == "keyboard-interactive" ) {
|
||||||
|
keybd = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slog( "Unknown/unsupported authentication type '%s'", s.c_str() );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if( pubkey ) {
|
||||||
|
if( try_pub_key() )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( pass ) {
|
||||||
|
if( try_pass() )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( keybd ) {
|
||||||
|
if( try_keyboard() )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FC_THROW_MSG( "Unable to authenticate" );
|
||||||
|
} // authenticate()
|
||||||
|
|
||||||
|
bool try_pass() {
|
||||||
|
int ec = libssh2_userauth_password(session, uname.c_str(), upass.c_str() );
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_userauth_password(session, uname.c_str(), upass.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ec;
|
||||||
|
}
|
||||||
|
bool try_keyboard() {
|
||||||
|
int ec = libssh2_userauth_keyboard_interactive(session, uname.c_str(),
|
||||||
|
&client_impl::kbd_callback);
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_userauth_keyboard_interactive(session, uname.c_str(),
|
||||||
|
&client_impl::kbd_callback);
|
||||||
|
}
|
||||||
|
return !ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_pub_key() {
|
||||||
|
int ec = libssh2_userauth_publickey_fromfile(session,
|
||||||
|
uname.c_str(),
|
||||||
|
pubkey.c_str(),
|
||||||
|
privkey.c_str(),
|
||||||
|
passphrase.c_str() );
|
||||||
|
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
ec = libssh2_userauth_publickey_fromfile(session,
|
||||||
|
uname.c_str(),
|
||||||
|
pubkey.c_str(),
|
||||||
|
privkey.c_str(),
|
||||||
|
passphrase.c_str() );
|
||||||
|
}
|
||||||
|
return !ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_on_socket() {
|
||||||
|
auto dir = libssh2_session_block_directions(session);
|
||||||
|
if( !dir ) return;
|
||||||
|
|
||||||
|
fc::promise<boost::system::error_code>::ptr rprom, wprom;
|
||||||
|
if( dir & LIBSSH2_SESSION_BLOCK_INBOUND ) {
|
||||||
|
rprom = read_prom;
|
||||||
|
if(!rprom.get()) {
|
||||||
|
// elog( " this %2% NEW READ PROM %1% ", read_prom.get(), this );
|
||||||
|
read_prom.reset( new fc::promise<boost::system::error_code>("read_prom") );
|
||||||
|
// wlog( " new read prom %1% this %2%", read_prom.get(), this );
|
||||||
|
rprom = read_prom;
|
||||||
|
sock->async_read_some( boost::asio::null_buffers(),
|
||||||
|
[=]( const boost::system::error_code& e, size_t ) {
|
||||||
|
this->read_prom->set_value(e);
|
||||||
|
this->read_prom.reset(0);
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
// elog( "already waiting on read %1%", read_prom.get() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dir & LIBSSH2_SESSION_BLOCK_OUTBOUND ) {
|
||||||
|
wprom = write_prom;
|
||||||
|
if( !write_prom ) {
|
||||||
|
write_prom.reset( new fc::promise<boost::system::error_code>("write_prom") );
|
||||||
|
wprom = write_prom;
|
||||||
|
sock->async_write_some( boost::asio::null_buffers(),
|
||||||
|
[=]( const boost::system::error_code& e, size_t ) {
|
||||||
|
this->write_prom->set_value(e);
|
||||||
|
this->write_prom.reset(0);
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
// elog( "already waiting on write" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boost::system::error_code ec;
|
||||||
|
if( rprom.get() && wprom.get() ) {
|
||||||
|
// elog( "************* Attempt to wait in either direction currently waits for both directions ****** " );
|
||||||
|
//wlog( "rprom %1% wprom %2%", rprom.get(), write_prom.get() );
|
||||||
|
// wlog( "wait on read %1% or write %2% ", rprom.get(), wprom.get() );
|
||||||
|
typedef fc::future<boost::system::error_code> fprom;
|
||||||
|
fprom fw(wprom);
|
||||||
|
fprom fr(rprom);
|
||||||
|
int r = fc::wait_any( fw, fr );
|
||||||
|
switch( r ) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if( rprom ) {
|
||||||
|
if( rprom->wait() ) {
|
||||||
|
FC_THROW( boost::system::system_error(rprom->wait() ) );
|
||||||
|
}
|
||||||
|
} else if( wprom ) {
|
||||||
|
if( wprom->wait() ) { FC_THROW( boost::system::system_error(wprom->wait() ) ); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void init_sftp() {
|
||||||
|
if( !sftp ) {
|
||||||
|
sftp = libssh2_sftp_init(session);
|
||||||
|
while( !sftp ) {
|
||||||
|
char* msg = 0;
|
||||||
|
int ec = libssh2_session_last_error(session,&msg,NULL,0);
|
||||||
|
if( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
wait_on_socket();
|
||||||
|
sftp = libssh2_sftp_init(session);
|
||||||
|
} else {
|
||||||
|
FC_THROW_MSG( "init sftp error %s: %s", ec, msg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
client::client():my( new detail::client_impl() ){}
|
||||||
|
client::~client(){}
|
||||||
|
|
||||||
|
void client::connect( const fc::string& user, const fc::string& host, uint16_t port ) {
|
||||||
|
my->hostname = host;
|
||||||
|
my->uname = user;
|
||||||
|
my->port = port;
|
||||||
|
my->connect();
|
||||||
|
}
|
||||||
|
void client::connect( const fc::string& user, const fc::string& pass,
|
||||||
|
const fc::string& host, uint16_t port ) {
|
||||||
|
my->hostname = host;
|
||||||
|
my->uname = user;
|
||||||
|
my->upass = pass;
|
||||||
|
my->port = port;
|
||||||
|
|
||||||
|
my->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssh::process client::exec( const fc::string& cmd, const fc::string& pty_type ) {
|
||||||
|
return ssh::process( *this, cmd, pty_type );
|
||||||
|
}
|
||||||
|
|
||||||
|
void client::scp_send( const fc::path& local_path, const fc::path& remote_path,
|
||||||
|
fc::function<bool,size_t,size_t> progress ) {
|
||||||
|
/**
|
||||||
|
* Tests have shown that if one scp is 'blocked' by a need to read (presumably to
|
||||||
|
* ack recv for the trx window), and then a second transfer begins that the first
|
||||||
|
* transfer will never be acked. Placing this mutex limits the transfer of
|
||||||
|
* one file at a time via SCP which is just as well because there is a fixed
|
||||||
|
* amount of bandwidth.
|
||||||
|
*/
|
||||||
|
fc::unique_lock<fc::mutex> lock(my->scp_send_mutex);
|
||||||
|
|
||||||
|
|
||||||
|
// using namespace boost::filesystem;
|
||||||
|
if( !fc::exists(local_path) ) {
|
||||||
|
FC_THROW_MSG( "Source file '%s' does not exist", local_path.string() );
|
||||||
|
}
|
||||||
|
if( is_directory( local_path ) ) {
|
||||||
|
FC_THROW_MSG( "Source path '%s' is a directory, expected a file.", local_path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory map the file
|
||||||
|
file_mapping fmap( local_path.string().c_str(), read_only );
|
||||||
|
size_t fsize = file_size(local_path);
|
||||||
|
|
||||||
|
mapped_region mr( fmap, fc::read_only, 0, fsize );
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL* chan = 0;
|
||||||
|
time_t now;
|
||||||
|
memset( &now, 0, sizeof(now) );
|
||||||
|
// TODO: preserve creation / modification date
|
||||||
|
chan = libssh2_scp_send64( my->session, remote_path.string().c_str(), 0700, fsize, now, now );
|
||||||
|
while( chan == 0 ) {
|
||||||
|
char* msg;
|
||||||
|
int ec = libssh2_session_last_error( my->session, &msg, 0, 0 );
|
||||||
|
if( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
my->wait_on_socket();
|
||||||
|
chan = libssh2_scp_send64( my->session, local_path.string().c_str(), 0700, fsize, now, now );
|
||||||
|
} else {
|
||||||
|
FC_THROW_MSG( "scp %s to %s failed %s - %s",local_path.string(), remote_path.string(), ec, msg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
uint64_t wrote = 0;
|
||||||
|
char* pos = reinterpret_cast<char*>(mr.get_address());
|
||||||
|
while( progress( wrote, fsize ) && wrote < fsize ) {
|
||||||
|
int r = libssh2_channel_write( chan, pos, fsize - wrote );
|
||||||
|
while( r == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
my->wait_on_socket();
|
||||||
|
r = libssh2_channel_write( chan, pos, fsize - wrote );
|
||||||
|
}
|
||||||
|
if( r < 0 ) {
|
||||||
|
char* msg = 0;
|
||||||
|
int ec = libssh2_session_last_error( my->session, &msg, 0, 0 );
|
||||||
|
FC_THROW_MSG( "scp failed %s - %s", ec, msg );
|
||||||
|
}
|
||||||
|
wrote += r;
|
||||||
|
pos += r;
|
||||||
|
}
|
||||||
|
} catch ( ... ) {
|
||||||
|
// clean up chan
|
||||||
|
int ec = libssh2_channel_free(chan );
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
my->wait_on_socket();
|
||||||
|
ec = libssh2_channel_free( chan );
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
int ec = libssh2_channel_free( chan );
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
my->wait_on_socket();
|
||||||
|
ec = libssh2_channel_free( chan );
|
||||||
|
}
|
||||||
|
if( ec < 0 ) {
|
||||||
|
char* msg = 0;
|
||||||
|
int ec = libssh2_session_last_error( my->session, &msg, 0, 0 );
|
||||||
|
FC_THROW_MSG( "scp failed %s - %s", ec, msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void client::rm( const fc::path& remote_path ) {
|
||||||
|
auto s = stat(remote_path);
|
||||||
|
if( s.is_directory() ) {
|
||||||
|
FC_THROW_MSG( "Directory exists at path %s", remote_path.string() );
|
||||||
|
}
|
||||||
|
else if( !s.exists() ) {
|
||||||
|
return; // nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = libssh2_sftp_unlink(my->sftp, remote_path.string().c_str() );
|
||||||
|
while( rc == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
my->wait_on_socket();
|
||||||
|
rc = libssh2_sftp_unlink(my->sftp, remote_path.string().c_str() );
|
||||||
|
}
|
||||||
|
if( 0 != rc ) {
|
||||||
|
rc = libssh2_sftp_last_error(my->sftp);
|
||||||
|
FC_THROW_MSG( "rm error %s", rc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file_attrib client::stat( const fc::path& remote_path ){
|
||||||
|
my->init_sftp();
|
||||||
|
LIBSSH2_SFTP_ATTRIBUTES att;
|
||||||
|
int ec = libssh2_sftp_stat( my->sftp, remote_path.string().c_str(), &att );
|
||||||
|
while( ec == LIBSSH2_ERROR_EAGAIN ) {
|
||||||
|
my->wait_on_socket();
|
||||||
|
ec = libssh2_sftp_stat( my->sftp, remote_path.string().c_str(), &att );
|
||||||
|
}
|
||||||
|
if( ec ) {
|
||||||
|
return file_attrib();
|
||||||
|
}
|
||||||
|
file_attrib ft;
|
||||||
|
ft.size = att.filesize;
|
||||||
|
ft.permissions = att.permissions;
|
||||||
|
return ft;
|
||||||
|
}
|
||||||
|
|
||||||
|
void client::mkdir( const fc::path& remote_dir, int mode ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void client::close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
||||||
26
vendor/libssh2-1.4.2/CMakeLists.txt
vendored
Normal file
26
vendor/libssh2-1.4.2/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
include_directories(include)
|
||||||
|
include_directories( ${OPENSSL_INCLUDE_DIR} )
|
||||||
|
SET( sources
|
||||||
|
src/agent.c
|
||||||
|
src/channel.c
|
||||||
|
src/comp.c
|
||||||
|
src/crypt.c
|
||||||
|
src/global.c
|
||||||
|
src/hostkey.c
|
||||||
|
src/keepalive.c
|
||||||
|
src/kex.c
|
||||||
|
src/knownhost.c
|
||||||
|
src/mac.c
|
||||||
|
src/misc.c
|
||||||
|
src/openssl.c
|
||||||
|
src/packet.c
|
||||||
|
src/publickey.c
|
||||||
|
src/scp.c
|
||||||
|
src/session.c
|
||||||
|
src/sftp.c
|
||||||
|
src/transport.c
|
||||||
|
src/userauth.c
|
||||||
|
src/version.c
|
||||||
|
)
|
||||||
|
|
||||||
|
SETUP_LIBRARY( ssh2 SOURCES ${sources} LIBRARIES ${libraries} LIBRARY_TYPE STATIC )
|
||||||
1188
vendor/libssh2-1.4.2/include/libssh2.h
vendored
Normal file
1188
vendor/libssh2-1.4.2/include/libssh2.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
118
vendor/libssh2-1.4.2/include/libssh2_publickey.h
vendored
Normal file
118
vendor/libssh2-1.4.2/include/libssh2_publickey.h
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Note: This include file is only needed for using the
|
||||||
|
* publickey SUBSYSTEM which is not the same as publickey
|
||||||
|
* authentication. For authentication you only need libssh2.h
|
||||||
|
*
|
||||||
|
* For more information on the publickey subsystem,
|
||||||
|
* refer to IETF draft: secsh-publickey
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBSSH2_PUBLICKEY_H
|
||||||
|
#define LIBSSH2_PUBLICKEY_H 1
|
||||||
|
|
||||||
|
#include "libssh2.h"
|
||||||
|
|
||||||
|
typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY;
|
||||||
|
|
||||||
|
typedef struct _libssh2_publickey_attribute {
|
||||||
|
const char *name;
|
||||||
|
unsigned long name_len;
|
||||||
|
const char *value;
|
||||||
|
unsigned long value_len;
|
||||||
|
char mandatory;
|
||||||
|
} libssh2_publickey_attribute;
|
||||||
|
|
||||||
|
typedef struct _libssh2_publickey_list {
|
||||||
|
unsigned char *packet; /* For freeing */
|
||||||
|
|
||||||
|
const unsigned char *name;
|
||||||
|
unsigned long name_len;
|
||||||
|
const unsigned char *blob;
|
||||||
|
unsigned long blob_len;
|
||||||
|
unsigned long num_attrs;
|
||||||
|
libssh2_publickey_attribute *attrs; /* free me */
|
||||||
|
} libssh2_publickey_list;
|
||||||
|
|
||||||
|
/* Generally use the first macro here, but if both name and value are string literals, you can use _fast() to take advantage of preprocessing */
|
||||||
|
#define libssh2_publickey_attribute(name, value, mandatory) \
|
||||||
|
{ (name), strlen(name), (value), strlen(value), (mandatory) },
|
||||||
|
#define libssh2_publickey_attribute_fast(name, value, mandatory) \
|
||||||
|
{ (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Publickey Subsystem */
|
||||||
|
LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey,
|
||||||
|
const unsigned char *name,
|
||||||
|
unsigned long name_len,
|
||||||
|
const unsigned char *blob,
|
||||||
|
unsigned long blob_len, char overwrite,
|
||||||
|
unsigned long num_attrs,
|
||||||
|
const libssh2_publickey_attribute attrs[]);
|
||||||
|
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \
|
||||||
|
num_attrs, attrs) \
|
||||||
|
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \
|
||||||
|
(overwrite), (num_attrs), (attrs))
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey,
|
||||||
|
const unsigned char *name,
|
||||||
|
unsigned long name_len,
|
||||||
|
const unsigned char *blob,
|
||||||
|
unsigned long blob_len);
|
||||||
|
#define libssh2_publickey_remove(pkey, name, blob, blob_len) \
|
||||||
|
libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len))
|
||||||
|
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
|
||||||
|
unsigned long *num_keys,
|
||||||
|
libssh2_publickey_list **pkey_list);
|
||||||
|
LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey,
|
||||||
|
libssh2_publickey_list *pkey_list);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ifndef: LIBSSH2_PUBLICKEY_H */
|
||||||
345
vendor/libssh2-1.4.2/include/libssh2_sftp.h
vendored
Normal file
345
vendor/libssh2-1.4.2/include/libssh2_sftp.h
vendored
Normal file
|
|
@ -0,0 +1,345 @@
|
||||||
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBSSH2_SFTP_H
|
||||||
|
#define LIBSSH2_SFTP_H 1
|
||||||
|
|
||||||
|
#include "libssh2.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Note: Version 6 was documented at the time of writing
|
||||||
|
* However it was marked as "DO NOT IMPLEMENT" due to pending changes
|
||||||
|
*
|
||||||
|
* Let's start with Version 3 (The version found in OpenSSH) and go from there
|
||||||
|
*/
|
||||||
|
#define LIBSSH2_SFTP_VERSION 3
|
||||||
|
|
||||||
|
typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP;
|
||||||
|
typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE;
|
||||||
|
typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES;
|
||||||
|
typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS;
|
||||||
|
|
||||||
|
/* Flags for open_ex() */
|
||||||
|
#define LIBSSH2_SFTP_OPENFILE 0
|
||||||
|
#define LIBSSH2_SFTP_OPENDIR 1
|
||||||
|
|
||||||
|
/* Flags for rename_ex() */
|
||||||
|
#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001
|
||||||
|
#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002
|
||||||
|
#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004
|
||||||
|
|
||||||
|
/* Flags for stat_ex() */
|
||||||
|
#define LIBSSH2_SFTP_STAT 0
|
||||||
|
#define LIBSSH2_SFTP_LSTAT 1
|
||||||
|
#define LIBSSH2_SFTP_SETSTAT 2
|
||||||
|
|
||||||
|
/* Flags for symlink_ex() */
|
||||||
|
#define LIBSSH2_SFTP_SYMLINK 0
|
||||||
|
#define LIBSSH2_SFTP_READLINK 1
|
||||||
|
#define LIBSSH2_SFTP_REALPATH 2
|
||||||
|
|
||||||
|
/* SFTP attribute flag bits */
|
||||||
|
#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001
|
||||||
|
#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002
|
||||||
|
#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004
|
||||||
|
#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008
|
||||||
|
#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000
|
||||||
|
|
||||||
|
/* SFTP statvfs flag bits */
|
||||||
|
#define LIBSSH2_SFTP_ST_RDONLY 0x00000001
|
||||||
|
#define LIBSSH2_SFTP_ST_NOSUID 0x00000002
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP_ATTRIBUTES {
|
||||||
|
/* If flags & ATTR_* bit is set, then the value in this struct will be
|
||||||
|
* meaningful Otherwise it should be ignored
|
||||||
|
*/
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
libssh2_uint64_t filesize;
|
||||||
|
unsigned long uid, gid;
|
||||||
|
unsigned long permissions;
|
||||||
|
unsigned long atime, mtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP_STATVFS {
|
||||||
|
libssh2_uint64_t f_bsize; /* file system block size */
|
||||||
|
libssh2_uint64_t f_frsize; /* fragment size */
|
||||||
|
libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */
|
||||||
|
libssh2_uint64_t f_bfree; /* # free blocks */
|
||||||
|
libssh2_uint64_t f_bavail; /* # free blocks for non-root */
|
||||||
|
libssh2_uint64_t f_files; /* # inodes */
|
||||||
|
libssh2_uint64_t f_ffree; /* # free inodes */
|
||||||
|
libssh2_uint64_t f_favail; /* # free inodes for non-root */
|
||||||
|
libssh2_uint64_t f_fsid; /* file system ID */
|
||||||
|
libssh2_uint64_t f_flag; /* mount flags */
|
||||||
|
libssh2_uint64_t f_namemax; /* maximum filename length */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SFTP filetypes */
|
||||||
|
#define LIBSSH2_SFTP_TYPE_REGULAR 1
|
||||||
|
#define LIBSSH2_SFTP_TYPE_DIRECTORY 2
|
||||||
|
#define LIBSSH2_SFTP_TYPE_SYMLINK 3
|
||||||
|
#define LIBSSH2_SFTP_TYPE_SPECIAL 4
|
||||||
|
#define LIBSSH2_SFTP_TYPE_UNKNOWN 5
|
||||||
|
#define LIBSSH2_SFTP_TYPE_SOCKET 6
|
||||||
|
#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7
|
||||||
|
#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8
|
||||||
|
#define LIBSSH2_SFTP_TYPE_FIFO 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reproduce the POSIX file modes here for systems that are not POSIX
|
||||||
|
* compliant.
|
||||||
|
*
|
||||||
|
* These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES"
|
||||||
|
*/
|
||||||
|
/* File type */
|
||||||
|
#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */
|
||||||
|
#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */
|
||||||
|
#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */
|
||||||
|
#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */
|
||||||
|
#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */
|
||||||
|
#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */
|
||||||
|
#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */
|
||||||
|
#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */
|
||||||
|
|
||||||
|
/* File mode */
|
||||||
|
/* Read, write, execute/search by owner */
|
||||||
|
#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */
|
||||||
|
#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */
|
||||||
|
#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */
|
||||||
|
#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */
|
||||||
|
/* Read, write, execute/search by group */
|
||||||
|
#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */
|
||||||
|
#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */
|
||||||
|
#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */
|
||||||
|
#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */
|
||||||
|
/* Read, write, execute/search by others */
|
||||||
|
#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */
|
||||||
|
#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */
|
||||||
|
#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */
|
||||||
|
#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */
|
||||||
|
|
||||||
|
/* macros to check for specific file types, added in 1.2.5 */
|
||||||
|
#define LIBSSH2_SFTP_S_ISLNK(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)
|
||||||
|
#define LIBSSH2_SFTP_S_ISREG(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG)
|
||||||
|
#define LIBSSH2_SFTP_S_ISDIR(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR)
|
||||||
|
#define LIBSSH2_SFTP_S_ISCHR(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR)
|
||||||
|
#define LIBSSH2_SFTP_S_ISBLK(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK)
|
||||||
|
#define LIBSSH2_SFTP_S_ISFIFO(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO)
|
||||||
|
#define LIBSSH2_SFTP_S_ISSOCK(m) \
|
||||||
|
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK)
|
||||||
|
|
||||||
|
/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open())
|
||||||
|
* Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */
|
||||||
|
#define LIBSSH2_FXF_READ 0x00000001
|
||||||
|
#define LIBSSH2_FXF_WRITE 0x00000002
|
||||||
|
#define LIBSSH2_FXF_APPEND 0x00000004
|
||||||
|
#define LIBSSH2_FXF_CREAT 0x00000008
|
||||||
|
#define LIBSSH2_FXF_TRUNC 0x00000010
|
||||||
|
#define LIBSSH2_FXF_EXCL 0x00000020
|
||||||
|
|
||||||
|
/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */
|
||||||
|
#define LIBSSH2_FX_OK 0
|
||||||
|
#define LIBSSH2_FX_EOF 1
|
||||||
|
#define LIBSSH2_FX_NO_SUCH_FILE 2
|
||||||
|
#define LIBSSH2_FX_PERMISSION_DENIED 3
|
||||||
|
#define LIBSSH2_FX_FAILURE 4
|
||||||
|
#define LIBSSH2_FX_BAD_MESSAGE 5
|
||||||
|
#define LIBSSH2_FX_NO_CONNECTION 6
|
||||||
|
#define LIBSSH2_FX_CONNECTION_LOST 7
|
||||||
|
#define LIBSSH2_FX_OP_UNSUPPORTED 8
|
||||||
|
#define LIBSSH2_FX_INVALID_HANDLE 9
|
||||||
|
#define LIBSSH2_FX_NO_SUCH_PATH 10
|
||||||
|
#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11
|
||||||
|
#define LIBSSH2_FX_WRITE_PROTECT 12
|
||||||
|
#define LIBSSH2_FX_NO_MEDIA 13
|
||||||
|
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14
|
||||||
|
#define LIBSSH2_FX_QUOTA_EXCEEDED 15
|
||||||
|
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 /* Initial mis-spelling */
|
||||||
|
#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16
|
||||||
|
#define LIBSSH2_FX_LOCK_CONFlICT 17 /* Initial mis-spelling */
|
||||||
|
#define LIBSSH2_FX_LOCK_CONFLICT 17
|
||||||
|
#define LIBSSH2_FX_DIR_NOT_EMPTY 18
|
||||||
|
#define LIBSSH2_FX_NOT_A_DIRECTORY 19
|
||||||
|
#define LIBSSH2_FX_INVALID_FILENAME 20
|
||||||
|
#define LIBSSH2_FX_LINK_LOOP 21
|
||||||
|
|
||||||
|
/* Returned by any function that would block during a read/write opperation */
|
||||||
|
#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||||
|
|
||||||
|
/* SFTP API */
|
||||||
|
LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
|
||||||
|
LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
|
||||||
|
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
||||||
|
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp);
|
||||||
|
|
||||||
|
/* File / Directory Ops */
|
||||||
|
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *filename,
|
||||||
|
unsigned int filename_len,
|
||||||
|
unsigned long flags,
|
||||||
|
long mode, int open_type);
|
||||||
|
#define libssh2_sftp_open(sftp, filename, flags, mode) \
|
||||||
|
libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \
|
||||||
|
(mode), LIBSSH2_SFTP_OPENFILE)
|
||||||
|
#define libssh2_sftp_opendir(sftp, path) \
|
||||||
|
libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \
|
||||||
|
LIBSSH2_SFTP_OPENDIR)
|
||||||
|
|
||||||
|
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
|
char *buffer, size_t buffer_maxlen);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
|
||||||
|
char *buffer, size_t buffer_maxlen,
|
||||||
|
char *longentry,
|
||||||
|
size_t longentry_maxlen,
|
||||||
|
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
|
||||||
|
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \
|
||||||
|
(attrs))
|
||||||
|
|
||||||
|
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
|
const char *buffer, size_t count);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
||||||
|
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
|
||||||
|
|
||||||
|
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||||
|
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
|
libssh2_uint64_t offset);
|
||||||
|
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
|
||||||
|
|
||||||
|
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
|
LIBSSH2_SFTP_ATTRIBUTES *attrs,
|
||||||
|
int setstat);
|
||||||
|
#define libssh2_sftp_fstat(handle, attrs) \
|
||||||
|
libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
||||||
|
#define libssh2_sftp_fsetstat(handle, attrs) \
|
||||||
|
libssh2_sftp_fstat_ex((handle), (attrs), 1)
|
||||||
|
|
||||||
|
/* Miscellaneous Ops */
|
||||||
|
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *source_filename,
|
||||||
|
unsigned int srouce_filename_len,
|
||||||
|
const char *dest_filename,
|
||||||
|
unsigned int dest_filename_len,
|
||||||
|
long flags);
|
||||||
|
#define libssh2_sftp_rename(sftp, sourcefile, destfile) \
|
||||||
|
libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \
|
||||||
|
(destfile), strlen(destfile), \
|
||||||
|
LIBSSH2_SFTP_RENAME_OVERWRITE | \
|
||||||
|
LIBSSH2_SFTP_RENAME_ATOMIC | \
|
||||||
|
LIBSSH2_SFTP_RENAME_NATIVE)
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *filename,
|
||||||
|
unsigned int filename_len);
|
||||||
|
#define libssh2_sftp_unlink(sftp, filename) \
|
||||||
|
libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
|
LIBSSH2_SFTP_STATVFS *st);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *path,
|
||||||
|
size_t path_len,
|
||||||
|
LIBSSH2_SFTP_STATVFS *st);
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *path,
|
||||||
|
unsigned int path_len, long mode);
|
||||||
|
#define libssh2_sftp_mkdir(sftp, path, mode) \
|
||||||
|
libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *path,
|
||||||
|
unsigned int path_len);
|
||||||
|
#define libssh2_sftp_rmdir(sftp, path) \
|
||||||
|
libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *path,
|
||||||
|
unsigned int path_len,
|
||||||
|
int stat_type,
|
||||||
|
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
#define libssh2_sftp_stat(sftp, path, attrs) \
|
||||||
|
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \
|
||||||
|
(attrs))
|
||||||
|
#define libssh2_sftp_lstat(sftp, path, attrs) \
|
||||||
|
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \
|
||||||
|
(attrs))
|
||||||
|
#define libssh2_sftp_setstat(sftp, path, attrs) \
|
||||||
|
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \
|
||||||
|
(attrs))
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
|
||||||
|
const char *path,
|
||||||
|
unsigned int path_len,
|
||||||
|
char *target,
|
||||||
|
unsigned int target_len, int link_type);
|
||||||
|
#define libssh2_sftp_symlink(sftp, orig, linkpath) \
|
||||||
|
libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \
|
||||||
|
strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
|
||||||
|
#define libssh2_sftp_readlink(sftp, path, target, maxlen) \
|
||||||
|
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
|
||||||
|
LIBSSH2_SFTP_READLINK)
|
||||||
|
#define libssh2_sftp_realpath(sftp, path, target, maxlen) \
|
||||||
|
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
|
||||||
|
LIBSSH2_SFTP_REALPATH)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_SFTP_H */
|
||||||
793
vendor/libssh2-1.4.2/src/agent.c
vendored
Normal file
793
vendor/libssh2-1.4.2/src/agent.c
vendored
Normal file
|
|
@ -0,0 +1,793 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 by Daiki Ueno
|
||||||
|
* Copyright (C) 2010 by Daniel Stenberg
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
#include <sys/un.h>
|
||||||
|
#else
|
||||||
|
/* Use the existence of sys/un.h as a test if Unix domain socket is
|
||||||
|
supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually
|
||||||
|
support them. */
|
||||||
|
#undef PF_UNIX
|
||||||
|
#endif
|
||||||
|
#include "userauth.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
/* Requests from client to agent for protocol 1 key operations */
|
||||||
|
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||||
|
#define SSH_AGENTC_RSA_CHALLENGE 3
|
||||||
|
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
|
||||||
|
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
|
||||||
|
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
|
||||||
|
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
|
||||||
|
|
||||||
|
/* Requests from client to agent for protocol 2 key operations */
|
||||||
|
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
|
||||||
|
#define SSH2_AGENTC_SIGN_REQUEST 13
|
||||||
|
#define SSH2_AGENTC_ADD_IDENTITY 17
|
||||||
|
#define SSH2_AGENTC_REMOVE_IDENTITY 18
|
||||||
|
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
|
||||||
|
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||||
|
|
||||||
|
/* Key-type independent requests from client to agent */
|
||||||
|
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
|
||||||
|
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||||
|
#define SSH_AGENTC_LOCK 22
|
||||||
|
#define SSH_AGENTC_UNLOCK 23
|
||||||
|
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||||
|
|
||||||
|
/* Generic replies from agent to client */
|
||||||
|
#define SSH_AGENT_FAILURE 5
|
||||||
|
#define SSH_AGENT_SUCCESS 6
|
||||||
|
|
||||||
|
/* Replies from agent to client for protocol 1 key operations */
|
||||||
|
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||||
|
#define SSH_AGENT_RSA_RESPONSE 4
|
||||||
|
|
||||||
|
/* Replies from agent to client for protocol 2 key operations */
|
||||||
|
#define SSH2_AGENT_IDENTITIES_ANSWER 12
|
||||||
|
#define SSH2_AGENT_SIGN_RESPONSE 14
|
||||||
|
|
||||||
|
/* Key constraint identifiers */
|
||||||
|
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||||
|
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||||
|
|
||||||
|
/* non-blocking mode on agent connection is not yet implemented, but
|
||||||
|
for future use. */
|
||||||
|
typedef enum {
|
||||||
|
agent_NB_state_init = 0,
|
||||||
|
agent_NB_state_request_created,
|
||||||
|
agent_NB_state_request_length_sent,
|
||||||
|
agent_NB_state_request_sent,
|
||||||
|
agent_NB_state_response_length_received,
|
||||||
|
agent_NB_state_response_received
|
||||||
|
} agent_nonblocking_states;
|
||||||
|
|
||||||
|
typedef struct agent_transaction_ctx {
|
||||||
|
unsigned char *request;
|
||||||
|
size_t request_len;
|
||||||
|
unsigned char *response;
|
||||||
|
size_t response_len;
|
||||||
|
agent_nonblocking_states state;
|
||||||
|
} *agent_transaction_ctx_t;
|
||||||
|
|
||||||
|
typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent);
|
||||||
|
typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent,
|
||||||
|
agent_transaction_ctx_t transctx);
|
||||||
|
typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent);
|
||||||
|
|
||||||
|
struct agent_publickey {
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
|
/* this is the struct we expose externally */
|
||||||
|
struct libssh2_agent_publickey external;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct agent_ops {
|
||||||
|
agent_connect_func connect;
|
||||||
|
agent_transact_func transact;
|
||||||
|
agent_disconnect_func disconnect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _LIBSSH2_AGENT
|
||||||
|
{
|
||||||
|
LIBSSH2_SESSION *session; /* the session this "belongs to" */
|
||||||
|
|
||||||
|
libssh2_socket_t fd;
|
||||||
|
|
||||||
|
struct agent_ops *ops;
|
||||||
|
|
||||||
|
struct agent_transaction_ctx transctx;
|
||||||
|
struct agent_publickey *identity;
|
||||||
|
struct list_head head; /* list of public keys */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef PF_UNIX
|
||||||
|
static int
|
||||||
|
agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
const char *path;
|
||||||
|
struct sockaddr_un s_un;
|
||||||
|
|
||||||
|
path = getenv("SSH_AUTH_SOCK");
|
||||||
|
if (!path)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
|
||||||
|
"no auth sock variable");
|
||||||
|
|
||||||
|
agent->fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (agent->fd < 0)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET,
|
||||||
|
"failed creating socket");
|
||||||
|
|
||||||
|
s_un.sun_family = AF_UNIX;
|
||||||
|
strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
|
||||||
|
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
|
||||||
|
close (agent->fd);
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||||
|
"failed connecting with agent");
|
||||||
|
}
|
||||||
|
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||||
|
{
|
||||||
|
unsigned char buf[4];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Send the length of the request */
|
||||||
|
if (transctx->state == agent_NB_state_request_created) {
|
||||||
|
_libssh2_htonu32(buf, transctx->request_len);
|
||||||
|
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0);
|
||||||
|
if (rc == -EAGAIN)
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
else if (rc < 0)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
"agent send failed");
|
||||||
|
transctx->state = agent_NB_state_request_length_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the request body */
|
||||||
|
if (transctx->state == agent_NB_state_request_length_sent) {
|
||||||
|
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request,
|
||||||
|
transctx->request_len, 0);
|
||||||
|
if (rc == -EAGAIN)
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
else if (rc < 0)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
"agent send failed");
|
||||||
|
transctx->state = agent_NB_state_request_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive the length of a response */
|
||||||
|
if (transctx->state == agent_NB_state_request_sent) {
|
||||||
|
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0);
|
||||||
|
if (rc < 0) {
|
||||||
|
if (rc == -EAGAIN)
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
|
||||||
|
"agent recv failed");
|
||||||
|
}
|
||||||
|
transctx->response_len = _libssh2_ntohu32(buf);
|
||||||
|
transctx->response = LIBSSH2_ALLOC(agent->session,
|
||||||
|
transctx->response_len);
|
||||||
|
if (!transctx->response)
|
||||||
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
|
|
||||||
|
transctx->state = agent_NB_state_response_length_received;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive the response body */
|
||||||
|
if (transctx->state == agent_NB_state_response_length_received) {
|
||||||
|
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response,
|
||||||
|
transctx->response_len, 0);
|
||||||
|
if (rc < 0) {
|
||||||
|
if (rc == -EAGAIN)
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
"agent recv failed");
|
||||||
|
}
|
||||||
|
transctx->state = agent_NB_state_response_received;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_disconnect_unix(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = close(agent->fd);
|
||||||
|
|
||||||
|
if(ret == -1)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
|
||||||
|
"failed closing the agent socket");
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct agent_ops agent_ops_unix = {
|
||||||
|
agent_connect_unix,
|
||||||
|
agent_transact_unix,
|
||||||
|
agent_disconnect_unix
|
||||||
|
};
|
||||||
|
#endif /* PF_UNIX */
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* Code to talk to Pageant was taken from PuTTY.
|
||||||
|
*
|
||||||
|
* Portions copyright Robert de Bath, Joris van Rantwijk, Delian
|
||||||
|
* Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas
|
||||||
|
* Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa,
|
||||||
|
* Markus Kuhn, Colin Watson, and CORE SDI S.A.
|
||||||
|
*/
|
||||||
|
#define PAGEANT_COPYDATA_ID 0x804e50ba /* random goop */
|
||||||
|
#define PAGEANT_MAX_MSGLEN 8192
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_connect_pageant(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
hwnd = FindWindow("Pageant", "Pageant");
|
||||||
|
if (!hwnd)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||||
|
"failed connecting agent");
|
||||||
|
agent->fd = 0; /* Mark as the connection has been established */
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
char mapname[23];
|
||||||
|
HANDLE filemap;
|
||||||
|
unsigned char *p;
|
||||||
|
unsigned char *p2;
|
||||||
|
int id;
|
||||||
|
COPYDATASTRUCT cds;
|
||||||
|
|
||||||
|
if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL,
|
||||||
|
"illegal input");
|
||||||
|
|
||||||
|
hwnd = FindWindow("Pageant", "Pageant");
|
||||||
|
if (!hwnd)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||||
|
"found no pageant");
|
||||||
|
|
||||||
|
sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
|
||||||
|
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||||
|
0, PAGEANT_MAX_MSGLEN, mapname);
|
||||||
|
|
||||||
|
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||||
|
"failed setting up pageant filemap");
|
||||||
|
|
||||||
|
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
|
||||||
|
_libssh2_store_str(&p2, (const char *)transctx->request,
|
||||||
|
transctx->request_len);
|
||||||
|
|
||||||
|
cds.dwData = PAGEANT_COPYDATA_ID;
|
||||||
|
cds.cbData = 1 + strlen(mapname);
|
||||||
|
cds.lpData = mapname;
|
||||||
|
|
||||||
|
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
|
||||||
|
if (id > 0) {
|
||||||
|
transctx->response_len = _libssh2_ntohu32(p);
|
||||||
|
if (transctx->response_len > PAGEANT_MAX_MSGLEN) {
|
||||||
|
UnmapViewOfFile(p);
|
||||||
|
CloseHandle(filemap);
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||||
|
"agent setup fail");
|
||||||
|
}
|
||||||
|
transctx->response = LIBSSH2_ALLOC(agent->session,
|
||||||
|
transctx->response_len);
|
||||||
|
if (!transctx->response) {
|
||||||
|
UnmapViewOfFile(p);
|
||||||
|
CloseHandle(filemap);
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"agent malloc");
|
||||||
|
}
|
||||||
|
memcpy(transctx->response, p + 4, transctx->response_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnmapViewOfFile(p);
|
||||||
|
CloseHandle(filemap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_disconnect_pageant(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
agent->fd = LIBSSH2_INVALID_SOCKET;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct agent_ops agent_ops_pageant = {
|
||||||
|
agent_connect_pageant,
|
||||||
|
agent_transact_pageant,
|
||||||
|
agent_disconnect_pageant
|
||||||
|
};
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
struct agent_ops *ops;
|
||||||
|
} supported_backends[] = {
|
||||||
|
#ifdef WIN32
|
||||||
|
{"Pageant", &agent_ops_pageant},
|
||||||
|
#endif /* WIN32 */
|
||||||
|
#ifdef PF_UNIX
|
||||||
|
{"Unix", &agent_ops_unix},
|
||||||
|
#endif /* PF_UNIX */
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||||
|
const unsigned char *data, size_t data_len, void **abstract)
|
||||||
|
{
|
||||||
|
LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract);
|
||||||
|
agent_transaction_ctx_t transctx = &agent->transctx;
|
||||||
|
struct agent_publickey *identity = agent->identity;
|
||||||
|
ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4;
|
||||||
|
ssize_t method_len;
|
||||||
|
unsigned char *s;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Create a request to sign the data */
|
||||||
|
if (transctx->state == agent_NB_state_init) {
|
||||||
|
s = transctx->request = LIBSSH2_ALLOC(session, len);
|
||||||
|
if (!transctx->request)
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"out of memory");
|
||||||
|
|
||||||
|
*s++ = SSH2_AGENTC_SIGN_REQUEST;
|
||||||
|
/* key blob */
|
||||||
|
_libssh2_store_str(&s, (const char *)identity->external.blob,
|
||||||
|
identity->external.blob_len);
|
||||||
|
/* data */
|
||||||
|
_libssh2_store_str(&s, (const char *)data, data_len);
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
_libssh2_store_u32(&s, 0);
|
||||||
|
|
||||||
|
transctx->request_len = s - transctx->request;
|
||||||
|
transctx->state = agent_NB_state_request_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure to be re-called as a result of EAGAIN. */
|
||||||
|
if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST)
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
|
||||||
|
"illegal request");
|
||||||
|
|
||||||
|
if (!agent->ops)
|
||||||
|
/* if no agent has been connected, bail out */
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
|
||||||
|
"agent not connected");
|
||||||
|
|
||||||
|
rc = agent->ops->transact(agent, transctx);
|
||||||
|
if (rc) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
LIBSSH2_FREE(session, transctx->request);
|
||||||
|
transctx->request = NULL;
|
||||||
|
|
||||||
|
len = transctx->response_len;
|
||||||
|
s = transctx->response;
|
||||||
|
len--;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (*s != SSH2_AGENT_SIGN_RESPONSE) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
|
||||||
|
/* Skip the entire length of the signature */
|
||||||
|
len -= 4;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
/* Skip signing method */
|
||||||
|
len -= 4;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
method_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
len -= method_len;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s += method_len;
|
||||||
|
|
||||||
|
/* Read the signature */
|
||||||
|
len -= 4;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
*sig_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
len -= *sig_len;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sig = LIBSSH2_ALLOC(session, *sig_len);
|
||||||
|
if (!*sig) {
|
||||||
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memcpy(*sig, s, *sig_len);
|
||||||
|
|
||||||
|
error:
|
||||||
|
LIBSSH2_FREE(session, transctx->request);
|
||||||
|
transctx->request = NULL;
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, transctx->response);
|
||||||
|
transctx->response = NULL;
|
||||||
|
|
||||||
|
return _libssh2_error(session, rc, "agent sign failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
agent_list_identities(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
agent_transaction_ctx_t transctx = &agent->transctx;
|
||||||
|
ssize_t len, num_identities;
|
||||||
|
unsigned char *s;
|
||||||
|
int rc;
|
||||||
|
unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES;
|
||||||
|
|
||||||
|
/* Create a request to list identities */
|
||||||
|
if (transctx->state == agent_NB_state_init) {
|
||||||
|
transctx->request = &c;
|
||||||
|
transctx->request_len = 1;
|
||||||
|
transctx->state = agent_NB_state_request_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure to be re-called as a result of EAGAIN. */
|
||||||
|
if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES)
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
|
||||||
|
"illegal agent request");
|
||||||
|
|
||||||
|
if (!agent->ops)
|
||||||
|
/* if no agent has been connected, bail out */
|
||||||
|
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
|
||||||
|
"agent not connected");
|
||||||
|
|
||||||
|
rc = agent->ops->transact(agent, transctx);
|
||||||
|
if (rc) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
transctx->request = NULL;
|
||||||
|
|
||||||
|
len = transctx->response_len;
|
||||||
|
s = transctx->response;
|
||||||
|
len--;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (*s != SSH2_AGENT_IDENTITIES_ANSWER) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
|
||||||
|
/* Read the length of identities */
|
||||||
|
len -= 4;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
num_identities = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
while (num_identities--) {
|
||||||
|
struct agent_publickey *identity;
|
||||||
|
ssize_t comment_len;
|
||||||
|
|
||||||
|
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
|
||||||
|
if (!identity) {
|
||||||
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the length of the blob */
|
||||||
|
len -= 4;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
identity->external.blob_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
/* Read the blob */
|
||||||
|
len -= identity->external.blob_len;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
identity->external.blob = LIBSSH2_ALLOC(agent->session,
|
||||||
|
identity->external.blob_len);
|
||||||
|
if (!identity->external.blob) {
|
||||||
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memcpy(identity->external.blob, s, identity->external.blob_len);
|
||||||
|
s += identity->external.blob_len;
|
||||||
|
|
||||||
|
/* Read the length of the comment */
|
||||||
|
len -= 4;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
comment_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
/* Read the comment */
|
||||||
|
len -= comment_len;
|
||||||
|
if (len < 0) {
|
||||||
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
identity->external.comment = LIBSSH2_ALLOC(agent->session,
|
||||||
|
comment_len + 1);
|
||||||
|
if (!identity->external.comment) {
|
||||||
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
identity->external.comment[comment_len] = '\0';
|
||||||
|
memcpy(identity->external.comment, s, comment_len);
|
||||||
|
s += comment_len;
|
||||||
|
|
||||||
|
_libssh2_list_add(&agent->head, &identity->node);
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
LIBSSH2_FREE(agent->session, transctx->response);
|
||||||
|
transctx->response = NULL;
|
||||||
|
|
||||||
|
return _libssh2_error(agent->session, rc,
|
||||||
|
"agent list id failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
agent_free_identities(LIBSSH2_AGENT *agent) {
|
||||||
|
struct agent_publickey *node;
|
||||||
|
struct agent_publickey *next;
|
||||||
|
|
||||||
|
for (node = _libssh2_list_first(&agent->head); node; node = next) {
|
||||||
|
next = _libssh2_list_next(&node->node);
|
||||||
|
LIBSSH2_FREE(agent->session, node->external.blob);
|
||||||
|
LIBSSH2_FREE(agent->session, node->external.comment);
|
||||||
|
LIBSSH2_FREE(agent->session, node);
|
||||||
|
}
|
||||||
|
_libssh2_list_init(&agent->head);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2
|
||||||
|
/*
|
||||||
|
* agent_publickey_to_external()
|
||||||
|
*
|
||||||
|
* Copies data from the internal to the external representation struct.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static struct libssh2_agent_publickey *
|
||||||
|
agent_publickey_to_external(struct agent_publickey *node)
|
||||||
|
{
|
||||||
|
struct libssh2_agent_publickey *ext = &node->external;
|
||||||
|
|
||||||
|
ext->magic = AGENT_PUBLICKEY_MAGIC;
|
||||||
|
ext->node = node;
|
||||||
|
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_init
|
||||||
|
*
|
||||||
|
* Init an ssh-agent handle. Returns the pointer to the handle.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
LIBSSH2_API LIBSSH2_AGENT *
|
||||||
|
libssh2_agent_init(LIBSSH2_SESSION *session)
|
||||||
|
{
|
||||||
|
LIBSSH2_AGENT *agent;
|
||||||
|
|
||||||
|
agent = LIBSSH2_ALLOC(session, sizeof *agent);
|
||||||
|
if (!agent) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate space for agent connection");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(agent, 0, sizeof *agent);
|
||||||
|
agent->session = session;
|
||||||
|
_libssh2_list_init(&agent->head);
|
||||||
|
|
||||||
|
return agent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_connect()
|
||||||
|
*
|
||||||
|
* Connect to an ssh-agent.
|
||||||
|
*
|
||||||
|
* Returns 0 if succeeded, or a negative value for error.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_agent_connect(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
int i, rc = -1;
|
||||||
|
for (i = 0; supported_backends[i].name; i++) {
|
||||||
|
agent->ops = supported_backends[i].ops;
|
||||||
|
rc = agent->ops->connect(agent);
|
||||||
|
if (!rc)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_list_identities()
|
||||||
|
*
|
||||||
|
* Request ssh-agent to list identities.
|
||||||
|
*
|
||||||
|
* Returns 0 if succeeded, or a negative value for error.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
memset(&agent->transctx, 0, sizeof agent->transctx);
|
||||||
|
/* Abondon the last fetched identities */
|
||||||
|
agent_free_identities(agent);
|
||||||
|
return agent_list_identities(agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_get_identity()
|
||||||
|
*
|
||||||
|
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
|
||||||
|
* the first one. Or pass a poiner to the previously returned one to get the
|
||||||
|
* next.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 if a fine public key was stored in 'store'
|
||||||
|
* 1 if end of public keys
|
||||||
|
* [negative] on errors
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
|
||||||
|
struct libssh2_agent_publickey **ext,
|
||||||
|
struct libssh2_agent_publickey *oprev)
|
||||||
|
{
|
||||||
|
struct agent_publickey *node;
|
||||||
|
if (oprev && oprev->node) {
|
||||||
|
/* we have a starting point */
|
||||||
|
struct agent_publickey *prev = oprev->node;
|
||||||
|
|
||||||
|
/* get the next node in the list */
|
||||||
|
node = _libssh2_list_next(&prev->node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node = _libssh2_list_first(&agent->head);
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
/* no (more) node */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
*ext = agent_publickey_to_external(node);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_userauth()
|
||||||
|
*
|
||||||
|
* Do publickey user authentication with the help of ssh-agent.
|
||||||
|
*
|
||||||
|
* Returns 0 if succeeded, or a negative value for error.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_agent_userauth(LIBSSH2_AGENT *agent,
|
||||||
|
const char *username,
|
||||||
|
struct libssh2_agent_publickey *identity)
|
||||||
|
{
|
||||||
|
void *abstract = agent;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
|
||||||
|
memset(&agent->transctx, 0, sizeof agent->transctx);
|
||||||
|
agent->identity = identity->node;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLOCK_ADJUST(rc, agent->session,
|
||||||
|
_libssh2_userauth_publickey(agent->session, username,
|
||||||
|
strlen(username),
|
||||||
|
identity->blob,
|
||||||
|
identity->blob_len,
|
||||||
|
agent_sign,
|
||||||
|
&abstract));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_disconnect()
|
||||||
|
*
|
||||||
|
* Close a connection to an ssh-agent.
|
||||||
|
*
|
||||||
|
* Returns 0 if succeeded, or a negative value for error.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_agent_disconnect(LIBSSH2_AGENT *agent)
|
||||||
|
{
|
||||||
|
if (agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET)
|
||||||
|
return agent->ops->disconnect(agent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_agent_free()
|
||||||
|
*
|
||||||
|
* Free an ssh-agent handle. This function also frees the internal
|
||||||
|
* collection of public keys.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API void
|
||||||
|
libssh2_agent_free(LIBSSH2_AGENT *agent) {
|
||||||
|
/* Allow connection freeing when the socket has lost its connection */
|
||||||
|
if (agent->fd != LIBSSH2_INVALID_SOCKET) {
|
||||||
|
libssh2_agent_disconnect(agent);
|
||||||
|
}
|
||||||
|
agent_free_identities(agent);
|
||||||
|
LIBSSH2_FREE(agent->session, agent);
|
||||||
|
}
|
||||||
2570
vendor/libssh2-1.4.2/src/channel.c
vendored
Normal file
2570
vendor/libssh2-1.4.2/src/channel.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
141
vendor/libssh2-1.4.2/src/channel.h
vendored
Normal file
141
vendor/libssh2-1.4.2/src/channel.h
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
#ifndef __LIBSSH2_CHANNEL_H
|
||||||
|
#define __LIBSSH2_CHANNEL_H
|
||||||
|
/* Copyright (c) 2008-2010 by Daniel Stenberg
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_receive_window_adjust
|
||||||
|
*
|
||||||
|
* Adjust the receive window for a channel by adjustment bytes. If the amount
|
||||||
|
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
|
||||||
|
* adjustment amount will be queued for a later packet.
|
||||||
|
*
|
||||||
|
* Always non-blocking.
|
||||||
|
*/
|
||||||
|
int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
||||||
|
uint32_t adjustment,
|
||||||
|
unsigned char force,
|
||||||
|
unsigned int *store);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_flush
|
||||||
|
*
|
||||||
|
* Flush data from one (or all) stream
|
||||||
|
* Returns number of bytes flushed, or negative on failure
|
||||||
|
*/
|
||||||
|
int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_free
|
||||||
|
*
|
||||||
|
* Make sure a channel is closed, then remove the channel from the session
|
||||||
|
* and free its resource(s)
|
||||||
|
*
|
||||||
|
* Returns 0 on success, negative on failure
|
||||||
|
*/
|
||||||
|
int _libssh2_channel_free(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_write
|
||||||
|
*
|
||||||
|
* Send data to a channel
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||||
|
const unsigned char *buf, size_t buflen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_open
|
||||||
|
*
|
||||||
|
* Establish a generic session channel
|
||||||
|
*/
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||||
|
uint32_t channel_type_len,
|
||||||
|
uint32_t window_size,
|
||||||
|
uint32_t packet_size,
|
||||||
|
const unsigned char *message, size_t message_len);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_process_startup
|
||||||
|
*
|
||||||
|
* Primitive for libssh2_channel_(shell|exec|subsystem)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
||||||
|
const char *request, size_t request_len,
|
||||||
|
const char *message, size_t message_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_read
|
||||||
|
*
|
||||||
|
* Read data from a channel
|
||||||
|
*
|
||||||
|
* It is important to not return 0 until the currently read channel is
|
||||||
|
* complete. If we read stuff from the wire but it was no payload data to fill
|
||||||
|
* in the buffer with, we MUST make sure to return PACKET_EAGAIN.
|
||||||
|
*/
|
||||||
|
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||||
|
char *buf, size_t buflen);
|
||||||
|
|
||||||
|
uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session);
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
|
||||||
|
uint32_t channel_id);
|
||||||
|
|
||||||
|
size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
|
||||||
|
int stream_id);
|
||||||
|
|
||||||
|
int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_channel_forward_cancel
|
||||||
|
*
|
||||||
|
* Stop listening on a remote port and free the listener
|
||||||
|
* Toss out any pending (un-accept()ed) connections
|
||||||
|
*
|
||||||
|
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
|
||||||
|
*/
|
||||||
|
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
|
||||||
|
|
||||||
|
#endif /* __LIBSSH2_CHANNEL_H */
|
||||||
|
|
||||||
390
vendor/libssh2-1.4.2/src/comp.c
vendored
Normal file
390
vendor/libssh2-1.4.2/src/comp.c
vendored
Normal file
|
|
@ -0,0 +1,390 @@
|
||||||
|
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* Copyright (c) 2010, Daniel Stenberg <daniel@haxx.se>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#ifdef LIBSSH2_HAVE_ZLIB
|
||||||
|
# include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "comp.h"
|
||||||
|
|
||||||
|
/* ********
|
||||||
|
* none *
|
||||||
|
******** */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* comp_method_none_comp
|
||||||
|
*
|
||||||
|
* Minimalist compression: Absolutely none
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char *dest,
|
||||||
|
size_t *dest_len,
|
||||||
|
const unsigned char *src,
|
||||||
|
size_t src_len,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
(void) session;
|
||||||
|
(void) abstract;
|
||||||
|
(void) dest;
|
||||||
|
(void) dest_len;
|
||||||
|
(void) src;
|
||||||
|
(void) src_len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* comp_method_none_decomp
|
||||||
|
*
|
||||||
|
* Minimalist decompression: Absolutely none
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
comp_method_none_decomp(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char **dest,
|
||||||
|
size_t *dest_len,
|
||||||
|
size_t payload_limit,
|
||||||
|
const unsigned char *src,
|
||||||
|
size_t src_len, void **abstract)
|
||||||
|
{
|
||||||
|
(void) session;
|
||||||
|
(void) payload_limit;
|
||||||
|
(void) abstract;
|
||||||
|
*dest = (unsigned char *) src;
|
||||||
|
*dest_len = src_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const LIBSSH2_COMP_METHOD comp_method_none = {
|
||||||
|
"none",
|
||||||
|
0, /* not really compressing */
|
||||||
|
NULL,
|
||||||
|
comp_method_none_comp,
|
||||||
|
comp_method_none_decomp,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_HAVE_ZLIB
|
||||||
|
/* ********
|
||||||
|
* zlib *
|
||||||
|
******** */
|
||||||
|
|
||||||
|
/* Memory management wrappers
|
||||||
|
* Yes, I realize we're doing a callback to a callback,
|
||||||
|
* Deal...
|
||||||
|
*/
|
||||||
|
|
||||||
|
static voidpf
|
||||||
|
comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
|
||||||
|
{
|
||||||
|
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||||
|
|
||||||
|
return (voidpf) LIBSSH2_ALLOC(session, items * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
comp_method_zlib_free(voidpf opaque, voidpf address)
|
||||||
|
{
|
||||||
|
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* libssh2_comp_method_zlib_init
|
||||||
|
* All your bandwidth are belong to us (so save some)
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
z_stream *strm;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
|
||||||
|
if (!strm) {
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for "
|
||||||
|
"zlib compression/decompression");
|
||||||
|
}
|
||||||
|
memset(strm, 0, sizeof(z_stream));
|
||||||
|
|
||||||
|
strm->opaque = (voidpf) session;
|
||||||
|
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
|
||||||
|
strm->zfree = (free_func) comp_method_zlib_free;
|
||||||
|
if (compr) {
|
||||||
|
/* deflate */
|
||||||
|
status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
|
||||||
|
} else {
|
||||||
|
/* inflate */
|
||||||
|
status = inflateInit(strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != Z_OK) {
|
||||||
|
LIBSSH2_FREE(session, strm);
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
|
"unhandled zlib error %d", status);
|
||||||
|
return LIBSSH2_ERROR_COMPRESS;
|
||||||
|
}
|
||||||
|
*abstract = strm;
|
||||||
|
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_comp_method_zlib_comp
|
||||||
|
*
|
||||||
|
* Compresses source to destination. Without allocation.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char *dest,
|
||||||
|
|
||||||
|
/* dest_len is a pointer to allow this function to
|
||||||
|
update it with the final actual size used */
|
||||||
|
size_t *dest_len,
|
||||||
|
const unsigned char *src,
|
||||||
|
size_t src_len,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
z_stream *strm = *abstract;
|
||||||
|
int out_maxlen = *dest_len;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
strm->next_in = (unsigned char *) src;
|
||||||
|
strm->avail_in = src_len;
|
||||||
|
strm->next_out = dest;
|
||||||
|
strm->avail_out = out_maxlen;
|
||||||
|
|
||||||
|
status = deflate(strm, Z_PARTIAL_FLUSH);
|
||||||
|
|
||||||
|
if (status != Z_OK) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
|
"unhandled zlib compression error %d", status);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
|
"compression failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest_len = out_maxlen - strm->avail_out;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_comp_method_zlib_decomp
|
||||||
|
*
|
||||||
|
* Decompresses source to destination. Allocates the output memory.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
comp_method_zlib_decomp(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char **dest,
|
||||||
|
size_t *dest_len,
|
||||||
|
size_t payload_limit,
|
||||||
|
const unsigned char *src,
|
||||||
|
size_t src_len, void **abstract)
|
||||||
|
{
|
||||||
|
z_stream *strm = *abstract;
|
||||||
|
/* A short-term alloc of a full data chunk is better than a series of
|
||||||
|
reallocs */
|
||||||
|
char *out;
|
||||||
|
int out_maxlen = 8 * src_len;
|
||||||
|
int limiter = 0;
|
||||||
|
|
||||||
|
/* If strm is null, then we have not yet been initialized. */
|
||||||
|
if (strm == NULL)
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
|
||||||
|
"decompression unitilized");;
|
||||||
|
|
||||||
|
/* In practice they never come smaller than this */
|
||||||
|
if (out_maxlen < 25)
|
||||||
|
out_maxlen = 25;
|
||||||
|
|
||||||
|
if (out_maxlen > (int) payload_limit)
|
||||||
|
out_maxlen = payload_limit;
|
||||||
|
|
||||||
|
strm->next_in = (unsigned char *) src;
|
||||||
|
strm->avail_in = src_len;
|
||||||
|
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
|
||||||
|
out = (char *) strm->next_out;
|
||||||
|
strm->avail_out = out_maxlen;
|
||||||
|
if (!strm->next_out)
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate decompression buffer");
|
||||||
|
while (strm->avail_in) {
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||||
|
|
||||||
|
if (status != Z_OK) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
|
"unhandled zlib error %d", status);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
|
"decompression failure");
|
||||||
|
}
|
||||||
|
if (strm->avail_in) {
|
||||||
|
size_t out_ofs = out_maxlen - strm->avail_out;
|
||||||
|
char *newout;
|
||||||
|
|
||||||
|
out_maxlen += 8 * strm->avail_in;
|
||||||
|
|
||||||
|
if ((out_maxlen > (int) payload_limit) && limiter++) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
|
"Excessive growth in decompression phase");
|
||||||
|
}
|
||||||
|
|
||||||
|
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||||
|
if (!newout) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to expand decompression buffer");
|
||||||
|
}
|
||||||
|
out = newout;
|
||||||
|
strm->next_out = (unsigned char *) out + out_ofs;
|
||||||
|
strm->avail_out += 8 * strm->avail_in;
|
||||||
|
} else
|
||||||
|
while (!strm->avail_out) {
|
||||||
|
/* Done with input, might be a byte or two in internal buffer
|
||||||
|
* during compress. Or potentially many bytes if it's a
|
||||||
|
* decompress
|
||||||
|
*/
|
||||||
|
int grow_size = 2048;
|
||||||
|
char *newout;
|
||||||
|
|
||||||
|
if (out_maxlen >= (int) payload_limit) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
|
"Excessive growth in decompression "
|
||||||
|
"phase");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grow_size > (int) (payload_limit - out_maxlen)) {
|
||||||
|
grow_size = payload_limit - out_maxlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_maxlen += grow_size;
|
||||||
|
strm->avail_out = grow_size;
|
||||||
|
|
||||||
|
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||||
|
if (!newout) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to expand final "
|
||||||
|
"decompress buffer");
|
||||||
|
}
|
||||||
|
out = newout;
|
||||||
|
strm->next_out = (unsigned char *) out + out_maxlen -
|
||||||
|
grow_size;
|
||||||
|
|
||||||
|
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||||
|
|
||||||
|
if (status != Z_OK) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
|
"unhandled zlib error %d", status);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
|
"decompression failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest = (unsigned char *) out;
|
||||||
|
*dest_len = out_maxlen - strm->avail_out;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* libssh2_comp_method_zlib_dtor
|
||||||
|
* All done, no more compression for you
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
|
||||||
|
{
|
||||||
|
z_stream *strm = *abstract;
|
||||||
|
|
||||||
|
if (strm) {
|
||||||
|
if (compr)
|
||||||
|
deflateEnd(strm);
|
||||||
|
else
|
||||||
|
inflateEnd(strm);
|
||||||
|
LIBSSH2_FREE(session, strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
*abstract = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
|
||||||
|
"zlib",
|
||||||
|
1, /* yes, this compresses */
|
||||||
|
comp_method_zlib_init,
|
||||||
|
comp_method_zlib_comp,
|
||||||
|
comp_method_zlib_decomp,
|
||||||
|
comp_method_zlib_dtor,
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_HAVE_ZLIB */
|
||||||
|
|
||||||
|
/* If compression is enabled by the API, then this array is used which then
|
||||||
|
may allow compression if zlib is available at build time */
|
||||||
|
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
|
||||||
|
#ifdef LIBSSH2_HAVE_ZLIB
|
||||||
|
&comp_method_zlib,
|
||||||
|
#endif /* LIBSSH2_HAVE_ZLIB */
|
||||||
|
&comp_method_none,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* If compression is disabled by the API, then this array is used */
|
||||||
|
static const LIBSSH2_COMP_METHOD *no_comp_methods[] = {
|
||||||
|
&comp_method_none,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const LIBSSH2_COMP_METHOD **
|
||||||
|
_libssh2_comp_methods(LIBSSH2_SESSION *session)
|
||||||
|
{
|
||||||
|
if(session->flag.compress)
|
||||||
|
return comp_methods;
|
||||||
|
else
|
||||||
|
return no_comp_methods;
|
||||||
|
}
|
||||||
45
vendor/libssh2-1.4.2/src/comp.h
vendored
Normal file
45
vendor/libssh2-1.4.2/src/comp.h
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef __LIBSSH2_COMP_H
|
||||||
|
#define __LIBSSH2_COMP_H
|
||||||
|
|
||||||
|
/* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
|
#endif /* __LIBSSH2_COMP_H */
|
||||||
334
vendor/libssh2-1.4.2/src/crypt.c
vendored
Normal file
334
vendor/libssh2-1.4.2/src/crypt.c
vendored
Normal file
|
|
@ -0,0 +1,334 @@
|
||||||
|
/* Copyright (c) 2009, 2010 Simon Josefsson <simon@josefsson.org>
|
||||||
|
* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_CRYPT_NONE
|
||||||
|
|
||||||
|
/* crypt_none_crypt
|
||||||
|
* Minimalist cipher: VERY secure *wink*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
/* Do nothing to the data! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
|
||||||
|
"none",
|
||||||
|
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
|
||||||
|
0, /* iv_len */
|
||||||
|
0, /* secret_len */
|
||||||
|
0, /* flags */
|
||||||
|
NULL,
|
||||||
|
crypt_none_crypt,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_CRYPT_NONE */
|
||||||
|
|
||||||
|
struct crypt_ctx
|
||||||
|
{
|
||||||
|
int encrypt;
|
||||||
|
_libssh2_cipher_type(algo);
|
||||||
|
_libssh2_cipher_ctx h;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
crypt_init(LIBSSH2_SESSION * session,
|
||||||
|
const LIBSSH2_CRYPT_METHOD * method,
|
||||||
|
unsigned char *iv, int *free_iv,
|
||||||
|
unsigned char *secret, int *free_secret,
|
||||||
|
int encrypt, void **abstract)
|
||||||
|
{
|
||||||
|
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
|
||||||
|
sizeof(struct crypt_ctx));
|
||||||
|
if (!ctx)
|
||||||
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
|
|
||||||
|
ctx->encrypt = encrypt;
|
||||||
|
ctx->algo = method->algo;
|
||||||
|
if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
|
||||||
|
LIBSSH2_FREE(session, ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*abstract = ctx;
|
||||||
|
*free_iv = 1;
|
||||||
|
*free_secret = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||||
|
(void) session;
|
||||||
|
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||||
|
{
|
||||||
|
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
|
||||||
|
if (cctx && *cctx) {
|
||||||
|
_libssh2_cipher_dtor(&(*cctx)->h);
|
||||||
|
LIBSSH2_FREE(session, *cctx);
|
||||||
|
*abstract = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIBSSH2_AES_CTR
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
|
||||||
|
"aes128-ctr",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
16, /* secret length -- 16*8 == 128bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes128ctr
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
|
||||||
|
"aes192-ctr",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
24, /* secret length -- 24*8 == 192bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes192ctr
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
|
||||||
|
"aes256-ctr",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
32, /* secret length -- 32*8 == 256bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes256ctr
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LIBSSH2_AES
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
||||||
|
"aes128-cbc",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
16, /* secret length -- 16*8 == 128bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes128
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
|
||||||
|
"aes192-cbc",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
24, /* secret length -- 24*8 == 192bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes192
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
|
||||||
|
"aes256-cbc",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
32, /* secret length -- 32*8 == 256bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes256
|
||||||
|
};
|
||||||
|
|
||||||
|
/* rijndael-cbc@lysator.liu.se == aes256-cbc */
|
||||||
|
static const LIBSSH2_CRYPT_METHOD
|
||||||
|
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
|
||||||
|
"rijndael-cbc@lysator.liu.se",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
32, /* secret length -- 32*8 == 256bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes256
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_AES */
|
||||||
|
|
||||||
|
#if LIBSSH2_BLOWFISH
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
|
||||||
|
"blowfish-cbc",
|
||||||
|
8, /* blocksize */
|
||||||
|
8, /* initial value length */
|
||||||
|
16, /* secret length */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_blowfish
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_BLOWFISH */
|
||||||
|
|
||||||
|
#if LIBSSH2_RC4
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
|
||||||
|
"arcfour",
|
||||||
|
8, /* blocksize */
|
||||||
|
8, /* initial value length */
|
||||||
|
16, /* secret length */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_arcfour
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
crypt_init_arcfour128(LIBSSH2_SESSION * session,
|
||||||
|
const LIBSSH2_CRYPT_METHOD * method,
|
||||||
|
unsigned char *iv, int *free_iv,
|
||||||
|
unsigned char *secret, int *free_secret,
|
||||||
|
int encrypt, void **abstract)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = crypt_init (session, method, iv, free_iv, secret, free_secret,
|
||||||
|
encrypt, abstract);
|
||||||
|
if (rc == 0) {
|
||||||
|
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||||
|
unsigned char block[8];
|
||||||
|
size_t discard = 1536;
|
||||||
|
for (; discard; discard -= 8)
|
||||||
|
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
|
||||||
|
"arcfour128",
|
||||||
|
8, /* blocksize */
|
||||||
|
8, /* initial value length */
|
||||||
|
16, /* secret length */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init_arcfour128,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_arcfour
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_RC4 */
|
||||||
|
|
||||||
|
#if LIBSSH2_CAST
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
|
||||||
|
"cast128-cbc",
|
||||||
|
8, /* blocksize */
|
||||||
|
8, /* initial value length */
|
||||||
|
16, /* secret length */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_cast5
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_CAST */
|
||||||
|
|
||||||
|
#if LIBSSH2_3DES
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
|
||||||
|
"3des-cbc",
|
||||||
|
8, /* blocksize */
|
||||||
|
8, /* initial value length */
|
||||||
|
24, /* secret length */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_3des
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||||
|
#if LIBSSH2_AES_CTR
|
||||||
|
&libssh2_crypt_method_aes128_ctr,
|
||||||
|
&libssh2_crypt_method_aes192_ctr,
|
||||||
|
&libssh2_crypt_method_aes256_ctr,
|
||||||
|
#endif /* LIBSSH2_AES */
|
||||||
|
#if LIBSSH2_AES
|
||||||
|
&libssh2_crypt_method_aes256_cbc,
|
||||||
|
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
||||||
|
&libssh2_crypt_method_aes192_cbc,
|
||||||
|
&libssh2_crypt_method_aes128_cbc,
|
||||||
|
#endif /* LIBSSH2_AES */
|
||||||
|
#if LIBSSH2_BLOWFISH
|
||||||
|
&libssh2_crypt_method_blowfish_cbc,
|
||||||
|
#endif /* LIBSSH2_BLOWFISH */
|
||||||
|
#if LIBSSH2_RC4
|
||||||
|
&libssh2_crypt_method_arcfour128,
|
||||||
|
&libssh2_crypt_method_arcfour,
|
||||||
|
#endif /* LIBSSH2_RC4 */
|
||||||
|
#if LIBSSH2_CAST
|
||||||
|
&libssh2_crypt_method_cast128_cbc,
|
||||||
|
#endif /* LIBSSH2_CAST */
|
||||||
|
#if LIBSSH2_3DES
|
||||||
|
&libssh2_crypt_method_3des_cbc,
|
||||||
|
#endif /* LIBSSH2_DES */
|
||||||
|
#ifdef LIBSSH2_CRYPT_NONE
|
||||||
|
&libssh2_crypt_method_none,
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Expose to kex.c */
|
||||||
|
const LIBSSH2_CRYPT_METHOD **
|
||||||
|
libssh2_crypt_methods(void)
|
||||||
|
{
|
||||||
|
return _libssh2_crypt_methods;
|
||||||
|
}
|
||||||
118
vendor/libssh2-1.4.2/src/crypto.h
vendored
Normal file
118
vendor/libssh2-1.4.2/src/crypto.h
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||||
|
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2010 Daniel Stenberg
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef LIBSSH2_CRYPTO_H
|
||||||
|
#define LIBSSH2_CRYPTO_H
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_LIBGCRYPT
|
||||||
|
#include "libgcrypt.h"
|
||||||
|
#else
|
||||||
|
#include "openssl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||||
|
const unsigned char *edata,
|
||||||
|
unsigned long elen,
|
||||||
|
const unsigned char *ndata,
|
||||||
|
unsigned long nlen,
|
||||||
|
const unsigned char *ddata,
|
||||||
|
unsigned long dlen,
|
||||||
|
const unsigned char *pdata,
|
||||||
|
unsigned long plen,
|
||||||
|
const unsigned char *qdata,
|
||||||
|
unsigned long qlen,
|
||||||
|
const unsigned char *e1data,
|
||||||
|
unsigned long e1len,
|
||||||
|
const unsigned char *e2data,
|
||||||
|
unsigned long e2len,
|
||||||
|
const unsigned char *coeffdata, unsigned long coefflen);
|
||||||
|
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
|
LIBSSH2_SESSION * session,
|
||||||
|
const char *filename,
|
||||||
|
unsigned const char *passphrase);
|
||||||
|
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||||
|
const unsigned char *sig,
|
||||||
|
unsigned long sig_len,
|
||||||
|
const unsigned char *m, unsigned long m_len);
|
||||||
|
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||||
|
libssh2_rsa_ctx * rsactx,
|
||||||
|
const unsigned char *hash,
|
||||||
|
size_t hash_len,
|
||||||
|
unsigned char **signature,
|
||||||
|
size_t *signature_len);
|
||||||
|
|
||||||
|
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
||||||
|
const unsigned char *pdata,
|
||||||
|
unsigned long plen,
|
||||||
|
const unsigned char *qdata,
|
||||||
|
unsigned long qlen,
|
||||||
|
const unsigned char *gdata,
|
||||||
|
unsigned long glen,
|
||||||
|
const unsigned char *ydata,
|
||||||
|
unsigned long ylen,
|
||||||
|
const unsigned char *x, unsigned long x_len);
|
||||||
|
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
|
LIBSSH2_SESSION * session,
|
||||||
|
const char *filename,
|
||||||
|
unsigned const char *passphrase);
|
||||||
|
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||||
|
const unsigned char *sig,
|
||||||
|
const unsigned char *m, unsigned long m_len);
|
||||||
|
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned long hash_len, unsigned char *sig);
|
||||||
|
|
||||||
|
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||||
|
_libssh2_cipher_type(algo),
|
||||||
|
unsigned char *iv,
|
||||||
|
unsigned char *secret, int encrypt);
|
||||||
|
|
||||||
|
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||||
|
_libssh2_cipher_type(algo),
|
||||||
|
int encrypt, unsigned char *block);
|
||||||
|
|
||||||
|
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char **method,
|
||||||
|
size_t *method_len,
|
||||||
|
unsigned char **pubkeydata,
|
||||||
|
size_t *pubkeydata_len,
|
||||||
|
const char *privatekey,
|
||||||
|
const char *passphrase);
|
||||||
|
|
||||||
|
void _libssh2_init_aes_ctr(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
78
vendor/libssh2-1.4.2/src/global.c
vendored
Normal file
78
vendor/libssh2-1.4.2/src/global.c
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
/* Copyright (c) 2010 Lars Nordin <Lars.Nordin@SDlabs.se>
|
||||||
|
* Copyright (C) 2010 Simon Josefsson <simon@josefsson.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
static int _libssh2_initialized = 0;
|
||||||
|
static int _libssh2_init_flags = 0;
|
||||||
|
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_init(int flags)
|
||||||
|
{
|
||||||
|
if (_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) {
|
||||||
|
libssh2_crypto_init();
|
||||||
|
_libssh2_init_aes_ctr();
|
||||||
|
}
|
||||||
|
|
||||||
|
_libssh2_initialized++;
|
||||||
|
_libssh2_init_flags |= flags;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_API void
|
||||||
|
libssh2_exit(void)
|
||||||
|
{
|
||||||
|
if (_libssh2_initialized == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_libssh2_initialized--;
|
||||||
|
|
||||||
|
if (!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
|
||||||
|
libssh2_crypto_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_libssh2_init_if_needed(void)
|
||||||
|
{
|
||||||
|
if (_libssh2_initialized == 0)
|
||||||
|
(void)libssh2_init (0);
|
||||||
|
}
|
||||||
485
vendor/libssh2-1.4.2/src/hostkey.c
vendored
Normal file
485
vendor/libssh2-1.4.2/src/hostkey.c
vendored
Normal file
|
|
@ -0,0 +1,485 @@
|
||||||
|
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* Copyright (c) 2009 by Daniel Stenberg
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
/* Needed for struct iovec on some platforms */
|
||||||
|
#ifdef HAVE_SYS_UIO_H
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LIBSSH2_RSA
|
||||||
|
/* ***********
|
||||||
|
* ssh-rsa *
|
||||||
|
*********** */
|
||||||
|
|
||||||
|
static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
|
||||||
|
void **abstract);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_rsa_init
|
||||||
|
*
|
||||||
|
* Initialize the server hostkey working area with e/n pair
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
|
||||||
|
const unsigned char *hostkey_data,
|
||||||
|
size_t hostkey_data_len,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_rsa_ctx *rsactx;
|
||||||
|
const unsigned char *s, *e, *n;
|
||||||
|
unsigned long len, e_len, n_len;
|
||||||
|
|
||||||
|
(void) hostkey_data_len;
|
||||||
|
|
||||||
|
if (*abstract) {
|
||||||
|
hostkey_method_ssh_rsa_dtor(session, abstract);
|
||||||
|
*abstract = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = hostkey_data;
|
||||||
|
len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s += 7;
|
||||||
|
|
||||||
|
e_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
e = s;
|
||||||
|
s += e_len;
|
||||||
|
n_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
n = s;
|
||||||
|
|
||||||
|
if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
|
||||||
|
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*abstract = rsactx;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_rsa_initPEM
|
||||||
|
*
|
||||||
|
* Load a Private Key from a PEM file
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
|
||||||
|
const char *privkeyfile,
|
||||||
|
unsigned const char *passphrase,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_rsa_ctx *rsactx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (*abstract) {
|
||||||
|
hostkey_method_ssh_rsa_dtor(session, abstract);
|
||||||
|
*abstract = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase);
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*abstract = rsactx;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_rsa_sign
|
||||||
|
*
|
||||||
|
* Verify signature created by remote
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
|
||||||
|
const unsigned char *sig,
|
||||||
|
size_t sig_len,
|
||||||
|
const unsigned char *m,
|
||||||
|
size_t m_len, void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
|
||||||
|
sig += 15;
|
||||||
|
sig_len -= 15;
|
||||||
|
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_rsa_signv
|
||||||
|
*
|
||||||
|
* Construct a signature from an array of vectors
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char **signature,
|
||||||
|
size_t *signature_len,
|
||||||
|
int veccount,
|
||||||
|
const struct iovec datavec[],
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||||
|
libssh2_sha1_ctx ctx;
|
||||||
|
|
||||||
|
libssh2_sha1_init(&ctx);
|
||||||
|
for(i = 0; i < veccount; i++) {
|
||||||
|
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
|
||||||
|
}
|
||||||
|
libssh2_sha1_final(ctx, hash);
|
||||||
|
|
||||||
|
ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
|
||||||
|
signature, signature_len);
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_rsa_dtor
|
||||||
|
*
|
||||||
|
* Shutdown the hostkey
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_rsa_free(rsactx);
|
||||||
|
|
||||||
|
*abstract = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
|
||||||
|
"ssh-rsa",
|
||||||
|
MD5_DIGEST_LENGTH,
|
||||||
|
hostkey_method_ssh_rsa_init,
|
||||||
|
hostkey_method_ssh_rsa_initPEM,
|
||||||
|
hostkey_method_ssh_rsa_sig_verify,
|
||||||
|
hostkey_method_ssh_rsa_signv,
|
||||||
|
NULL, /* encrypt */
|
||||||
|
hostkey_method_ssh_rsa_dtor,
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_RSA */
|
||||||
|
|
||||||
|
#if LIBSSH2_DSA
|
||||||
|
/* ***********
|
||||||
|
* ssh-dss *
|
||||||
|
*********** */
|
||||||
|
|
||||||
|
static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
|
||||||
|
void **abstract);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_dss_init
|
||||||
|
*
|
||||||
|
* Initialize the server hostkey working area with p/q/g/y set
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
|
||||||
|
const unsigned char *hostkey_data,
|
||||||
|
size_t hostkey_data_len,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_dsa_ctx *dsactx;
|
||||||
|
const unsigned char *p, *q, *g, *y, *s;
|
||||||
|
unsigned long p_len, q_len, g_len, y_len, len;
|
||||||
|
(void) hostkey_data_len;
|
||||||
|
|
||||||
|
if (*abstract) {
|
||||||
|
hostkey_method_ssh_dss_dtor(session, abstract);
|
||||||
|
*abstract = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = hostkey_data;
|
||||||
|
len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s += 7;
|
||||||
|
|
||||||
|
p_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
p = s;
|
||||||
|
s += p_len;
|
||||||
|
q_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
q = s;
|
||||||
|
s += q_len;
|
||||||
|
g_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
g = s;
|
||||||
|
s += g_len;
|
||||||
|
y_len = _libssh2_ntohu32(s);
|
||||||
|
s += 4;
|
||||||
|
y = s;
|
||||||
|
/* s += y_len; */
|
||||||
|
|
||||||
|
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
|
||||||
|
|
||||||
|
*abstract = dsactx;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_dss_initPEM
|
||||||
|
*
|
||||||
|
* Load a Private Key from a PEM file
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
|
||||||
|
const char *privkeyfile,
|
||||||
|
unsigned const char *passphrase,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_dsa_ctx *dsactx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (*abstract) {
|
||||||
|
hostkey_method_ssh_dss_dtor(session, abstract);
|
||||||
|
*abstract = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase);
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*abstract = dsactx;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_hostkey_method_ssh_dss_sign
|
||||||
|
*
|
||||||
|
* Verify signature created by remote
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
|
||||||
|
const unsigned char *sig,
|
||||||
|
size_t sig_len,
|
||||||
|
const unsigned char *m,
|
||||||
|
size_t m_len, void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||||
|
|
||||||
|
/* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */
|
||||||
|
sig += 15;
|
||||||
|
sig_len -= 15;
|
||||||
|
if (sig_len != 40) {
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||||
|
"Invalid DSS signature length");
|
||||||
|
}
|
||||||
|
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostkey_method_ssh_dss_signv
|
||||||
|
*
|
||||||
|
* Construct a signature from an array of vectors
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char **signature,
|
||||||
|
size_t *signature_len,
|
||||||
|
int veccount,
|
||||||
|
const struct iovec datavec[],
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||||
|
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||||
|
libssh2_sha1_ctx ctx;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
|
||||||
|
if (!*signature) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*signature_len = 2 * SHA_DIGEST_LENGTH;
|
||||||
|
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
|
||||||
|
|
||||||
|
libssh2_sha1_init(&ctx);
|
||||||
|
for(i = 0; i < veccount; i++) {
|
||||||
|
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
|
||||||
|
}
|
||||||
|
libssh2_sha1_final(ctx, hash);
|
||||||
|
|
||||||
|
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
|
||||||
|
LIBSSH2_FREE(session, *signature);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_hostkey_method_ssh_dss_dtor
|
||||||
|
*
|
||||||
|
* Shutdown the hostkey method
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_dsa_free(dsactx);
|
||||||
|
|
||||||
|
*abstract = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = {
|
||||||
|
"ssh-dss",
|
||||||
|
MD5_DIGEST_LENGTH,
|
||||||
|
hostkey_method_ssh_dss_init,
|
||||||
|
hostkey_method_ssh_dss_initPEM,
|
||||||
|
hostkey_method_ssh_dss_sig_verify,
|
||||||
|
hostkey_method_ssh_dss_signv,
|
||||||
|
NULL, /* encrypt */
|
||||||
|
hostkey_method_ssh_dss_dtor,
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_DSA */
|
||||||
|
|
||||||
|
static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
|
||||||
|
#if LIBSSH2_RSA
|
||||||
|
&hostkey_method_ssh_rsa,
|
||||||
|
#endif /* LIBSSH2_RSA */
|
||||||
|
#if LIBSSH2_DSA
|
||||||
|
&hostkey_method_ssh_dss,
|
||||||
|
#endif /* LIBSSH2_DSA */
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const LIBSSH2_HOSTKEY_METHOD **
|
||||||
|
libssh2_hostkey_methods(void)
|
||||||
|
{
|
||||||
|
return hostkey_methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_hostkey_hash
|
||||||
|
*
|
||||||
|
* Returns hash signature
|
||||||
|
* Returned buffer should NOT be freed
|
||||||
|
* Length of buffer is determined by hash type
|
||||||
|
* i.e. MD5 == 16, SHA1 == 20
|
||||||
|
*/
|
||||||
|
LIBSSH2_API const char *
|
||||||
|
libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
|
||||||
|
{
|
||||||
|
switch (hash_type) {
|
||||||
|
#if LIBSSH2_MD5
|
||||||
|
case LIBSSH2_HOSTKEY_HASH_MD5:
|
||||||
|
return (char *) session->server_hostkey_md5;
|
||||||
|
break;
|
||||||
|
#endif /* LIBSSH2_MD5 */
|
||||||
|
case LIBSSH2_HOSTKEY_HASH_SHA1:
|
||||||
|
return (char *) session->server_hostkey_sha1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hostkey_type(const unsigned char *hostkey, size_t len)
|
||||||
|
{
|
||||||
|
const unsigned char rsa[] = {
|
||||||
|
0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a'
|
||||||
|
};
|
||||||
|
const unsigned char dss[] = {
|
||||||
|
0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (len < 11)
|
||||||
|
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
if (!memcmp(rsa, hostkey, 11))
|
||||||
|
return LIBSSH2_HOSTKEY_TYPE_RSA;
|
||||||
|
|
||||||
|
if (!memcmp(dss, hostkey, 11))
|
||||||
|
return LIBSSH2_HOSTKEY_TYPE_DSS;
|
||||||
|
|
||||||
|
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_session_hostkey()
|
||||||
|
*
|
||||||
|
* Returns the server key and length.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
LIBSSH2_API const char *
|
||||||
|
libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type)
|
||||||
|
{
|
||||||
|
if(session->server_hostkey_len) {
|
||||||
|
if(len)
|
||||||
|
*len = session->server_hostkey_len;
|
||||||
|
if (type)
|
||||||
|
*type = hostkey_type(session->server_hostkey,
|
||||||
|
session->server_hostkey_len);
|
||||||
|
return (char *) session->server_hostkey;
|
||||||
|
}
|
||||||
|
if(len)
|
||||||
|
*len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
98
vendor/libssh2-1.4.2/src/keepalive.c
vendored
Normal file
98
vendor/libssh2-1.4.2/src/keepalive.c
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* Copyright (C) 2010 Simon Josefsson
|
||||||
|
* Author: Simon Josefsson
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include "transport.h" /* _libssh2_transport_write */
|
||||||
|
|
||||||
|
/* Keep-alive stuff. */
|
||||||
|
|
||||||
|
LIBSSH2_API void
|
||||||
|
libssh2_keepalive_config (LIBSSH2_SESSION *session,
|
||||||
|
int want_reply,
|
||||||
|
unsigned interval)
|
||||||
|
{
|
||||||
|
if (interval == 1)
|
||||||
|
session->keepalive_interval = 2;
|
||||||
|
else
|
||||||
|
session->keepalive_interval = interval;
|
||||||
|
session->keepalive_want_reply = want_reply ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
||||||
|
int *seconds_to_next)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
if (!session->keepalive_interval) {
|
||||||
|
if (seconds_to_next)
|
||||||
|
*seconds_to_next = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
now = time (NULL);
|
||||||
|
|
||||||
|
if (session->keepalive_last_sent + session->keepalive_interval <= now) {
|
||||||
|
/* Format is
|
||||||
|
"SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
|
||||||
|
unsigned char keepalive_data[]
|
||||||
|
= "\x50\x00\x00\x00\x15keepalive@libssh2.orgW";
|
||||||
|
size_t len = sizeof (keepalive_data) - 1;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
keepalive_data[len - 1] = session->keepalive_want_reply;
|
||||||
|
|
||||||
|
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
|
||||||
|
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
||||||
|
already full, sending another keepalive is not useful. */
|
||||||
|
if (rc && rc != LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
"Unable to send keepalive message");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->keepalive_last_sent = now;
|
||||||
|
if (seconds_to_next)
|
||||||
|
*seconds_to_next = session->keepalive_interval;
|
||||||
|
} else if (seconds_to_next) {
|
||||||
|
*seconds_to_next = (int) session->keepalive_last_sent
|
||||||
|
+ session->keepalive_interval - now;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
2008
vendor/libssh2-1.4.2/src/kex.c
vendored
Normal file
2008
vendor/libssh2-1.4.2/src/kex.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
1146
vendor/libssh2-1.4.2/src/knownhost.c
vendored
Normal file
1146
vendor/libssh2-1.4.2/src/knownhost.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
593
vendor/libssh2-1.4.2/src/libgcrypt.c
vendored
Normal file
593
vendor/libssh2-1.4.2/src/libgcrypt.c
vendored
Normal file
|
|
@ -0,0 +1,593 @@
|
||||||
|
/* Copyright (C) 2008, 2009, Simon Josefsson
|
||||||
|
* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||||
|
const unsigned char *edata,
|
||||||
|
unsigned long elen,
|
||||||
|
const unsigned char *ndata,
|
||||||
|
unsigned long nlen,
|
||||||
|
const unsigned char *ddata,
|
||||||
|
unsigned long dlen,
|
||||||
|
const unsigned char *pdata,
|
||||||
|
unsigned long plen,
|
||||||
|
const unsigned char *qdata,
|
||||||
|
unsigned long qlen,
|
||||||
|
const unsigned char *e1data,
|
||||||
|
unsigned long e1len,
|
||||||
|
const unsigned char *e2data,
|
||||||
|
unsigned long e2len,
|
||||||
|
const unsigned char *coeffdata, unsigned long coefflen)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
(void) e1data;
|
||||||
|
(void) e1len;
|
||||||
|
(void) e2data;
|
||||||
|
(void) e2len;
|
||||||
|
|
||||||
|
if (ddata) {
|
||||||
|
rc = gcry_sexp_build
|
||||||
|
(rsa, NULL,
|
||||||
|
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
|
||||||
|
nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
|
||||||
|
qlen, qdata, coefflen, coeffdata);
|
||||||
|
} else {
|
||||||
|
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
|
||||||
|
nlen, ndata, elen, edata);
|
||||||
|
}
|
||||||
|
if (rc) {
|
||||||
|
*rsa = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||||
|
const unsigned char *sig,
|
||||||
|
unsigned long sig_len,
|
||||||
|
const unsigned char *m, unsigned long m_len)
|
||||||
|
{
|
||||||
|
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||||
|
gcry_sexp_t s_sig, s_hash;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
libssh2_sha1(m, m_len, hash);
|
||||||
|
|
||||||
|
rc = gcry_sexp_build(&s_hash, NULL,
|
||||||
|
"(data (flags pkcs1) (hash sha1 %b))",
|
||||||
|
SHA_DIGEST_LENGTH, hash);
|
||||||
|
if (rc != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
|
||||||
|
if (rc != 0) {
|
||||||
|
gcry_sexp_release(s_hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = gcry_pk_verify(s_sig, s_hash, rsa);
|
||||||
|
gcry_sexp_release(s_sig);
|
||||||
|
gcry_sexp_release(s_hash);
|
||||||
|
|
||||||
|
return (rc == 0) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||||
|
const unsigned char *p,
|
||||||
|
unsigned long p_len,
|
||||||
|
const unsigned char *q,
|
||||||
|
unsigned long q_len,
|
||||||
|
const unsigned char *g,
|
||||||
|
unsigned long g_len,
|
||||||
|
const unsigned char *y,
|
||||||
|
unsigned long y_len,
|
||||||
|
const unsigned char *x, unsigned long x_len)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (x_len) {
|
||||||
|
rc = gcry_sexp_build
|
||||||
|
(dsactx, NULL,
|
||||||
|
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
|
||||||
|
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
|
||||||
|
} else {
|
||||||
|
rc = gcry_sexp_build(dsactx, NULL,
|
||||||
|
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
|
||||||
|
p_len, p, q_len, q, g_len, g, y_len, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
*dsactx = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
|
LIBSSH2_SESSION * session,
|
||||||
|
const char *filename, unsigned const char *passphrase)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
unsigned char *data, *save_data;
|
||||||
|
unsigned int datalen;
|
||||||
|
int ret;
|
||||||
|
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
|
||||||
|
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
|
||||||
|
|
||||||
|
(void) passphrase;
|
||||||
|
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
if (!fp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_parse(session,
|
||||||
|
"-----BEGIN RSA PRIVATE KEY-----",
|
||||||
|
"-----END RSA PRIVATE KEY-----",
|
||||||
|
fp, &data, &datalen);
|
||||||
|
fclose(fp);
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
save_data = data;
|
||||||
|
|
||||||
|
if (_libssh2_pem_decode_sequence(&data, &datalen)) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* First read Version field (should be 0). */
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
|
||||||
|
if (ret != 0 || (nlen != 1 && *n != '\0')) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
|
||||||
|
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
LIBSSH2_FREE(session, save_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
|
LIBSSH2_SESSION * session,
|
||||||
|
const char *filename, unsigned const char *passphrase)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
unsigned char *data, *save_data;
|
||||||
|
unsigned int datalen;
|
||||||
|
int ret;
|
||||||
|
unsigned char *p, *q, *g, *y, *x;
|
||||||
|
unsigned int plen, qlen, glen, ylen, xlen;
|
||||||
|
|
||||||
|
(void) passphrase;
|
||||||
|
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
if (!fp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_parse(session,
|
||||||
|
"-----BEGIN DSA PRIVATE KEY-----",
|
||||||
|
"-----END DSA PRIVATE KEY-----",
|
||||||
|
fp, &data, &datalen);
|
||||||
|
fclose(fp);
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
save_data = data;
|
||||||
|
|
||||||
|
if (_libssh2_pem_decode_sequence(&data, &datalen)) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First read Version field (should be 0). */
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
|
||||||
|
if (ret != 0 || (plen != 1 && *p != '\0')) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datalen != 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
|
||||||
|
ret = -1;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
LIBSSH2_FREE(session, save_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||||
|
libssh2_dsa_ctx * rsactx,
|
||||||
|
const unsigned char *hash,
|
||||||
|
size_t hash_len,
|
||||||
|
unsigned char **signature, size_t *signature_len)
|
||||||
|
{
|
||||||
|
gcry_sexp_t sig_sexp;
|
||||||
|
gcry_sexp_t data;
|
||||||
|
int rc;
|
||||||
|
const char *tmp;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
if (hash_len != SHA_DIGEST_LENGTH) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gcry_sexp_build(&data, NULL,
|
||||||
|
"(data (flags pkcs1) (hash sha1 %b))",
|
||||||
|
hash_len, hash)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = gcry_pk_sign(&sig_sexp, data, rsactx);
|
||||||
|
|
||||||
|
gcry_sexp_release(data);
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = gcry_sexp_find_token(sig_sexp, "s", 0);
|
||||||
|
if (!data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = gcry_sexp_nth_data(data, 1, &size);
|
||||||
|
if (!tmp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp[0] == '\0') {
|
||||||
|
tmp++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
*signature = LIBSSH2_ALLOC(session, size);
|
||||||
|
memcpy(*signature, tmp, size);
|
||||||
|
*signature_len = size;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned long hash_len, unsigned char *sig)
|
||||||
|
{
|
||||||
|
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
|
||||||
|
gcry_sexp_t sig_sexp;
|
||||||
|
gcry_sexp_t data;
|
||||||
|
int ret;
|
||||||
|
const char *tmp;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
if (hash_len != SHA_DIGEST_LENGTH) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(zhash + 1, hash, hash_len);
|
||||||
|
zhash[0] = 0;
|
||||||
|
|
||||||
|
if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gcry_pk_sign(&sig_sexp, data, dsactx);
|
||||||
|
|
||||||
|
gcry_sexp_release(data);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(sig, 0, 40);
|
||||||
|
|
||||||
|
/* Extract R. */
|
||||||
|
|
||||||
|
data = gcry_sexp_find_token(sig_sexp, "r", 0);
|
||||||
|
if (!data)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
tmp = gcry_sexp_nth_data(data, 1, &size);
|
||||||
|
if (!tmp)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (tmp[0] == '\0') {
|
||||||
|
tmp++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 1 || size > 20)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
memcpy(sig + (20 - size), tmp, size);
|
||||||
|
|
||||||
|
gcry_sexp_release(data);
|
||||||
|
|
||||||
|
/* Extract S. */
|
||||||
|
|
||||||
|
data = gcry_sexp_find_token(sig_sexp, "s", 0);
|
||||||
|
if (!data)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
tmp = gcry_sexp_nth_data(data, 1, &size);
|
||||||
|
if (!tmp)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (tmp[0] == '\0') {
|
||||||
|
tmp++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 1 || size > 20)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
memcpy(sig + 20 + (20 - size), tmp, size);
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (sig_sexp) {
|
||||||
|
gcry_sexp_release(sig_sexp);
|
||||||
|
}
|
||||||
|
if (data) {
|
||||||
|
gcry_sexp_release(data);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||||
|
const unsigned char *sig,
|
||||||
|
const unsigned char *m, unsigned long m_len)
|
||||||
|
{
|
||||||
|
unsigned char hash[SHA_DIGEST_LENGTH + 1];
|
||||||
|
gcry_sexp_t s_sig, s_hash;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
libssh2_sha1(m, m_len, hash + 1);
|
||||||
|
hash[0] = 0;
|
||||||
|
|
||||||
|
if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
|
||||||
|
SHA_DIGEST_LENGTH + 1, hash)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
|
||||||
|
20, sig, 20, sig + 20)) {
|
||||||
|
gcry_sexp_release(s_hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = gcry_pk_verify(s_sig, s_hash, dsactx);
|
||||||
|
gcry_sexp_release(s_sig);
|
||||||
|
gcry_sexp_release(s_hash);
|
||||||
|
|
||||||
|
return (rc == 0) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||||
|
_libssh2_cipher_type(algo),
|
||||||
|
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int cipher = _libssh2_gcry_cipher (algo);
|
||||||
|
int mode = _libssh2_gcry_mode (algo);
|
||||||
|
int keylen = gcry_cipher_get_algo_keylen(cipher);
|
||||||
|
|
||||||
|
(void) encrypt;
|
||||||
|
|
||||||
|
ret = gcry_cipher_open(h, cipher, mode, 0);
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gcry_cipher_setkey(*h, secret, keylen);
|
||||||
|
if (ret) {
|
||||||
|
gcry_cipher_close(*h);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode != GCRY_CIPHER_MODE_STREAM) {
|
||||||
|
int blklen = gcry_cipher_get_algo_blklen(cipher);
|
||||||
|
if (mode == GCRY_CIPHER_MODE_CTR)
|
||||||
|
ret = gcry_cipher_setctr(*h, iv, blklen);
|
||||||
|
else
|
||||||
|
ret = gcry_cipher_setiv(*h, iv, blklen);
|
||||||
|
if (ret) {
|
||||||
|
gcry_cipher_close(*h);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||||
|
_libssh2_cipher_type(algo),
|
||||||
|
int encrypt, unsigned char *block)
|
||||||
|
{
|
||||||
|
int cipher = _libssh2_gcry_cipher (algo);
|
||||||
|
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (blklen == 1) {
|
||||||
|
/* Hack for arcfour. */
|
||||||
|
blklen = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encrypt) {
|
||||||
|
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
|
||||||
|
} else {
|
||||||
|
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char **method,
|
||||||
|
size_t *method_len,
|
||||||
|
unsigned char **pubkeydata,
|
||||||
|
size_t *pubkeydata_len,
|
||||||
|
const char *privatekey,
|
||||||
|
const char *passphrase)
|
||||||
|
{
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||||
|
"Unable to extract public key from private key file: "
|
||||||
|
"Method unimplemented in libgcrypt backend");
|
||||||
|
}
|
||||||
|
|
||||||
|
void _libssh2_init_aes_ctr(void)
|
||||||
|
{
|
||||||
|
/* no implementation */
|
||||||
|
}
|
||||||
|
#endif /* LIBSSH2_LIBGCRYPT */
|
||||||
150
vendor/libssh2-1.4.2/src/libgcrypt.h
vendored
Normal file
150
vendor/libssh2-1.4.2/src/libgcrypt.h
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008, 2009, 2010 Simon Josefsson
|
||||||
|
* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gcrypt.h>
|
||||||
|
|
||||||
|
#define LIBSSH2_MD5 1
|
||||||
|
|
||||||
|
#define LIBSSH2_HMAC_RIPEMD 1
|
||||||
|
|
||||||
|
#define LIBSSH2_AES 1
|
||||||
|
#define LIBSSH2_AES_CTR 1
|
||||||
|
#define LIBSSH2_BLOWFISH 1
|
||||||
|
#define LIBSSH2_RC4 1
|
||||||
|
#define LIBSSH2_CAST 1
|
||||||
|
#define LIBSSH2_3DES 1
|
||||||
|
|
||||||
|
#define LIBSSH2_RSA 1
|
||||||
|
#define LIBSSH2_DSA 1
|
||||||
|
|
||||||
|
#define MD5_DIGEST_LENGTH 16
|
||||||
|
#define SHA_DIGEST_LENGTH 20
|
||||||
|
|
||||||
|
#define _libssh2_random(buf, len) \
|
||||||
|
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
|
||||||
|
|
||||||
|
#define libssh2_sha1_ctx gcry_md_hd_t
|
||||||
|
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
|
||||||
|
#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
|
||||||
|
#define libssh2_sha1_final(ctx, out) \
|
||||||
|
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||||
|
#define libssh2_sha1(message, len, out) \
|
||||||
|
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
|
||||||
|
|
||||||
|
#define libssh2_md5_ctx gcry_md_hd_t
|
||||||
|
#define libssh2_md5_init(ctx) gcry_md_open (ctx, GCRY_MD_MD5, 0);
|
||||||
|
#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
|
||||||
|
#define libssh2_md5_final(ctx, out) \
|
||||||
|
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||||
|
#define libssh2_md5(message, len, out) \
|
||||||
|
gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len)
|
||||||
|
|
||||||
|
#define libssh2_hmac_ctx gcry_md_hd_t
|
||||||
|
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||||
|
gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
|
||||||
|
gcry_md_setkey (*ctx, key, keylen)
|
||||||
|
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||||
|
gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
|
||||||
|
gcry_md_setkey (*ctx, key, keylen)
|
||||||
|
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
|
||||||
|
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
|
||||||
|
gcry_md_setkey (*ctx, key, keylen)
|
||||||
|
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||||
|
gcry_md_write (ctx, data, datalen)
|
||||||
|
#define libssh2_hmac_final(ctx, data) \
|
||||||
|
memcpy (data, gcry_md_read (ctx, 0), \
|
||||||
|
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))
|
||||||
|
#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
|
||||||
|
|
||||||
|
#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)
|
||||||
|
#define libssh2_crypto_exit()
|
||||||
|
|
||||||
|
#define libssh2_rsa_ctx struct gcry_sexp
|
||||||
|
|
||||||
|
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)
|
||||||
|
|
||||||
|
#define libssh2_dsa_ctx struct gcry_sexp
|
||||||
|
|
||||||
|
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
|
||||||
|
|
||||||
|
#define _libssh2_cipher_type(name) int name
|
||||||
|
#define _libssh2_cipher_ctx gcry_cipher_hd_t
|
||||||
|
|
||||||
|
#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m)
|
||||||
|
#define _libssh2_gcry_cipher(c) (c >> 8)
|
||||||
|
#define _libssh2_gcry_mode(m) (m & 0xFF)
|
||||||
|
|
||||||
|
#define _libssh2_cipher_aes256ctr \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
|
||||||
|
#define _libssh2_cipher_aes192ctr \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
|
||||||
|
#define _libssh2_cipher_aes128ctr \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
|
||||||
|
#define _libssh2_cipher_aes256 \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
|
||||||
|
#define _libssh2_cipher_aes192 \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
|
||||||
|
#define _libssh2_cipher_aes128 \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
|
||||||
|
#define _libssh2_cipher_blowfish \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
|
||||||
|
#define _libssh2_cipher_arcfour \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
|
||||||
|
#define _libssh2_cipher_cast5 \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
|
||||||
|
#define _libssh2_cipher_3des \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
|
||||||
|
|
||||||
|
|
||||||
|
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
|
||||||
|
|
||||||
|
#define _libssh2_bn struct gcry_mpi
|
||||||
|
#define _libssh2_bn_ctx int
|
||||||
|
#define _libssh2_bn_ctx_new() 0
|
||||||
|
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
|
||||||
|
#define _libssh2_bn_init() gcry_mpi_new(0)
|
||||||
|
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
|
||||||
|
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
|
||||||
|
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
|
||||||
|
#define _libssh2_bn_from_bin(bn, len, val) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
|
||||||
|
#define _libssh2_bn_to_bin(bn, val) gcry_mpi_print (GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
|
||||||
|
#define _libssh2_bn_bytes(bn) (gcry_mpi_get_nbits (bn) / 8 + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1))
|
||||||
|
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn)
|
||||||
|
#define _libssh2_bn_free(bn) gcry_mpi_release(bn)
|
||||||
|
|
||||||
5
vendor/libssh2-1.4.2/src/libssh2_config.h
vendored
Normal file
5
vendor/libssh2-1.4.2/src/libssh2_config.h
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "libssh2_config_win.h"
|
||||||
|
#else
|
||||||
|
#include "libssh2_config_osx.h"
|
||||||
|
#endif
|
||||||
224
vendor/libssh2-1.4.2/src/libssh2_config_osx.h
vendored
Normal file
224
vendor/libssh2-1.4.2/src/libssh2_config_osx.h
vendored
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
/* src/libssh2_config.h. Generated from libssh2_config.h.in by configure. */
|
||||||
|
/* src/libssh2_config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define if building universal (internal helper macro) */
|
||||||
|
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||||
|
|
||||||
|
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||||
|
systems. This function is required for `alloca.c' support on those systems.
|
||||||
|
*/
|
||||||
|
/* #undef CRAY_STACKSEG_END */
|
||||||
|
|
||||||
|
/* Define to 1 if using `alloca.c'. */
|
||||||
|
/* #undef C_ALLOCA */
|
||||||
|
|
||||||
|
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||||
|
#define HAVE_ALLOCA 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||||
|
*/
|
||||||
|
#define HAVE_ALLOCA_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
|
#define HAVE_ARPA_INET_H 1
|
||||||
|
|
||||||
|
/* disabled non-blocking sockets */
|
||||||
|
/* #undef HAVE_DISABLED_NONBLOCKING */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#define HAVE_DLFCN_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <errno.h> header file. */
|
||||||
|
#define HAVE_ERRNO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `EVP_aes_128_ctr' function. */
|
||||||
|
/* #undef HAVE_EVP_AES_128_CTR */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
|
#define HAVE_FCNTL_H 1
|
||||||
|
|
||||||
|
/* use FIONBIO for non-blocking sockets */
|
||||||
|
/* #undef HAVE_FIONBIO */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
|
#define HAVE_GETTIMEOFDAY 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#define HAVE_INTTYPES_H 1
|
||||||
|
|
||||||
|
/* use ioctlsocket() for non-blocking sockets */
|
||||||
|
/* #undef HAVE_IOCTLSOCKET */
|
||||||
|
|
||||||
|
/* use Ioctlsocket() for non-blocking sockets */
|
||||||
|
/* #undef HAVE_IOCTLSOCKET_CASE */
|
||||||
|
|
||||||
|
/* Define if you have the gcrypt library. */
|
||||||
|
/* #undef HAVE_LIBGCRYPT */
|
||||||
|
|
||||||
|
/* Define if you have the ssl library. */
|
||||||
|
#define HAVE_LIBSSL 1
|
||||||
|
|
||||||
|
/* Define if you have the z library. */
|
||||||
|
#define HAVE_LIBZ 1
|
||||||
|
|
||||||
|
/* Define to 1 if the compiler supports the 'long long' data type. */
|
||||||
|
#define HAVE_LONGLONG 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#define HAVE_MEMORY_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||||
|
#define HAVE_NETINET_IN_H 1
|
||||||
|
|
||||||
|
/* use O_NONBLOCK for non-blocking sockets */
|
||||||
|
#define HAVE_O_NONBLOCK 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `poll' function. */
|
||||||
|
/* #undef HAVE_POLL */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the select function. */
|
||||||
|
#define HAVE_SELECT 1
|
||||||
|
|
||||||
|
/* use SO_NONBLOCK for non-blocking sockets */
|
||||||
|
/* #undef HAVE_SO_NONBLOCK */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#define HAVE_STDINT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdio.h> header file. */
|
||||||
|
#define HAVE_STDIO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#define HAVE_STDLIB_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#define HAVE_STRINGS_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#define HAVE_STRING_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtoll' function. */
|
||||||
|
#define HAVE_STRTOLL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||||
|
#define HAVE_SYS_IOCTL_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||||
|
#define HAVE_SYS_SELECT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||||
|
#define HAVE_SYS_SOCKET_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#define HAVE_SYS_TIME_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||||
|
#define HAVE_SYS_UIO_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||||
|
#define HAVE_SYS_UN_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <windows.h> header file. */
|
||||||
|
/* #undef HAVE_WINDOWS_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||||
|
/* #undef HAVE_WINSOCK2_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||||
|
/* #undef HAVE_WS2TCPIP_H */
|
||||||
|
|
||||||
|
/* to make a symbol visible */
|
||||||
|
/* #undef LIBSSH2_API */
|
||||||
|
|
||||||
|
/* Enable "none" cipher -- NOT RECOMMENDED */
|
||||||
|
/* #undef LIBSSH2_CRYPT_NONE */
|
||||||
|
|
||||||
|
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
|
||||||
|
#define LIBSSH2_DH_GEX_NEW 1
|
||||||
|
|
||||||
|
/* Compile in zlib support */
|
||||||
|
#define LIBSSH2_HAVE_ZLIB 1
|
||||||
|
|
||||||
|
/* Use libgcrypt */
|
||||||
|
/* #undef LIBSSH2_LIBGCRYPT */
|
||||||
|
|
||||||
|
/* Enable "none" MAC -- NOT RECOMMENDED */
|
||||||
|
/* #undef LIBSSH2_MAC_NONE */
|
||||||
|
|
||||||
|
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||||
|
*/
|
||||||
|
#define LT_OBJDIR ".libs/"
|
||||||
|
|
||||||
|
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
|
||||||
|
/* #undef NEED_REENTRANT */
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#define PACKAGE "libssh2"
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#define PACKAGE_BUGREPORT "libssh2-devel@cool.haxx.se"
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#define PACKAGE_NAME "libssh2"
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#define PACKAGE_STRING "libssh2 -"
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#define PACKAGE_TARNAME "libssh2"
|
||||||
|
|
||||||
|
/* Define to the home page for this package. */
|
||||||
|
#define PACKAGE_URL ""
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#define PACKAGE_VERSION "-"
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at runtime.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
/* #undef STACK_DIRECTION */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#define VERSION "-"
|
||||||
|
|
||||||
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||||
|
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||||
|
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||||
|
# if defined __BIG_ENDIAN__
|
||||||
|
# define WORDS_BIGENDIAN 1
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifndef WORDS_BIGENDIAN
|
||||||
|
/* # undef WORDS_BIGENDIAN */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||||
|
/* #undef _FILE_OFFSET_BITS */
|
||||||
|
|
||||||
|
/* Define for large files, on AIX-style hosts. */
|
||||||
|
/* #undef _LARGE_FILES */
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
/* #undef const */
|
||||||
|
|
||||||
|
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||||
|
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||||
|
#ifndef __cplusplus
|
||||||
|
/* #undef inline */
|
||||||
|
#endif
|
||||||
41
vendor/libssh2-1.4.2/src/libssh2_config_win.h
vendored
Normal file
41
vendor/libssh2-1.4.2/src/libssh2_config_win.h
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef LIBSSH2_CONFIG_H
|
||||||
|
#define LIBSSH2_CONFIG_H
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#endif /* _CRT_SECURE_NO_DEPRECATE */
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#define HAVE_UNISTD_H
|
||||||
|
#define HAVE_INTTYPES_H
|
||||||
|
#define HAVE_SYS_TIME_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAVE_WINSOCK2_H
|
||||||
|
#define HAVE_IOCTLSOCKET
|
||||||
|
#define HAVE_SELECT
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#if _MSC_VER < 1500
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
#endif
|
||||||
|
#define strdup _strdup
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#define strcasecmp _stricmp
|
||||||
|
#else
|
||||||
|
#define strncasecmp strnicmp
|
||||||
|
#define strcasecmp stricmp
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
|
||||||
|
#define LIBSSH2_DH_GEX_NEW 1
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_CONFIG_H */
|
||||||
|
|
||||||
1038
vendor/libssh2-1.4.2/src/libssh2_priv.h
vendored
Normal file
1038
vendor/libssh2-1.4.2/src/libssh2_priv.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
314
vendor/libssh2-1.4.2/src/mac.c
vendored
Normal file
314
vendor/libssh2-1.4.2/src/mac.c
vendored
Normal file
|
|
@ -0,0 +1,314 @@
|
||||||
|
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include "mac.h"
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_MAC_NONE
|
||||||
|
/* mac_none_MAC
|
||||||
|
* Minimalist MAC: No MAC
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||||
|
uint32_t seqno, const unsigned char *packet,
|
||||||
|
uint32_t packet_len, const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len, void **abstract)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static LIBSSH2_MAC_METHOD mac_method_none = {
|
||||||
|
"none",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
mac_none_MAC,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_MAC_NONE */
|
||||||
|
|
||||||
|
/* mac_method_common_init
|
||||||
|
* Initialize simple mac methods
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
|
||||||
|
int *free_key, void **abstract)
|
||||||
|
{
|
||||||
|
*abstract = key;
|
||||||
|
*free_key = 0;
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mac_method_common_dtor
|
||||||
|
* Cleanup simple mac methods
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||||
|
{
|
||||||
|
if (*abstract) {
|
||||||
|
LIBSSH2_FREE(session, *abstract);
|
||||||
|
}
|
||||||
|
*abstract = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* mac_method_hmac_sha1_hash
|
||||||
|
* Calculate hash using full sha1 value
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char *buf, uint32_t seqno,
|
||||||
|
const unsigned char *packet,
|
||||||
|
uint32_t packet_len,
|
||||||
|
const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len, void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_hmac_ctx ctx;
|
||||||
|
unsigned char seqno_buf[4];
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_htonu32(seqno_buf, seqno);
|
||||||
|
|
||||||
|
libssh2_hmac_sha1_init(&ctx, *abstract, 20);
|
||||||
|
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||||
|
libssh2_hmac_update(ctx, packet, packet_len);
|
||||||
|
if (addtl && addtl_len) {
|
||||||
|
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||||
|
}
|
||||||
|
libssh2_hmac_final(ctx, buf);
|
||||||
|
libssh2_hmac_cleanup(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
|
||||||
|
"hmac-sha1",
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
mac_method_common_init,
|
||||||
|
mac_method_hmac_sha1_hash,
|
||||||
|
mac_method_common_dtor,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mac_method_hmac_sha1_96_hash
|
||||||
|
* Calculate hash using first 96 bits of sha1 value
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char *buf, uint32_t seqno,
|
||||||
|
const unsigned char *packet,
|
||||||
|
uint32_t packet_len,
|
||||||
|
const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len, void **abstract)
|
||||||
|
{
|
||||||
|
unsigned char temp[SHA_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
|
||||||
|
addtl, addtl_len, abstract);
|
||||||
|
memcpy(buf, (char *) temp, 96 / 8);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
|
||||||
|
"hmac-sha1-96",
|
||||||
|
12,
|
||||||
|
20,
|
||||||
|
mac_method_common_init,
|
||||||
|
mac_method_hmac_sha1_96_hash,
|
||||||
|
mac_method_common_dtor,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if LIBSSH2_MD5
|
||||||
|
/* mac_method_hmac_md5_hash
|
||||||
|
* Calculate hash using full md5 value
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||||
|
uint32_t seqno,
|
||||||
|
const unsigned char *packet,
|
||||||
|
uint32_t packet_len,
|
||||||
|
const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len, void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_hmac_ctx ctx;
|
||||||
|
unsigned char seqno_buf[4];
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_htonu32(seqno_buf, seqno);
|
||||||
|
|
||||||
|
libssh2_hmac_md5_init(&ctx, *abstract, 16);
|
||||||
|
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||||
|
libssh2_hmac_update(ctx, packet, packet_len);
|
||||||
|
if (addtl && addtl_len) {
|
||||||
|
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||||
|
}
|
||||||
|
libssh2_hmac_final(ctx, buf);
|
||||||
|
libssh2_hmac_cleanup(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
|
||||||
|
"hmac-md5",
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
mac_method_common_init,
|
||||||
|
mac_method_hmac_md5_hash,
|
||||||
|
mac_method_common_dtor,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mac_method_hmac_md5_96_hash
|
||||||
|
* Calculate hash using first 96 bits of md5 value
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char *buf, uint32_t seqno,
|
||||||
|
const unsigned char *packet,
|
||||||
|
uint32_t packet_len,
|
||||||
|
const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len, void **abstract)
|
||||||
|
{
|
||||||
|
unsigned char temp[MD5_DIGEST_LENGTH];
|
||||||
|
mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
|
||||||
|
addtl, addtl_len, abstract);
|
||||||
|
memcpy(buf, (char *) temp, 96 / 8);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
|
||||||
|
"hmac-md5-96",
|
||||||
|
12,
|
||||||
|
16,
|
||||||
|
mac_method_common_init,
|
||||||
|
mac_method_hmac_md5_96_hash,
|
||||||
|
mac_method_common_dtor,
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_MD5 */
|
||||||
|
|
||||||
|
#if LIBSSH2_HMAC_RIPEMD
|
||||||
|
/* mac_method_hmac_ripemd160_hash
|
||||||
|
* Calculate hash using ripemd160 value
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char *buf, uint32_t seqno,
|
||||||
|
const unsigned char *packet,
|
||||||
|
uint32_t packet_len,
|
||||||
|
const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len,
|
||||||
|
void **abstract)
|
||||||
|
{
|
||||||
|
libssh2_hmac_ctx ctx;
|
||||||
|
unsigned char seqno_buf[4];
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_htonu32(seqno_buf, seqno);
|
||||||
|
|
||||||
|
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
|
||||||
|
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||||
|
libssh2_hmac_update(ctx, packet, packet_len);
|
||||||
|
if (addtl && addtl_len) {
|
||||||
|
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||||
|
}
|
||||||
|
libssh2_hmac_final(ctx, buf);
|
||||||
|
libssh2_hmac_cleanup(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
|
||||||
|
"hmac-ripemd160",
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
mac_method_common_init,
|
||||||
|
mac_method_hmac_ripemd160_hash,
|
||||||
|
mac_method_common_dtor,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
20,
|
||||||
|
20,
|
||||||
|
mac_method_common_init,
|
||||||
|
mac_method_hmac_ripemd160_hash,
|
||||||
|
mac_method_common_dtor,
|
||||||
|
};
|
||||||
|
#endif /* LIBSSH2_HMAC_RIPEMD */
|
||||||
|
|
||||||
|
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
|
||||||
|
&mac_method_hmac_sha1,
|
||||||
|
&mac_method_hmac_sha1_96,
|
||||||
|
#if LIBSSH2_MD5
|
||||||
|
&mac_method_hmac_md5,
|
||||||
|
&mac_method_hmac_md5_96,
|
||||||
|
#endif
|
||||||
|
#if LIBSSH2_HMAC_RIPEMD
|
||||||
|
&mac_method_hmac_ripemd160,
|
||||||
|
&mac_method_hmac_ripemd160_openssh_com,
|
||||||
|
#endif /* LIBSSH2_HMAC_RIPEMD */
|
||||||
|
#ifdef LIBSSH2_MAC_NONE
|
||||||
|
&mac_method_none,
|
||||||
|
#endif /* LIBSSH2_MAC_NONE */
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const LIBSSH2_MAC_METHOD **
|
||||||
|
_libssh2_mac_methods(void)
|
||||||
|
{
|
||||||
|
return mac_methods;
|
||||||
|
}
|
||||||
67
vendor/libssh2-1.4.2/src/mac.h
vendored
Normal file
67
vendor/libssh2-1.4.2/src/mac.h
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#ifndef __LIBSSH2_MAC_H
|
||||||
|
#define __LIBSSH2_MAC_H
|
||||||
|
|
||||||
|
/* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
struct _LIBSSH2_MAC_METHOD
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* The length of a given MAC packet */
|
||||||
|
int mac_len;
|
||||||
|
|
||||||
|
/* integrity key length */
|
||||||
|
int key_len;
|
||||||
|
|
||||||
|
/* Message Authentication Code Hashing algo */
|
||||||
|
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
|
||||||
|
void **abstract);
|
||||||
|
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
|
||||||
|
uint32_t seqno, const unsigned char *packet,
|
||||||
|
uint32_t packet_len, const unsigned char *addtl,
|
||||||
|
uint32_t addtl_len, void **abstract);
|
||||||
|
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
|
||||||
|
|
||||||
|
const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
|
||||||
|
|
||||||
|
#endif /* __LIBSSH2_MAC_H */
|
||||||
612
vendor/libssh2-1.4.2/src/misc.c
vendored
Normal file
612
vendor/libssh2-1.4.2/src/misc.c
vendored
Normal file
|
|
@ -0,0 +1,612 @@
|
||||||
|
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||||
|
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||||
|
* Copyright (c) 2010 Simon Josefsson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
|
||||||
|
{
|
||||||
|
session->err_msg = errmsg;
|
||||||
|
session->err_code = errcode;
|
||||||
|
#ifdef LIBSSH2DEBUG
|
||||||
|
if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode)
|
||||||
|
/* if this is EAGAIN and we're in non-blocking mode, don't generate
|
||||||
|
a debug output for this */
|
||||||
|
return errcode;
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code,
|
||||||
|
session->err_msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
static int wsa2errno(void)
|
||||||
|
{
|
||||||
|
switch (WSAGetLastError()) {
|
||||||
|
case WSAEWOULDBLOCK:
|
||||||
|
return EAGAIN;
|
||||||
|
|
||||||
|
case WSAENOTSOCK:
|
||||||
|
return EBADF;
|
||||||
|
|
||||||
|
case WSAEINTR:
|
||||||
|
return EINTR;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* It is most important to ensure errno does not stay at EAGAIN
|
||||||
|
* when a different error occurs so just set errno to a generic
|
||||||
|
* error */
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* _libssh2_recv
|
||||||
|
*
|
||||||
|
* Replacement for the standard recv, return -errno on failure.
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract)
|
||||||
|
{
|
||||||
|
ssize_t rc = recv(sock, buffer, length, flags);
|
||||||
|
#ifdef WIN32
|
||||||
|
if (rc < 0 )
|
||||||
|
return -wsa2errno();
|
||||||
|
#elif defined(__VMS)
|
||||||
|
if (rc < 0 ){
|
||||||
|
if ( errno == EWOULDBLOCK )
|
||||||
|
return -EAGAIN;
|
||||||
|
else
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (rc < 0 ){
|
||||||
|
/* Sometimes the first recv() function call sets errno to ENOENT on
|
||||||
|
Solaris and HP-UX */
|
||||||
|
if ( errno == ENOENT )
|
||||||
|
return -EAGAIN;
|
||||||
|
else
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _libssh2_send
|
||||||
|
*
|
||||||
|
* Replacement for the standard send, return -errno on failure.
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||||
|
int flags, void **abstract)
|
||||||
|
{
|
||||||
|
ssize_t rc = send(sock, buffer, length, flags);
|
||||||
|
#ifdef WIN32
|
||||||
|
if (rc < 0 )
|
||||||
|
return -wsa2errno();
|
||||||
|
#elif defined(__VMS)
|
||||||
|
if (rc < 0 ) {
|
||||||
|
if ( errno == EWOULDBLOCK )
|
||||||
|
return -EAGAIN;
|
||||||
|
else
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (rc < 0 )
|
||||||
|
return -errno;
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* libssh2_ntohu32
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
_libssh2_ntohu32(const unsigned char *buf)
|
||||||
|
{
|
||||||
|
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* _libssh2_ntohu64
|
||||||
|
*/
|
||||||
|
libssh2_uint64_t
|
||||||
|
_libssh2_ntohu64(const unsigned char *buf)
|
||||||
|
{
|
||||||
|
unsigned long msl, lsl;
|
||||||
|
|
||||||
|
msl = ((libssh2_uint64_t)buf[0] << 24) | ((libssh2_uint64_t)buf[1] << 16)
|
||||||
|
| ((libssh2_uint64_t)buf[2] << 8) | (libssh2_uint64_t)buf[3];
|
||||||
|
lsl = ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16)
|
||||||
|
| ((libssh2_uint64_t)buf[6] << 8) | (libssh2_uint64_t)buf[7];
|
||||||
|
|
||||||
|
return ((libssh2_uint64_t)msl <<32) | lsl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _libssh2_htonu32
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_libssh2_htonu32(unsigned char *buf, uint32_t value)
|
||||||
|
{
|
||||||
|
buf[0] = (value >> 24) & 0xFF;
|
||||||
|
buf[1] = (value >> 16) & 0xFF;
|
||||||
|
buf[2] = (value >> 8) & 0xFF;
|
||||||
|
buf[3] = value & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _libssh2_store_u32
|
||||||
|
*/
|
||||||
|
void _libssh2_store_u32(unsigned char **buf, uint32_t value)
|
||||||
|
{
|
||||||
|
_libssh2_htonu32(*buf, value);
|
||||||
|
*buf += sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _libssh2_store_str
|
||||||
|
*/
|
||||||
|
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
|
||||||
|
{
|
||||||
|
_libssh2_store_u32(buf, (uint32_t)len);
|
||||||
|
if(len) {
|
||||||
|
memcpy(*buf, str, len);
|
||||||
|
*buf += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Base64 Conversion */
|
||||||
|
|
||||||
|
static const char base64_table[] =
|
||||||
|
{
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char base64_pad = '=';
|
||||||
|
|
||||||
|
static const short base64_reverse_table[256] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||||
|
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||||
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* libssh2_base64_decode
|
||||||
|
*
|
||||||
|
* Decode a base64 chunk and store it into a newly alloc'd buffer
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
|
||||||
|
unsigned int *datalen, const char *src,
|
||||||
|
unsigned int src_len)
|
||||||
|
{
|
||||||
|
unsigned char *s, *d;
|
||||||
|
short v;
|
||||||
|
int i = 0, len = 0;
|
||||||
|
|
||||||
|
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
|
||||||
|
d = (unsigned char *) *data;
|
||||||
|
if (!d) {
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for base64 decoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
|
||||||
|
if ((v = base64_reverse_table[*s]) < 0)
|
||||||
|
continue;
|
||||||
|
switch (i % 4) {
|
||||||
|
case 0:
|
||||||
|
d[len] = v << 2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
d[len++] |= v >> 4;
|
||||||
|
d[len] = v << 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
d[len++] |= v >> 2;
|
||||||
|
d[len] = v << 6;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
d[len++] |= v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if ((i % 4) == 1) {
|
||||||
|
/* Invalid -- We have a byte which belongs exclusively to a partial
|
||||||
|
octet */
|
||||||
|
LIBSSH2_FREE(session, *data);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64");
|
||||||
|
}
|
||||||
|
|
||||||
|
*datalen = len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Base64 Encoding/Decoding Table --- */
|
||||||
|
static const char table64[]=
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_base64_encode()
|
||||||
|
*
|
||||||
|
* Returns the length of the newly created base64 string. The third argument
|
||||||
|
* is a pointer to an allocated area holding the base64 data. If something
|
||||||
|
* went wrong, 0 is returned.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
|
||||||
|
const char *inp, size_t insize, char **outptr)
|
||||||
|
{
|
||||||
|
unsigned char ibuf[3];
|
||||||
|
unsigned char obuf[4];
|
||||||
|
int i;
|
||||||
|
int inputparts;
|
||||||
|
char *output;
|
||||||
|
char *base64data;
|
||||||
|
const char *indata = inp;
|
||||||
|
|
||||||
|
*outptr = NULL; /* set to NULL in case of failure before we reach the end */
|
||||||
|
|
||||||
|
if(0 == insize)
|
||||||
|
insize = strlen(indata);
|
||||||
|
|
||||||
|
base64data = output = LIBSSH2_ALLOC(session, insize*4/3+4);
|
||||||
|
if(NULL == output)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while(insize > 0) {
|
||||||
|
for (i = inputparts = 0; i < 3; i++) {
|
||||||
|
if(insize > 0) {
|
||||||
|
inputparts++;
|
||||||
|
ibuf[i] = *indata;
|
||||||
|
indata++;
|
||||||
|
insize--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ibuf[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
|
||||||
|
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
|
||||||
|
((ibuf[1] & 0xF0) >> 4));
|
||||||
|
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
|
||||||
|
((ibuf[2] & 0xC0) >> 6));
|
||||||
|
obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
|
||||||
|
|
||||||
|
switch(inputparts) {
|
||||||
|
case 1: /* only one byte read */
|
||||||
|
snprintf(output, 5, "%c%c==",
|
||||||
|
table64[obuf[0]],
|
||||||
|
table64[obuf[1]]);
|
||||||
|
break;
|
||||||
|
case 2: /* two bytes read */
|
||||||
|
snprintf(output, 5, "%c%c%c=",
|
||||||
|
table64[obuf[0]],
|
||||||
|
table64[obuf[1]],
|
||||||
|
table64[obuf[2]]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(output, 5, "%c%c%c%c",
|
||||||
|
table64[obuf[0]],
|
||||||
|
table64[obuf[1]],
|
||||||
|
table64[obuf[2]],
|
||||||
|
table64[obuf[3]] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
output += 4;
|
||||||
|
}
|
||||||
|
*output=0;
|
||||||
|
*outptr = base64data; /* make it return the actual data memory */
|
||||||
|
|
||||||
|
return strlen(base64data); /* return the length of the new data */
|
||||||
|
}
|
||||||
|
/* ---- End of Base64 Encoding ---- */
|
||||||
|
|
||||||
|
LIBSSH2_API void
|
||||||
|
libssh2_free(LIBSSH2_SESSION *session, void *ptr)
|
||||||
|
{
|
||||||
|
LIBSSH2_FREE(session, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef LIBSSH2DEBUG
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||||
|
{
|
||||||
|
session->showmask = bitmask;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context,
|
||||||
|
libssh2_trace_handler_func callback)
|
||||||
|
{
|
||||||
|
session->tracehandler = callback;
|
||||||
|
session->tracehandler_context = handler_context;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||||
|
{
|
||||||
|
char buffer[1536];
|
||||||
|
int len, msglen, buflen = sizeof(buffer);
|
||||||
|
va_list vargs;
|
||||||
|
struct timeval now;
|
||||||
|
static int firstsec;
|
||||||
|
static const char *const contexts[] = {
|
||||||
|
"Unknown",
|
||||||
|
"Transport",
|
||||||
|
"Key Ex",
|
||||||
|
"Userauth",
|
||||||
|
"Conn",
|
||||||
|
"SCP",
|
||||||
|
"SFTP",
|
||||||
|
"Failure Event",
|
||||||
|
"Publickey",
|
||||||
|
"Socket",
|
||||||
|
};
|
||||||
|
const char* contexttext = contexts[0];
|
||||||
|
unsigned int contextindex;
|
||||||
|
|
||||||
|
if (!(session->showmask & context)) {
|
||||||
|
/* no such output asked for */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the first matching context string for this message */
|
||||||
|
for (contextindex = 0; contextindex < ARRAY_SIZE(contexts);
|
||||||
|
contextindex++) {
|
||||||
|
if ((context & (1 << contextindex)) != 0) {
|
||||||
|
contexttext = contexts[contextindex];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_libssh2_gettimeofday(&now, NULL);
|
||||||
|
if(!firstsec) {
|
||||||
|
firstsec = now.tv_sec;
|
||||||
|
}
|
||||||
|
now.tv_sec -= firstsec;
|
||||||
|
|
||||||
|
len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ",
|
||||||
|
(int)now.tv_sec, (int)now.tv_usec, contexttext);
|
||||||
|
|
||||||
|
if (len >= buflen)
|
||||||
|
msglen = buflen - 1;
|
||||||
|
else {
|
||||||
|
buflen -= len;
|
||||||
|
msglen = len;
|
||||||
|
va_start(vargs, format);
|
||||||
|
len = vsnprintf(buffer + msglen, buflen, format, vargs);
|
||||||
|
va_end(vargs);
|
||||||
|
msglen += len < buflen ? len : buflen - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->tracehandler)
|
||||||
|
(session->tracehandler)(session, session->tracehandler_context, buffer,
|
||||||
|
msglen);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s\n", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||||
|
{
|
||||||
|
(void) session;
|
||||||
|
(void) bitmask;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context,
|
||||||
|
libssh2_trace_handler_func callback)
|
||||||
|
{
|
||||||
|
(void) session;
|
||||||
|
(void) handler_context;
|
||||||
|
(void) callback;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* init the list head */
|
||||||
|
void _libssh2_list_init(struct list_head *head)
|
||||||
|
{
|
||||||
|
head->first = head->last = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add a node to the list */
|
||||||
|
void _libssh2_list_add(struct list_head *head,
|
||||||
|
struct list_node *entry)
|
||||||
|
{
|
||||||
|
/* store a pointer to the head */
|
||||||
|
entry->head = head;
|
||||||
|
|
||||||
|
/* we add this entry at the "top" so it has no next */
|
||||||
|
entry->next = NULL;
|
||||||
|
|
||||||
|
/* make our prev point to what the head thinks is last */
|
||||||
|
entry->prev = head->last;
|
||||||
|
|
||||||
|
/* and make head's last be us now */
|
||||||
|
head->last = entry;
|
||||||
|
|
||||||
|
/* make sure our 'prev' node points to us next */
|
||||||
|
if(entry->prev)
|
||||||
|
entry->prev->next = entry;
|
||||||
|
else
|
||||||
|
head->first = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the "first" node in the list this head points to */
|
||||||
|
void *_libssh2_list_first(struct list_head *head)
|
||||||
|
{
|
||||||
|
return head->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the next node in the list */
|
||||||
|
void *_libssh2_list_next(struct list_node *node)
|
||||||
|
{
|
||||||
|
return node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the prev node in the list */
|
||||||
|
void *_libssh2_list_prev(struct list_node *node)
|
||||||
|
{
|
||||||
|
return node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove this node from the list */
|
||||||
|
void _libssh2_list_remove(struct list_node *entry)
|
||||||
|
{
|
||||||
|
if(entry->prev)
|
||||||
|
entry->prev->next = entry->next;
|
||||||
|
else
|
||||||
|
entry->head->first = entry->next;
|
||||||
|
|
||||||
|
if(entry->next)
|
||||||
|
entry->next->prev = entry->prev;
|
||||||
|
else
|
||||||
|
entry->head->last = entry->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* insert a node before the given 'after' entry */
|
||||||
|
void _libssh2_list_insert(struct list_node *after, /* insert before this */
|
||||||
|
struct list_node *entry)
|
||||||
|
{
|
||||||
|
/* 'after' is next to 'entry' */
|
||||||
|
bentry->next = after;
|
||||||
|
|
||||||
|
/* entry's prev is then made to be the prev after current has */
|
||||||
|
entry->prev = after->prev;
|
||||||
|
|
||||||
|
/* the node that is now before 'entry' was previously before 'after'
|
||||||
|
and must be made to point to 'entry' correctly */
|
||||||
|
if(entry->prev)
|
||||||
|
entry->prev->next = entry;
|
||||||
|
else
|
||||||
|
/* there was no node before this, so we make sure we point the head
|
||||||
|
pointer to this node */
|
||||||
|
after->head->first = entry;
|
||||||
|
|
||||||
|
/* after's prev entry points back to entry */
|
||||||
|
after->prev = entry;
|
||||||
|
|
||||||
|
/* after's next entry is still the same as before */
|
||||||
|
|
||||||
|
/* entry's head is the same as after's */
|
||||||
|
entry->head = after->head;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this define is defined in misc.h for the correct platforms */
|
||||||
|
#ifdef LIBSSH2_GETTIMEOFDAY_WIN32
|
||||||
|
/*
|
||||||
|
* gettimeofday
|
||||||
|
* Implementation according to:
|
||||||
|
* The Open Group Base Specifications Issue 6
|
||||||
|
* IEEE Std 1003.1, 2004 Edition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||||
|
*
|
||||||
|
* This source code is offered for use in the public domain. You may
|
||||||
|
* use, modify or distribute it freely.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful but
|
||||||
|
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||||
|
* DISCLAIMED. This includes but is not limited to warranties of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Contributed by:
|
||||||
|
* Danny Smith <dannysmith@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
|
||||||
|
#define _W32_FT_OFFSET (116444736000000000)
|
||||||
|
|
||||||
|
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
|
||||||
|
FILETIME ft;
|
||||||
|
} _now;
|
||||||
|
|
||||||
|
if(tp)
|
||||||
|
{
|
||||||
|
GetSystemTimeAsFileTime (&_now.ft);
|
||||||
|
tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 );
|
||||||
|
tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
|
||||||
|
}
|
||||||
|
/* Always return 0 as per Open Group Base Specifications Issue 6.
|
||||||
|
Do not set errno on error. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
94
vendor/libssh2-1.4.2/src/misc.h
vendored
Normal file
94
vendor/libssh2-1.4.2/src/misc.h
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#ifndef __LIBSSH2_MISC_H
|
||||||
|
#define __LIBSSH2_MISC_H
|
||||||
|
/* Copyright (c) 2009-2011 by Daniel Stenberg
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct list_head {
|
||||||
|
struct list_node *last;
|
||||||
|
struct list_node *first;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct list_node {
|
||||||
|
struct list_node *next;
|
||||||
|
struct list_node *prev;
|
||||||
|
struct list_head *head;
|
||||||
|
};
|
||||||
|
|
||||||
|
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg);
|
||||||
|
|
||||||
|
void _libssh2_list_init(struct list_head *head);
|
||||||
|
|
||||||
|
/* add a node last in the list */
|
||||||
|
void _libssh2_list_add(struct list_head *head,
|
||||||
|
struct list_node *entry);
|
||||||
|
|
||||||
|
/* return the "first" node in the list this head points to */
|
||||||
|
void *_libssh2_list_first(struct list_head *head);
|
||||||
|
|
||||||
|
/* return the next node in the list */
|
||||||
|
void *_libssh2_list_next(struct list_node *node);
|
||||||
|
|
||||||
|
/* return the prev node in the list */
|
||||||
|
void *_libssh2_list_prev(struct list_node *node);
|
||||||
|
|
||||||
|
/* remove this node from the list */
|
||||||
|
void _libssh2_list_remove(struct list_node *entry);
|
||||||
|
|
||||||
|
size_t _libssh2_base64_encode(struct _LIBSSH2_SESSION *session,
|
||||||
|
const char *inp, size_t insize, char **outptr);
|
||||||
|
|
||||||
|
unsigned int _libssh2_ntohu32(const unsigned char *buf);
|
||||||
|
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
|
||||||
|
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
|
||||||
|
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
|
||||||
|
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
|
||||||
|
|
||||||
|
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||||
|
/* provide a private one */
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
|
||||||
|
#define HAVE_LIBSSH2_GETTIMEOFDAY
|
||||||
|
#define LIBSSH2_GETTIMEOFDAY_WIN32 /* enable the win32 implementation */
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
|
#define _libssh2_gettimeofday(x,y) gettimeofday(x,y)
|
||||||
|
#define HAVE_LIBSSH2_GETTIMEOFDAY
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LIBSSH2_MISC_H */
|
||||||
804
vendor/libssh2-1.4.2/src/openssl.c
vendored
Normal file
804
vendor/libssh2-1.4.2/src/openssl.c
vendored
Normal file
|
|
@ -0,0 +1,804 @@
|
||||||
|
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||||
|
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||||
|
*
|
||||||
|
* Author: Simon Josefsson
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifndef LIBSSH2_LIBGCRYPT /* compile only if we build with OpenSSL */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef EVP_MAX_BLOCK_LENGTH
|
||||||
|
#define EVP_MAX_BLOCK_LENGTH 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||||
|
const unsigned char *edata,
|
||||||
|
unsigned long elen,
|
||||||
|
const unsigned char *ndata,
|
||||||
|
unsigned long nlen,
|
||||||
|
const unsigned char *ddata,
|
||||||
|
unsigned long dlen,
|
||||||
|
const unsigned char *pdata,
|
||||||
|
unsigned long plen,
|
||||||
|
const unsigned char *qdata,
|
||||||
|
unsigned long qlen,
|
||||||
|
const unsigned char *e1data,
|
||||||
|
unsigned long e1len,
|
||||||
|
const unsigned char *e2data,
|
||||||
|
unsigned long e2len,
|
||||||
|
const unsigned char *coeffdata, unsigned long coefflen)
|
||||||
|
{
|
||||||
|
*rsa = RSA_new();
|
||||||
|
|
||||||
|
(*rsa)->e = BN_new();
|
||||||
|
BN_bin2bn(edata, elen, (*rsa)->e);
|
||||||
|
|
||||||
|
(*rsa)->n = BN_new();
|
||||||
|
BN_bin2bn(ndata, nlen, (*rsa)->n);
|
||||||
|
|
||||||
|
if (ddata) {
|
||||||
|
(*rsa)->d = BN_new();
|
||||||
|
BN_bin2bn(ddata, dlen, (*rsa)->d);
|
||||||
|
|
||||||
|
(*rsa)->p = BN_new();
|
||||||
|
BN_bin2bn(pdata, plen, (*rsa)->p);
|
||||||
|
|
||||||
|
(*rsa)->q = BN_new();
|
||||||
|
BN_bin2bn(qdata, qlen, (*rsa)->q);
|
||||||
|
|
||||||
|
(*rsa)->dmp1 = BN_new();
|
||||||
|
BN_bin2bn(e1data, e1len, (*rsa)->dmp1);
|
||||||
|
|
||||||
|
(*rsa)->dmq1 = BN_new();
|
||||||
|
BN_bin2bn(e2data, e2len, (*rsa)->dmq1);
|
||||||
|
|
||||||
|
(*rsa)->iqmp = BN_new();
|
||||||
|
BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
|
||||||
|
const unsigned char *sig,
|
||||||
|
unsigned long sig_len,
|
||||||
|
const unsigned char *m, unsigned long m_len)
|
||||||
|
{
|
||||||
|
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
libssh2_sha1(m, m_len, hash);
|
||||||
|
ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
|
||||||
|
(unsigned char *) sig, sig_len, rsactx);
|
||||||
|
return (ret == 1) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIBSSH2_DSA
|
||||||
|
int
|
||||||
|
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||||
|
const unsigned char *p,
|
||||||
|
unsigned long p_len,
|
||||||
|
const unsigned char *q,
|
||||||
|
unsigned long q_len,
|
||||||
|
const unsigned char *g,
|
||||||
|
unsigned long g_len,
|
||||||
|
const unsigned char *y,
|
||||||
|
unsigned long y_len,
|
||||||
|
const unsigned char *x, unsigned long x_len)
|
||||||
|
{
|
||||||
|
*dsactx = DSA_new();
|
||||||
|
|
||||||
|
(*dsactx)->p = BN_new();
|
||||||
|
BN_bin2bn(p, p_len, (*dsactx)->p);
|
||||||
|
|
||||||
|
(*dsactx)->q = BN_new();
|
||||||
|
BN_bin2bn(q, q_len, (*dsactx)->q);
|
||||||
|
|
||||||
|
(*dsactx)->g = BN_new();
|
||||||
|
BN_bin2bn(g, g_len, (*dsactx)->g);
|
||||||
|
|
||||||
|
(*dsactx)->pub_key = BN_new();
|
||||||
|
BN_bin2bn(y, y_len, (*dsactx)->pub_key);
|
||||||
|
|
||||||
|
if (x_len) {
|
||||||
|
(*dsactx)->priv_key = BN_new();
|
||||||
|
BN_bin2bn(x, x_len, (*dsactx)->priv_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||||
|
const unsigned char *sig,
|
||||||
|
const unsigned char *m, unsigned long m_len)
|
||||||
|
{
|
||||||
|
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||||
|
DSA_SIG dsasig;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dsasig.r = BN_new();
|
||||||
|
BN_bin2bn(sig, 20, dsasig.r);
|
||||||
|
dsasig.s = BN_new();
|
||||||
|
BN_bin2bn(sig + 20, 20, dsasig.s);
|
||||||
|
|
||||||
|
libssh2_sha1(m, m_len, hash);
|
||||||
|
ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx);
|
||||||
|
BN_clear_free(dsasig.s);
|
||||||
|
BN_clear_free(dsasig.r);
|
||||||
|
|
||||||
|
return (ret == 1) ? 0 : -1;
|
||||||
|
}
|
||||||
|
#endif /* LIBSSH_DSA */
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||||
|
_libssh2_cipher_type(algo),
|
||||||
|
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX_init(h);
|
||||||
|
EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||||
|
_libssh2_cipher_type(algo),
|
||||||
|
int encrypt, unsigned char *block)
|
||||||
|
{
|
||||||
|
int blocksize = ctx->cipher->block_size;
|
||||||
|
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
|
||||||
|
int ret;
|
||||||
|
(void) algo;
|
||||||
|
(void) encrypt;
|
||||||
|
|
||||||
|
if (blocksize == 1) {
|
||||||
|
/* Hack for arcfour. */
|
||||||
|
blocksize = 8;
|
||||||
|
}
|
||||||
|
ret = EVP_Cipher(ctx, buf, block, blocksize);
|
||||||
|
if (ret == 1) {
|
||||||
|
memcpy(block, buf, blocksize);
|
||||||
|
}
|
||||||
|
return ret == 1 ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIBSSH2_AES_CTR
|
||||||
|
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
AES_KEY key;
|
||||||
|
EVP_CIPHER_CTX *aes_ctx;
|
||||||
|
unsigned char ctr[AES_BLOCK_SIZE];
|
||||||
|
} aes_ctr_ctx;
|
||||||
|
|
||||||
|
static int
|
||||||
|
aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
|
const unsigned char *iv, int enc) /* init key */
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* variable "c" is leaked from this scope, but is later freed
|
||||||
|
* in aes_ctr_cleanup
|
||||||
|
*/
|
||||||
|
aes_ctr_ctx *c = malloc(sizeof(*c));
|
||||||
|
const EVP_CIPHER *aes_cipher;
|
||||||
|
(void) enc;
|
||||||
|
|
||||||
|
if (c == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (ctx->key_len) {
|
||||||
|
case 16:
|
||||||
|
aes_cipher = EVP_aes_128_ecb();
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
aes_cipher = EVP_aes_192_ecb();
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
aes_cipher = EVP_aes_256_ecb();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
|
||||||
|
if (c->aes_ctx == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0);
|
||||||
|
|
||||||
|
memcpy(c->ctr, iv, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
const unsigned char *in,
|
||||||
|
size_t inl) /* encrypt/decrypt data */
|
||||||
|
{
|
||||||
|
aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||||
|
unsigned char b1[AES_BLOCK_SIZE];
|
||||||
|
size_t i = 0;
|
||||||
|
int outlen = 0;
|
||||||
|
|
||||||
|
if (inl != 16) /* libssh2 only ever encrypt one block */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (c == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each
|
||||||
|
blocks of length L), the encryptor first encrypts <X> with <cipher>
|
||||||
|
to obtain a block B1. The block B1 is then XORed with P1 to generate
|
||||||
|
the ciphertext block C1. The counter X is then incremented
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (EVP_EncryptUpdate(c->aes_ctx, b1, &outlen, c->ctr, AES_BLOCK_SIZE) != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
*out++ = *in++ ^ b1[i];
|
||||||
|
|
||||||
|
i = 15;
|
||||||
|
while (c->ctr[i]++ == 0xFF) {
|
||||||
|
if (i == 0)
|
||||||
|
break;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */
|
||||||
|
{
|
||||||
|
aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||||
|
|
||||||
|
if (c == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->aes_ctx != NULL) {
|
||||||
|
_libssh2_cipher_dtor(c->aes_ctx);
|
||||||
|
free(c->aes_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(c);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EVP_CIPHER *
|
||||||
|
make_ctr_evp (size_t keylen, EVP_CIPHER *aes_ctr_cipher)
|
||||||
|
{
|
||||||
|
aes_ctr_cipher->block_size = 16;
|
||||||
|
aes_ctr_cipher->key_len = keylen;
|
||||||
|
aes_ctr_cipher->iv_len = 16;
|
||||||
|
aes_ctr_cipher->init = aes_ctr_init;
|
||||||
|
aes_ctr_cipher->do_cipher = aes_ctr_do_cipher;
|
||||||
|
aes_ctr_cipher->cleanup = aes_ctr_cleanup;
|
||||||
|
|
||||||
|
return aes_ctr_cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_CIPHER *
|
||||||
|
_libssh2_EVP_aes_128_ctr(void)
|
||||||
|
{
|
||||||
|
static EVP_CIPHER aes_ctr_cipher;
|
||||||
|
return !aes_ctr_cipher.key_len?
|
||||||
|
make_ctr_evp (16, &aes_ctr_cipher) : &aes_ctr_cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_CIPHER *
|
||||||
|
_libssh2_EVP_aes_192_ctr(void)
|
||||||
|
{
|
||||||
|
static EVP_CIPHER aes_ctr_cipher;
|
||||||
|
return !aes_ctr_cipher.key_len?
|
||||||
|
make_ctr_evp (24, &aes_ctr_cipher) : &aes_ctr_cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_CIPHER *
|
||||||
|
_libssh2_EVP_aes_256_ctr(void)
|
||||||
|
{
|
||||||
|
static EVP_CIPHER aes_ctr_cipher;
|
||||||
|
return !aes_ctr_cipher.key_len?
|
||||||
|
make_ctr_evp (32, &aes_ctr_cipher) : &aes_ctr_cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _libssh2_init_aes_ctr(void)
|
||||||
|
{
|
||||||
|
_libssh2_EVP_aes_128_ctr();
|
||||||
|
_libssh2_EVP_aes_192_ctr();
|
||||||
|
_libssh2_EVP_aes_256_ctr();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void _libssh2_init_aes_ctr(void) {}
|
||||||
|
#endif /* LIBSSH2_AES_CTR */
|
||||||
|
|
||||||
|
/* TODO: Optionally call a passphrase callback specified by the
|
||||||
|
* calling program
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
|
||||||
|
{
|
||||||
|
int passphrase_len = strlen(passphrase);
|
||||||
|
(void) rwflag;
|
||||||
|
|
||||||
|
if (passphrase_len > (size - 1)) {
|
||||||
|
passphrase_len = size - 1;
|
||||||
|
}
|
||||||
|
memcpy(buf, passphrase, passphrase_len);
|
||||||
|
buf[passphrase_len] = '\0';
|
||||||
|
|
||||||
|
return passphrase_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *,
|
||||||
|
void * u);
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_private_key_from_file(void ** key_ctx,
|
||||||
|
pem_read_bio_func read_private_key,
|
||||||
|
const char * filename,
|
||||||
|
unsigned const char *passphrase)
|
||||||
|
{
|
||||||
|
BIO * bp;
|
||||||
|
|
||||||
|
*key_ctx = NULL;
|
||||||
|
|
||||||
|
bp = BIO_new_file(filename, "r");
|
||||||
|
if (!bp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
|
||||||
|
(void *) passphrase);
|
||||||
|
|
||||||
|
BIO_free(bp);
|
||||||
|
return (*key_ctx) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
|
LIBSSH2_SESSION * session,
|
||||||
|
const char *filename, unsigned const char *passphrase)
|
||||||
|
{
|
||||||
|
pem_read_bio_func read_rsa =
|
||||||
|
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_init_if_needed ();
|
||||||
|
|
||||||
|
return read_private_key_from_file((void **) rsa, read_rsa,
|
||||||
|
filename, passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIBSSH2_DSA
|
||||||
|
int
|
||||||
|
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
|
LIBSSH2_SESSION * session,
|
||||||
|
const char *filename, unsigned const char *passphrase)
|
||||||
|
{
|
||||||
|
pem_read_bio_func read_dsa =
|
||||||
|
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
||||||
|
(void) session;
|
||||||
|
|
||||||
|
_libssh2_init_if_needed ();
|
||||||
|
|
||||||
|
return read_private_key_from_file((void **) dsa, read_dsa,
|
||||||
|
filename, passphrase);
|
||||||
|
}
|
||||||
|
#endif /* LIBSSH_DSA */
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||||
|
libssh2_rsa_ctx * rsactx,
|
||||||
|
const unsigned char *hash,
|
||||||
|
size_t hash_len,
|
||||||
|
unsigned char **signature, size_t *signature_len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char *sig;
|
||||||
|
unsigned int sig_len;
|
||||||
|
|
||||||
|
sig_len = RSA_size(rsactx);
|
||||||
|
sig = LIBSSH2_ALLOC(session, sig_len);
|
||||||
|
|
||||||
|
if (!sig) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
LIBSSH2_FREE(session, sig);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*signature = sig;
|
||||||
|
*signature_len = sig_len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIBSSH2_DSA
|
||||||
|
int
|
||||||
|
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned long hash_len, unsigned char *signature)
|
||||||
|
{
|
||||||
|
DSA_SIG *sig;
|
||||||
|
int r_len, s_len;
|
||||||
|
(void) hash_len;
|
||||||
|
|
||||||
|
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
|
||||||
|
if (!sig) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_len = BN_num_bytes(sig->r);
|
||||||
|
if (r_len < 1 || r_len > 20) {
|
||||||
|
DSA_SIG_free(sig);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s_len = BN_num_bytes(sig->s);
|
||||||
|
if (s_len < 1 || s_len > 20) {
|
||||||
|
DSA_SIG_free(sig);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(signature, 0, 40);
|
||||||
|
|
||||||
|
BN_bn2bin(sig->r, signature + (20 - r_len));
|
||||||
|
BN_bn2bin(sig->s, signature + 20 + (20 - s_len));
|
||||||
|
|
||||||
|
DSA_SIG_free(sig);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* LIBSSH_DSA */
|
||||||
|
|
||||||
|
void
|
||||||
|
libssh2_sha1(const unsigned char *message, unsigned long len,
|
||||||
|
unsigned char *out)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX ctx;
|
||||||
|
|
||||||
|
EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"));
|
||||||
|
EVP_DigestUpdate(&ctx, message, len);
|
||||||
|
EVP_DigestFinal(&ctx, out, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
libssh2_md5(const unsigned char *message, unsigned long len,
|
||||||
|
unsigned char *out)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX ctx;
|
||||||
|
|
||||||
|
EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"));
|
||||||
|
EVP_DigestUpdate(&ctx, message, len);
|
||||||
|
EVP_DigestFinal(&ctx, out, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char *
|
||||||
|
write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes)
|
||||||
|
{
|
||||||
|
unsigned char *p = buf;
|
||||||
|
|
||||||
|
/* Left space for bn size which will be written below. */
|
||||||
|
p += 4;
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
BN_bn2bin(bn, p + 1);
|
||||||
|
if (!(*(p + 1) & 0x80)) {
|
||||||
|
memmove(p, p + 1, --bn_bytes);
|
||||||
|
}
|
||||||
|
_libssh2_htonu32(p - 4, bn_bytes); /* Post write bn size. */
|
||||||
|
|
||||||
|
return p + bn_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char *
|
||||||
|
gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa,
|
||||||
|
size_t *key_len)
|
||||||
|
{
|
||||||
|
int e_bytes, n_bytes;
|
||||||
|
unsigned long len;
|
||||||
|
unsigned char* key;
|
||||||
|
unsigned char* p;
|
||||||
|
|
||||||
|
e_bytes = BN_num_bytes(rsa->e) + 1;
|
||||||
|
n_bytes = BN_num_bytes(rsa->n) + 1;
|
||||||
|
|
||||||
|
/* Key form is "ssh-rsa" + e + n. */
|
||||||
|
len = 4 + 7 + 4 + e_bytes + 4 + n_bytes;
|
||||||
|
|
||||||
|
key = LIBSSH2_ALLOC(session, len);
|
||||||
|
if (key == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process key encoding. */
|
||||||
|
p = key;
|
||||||
|
|
||||||
|
_libssh2_htonu32(p, 7); /* Key type. */
|
||||||
|
p += 4;
|
||||||
|
memcpy(p, "ssh-rsa", 7);
|
||||||
|
p += 7;
|
||||||
|
|
||||||
|
p = write_bn(p, rsa->e, e_bytes);
|
||||||
|
p = write_bn(p, rsa->n, n_bytes);
|
||||||
|
|
||||||
|
*key_len = (size_t)(p - key);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char *
|
||||||
|
gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
|
||||||
|
size_t *key_len)
|
||||||
|
{
|
||||||
|
int p_bytes, q_bytes, g_bytes, k_bytes;
|
||||||
|
unsigned long len;
|
||||||
|
unsigned char* key;
|
||||||
|
unsigned char* p;
|
||||||
|
|
||||||
|
p_bytes = BN_num_bytes(dsa->p) + 1;
|
||||||
|
q_bytes = BN_num_bytes(dsa->q) + 1;
|
||||||
|
g_bytes = BN_num_bytes(dsa->g) + 1;
|
||||||
|
k_bytes = BN_num_bytes(dsa->pub_key) + 1;
|
||||||
|
|
||||||
|
/* Key form is "ssh-dss" + p + q + g + pub_key. */
|
||||||
|
len = 4 + 7 + 4 + p_bytes + 4 + q_bytes + 4 + g_bytes + 4 + k_bytes;
|
||||||
|
|
||||||
|
key = LIBSSH2_ALLOC(session, len);
|
||||||
|
if (key == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process key encoding. */
|
||||||
|
p = key;
|
||||||
|
|
||||||
|
_libssh2_htonu32(p, 7); /* Key type. */
|
||||||
|
p += 4;
|
||||||
|
memcpy(p, "ssh-dss", 7);
|
||||||
|
p += 7;
|
||||||
|
|
||||||
|
p = write_bn(p, dsa->p, p_bytes);
|
||||||
|
p = write_bn(p, dsa->q, q_bytes);
|
||||||
|
p = write_bn(p, dsa->g, g_bytes);
|
||||||
|
p = write_bn(p, dsa->pub_key, k_bytes);
|
||||||
|
|
||||||
|
*key_len = (size_t)(p - key);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char **method,
|
||||||
|
size_t *method_len,
|
||||||
|
unsigned char **pubkeydata,
|
||||||
|
size_t *pubkeydata_len,
|
||||||
|
EVP_PKEY *pk)
|
||||||
|
{
|
||||||
|
RSA* rsa = NULL;
|
||||||
|
unsigned char* key;
|
||||||
|
unsigned char* method_buf = NULL;
|
||||||
|
size_t key_len;
|
||||||
|
|
||||||
|
_libssh2_debug(session,
|
||||||
|
LIBSSH2_TRACE_AUTH,
|
||||||
|
"Computing public key from RSA private key envelop");
|
||||||
|
|
||||||
|
rsa = EVP_PKEY_get1_RSA(pk);
|
||||||
|
if (rsa == NULL) {
|
||||||
|
/* Assume memory allocation error... what else could it be ? */
|
||||||
|
goto __alloc_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-rsa. */
|
||||||
|
if (method_buf == NULL) {
|
||||||
|
goto __alloc_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = gen_publickey_from_rsa(session, rsa, &key_len);
|
||||||
|
if (key == NULL) {
|
||||||
|
goto __alloc_error;
|
||||||
|
}
|
||||||
|
RSA_free(rsa);
|
||||||
|
|
||||||
|
memcpy(method_buf, "ssh-rsa", 7);
|
||||||
|
*method = method_buf;
|
||||||
|
*method_len = 7;
|
||||||
|
*pubkeydata = key;
|
||||||
|
*pubkeydata_len = key_len;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
__alloc_error:
|
||||||
|
if (rsa != NULL) {
|
||||||
|
RSA_free(rsa);
|
||||||
|
}
|
||||||
|
if (method_buf != NULL) {
|
||||||
|
LIBSSH2_FREE(session, method_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _libssh2_error(session,
|
||||||
|
LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for private key data");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char **method,
|
||||||
|
size_t *method_len,
|
||||||
|
unsigned char **pubkeydata,
|
||||||
|
size_t *pubkeydata_len,
|
||||||
|
EVP_PKEY *pk)
|
||||||
|
{
|
||||||
|
DSA* dsa = NULL;
|
||||||
|
unsigned char* key;
|
||||||
|
unsigned char* method_buf = NULL;
|
||||||
|
size_t key_len;
|
||||||
|
|
||||||
|
_libssh2_debug(session,
|
||||||
|
LIBSSH2_TRACE_AUTH,
|
||||||
|
"Computing public key from DSA private key envelop");
|
||||||
|
|
||||||
|
dsa = EVP_PKEY_get1_DSA(pk);
|
||||||
|
if (dsa == NULL) {
|
||||||
|
/* Assume memory allocation error... what else could it be ? */
|
||||||
|
goto __alloc_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-dss. */
|
||||||
|
if (method_buf == NULL) {
|
||||||
|
goto __alloc_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = gen_publickey_from_dsa(session, dsa, &key_len);
|
||||||
|
if (key == NULL) {
|
||||||
|
goto __alloc_error;
|
||||||
|
}
|
||||||
|
DSA_free(dsa);
|
||||||
|
|
||||||
|
memcpy(method_buf, "ssh-dss", 7);
|
||||||
|
*method = method_buf;
|
||||||
|
*method_len = 7;
|
||||||
|
*pubkeydata = key;
|
||||||
|
*pubkeydata_len = key_len;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
__alloc_error:
|
||||||
|
if (dsa != NULL) {
|
||||||
|
DSA_free(dsa);
|
||||||
|
}
|
||||||
|
if (method_buf != NULL) {
|
||||||
|
LIBSSH2_FREE(session, method_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _libssh2_error(session,
|
||||||
|
LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for private key data");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char **method,
|
||||||
|
size_t *method_len,
|
||||||
|
unsigned char **pubkeydata,
|
||||||
|
size_t *pubkeydata_len,
|
||||||
|
const char *privatekey,
|
||||||
|
const char *passphrase)
|
||||||
|
{
|
||||||
|
int st;
|
||||||
|
BIO* bp;
|
||||||
|
EVP_PKEY* pk;
|
||||||
|
|
||||||
|
_libssh2_debug(session,
|
||||||
|
LIBSSH2_TRACE_AUTH,
|
||||||
|
"Computing public key from private key file: %s",
|
||||||
|
privatekey);
|
||||||
|
|
||||||
|
bp = BIO_new_file(privatekey, "r");
|
||||||
|
if (bp == NULL) {
|
||||||
|
return _libssh2_error(session,
|
||||||
|
LIBSSH2_ERROR_FILE,
|
||||||
|
"Unable to extract public key from private key "
|
||||||
|
"file: Unable to open private key file");
|
||||||
|
}
|
||||||
|
if (!EVP_get_cipherbyname("des")) {
|
||||||
|
/* If this cipher isn't loaded it's a pretty good indication that none
|
||||||
|
* are. I have *NO DOUBT* that there's a better way to deal with this
|
||||||
|
* ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
OpenSSL_add_all_ciphers();
|
||||||
|
}
|
||||||
|
BIO_reset(bp);
|
||||||
|
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase);
|
||||||
|
BIO_free(bp);
|
||||||
|
|
||||||
|
if (pk == NULL) {
|
||||||
|
return _libssh2_error(session,
|
||||||
|
LIBSSH2_ERROR_FILE,
|
||||||
|
"Unable to extract public key "
|
||||||
|
"from private key file: "
|
||||||
|
"Wrong passphrase or invalid/unrecognized "
|
||||||
|
"private key file format");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pk->type) {
|
||||||
|
case EVP_PKEY_RSA :
|
||||||
|
st = gen_publickey_from_rsa_evp(
|
||||||
|
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVP_PKEY_DSA :
|
||||||
|
st = gen_publickey_from_dsa_evp(
|
||||||
|
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
st = _libssh2_error(session,
|
||||||
|
LIBSSH2_ERROR_FILE,
|
||||||
|
"Unable to extract public key "
|
||||||
|
"from private key file: "
|
||||||
|
"Unsupported private key file format");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_free(pk);
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !LIBSSH2_LIBGCRYPT */
|
||||||
178
vendor/libssh2-1.4.2/src/openssl.h
vendored
Normal file
178
vendor/libssh2-1.4.2/src/openssl.h
vendored
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||||
|
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Author: Simon Josefsson
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <openssl/opensslconf.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#ifndef OPENSSL_NO_MD5
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#endif
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_RSA
|
||||||
|
# define LIBSSH2_RSA 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_RSA 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_DSA
|
||||||
|
# define LIBSSH2_DSA 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_DSA 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_MD5
|
||||||
|
# define LIBSSH2_MD5 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_MD5 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_RIPEMD
|
||||||
|
# define LIBSSH2_HMAC_RIPEMD 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_HMAC_RIPEMD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
|
||||||
|
# define LIBSSH2_AES_CTR 1
|
||||||
|
# define LIBSSH2_AES 1
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_AES_CTR 0
|
||||||
|
# define LIBSSH2_AES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_BLOWFISH
|
||||||
|
# define LIBSSH2_BLOWFISH 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_BLOWFISH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_RC4
|
||||||
|
# define LIBSSH2_RC4 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_RC4 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_CAST
|
||||||
|
# define LIBSSH2_CAST 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_CAST 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_DES
|
||||||
|
# define LIBSSH2_3DES 0
|
||||||
|
#else
|
||||||
|
# define LIBSSH2_3DES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
|
||||||
|
|
||||||
|
#define libssh2_sha1_ctx EVP_MD_CTX
|
||||||
|
#define libssh2_sha1_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))
|
||||||
|
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||||
|
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||||
|
void libssh2_sha1(const unsigned char *message, unsigned long len, unsigned char *out);
|
||||||
|
|
||||||
|
#define libssh2_md5_ctx EVP_MD_CTX
|
||||||
|
#define libssh2_md5_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("md5"))
|
||||||
|
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||||
|
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||||
|
void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char *out);
|
||||||
|
|
||||||
|
#define libssh2_hmac_ctx HMAC_CTX
|
||||||
|
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||||
|
HMAC_Init(ctx, key, keylen, EVP_sha1())
|
||||||
|
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||||
|
HMAC_Init(ctx, key, keylen, EVP_md5())
|
||||||
|
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
|
||||||
|
HMAC_Init(ctx, key, keylen, EVP_ripemd160())
|
||||||
|
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||||
|
HMAC_Update(&(ctx), data, datalen)
|
||||||
|
#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
|
||||||
|
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
|
||||||
|
|
||||||
|
#define libssh2_crypto_init() OpenSSL_add_all_algorithms()
|
||||||
|
#define libssh2_crypto_exit()
|
||||||
|
|
||||||
|
#define libssh2_rsa_ctx RSA
|
||||||
|
|
||||||
|
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
|
||||||
|
|
||||||
|
#define libssh2_dsa_ctx DSA
|
||||||
|
|
||||||
|
|
||||||
|
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
|
||||||
|
|
||||||
|
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
|
||||||
|
#define _libssh2_cipher_ctx EVP_CIPHER_CTX
|
||||||
|
|
||||||
|
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
|
||||||
|
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
||||||
|
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
|
||||||
|
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
|
||||||
|
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
|
||||||
|
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
|
||||||
|
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
||||||
|
#define _libssh2_cipher_arcfour EVP_rc4
|
||||||
|
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
||||||
|
#define _libssh2_cipher_3des EVP_des_ede3_cbc
|
||||||
|
|
||||||
|
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
|
||||||
|
|
||||||
|
#define _libssh2_bn BIGNUM
|
||||||
|
#define _libssh2_bn_ctx BN_CTX
|
||||||
|
#define _libssh2_bn_ctx_new() BN_CTX_new()
|
||||||
|
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
|
||||||
|
#define _libssh2_bn_init() BN_new()
|
||||||
|
#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom)
|
||||||
|
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx)
|
||||||
|
#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
|
||||||
|
#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn)
|
||||||
|
#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val)
|
||||||
|
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
|
||||||
|
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
|
||||||
|
#define _libssh2_bn_free(bn) BN_clear_free(bn)
|
||||||
|
|
||||||
|
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
|
||||||
|
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
|
||||||
|
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);
|
||||||
|
|
||||||
1243
vendor/libssh2-1.4.2/src/packet.c
vendored
Normal file
1243
vendor/libssh2-1.4.2/src/packet.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
76
vendor/libssh2-1.4.2/src/packet.h
vendored
Normal file
76
vendor/libssh2-1.4.2/src/packet.h
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef LIBSSH2_PACKET_H
|
||||||
|
#define LIBSSH2_PACKET_H
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 by Daniel Stenberg
|
||||||
|
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _libssh2_packet_read(LIBSSH2_SESSION * session);
|
||||||
|
|
||||||
|
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||||
|
unsigned char **data, size_t *data_len,
|
||||||
|
int match_ofs,
|
||||||
|
const unsigned char *match_buf,
|
||||||
|
size_t match_len);
|
||||||
|
|
||||||
|
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
|
||||||
|
const unsigned char *packet_types,
|
||||||
|
unsigned char **data, size_t *data_len,
|
||||||
|
int match_ofs,
|
||||||
|
const unsigned char *match_buf,
|
||||||
|
size_t match_len);
|
||||||
|
int _libssh2_packet_require(LIBSSH2_SESSION * session,
|
||||||
|
unsigned char packet_type, unsigned char **data,
|
||||||
|
size_t *data_len, int match_ofs,
|
||||||
|
const unsigned char *match_buf,
|
||||||
|
size_t match_len,
|
||||||
|
packet_require_state_t * state);
|
||||||
|
int _libssh2_packet_requirev(LIBSSH2_SESSION *session,
|
||||||
|
const unsigned char *packet_types,
|
||||||
|
unsigned char **data, size_t *data_len,
|
||||||
|
int match_ofs,
|
||||||
|
const unsigned char *match_buf,
|
||||||
|
size_t match_len,
|
||||||
|
packet_requirev_state_t * state);
|
||||||
|
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||||
|
libssh2_nonblocking_states * state);
|
||||||
|
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
|
unsigned long data_len);
|
||||||
|
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
|
size_t datalen, int macstate);
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_PACKET_H */
|
||||||
213
vendor/libssh2-1.4.2/src/pem.c
vendored
Normal file
213
vendor/libssh2-1.4.2/src/pem.c
vendored
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
/* Copyright (C) 2007 The Written Word, Inc.
|
||||||
|
* Copyright (C) 2008, Simon Josefsson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
|
||||||
|
|
||||||
|
static int
|
||||||
|
readline(char *line, int line_size, FILE * fp)
|
||||||
|
{
|
||||||
|
if (!fgets(line, line_size, fp)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*line && line[strlen(line) - 1] == '\n') {
|
||||||
|
line[strlen(line) - 1] = '\0';
|
||||||
|
}
|
||||||
|
if (*line && line[strlen(line) - 1] == '\r') {
|
||||||
|
line[strlen(line) - 1] = '\0';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LINE_SIZE 128
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||||
|
const char *headerbegin,
|
||||||
|
const char *headerend,
|
||||||
|
FILE * fp, unsigned char **data, unsigned int *datalen)
|
||||||
|
{
|
||||||
|
char line[LINE_SIZE];
|
||||||
|
char *b64data = NULL;
|
||||||
|
unsigned int b64datalen = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (readline(line, LINE_SIZE, fp)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (strcmp(line, headerbegin) != 0);
|
||||||
|
|
||||||
|
*line = '\0';
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (*line) {
|
||||||
|
char *tmp;
|
||||||
|
size_t linelen;
|
||||||
|
|
||||||
|
linelen = strlen(line);
|
||||||
|
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||||
|
if (!tmp) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memcpy(tmp + b64datalen, line, linelen);
|
||||||
|
b64data = tmp;
|
||||||
|
b64datalen += linelen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readline(line, LINE_SIZE, fp)) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} while (strcmp(line, headerend) != 0);
|
||||||
|
|
||||||
|
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||||
|
b64data, b64datalen)) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
if (b64data) {
|
||||||
|
LIBSSH2_FREE(session, b64data);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_asn1_length(const unsigned char *data,
|
||||||
|
unsigned int datalen, unsigned int *len)
|
||||||
|
{
|
||||||
|
unsigned int lenlen;
|
||||||
|
int nextpos;
|
||||||
|
|
||||||
|
if (datalen < 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*len = data[0];
|
||||||
|
|
||||||
|
if (*len >= 0x80) {
|
||||||
|
lenlen = *len & 0x7F;
|
||||||
|
*len = data[1];
|
||||||
|
if (1 + lenlen > datalen) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (lenlen > 1) {
|
||||||
|
*len <<= 8;
|
||||||
|
*len |= data[2];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lenlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextpos = 1 + lenlen;
|
||||||
|
if (lenlen > 2 || 1 + lenlen + *len > datalen) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
int lenlen;
|
||||||
|
|
||||||
|
if (*datalen < 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*data)[0] != '\x30') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*data)++;
|
||||||
|
(*datalen)--;
|
||||||
|
|
||||||
|
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||||
|
if (lenlen < 0 || lenlen + len != *datalen) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data += lenlen;
|
||||||
|
*datalen -= lenlen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||||
|
unsigned char **i, unsigned int *ilen)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
int lenlen;
|
||||||
|
|
||||||
|
if (*datalen < 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*data)[0] != '\x02') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*data)++;
|
||||||
|
(*datalen)--;
|
||||||
|
|
||||||
|
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||||
|
if (lenlen < 0 || lenlen + len > *datalen) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data += lenlen;
|
||||||
|
*datalen -= lenlen;
|
||||||
|
|
||||||
|
*i = *data;
|
||||||
|
*ilen = len;
|
||||||
|
|
||||||
|
*data += len;
|
||||||
|
*datalen -= len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_LIBGCRYPT */
|
||||||
1058
vendor/libssh2-1.4.2/src/publickey.c
vendored
Normal file
1058
vendor/libssh2-1.4.2/src/publickey.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
1085
vendor/libssh2-1.4.2/src/scp.c
vendored
Normal file
1085
vendor/libssh2-1.4.2/src/scp.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
1751
vendor/libssh2-1.4.2/src/session.c
vendored
Normal file
1751
vendor/libssh2-1.4.2/src/session.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
93
vendor/libssh2-1.4.2/src/session.h
vendored
Normal file
93
vendor/libssh2-1.4.2/src/session.h
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#ifndef LIBSSH2_SESSION_H
|
||||||
|
#define LIBSSH2_SESSION_H
|
||||||
|
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||||
|
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||||
|
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Conveniance-macros to allow code like this;
|
||||||
|
|
||||||
|
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
|
||||||
|
|
||||||
|
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
|
||||||
|
|
||||||
|
The point of course being to make sure that while in non-blocking mode
|
||||||
|
these always return no matter what the return code is, but in blocking mode
|
||||||
|
it blocks if EAGAIN is the reason for the return from the underlying
|
||||||
|
function.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#define BLOCK_ADJUST(rc,sess,x) \
|
||||||
|
do { \
|
||||||
|
time_t entry_time = time (NULL); \
|
||||||
|
do { \
|
||||||
|
rc = x; \
|
||||||
|
/* the order of the check below is important to properly deal with \
|
||||||
|
the case when the 'sess' is freed */ \
|
||||||
|
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
|
||||||
|
break; \
|
||||||
|
rc = _libssh2_wait_socket(sess, entry_time); \
|
||||||
|
} while(!rc); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For functions that returns a pointer, we need to check if the API is
|
||||||
|
* non-blocking and return immediately. If the pointer is non-NULL we return
|
||||||
|
* immediately. If the API is blocking and we get a NULL we check the errno
|
||||||
|
* and *only* if that is EAGAIN we loop and wait for socket action.
|
||||||
|
*/
|
||||||
|
#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \
|
||||||
|
do { \
|
||||||
|
time_t entry_time = time (NULL); \
|
||||||
|
int rc; \
|
||||||
|
do { \
|
||||||
|
ptr = x; \
|
||||||
|
if(!sess->api_block_mode || \
|
||||||
|
(ptr != NULL) || \
|
||||||
|
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
|
||||||
|
break; \
|
||||||
|
rc = _libssh2_wait_socket(sess, entry_time); \
|
||||||
|
} while(!rc); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time);
|
||||||
|
|
||||||
|
/* this is the lib-internal set blocking function */
|
||||||
|
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_SESSION_H */
|
||||||
3278
vendor/libssh2-1.4.2/src/sftp.c
vendored
Normal file
3278
vendor/libssh2-1.4.2/src/sftp.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
230
vendor/libssh2-1.4.2/src/sftp.h
vendored
Normal file
230
vendor/libssh2-1.4.2/src/sftp.h
vendored
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
#ifndef _LIBSSH2_SFTP_H
|
||||||
|
#define _LIBSSH2_SFTP_H
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 - 2012 by Daniel Stenberg
|
||||||
|
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the
|
||||||
|
* amount of data sent in each FXP_WRITE packet
|
||||||
|
*/
|
||||||
|
#define MAX_SFTP_OUTGOING_SIZE 30000
|
||||||
|
|
||||||
|
/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ
|
||||||
|
* packets.
|
||||||
|
*/
|
||||||
|
#define MAX_SFTP_READ_SIZE 2000
|
||||||
|
|
||||||
|
struct sftp_pipeline_chunk {
|
||||||
|
struct list_node node;
|
||||||
|
size_t len; /* WRITE: size of the data to write
|
||||||
|
READ: how many bytes that was asked for */
|
||||||
|
size_t sent;
|
||||||
|
ssize_t lefttosend; /* if 0, the entire packet has been sent off */
|
||||||
|
uint32_t request_id;
|
||||||
|
unsigned char packet[1]; /* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sftp_zombie_requests {
|
||||||
|
struct list_node node;
|
||||||
|
uint32_t request_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP_PACKET
|
||||||
|
{
|
||||||
|
struct list_node node; /* linked list header */
|
||||||
|
uint32_t request_id;
|
||||||
|
unsigned char *data;
|
||||||
|
size_t data_len; /* payload size */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET;
|
||||||
|
|
||||||
|
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP_HANDLE
|
||||||
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
|
LIBSSH2_SFTP *sftp;
|
||||||
|
|
||||||
|
char handle[SFTP_HANDLE_MAXLEN];
|
||||||
|
size_t handle_len;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LIBSSH2_SFTP_HANDLE_FILE,
|
||||||
|
LIBSSH2_SFTP_HANDLE_DIR
|
||||||
|
} handle_type;
|
||||||
|
|
||||||
|
union _libssh2_sftp_handle_data
|
||||||
|
{
|
||||||
|
struct _libssh2_sftp_handle_file_data
|
||||||
|
{
|
||||||
|
libssh2_uint64_t offset;
|
||||||
|
libssh2_uint64_t offset_sent;
|
||||||
|
size_t acked; /* container for acked data that hasn't been
|
||||||
|
returned to caller yet, used for sftp_write */
|
||||||
|
|
||||||
|
/* 'data' is used by sftp_read() and is allocated data that has
|
||||||
|
been received already from the server but wasn't returned to
|
||||||
|
the caller yet. It is of size 'data_len' and 'data_left is the
|
||||||
|
number of bytes not yet returned, counted from the end of the
|
||||||
|
buffer. */
|
||||||
|
unsigned char *data;
|
||||||
|
size_t data_len;
|
||||||
|
size_t data_left;
|
||||||
|
|
||||||
|
char eof; /* we have read to the end */
|
||||||
|
} file;
|
||||||
|
struct _libssh2_sftp_handle_dir_data
|
||||||
|
{
|
||||||
|
uint32_t names_left;
|
||||||
|
void *names_packet;
|
||||||
|
char *next_name;
|
||||||
|
} dir;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_close_handle() */
|
||||||
|
libssh2_nonblocking_states close_state;
|
||||||
|
uint32_t close_request_id;
|
||||||
|
unsigned char *close_packet;
|
||||||
|
|
||||||
|
/* list of outstanding packets sent to server */
|
||||||
|
struct list_head packet_list;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP
|
||||||
|
{
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
|
||||||
|
uint32_t request_id, version;
|
||||||
|
|
||||||
|
struct list_head packets;
|
||||||
|
|
||||||
|
/* List of FXP_READ responses to ignore because EOF already received. */
|
||||||
|
struct list_head zombie_requests;
|
||||||
|
|
||||||
|
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||||
|
struct list_head sftp_handles;
|
||||||
|
|
||||||
|
uint32_t last_errno;
|
||||||
|
|
||||||
|
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
|
||||||
|
unsigned char partial_size[4]; /* buffer for size field */
|
||||||
|
size_t partial_size_len; /* size field length */
|
||||||
|
unsigned char *partial_packet; /* The data */
|
||||||
|
uint32_t partial_len; /* Desired number of bytes */
|
||||||
|
size_t partial_received; /* Bytes received so far */
|
||||||
|
|
||||||
|
/* Time that libssh2_sftp_packet_requirev() started reading */
|
||||||
|
time_t requirev_start;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_open_ex() */
|
||||||
|
libssh2_nonblocking_states open_state;
|
||||||
|
unsigned char *open_packet;
|
||||||
|
uint32_t open_packet_len; /* 32 bit on the wire */
|
||||||
|
size_t open_packet_sent;
|
||||||
|
uint32_t open_request_id;
|
||||||
|
|
||||||
|
/* State variable used in sftp_read() */
|
||||||
|
libssh2_nonblocking_states read_state;
|
||||||
|
|
||||||
|
/* State variable used in sftp_packet_read() */
|
||||||
|
libssh2_nonblocking_states packet_state;
|
||||||
|
|
||||||
|
/* State variable used in sftp_write() */
|
||||||
|
libssh2_nonblocking_states write_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_readdir() */
|
||||||
|
libssh2_nonblocking_states readdir_state;
|
||||||
|
unsigned char *readdir_packet;
|
||||||
|
uint32_t readdir_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_fstat_ex() */
|
||||||
|
libssh2_nonblocking_states fstat_state;
|
||||||
|
unsigned char *fstat_packet;
|
||||||
|
uint32_t fstat_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_unlink_ex() */
|
||||||
|
libssh2_nonblocking_states unlink_state;
|
||||||
|
unsigned char *unlink_packet;
|
||||||
|
uint32_t unlink_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_rename_ex() */
|
||||||
|
libssh2_nonblocking_states rename_state;
|
||||||
|
unsigned char *rename_packet;
|
||||||
|
unsigned char *rename_s;
|
||||||
|
uint32_t rename_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_fstatvfs() */
|
||||||
|
libssh2_nonblocking_states fstatvfs_state;
|
||||||
|
unsigned char *fstatvfs_packet;
|
||||||
|
uint32_t fstatvfs_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_statvfs() */
|
||||||
|
libssh2_nonblocking_states statvfs_state;
|
||||||
|
unsigned char *statvfs_packet;
|
||||||
|
uint32_t statvfs_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_mkdir() */
|
||||||
|
libssh2_nonblocking_states mkdir_state;
|
||||||
|
unsigned char *mkdir_packet;
|
||||||
|
uint32_t mkdir_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_rmdir() */
|
||||||
|
libssh2_nonblocking_states rmdir_state;
|
||||||
|
unsigned char *rmdir_packet;
|
||||||
|
uint32_t rmdir_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_stat() */
|
||||||
|
libssh2_nonblocking_states stat_state;
|
||||||
|
unsigned char *stat_packet;
|
||||||
|
uint32_t stat_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_symlink() */
|
||||||
|
libssh2_nonblocking_states symlink_state;
|
||||||
|
unsigned char *symlink_packet;
|
||||||
|
uint32_t symlink_request_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
873
vendor/libssh2-1.4.2/src/transport.c
vendored
Normal file
873
vendor/libssh2-1.4.2/src/transport.c
vendored
Normal file
|
|
@ -0,0 +1,873 @@
|
||||||
|
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||||
|
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file handles reading and writing to the SECSH transport layer. RFC4253.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef LIBSSH2DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
#include "mac.h"
|
||||||
|
|
||||||
|
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
|
||||||
|
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
|
||||||
|
|
||||||
|
#ifdef LIBSSH2DEBUG
|
||||||
|
#define UNPRINTABLE_CHAR '.'
|
||||||
|
static void
|
||||||
|
debugdump(LIBSSH2_SESSION * session,
|
||||||
|
const char *desc, const unsigned char *ptr, size_t size)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t c;
|
||||||
|
unsigned int width = 0x10;
|
||||||
|
char buffer[256]; /* Must be enough for width*4 + about 30 or so */
|
||||||
|
size_t used;
|
||||||
|
static const char* hex_chars = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
if (!(session->showmask & LIBSSH2_TRACE_TRANS)) {
|
||||||
|
/* not asked for, bail out */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
|
||||||
|
desc, (int) size);
|
||||||
|
if (session->tracehandler)
|
||||||
|
(session->tracehandler)(session, session->tracehandler_context,
|
||||||
|
buffer, used);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s", buffer);
|
||||||
|
|
||||||
|
for(i = 0; i < size; i += width) {
|
||||||
|
|
||||||
|
used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i);
|
||||||
|
|
||||||
|
/* hex not disabled, show it */
|
||||||
|
for(c = 0; c < width; c++) {
|
||||||
|
if (i + c < size) {
|
||||||
|
buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF];
|
||||||
|
buffer[used++] = hex_chars[ptr[i+c] & 0xF];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffer[used++] = ' ';
|
||||||
|
buffer[used++] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[used++] = ' ';
|
||||||
|
if ((width/2) - 1 == c)
|
||||||
|
buffer[used++] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[used++] = ':';
|
||||||
|
buffer[used++] = ' ';
|
||||||
|
|
||||||
|
for(c = 0; (c < width) && (i + c < size); c++) {
|
||||||
|
buffer[used++] = isprint(ptr[i + c]) ?
|
||||||
|
ptr[i + c] : UNPRINTABLE_CHAR;
|
||||||
|
}
|
||||||
|
buffer[used++] = '\n';
|
||||||
|
buffer[used] = 0;
|
||||||
|
|
||||||
|
if (session->tracehandler)
|
||||||
|
(session->tracehandler)(session, session->tracehandler_context,
|
||||||
|
buffer, used);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define debugdump(a,x,y,z)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
|
||||||
|
*
|
||||||
|
* returns 0 on success and negative on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||||
|
unsigned char *dest, int len)
|
||||||
|
{
|
||||||
|
struct transportpacket *p = &session->packet;
|
||||||
|
int blocksize = session->remote.crypt->blocksize;
|
||||||
|
|
||||||
|
/* if we get called with a len that isn't an even number of blocksizes
|
||||||
|
we risk losing those extra bytes */
|
||||||
|
assert((len % blocksize) == 0);
|
||||||
|
|
||||||
|
while (len >= blocksize) {
|
||||||
|
if (session->remote.crypt->crypt(session, source,
|
||||||
|
&session->remote.crypt_abstract)) {
|
||||||
|
LIBSSH2_FREE(session, p->payload);
|
||||||
|
return LIBSSH2_ERROR_DECRYPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the crypt() function would write to a given address it
|
||||||
|
wouldn't have to memcpy() and we could avoid this memcpy()
|
||||||
|
too */
|
||||||
|
memcpy(dest, source, blocksize);
|
||||||
|
|
||||||
|
len -= blocksize; /* less bytes left */
|
||||||
|
dest += blocksize; /* advance write pointer */
|
||||||
|
source += blocksize; /* advance read pointer */
|
||||||
|
}
|
||||||
|
return LIBSSH2_ERROR_NONE; /* all is fine */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fullpacket() gets called when a full packet has been received and properly
|
||||||
|
* collected.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||||
|
{
|
||||||
|
unsigned char macbuf[MAX_MACSIZE];
|
||||||
|
struct transportpacket *p = &session->packet;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (session->fullpacket_state == libssh2_NB_state_idle) {
|
||||||
|
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
|
||||||
|
session->fullpacket_payload_len = p->packet_length - 1;
|
||||||
|
|
||||||
|
if (encrypted) {
|
||||||
|
|
||||||
|
/* Calculate MAC hash */
|
||||||
|
session->remote.mac->hash(session, macbuf, /* store hash here */
|
||||||
|
session->remote.seqno,
|
||||||
|
p->init, 5,
|
||||||
|
p->payload,
|
||||||
|
session->fullpacket_payload_len,
|
||||||
|
&session->remote.mac_abstract);
|
||||||
|
|
||||||
|
/* Compare the calculated hash with the MAC we just read from
|
||||||
|
* the network. The read one is at the very end of the payload
|
||||||
|
* buffer. Note that 'payload_len' here is the packet_length
|
||||||
|
* field which includes the padding but not the MAC.
|
||||||
|
*/
|
||||||
|
if (memcmp(macbuf, p->payload + session->fullpacket_payload_len,
|
||||||
|
session->remote.mac->mac_len)) {
|
||||||
|
session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session->remote.seqno++;
|
||||||
|
|
||||||
|
/* ignore the padding */
|
||||||
|
session->fullpacket_payload_len -= p->padding_length;
|
||||||
|
|
||||||
|
/* Check for and deal with decompression */
|
||||||
|
if (session->remote.comp &&
|
||||||
|
session->remote.comp->compress &&
|
||||||
|
session->remote.comp_abstract) {
|
||||||
|
/*
|
||||||
|
* The buffer for the decompression (remote.comp_abstract) is
|
||||||
|
* initialised in time when it is needed so as long it is NULL we
|
||||||
|
* cannot decompress.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned char *data;
|
||||||
|
size_t data_len;
|
||||||
|
rc = session->remote.comp->decomp(session,
|
||||||
|
&data, &data_len,
|
||||||
|
LIBSSH2_PACKET_MAXDECOMP,
|
||||||
|
p->payload,
|
||||||
|
session->fullpacket_payload_len,
|
||||||
|
&session->remote.comp_abstract);
|
||||||
|
LIBSSH2_FREE(session, p->payload);
|
||||||
|
if(rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
p->payload = data;
|
||||||
|
session->fullpacket_payload_len = data_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->fullpacket_packet_type = p->payload[0];
|
||||||
|
|
||||||
|
debugdump(session, "libssh2_transport_read() plain",
|
||||||
|
p->payload, session->fullpacket_payload_len);
|
||||||
|
|
||||||
|
session->fullpacket_state = libssh2_NB_state_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->fullpacket_state == libssh2_NB_state_created) {
|
||||||
|
rc = _libssh2_packet_add(session, p->payload,
|
||||||
|
session->fullpacket_payload_len,
|
||||||
|
session->fullpacket_macstate);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->fullpacket_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
return session->fullpacket_packet_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_transport_read
|
||||||
|
*
|
||||||
|
* Collect a packet into the input queue.
|
||||||
|
*
|
||||||
|
* Returns packet type added to input queue (0 if nothing added), or a
|
||||||
|
* negative error number.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||||
|
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||||
|
*
|
||||||
|
* DOES NOT call _libssh2_error() for ANY error case.
|
||||||
|
*/
|
||||||
|
int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct transportpacket *p = &session->packet;
|
||||||
|
int remainbuf;
|
||||||
|
int remainpack;
|
||||||
|
int numbytes;
|
||||||
|
int numdecrypt;
|
||||||
|
unsigned char block[MAX_BLOCKSIZE];
|
||||||
|
int blocksize;
|
||||||
|
int encrypted = 1;
|
||||||
|
size_t total_num;
|
||||||
|
|
||||||
|
/* default clear the bit */
|
||||||
|
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All channels, systems, subsystems, etc eventually make it down here
|
||||||
|
* when looking for more incoming data. If a key exchange is going on
|
||||||
|
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will
|
||||||
|
* ONLY send key exchange related traffic. In non-blocking mode, there is
|
||||||
|
* a chance to break out of the kex_exchange function with an EAGAIN
|
||||||
|
* status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is
|
||||||
|
* active, then we must redirect to the key exchange. However, if
|
||||||
|
* kex_exchange is active (as in it is the one that calls this execution
|
||||||
|
* of packet_read, then don't redirect, as that would be an infinite loop!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||||
|
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||||
|
|
||||||
|
/* Whoever wants a packet won't get anything until the key re-exchange
|
||||||
|
* is done!
|
||||||
|
*/
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
|
||||||
|
" key re-exchange from _libssh2_transport_read");
|
||||||
|
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =============================== NOTE ===============================
|
||||||
|
* I know this is very ugly and not a really good use of "goto", but
|
||||||
|
* this case statement would be even uglier to do it any other way
|
||||||
|
*/
|
||||||
|
if (session->readPack_state == libssh2_NB_state_jump1) {
|
||||||
|
session->readPack_state = libssh2_NB_state_idle;
|
||||||
|
encrypted = session->readPack_encrypted;
|
||||||
|
goto libssh2_transport_read_point1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||||
|
blocksize = session->remote.crypt->blocksize;
|
||||||
|
} else {
|
||||||
|
encrypted = 0; /* not encrypted */
|
||||||
|
blocksize = 5; /* not strictly true, but we can use 5 here to
|
||||||
|
make the checks below work fine still */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read/use a whole big chunk into a temporary area stored in
|
||||||
|
the LIBSSH2_SESSION struct. We will decrypt data from that
|
||||||
|
buffer into the packet buffer so this temp one doesn't have
|
||||||
|
to be able to keep a whole SSH packet, just be large enough
|
||||||
|
so that we can read big chunks from the network layer. */
|
||||||
|
|
||||||
|
/* how much data there is remaining in the buffer to deal with
|
||||||
|
before we should read more from the network */
|
||||||
|
remainbuf = p->writeidx - p->readidx;
|
||||||
|
|
||||||
|
/* if remainbuf turns negative we have a bad internal error */
|
||||||
|
assert(remainbuf >= 0);
|
||||||
|
|
||||||
|
if (remainbuf < blocksize) {
|
||||||
|
/* If we have less than a blocksize left, it is too
|
||||||
|
little data to deal with, read more */
|
||||||
|
ssize_t nread;
|
||||||
|
|
||||||
|
/* move any remainder to the start of the buffer so
|
||||||
|
that we can do a full refill */
|
||||||
|
if (remainbuf) {
|
||||||
|
memmove(p->buf, &p->buf[p->readidx], remainbuf);
|
||||||
|
p->readidx = 0;
|
||||||
|
p->writeidx = remainbuf;
|
||||||
|
} else {
|
||||||
|
/* nothing to move, just zero the indexes */
|
||||||
|
p->readidx = p->writeidx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now read a big chunk from the network into the temp buffer */
|
||||||
|
nread =
|
||||||
|
LIBSSH2_RECV(session, &p->buf[remainbuf],
|
||||||
|
PACKETBUFSIZE - remainbuf,
|
||||||
|
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||||
|
if (nread <= 0) {
|
||||||
|
/* check if this is due to EAGAIN and return the special
|
||||||
|
return code if so, error out normally otherwise */
|
||||||
|
if ((nread < 0) && (nread == -EAGAIN)) {
|
||||||
|
session->socket_block_directions |=
|
||||||
|
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||||
|
"Error recving %d bytes (got %d)",
|
||||||
|
PACKETBUFSIZE - remainbuf, -nread);
|
||||||
|
return LIBSSH2_ERROR_SOCKET_RECV;
|
||||||
|
}
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||||
|
"Recved %d/%d bytes to %p+%d", nread,
|
||||||
|
PACKETBUFSIZE - remainbuf, p->buf, remainbuf);
|
||||||
|
|
||||||
|
debugdump(session, "libssh2_transport_read() raw",
|
||||||
|
&p->buf[remainbuf], nread);
|
||||||
|
/* advance write pointer */
|
||||||
|
p->writeidx += nread;
|
||||||
|
|
||||||
|
/* update remainbuf counter */
|
||||||
|
remainbuf = p->writeidx - p->readidx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* how much data to deal with from the buffer */
|
||||||
|
numbytes = remainbuf;
|
||||||
|
|
||||||
|
if (!p->total_num) {
|
||||||
|
/* No payload package area allocated yet. To know the
|
||||||
|
size of this payload, we need to decrypt the first
|
||||||
|
blocksize data. */
|
||||||
|
|
||||||
|
if (numbytes < blocksize) {
|
||||||
|
/* we can't act on anything less than blocksize, but this
|
||||||
|
check is only done for the initial block since once we have
|
||||||
|
got the start of a block we can in fact deal with fractions
|
||||||
|
*/
|
||||||
|
session->socket_block_directions |=
|
||||||
|
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encrypted) {
|
||||||
|
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
|
||||||
|
if (rc != LIBSSH2_ERROR_NONE) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/* save the first 5 bytes of the decrypted package, to be
|
||||||
|
used in the hash calculation later down. */
|
||||||
|
memcpy(p->init, &p->buf[p->readidx], 5);
|
||||||
|
} else {
|
||||||
|
/* the data is plain, just copy it verbatim to
|
||||||
|
the working block buffer */
|
||||||
|
memcpy(block, &p->buf[p->readidx], blocksize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* advance the read pointer */
|
||||||
|
p->readidx += blocksize;
|
||||||
|
|
||||||
|
/* we now have the initial blocksize bytes decrypted,
|
||||||
|
* and we can extract packet and padding length from it
|
||||||
|
*/
|
||||||
|
p->packet_length = _libssh2_ntohu32(block);
|
||||||
|
if (p->packet_length < 1)
|
||||||
|
return LIBSSH2_ERROR_DECRYPT;
|
||||||
|
|
||||||
|
p->padding_length = block[4];
|
||||||
|
|
||||||
|
/* total_num is the number of bytes following the initial
|
||||||
|
(5 bytes) packet length and padding length fields */
|
||||||
|
total_num =
|
||||||
|
p->packet_length - 1 +
|
||||||
|
(encrypted ? session->remote.mac->mac_len : 0);
|
||||||
|
|
||||||
|
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||||
|
*
|
||||||
|
* "All implementations MUST be able to process
|
||||||
|
* packets with uncompressed payload length of 32768
|
||||||
|
* bytes or less and total packet size of 35000 bytes
|
||||||
|
* or less (including length, padding length, payload,
|
||||||
|
* padding, and MAC.)."
|
||||||
|
*/
|
||||||
|
if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
|
||||||
|
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a packet handle put data into. We get one to
|
||||||
|
hold all data, including padding and MAC. */
|
||||||
|
p->payload = LIBSSH2_ALLOC(session, total_num);
|
||||||
|
if (!p->payload) {
|
||||||
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
|
}
|
||||||
|
p->total_num = total_num;
|
||||||
|
/* init write pointer to start of payload buffer */
|
||||||
|
p->wptr = p->payload;
|
||||||
|
|
||||||
|
if (blocksize > 5) {
|
||||||
|
/* copy the data from index 5 to the end of
|
||||||
|
the blocksize from the temporary buffer to
|
||||||
|
the start of the decrypted buffer */
|
||||||
|
memcpy(p->wptr, &block[5], blocksize - 5);
|
||||||
|
p->wptr += blocksize - 5; /* advance write pointer */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init the data_num field to the number of bytes of
|
||||||
|
the package read so far */
|
||||||
|
p->data_num = p->wptr - p->payload;
|
||||||
|
|
||||||
|
/* we already dealt with a blocksize worth of data */
|
||||||
|
numbytes -= blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* how much there is left to add to the current payload
|
||||||
|
package */
|
||||||
|
remainpack = p->total_num - p->data_num;
|
||||||
|
|
||||||
|
if (numbytes > remainpack) {
|
||||||
|
/* if we have more data in the buffer than what is going into this
|
||||||
|
particular packet, we limit this round to this packet only */
|
||||||
|
numbytes = remainpack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encrypted) {
|
||||||
|
/* At the end of the incoming stream, there is a MAC,
|
||||||
|
and we don't want to decrypt that since we need it
|
||||||
|
"raw". We MUST however decrypt the padding data
|
||||||
|
since it is used for the hash later on. */
|
||||||
|
int skip = session->remote.mac->mac_len;
|
||||||
|
|
||||||
|
/* if what we have plus numbytes is bigger than the
|
||||||
|
total minus the skip margin, we should lower the
|
||||||
|
amount to decrypt even more */
|
||||||
|
if ((p->data_num + numbytes) > (p->total_num - skip)) {
|
||||||
|
numdecrypt = (p->total_num - skip) - p->data_num;
|
||||||
|
} else {
|
||||||
|
int frac;
|
||||||
|
numdecrypt = numbytes;
|
||||||
|
frac = numdecrypt % blocksize;
|
||||||
|
if (frac) {
|
||||||
|
/* not an aligned amount of blocks,
|
||||||
|
align it */
|
||||||
|
numdecrypt -= frac;
|
||||||
|
/* and make it no unencrypted data
|
||||||
|
after it */
|
||||||
|
numbytes = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* unencrypted data should not be decrypted at all */
|
||||||
|
numdecrypt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there are bytes to decrypt, do that */
|
||||||
|
if (numdecrypt > 0) {
|
||||||
|
/* now decrypt the lot */
|
||||||
|
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
||||||
|
if (rc != LIBSSH2_ERROR_NONE) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* advance the read pointer */
|
||||||
|
p->readidx += numdecrypt;
|
||||||
|
/* advance write pointer */
|
||||||
|
p->wptr += numdecrypt;
|
||||||
|
/* increse data_num */
|
||||||
|
p->data_num += numdecrypt;
|
||||||
|
|
||||||
|
/* bytes left to take care of without decryption */
|
||||||
|
numbytes -= numdecrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there are bytes to copy that aren't decrypted, simply
|
||||||
|
copy them as-is to the target buffer */
|
||||||
|
if (numbytes > 0) {
|
||||||
|
memcpy(p->wptr, &p->buf[p->readidx], numbytes);
|
||||||
|
|
||||||
|
/* advance the read pointer */
|
||||||
|
p->readidx += numbytes;
|
||||||
|
/* advance write pointer */
|
||||||
|
p->wptr += numbytes;
|
||||||
|
/* increse data_num */
|
||||||
|
p->data_num += numbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now check how much data there's left to read to finish the
|
||||||
|
current packet */
|
||||||
|
remainpack = p->total_num - p->data_num;
|
||||||
|
|
||||||
|
if (!remainpack) {
|
||||||
|
/* we have a full packet */
|
||||||
|
libssh2_transport_read_point1:
|
||||||
|
rc = fullpacket(session, encrypted);
|
||||||
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
|
||||||
|
if (session->packAdd_state != libssh2_NB_state_idle)
|
||||||
|
{
|
||||||
|
/* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
|
||||||
|
* libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that
|
||||||
|
* returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle,
|
||||||
|
* then the packet has been added to the brigade, but some
|
||||||
|
* immediate action that was taken based on the packet
|
||||||
|
* type (such as key re-exchange) is not yet complete.
|
||||||
|
* Clear the way for a new packet to be read in.
|
||||||
|
*/
|
||||||
|
session->readPack_encrypted = encrypted;
|
||||||
|
session->readPack_state = libssh2_NB_state_jump1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->total_num = 0; /* no packet buffer available */
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
} while (1); /* loop */
|
||||||
|
|
||||||
|
return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
|
||||||
|
size_t data_len, ssize_t *ret)
|
||||||
|
{
|
||||||
|
ssize_t rc;
|
||||||
|
ssize_t length;
|
||||||
|
struct transportpacket *p = &session->packet;
|
||||||
|
|
||||||
|
if (!p->olen) {
|
||||||
|
*ret = 0;
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send as much as possible of the existing packet */
|
||||||
|
if ((data != p->odata) || (data_len != p->olen)) {
|
||||||
|
/* When we are about to complete the sending of a packet, it is vital
|
||||||
|
that the caller doesn't try to send a new/different packet since
|
||||||
|
we don't add this one up until the previous one has been sent. To
|
||||||
|
make the caller really notice his/hers flaw, we return error for
|
||||||
|
this case */
|
||||||
|
return LIBSSH2_ERROR_BAD_USE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = 1; /* set to make our parent return */
|
||||||
|
|
||||||
|
/* number of bytes left to send */
|
||||||
|
length = p->ototal_num - p->osent;
|
||||||
|
|
||||||
|
rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
|
||||||
|
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||||
|
if (rc < 0)
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||||
|
"Error sending %d bytes: %d", length, -rc);
|
||||||
|
else {
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||||
|
"Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
|
||||||
|
p->osent);
|
||||||
|
debugdump(session, "libssh2_transport_write send()",
|
||||||
|
&p->outbuf[p->osent], rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == length) {
|
||||||
|
/* the remainder of the package was sent */
|
||||||
|
p->ototal_num = 0;
|
||||||
|
p->olen = 0;
|
||||||
|
/* we leave *ret set so that the parent returns as we MUST return back
|
||||||
|
a send success now, so that we don't risk sending EAGAIN later
|
||||||
|
which then would confuse the parent function */
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (rc < 0) {
|
||||||
|
/* nothing was sent */
|
||||||
|
if (rc != -EAGAIN)
|
||||||
|
/* send failure! */
|
||||||
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
|
|
||||||
|
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->osent += rc; /* we sent away this much data */
|
||||||
|
|
||||||
|
return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_transport_send
|
||||||
|
*
|
||||||
|
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||||
|
* Returns 0 on success, non-zero on failure.
|
||||||
|
*
|
||||||
|
* The data is provided as _two_ data areas that are combined by this
|
||||||
|
* function. The 'data' part is sent immediately before 'data2'. 'data2' may
|
||||||
|
* be set to NULL to only use a single part.
|
||||||
|
*
|
||||||
|
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||||
|
* not sent yet. If it does so, the caller should call this function again as
|
||||||
|
* soon as it is likely that more data can be sent, and this function MUST
|
||||||
|
* then be called with the same argument set (same data pointer and same
|
||||||
|
* data_len) until ERROR_NONE or failure is returned.
|
||||||
|
*
|
||||||
|
* This function DOES NOT call _libssh2_error() on any errors.
|
||||||
|
*/
|
||||||
|
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||||
|
const unsigned char *data, size_t data_len,
|
||||||
|
const unsigned char *data2, size_t data2_len)
|
||||||
|
{
|
||||||
|
int blocksize =
|
||||||
|
(session->state & LIBSSH2_STATE_NEWKEYS) ?
|
||||||
|
session->local.crypt->blocksize : 8;
|
||||||
|
int padding_length;
|
||||||
|
size_t packet_length;
|
||||||
|
int total_length;
|
||||||
|
#ifdef RANDOM_PADDING
|
||||||
|
int rand_max;
|
||||||
|
int seed = data[0]; /* FIXME: make this random */
|
||||||
|
#endif
|
||||||
|
struct transportpacket *p = &session->packet;
|
||||||
|
int encrypted;
|
||||||
|
ssize_t ret;
|
||||||
|
int rc;
|
||||||
|
const unsigned char *orgdata = data;
|
||||||
|
size_t orgdata_len = data_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the last read operation was interrupted in the middle of a key
|
||||||
|
* exchange, we must complete that key exchange before continuing to write
|
||||||
|
* further data.
|
||||||
|
*
|
||||||
|
* See the similar block in _libssh2_transport_read for more details.
|
||||||
|
*/
|
||||||
|
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||||
|
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||||
|
/* Don't write any new packets if we're still in the middle of a key
|
||||||
|
* exchange. */
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
|
||||||
|
" key re-exchange from _libssh2_transport_send");
|
||||||
|
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugdump(session, "libssh2_transport_write plain", data, data_len);
|
||||||
|
if(data2)
|
||||||
|
debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
|
||||||
|
|
||||||
|
/* FIRST, check if we have a pending write to complete. send_existing
|
||||||
|
only sanity-check data and data_len and not data2 and data2_len!! */
|
||||||
|
rc = send_existing(session, data, data_len, &ret);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
/* set by send_existing if data was sent */
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
|
||||||
|
|
||||||
|
if (encrypted && session->local.comp->compress) {
|
||||||
|
/* the idea here is that these function must fail if the output gets
|
||||||
|
larger than what fits in the assigned buffer so thus they don't
|
||||||
|
check the input size as we don't know how much it compresses */
|
||||||
|
size_t dest_len = MAX_SSH_PACKET_LEN-5-256;
|
||||||
|
size_t dest2_len = dest_len;
|
||||||
|
|
||||||
|
/* compress directly to the target buffer */
|
||||||
|
rc = session->local.comp->comp(session,
|
||||||
|
&p->outbuf[5], &dest_len,
|
||||||
|
data, data_len,
|
||||||
|
&session->local.comp_abstract);
|
||||||
|
if(rc)
|
||||||
|
return rc; /* compression failure */
|
||||||
|
|
||||||
|
if(data2 && data2_len) {
|
||||||
|
/* compress directly to the target buffer right after where the
|
||||||
|
previous call put data */
|
||||||
|
dest2_len -= dest_len;
|
||||||
|
|
||||||
|
rc = session->local.comp->comp(session,
|
||||||
|
&p->outbuf[5+dest_len], &dest2_len,
|
||||||
|
data2, data2_len,
|
||||||
|
&session->local.comp_abstract);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dest2_len = 0;
|
||||||
|
if(rc)
|
||||||
|
return rc; /* compression failure */
|
||||||
|
|
||||||
|
data_len = dest_len + dest2_len; /* use the combined length */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100))
|
||||||
|
/* too large packet, return error for this until we make this
|
||||||
|
function split it up and send multiple SSH packets */
|
||||||
|
return LIBSSH2_ERROR_INVAL;
|
||||||
|
|
||||||
|
/* copy the payload data */
|
||||||
|
memcpy(&p->outbuf[5], data, data_len);
|
||||||
|
if(data2 && data2_len)
|
||||||
|
memcpy(&p->outbuf[5+data_len], data2, data2_len);
|
||||||
|
data_len += data2_len; /* use the combined length */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* RFC4253 says: Note that the length of the concatenation of
|
||||||
|
'packet_length', 'padding_length', 'payload', and 'random padding'
|
||||||
|
MUST be a multiple of the cipher block size or 8, whichever is
|
||||||
|
larger. */
|
||||||
|
|
||||||
|
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
|
||||||
|
|
||||||
|
packet_length = data_len + 1 + 4; /* 1 is for padding_length field
|
||||||
|
4 for the packet_length field */
|
||||||
|
|
||||||
|
/* at this point we have it all except the padding */
|
||||||
|
|
||||||
|
/* first figure out our minimum padding amount to make it an even
|
||||||
|
block size */
|
||||||
|
padding_length = blocksize - (packet_length % blocksize);
|
||||||
|
|
||||||
|
/* if the padding becomes too small we add another blocksize worth
|
||||||
|
of it (taken from the original libssh2 where it didn't have any
|
||||||
|
real explanation) */
|
||||||
|
if (padding_length < 4) {
|
||||||
|
padding_length += blocksize;
|
||||||
|
}
|
||||||
|
#ifdef RANDOM_PADDING
|
||||||
|
/* FIXME: we can add padding here, but that also makes the packets
|
||||||
|
bigger etc */
|
||||||
|
|
||||||
|
/* now we can add 'blocksize' to the padding_length N number of times
|
||||||
|
(to "help thwart traffic analysis") but it must be less than 255 in
|
||||||
|
total */
|
||||||
|
rand_max = (255 - padding_length) / blocksize + 1;
|
||||||
|
padding_length += blocksize * (seed % rand_max);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
packet_length += padding_length;
|
||||||
|
|
||||||
|
/* append the MAC length to the total_length size */
|
||||||
|
total_length =
|
||||||
|
packet_length + (encrypted ? session->local.mac->mac_len : 0);
|
||||||
|
|
||||||
|
/* store packet_length, which is the size of the whole packet except
|
||||||
|
the MAC and the packet_length field itself */
|
||||||
|
_libssh2_htonu32(p->outbuf, packet_length - 4);
|
||||||
|
/* store padding_length */
|
||||||
|
p->outbuf[4] = padding_length;
|
||||||
|
|
||||||
|
/* fill the padding area with random junk */
|
||||||
|
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
|
||||||
|
|
||||||
|
if (encrypted) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Calculate MAC hash. Put the output at index packet_length,
|
||||||
|
since that size includes the whole packet. The MAC is
|
||||||
|
calculated on the entire unencrypted packet, including all
|
||||||
|
fields except the MAC field itself. */
|
||||||
|
session->local.mac->hash(session, p->outbuf + packet_length,
|
||||||
|
session->local.seqno, p->outbuf,
|
||||||
|
packet_length, NULL, 0,
|
||||||
|
&session->local.mac_abstract);
|
||||||
|
|
||||||
|
/* Encrypt the whole packet data, one block size at a time.
|
||||||
|
The MAC field is not encrypted. */
|
||||||
|
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||||
|
unsigned char *ptr = &p->outbuf[i];
|
||||||
|
if (session->local.crypt->crypt(session, ptr,
|
||||||
|
&session->local.crypt_abstract))
|
||||||
|
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session->local.seqno++;
|
||||||
|
|
||||||
|
ret = LIBSSH2_SEND(session, p->outbuf, total_length,
|
||||||
|
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||||
|
if (ret < 0)
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||||
|
"Error sending %d bytes: %d", total_length, -ret);
|
||||||
|
else {
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p",
|
||||||
|
ret, total_length, p->outbuf);
|
||||||
|
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != total_length) {
|
||||||
|
if (ret >= 0 || ret == -EAGAIN) {
|
||||||
|
/* the whole packet could not be sent, save the rest */
|
||||||
|
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
|
p->odata = orgdata;
|
||||||
|
p->olen = orgdata_len;
|
||||||
|
p->osent = ret <= 0 ? 0 : ret;
|
||||||
|
p->ototal_num = total_length;
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the whole thing got sent away */
|
||||||
|
p->odata = NULL;
|
||||||
|
p->olen = 0;
|
||||||
|
|
||||||
|
return LIBSSH2_ERROR_NONE; /* all is good */
|
||||||
|
}
|
||||||
87
vendor/libssh2-1.4.2/src/transport.h
vendored
Normal file
87
vendor/libssh2-1.4.2/src/transport.h
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#ifndef __LIBSSH2_TRANSPORT_H
|
||||||
|
#define __LIBSSH2_TRANSPORT_H
|
||||||
|
|
||||||
|
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||||
|
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file handles reading and writing to the SECSH transport layer. RFC4253.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
#include "packet.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libssh2_transport_send
|
||||||
|
*
|
||||||
|
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||||
|
* Returns 0 on success, non-zero on failure.
|
||||||
|
*
|
||||||
|
* The data is provided as _two_ data areas that are combined by this
|
||||||
|
* function. The 'data' part is sent immediately before 'data2'. 'data2' can
|
||||||
|
* be set to NULL (or data2_len to 0) to only use a single part.
|
||||||
|
*
|
||||||
|
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||||
|
* not sent yet. If it does so, the caller should call this function again as
|
||||||
|
* soon as it is likely that more data can be sent, and this function MUST
|
||||||
|
* then be called with the same argument set (same data pointer and same
|
||||||
|
* data_len) until ERROR_NONE or failure is returned.
|
||||||
|
*
|
||||||
|
* This function DOES NOT call _libssh2_error() on any errors.
|
||||||
|
*/
|
||||||
|
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||||
|
const unsigned char *data, size_t data_len,
|
||||||
|
const unsigned char *data2, size_t data2_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_transport_read
|
||||||
|
*
|
||||||
|
* Collect a packet into the input brigade block only controls whether or not
|
||||||
|
* to wait for a packet to start.
|
||||||
|
*
|
||||||
|
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
|
||||||
|
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
|
||||||
|
* packet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||||
|
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||||
|
*/
|
||||||
|
int _libssh2_transport_read(LIBSSH2_SESSION * session);
|
||||||
|
|
||||||
|
#endif /* __LIBSSH2_TRANSPORT_H */
|
||||||
1687
vendor/libssh2-1.4.2/src/userauth.c
vendored
Normal file
1687
vendor/libssh2-1.4.2/src/userauth.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
50
vendor/libssh2-1.4.2/src/userauth.h
vendored
Normal file
50
vendor/libssh2-1.4.2/src/userauth.h
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef LIBSSH2_USERAUTH_H
|
||||||
|
#define LIBSSH2_USERAUTH_H
|
||||||
|
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||||
|
const char *username,
|
||||||
|
unsigned int username_len,
|
||||||
|
const unsigned char *pubkeydata,
|
||||||
|
unsigned long pubkeydata_len,
|
||||||
|
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
|
||||||
|
void *abstract);
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_USERAUTH_H */
|
||||||
54
vendor/libssh2-1.4.2/src/version.c
vendored
Normal file
54
vendor/libssh2-1.4.2/src/version.c
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* Copyright (C) 2009 Daniel Stenberg. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
libssh2_version() can be used like this:
|
||||||
|
|
||||||
|
if (!libssh2_version(LIBSSH2_VERSION_NUM)) {
|
||||||
|
fprintf (stderr, "Runtime libssh2 version too old!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
LIBSSH2_API
|
||||||
|
const char *libssh2_version(int req_version_num)
|
||||||
|
{
|
||||||
|
if(req_version_num <= LIBSSH2_VERSION_NUM)
|
||||||
|
return LIBSSH2_VERSION;
|
||||||
|
return NULL; /* this is not a suitable library! */
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue