Merge branch 'master' of github.com:bytemaster/fc
This commit is contained in:
commit
7114399f47
107 changed files with 775 additions and 29257 deletions
|
|
@ -50,13 +50,16 @@ include_directories( include )
|
|||
|
||||
set( sources
|
||||
src/ssh.cpp
|
||||
src/url.cpp
|
||||
src/process.cpp
|
||||
src/http_connection.cpp
|
||||
src/http_server.cpp
|
||||
src/json_rpc_connection.cpp
|
||||
src/json_rpc_stream_connection.cpp
|
||||
src/json_rpc_tcp_connection.cpp
|
||||
src/json_rpc_tcp_server.cpp
|
||||
src/json_rpc_error_object.cpp
|
||||
src/error_report.cpp
|
||||
src/value.cpp
|
||||
src/lexical_cast.cpp
|
||||
src/spin_lock.cpp
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc {
|
||||
fc::string to_base58( const char* d, uint32_t s );
|
||||
size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_data_len );
|
||||
fc::string to_base58( const char* d, uint32_t s );
|
||||
size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_data_len );
|
||||
}
|
||||
#endif // _FC_BASE58_HPP_
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _FC_DATASTREAM_HPP_
|
||||
#define _FC_DATASTREAM_HPP_
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/exception.hpp>
|
||||
#include <fc/error_report.hpp>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -40,8 +40,8 @@ struct datastream {
|
|||
m_pos += s;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_MSG( "Attempt to read %s bytes beyond end of buffer of size %s",
|
||||
int64_t(-((m_end-m_pos) - s)), int64_t(m_end-m_start) );
|
||||
FC_THROW_REPORT( "Attempt to read ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ",
|
||||
fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - s))).set("buffer_size", int64_t(m_end-m_start)) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,8 @@ struct datastream {
|
|||
m_pos += s;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_MSG( "Attempt to write %s bytes beyond end of buffer of size %s", int64_t(-((m_end-m_pos) - s)),int64_t(m_end-m_start) );
|
||||
FC_THROW_REPORT( "Attempt to write ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ",
|
||||
fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - s))).set("buffer_size", int64_t(m_end-m_start)) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +62,8 @@ struct datastream {
|
|||
++m_pos;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_MSG( "Attempt to write %s byte beyond end of buffer of size %s", int64_t(-((m_end-m_pos) - 1)), int64_t(m_end-m_start) );
|
||||
FC_THROW_REPORT( "Attempt to write ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ",
|
||||
fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - 1))).set("buffer_size", int64_t(m_end-m_start)) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +74,8 @@ struct datastream {
|
|||
++m_pos;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_MSG( "Attempt to read %s byte beyond end of buffer of size %s", int64_t(-((m_end-m_pos) - 1)), int64_t(m_end-m_start) );
|
||||
FC_THROW_REPORT( "Attempt to read ${bytes_past} bytes beyond end of buffer of size ${buffer_size} ",
|
||||
fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - 1))).set("buffer_size", int64_t(m_end-m_start)) );
|
||||
++m_pos;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
68
include/fc/error_report.hpp
Normal file
68
include/fc/error_report.hpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/exception.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
/**
|
||||
* Represents one stack frame within an error_report.
|
||||
*/
|
||||
class error_frame {
|
||||
public:
|
||||
error_frame( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value m );
|
||||
error_frame(){}
|
||||
error_frame(const error_frame& );
|
||||
error_frame(error_frame&& );
|
||||
|
||||
error_frame& operator=(const error_frame& );
|
||||
error_frame& operator=(error_frame&& );
|
||||
|
||||
fc::string to_string()const;
|
||||
fc::string to_detail_string()const;
|
||||
|
||||
fc::string desc;
|
||||
fc::string file;
|
||||
int64_t line;
|
||||
fc::string method;
|
||||
uint64_t time;
|
||||
fc::optional<fc::value> meta;
|
||||
};
|
||||
typedef fc::vector<error_frame> error_context;
|
||||
|
||||
/**
|
||||
* This class is used for rich error reporting that captures relevant errors the
|
||||
* whole way up the stack. By using FC_THROW_REPORT(...) and FC_REPORT_PUSH( e, ...)
|
||||
* you can capture the file, line, and method where the error was caught / rethrown.
|
||||
*/
|
||||
class error_report {
|
||||
public:
|
||||
error_report();
|
||||
error_report( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta = fc::value() );
|
||||
|
||||
error_frame& current();
|
||||
error_report& pop_frame();
|
||||
error_report& push_frame( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta = fc::value() );
|
||||
error_report& append( const error_report& e );
|
||||
|
||||
fc::string to_string()const;
|
||||
fc::string to_detail_string()const;
|
||||
error_context stack; ///< Human readable stack of what we were atempting to do.
|
||||
|
||||
fc::exception_ptr copy_exception();
|
||||
};
|
||||
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::error_frame, (desc)(file)(line)(method)(time)(meta) )
|
||||
FC_REFLECT( fc::error_report, (stack) )
|
||||
|
||||
#define FC_REPORT( X, ... ) fc::error_report X( __FILE__, __LINE__, __func__, __VA_ARGS__ )
|
||||
#define FC_THROW_REPORT( ... ) FC_THROW( fc::error_report( __FILE__, __LINE__, __func__, __VA_ARGS__ ))
|
||||
#define FC_REPORT_CURRENT(ER, ... ) (ER).pop_frame().push_frame( __FILE__, __LINE__, __func__, __VA_ARGS__ )
|
||||
#define FC_REPORT_PUSH( ER, ... ) (ER).push_frame( __FILE__, __LINE__, __func__, __VA_ARGS__ );
|
||||
#define FC_REPORT_POP(ER) (ER).pop_frame()
|
||||
|
|
@ -48,7 +48,7 @@ namespace fc {
|
|||
try { throw e; } catch (...) { return current_exception(); }
|
||||
return exception_ptr();
|
||||
}
|
||||
void rethrow_exception( const exception_ptr& e );
|
||||
void rethrow_exception( const exception_ptr& e );
|
||||
|
||||
void throw_exception( const char* func, const char* file, int line, const char* msg );
|
||||
void throw_exception_( const char* func, const char* file, int line, const char* msg,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ namespace fc {
|
|||
bool is_directory( const path& p );
|
||||
bool is_regular_file( const path& p );
|
||||
void create_directories( const path& p );
|
||||
path absolute( const path& p );
|
||||
path canonical( const path& p );
|
||||
uint64_t file_size( const path& p );
|
||||
bool remove( const path& p );
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ namespace fc {
|
|||
namespace http {
|
||||
|
||||
struct header {
|
||||
header( fc::string k, fc::string v )
|
||||
:key(fc::move(k)),val(fc::move(v)){}
|
||||
header(){}
|
||||
fc::string key;
|
||||
fc::string val;
|
||||
};
|
||||
|
|
@ -47,10 +50,9 @@ namespace fc {
|
|||
http::reply request( const fc::string& method, const fc::string& url, const fc::string& body );
|
||||
|
||||
// used for servers
|
||||
fc::tcp_socket& get_socket();
|
||||
fc::tcp_socket& get_socket()const;
|
||||
|
||||
http::request read_request();
|
||||
void send_reply( const http::reply& );
|
||||
http::request read_request()const;
|
||||
|
||||
FC_REFERENCE_TYPE(connection)
|
||||
};
|
||||
|
|
|
|||
60
include/fc/http/server.hpp
Normal file
60
include/fc/http/server.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
#include <fc/http/connection.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace fc { namespace http {
|
||||
|
||||
/**
|
||||
* Listens on a given port for incomming http
|
||||
* connections and then calls a user provided callback
|
||||
* function for every http request.
|
||||
*
|
||||
*/
|
||||
class server {
|
||||
public:
|
||||
server();
|
||||
server( uint16_t port );
|
||||
server( const server& s );
|
||||
server( server&& s );
|
||||
~server();
|
||||
|
||||
server& operator=(const server& s);
|
||||
server& operator=(server&& s);
|
||||
|
||||
class response {
|
||||
public:
|
||||
class impl;
|
||||
|
||||
response();
|
||||
response( const fc::shared_ptr<impl>& my);
|
||||
response( const response& r);
|
||||
response( response&& r );
|
||||
~response();
|
||||
response& operator=(const response& );
|
||||
response& operator=( response&& );
|
||||
|
||||
void add_header( const fc::string& key, const fc::string& val )const;
|
||||
void set_status( const http::reply::status_code& s )const;
|
||||
void set_length( uint64_t s )const;
|
||||
|
||||
void write( const char* data, uint64_t len )const;
|
||||
|
||||
private:
|
||||
fc::shared_ptr<impl> my;
|
||||
};
|
||||
|
||||
void listen( uint16_t p );
|
||||
|
||||
/**
|
||||
* Set the callback to be called for every http request made.
|
||||
*/
|
||||
void on_request( const std::function<void(const http::request&, const server::response& s )>& cb );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
|
||||
};
|
||||
|
||||
} }
|
||||
|
|
@ -64,14 +64,18 @@ namespace fc {
|
|||
|
||||
virtual ~istream_wrapper(){};
|
||||
|
||||
virtual size_t readsome( char* buf, size_t len ) { return my->readsome(buf,len); }
|
||||
virtual size_t readsome( char* buf, size_t len ) {
|
||||
return my->readsome(buf,len);
|
||||
}
|
||||
virtual istream& read( char* buf, size_t len ) {
|
||||
// slog( "%p %lld", my.get(), len );
|
||||
my->read(buf,len);
|
||||
return *this;
|
||||
}
|
||||
virtual void close() { }
|
||||
virtual bool eof()const{ return my->eof(); }
|
||||
|
||||
/*
|
||||
virtual istream& read( int64_t& ) { return *this; }
|
||||
virtual istream& read( uint64_t& ) { return *this; }
|
||||
virtual istream& read( int32_t& ) { return *this; }
|
||||
|
|
@ -85,6 +89,7 @@ namespace fc {
|
|||
virtual istream& read( bool& ) { return *this; }
|
||||
virtual istream& read( char& ) { return *this; }
|
||||
virtual istream& read( fc::string& ) { return *this; }
|
||||
*/
|
||||
|
||||
protected:
|
||||
struct impl_base : public fc::retainable {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_error_object.hpp>
|
||||
#include <fc/json.hpp>
|
||||
#include <fc/future.hpp>
|
||||
#include <fc/function.hpp>
|
||||
|
|
@ -6,6 +7,7 @@
|
|||
|
||||
namespace fc { namespace json {
|
||||
class rpc_connection;
|
||||
class error_object;
|
||||
|
||||
struct rpc_server_method : public fc::retainable {
|
||||
typedef fc::shared_ptr<rpc_server_method> ptr;
|
||||
|
|
@ -141,7 +143,7 @@ namespace fc { namespace json {
|
|||
void handle_message( const value& m );
|
||||
virtual void send_notice( const fc::string& m, value&& param ) = 0;
|
||||
virtual void send_invoke( uint64_t id, const fc::string& m, value&& param ) = 0;
|
||||
virtual void send_error( uint64_t id, int64_t code, const fc::string& msg ) = 0;
|
||||
virtual void send_error( uint64_t id, const error_object& e ) = 0;
|
||||
virtual void send_result( uint64_t id, value&& r ) = 0;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,26 @@
|
|||
#include <fc/string.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/reflect.hpp>
|
||||
|
||||
namespace fc { namespace json {
|
||||
|
||||
struct error_object {
|
||||
error_object( const fc::string& msg = fc::string(), fc::value v = fc::value(), int64_t c = -32000);
|
||||
namespace fc {
|
||||
class value;
|
||||
|
||||
int64_t code;
|
||||
fc::string message;
|
||||
fc::optional<fc::value> data;
|
||||
namespace json {
|
||||
|
||||
class error_object {
|
||||
public:
|
||||
error_object( const fc::string& msg, const fc::value& v , int64_t c = -32000);
|
||||
error_object( const fc::string& msg=fc::string(), int64_t c = -32000 );
|
||||
error_object( const error_object& e );
|
||||
~error_object();
|
||||
|
||||
int64_t code;
|
||||
fc::string message;
|
||||
fc::optional<fc::value> data;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::json::error_object, (code)(message)(data) )
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ namespace fc { namespace json {
|
|||
void on_close( T&& f) { _con->on_close( fc::forward<T>(f) ); }
|
||||
|
||||
const fc::json::rpc_stream_connection::ptr& connection()const { return _con; }
|
||||
|
||||
~rpc_process_client() {
|
||||
if(_con)
|
||||
_con->close();
|
||||
}
|
||||
private:
|
||||
fc::process _proc;
|
||||
fc::json::rpc_stream_connection::ptr _con;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace fc {
|
|||
~rpc_stream_connection();
|
||||
virtual void send_invoke( uint64_t id, const fc::string& m, value&& param );
|
||||
virtual void send_notice( const fc::string& m, value&& param );
|
||||
virtual void send_error( uint64_t id, int64_t code, const fc::string& msg );
|
||||
virtual void send_error( uint64_t id, const error_object& eo );
|
||||
virtual void send_result( uint64_t id, value&& r );
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <fc/exception.hpp>
|
||||
#include <fc/typename.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
|
|
@ -79,8 +80,7 @@ struct reflector{
|
|||
#endif
|
||||
//#include <boost/typeof/typeof.hpp>
|
||||
#define FC_REFLECT_VISIT_MEMBER( r, visitor, elem ) \
|
||||
|
||||
// visitor.TEMPLATE operator()<decltype(((type*)0)->elem), type, &type::elem>( BOOST_PP_STRINGIZE(elem) );
|
||||
visitor.TEMPLATE operator()<decltype(((type*)0)->elem), type, &type::elem>( BOOST_PP_STRINGIZE(elem) );
|
||||
|
||||
|
||||
#define FC_REFLECT_BASE_MEMBER_COUNT( r, OP, elem ) \
|
||||
|
|
@ -147,6 +147,7 @@ template<> struct reflector<ENUM> { \
|
|||
*/
|
||||
#define FC_REFLECT_DERIVED( TYPE, INHERITS, MEMBERS ) \
|
||||
namespace fc { \
|
||||
template<> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \
|
||||
template<> struct reflector<TYPE> {\
|
||||
typedef TYPE type; \
|
||||
typedef fc::true_type is_defined; \
|
||||
|
|
@ -172,6 +173,7 @@ template<> struct reflector<TYPE> {\
|
|||
|
||||
#define FC_REFLECT_FWD( TYPE ) \
|
||||
namespace fc { \
|
||||
template<> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \
|
||||
template<> struct reflector<TYPE> {\
|
||||
typedef TYPE type; \
|
||||
typedef fc::true_type is_defined; \
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ shared_impl<T>::shared_impl( U&& u ):_impl(fc::forward<U>(u)){}
|
|||
|
||||
template<typename T>
|
||||
shared_impl<T>::shared_impl( const shared_impl<T>& u ):_impl(u._impl){}
|
||||
template<typename T>
|
||||
shared_impl<T>::shared_impl( shared_impl<T>& u ):_impl(u._impl){}
|
||||
|
||||
template<typename T>
|
||||
shared_impl<T>::shared_impl( shared_impl<T>&& u ):_impl(fc::move(u._impl)){}
|
||||
|
|
@ -55,6 +57,8 @@ TYPE::TYPE( TYPE&& c )\
|
|||
:my(fc::move(c.my)){}\
|
||||
TYPE::TYPE( const TYPE& c )\
|
||||
:my(c.my){}\
|
||||
TYPE::TYPE( TYPE& c )\
|
||||
:my(c.my){}\
|
||||
TYPE::TYPE() \
|
||||
:my( new fc::shared_impl<TYPE>::impl( ) ){}\
|
||||
TYPE::~TYPE(){}\
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ namespace fc {
|
|||
shared_impl( U&& u );
|
||||
|
||||
shared_impl( const shared_impl& u );
|
||||
shared_impl( shared_impl& u );
|
||||
shared_impl( shared_impl&& u );
|
||||
shared_impl& operator=( shared_impl&& u );
|
||||
shared_impl& operator=( const shared_impl& u );
|
||||
|
|
@ -131,6 +132,7 @@ namespace fc {
|
|||
TYPE( TYPE* ); \
|
||||
TYPE( TYPE&& ); \
|
||||
TYPE( const TYPE& ); \
|
||||
TYPE( TYPE& ); \
|
||||
template<typename A1> \
|
||||
TYPE( A1&& ); \
|
||||
template<typename A1,typename A2> \
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ namespace fc {
|
|||
_ptr = p._ptr;
|
||||
if( _ptr ) _ptr->retain();
|
||||
}
|
||||
shared_ptr( shared_ptr& p ) {
|
||||
_ptr = p._ptr;
|
||||
if( _ptr ) _ptr->retain();
|
||||
}
|
||||
shared_ptr( shared_ptr&& p ) {
|
||||
_ptr = p._ptr;
|
||||
p._ptr = nullptr;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace fc {
|
|||
friend string operator + ( const string&, const string& );
|
||||
friend string operator + ( const string&, char c );
|
||||
|
||||
fc::string substr( int32_t start, int32_t len = 0x7fffffff );
|
||||
fc::string substr( int32_t start, int32_t len = 0x7fffffff )const;
|
||||
|
||||
private:
|
||||
fc::fwd<std::string,32> my;
|
||||
|
|
|
|||
|
|
@ -61,12 +61,13 @@ namespace fc {
|
|||
public:
|
||||
template<typename Functor>
|
||||
task( Functor&& f ):task_base(&_functor) {
|
||||
typedef typename fc::deduce<Functor>::type FunctorType;
|
||||
static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" );
|
||||
new ((char*)&_functor) Functor( fc::forward<Functor>(f) );
|
||||
_destroy_functor = &detail::functor_destructor<Functor>::destroy;
|
||||
new ((char*)&_functor) FunctorType( fc::forward<Functor>(f) );
|
||||
_destroy_functor = &detail::functor_destructor<FunctorType>::destroy;
|
||||
|
||||
_promise_impl = static_cast<promise<R>*>(this);
|
||||
_run_functor = &detail::functor_run<Functor>::run;
|
||||
_run_functor = &detail::functor_run<FunctorType>::run;
|
||||
}
|
||||
aligned<FunctorSize> _functor;
|
||||
private:
|
||||
|
|
@ -77,12 +78,13 @@ namespace fc {
|
|||
public:
|
||||
template<typename Functor>
|
||||
task( Functor&& f ):task_base(&_functor) {
|
||||
typedef typename fc::deduce<Functor>::type FunctorType;
|
||||
static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" );
|
||||
new ((char*)&_functor) Functor( fc::forward<Functor>(f) );
|
||||
_destroy_functor = &detail::functor_destructor<Functor>::destroy;
|
||||
new ((char*)&_functor) FunctorType( fc::forward<Functor>(f) );
|
||||
_destroy_functor = &detail::functor_destructor<FunctorType>::destroy;
|
||||
|
||||
_promise_impl = static_cast<promise<void>*>(this);
|
||||
_run_functor = &detail::void_functor_run<Functor>::run;
|
||||
_run_functor = &detail::void_functor_run<FunctorType>::run;
|
||||
}
|
||||
aligned<FunctorSize> _functor;
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -52,8 +52,9 @@ namespace fc {
|
|||
template<typename Functor>
|
||||
auto async( Functor&& f, const char* desc ="", priority prio = priority()) -> fc::future<decltype(f())> {
|
||||
typedef decltype(f()) Result;
|
||||
fc::task<Result,sizeof(Functor)>* tsk =
|
||||
new fc::task<Result,sizeof(Functor)>( fc::forward<Functor>(f) );
|
||||
typedef typename fc::deduce<Functor>::type FunctorType;
|
||||
fc::task<Result,sizeof(FunctorType)>* tsk =
|
||||
new fc::task<Result,sizeof(FunctorType)>( fc::forward<Functor>(f) );
|
||||
fc::future<Result> r(fc::shared_ptr< fc::promise<Result> >(tsk,true) );
|
||||
async_task(tsk,prio,desc);
|
||||
return r;
|
||||
|
|
|
|||
40
include/fc/url.hpp
Normal file
40
include/fc/url.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
||||
typedef fc::optional<fc::string> ostring;
|
||||
|
||||
struct url {
|
||||
url(){}
|
||||
url( const string& url );
|
||||
/*
|
||||
url( const url& u );
|
||||
|
||||
url( url&& u );
|
||||
url& operator=(url&& c);
|
||||
url& operator=(const url& c);
|
||||
*/
|
||||
|
||||
operator string()const { return to_string(); }
|
||||
string to_string()const;
|
||||
url& from_string( const string& s );
|
||||
|
||||
bool operator==( const url& cmp )const;
|
||||
|
||||
string proto; // file, ssh, tcp, http, ssl, etc...
|
||||
ostring host;
|
||||
ostring user;
|
||||
ostring pass;
|
||||
ostring path;
|
||||
ostring args;
|
||||
fc::optional<uint16_t> port;
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::url, (proto)(host)(user)(pass)(path)(args)(port) )
|
||||
|
||||
|
|
@ -85,6 +85,7 @@ namespace fc {
|
|||
|
||||
value& operator=( value&& v );
|
||||
value& operator=( const value& v );
|
||||
value& operator=( value& v );
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@
|
|||
#include <fc/value_io.hpp>
|
||||
#include <fc/tuple.hpp>
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/typename.hpp>
|
||||
|
||||
#include <typeinfo>
|
||||
//#include <typeinfo>
|
||||
|
||||
namespace fc {
|
||||
|
||||
|
|
|
|||
|
|
@ -177,11 +177,12 @@ namespace fc {
|
|||
template<typename T>
|
||||
static inline void pack(fc::value& s, const T& v ) {
|
||||
v.did_not_implement_reflect_macro();
|
||||
wlog( "warning, ignoring unknown type" );
|
||||
}
|
||||
template<typename T>
|
||||
static inline void unpack( const fc::value& s, T& v ) {
|
||||
v.did_not_implement_reflect_macro();
|
||||
//wlog( "warning, ignoring unknown type" );
|
||||
wlog( "warning, ignoring unknown type" );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <fc/log.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/exception.hpp>
|
||||
#include <fc/error_report.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
|
@ -616,7 +617,7 @@ size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_dat
|
|||
//slog( "%s", base58_str.c_str() );
|
||||
std::vector<unsigned char> out;
|
||||
if( !DecodeBase58( base58_str.c_str(), out ) ) {
|
||||
FC_THROW_MSG( "Unable to decode base58 string '%s'", base58_str );
|
||||
FC_THROW_REPORT( "Unable to decode base58 string ${base58_str}", fc::value().set("base58_str",base58_str) );
|
||||
}
|
||||
|
||||
memcpy( out_data, out.data(), out.size() );
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ namespace fc {
|
|||
cur_task(0)
|
||||
{
|
||||
my_context.fc_stack.base = alloc.allocate( bc::default_stacksize() );
|
||||
// slog( "new stack %1% bytes at %2%", bc::default_stacksize(), my_context.fc_stack.base );
|
||||
my_context.fc_stack.limit =
|
||||
static_cast<char*>( my_context.fc_stack.base) - bc::default_stacksize();
|
||||
make_fcontext( &my_context, sf );
|
||||
|
|
|
|||
147
src/error_report.cpp
Normal file
147
src/error_report.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include <fc/error_report.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
#include <fc/sstream.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/json.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
namespace fc {
|
||||
|
||||
error_frame::error_frame( const fc::string& f, uint64_t l, const fc::string& m, const fc::string& d, fc::value met )
|
||||
:desc(d),file(fc::path(f).filename().generic_string()),line(l),method(m),meta(fc::move(met)){}
|
||||
|
||||
error_report::error_report()
|
||||
{
|
||||
}
|
||||
error_frame::error_frame(const fc::error_frame& e)
|
||||
:desc(e.desc),file(e.file),line(e.line),method(e.method),time(e.time),meta(e.meta){}
|
||||
|
||||
error_frame::error_frame(fc::error_frame&& e)
|
||||
:desc(fc::move(e.desc)),
|
||||
file(fc::move(e.file)),
|
||||
line(e.line),
|
||||
method(fc::move(e.method)),
|
||||
time(e.time),
|
||||
meta(fc::move(e.meta))
|
||||
{}
|
||||
|
||||
fc::error_frame& fc::error_frame::operator=(const fc::error_frame& f ) {
|
||||
auto tmp = f;
|
||||
fc_swap( tmp, *this );
|
||||
return *this;
|
||||
}
|
||||
fc::error_frame& fc::error_frame::operator=(fc::error_frame&& e )
|
||||
{
|
||||
desc=fc::move(e.desc);
|
||||
file=fc::move(e.file);
|
||||
line=fc::move(e.line);
|
||||
method=fc::move(e.method);
|
||||
time=e.time;
|
||||
meta=fc::move(e.meta);
|
||||
return *this;
|
||||
}
|
||||
|
||||
error_report::error_report( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta )
|
||||
{
|
||||
push_frame( file, line, method, desc, meta );
|
||||
}
|
||||
|
||||
|
||||
fc::error_frame& error_report::current()
|
||||
{
|
||||
if( !stack.size() ) stack.resize(1);
|
||||
return stack.back();
|
||||
}
|
||||
|
||||
fc::error_report& error_report::pop_frame()
|
||||
{
|
||||
stack.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
fc::error_report& error_report::push_frame( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta )
|
||||
{
|
||||
stack.push_back( fc::error_frame( file, line, method, desc, meta ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
fc::error_report& error_report::append( const error_report& e )
|
||||
{
|
||||
// TODO: what to do about the 'failure...?'
|
||||
stack.reserve( stack.size()+e.stack.size());
|
||||
for( uint32_t i = 0; i < e.stack.size(); ++i ) {
|
||||
stack.push_back( e.stack[i] );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
fc::string error_frame::to_detail_string()const {
|
||||
fc::stringstream ss;
|
||||
ss << to_string() << "\n\t";
|
||||
ss << file << ":" << line << "\t"<<method;
|
||||
if( meta ) ss << "\t" <<fc::json::to_string(*meta);
|
||||
return ss.str();
|
||||
}
|
||||
fc::string error_frame::to_string()const {
|
||||
fc::stringstream ss;
|
||||
int64_t prev = 0;
|
||||
auto next = desc.find( '$' );
|
||||
while( prev != int64_t(fc::string::npos) && prev < int64_t(desc.size()) ) {
|
||||
// slog( "prev: %d next %d %s", prev, next, desc.substr(prev,next).c_str() );
|
||||
// print everything from the last pos until the first '$'
|
||||
ss << desc.substr( prev, next-prev );
|
||||
|
||||
// if we got to the end, return it.
|
||||
if( next == string::npos ) { return ss.str(); }
|
||||
|
||||
// if we are not at the end, then update the start
|
||||
prev = next + 1;
|
||||
|
||||
if( desc[prev] == '{' ) {
|
||||
// if the next char is a open, then find close
|
||||
next = desc.find( '}', prev );
|
||||
// if we found close...
|
||||
if( next != fc::string::npos ) {
|
||||
// the key is between prev and next
|
||||
fc::string key = desc.substr( prev+1, (next-prev-1) );
|
||||
//slog( "key '%s'", key.c_str() );
|
||||
if( meta ) {
|
||||
auto itr = meta->find( key.c_str() );
|
||||
if( itr != meta->end() ) {
|
||||
ss << fc::json::to_string( itr->val );
|
||||
} else {
|
||||
ss << "???";
|
||||
}
|
||||
}
|
||||
prev = next + 1;
|
||||
// find the next $
|
||||
next = desc.find( '$', prev );
|
||||
} else {
|
||||
// we didn't find it.. continue to while...
|
||||
}
|
||||
} else {
|
||||
ss << desc[prev];
|
||||
++prev;
|
||||
next = desc.find( '$', prev );
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
fc::string error_report::to_string()const {
|
||||
fc::stringstream ss;
|
||||
for( int i = 0; i < stack.size(); ++i ) {
|
||||
ss << stack[i].to_string() << "\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
fc::string error_report::to_detail_string()const {
|
||||
fc::stringstream ss;
|
||||
for( int i = 0; i < stack.size(); ++i ) {
|
||||
ss << stack[i].to_detail_string() << "\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
fc::exception_ptr error_report::copy_exception() {
|
||||
return boost::copy_exception(*this);
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -94,6 +94,7 @@ namespace fc {
|
|||
void copy( const path& f, const path& t ) { boost::filesystem::copy( f, t ); }
|
||||
bool remove( const path& f ) { return boost::filesystem::remove( f ); }
|
||||
fc::path canonical( const fc::path& p ) { return boost::filesystem::canonical(p); }
|
||||
fc::path absolute( const fc::path& p ) { return boost::filesystem::absolute(p); }
|
||||
path unique_path() { return boost::filesystem::unique_path(); }
|
||||
path temp_directory_path() { return boost::filesystem::temp_directory_path(); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
FC_START_SHARED_IMPL(fc::http::connection)
|
||||
fc::tcp_socket sock;
|
||||
fc::ip::endpoint ep;
|
||||
impl() {
|
||||
}
|
||||
|
||||
int read_until( char* buffer, char* end, char c = '\n' ) {
|
||||
char* p = buffer;
|
||||
|
|
@ -114,16 +116,42 @@ http::reply connection::request( const fc::string& method,
|
|||
}
|
||||
|
||||
// used for servers
|
||||
fc::tcp_socket& connection::get_socket() {
|
||||
fc::tcp_socket& connection::get_socket()const {
|
||||
return my->sock;
|
||||
}
|
||||
|
||||
http::request connection::read_request() {
|
||||
http::request r;
|
||||
return r;
|
||||
}
|
||||
void connection::send_reply( const http::reply& ) {
|
||||
http::request connection::read_request()const {
|
||||
http::request req;
|
||||
fc::vector<char> line(1024*8);
|
||||
int s = my->read_until( line.data(), line.data()+line.size(), ' ' ); // METHOD
|
||||
req.method = line.data();
|
||||
s = my->read_until( line.data(), line.data()+line.size(), ' ' ); // PATH
|
||||
req.path = line.data();
|
||||
s = my->read_until( line.data(), line.data()+line.size(), '\n' ); // HTTP/1.0
|
||||
|
||||
while( (s = my->read_until( line.data(), line.data()+line.size(), '\n' )) > 1 ) {
|
||||
fc::http::header h;
|
||||
char* end = line.data();
|
||||
while( *end != ':' )++end;
|
||||
h.key = fc::string(line.data(),end);
|
||||
++end; // skip ':'
|
||||
++end; // skip space
|
||||
char* skey = end;
|
||||
while( *end != '\r' ) ++end;
|
||||
h.val = fc::string(skey,end);
|
||||
req.headers.push_back(h);
|
||||
if( h.key == "Content-Length" ) {
|
||||
req.body.resize( fc::lexical_cast<int>( fc::string(h.val) ) );
|
||||
}
|
||||
if( h.key == "Host" ) {
|
||||
req.domain = h.val;
|
||||
}
|
||||
}
|
||||
if( req.body.size() ) {
|
||||
slog( "Reading body size %d", req.body.size() );
|
||||
my->sock.read( req.body.data(), req.body.size() );
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
} } // fc::http
|
||||
|
|
|
|||
151
src/http_server.cpp
Normal file
151
src/http_server.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#include <fc/http/server.hpp>
|
||||
#include <fc/thread.hpp>
|
||||
#include <fc/tcp_socket.hpp>
|
||||
#include <fc/sstream.hpp>
|
||||
|
||||
|
||||
namespace fc { namespace http {
|
||||
|
||||
class server::response::impl : public fc::retainable {
|
||||
public:
|
||||
impl( const fc::http::connection& c, const std::function<void()>& cont = std::function<void()>() )
|
||||
:body_bytes_sent(0),body_length(0),con(c),handle_next_req(cont)
|
||||
{}
|
||||
|
||||
void send_header() {
|
||||
fc::stringstream ss;
|
||||
ss << "HTTP/1.1 " << rep.status << " ";
|
||||
switch( rep.status ) {
|
||||
case fc::http::reply::OK: ss << "OK\n\r"; break;
|
||||
case fc::http::reply::RecordCreated: ss << "Record Created\n\r"; break;
|
||||
case fc::http::reply::NotFound: ss << "Not Found\n\r"; break;
|
||||
case fc::http::reply::Found: ss << "Found\n\r"; break;
|
||||
case fc::http::reply::InternalServerError: ss << "Internal Server Error\r\n"; break;
|
||||
}
|
||||
for( uint32_t i = 0; i < rep.headers.size(); ++i ) {
|
||||
ss << rep.headers[i].key <<": "<<rep.headers[i].val <<"\r\n";
|
||||
}
|
||||
ss << "Content-Length: "<<body_length<<"\r\n\r\n";
|
||||
auto s = ss.str();
|
||||
con.get_socket().write( s.c_str(), s.size() );
|
||||
}
|
||||
|
||||
http::reply rep;
|
||||
int64_t body_bytes_sent;
|
||||
uint64_t body_length;
|
||||
http::connection con;
|
||||
std::function<void()> handle_next_req;
|
||||
};
|
||||
|
||||
|
||||
class server::impl : public fc::retainable {
|
||||
public:
|
||||
impl(){}
|
||||
impl(uint16_t p ) {
|
||||
tcp_serv.listen(p);
|
||||
accept_complete = fc::async([this](){ this->accept_loop(); });
|
||||
}
|
||||
fc::future<void> accept_complete;
|
||||
~impl() {
|
||||
try {
|
||||
tcp_serv.close();
|
||||
accept_complete.wait();
|
||||
}catch(...){}
|
||||
}
|
||||
void accept_loop() {
|
||||
try {
|
||||
http::connection con;
|
||||
while( tcp_serv.accept( con.get_socket() ) ) {
|
||||
slog( "Accept Connection" );
|
||||
fc::async( [=](){ handle_connection( con, on_req ); } );
|
||||
con = http::connection();
|
||||
}
|
||||
} catch ( ... ) {
|
||||
wlog( "tcp listen failed...%s", fc::except_str().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
void handle_connection( const http::connection& c,
|
||||
std::function<void(const http::request&, const server::response& s )> do_on_req ) {
|
||||
wlog( "reading request.." );
|
||||
try {
|
||||
http::server::response rep( fc::shared_ptr<response::impl>( new response::impl(c, [=](){ this->handle_connection(c,do_on_req); } ) ) );
|
||||
auto req = c.read_request();
|
||||
if( do_on_req ) do_on_req( req, rep );
|
||||
} catch ( ... ) {
|
||||
wlog( "unable to read request %s", fc::except_str().c_str());
|
||||
}
|
||||
}
|
||||
std::function<void(const http::request&, const server::response& s )> on_req;
|
||||
fc::tcp_server tcp_serv;
|
||||
};
|
||||
|
||||
|
||||
|
||||
server::server(){}
|
||||
server::server( uint16_t port ) :my( new impl(port) ){}
|
||||
server::server( const server& s ):my(s.my){}
|
||||
server::server( server&& s ):my(fc::move(s.my)){}
|
||||
|
||||
server& server::operator=(const server& s) { my = s.my; return *this; }
|
||||
server& server::operator=(server&& s) { fc_swap(my,s.my); return *this; }
|
||||
|
||||
server::~server(){}
|
||||
|
||||
void server::listen( uint16_t p ) {
|
||||
my.reset( new impl(p) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
server::response::response(){}
|
||||
server::response::response( const server::response& s ):my(s.my){}
|
||||
server::response::response( server::response&& s ):my(fc::move(s.my)){}
|
||||
server::response::response( const fc::shared_ptr<server::response::impl>& m ):my(m){}
|
||||
|
||||
server::response& server::response::operator=(const server::response& s) { my = s.my; return *this; }
|
||||
server::response& server::response::operator=(server::response&& s) { fc_swap(my,s.my); return *this; }
|
||||
|
||||
void server::response::add_header( const fc::string& key, const fc::string& val )const {
|
||||
wlog( "Attempt to add header after sending headers" );
|
||||
my->rep.headers.push_back( fc::http::header( key, val ) );
|
||||
}
|
||||
void server::response::set_status( const http::reply::status_code& s )const {
|
||||
if( my->body_bytes_sent != 0 ) {
|
||||
wlog( "Attempt to set status after sending headers" );
|
||||
}
|
||||
my->rep.status = s;
|
||||
}
|
||||
void server::response::set_length( uint64_t s )const {
|
||||
if( my->body_bytes_sent != 0 ) {
|
||||
wlog( "Attempt to set length after sending headers" );
|
||||
}
|
||||
my->body_length = s;
|
||||
}
|
||||
void server::response::write( const char* data, uint64_t len )const {
|
||||
if( my->body_bytes_sent + len > my->body_length ) {
|
||||
wlog( "Attempt to send to many bytes.." );
|
||||
len = my->body_bytes_sent + len - my->body_length;
|
||||
}
|
||||
if( my->body_bytes_sent == 0 ) {
|
||||
my->send_header();
|
||||
}
|
||||
my->body_bytes_sent += len;
|
||||
my->con.get_socket().write( data, len );
|
||||
if( my->body_bytes_sent == int64_t(my->body_length) ) {
|
||||
if( my->handle_next_req ) {
|
||||
slog( "handle next request..." );
|
||||
//fc::async( std::function<void()>(my->handle_next_req) );
|
||||
fc::async( my->handle_next_req );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server::response::~response(){}
|
||||
void server::on_request( const std::function<void(const http::request&, const server::response& s )>& cb )
|
||||
{ my->on_req = cb; }
|
||||
|
||||
|
||||
|
||||
|
||||
} }
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include <fc/sstream.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
#include <fc/interprocess/file_mapping.hpp>
|
||||
#include <fc/error_report.hpp>
|
||||
#include <map>
|
||||
|
||||
|
||||
|
|
@ -918,15 +919,17 @@ fc::string pretty_print( fc::vector<char>&& v, uint8_t indent ) {
|
|||
|
||||
value from_file( const fc::path& local_path ) {
|
||||
if( !exists(local_path) ) {
|
||||
FC_THROW_MSG( "Source file '%s' does not exist", local_path.string() );
|
||||
FC_THROW_REPORT( "Source file ${filename} does not exist", value().set("filename",local_path.string()) );
|
||||
}
|
||||
if( is_directory( local_path ) ) {
|
||||
FC_THROW_MSG( "Source path '%s' is a directory, expected a file.", local_path.string() );
|
||||
FC_THROW_REPORT( "Source path ${path} is a directory; a file was expected",
|
||||
value().set("path",local_path.string()) );
|
||||
}
|
||||
|
||||
// memory map the file
|
||||
file_mapping fmap( local_path.string().c_str(), read_only );
|
||||
size_t fsize = static_cast<size_t>(file_size(local_path));
|
||||
if( fsize == 0 ) { return value(); }
|
||||
file_mapping fmap( local_path.string().c_str(), read_only );
|
||||
|
||||
|
||||
mapped_region mr( fmap, fc::read_only, 0, fsize );
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#include <fc/log.hpp>
|
||||
#include <fc/thread.hpp>
|
||||
#include <fc/error.hpp>
|
||||
#include <fc/error_report.hpp>
|
||||
#include <fc/json_rpc_error_object.hpp>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -57,7 +59,7 @@ namespace fc { namespace json {
|
|||
if( id_itr != end ) {
|
||||
// TODO: send invalid method reply
|
||||
auto id = value_cast<uint64_t>(id_itr->val);
|
||||
send_error( id, -1, "Unknown method '"+mname+"'");
|
||||
send_error( id, fc::json::error_object( "Unknown method '"+mname+"'" ));
|
||||
}
|
||||
// nothing to do, unknown method
|
||||
} else { // known method, attempt to call it and send reply;
|
||||
|
|
@ -65,14 +67,22 @@ namespace fc { namespace json {
|
|||
|
||||
value nul;
|
||||
const value& params = (p_itr != end) ? p_itr->val : nul;
|
||||
slog( "params '%s'", to_string( params ).c_str() );
|
||||
// slog( "params '%s'", to_string( params ).c_str() );
|
||||
|
||||
if( id_itr != end ) { // capture reply
|
||||
auto id = value_cast<uint64_t>(id_itr->val);
|
||||
try {
|
||||
send_result( id, smeth->second->call(params) );
|
||||
} catch ( fc::error_report& eo ) {
|
||||
if( eo.stack.size() ) {
|
||||
send_error( id, error_object( eo.current().desc, fc::value(eo) ) );
|
||||
} else {
|
||||
send_error( id, error_object( "error report", fc::value(eo) ) );
|
||||
}
|
||||
} catch ( const fc::json::error_object& eo ) {
|
||||
send_error( id, eo );
|
||||
} catch ( ... ) {
|
||||
send_error( id, -1, fc::except_str() );
|
||||
send_error( id, error_object( fc::except_str(), fc::value() ) );
|
||||
}
|
||||
} else { // ignore exception + result
|
||||
try { smeth->second->call( params ); }catch(...){}
|
||||
|
|
@ -96,13 +106,11 @@ namespace fc { namespace json {
|
|||
} else {
|
||||
auto e_itr = v.find( "error" );
|
||||
if( e_itr != end ) {
|
||||
cur->set_exception(
|
||||
fc::copy_exception(
|
||||
fc::generic_exception(
|
||||
value_cast<fc::string>(
|
||||
e_itr->val["message"] ) ) ) );
|
||||
cur->set_exception( fc::value_cast<error_report>(e_itr->val["data"]).copy_exception() );
|
||||
} else {
|
||||
elog( "no result nor error field" );
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch( ... ) {
|
||||
cur->set_exception( fc::current_exception() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
#include <fc/json_rpc_error_object.hpp>
|
||||
#include <fc/json.hpp>
|
||||
|
||||
|
||||
namespace fc { namespace json {
|
||||
error_object::error_object( const fc::string& m, fc::value v, int64_t c )
|
||||
:code(c),message(m),data(fc::move(v)){}
|
||||
error_object::error_object( const fc::string& m, const fc::value& v, int64_t c )
|
||||
:code(c),message(m),data(v){ }
|
||||
error_object::error_object(const fc::string& m, int64_t c)
|
||||
:code(c),message(m){ }
|
||||
error_object::error_object(const error_object& e)
|
||||
:code(e.code),message(e.message),data(e.data){}
|
||||
error_object::~error_object(){}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <fc/json_rpc_stream_connection.hpp>
|
||||
#include <fc/json_rpc_error_object.hpp>
|
||||
#include <fc/iostream.hpp>
|
||||
#include <fc/sstream.hpp>
|
||||
#include <fc/thread.hpp>
|
||||
|
|
@ -27,21 +28,24 @@ namespace fc { namespace json {
|
|||
|
||||
fc::future<void> _read_loop_complete;
|
||||
void read_loop() {
|
||||
fc::string line;
|
||||
fc::getline( in, line );
|
||||
while( !in.eof() ) {
|
||||
try {
|
||||
fc::value v= fc::json::from_string( line );
|
||||
//slog( "%s", fc::json::to_string(v).c_str() );
|
||||
self.handle_message(v);
|
||||
} catch (...) {
|
||||
wlog( "%s", fc::except_str().c_str() );
|
||||
return;
|
||||
}
|
||||
fc::getline( in, line );
|
||||
}
|
||||
self.cancel_pending_requests();
|
||||
if( !!on_close ) on_close();
|
||||
try {
|
||||
fc::string line;
|
||||
fc::getline( in, line );
|
||||
while( !in.eof() ) {
|
||||
try {
|
||||
fc::value v= fc::json::from_string( line );
|
||||
self.handle_message(v);
|
||||
} catch (...) {
|
||||
wlog( "%s", fc::except_str().c_str() );
|
||||
return;
|
||||
}
|
||||
fc::getline( in, line );
|
||||
}
|
||||
} catch ( ... ) {
|
||||
wlog( "%s", fc::except_str().c_str() );
|
||||
}
|
||||
self.cancel_pending_requests();
|
||||
if( !!on_close ) on_close();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -79,24 +83,28 @@ namespace fc { namespace json {
|
|||
ss<<"{\"id\":"<<id<<",\"method\":\""<<m<<"\",\"params\":"<<fc::json::to_string(param)<<"}\n";
|
||||
fc::string o = ss.str();
|
||||
my->out.write( o.c_str(), o.size() );
|
||||
my->out.flush();
|
||||
}
|
||||
void rpc_stream_connection::send_notice( const fc::string& m, value&& param ) {
|
||||
fc::stringstream ss;
|
||||
ss<<"{\"method\":\""<<m<<"\",\"params\":"<<fc::json::to_string(param)<<"}\n";
|
||||
fc::string o = ss.str();
|
||||
my->out.write( o.c_str(), o.size() );
|
||||
my->out.flush();
|
||||
}
|
||||
void rpc_stream_connection::send_error( uint64_t id, int64_t code, const fc::string& msg ) {
|
||||
void rpc_stream_connection::send_error( uint64_t id, const json::error_object& eo ) {
|
||||
fc::stringstream ss;
|
||||
ss<<"{\"id\":"<<id<<",\"error\":{\"code\":"<<code<<",\"message\":"<<fc::json::to_string(fc::value(msg))<<"}}\n";
|
||||
ss<<"{\"id\":"<<id<<",\"error\":"<<fc::json::to_string(eo)<<"}\n";
|
||||
fc::string o = ss.str();
|
||||
my->out.write( o.c_str(), o.size() );
|
||||
my->out.flush();
|
||||
}
|
||||
void rpc_stream_connection::send_result( uint64_t id, value&& r ) {
|
||||
fc::stringstream ss;
|
||||
ss<<"{\"id\":"<<id<<",\"result\":"<<fc::json::to_string(r)<<"}\n";
|
||||
fc::string o = ss.str();
|
||||
my->out.write( o.c_str(), o.size() );
|
||||
my->out.flush();
|
||||
}
|
||||
|
||||
} } // fc::json
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fc/filesystem.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace fc {
|
||||
const char* thread_name();
|
||||
void* thread_ptr();
|
||||
|
||||
/*
|
||||
const char* short_name( const char* file_name ) {
|
||||
const char* end = file_name + strlen(file_name);
|
||||
--end;
|
||||
|
|
@ -25,6 +27,7 @@ namespace fc {
|
|||
}
|
||||
return file_name;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#define isatty _isatty
|
||||
|
|
@ -39,7 +42,7 @@ namespace fc {
|
|||
std::cerr<<"\r"<<color;
|
||||
#endif
|
||||
|
||||
fprintf( stderr, "%-15s %-15s %-5zd %-15s ", thread_name(), short_name(file_name), line_num, method_name );
|
||||
fprintf( stderr, "%-15s %-15s %-5zd %-15s ", thread_name(), fc::path(file_name).filename().generic_string().c_str(), line_num, method_name );
|
||||
//std::cerr<<thread_ptr()<< thread_name()<< short_name(file_name)<< line_num<< method_name ;
|
||||
va_list args;
|
||||
va_start(args,format);
|
||||
|
|
|
|||
|
|
@ -43,9 +43,13 @@ namespace fc {
|
|||
try {
|
||||
return static_cast<std::streamsize>(fc::asio::read_some( *m_pi, boost::asio::buffer( s, static_cast<size_t>(n) ) ));
|
||||
} catch ( const boost::system::system_error& e ) {
|
||||
wlog( "%s", fc::except_str().c_str() );
|
||||
if( e.code() == boost::asio::error::eof )
|
||||
return -1;
|
||||
throw;
|
||||
} catch ( ... ) {
|
||||
wlog( "%s", fc::except_str().c_str() );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
|
@ -69,9 +73,13 @@ FC_START_SHARED_IMPL( fc::process )
|
|||
if( inp ) {
|
||||
inp->close();
|
||||
}
|
||||
child->terminate();
|
||||
if( _exited.valid() && !_exited.ready()) {
|
||||
slog( "terminate...");
|
||||
child->terminate();
|
||||
_exited.wait();
|
||||
}
|
||||
}catch(...) {
|
||||
wlog( "caught exception cleaning up process" );
|
||||
wlog( "caught exception cleaning up process: %s", fc::except_str().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +96,8 @@ FC_START_SHARED_IMPL( fc::process )
|
|||
io::stream<fc::process_source> std_err;
|
||||
io::stream<fc::process_sink> std_in;
|
||||
|
||||
fc::future<int> _exited;
|
||||
|
||||
// adapt to ostream and istream interfaces
|
||||
fc::ostream_wrapper _ins;
|
||||
fc::istream_wrapper _outs;
|
||||
|
|
@ -163,8 +173,7 @@ fc::future<int> process::exec( const fc::path& exe, fc::vector<fc::string>&& arg
|
|||
}
|
||||
else p->set_exception( fc::copy_exception( boost::system::system_error(ec) ) );
|
||||
});
|
||||
return p;
|
||||
|
||||
return my->_exited = p;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace fc {
|
|||
void string::clear() { my->clear(); }
|
||||
void string::resize( uint64_t s ) { my->resize(s); }
|
||||
|
||||
fc::string string::substr( int32_t start, int32_t len ) { return my->substr(start,len); }
|
||||
fc::string string::substr( int32_t start, int32_t len )const { return my->substr(start,len); }
|
||||
const char* string::c_str()const { return my->c_str(); }
|
||||
|
||||
bool string::operator == ( const char* s )const { return *my == s; }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace fc {
|
|||
|
||||
class tcp_socket::impl {
|
||||
public:
|
||||
impl():_sock( fc::asio::default_io_service() ){ }
|
||||
impl():_sock( fc::asio::default_io_service() ){ }
|
||||
~impl(){
|
||||
if( _sock.is_open() ) _sock.close();
|
||||
}
|
||||
|
|
@ -85,7 +85,9 @@ namespace fc {
|
|||
|
||||
class tcp_server::impl {
|
||||
public:
|
||||
impl(uint16_t port):_accept( fc::asio::default_io_service(), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port) ){}
|
||||
impl(uint16_t port):
|
||||
_accept( fc::asio::default_io_service(), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port) ){
|
||||
}
|
||||
~impl(){
|
||||
_accept.close();
|
||||
}
|
||||
|
|
@ -105,7 +107,8 @@ namespace fc {
|
|||
|
||||
|
||||
bool tcp_server::accept( tcp_socket& s ) {
|
||||
fc::promise<boost::system::error_code>::ptr p( new promise<boost::system::error_code>("mace::cmt::asio::tcp::accept") );
|
||||
if( !my ) return false;
|
||||
fc::promise<boost::system::error_code>::ptr p( new promise<boost::system::error_code>("tcp::accept") );
|
||||
my->_accept.async_accept( s.my->_sock, [=]( const boost::system::error_code& e ) {
|
||||
p->set_value(e);
|
||||
} );
|
||||
|
|
|
|||
103
src/url.cpp
Normal file
103
src/url.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#include <fc/url.hpp>
|
||||
#include <fc/Value.hpp>
|
||||
#include <fc/error_report.hpp>
|
||||
#include <fc/lexical_cast.hpp>
|
||||
#include <fc/value_cast.hpp>
|
||||
#include <fc/sstream.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
// url::url( const url& u );
|
||||
#if 0
|
||||
url::url( url&& u )
|
||||
:proto(fc::move(u.proto)),
|
||||
host(fc::move(u.host)),
|
||||
user(fc::move(u.user)),
|
||||
pass(fc::move(u.pass)),
|
||||
path(fc::move(u.path)),
|
||||
args(fc::move(u.args)),
|
||||
port(u.port){}
|
||||
|
||||
url& url::operator=(url&& c)
|
||||
{
|
||||
fc::swap(*this,c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// url::url& operator=(const url& c) {
|
||||
// }
|
||||
#endif
|
||||
url::url( const string& s ) {
|
||||
from_string(s);
|
||||
}
|
||||
string url::to_string()const {
|
||||
fc::stringstream ss;
|
||||
ss<<proto<<"://";
|
||||
if( user ) {
|
||||
ss << *user;
|
||||
if( pass ) {
|
||||
ss<<":"<<*pass;
|
||||
}
|
||||
ss<<"@";
|
||||
}
|
||||
ss<<*host;
|
||||
if( port ) ss<<":"<<*port;
|
||||
if( path ) ss<<"/"<<*path;
|
||||
if( args ) ss<<"?"<<*args;
|
||||
return ss.str();
|
||||
}
|
||||
/**
|
||||
* proto://user:pass@host:port/~/path?args
|
||||
* proto://user:pass@host:port/absolute?args
|
||||
*/
|
||||
url& url::from_string( const string& s ) {
|
||||
fc::stringstream ss(s);
|
||||
fc::string _proto,skip,_user,_pass,_host,_port,_path,_args;
|
||||
fc::getline( ss, _proto, ':' );
|
||||
fc::getline( ss, skip, '/' );
|
||||
fc::getline( ss, skip, '/' );
|
||||
if( s.find('@') != fc::string::npos ) {
|
||||
fc::string user_pass;
|
||||
fc::getline( ss, user_pass, '@' );
|
||||
fc::stringstream upss(user_pass);
|
||||
if( user_pass.find( ':' ) != fc::string::npos ) {
|
||||
fc::getline( upss, _user, ':' );
|
||||
fc::getline( upss, _pass, ':' );
|
||||
user = fc::move(_user);
|
||||
pass = fc::move(_pass);
|
||||
} else {
|
||||
user = fc::move(user_pass);
|
||||
}
|
||||
}
|
||||
fc::string host_port;
|
||||
fc::getline( ss, host_port, '/' );
|
||||
auto pos = host_port.find( ':' );
|
||||
if( pos != fc::string::npos ) {
|
||||
try {
|
||||
port = fc::lexical_cast<uint16_t>( host_port.substr( pos+1 ) );
|
||||
} catch ( ... ) {
|
||||
FC_THROW_REPORT( "Unable to parse port field in url", value().set( "url", s ) );
|
||||
}
|
||||
host = host_port.substr(0,pos);
|
||||
} else {
|
||||
host = fc::move(host_port);
|
||||
}
|
||||
fc::getline( ss, _path, '?' );
|
||||
fc::getline( ss, _args );
|
||||
path = fc::move(_path);
|
||||
if( _args.size() ) args = fc::move(_args);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool url::operator==( const url& cmp )const {
|
||||
return cmp.proto == proto &&
|
||||
cmp.host == host &&
|
||||
cmp.user == user &&
|
||||
cmp.pass == pass &&
|
||||
cmp.path == path &&
|
||||
cmp.args == args &&
|
||||
cmp.port == port;
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -276,6 +276,12 @@ value& value::operator=( const value& v ){
|
|||
gh(v.holder)->copy_helper(holder);
|
||||
return *this;
|
||||
}
|
||||
value& value::operator=( value& v ){
|
||||
if( this == &v ) return *this;
|
||||
gh(holder)->~value_holder();
|
||||
gh(v.holder)->copy_helper(holder);
|
||||
return *this;
|
||||
}
|
||||
bool value::is_null()const {
|
||||
return strcmp(gh(holder)->type(), "void") == 0;
|
||||
}
|
||||
|
|
|
|||
25
vendor/boost/process/include/boost/process.hpp
vendored
25
vendor/boost/process/include/boost/process.hpp
vendored
|
|
@ -1,25 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process.hpp
|
||||
*
|
||||
* Convenience header that includes all public Boost.Process header files.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_HPP
|
||||
#define BOOST_PROCESS_HPP
|
||||
|
||||
#include <boost/process/all.hpp>
|
||||
|
||||
#endif
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/all.hpp
|
||||
*
|
||||
* Convenience header that includes all public Boost.Process header files.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_ALL_HPP
|
||||
#define BOOST_PROCESS_ALL_HPP
|
||||
|
||||
#include <boost/process/child.hpp>
|
||||
#include <boost/process/context.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <boost/process/handle.hpp>
|
||||
#include <boost/process/operations.hpp>
|
||||
#include <boost/process/pid_type.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/pistream.hpp>
|
||||
#include <boost/process/postream.hpp>
|
||||
#include <boost/process/process.hpp>
|
||||
#include <boost/process/self.hpp>
|
||||
#include <boost/process/status.hpp>
|
||||
#include <boost/process/stream_behavior.hpp>
|
||||
#include <boost/process/stream_ends.hpp>
|
||||
#include <boost/process/stream_id.hpp>
|
||||
#include <boost/process/stream_type.hpp>
|
||||
|
||||
#endif
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/child.hpp
|
||||
*
|
||||
* Includes the declaration of the child class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_CHILD_HPP
|
||||
#define BOOST_PROCESS_CHILD_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/process/process.hpp>
|
||||
#include <boost/process/pid_type.hpp>
|
||||
#include <boost/process/stream_id.hpp>
|
||||
#include <boost/process/handle.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* The child class provides access to a child process.
|
||||
*/
|
||||
class child : public process
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new child object that represents the just spawned child
|
||||
* process \a id.
|
||||
*/
|
||||
child(pid_type id, std::map<stream_id, handle> handles)
|
||||
: process(id),
|
||||
handles_(handles)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
/**
|
||||
* Creates a new child object that represents the just spawned child
|
||||
* process \a id.
|
||||
*
|
||||
* This operation is only available on Windows systems.
|
||||
*/
|
||||
child(handle hprocess, std::map<stream_id, handle> handles)
|
||||
: process(hprocess),
|
||||
handles_(handles)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gets a handle to a stream attached to the child.
|
||||
*
|
||||
* If the handle doesn't exist an invalid handle is returned.
|
||||
*/
|
||||
handle get_handle(stream_id id) const
|
||||
{
|
||||
std::map<stream_id, handle>::const_iterator it = handles_.find(id);
|
||||
return (it != handles_.end()) ? it->second : handle();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Handles providing access to streams attached to the child process.
|
||||
*/
|
||||
std::map<stream_id, handle> handles_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/config.hpp
|
||||
*
|
||||
* Defines macros that are used by the library to determine the operating
|
||||
* system it is running under and the features it supports.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_CONFIG_HPP
|
||||
#define BOOST_PROCESS_CONFIG_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/system/config.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <errno.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
|
||||
# if !defined(BOOST_PROCESS_POSIX_PATH_MAX) || defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Specifies the system's maximal supported path length.
|
||||
*
|
||||
* The macro BOOST_PROCESS_POSIX_PATH_MAX is set to a positive integer
|
||||
* value which specifies the system's maximal supported path length. It is
|
||||
* only used if neither PATH_MAX nor _PC_PATH_MAX and HAVE_PATHCONF are defined.
|
||||
* The maximal supported path length is required by
|
||||
* boost::process::self::get_work_dir(). Please note that this function is
|
||||
* also called by the constructor of boost::process::context.
|
||||
*/
|
||||
# define BOOST_PROCESS_POSIX_PATH_MAX 259
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** \cond */
|
||||
#define BOOST_PROCESS_SOURCE_LOCATION \
|
||||
"in file '" __FILE__ "', line " BOOST_STRINGIZE(__LINE__) ": "
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# define BOOST_PROCESS_LAST_ERROR errno
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# define BOOST_PROCESS_LAST_ERROR GetLastError()
|
||||
#endif
|
||||
|
||||
#define BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(what) \
|
||||
boost::throw_exception(boost::system::system_error( \
|
||||
boost::system::error_code(BOOST_PROCESS_LAST_ERROR, \
|
||||
boost::system::get_system_category()), \
|
||||
BOOST_PROCESS_SOURCE_LOCATION what))
|
||||
|
||||
#define BOOST_PROCESS_THROW_ERROR(error, what) \
|
||||
boost::throw_exception(boost::system::system_error( \
|
||||
boost::system::error_code(error, \
|
||||
boost::system::get_system_category()), \
|
||||
BOOST_PROCESS_SOURCE_LOCATION what))
|
||||
/** \endcond */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/context.hpp
|
||||
*
|
||||
* Includes the declaration of the context class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_CONTEXT_HPP
|
||||
#define BOOST_PROCESS_CONTEXT_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <unistd.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <boost/process/stream_id.hpp>
|
||||
#include <boost/process/stream_ends.hpp>
|
||||
#include <boost/process/stream_type.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <boost/process/self.hpp>
|
||||
#include <boost/process/stream_behavior.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Context class to define how a child process is created.
|
||||
*
|
||||
* The context class is used to configure streams, to set the work directory
|
||||
* and define environment variables. It is also used to change a process
|
||||
* name (the variable commonly known as argv[0]).
|
||||
*/
|
||||
struct context
|
||||
{
|
||||
typedef std::map<stream_id, boost::function<stream_ends (stream_type)> >
|
||||
streams_t;
|
||||
|
||||
/**
|
||||
* Streams.
|
||||
*
|
||||
* Streams of a child process can be configured through factory functions
|
||||
* which return a pair of handles - one handle to use as a stream end
|
||||
* in the child process and possibly another handle to use as a stream end
|
||||
* in the parent process (if a pipe is setup both processes can communicate
|
||||
* with each other).
|
||||
*/
|
||||
streams_t streams;
|
||||
|
||||
/**
|
||||
* Process name.
|
||||
*
|
||||
* The child process can access the process name via a variable
|
||||
* commonly known as argv[0].
|
||||
*/
|
||||
std::string process_name;
|
||||
|
||||
/**
|
||||
* Work directory.
|
||||
*/
|
||||
std::string work_dir;
|
||||
|
||||
/**
|
||||
* Environment variables.
|
||||
*/
|
||||
environment env;
|
||||
|
||||
/**
|
||||
* Constructs a process context.
|
||||
*
|
||||
* The default behavior of standard streams is to inherit them. The current
|
||||
* work directory is also the work directory of the child process. The child
|
||||
* process also inherits all environment variables.
|
||||
*/
|
||||
context()
|
||||
: work_dir(self::get_work_dir()),
|
||||
env(self::get_environment())
|
||||
{
|
||||
#if 0 // this default behavior will throw in non-console apps
|
||||
#if defined(BOOST_POSIX_API)
|
||||
streams[stdin_id] = behavior::inherit(STDIN_FILENO);
|
||||
streams[stdout_id] = behavior::inherit(STDOUT_FILENO);
|
||||
streams[stderr_id] = behavior::inherit(STDERR_FILENO);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
streams[stdin_id] = behavior::inherit(GetStdHandle(STD_INPUT_HANDLE));
|
||||
streams[stdout_id] = behavior::inherit(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
streams[stderr_id] = behavior::inherit(GetStdHandle(STD_ERROR_HANDLE));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Setups a child process.
|
||||
*
|
||||
* This is an extension point to support more configuration options for
|
||||
* child processes. You can initialize \a setup with a user-defined function
|
||||
* which is called when a child process is created.
|
||||
*
|
||||
* On POSIX platforms setup() is called in the child process. That's why in
|
||||
* a multithreaded application only async-signal-safe functions must be
|
||||
* called in the function \a setup is bound to.
|
||||
*
|
||||
* On Windows platforms setup() is called in the parent process. A
|
||||
* reference to a STARTUPINFOA structure is passed as parameter.
|
||||
*/
|
||||
boost::function<void ()> setup;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
boost::function<void (STARTUPINFOA&)> setup;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/detail/basic_status.hpp
|
||||
*
|
||||
* Includes the declaration of the basic status class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_DETAIL_BASIC_STATUS_HPP
|
||||
#define BOOST_PROCESS_DETAIL_BASIC_STATUS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
#include <boost/process/pid_type.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* The basic_status class to wait for processes to exit.
|
||||
*
|
||||
* The basic_status class is a Boost.Asio I/O object and supports synchronous
|
||||
* and asynchronous wait operations. It must be instantiated with a Service.
|
||||
*/
|
||||
template <typename Service>
|
||||
class basic_status
|
||||
: public boost::asio::basic_io_object<Service>
|
||||
{
|
||||
public:
|
||||
explicit basic_status(boost::asio::io_service &io_service)
|
||||
: boost::asio::basic_io_object<Service>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits synchronously for a process to exit.
|
||||
*/
|
||||
int wait(pid_type pid)
|
||||
{
|
||||
return this->service.wait(this->implementation, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits asynchronously for a process to exit.
|
||||
*/
|
||||
template <typename Handler>
|
||||
void async_wait(pid_type pid, Handler handler)
|
||||
{
|
||||
this->service.async_wait(this->implementation, pid, handler);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,318 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/detail/basic_status_service.hpp
|
||||
*
|
||||
* Includes the declaration of the basic status service class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_DETAIL_BASIC_STATUS_SERVICE_HPP
|
||||
#define BOOST_PROCESS_DETAIL_BASIC_STATUS_SERVICE_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <boost/process/operations.hpp>
|
||||
# include <string>
|
||||
# include <sys/types.h>
|
||||
# include <sys/wait.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/process/pid_type.hpp>
|
||||
#include <boost/process/detail/status_impl.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* The basic_status_service class provides the service to wait for processes
|
||||
* synchronously and asynchronously.
|
||||
*/
|
||||
template <typename StatusImplementation = status_impl>
|
||||
class basic_status_service
|
||||
: public boost::asio::detail::service_base<StatusImplementation>
|
||||
{
|
||||
public:
|
||||
explicit basic_status_service(boost::asio::io_service &io_service)
|
||||
: boost::asio::detail::service_base<StatusImplementation>(io_service),
|
||||
#if defined(BOOST_POSIX_API)
|
||||
interrupt_pid_(-1),
|
||||
pids_(0)
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
run_(true)
|
||||
#endif
|
||||
{
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
handles_.push_back(CreateEvent(NULL, FALSE, FALSE, NULL));
|
||||
if (handles_[0] == NULL)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateEvent() failed");
|
||||
work_thread_ = boost::thread(
|
||||
&basic_status_service<StatusImplementation>::work_thread, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
~basic_status_service()
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
bool worker_thread_active = (pids_ != 0);
|
||||
lock.unlock();
|
||||
if (worker_thread_active)
|
||||
{
|
||||
stop_work_thread();
|
||||
work_thread_.join();
|
||||
}
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
stop_work_thread();
|
||||
work_thread_.join();
|
||||
CloseHandle(handles_[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef boost::shared_ptr<StatusImplementation> implementation_type;
|
||||
|
||||
void construct(implementation_type &impl)
|
||||
{
|
||||
impl = boost::make_shared<StatusImplementation>();
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
impls_.push_back(impl);
|
||||
}
|
||||
|
||||
void destroy(implementation_type &impl)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
typename std::vector<implementation_type>::iterator it =
|
||||
std::find(impls_.begin(), impls_.end(), impl);
|
||||
if (it != impls_.end())
|
||||
impls_.erase(it);
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
interrupt_work_thread();
|
||||
work_thread_cond_.wait(work_thread_mutex_);
|
||||
impl->clear(handles_);
|
||||
work_thread_cond_.notify_all();
|
||||
#endif
|
||||
impl.reset();
|
||||
}
|
||||
|
||||
int wait(implementation_type &impl, pid_type pid)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
int status = impl->wait(pid, ec);
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (ec.value() == ECHILD)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
boost::unordered_map<pid_t, int>::iterator it = statuses_.find(pid);
|
||||
if (it == statuses_.end())
|
||||
{
|
||||
work_thread_cond_.wait(work_thread_mutex_);
|
||||
it = statuses_.find(pid);
|
||||
}
|
||||
if (it != statuses_.end())
|
||||
{
|
||||
status = it->second;
|
||||
statuses_.erase(it);
|
||||
ec.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
boost::asio::detail::throw_error(ec);
|
||||
return status;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void async_wait(implementation_type &impl, pid_type pid, Handler handler)
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
if (++pids_ == 1)
|
||||
{
|
||||
work_.reset(new boost::asio::io_service::work(
|
||||
this->get_io_service()));
|
||||
work_thread_ = boost::thread(
|
||||
&basic_status_service<StatusImplementation>::work_thread,
|
||||
this);
|
||||
}
|
||||
impl->async_wait(pid, this->get_io_service().wrap(handler));
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
HANDLE handle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
|
||||
FALSE, pid);
|
||||
if (handle == NULL)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
if (!work_)
|
||||
work_.reset(new boost::asio::io_service::work(
|
||||
this->get_io_service()));
|
||||
interrupt_work_thread();
|
||||
work_thread_cond_.wait(work_thread_mutex_);
|
||||
handles_.push_back(handle);
|
||||
impl->async_wait(handle, this->get_io_service().wrap(handler));
|
||||
work_thread_cond_.notify_all();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
void shutdown_service()
|
||||
{
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
work_.reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void work_thread()
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
for (;;)
|
||||
{
|
||||
int status;
|
||||
pid_t pid = ::wait(&status);
|
||||
if (pid == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("wait(2) failed");
|
||||
}
|
||||
else if (interrupted(pid))
|
||||
{
|
||||
// On POSIX the only reason to interrupt is to break out.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
bool regchild = false;
|
||||
for (typename std::vector<implementation_type>::iterator it =
|
||||
impls_.begin(); it != impls_.end(); ++it)
|
||||
regchild |= (*it)->complete(pid, status);
|
||||
if (regchild && --pids_ == 0)
|
||||
{
|
||||
work_.reset();
|
||||
break;
|
||||
}
|
||||
else if (!regchild)
|
||||
{
|
||||
statuses_.insert(boost::unordered_map<pid_t, int>::
|
||||
value_type(pid, status));
|
||||
work_thread_cond_.notify_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
for (;;)
|
||||
{
|
||||
DWORD res = WaitForMultipleObjects(handles_.size(), &handles_[0],
|
||||
FALSE, INFINITE);
|
||||
if (res == WAIT_FAILED)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"WaitForMultipleObjects() failed");
|
||||
else if (res - WAIT_OBJECT_0 == 0)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
if (!run_)
|
||||
break;
|
||||
work_thread_cond_.notify_all();
|
||||
work_thread_cond_.wait(work_thread_mutex_);
|
||||
}
|
||||
else if (res - WAIT_OBJECT_0 > 0)
|
||||
{
|
||||
HANDLE handle = handles_[res - WAIT_OBJECT_0];
|
||||
DWORD exit_code;
|
||||
if (!GetExitCodeProcess(handle, &exit_code))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"GetExitCodeProcess() failed");
|
||||
boost::unique_lock<boost::mutex> lock(work_thread_mutex_);
|
||||
for (typename std::vector<implementation_type>::iterator it =
|
||||
impls_.begin(); it != impls_.end(); ++it)
|
||||
(*it)->complete(handle, exit_code);
|
||||
std::vector<HANDLE>::iterator it = handles_.begin();
|
||||
std::advance(it, res - WAIT_OBJECT_0);
|
||||
handles_.erase(it);
|
||||
if (handles_.size() == 1)
|
||||
work_.reset();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void interrupt_work_thread()
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
// By creating a child process which immediately exits
|
||||
// we interrupt wait().
|
||||
std::vector<std::string> args;
|
||||
args.push_back("-c");
|
||||
args.push_back("'exit'");
|
||||
interrupt_pid_ = create_child("/bin/sh", args).get_id();
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
// By signaling the event in the first slot WaitForMultipleObjects()
|
||||
// will return. The work thread won't do anything except checking if
|
||||
// it should continue to run.
|
||||
if (!SetEvent(handles_[0]))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetEvent() failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
bool interrupted(pid_t pid)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(work_thread_mutex_);
|
||||
return interrupt_pid_ == pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
void stop_work_thread()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(work_thread_mutex_);
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
// Access to run_ must be sychronized with running().
|
||||
run_ = false;
|
||||
#endif
|
||||
// Access to interrupt_pid_ must be sychronized with interrupted().
|
||||
interrupt_work_thread();
|
||||
}
|
||||
|
||||
boost::scoped_ptr<boost::asio::io_service::work> work_;
|
||||
std::vector<implementation_type> impls_;
|
||||
boost::mutex work_thread_mutex_;
|
||||
boost::thread work_thread_;
|
||||
boost::condition_variable_any work_thread_cond_;
|
||||
#if defined(BOOST_POSIX_API)
|
||||
pid_t interrupt_pid_;
|
||||
int pids_;
|
||||
boost::unordered_map<pid_t, int> statuses_;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
bool run_;
|
||||
std::vector<HANDLE> handles_;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/detail/posix_helpers.hpp
|
||||
*
|
||||
* Includes the declaration of helper functions for POSIX systems.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_POSIX_HELPERS_HPP
|
||||
#define BOOST_PROCESS_POSIX_HELPERS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Converts an environment to a char** table as used by execve().
|
||||
*
|
||||
* Converts the environment's contents to the format used by the
|
||||
* execve() system call. The returned char** array is allocated
|
||||
* in dynamic memory; the caller must free it when not used any
|
||||
* more. Each entry is also allocated in dynamic memory and is a
|
||||
* NULL-terminated string of the form var=value; these must also be
|
||||
* released by the caller.
|
||||
*
|
||||
* This operation is only available on POSIX systems.
|
||||
*
|
||||
* \return The first argument of the pair is an integer that indicates
|
||||
* how many strings are stored in the second argument. The
|
||||
* second argument is a NULL-terminated, dynamically allocated
|
||||
* array of dynamically allocated strings representing the
|
||||
* enviroment's content. Each array entry is a NULL-terminated
|
||||
* string of the form var=value. The caller is responsible for
|
||||
* freeing them.
|
||||
*/
|
||||
inline std::pair<std::size_t, char**> environment_to_envp(const environment
|
||||
&env)
|
||||
{
|
||||
std::size_t nargs = env.size();
|
||||
char **envp = new char*[nargs + 1];
|
||||
environment::size_type i = 0;
|
||||
for (environment::const_iterator it = env.begin(); it != env.end(); ++it)
|
||||
{
|
||||
std::string s = it->first + "=" + it->second;
|
||||
envp[i] = new char[s.size() + 1];
|
||||
std::strncpy(envp[i], s.c_str(), s.size() + 1);
|
||||
++i;
|
||||
}
|
||||
envp[i] = 0;
|
||||
return std::pair<std::size_t, char**>(nargs, envp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the command line to an array of C strings.
|
||||
*
|
||||
* Converts the command line's list of arguments to the format expected
|
||||
* by the \a argv parameter in the POSIX execve() system call.
|
||||
*
|
||||
* This operation is only available on POSIX systems.
|
||||
*
|
||||
* \return The first argument of the pair is an integer that indicates
|
||||
* how many strings are stored in the second argument. The
|
||||
* second argument is a NULL-terminated, dynamically allocated
|
||||
* array of dynamically allocated strings holding the arguments
|
||||
* to the executable. The caller is responsible for freeing them.
|
||||
*/
|
||||
template <class Arguments>
|
||||
inline std::pair<std::size_t, char**> collection_to_argv(const Arguments &args)
|
||||
{
|
||||
std::size_t nargs = args.size();
|
||||
char **argv = new char*[nargs + 1];
|
||||
typename Arguments::size_type i = 0;
|
||||
for (typename Arguments::const_iterator it = args.begin(); it != args.end();
|
||||
++it)
|
||||
{
|
||||
argv[i] = new char[it->size() + 1];
|
||||
std::strncpy(argv[i], it->c_str(), it->size() + 1);
|
||||
++i;
|
||||
}
|
||||
argv[nargs] = 0;
|
||||
return std::pair<std::size_t, char**>(nargs, argv);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/detail/status_impl.hpp
|
||||
*
|
||||
* Includes the declaration of the status implementation class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_DETAIL_STATUS_IMPL_HPP
|
||||
#define BOOST_PROCESS_DETAIL_STATUS_IMPL_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <sys/types.h>
|
||||
# include <signal.h>
|
||||
# include <sys/wait.h>
|
||||
# include <errno.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/process/pid_type.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/ptr_container/ptr_unordered_map.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
typedef pid_t phandle;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
typedef HANDLE phandle;
|
||||
#endif
|
||||
|
||||
struct operation
|
||||
{
|
||||
virtual ~operation(){}
|
||||
virtual void operator()(int exit_code)
|
||||
{
|
||||
#if defined(BOOST_MSVC)
|
||||
exit_code;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Handler>
|
||||
class wrapped_handler : public operation
|
||||
{
|
||||
public:
|
||||
wrapped_handler(Handler handler)
|
||||
: handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(int exit_code)
|
||||
{
|
||||
handler_(boost::system::error_code(), exit_code);
|
||||
}
|
||||
|
||||
private:
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
/**
|
||||
* The status_impl class saves internal data of every status I/O object.
|
||||
*/
|
||||
class status_impl
|
||||
{
|
||||
public:
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
template <typename Container>
|
||||
void clear(Container &handles)
|
||||
{
|
||||
for (operations_type::iterator it = ops_.begin(); it != ops_.end();
|
||||
++it)
|
||||
{
|
||||
for (typename Container::iterator it2 = handles.begin(); it2 !=
|
||||
handles.end(); ++it2)
|
||||
{
|
||||
if (*it2 == it->first)
|
||||
{
|
||||
handles.erase(it2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseHandle(it->first);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int wait(pid_type pid, boost::system::error_code &ec)
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
pid_t p;
|
||||
int status;
|
||||
do
|
||||
{
|
||||
p = waitpid(pid, &status, 0);
|
||||
} while (p == -1 && errno == EINTR);
|
||||
if (p == -1)
|
||||
{
|
||||
ec = boost::system::error_code(errno,
|
||||
boost::system::get_system_category());
|
||||
return -1;
|
||||
}
|
||||
return status;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE,
|
||||
pid);
|
||||
if (h == NULL)
|
||||
{
|
||||
ec = boost::system::error_code(GetLastError(),
|
||||
boost::system::get_system_category());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
CloseHandle(h);
|
||||
ec = boost::system::error_code(GetLastError(),
|
||||
boost::system::get_system_category());
|
||||
return -1;
|
||||
}
|
||||
|
||||
DWORD exit_code;
|
||||
if (!GetExitCodeProcess(h, &exit_code))
|
||||
{
|
||||
CloseHandle(h);
|
||||
ec = boost::system::error_code(GetLastError(),
|
||||
boost::system::get_system_category());
|
||||
return -1;
|
||||
}
|
||||
if (!CloseHandle(h))
|
||||
{
|
||||
ec = boost::system::error_code(GetLastError(),
|
||||
boost::system::get_system_category());
|
||||
return -1;
|
||||
}
|
||||
return exit_code;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void async_wait(phandle ph, Handler handler)
|
||||
{
|
||||
ops_.insert(ph, new wrapped_handler<Handler>(handler));
|
||||
}
|
||||
|
||||
bool complete(phandle ph, int exit_code)
|
||||
{
|
||||
boost::iterator_range<operations_type::iterator> r =
|
||||
ops_.equal_range(ph);
|
||||
if (r.empty())
|
||||
return false;
|
||||
for (operations_type::iterator it = r.begin(); it != r.end(); ++it)
|
||||
(*it->second)(exit_code);
|
||||
ops_.erase(r.begin(), r.end());
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
if (!CloseHandle(ph))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef boost::ptr_unordered_multimap<phandle, operation> operations_type;
|
||||
operations_type ops_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/detail/systembuf.hpp
|
||||
*
|
||||
* Includes the declaration of the systembuf class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
|
||||
#define BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <streambuf>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
class postream;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* std::streambuf implementation for handles.
|
||||
*
|
||||
* systembuf provides a std::streambuf implementation for handles.
|
||||
* Contrarywise to the handle class, this class does \b not take
|
||||
* ownership of the native handle; this should be taken care of
|
||||
* somewhere else.
|
||||
*
|
||||
* This class follows the expected semantics of a std::streambuf object.
|
||||
* However, it is not copyable to avoid introducing inconsistences with
|
||||
* the on-disk file and the in-memory buffers.
|
||||
*/
|
||||
class systembuf : public std::streambuf, public boost::noncopyable
|
||||
{
|
||||
friend class boost::process::postream;
|
||||
|
||||
public:
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Opaque name for the native handle type.
|
||||
*/
|
||||
typedef NativeHandleType handle_type;
|
||||
#elif defined(BOOST_POSIX_API)
|
||||
typedef int handle_type;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
typedef HANDLE handle_type;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Constructs a new systembuf for the given handle.
|
||||
*
|
||||
* This constructor creates a new systembuf object that reads or
|
||||
* writes data from/to the \a h native handle. This handle
|
||||
* is \b not owned by the created systembuf object; the code
|
||||
* should take care of it externally.
|
||||
*
|
||||
* This class buffers input and output; the buffer size may be
|
||||
* tuned through the \a bufsize parameter, which defaults to 8192
|
||||
* bytes.
|
||||
*
|
||||
* \see pistream and postream
|
||||
*/
|
||||
explicit systembuf(handle_type h, std::size_t bufsize = 8192)
|
||||
: handle_(h),
|
||||
bufsize_(bufsize),
|
||||
read_buf_(new char[bufsize]),
|
||||
write_buf_(new char[bufsize])
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
BOOST_ASSERT(handle_ >= 0);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
BOOST_ASSERT(handle_ != INVALID_HANDLE_VALUE);
|
||||
#endif
|
||||
BOOST_ASSERT(bufsize_ > 0);
|
||||
setp(write_buf_.get(), write_buf_.get() + bufsize_);
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Reads new data from the native handle.
|
||||
*
|
||||
* This operation is called by input methods when there is no more
|
||||
* data in the input buffer. The function fills the buffer with new
|
||||
* data, if available.
|
||||
*
|
||||
* \pre All input positions are exhausted (gptr() >= egptr()).
|
||||
* \post The input buffer has new data, if available.
|
||||
* \returns traits_type::eof() if a read error occurrs or there are
|
||||
* no more data to be read. Otherwise returns
|
||||
* traits_type::to_int_type(*gptr()).
|
||||
*/
|
||||
virtual int_type underflow()
|
||||
{
|
||||
BOOST_ASSERT(gptr() >= egptr());
|
||||
|
||||
bool ok;
|
||||
#if defined(BOOST_POSIX_API)
|
||||
ssize_t cnt = read(handle_, read_buf_.get(), bufsize_);
|
||||
ok = (cnt != -1 && cnt != 0);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
DWORD cnt;
|
||||
BOOL res = ReadFile(handle_, read_buf_.get(), bufsize_, &cnt, NULL);
|
||||
ok = (res && cnt > 0);
|
||||
#endif
|
||||
|
||||
if (!ok)
|
||||
return traits_type::eof();
|
||||
else
|
||||
{
|
||||
setg(read_buf_.get(), read_buf_.get(), read_buf_.get() + cnt);
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes room in the write buffer for additional data.
|
||||
*
|
||||
* This operation is called by output methods when there is no more
|
||||
* space in the output buffer to hold a new element. The function
|
||||
* first flushes the buffer's contents to disk and then clears it to
|
||||
* leave room for more characters. The given \a c character is
|
||||
* stored at the beginning of the new space.
|
||||
*
|
||||
* \pre All output positions are exhausted (pptr() >= epptr()).
|
||||
* \post The output buffer has more space if no errors occurred
|
||||
* during the write to disk.
|
||||
* \post *(pptr() - 1) is \a c.
|
||||
* \returns traits_type::eof() if a write error occurrs. Otherwise
|
||||
* returns traits_type::not_eof(c).
|
||||
*/
|
||||
virtual int_type overflow(int c)
|
||||
{
|
||||
BOOST_ASSERT(pptr() >= epptr());
|
||||
|
||||
if (sync() == -1)
|
||||
return traits_type::eof();
|
||||
|
||||
if (!traits_type::eq_int_type(c, traits_type::eof()))
|
||||
{
|
||||
traits_type::assign(*pptr(), static_cast<traits_type::char_type>(
|
||||
c));
|
||||
pbump(1);
|
||||
}
|
||||
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the output buffer to disk.
|
||||
*
|
||||
* Synchronizes the systembuf buffers with the contents of the file
|
||||
* associated to this object through the native handle. The output buffer
|
||||
* is flushed to disk and cleared to leave new room for more data.
|
||||
*
|
||||
* \returns 0 on success, -1 if an error occurred.
|
||||
*/
|
||||
virtual int sync()
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
ssize_t cnt = pptr() - pbase();
|
||||
bool ok = (write(handle_, pbase(), cnt) == cnt);
|
||||
if (ok)
|
||||
pbump(-cnt);
|
||||
return ok ? 0 : -1;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
long cnt = pptr() - pbase();
|
||||
DWORD rcnt;
|
||||
BOOL res = WriteFile(handle_, pbase(), cnt, &rcnt, NULL);
|
||||
bool ok = (res && static_cast<long>(rcnt) == cnt);
|
||||
if (ok)
|
||||
pbump(-cnt);
|
||||
return ok ? 0 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Native handle used by the systembuf object.
|
||||
*/
|
||||
handle_type handle_;
|
||||
|
||||
/**
|
||||
* Internal buffer size used during read and write operations.
|
||||
*/
|
||||
std::size_t bufsize_;
|
||||
|
||||
/**
|
||||
* Internal buffer used during read operations.
|
||||
*/
|
||||
boost::scoped_array<char> read_buf_;
|
||||
|
||||
/**
|
||||
* Internal buffer used during write operations.
|
||||
*/
|
||||
boost::scoped_array<char> write_buf_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/detail/windows_helpers.hpp
|
||||
*
|
||||
* Includes the declaration of helper functions for Windows systems.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_WINDOWS_HELPERS_HPP
|
||||
#define BOOST_PROCESS_WINDOWS_HELPERS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Converts an environment to a string used by CreateProcess().
|
||||
*
|
||||
* Converts the environment's contents to the format used by the
|
||||
* CreateProcess() system call. The returned char* string is
|
||||
* allocated in dynamic memory; the caller must free it when not
|
||||
* used any more. This is enforced by the use of a shared pointer.
|
||||
*
|
||||
* This operation is only available on Windows systems.
|
||||
*
|
||||
* \return A dynamically allocated char* string that represents
|
||||
* the environment's content. This string is of the form
|
||||
* var1=value1\\0var2=value2\\0\\0.
|
||||
*/
|
||||
inline boost::shared_array<char> environment_to_windows_strings(environment
|
||||
&env)
|
||||
{
|
||||
boost::shared_array<char> envp;
|
||||
|
||||
if (env.empty())
|
||||
{
|
||||
envp.reset(new char[2]);
|
||||
ZeroMemory(envp.get(), 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string s;
|
||||
for (environment::const_iterator it = env.begin(); it != env.end();
|
||||
++it)
|
||||
{
|
||||
s += it->first + "=" + it->second;
|
||||
s.push_back(0);
|
||||
}
|
||||
envp.reset(new char[s.size() + 1]);
|
||||
#if (BOOST_MSVC >= 1400)
|
||||
memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1);
|
||||
#else
|
||||
memcpy(envp.get(), s.c_str(), s.size() + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
return envp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the command line to a plain string.
|
||||
*
|
||||
* Converts the command line's list of arguments to the format expected by the
|
||||
* \a lpCommandLine parameter in the CreateProcess() system call.
|
||||
*
|
||||
* This operation is only available on Windows systems.
|
||||
*
|
||||
* \return A dynamically allocated string holding the command line
|
||||
* to be passed to the executable. It is returned in a
|
||||
* shared_array object to ensure its release at some point.
|
||||
*/
|
||||
template <class Arguments>
|
||||
inline boost::shared_array<char> collection_to_windows_cmdline(const Arguments
|
||||
&args)
|
||||
{
|
||||
typedef std::vector<std::string> arguments_t;
|
||||
arguments_t args2;
|
||||
typename Arguments::size_type i = 0;
|
||||
std::size_t size = 0;
|
||||
for (typename Arguments::const_iterator it = args.begin(); it != args.end();
|
||||
++it)
|
||||
{
|
||||
std::string arg = *it;
|
||||
|
||||
std::string::size_type pos = 0;
|
||||
while ( (pos = arg.find('"', pos)) != std::string::npos)
|
||||
{
|
||||
arg.replace(pos, 1, "\\\"");
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
if (arg.find(' ') != std::string::npos)
|
||||
arg = '\"' + arg + '\"';
|
||||
|
||||
if (i++ != args.size() - 1)
|
||||
arg += ' ';
|
||||
|
||||
args2.push_back(arg);
|
||||
size += arg.size() + 1;
|
||||
}
|
||||
|
||||
boost::shared_array<char> cmdline(new char[size]);
|
||||
cmdline.get()[0] = '\0';
|
||||
for (arguments_t::size_type i = 0; i < args.size(); ++i)
|
||||
#if (BOOST_MSVC >= 1400)
|
||||
strcat_s(cmdline.get(), size, args2[i].c_str());
|
||||
#else
|
||||
strncat(cmdline.get(), args2[i].c_str(), args2[i].size());
|
||||
#endif
|
||||
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/environment.hpp
|
||||
*
|
||||
* Includes the declaration of the environment class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_ENVIRONMENT_HPP
|
||||
#define BOOST_PROCESS_ENVIRONMENT_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Representation of a process' environment variables.
|
||||
*
|
||||
* The environment is a map that establishes an unidirectional
|
||||
* association between variable names and their values and is
|
||||
* represented by a string to string map.
|
||||
*
|
||||
* Variables may be defined to the empty string. Be aware that doing so
|
||||
* is not portable: POSIX systems will treat such variables as being
|
||||
* defined to the empty value, but Windows systems are not able to
|
||||
* distinguish them from undefined variables.
|
||||
*
|
||||
* Neither POSIX nor Windows systems support a variable with no name.
|
||||
*
|
||||
* It is worthy to note that the environment is sorted alphabetically.
|
||||
* This is provided for-free by the map container used to implement this
|
||||
* type, and this behavior is required by Windows systems.
|
||||
*/
|
||||
typedef std::map<std::string, std::string> environment;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/handle.hpp
|
||||
*
|
||||
* Includes the declaration of the handle class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_HANDLE_HPP
|
||||
#define BOOST_PROCESS_HANDLE_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <unistd.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* RAII model for handles.
|
||||
*
|
||||
* The \a handle class is a RAII model for native handles. This class wraps
|
||||
* one of such handles grabbing its ownership, and automaticaly closes it
|
||||
* upon destruction. It is used to avoid leaking open handles, shall an
|
||||
* unexpected execution trace occur.
|
||||
*/
|
||||
class handle
|
||||
{
|
||||
public:
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Opaque name for the native handle type.
|
||||
*
|
||||
* On POSIX systems \a NativeSystemHandle is an integer type while it is
|
||||
* a \a HANDLE on Windows systems.
|
||||
*/
|
||||
typedef NativeSystemHandle native_type;
|
||||
#elif defined(BOOST_POSIX_API)
|
||||
typedef int native_type;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
typedef HANDLE native_type;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Constructs an invalid handle.
|
||||
*
|
||||
* \see valid()
|
||||
*/
|
||||
handle()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* RAII settings to specify if handle should be automatically closed.
|
||||
*/
|
||||
enum close_type { do_close, dont_close };
|
||||
|
||||
/**
|
||||
* Constructs a handle from a native handle.
|
||||
*
|
||||
* This constructor creates a new \a handle object that takes
|
||||
* ownership of the given \a native handle. If \a close is set to
|
||||
* handle::dont_close the \a native handle is not closed upon destruction.
|
||||
* The user must not close \a native if it is owned by a \a handle object.
|
||||
* Ownership can be reclaimed using release().
|
||||
*
|
||||
* \see release()
|
||||
*/
|
||||
handle(native_type native, close_type close = handle::do_close)
|
||||
: impl_(boost::make_shared<impl>(native, close))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the handle is valid or not.
|
||||
*
|
||||
* \return true if the handle is valid; false otherwise.
|
||||
*/
|
||||
bool valid() const
|
||||
{
|
||||
return impl_ && impl_->valid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the handle.
|
||||
*
|
||||
* \post The handle is invalid.
|
||||
* \post The native handle is closed.
|
||||
*/
|
||||
void close()
|
||||
{
|
||||
if (impl_)
|
||||
impl_->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the native handle.
|
||||
*
|
||||
* The caller can issue any operation on it except closing it.
|
||||
* If closing is required, release() shall be used.
|
||||
*
|
||||
* \return The native handle.
|
||||
*/
|
||||
native_type native() const
|
||||
{
|
||||
return impl_ ? impl_->native() : invalid_handle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims ownership of the native handle.
|
||||
*
|
||||
* The caller is responsible of closing the native handle.
|
||||
*
|
||||
* \post The handle is invalid.
|
||||
* \return The native handle.
|
||||
*/
|
||||
native_type release()
|
||||
{
|
||||
return impl_ ? impl_->release() : invalid_handle();
|
||||
}
|
||||
|
||||
private:
|
||||
class impl
|
||||
{
|
||||
public:
|
||||
typedef handle::native_type native_type;
|
||||
|
||||
impl(native_type native, close_type close)
|
||||
: native_(native),
|
||||
close_(close)
|
||||
{
|
||||
}
|
||||
|
||||
~impl()
|
||||
{
|
||||
if (valid() && close_ == handle::do_close)
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
::close(native_);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
CloseHandle(native_);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool valid() const
|
||||
{
|
||||
return native_ != handle::invalid_handle();
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if (valid())
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
::close(native_);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
CloseHandle(native_);
|
||||
#endif
|
||||
native_ = handle::invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
native_type native() const
|
||||
{
|
||||
return native_;
|
||||
}
|
||||
|
||||
native_type release()
|
||||
{
|
||||
native_type native = native_;
|
||||
native_ = handle::invalid_handle();
|
||||
return native;
|
||||
}
|
||||
|
||||
private:
|
||||
native_type native_;
|
||||
close_type close_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of handle to store native handle value.
|
||||
*
|
||||
* A shared pointer is used as handles represent system resources. If a
|
||||
* handle is closed and becomes invalid the state of copies of the handle
|
||||
* object will be updated as they all share the handle implementation.
|
||||
*/
|
||||
boost::shared_ptr<impl> impl_;
|
||||
|
||||
/**
|
||||
* Constant function representing an invalid handle value.
|
||||
*
|
||||
* Returns the platform-specific handle value that represents an
|
||||
* invalid handle. This is a constant function rather than a regular
|
||||
* constant because, in the latter case, we cannot define it under
|
||||
* Windows due to the value being of a complex type.
|
||||
*/
|
||||
static const native_type invalid_handle()
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
return -1;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,433 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/operations.hpp
|
||||
*
|
||||
* Provides miscellaneous free functions.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_OPERATIONS_HPP
|
||||
#define BOOST_PROCESS_OPERATIONS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <boost/process/detail/posix_helpers.hpp>
|
||||
# include <utility>
|
||||
# include <cstddef>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# if defined(__CYGWIN__)
|
||||
# include <boost/scoped_array.hpp>
|
||||
# include <sys/cygwin.h>
|
||||
# endif
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <boost/process/detail/windows_helpers.hpp>
|
||||
# include <boost/scoped_array.hpp>
|
||||
# include <boost/shared_array.hpp>
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/process/child.hpp>
|
||||
#include <boost/process/context.hpp>
|
||||
#include <boost/process/stream_id.hpp>
|
||||
#include <boost/process/stream_ends.hpp>
|
||||
#include <boost/process/handle.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Locates the executable program \a file in all the directory components
|
||||
* specified in \a path. If \a path is empty, the value of the PATH
|
||||
* environment variable is used.
|
||||
*
|
||||
* The path variable is interpreted following the same conventions used
|
||||
* to parse the PATH environment variable in the underlying platform.
|
||||
*
|
||||
* \throw boost::filesystem::filesystem_error If the file cannot be found
|
||||
* in the path.
|
||||
*/
|
||||
inline std::string find_executable_in_path(const std::string &file,
|
||||
std::string path = "")
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
BOOST_ASSERT(file.find('/') == std::string::npos);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
BOOST_ASSERT(file.find_first_of("\\/") == std::string::npos);
|
||||
#endif
|
||||
|
||||
std::string result;
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (path.empty())
|
||||
{
|
||||
const char *envpath = getenv("PATH");
|
||||
if (!envpath)
|
||||
boost::throw_exception(boost::filesystem::filesystem_error(
|
||||
BOOST_PROCESS_SOURCE_LOCATION "file not found", file,
|
||||
boost::system::errc::make_error_code(
|
||||
boost::system::errc::no_such_file_or_directory)));
|
||||
path = envpath;
|
||||
}
|
||||
BOOST_ASSERT(!path.empty());
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
if (!cygwin_posix_path_list_p(path.c_str()))
|
||||
{
|
||||
int size = cygwin_win32_to_posix_path_list_buf_size(path.c_str());
|
||||
boost::scoped_array<char> cygpath(new char[size]);
|
||||
cygwin_win32_to_posix_path_list(path.c_str(), cygpath.get());
|
||||
path = cygpath.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string::size_type pos1 = 0, pos2;
|
||||
do
|
||||
{
|
||||
pos2 = path.find(':', pos1);
|
||||
std::string dir = (pos2 != std::string::npos) ?
|
||||
path.substr(pos1, pos2 - pos1) : path.substr(pos1);
|
||||
std::string f = dir +
|
||||
(boost::algorithm::ends_with(dir, "/") ? "" : "/") + file;
|
||||
if (!access(f.c_str(), X_OK))
|
||||
result = f;
|
||||
pos1 = pos2 + 1;
|
||||
} while (pos2 != std::string::npos && result.empty());
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
const char *exts[] = { "", ".exe", ".com", ".bat", NULL };
|
||||
const char **ext = exts;
|
||||
while (*ext)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
char *dummy;
|
||||
DWORD size = SearchPathA(path.empty() ? NULL : path.c_str(),
|
||||
file.c_str(), *ext, MAX_PATH, buf, &dummy);
|
||||
BOOST_ASSERT(size < MAX_PATH);
|
||||
if (size > 0)
|
||||
{
|
||||
result = buf;
|
||||
break;
|
||||
}
|
||||
++ext;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (result.empty())
|
||||
boost::throw_exception(boost::filesystem::filesystem_error(
|
||||
BOOST_PROCESS_SOURCE_LOCATION "file not found", file,
|
||||
boost::system::errc::make_error_code(
|
||||
boost::system::errc::no_such_file_or_directory)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the program name from a given executable.
|
||||
*
|
||||
* \return The program name. On Windows the program name
|
||||
* is returned without a file extension.
|
||||
*/
|
||||
inline std::string executable_to_progname(const std::string &exe)
|
||||
{
|
||||
std::string::size_type begin = 0;
|
||||
std::string::size_type end = std::string::npos;
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
std::string::size_type slash = exe.rfind('/');
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
std::string::size_type slash = exe.find_last_of("/\\");
|
||||
#endif
|
||||
if (slash != std::string::npos)
|
||||
begin = slash + 1;
|
||||
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
if (exe.size() > 4 && (boost::algorithm::iends_with(exe, ".exe") ||
|
||||
boost::algorithm::iends_with(exe, ".com") ||
|
||||
boost::algorithm::iends_with(exe, ".bat")))
|
||||
end = exe.size() - 4;
|
||||
#endif
|
||||
|
||||
return exe.substr(begin, end - begin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new child process.
|
||||
*
|
||||
* Launches a new process based on the binary image specified by the
|
||||
* executable, the set of arguments passed to it and the execution context.
|
||||
*
|
||||
* \remark Blocking remarks: This function may block if the device holding the
|
||||
* executable blocks when loading the image. This might happen if, e.g.,
|
||||
* the binary is being loaded from a network share.
|
||||
*
|
||||
* \return A handle to the new child process.
|
||||
*/
|
||||
template <typename Arguments, typename Context>
|
||||
inline child create_child(const std::string &executable, Arguments args,
|
||||
Context ctx)
|
||||
{
|
||||
typedef std::map<stream_id, stream_ends> handles_t;
|
||||
handles_t handles;
|
||||
typename Context::streams_t::iterator it = ctx.streams.begin();
|
||||
for (; it != ctx.streams.end(); ++it)
|
||||
{
|
||||
if (it->first == stdin_id)
|
||||
handles[it->first] = it->second(input_stream);
|
||||
else if (it->first == stdout_id)
|
||||
handles[it->first] = it->second(output_stream);
|
||||
else if (it->first == stderr_id)
|
||||
handles[it->first] = it->second(output_stream);
|
||||
#if defined(BOOST_POSIX_API)
|
||||
else
|
||||
handles[it->first] = it->second(unknown_stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string p_name = ctx.process_name.empty() ?
|
||||
executable_to_progname(executable) : ctx.process_name;
|
||||
args.insert(args.begin(), p_name);
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
// Between fork() and execve() only async-signal-safe functions
|
||||
// must be called if multithreaded applications should be supported.
|
||||
// That's why the following code is executed before fork() is called.
|
||||
#if defined(F_MAXFD)
|
||||
int maxdescs = fcntl(-1, F_MAXFD, 0);
|
||||
if (maxdescs == -1)
|
||||
maxdescs = sysconf(_SC_OPEN_MAX);
|
||||
#else
|
||||
int maxdescs = sysconf(_SC_OPEN_MAX);
|
||||
#endif
|
||||
if (maxdescs == -1)
|
||||
maxdescs = 1024;
|
||||
std::vector<bool> closeflags(maxdescs, true);
|
||||
std::pair<std::size_t, char**> argv = detail::collection_to_argv(args);
|
||||
std::pair<std::size_t, char**> envp =
|
||||
detail::environment_to_envp(ctx.env);
|
||||
|
||||
const char *work_dir = ctx.work_dir.c_str();
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fork(2) failed");
|
||||
else if (pid == 0)
|
||||
{
|
||||
if (chdir(work_dir) == -1)
|
||||
{
|
||||
write(STDERR_FILENO, "chdir() failed\n", 15);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
for (handles_t::iterator it = handles.begin(); it != handles.end();
|
||||
++it)
|
||||
{
|
||||
if (it->second.child.valid())
|
||||
{
|
||||
handles_t::iterator it2 = it;
|
||||
++it2;
|
||||
for (; it2 != handles.end(); ++it2)
|
||||
{
|
||||
if (it2->second.child.native() == it->first)
|
||||
{
|
||||
int fd = fcntl(it2->second.child.native(), F_DUPFD,
|
||||
it->first + 1);
|
||||
if (fd == -1)
|
||||
{
|
||||
write(STDERR_FILENO, "fcntl() failed\n", 15);
|
||||
_exit(127);
|
||||
}
|
||||
it2->second.child = fd;
|
||||
}
|
||||
}
|
||||
|
||||
if (dup2(it->second.child.native(), it->first) == -1)
|
||||
{
|
||||
write(STDERR_FILENO, "dup2() failed\n", 14);
|
||||
_exit(127);
|
||||
}
|
||||
closeflags[it->first] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.setup)
|
||||
ctx.setup();
|
||||
|
||||
for (std::size_t i = 0; i < closeflags.size(); ++i)
|
||||
{
|
||||
if (closeflags[i])
|
||||
close(i);
|
||||
}
|
||||
|
||||
execve(executable.c_str(), argv.second, envp.second);
|
||||
|
||||
// Actually we should delete argv and envp data. As we must not
|
||||
// call any non-async-signal-safe functions though we simply exit.
|
||||
write(STDERR_FILENO, "execve() failed\n", 16);
|
||||
_exit(127);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(pid > 0);
|
||||
|
||||
for (std::size_t i = 0; i < argv.first; ++i)
|
||||
delete[] argv.second[i];
|
||||
delete[] argv.second;
|
||||
|
||||
for (std::size_t i = 0; i < envp.first; ++i)
|
||||
delete[] envp.second[i];
|
||||
delete[] envp.second;
|
||||
|
||||
std::map<stream_id, handle> parent_ends;
|
||||
for (handles_t::iterator it = handles.begin(); it != handles.end();
|
||||
++it)
|
||||
parent_ends[it->first] = it->second.parent;
|
||||
|
||||
return child(pid, parent_ends);
|
||||
}
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
STARTUPINFOA startup_info;
|
||||
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
startup_info.hStdInput = handles[stdin_id].child.native();
|
||||
startup_info.hStdOutput = handles[stdout_id].child.native();
|
||||
startup_info.hStdError = handles[stderr_id].child.native();
|
||||
|
||||
if (ctx.setup)
|
||||
ctx.setup(startup_info);
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
boost::shared_array<char> cmdline =
|
||||
detail::collection_to_windows_cmdline(args);
|
||||
|
||||
boost::scoped_array<char> exe(new char[executable.size() + 1]);
|
||||
#if (BOOST_MSVC >= 1400)
|
||||
strcpy_s(exe.get(), executable.size() + 1, executable.c_str());
|
||||
#else
|
||||
strcpy(exe.get(), executable.c_str());
|
||||
#endif
|
||||
|
||||
boost::scoped_array<char> workdir(new char[ctx.work_dir.size() + 1]);
|
||||
#if (BOOST_MSVC >= 1400)
|
||||
strcpy_s(workdir.get(), ctx.work_dir.size() + 1, ctx.work_dir.c_str());
|
||||
#else
|
||||
strcpy(workdir.get(), ctx.work_dir.c_str());
|
||||
#endif
|
||||
|
||||
boost::shared_array<char> envstrs =
|
||||
detail::environment_to_windows_strings(ctx.env);
|
||||
|
||||
if (CreateProcessA(exe.get(), cmdline.get(), NULL, NULL, TRUE, 0,
|
||||
envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");
|
||||
|
||||
handle hprocess(pi.hProcess);
|
||||
|
||||
if (!CloseHandle(pi.hThread))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
|
||||
|
||||
std::map<stream_id, handle> parent_ends;
|
||||
parent_ends[stdin_id] = handles[stdin_id].parent;
|
||||
parent_ends[stdout_id] = handles[stdout_id].parent;
|
||||
parent_ends[stderr_id] = handles[stderr_id].parent;
|
||||
|
||||
return child(hprocess, parent_ends);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
inline child create_child(const std::string &executable)
|
||||
{
|
||||
return create_child(executable, std::vector<std::string>(), context());
|
||||
}
|
||||
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
template <typename Arguments>
|
||||
inline child create_child(const std::string &executable, Arguments args)
|
||||
{
|
||||
return create_child(executable, args, context());
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a shell-based command.
|
||||
*
|
||||
* Executes the given command through the default system shell. The
|
||||
* command is subject to pattern expansion, redirection and pipelining.
|
||||
* The shell is launched as described by the parameters in the context.
|
||||
*
|
||||
* This function behaves similarly to the system(3) system call. In a
|
||||
* POSIX system, the command is fed to /bin/sh whereas under a Windows
|
||||
* system, it is fed to cmd.exe. It is difficult to write portable
|
||||
* commands, but this function comes in handy in multiple situations.
|
||||
*
|
||||
* \remark Blocking remarks: This function may block if the device holding the
|
||||
* executable blocks when loading the image. This might happen if, e.g.,
|
||||
* the binary is being loaded from a network share.
|
||||
*
|
||||
* \return A handle to the new child process.
|
||||
*/
|
||||
template <typename Context>
|
||||
inline child shell(const std::string &command, Context ctx)
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
std::string executable = "/bin/sh";
|
||||
std::vector<std::string> args;
|
||||
args.push_back("-c");
|
||||
args.push_back(command);
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
char sysdir[MAX_PATH];
|
||||
UINT size = GetSystemDirectoryA(sysdir, sizeof(sysdir));
|
||||
if (!size)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetSystemDirectory() failed");
|
||||
std::string executable = std::string(sysdir) +
|
||||
(sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe");
|
||||
std::vector<std::string> args;
|
||||
args.push_back("/c");
|
||||
args.push_back(command);
|
||||
#endif
|
||||
return create_child(executable, args, ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
inline child shell(const std::string &command)
|
||||
{
|
||||
return shell(command, context());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/pid_type.hpp
|
||||
*
|
||||
* Includes the declaration of the pid type.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_PID_TYPE_HPP
|
||||
#define BOOST_PROCESS_PID_TYPE_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <sys/types.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Opaque name for the process identifier type.
|
||||
*
|
||||
* Each operating system identifies processes using a specific type.
|
||||
* The \a pid_type type is used to transparently refer to a process
|
||||
* regardless of the operating system.
|
||||
*
|
||||
* This type is guaranteed to be an integral type on all supported
|
||||
* platforms. On POSIX systems it is defined as pid_t, on Windows systems as
|
||||
* DWORD.
|
||||
*/
|
||||
typedef NativeProcessId pid_type;
|
||||
#elif defined(BOOST_POSIX_API)
|
||||
typedef pid_t pid_type;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
typedef DWORD pid_type;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/pipe.hpp
|
||||
*
|
||||
* Includes the declaration of the pipe class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_PIPE_HPP
|
||||
#define BOOST_PROCESS_PIPE_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* The pipe class is a type definition for stream-based classes defined by
|
||||
* Boost.Asio.
|
||||
*
|
||||
* The type definition is provided for convenience. You can also use Boost.Asio
|
||||
* classes directly for asynchronous I/O operations.
|
||||
*/
|
||||
typedef BoostAsioPipe pipe;
|
||||
#elif defined(BOOST_POSIX_API)
|
||||
typedef boost::asio::posix::stream_descriptor pipe;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
typedef boost::asio::windows::stream_handle pipe;
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/pistream.hpp
|
||||
*
|
||||
* Includes the declaration of the pistream class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_PISTREAM_HPP
|
||||
#define BOOST_PROCESS_PISTREAM_HPP
|
||||
|
||||
#include <boost/process/handle.hpp>
|
||||
#include <boost/process/detail/systembuf.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <istream>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Child process' output stream.
|
||||
*
|
||||
* The pistream class represents an output communication channel with the
|
||||
* child process. The child process writes data to this stream and the
|
||||
* parent process can read it through the pistream object. In other
|
||||
* words, from the child's point of view, the communication channel is an
|
||||
* output one, but from the parent's point of view it is an input one;
|
||||
* hence the confusing pistream name.
|
||||
*
|
||||
* pistream objects cannot be copied because they buffer data
|
||||
* that flows through the communication channel.
|
||||
*
|
||||
* A pistream object behaves as a std::istream stream in all senses.
|
||||
* The class is only provided because it must provide a method to let
|
||||
* the caller explicitly close the communication channel.
|
||||
*
|
||||
* \remark Blocking remarks: Functions that read data from this
|
||||
* stream can block if the associated handle blocks during
|
||||
* the read. As this class is used to communicate with child
|
||||
* processes through anonymous pipes, the most typical blocking
|
||||
* condition happens when the child has no more data to send to
|
||||
* the pipe's system buffer. When this happens, the buffer
|
||||
* eventually empties and the system blocks until the writer
|
||||
* generates some data.
|
||||
*/
|
||||
class pistream : public std::istream, public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new process' output stream.
|
||||
*/
|
||||
explicit pistream(boost::process::handle h)
|
||||
: std::istream(0),
|
||||
handle_(h),
|
||||
systembuf_(handle_.native())
|
||||
{
|
||||
rdbuf(&systembuf_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the handle managed by this stream.
|
||||
*/
|
||||
const boost::process::handle &handle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the handle managed by this stream.
|
||||
*/
|
||||
boost::process::handle &handle()
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the handle managed by this stream.
|
||||
*
|
||||
* Explicitly closes the handle managed by this stream. This
|
||||
* function can be used by the user to tell the child process it's
|
||||
* not willing to receive more data.
|
||||
*/
|
||||
void close()
|
||||
{
|
||||
handle_.close();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The handle managed by this stream.
|
||||
*/
|
||||
boost::process::handle handle_;
|
||||
|
||||
/**
|
||||
* The systembuf object used to manage this stream's data.
|
||||
*/
|
||||
detail::systembuf systembuf_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/postream.hpp
|
||||
*
|
||||
* Includes the declaration of the postream class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_POSTREAM_HPP
|
||||
#define BOOST_PROCESS_POSTREAM_HPP
|
||||
|
||||
#include <boost/process/handle.hpp>
|
||||
#include <boost/process/detail/systembuf.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Child process' input stream.
|
||||
*
|
||||
* The postream class represents an input communication channel with the
|
||||
* child process. The child process reads data from this stream and the
|
||||
* parent process can write to it through the postream object. In other
|
||||
* words, from the child's point of view, the communication channel is an
|
||||
* input one, but from the parent's point of view it is an output one;
|
||||
* hence the confusing postream name.
|
||||
*
|
||||
* postream objects cannot be copied because they buffer data that flows
|
||||
* through the communication channel.
|
||||
*
|
||||
* A postream object behaves as a std::ostream stream in all senses.
|
||||
* The class is only provided because it must provide a method to let
|
||||
* the caller explicitly close the communication channel.
|
||||
*
|
||||
* \remark Blocking remarks: Functions that write data to this
|
||||
* stream can block if the associated handle blocks during
|
||||
* the write. As this class is used to communicate with child
|
||||
* processes through anonymous pipes, the most typical blocking
|
||||
* condition happens when the child is not processing the data
|
||||
* in the pipe's system buffer. When this happens, the buffer
|
||||
* eventually fills up and the system blocks until the reader
|
||||
* consumes some data, leaving some new room.
|
||||
*/
|
||||
class postream : public std::ostream, public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new process' input stream.
|
||||
*/
|
||||
explicit postream(boost::process::handle h)
|
||||
: std::ostream(0),
|
||||
handle_(h),
|
||||
systembuf_(handle_.native())
|
||||
{
|
||||
rdbuf(&systembuf_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the handle managed by this stream.
|
||||
*/
|
||||
const boost::process::handle &handle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the handle managed by this stream.
|
||||
*/
|
||||
boost::process::handle &handle()
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the handle managed by this stream.
|
||||
*
|
||||
* Explicitly closes the handle managed by this stream. This
|
||||
* function can be used by the user to tell the child process there
|
||||
* is no more data to send.
|
||||
*/
|
||||
void close()
|
||||
{
|
||||
systembuf_.sync();
|
||||
handle_.close();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The handle managed by this stream.
|
||||
*/
|
||||
boost::process::handle handle_;
|
||||
|
||||
/**
|
||||
* The systembuf object used to manage this stream's data.
|
||||
*/
|
||||
detail::systembuf systembuf_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/process.hpp
|
||||
*
|
||||
* Includes the declaration of the process class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_PROCESS_HPP
|
||||
#define BOOST_PROCESS_PROCESS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <unistd.h>
|
||||
# include <sys/types.h>
|
||||
# include <signal.h>
|
||||
# include <sys/wait.h>
|
||||
# include <errno.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <boost/process/handle.hpp>
|
||||
# include <cstdlib>
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/process/pid_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Process class to represent any running process.
|
||||
*/
|
||||
class process
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructs a new process object.
|
||||
*
|
||||
* Creates a new process object that represents a running process
|
||||
* within the system.
|
||||
*
|
||||
* On Windows the process is opened and a handle saved. This is required
|
||||
* to avoid the operating system removing process resources when the
|
||||
* process exits. The handle is closed when the process instance (and all
|
||||
* of its copies) is destroyed.
|
||||
*/
|
||||
process(pid_type id)
|
||||
: id_(id)
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
, handle_(open_process(id))
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Constructs a new process object.
|
||||
*
|
||||
* Creates a new process object that represents a running process
|
||||
* within the system.
|
||||
*
|
||||
* This operation is only available on Windows systems. The handle is
|
||||
* closed when the process instance (and all of its copies) is destroyed.
|
||||
*/
|
||||
process(handle h)
|
||||
: id_(GetProcessId(h.native())),
|
||||
handle_(h)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the process identifier.
|
||||
*/
|
||||
pid_type get_id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the process execution.
|
||||
*
|
||||
* Forces the termination of the process execution. Some platforms
|
||||
* allow processes to ignore some external termination notifications
|
||||
* or to capture them for a proper exit cleanup. You can set the
|
||||
* \a force flag to true to force their termination regardless
|
||||
* of any exit handler.
|
||||
*
|
||||
* After this call, accessing this object can be dangerous because the
|
||||
* process identifier may have been reused by a different process. It
|
||||
* might still be valid, though, if the process has refused to die.
|
||||
*
|
||||
* \throw boost::system::system_error If system calls used to terminate the
|
||||
* process fail.
|
||||
*/
|
||||
void terminate(bool force = false) const
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (kill(id_, force ? SIGKILL : SIGTERM) == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed");
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#if defined(BOOST_MSVC)
|
||||
force;
|
||||
#endif
|
||||
HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, id_);
|
||||
if (h == NULL)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
|
||||
if (!TerminateProcess(h, EXIT_FAILURE))
|
||||
{
|
||||
CloseHandle(h);
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed");
|
||||
}
|
||||
if (!CloseHandle(h))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks and waits for the process to terminate.
|
||||
*
|
||||
* Returns an exit code. The process object ceases to be valid after this
|
||||
* call.
|
||||
*
|
||||
* \remark Blocking remarks: This call blocks if the process has not
|
||||
* finalized execution and waits until it terminates.
|
||||
*
|
||||
* \throw boost::system::system_error If system calls used to wait for the
|
||||
* process fail.
|
||||
*/
|
||||
int wait() const
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
pid_t p;
|
||||
int status;
|
||||
do
|
||||
{
|
||||
p = waitpid(id_, &status, 0);
|
||||
} while (p == -1 && errno == EINTR);
|
||||
if (p == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed");
|
||||
return status;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE,
|
||||
id_);
|
||||
if (h == NULL)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
|
||||
if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
CloseHandle(h);
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"WaitForSingleObject() failed");
|
||||
}
|
||||
DWORD exit_code;
|
||||
if (!GetExitCodeProcess(h, &exit_code))
|
||||
{
|
||||
CloseHandle(h);
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"GetExitCodeProcess() failed");
|
||||
}
|
||||
if (!CloseHandle(h))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
|
||||
return exit_code;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The process identifier.
|
||||
*/
|
||||
pid_type id_;
|
||||
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
/**
|
||||
* Opens a process and returns a handle.
|
||||
*
|
||||
* OpenProcess() returns NULL and not INVALID_HANDLE_VALUE on failure.
|
||||
* That's why the return value is manually checked in this helper function
|
||||
* instead of simply passing it to the constructor of the handle class.
|
||||
*/
|
||||
HANDLE open_process(pid_type id)
|
||||
{
|
||||
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id);
|
||||
if (h == NULL)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* The process handle.
|
||||
*/
|
||||
handle handle_;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
188
vendor/boost/process/include/boost/process/self.hpp
vendored
188
vendor/boost/process/include/boost/process/self.hpp
vendored
|
|
@ -1,188 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/self.hpp
|
||||
*
|
||||
* Includes the declaration of the self class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_SELF_HPP
|
||||
#define BOOST_PROCESS_SELF_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <boost/scoped_array.hpp>
|
||||
# include <errno.h>
|
||||
# include <unistd.h>
|
||||
# include <limits.h>
|
||||
# if defined(__APPLE__)
|
||||
# include <crt_externs.h>
|
||||
# endif
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#include <boost/process/process.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <string>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
extern "C"
|
||||
{
|
||||
extern char **environ;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* The self class provides access to the process itself.
|
||||
*/
|
||||
class self : public process, public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Returns the self instance representing the caller's process.
|
||||
*/
|
||||
static self &get_instance()
|
||||
{
|
||||
static self *instance = 0;
|
||||
if (!instance)
|
||||
instance = new self;
|
||||
return *instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current environment.
|
||||
*
|
||||
* Returns the current process environment variables. Modifying the
|
||||
* returned object has no effect on the current environment.
|
||||
*/
|
||||
static environment get_environment()
|
||||
{
|
||||
environment e;
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# if defined(__APPLE__)
|
||||
char **env = *_NSGetEnviron();
|
||||
# else
|
||||
char **env = environ;
|
||||
# endif
|
||||
|
||||
while (*env)
|
||||
{
|
||||
std::string s = *env;
|
||||
std::string::size_type pos = s.find('=');
|
||||
e.insert(environment::value_type(s.substr(0, pos),
|
||||
s.substr(pos + 1)));
|
||||
++env;
|
||||
}
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# ifdef GetEnvironmentStrings
|
||||
# undef GetEnvironmentStrings
|
||||
# endif
|
||||
|
||||
char *ms_environ = GetEnvironmentStrings();
|
||||
if (!ms_environ)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"GetEnvironmentStrings() failed");
|
||||
try
|
||||
{
|
||||
char *env = ms_environ;
|
||||
while (*env)
|
||||
{
|
||||
std::string s = env;
|
||||
std::string::size_type pos = s.find('=');
|
||||
e.insert(environment::value_type(s.substr(0, pos),
|
||||
s.substr(pos + 1)));
|
||||
env += s.size() + 1;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FreeEnvironmentStringsA(ms_environ);
|
||||
throw;
|
||||
}
|
||||
FreeEnvironmentStringsA(ms_environ);
|
||||
#endif
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current work directory.
|
||||
*/
|
||||
static std::string get_work_dir()
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#if defined(PATH_MAX)
|
||||
char buffer[PATH_MAX];
|
||||
char *cwd = buffer;
|
||||
long size = PATH_MAX;
|
||||
#elif defined(_PC_PATH_MAX)
|
||||
errno = 0;
|
||||
long size = pathconf("/", _PC_PATH_MAX);
|
||||
if (size == -1 && errno)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pathconf(2) failed");
|
||||
else if (size == -1)
|
||||
size = BOOST_PROCESS_POSIX_PATH_MAX;
|
||||
BOOST_ASSERT(size > 0);
|
||||
boost::scoped_array<char> buffer(new char[size]);
|
||||
char *cwd = buffer.get();
|
||||
#else
|
||||
char buffer[BOOST_PROCESS_POSIX_PATH_MAX];
|
||||
char *cwd = buffer;
|
||||
long size = BOOST_PROCESS_POSIX_PATH_MAX;
|
||||
#endif
|
||||
if (!getcwd(cwd, size))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("getcwd(2) failed");
|
||||
BOOST_ASSERT(cwd[0] != '\0');
|
||||
return cwd;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
BOOST_ASSERT(MAX_PATH > 0);
|
||||
char cwd[MAX_PATH];
|
||||
if (!GetCurrentDirectoryA(sizeof(cwd), cwd))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"GetCurrentDirectory() failed");
|
||||
BOOST_ASSERT(cwd[0] != '\0');
|
||||
return cwd;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Constructs a new self object.
|
||||
*
|
||||
* Creates a new self object that represents the current process.
|
||||
*/
|
||||
self() :
|
||||
#if defined(BOOST_POSIX_API)
|
||||
process(getpid())
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
process(GetCurrentProcessId())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/status.hpp
|
||||
*
|
||||
* Includes the declaration of the status class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_STATUS_HPP
|
||||
#define BOOST_PROCESS_STATUS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
#include <boost/process/detail/basic_status.hpp>
|
||||
#include <boost/process/detail/basic_status_service.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* The status class to wait for processes to exit.
|
||||
*
|
||||
* The status class is a Boost.Asio I/O object and supports synchronous
|
||||
* and asynchronous wait operations.
|
||||
*/
|
||||
typedef detail::basic_status<detail::basic_status_service<> > status;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,326 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/stream_behavior.hpp
|
||||
*
|
||||
* Includes the declaration of stream behavior classes.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_STREAM_BEHAVIOR_HPP
|
||||
#define BOOST_PROCESS_STREAM_BEHAVIOR_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
# include <rpc.h>
|
||||
#endif
|
||||
|
||||
#include <boost/process/stream_ends.hpp>
|
||||
#include <boost/process/stream_type.hpp>
|
||||
#include <boost/process/handle.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace behavior {
|
||||
|
||||
/**
|
||||
* Stream behavior to close streams of a child process.
|
||||
*
|
||||
* A child process will not be able to use the stream.
|
||||
*/
|
||||
class close
|
||||
{
|
||||
public:
|
||||
stream_ends operator()(stream_type) const
|
||||
{
|
||||
return stream_ends();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stream behavior to make a child process inherit streams.
|
||||
*
|
||||
* A child process will use the very same stream of its parent process.
|
||||
*/
|
||||
class inherit
|
||||
{
|
||||
public:
|
||||
inherit(handle::native_type h)
|
||||
: h_(h, handle::dont_close)
|
||||
{
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!SetHandleInformation(h_.native(), HANDLE_FLAG_INHERIT,
|
||||
HANDLE_FLAG_INHERIT))
|
||||
{
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
HANDLE dup;
|
||||
if (!DuplicateHandle(proc, h_.native(), proc, &dup, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"DuplicateHandle() failed");
|
||||
}
|
||||
h_ = dup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
stream_ends operator()(stream_type) const
|
||||
{
|
||||
return stream_ends(h_, handle());
|
||||
}
|
||||
|
||||
private:
|
||||
handle h_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stream behavior to redirect streams with a pipe.
|
||||
*
|
||||
* A child process will be able to communicate with its parent process.
|
||||
*/
|
||||
class pipe
|
||||
{
|
||||
public:
|
||||
#if defined(BOOST_POSIX_API)
|
||||
pipe()
|
||||
: stype_(unknown_stream)
|
||||
{
|
||||
}
|
||||
|
||||
pipe(stream_type stype)
|
||||
: stype_(stype)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
stream_ends operator()(stream_type stype) const
|
||||
{
|
||||
handle::native_type ends[2];
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (::pipe(ends) == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pipe(2) failed");
|
||||
if (stype_ != unknown_stream)
|
||||
stype = stype_;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
ZeroMemory(&sa, sizeof(sa));
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = FALSE;
|
||||
if (!CreatePipe(&ends[0], &ends[1], &sa, 0))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreatePipe() failed");
|
||||
#endif
|
||||
handle child_end = ends[stype == input_stream ? 0 : 1];
|
||||
handle parent_end = ends[stype == input_stream ? 1 : 0];
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
|
||||
HANDLE_FLAG_INHERIT))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"SetHandleInformation() failed");
|
||||
#endif
|
||||
return stream_ends(child_end, parent_end);
|
||||
}
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
private:
|
||||
stream_type stype_;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Stream behavior to redirect streams with a named pipe.
|
||||
*
|
||||
* A child process will be able to communicate with its parent process.
|
||||
*/
|
||||
class named_pipe
|
||||
{
|
||||
public:
|
||||
named_pipe(const std::string &name)
|
||||
: name_(name)
|
||||
#if defined(BOOST_POSIX_API)
|
||||
, stype_(unknown_stream)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
named_pipe(const std::string &name, stream_type stype)
|
||||
: name_(name),
|
||||
stype_(stype)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
stream_ends operator()(stream_type stype) const
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (mkfifo(name_.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("mkfifo(3) failed");
|
||||
handle child_end = open(name_.c_str(), O_RDONLY | O_NONBLOCK);
|
||||
if (!child_end.valid())
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
|
||||
int opts = fcntl(child_end.native(), F_GETFL);
|
||||
if (opts == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fcntl(2) failed");
|
||||
opts ^= O_NONBLOCK;
|
||||
if (fcntl(child_end.native(), F_SETFL, opts) == -1)
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fcntl(2) failed");
|
||||
handle parent_end = open(name_.c_str(), O_WRONLY);
|
||||
if (!parent_end.valid())
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
|
||||
if (stype_ != unknown_stream)
|
||||
stype = stype_;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
ZeroMemory(&sa, sizeof(sa));
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
handle child_end = CreateNamedPipeA(name_.c_str(), PIPE_ACCESS_INBOUND |
|
||||
FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
|
||||
if (!child_end.valid())
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateNamedPipe() failed");
|
||||
handle parent_end = CreateFileA(name_.c_str(), GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (!parent_end.valid())
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
|
||||
#endif
|
||||
if (stype == output_stream)
|
||||
std::swap(child_end, parent_end);
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
|
||||
HANDLE_FLAG_INHERIT))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"SetHandleInformation() failed");
|
||||
#endif
|
||||
return stream_ends(child_end, parent_end);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
stream_type stype_;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Stream behavior to redirect streams with a pipe which supports asynchronous
|
||||
* I/O.
|
||||
*
|
||||
* As platforms require different types of pipes for asynchronous I/O this
|
||||
* stream behavior is provided for convenience. It uses the minimum required
|
||||
* pipe type on a platform in order to be able to use asynchronous I/O.
|
||||
*/
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
|
||||
typedef pipe async_pipe;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
class async_pipe
|
||||
{
|
||||
public:
|
||||
stream_ends operator()(stream_type stype) const
|
||||
{
|
||||
UUID uuid;
|
||||
RPC_STATUS s = UuidCreateSequential(&uuid);
|
||||
if (s != RPC_S_OK && s != RPC_S_UUID_LOCAL_ONLY)
|
||||
BOOST_PROCESS_THROW_ERROR(s, "UuidCreateSequential() failed");
|
||||
unsigned char *c;
|
||||
s = UuidToStringA(&uuid, &c);
|
||||
if (s != RPC_S_OK)
|
||||
BOOST_PROCESS_THROW_ERROR(s, "UuidToString() failed");
|
||||
std::string name;
|
||||
try
|
||||
{
|
||||
name = reinterpret_cast<char*>(c);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
RpcStringFreeA(&c);
|
||||
throw;
|
||||
}
|
||||
RpcStringFreeA(&c);
|
||||
named_pipe p("\\\\.\\pipe\\boost_process_" + name);
|
||||
return p(stype);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Stream behavior to mute streams.
|
||||
*
|
||||
* A child process will be able to use streams. But data written to an
|
||||
* output stream is discarded and data read from an input stream is 0.
|
||||
*/
|
||||
class null
|
||||
{
|
||||
public:
|
||||
#if defined(BOOST_POSIX_API)
|
||||
null()
|
||||
: stype_(unknown_stream)
|
||||
{
|
||||
}
|
||||
|
||||
null(stream_type stype)
|
||||
: stype_(stype)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
stream_ends operator()(stream_type stype) const
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (stype_ != unknown_stream)
|
||||
stype = stype_;
|
||||
std::string filename = (stype == input_stream) ? "/dev/zero" :
|
||||
"/dev/null";
|
||||
int flag = (stype == input_stream) ? O_RDONLY : O_WRONLY;
|
||||
handle child_end = open(filename.c_str(), flag);
|
||||
if (!child_end.valid())
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
DWORD access = (stype == input_stream) ? GENERIC_READ : GENERIC_WRITE;
|
||||
handle child_end = CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (!child_end.valid())
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
|
||||
if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
|
||||
HANDLE_FLAG_INHERIT))
|
||||
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
|
||||
"SetHandleInformation() failed");
|
||||
#endif
|
||||
return stream_ends(child_end, handle());
|
||||
}
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
private:
|
||||
stream_type stype_;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/stream_ends.hpp
|
||||
*
|
||||
* Includes the declaration of the stream_ends class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_STREAM_ENDS_HPP
|
||||
#define BOOST_PROCESS_STREAM_ENDS_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
#include <boost/process/handle.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* A pair of handles to configure streams.
|
||||
*
|
||||
* Stream behaviors return a pair of handles to specify how a child's stream
|
||||
* should be configured and possibly the opposite end of a child's end. This
|
||||
* is the end remaining in the parent process and which can be used for example
|
||||
* to communicate with a child process through its standard streams.
|
||||
*/
|
||||
struct stream_ends {
|
||||
/**
|
||||
* The child's end.
|
||||
*/
|
||||
handle child;
|
||||
|
||||
/**
|
||||
* The parent's end.
|
||||
*/
|
||||
handle parent;
|
||||
|
||||
/**
|
||||
* Standard constructor creating two invalid handles.
|
||||
*/
|
||||
stream_ends()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor to easily initialize handles.
|
||||
*/
|
||||
stream_ends(handle c, handle p)
|
||||
: child(c),
|
||||
parent(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/stream_id.hpp
|
||||
*
|
||||
* Includes the declaration of the stream_id type.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_STREAM_ID_HPP
|
||||
#define BOOST_PROCESS_STREAM_ID_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Standard stream id to refer to standard streams in a cross-platform manner.
|
||||
*/
|
||||
enum std_stream_id { stdin_id, stdout_id, stderr_id };
|
||||
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/**
|
||||
* Stream id type.
|
||||
*
|
||||
* Depending on the platform the stream id type is defined to refer to standard
|
||||
* streams only or to support more streams.
|
||||
*/
|
||||
typedef NativeStreamId stream_id;
|
||||
#elif defined(BOOST_POSIX_API)
|
||||
typedef int stream_id;
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
typedef std_stream_id stream_id;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// Boost.Process
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
/**
|
||||
* \file boost/process/stream_type.hpp
|
||||
*
|
||||
* Includes the declaration of the stream_type enumeration.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_STREAM_TYPE_HPP
|
||||
#define BOOST_PROCESS_STREAM_TYPE_HPP
|
||||
|
||||
#include <boost/process/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
|
||||
/**
|
||||
* Stream type to differentiate between input and output streams.
|
||||
*
|
||||
* On POSIX systems another value unknown_stream is defined. It is passed
|
||||
* to stream behaviors for file descriptors greater than 2.
|
||||
*/
|
||||
enum stream_type {
|
||||
input_stream,
|
||||
output_stream
|
||||
#if defined(BOOST_POSIX_API)
|
||||
, unknown_stream
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
26
vendor/libssh2-1.4.2/CMakeLists.txt
vendored
26
vendor/libssh2-1.4.2/CMakeLists.txt
vendored
|
|
@ -1,26 +0,0 @@
|
|||
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
1188
vendor/libssh2-1.4.2/include/libssh2.h
vendored
File diff suppressed because it is too large
Load diff
118
vendor/libssh2-1.4.2/include/libssh2_publickey.h
vendored
118
vendor/libssh2-1.4.2/include/libssh2_publickey.h
vendored
|
|
@ -1,118 +0,0 @@
|
|||
/* 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
345
vendor/libssh2-1.4.2/include/libssh2_sftp.h
vendored
|
|
@ -1,345 +0,0 @@
|
|||
/* 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
793
vendor/libssh2-1.4.2/src/agent.c
vendored
|
|
@ -1,793 +0,0 @@
|
|||
/*
|
||||
* 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
2570
vendor/libssh2-1.4.2/src/channel.c
vendored
File diff suppressed because it is too large
Load diff
141
vendor/libssh2-1.4.2/src/channel.h
vendored
141
vendor/libssh2-1.4.2/src/channel.h
vendored
|
|
@ -1,141 +0,0 @@
|
|||
#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
390
vendor/libssh2-1.4.2/src/comp.c
vendored
|
|
@ -1,390 +0,0 @@
|
|||
/* 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
45
vendor/libssh2-1.4.2/src/comp.h
vendored
|
|
@ -1,45 +0,0 @@
|
|||
#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
334
vendor/libssh2-1.4.2/src/crypt.c
vendored
|
|
@ -1,334 +0,0 @@
|
|||
/* 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
118
vendor/libssh2-1.4.2/src/crypto.h
vendored
|
|
@ -1,118 +0,0 @@
|
|||
/* 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
78
vendor/libssh2-1.4.2/src/global.c
vendored
|
|
@ -1,78 +0,0 @@
|
|||
/* 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
485
vendor/libssh2-1.4.2/src/hostkey.c
vendored
|
|
@ -1,485 +0,0 @@
|
|||
/* 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
98
vendor/libssh2-1.4.2/src/keepalive.c
vendored
|
|
@ -1,98 +0,0 @@
|
|||
/* 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
2008
vendor/libssh2-1.4.2/src/kex.c
vendored
File diff suppressed because it is too large
Load diff
1146
vendor/libssh2-1.4.2/src/knownhost.c
vendored
1146
vendor/libssh2-1.4.2/src/knownhost.c
vendored
File diff suppressed because it is too large
Load diff
593
vendor/libssh2-1.4.2/src/libgcrypt.c
vendored
593
vendor/libssh2-1.4.2/src/libgcrypt.c
vendored
|
|
@ -1,593 +0,0 @@
|
|||
/* 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
150
vendor/libssh2-1.4.2/src/libgcrypt.h
vendored
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* 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
5
vendor/libssh2-1.4.2/src/libssh2_config.h
vendored
|
|
@ -1,5 +0,0 @@
|
|||
#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
224
vendor/libssh2-1.4.2/src/libssh2_config_osx.h
vendored
|
|
@ -1,224 +0,0 @@
|
|||
/* 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
41
vendor/libssh2-1.4.2/src/libssh2_config_win.h
vendored
|
|
@ -1,41 +0,0 @@
|
|||
#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
1038
vendor/libssh2-1.4.2/src/libssh2_priv.h
vendored
File diff suppressed because it is too large
Load diff
314
vendor/libssh2-1.4.2/src/mac.c
vendored
314
vendor/libssh2-1.4.2/src/mac.c
vendored
|
|
@ -1,314 +0,0 @@
|
|||
/* 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
67
vendor/libssh2-1.4.2/src/mac.h
vendored
|
|
@ -1,67 +0,0 @@
|
|||
#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
612
vendor/libssh2-1.4.2/src/misc.c
vendored
|
|
@ -1,612 +0,0 @@
|
|||
/* 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
94
vendor/libssh2-1.4.2/src/misc.h
vendored
|
|
@ -1,94 +0,0 @@
|
|||
#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
804
vendor/libssh2-1.4.2/src/openssl.c
vendored
|
|
@ -1,804 +0,0 @@
|
|||
/* 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
178
vendor/libssh2-1.4.2/src/openssl.h
vendored
|
|
@ -1,178 +0,0 @@
|
|||
/* 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
1243
vendor/libssh2-1.4.2/src/packet.c
vendored
File diff suppressed because it is too large
Load diff
76
vendor/libssh2-1.4.2/src/packet.h
vendored
76
vendor/libssh2-1.4.2/src/packet.h
vendored
|
|
@ -1,76 +0,0 @@
|
|||
#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
213
vendor/libssh2-1.4.2/src/pem.c
vendored
|
|
@ -1,213 +0,0 @@
|
|||
/* 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
1058
vendor/libssh2-1.4.2/src/publickey.c
vendored
File diff suppressed because it is too large
Load diff
1085
vendor/libssh2-1.4.2/src/scp.c
vendored
1085
vendor/libssh2-1.4.2/src/scp.c
vendored
File diff suppressed because it is too large
Load diff
1751
vendor/libssh2-1.4.2/src/session.c
vendored
1751
vendor/libssh2-1.4.2/src/session.c
vendored
File diff suppressed because it is too large
Load diff
93
vendor/libssh2-1.4.2/src/session.h
vendored
93
vendor/libssh2-1.4.2/src/session.h
vendored
|
|
@ -1,93 +0,0 @@
|
|||
#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 */
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue