bug fixes
This commit is contained in:
parent
44ea53407b
commit
74709a4983
78 changed files with 52 additions and 29194 deletions
|
|
@ -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,11 +2,20 @@
|
|||
#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;
|
||||
|
||||
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;
|
||||
|
|
@ -15,5 +24,4 @@ namespace fc { namespace json {
|
|||
|
||||
} }
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::json::error_object, (code)(message)(data) )
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <fc/log.hpp>
|
||||
#include <fc/thread.hpp>
|
||||
#include <fc/error.hpp>
|
||||
#include <fc/json_rpc_error_object.hpp>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -57,7 +58,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 +66,16 @@ 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 ( 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(...){}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -86,9 +87,9 @@ namespace fc { namespace json {
|
|||
fc::string o = ss.str();
|
||||
my->out.write( o.c_str(), o.size() );
|
||||
}
|
||||
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() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
3278
vendor/libssh2-1.4.2/src/sftp.c
vendored
3278
vendor/libssh2-1.4.2/src/sftp.c
vendored
File diff suppressed because it is too large
Load diff
230
vendor/libssh2-1.4.2/src/sftp.h
vendored
230
vendor/libssh2-1.4.2/src/sftp.h
vendored
|
|
@ -1,230 +0,0 @@
|
|||
#ifndef _LIBSSH2_SFTP_H
|
||||
#define _LIBSSH2_SFTP_H
|
||||
/*
|
||||
* Copyright (C) 2010 - 2012 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the
|
||||
* amount of data sent in each FXP_WRITE packet
|
||||
*/
|
||||
#define MAX_SFTP_OUTGOING_SIZE 30000
|
||||
|
||||
/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ
|
||||
* packets.
|
||||
*/
|
||||
#define MAX_SFTP_READ_SIZE 2000
|
||||
|
||||
struct sftp_pipeline_chunk {
|
||||
struct list_node node;
|
||||
size_t len; /* WRITE: size of the data to write
|
||||
READ: how many bytes that was asked for */
|
||||
size_t sent;
|
||||
ssize_t lefttosend; /* if 0, the entire packet has been sent off */
|
||||
uint32_t request_id;
|
||||
unsigned char packet[1]; /* data */
|
||||
};
|
||||
|
||||
struct sftp_zombie_requests {
|
||||
struct list_node node;
|
||||
uint32_t request_id;
|
||||
};
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
struct _LIBSSH2_SFTP_PACKET
|
||||
{
|
||||
struct list_node node; /* linked list header */
|
||||
uint32_t request_id;
|
||||
unsigned char *data;
|
||||
size_t data_len; /* payload size */
|
||||
};
|
||||
|
||||
typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET;
|
||||
|
||||
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
|
||||
|
||||
struct _LIBSSH2_SFTP_HANDLE
|
||||
{
|
||||
struct list_node node;
|
||||
|
||||
LIBSSH2_SFTP *sftp;
|
||||
|
||||
char handle[SFTP_HANDLE_MAXLEN];
|
||||
size_t handle_len;
|
||||
|
||||
enum {
|
||||
LIBSSH2_SFTP_HANDLE_FILE,
|
||||
LIBSSH2_SFTP_HANDLE_DIR
|
||||
} handle_type;
|
||||
|
||||
union _libssh2_sftp_handle_data
|
||||
{
|
||||
struct _libssh2_sftp_handle_file_data
|
||||
{
|
||||
libssh2_uint64_t offset;
|
||||
libssh2_uint64_t offset_sent;
|
||||
size_t acked; /* container for acked data that hasn't been
|
||||
returned to caller yet, used for sftp_write */
|
||||
|
||||
/* 'data' is used by sftp_read() and is allocated data that has
|
||||
been received already from the server but wasn't returned to
|
||||
the caller yet. It is of size 'data_len' and 'data_left is the
|
||||
number of bytes not yet returned, counted from the end of the
|
||||
buffer. */
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
size_t data_left;
|
||||
|
||||
char eof; /* we have read to the end */
|
||||
} file;
|
||||
struct _libssh2_sftp_handle_dir_data
|
||||
{
|
||||
uint32_t names_left;
|
||||
void *names_packet;
|
||||
char *next_name;
|
||||
} dir;
|
||||
} u;
|
||||
|
||||
/* State variables used in libssh2_sftp_close_handle() */
|
||||
libssh2_nonblocking_states close_state;
|
||||
uint32_t close_request_id;
|
||||
unsigned char *close_packet;
|
||||
|
||||
/* list of outstanding packets sent to server */
|
||||
struct list_head packet_list;
|
||||
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
uint32_t request_id, version;
|
||||
|
||||
struct list_head packets;
|
||||
|
||||
/* List of FXP_READ responses to ignore because EOF already received. */
|
||||
struct list_head zombie_requests;
|
||||
|
||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||
struct list_head sftp_handles;
|
||||
|
||||
uint32_t last_errno;
|
||||
|
||||
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
|
||||
unsigned char partial_size[4]; /* buffer for size field */
|
||||
size_t partial_size_len; /* size field length */
|
||||
unsigned char *partial_packet; /* The data */
|
||||
uint32_t partial_len; /* Desired number of bytes */
|
||||
size_t partial_received; /* Bytes received so far */
|
||||
|
||||
/* Time that libssh2_sftp_packet_requirev() started reading */
|
||||
time_t requirev_start;
|
||||
|
||||
/* State variables used in libssh2_sftp_open_ex() */
|
||||
libssh2_nonblocking_states open_state;
|
||||
unsigned char *open_packet;
|
||||
uint32_t open_packet_len; /* 32 bit on the wire */
|
||||
size_t open_packet_sent;
|
||||
uint32_t open_request_id;
|
||||
|
||||
/* State variable used in sftp_read() */
|
||||
libssh2_nonblocking_states read_state;
|
||||
|
||||
/* State variable used in sftp_packet_read() */
|
||||
libssh2_nonblocking_states packet_state;
|
||||
|
||||
/* State variable used in sftp_write() */
|
||||
libssh2_nonblocking_states write_state;
|
||||
|
||||
/* State variables used in libssh2_sftp_readdir() */
|
||||
libssh2_nonblocking_states readdir_state;
|
||||
unsigned char *readdir_packet;
|
||||
uint32_t readdir_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_fstat_ex() */
|
||||
libssh2_nonblocking_states fstat_state;
|
||||
unsigned char *fstat_packet;
|
||||
uint32_t fstat_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_unlink_ex() */
|
||||
libssh2_nonblocking_states unlink_state;
|
||||
unsigned char *unlink_packet;
|
||||
uint32_t unlink_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_rename_ex() */
|
||||
libssh2_nonblocking_states rename_state;
|
||||
unsigned char *rename_packet;
|
||||
unsigned char *rename_s;
|
||||
uint32_t rename_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_fstatvfs() */
|
||||
libssh2_nonblocking_states fstatvfs_state;
|
||||
unsigned char *fstatvfs_packet;
|
||||
uint32_t fstatvfs_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_statvfs() */
|
||||
libssh2_nonblocking_states statvfs_state;
|
||||
unsigned char *statvfs_packet;
|
||||
uint32_t statvfs_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_mkdir() */
|
||||
libssh2_nonblocking_states mkdir_state;
|
||||
unsigned char *mkdir_packet;
|
||||
uint32_t mkdir_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_rmdir() */
|
||||
libssh2_nonblocking_states rmdir_state;
|
||||
unsigned char *rmdir_packet;
|
||||
uint32_t rmdir_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_stat() */
|
||||
libssh2_nonblocking_states stat_state;
|
||||
unsigned char *stat_packet;
|
||||
uint32_t stat_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_symlink() */
|
||||
libssh2_nonblocking_states symlink_state;
|
||||
unsigned char *symlink_packet;
|
||||
uint32_t symlink_request_id;
|
||||
};
|
||||
|
||||
#endif
|
||||
873
vendor/libssh2-1.4.2/src/transport.c
vendored
873
vendor/libssh2-1.4.2/src/transport.c
vendored
|
|
@ -1,873 +0,0 @@
|
|||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file handles reading and writing to the SECSH transport layer. RFC4253.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "transport.h"
|
||||
#include "mac.h"
|
||||
|
||||
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
|
||||
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#define UNPRINTABLE_CHAR '.'
|
||||
static void
|
||||
debugdump(LIBSSH2_SESSION * session,
|
||||
const char *desc, const unsigned char *ptr, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
unsigned int width = 0x10;
|
||||
char buffer[256]; /* Must be enough for width*4 + about 30 or so */
|
||||
size_t used;
|
||||
static const char* hex_chars = "0123456789ABCDEF";
|
||||
|
||||
if (!(session->showmask & LIBSSH2_TRACE_TRANS)) {
|
||||
/* not asked for, bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
|
||||
desc, (int) size);
|
||||
if (session->tracehandler)
|
||||
(session->tracehandler)(session, session->tracehandler_context,
|
||||
buffer, used);
|
||||
else
|
||||
fprintf(stderr, "%s", buffer);
|
||||
|
||||
for(i = 0; i < size; i += width) {
|
||||
|
||||
used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i);
|
||||
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++) {
|
||||
if (i + c < size) {
|
||||
buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF];
|
||||
buffer[used++] = hex_chars[ptr[i+c] & 0xF];
|
||||
}
|
||||
else {
|
||||
buffer[used++] = ' ';
|
||||
buffer[used++] = ' ';
|
||||
}
|
||||
|
||||
buffer[used++] = ' ';
|
||||
if ((width/2) - 1 == c)
|
||||
buffer[used++] = ' ';
|
||||
}
|
||||
|
||||
buffer[used++] = ':';
|
||||
buffer[used++] = ' ';
|
||||
|
||||
for(c = 0; (c < width) && (i + c < size); c++) {
|
||||
buffer[used++] = isprint(ptr[i + c]) ?
|
||||
ptr[i + c] : UNPRINTABLE_CHAR;
|
||||
}
|
||||
buffer[used++] = '\n';
|
||||
buffer[used] = 0;
|
||||
|
||||
if (session->tracehandler)
|
||||
(session->tracehandler)(session, session->tracehandler_context,
|
||||
buffer, used);
|
||||
else
|
||||
fprintf(stderr, "%s", buffer);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define debugdump(a,x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
|
||||
*
|
||||
* returns 0 on success and negative on failure
|
||||
*/
|
||||
|
||||
static int
|
||||
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||
unsigned char *dest, int len)
|
||||
{
|
||||
struct transportpacket *p = &session->packet;
|
||||
int blocksize = session->remote.crypt->blocksize;
|
||||
|
||||
/* if we get called with a len that isn't an even number of blocksizes
|
||||
we risk losing those extra bytes */
|
||||
assert((len % blocksize) == 0);
|
||||
|
||||
while (len >= blocksize) {
|
||||
if (session->remote.crypt->crypt(session, source,
|
||||
&session->remote.crypt_abstract)) {
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_DECRYPT;
|
||||
}
|
||||
|
||||
/* if the crypt() function would write to a given address it
|
||||
wouldn't have to memcpy() and we could avoid this memcpy()
|
||||
too */
|
||||
memcpy(dest, source, blocksize);
|
||||
|
||||
len -= blocksize; /* less bytes left */
|
||||
dest += blocksize; /* advance write pointer */
|
||||
source += blocksize; /* advance read pointer */
|
||||
}
|
||||
return LIBSSH2_ERROR_NONE; /* all is fine */
|
||||
}
|
||||
|
||||
/*
|
||||
* fullpacket() gets called when a full packet has been received and properly
|
||||
* collected.
|
||||
*/
|
||||
static int
|
||||
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||
{
|
||||
unsigned char macbuf[MAX_MACSIZE];
|
||||
struct transportpacket *p = &session->packet;
|
||||
int rc;
|
||||
|
||||
if (session->fullpacket_state == libssh2_NB_state_idle) {
|
||||
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
|
||||
session->fullpacket_payload_len = p->packet_length - 1;
|
||||
|
||||
if (encrypted) {
|
||||
|
||||
/* Calculate MAC hash */
|
||||
session->remote.mac->hash(session, macbuf, /* store hash here */
|
||||
session->remote.seqno,
|
||||
p->init, 5,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.mac_abstract);
|
||||
|
||||
/* Compare the calculated hash with the MAC we just read from
|
||||
* the network. The read one is at the very end of the payload
|
||||
* buffer. Note that 'payload_len' here is the packet_length
|
||||
* field which includes the padding but not the MAC.
|
||||
*/
|
||||
if (memcmp(macbuf, p->payload + session->fullpacket_payload_len,
|
||||
session->remote.mac->mac_len)) {
|
||||
session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
session->remote.seqno++;
|
||||
|
||||
/* ignore the padding */
|
||||
session->fullpacket_payload_len -= p->padding_length;
|
||||
|
||||
/* Check for and deal with decompression */
|
||||
if (session->remote.comp &&
|
||||
session->remote.comp->compress &&
|
||||
session->remote.comp_abstract) {
|
||||
/*
|
||||
* The buffer for the decompression (remote.comp_abstract) is
|
||||
* initialised in time when it is needed so as long it is NULL we
|
||||
* cannot decompress.
|
||||
*/
|
||||
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
rc = session->remote.comp->decomp(session,
|
||||
&data, &data_len,
|
||||
LIBSSH2_PACKET_MAXDECOMP,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.comp_abstract);
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
p->payload = data;
|
||||
session->fullpacket_payload_len = data_len;
|
||||
}
|
||||
|
||||
session->fullpacket_packet_type = p->payload[0];
|
||||
|
||||
debugdump(session, "libssh2_transport_read() plain",
|
||||
p->payload, session->fullpacket_payload_len);
|
||||
|
||||
session->fullpacket_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->fullpacket_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_packet_add(session, p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
session->fullpacket_macstate);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
session->fullpacket_state = libssh2_NB_state_idle;
|
||||
|
||||
return session->fullpacket_packet_type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _libssh2_transport_read
|
||||
*
|
||||
* Collect a packet into the input queue.
|
||||
*
|
||||
* Returns packet type added to input queue (0 if nothing added), or a
|
||||
* negative error number.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*
|
||||
* DOES NOT call _libssh2_error() for ANY error case.
|
||||
*/
|
||||
int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
{
|
||||
int rc;
|
||||
struct transportpacket *p = &session->packet;
|
||||
int remainbuf;
|
||||
int remainpack;
|
||||
int numbytes;
|
||||
int numdecrypt;
|
||||
unsigned char block[MAX_BLOCKSIZE];
|
||||
int blocksize;
|
||||
int encrypted = 1;
|
||||
size_t total_num;
|
||||
|
||||
/* default clear the bit */
|
||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
|
||||
/*
|
||||
* All channels, systems, subsystems, etc eventually make it down here
|
||||
* when looking for more incoming data. If a key exchange is going on
|
||||
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will
|
||||
* ONLY send key exchange related traffic. In non-blocking mode, there is
|
||||
* a chance to break out of the kex_exchange function with an EAGAIN
|
||||
* status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is
|
||||
* active, then we must redirect to the key exchange. However, if
|
||||
* kex_exchange is active (as in it is the one that calls this execution
|
||||
* of packet_read, then don't redirect, as that would be an infinite loop!
|
||||
*/
|
||||
|
||||
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||
|
||||
/* Whoever wants a packet won't get anything until the key re-exchange
|
||||
* is done!
|
||||
*/
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
|
||||
" key re-exchange from _libssh2_transport_read");
|
||||
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================== NOTE ===============================
|
||||
* I know this is very ugly and not a really good use of "goto", but
|
||||
* this case statement would be even uglier to do it any other way
|
||||
*/
|
||||
if (session->readPack_state == libssh2_NB_state_jump1) {
|
||||
session->readPack_state = libssh2_NB_state_idle;
|
||||
encrypted = session->readPack_encrypted;
|
||||
goto libssh2_transport_read_point1;
|
||||
}
|
||||
|
||||
do {
|
||||
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||
blocksize = session->remote.crypt->blocksize;
|
||||
} else {
|
||||
encrypted = 0; /* not encrypted */
|
||||
blocksize = 5; /* not strictly true, but we can use 5 here to
|
||||
make the checks below work fine still */
|
||||
}
|
||||
|
||||
/* read/use a whole big chunk into a temporary area stored in
|
||||
the LIBSSH2_SESSION struct. We will decrypt data from that
|
||||
buffer into the packet buffer so this temp one doesn't have
|
||||
to be able to keep a whole SSH packet, just be large enough
|
||||
so that we can read big chunks from the network layer. */
|
||||
|
||||
/* how much data there is remaining in the buffer to deal with
|
||||
before we should read more from the network */
|
||||
remainbuf = p->writeidx - p->readidx;
|
||||
|
||||
/* if remainbuf turns negative we have a bad internal error */
|
||||
assert(remainbuf >= 0);
|
||||
|
||||
if (remainbuf < blocksize) {
|
||||
/* If we have less than a blocksize left, it is too
|
||||
little data to deal with, read more */
|
||||
ssize_t nread;
|
||||
|
||||
/* move any remainder to the start of the buffer so
|
||||
that we can do a full refill */
|
||||
if (remainbuf) {
|
||||
memmove(p->buf, &p->buf[p->readidx], remainbuf);
|
||||
p->readidx = 0;
|
||||
p->writeidx = remainbuf;
|
||||
} else {
|
||||
/* nothing to move, just zero the indexes */
|
||||
p->readidx = p->writeidx = 0;
|
||||
}
|
||||
|
||||
/* now read a big chunk from the network into the temp buffer */
|
||||
nread =
|
||||
LIBSSH2_RECV(session, &p->buf[remainbuf],
|
||||
PACKETBUFSIZE - remainbuf,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
if (nread <= 0) {
|
||||
/* check if this is due to EAGAIN and return the special
|
||||
return code if so, error out normally otherwise */
|
||||
if ((nread < 0) && (nread == -EAGAIN)) {
|
||||
session->socket_block_directions |=
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Error recving %d bytes (got %d)",
|
||||
PACKETBUFSIZE - remainbuf, -nread);
|
||||
return LIBSSH2_ERROR_SOCKET_RECV;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Recved %d/%d bytes to %p+%d", nread,
|
||||
PACKETBUFSIZE - remainbuf, p->buf, remainbuf);
|
||||
|
||||
debugdump(session, "libssh2_transport_read() raw",
|
||||
&p->buf[remainbuf], nread);
|
||||
/* advance write pointer */
|
||||
p->writeidx += nread;
|
||||
|
||||
/* update remainbuf counter */
|
||||
remainbuf = p->writeidx - p->readidx;
|
||||
}
|
||||
|
||||
/* how much data to deal with from the buffer */
|
||||
numbytes = remainbuf;
|
||||
|
||||
if (!p->total_num) {
|
||||
/* No payload package area allocated yet. To know the
|
||||
size of this payload, we need to decrypt the first
|
||||
blocksize data. */
|
||||
|
||||
if (numbytes < blocksize) {
|
||||
/* we can't act on anything less than blocksize, but this
|
||||
check is only done for the initial block since once we have
|
||||
got the start of a block we can in fact deal with fractions
|
||||
*/
|
||||
session->socket_block_directions |=
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
if (encrypted) {
|
||||
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
|
||||
if (rc != LIBSSH2_ERROR_NONE) {
|
||||
return rc;
|
||||
}
|
||||
/* save the first 5 bytes of the decrypted package, to be
|
||||
used in the hash calculation later down. */
|
||||
memcpy(p->init, &p->buf[p->readidx], 5);
|
||||
} else {
|
||||
/* the data is plain, just copy it verbatim to
|
||||
the working block buffer */
|
||||
memcpy(block, &p->buf[p->readidx], blocksize);
|
||||
}
|
||||
|
||||
/* advance the read pointer */
|
||||
p->readidx += blocksize;
|
||||
|
||||
/* we now have the initial blocksize bytes decrypted,
|
||||
* and we can extract packet and padding length from it
|
||||
*/
|
||||
p->packet_length = _libssh2_ntohu32(block);
|
||||
if (p->packet_length < 1)
|
||||
return LIBSSH2_ERROR_DECRYPT;
|
||||
|
||||
p->padding_length = block[4];
|
||||
|
||||
/* total_num is the number of bytes following the initial
|
||||
(5 bytes) packet length and padding length fields */
|
||||
total_num =
|
||||
p->packet_length - 1 +
|
||||
(encrypted ? session->remote.mac->mac_len : 0);
|
||||
|
||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||
*
|
||||
* "All implementations MUST be able to process
|
||||
* packets with uncompressed payload length of 32768
|
||||
* bytes or less and total packet size of 35000 bytes
|
||||
* or less (including length, padding length, payload,
|
||||
* padding, and MAC.)."
|
||||
*/
|
||||
if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
|
||||
/* Get a packet handle put data into. We get one to
|
||||
hold all data, including padding and MAC. */
|
||||
p->payload = LIBSSH2_ALLOC(session, total_num);
|
||||
if (!p->payload) {
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
}
|
||||
p->total_num = total_num;
|
||||
/* init write pointer to start of payload buffer */
|
||||
p->wptr = p->payload;
|
||||
|
||||
if (blocksize > 5) {
|
||||
/* copy the data from index 5 to the end of
|
||||
the blocksize from the temporary buffer to
|
||||
the start of the decrypted buffer */
|
||||
memcpy(p->wptr, &block[5], blocksize - 5);
|
||||
p->wptr += blocksize - 5; /* advance write pointer */
|
||||
}
|
||||
|
||||
/* init the data_num field to the number of bytes of
|
||||
the package read so far */
|
||||
p->data_num = p->wptr - p->payload;
|
||||
|
||||
/* we already dealt with a blocksize worth of data */
|
||||
numbytes -= blocksize;
|
||||
}
|
||||
|
||||
/* how much there is left to add to the current payload
|
||||
package */
|
||||
remainpack = p->total_num - p->data_num;
|
||||
|
||||
if (numbytes > remainpack) {
|
||||
/* if we have more data in the buffer than what is going into this
|
||||
particular packet, we limit this round to this packet only */
|
||||
numbytes = remainpack;
|
||||
}
|
||||
|
||||
if (encrypted) {
|
||||
/* At the end of the incoming stream, there is a MAC,
|
||||
and we don't want to decrypt that since we need it
|
||||
"raw". We MUST however decrypt the padding data
|
||||
since it is used for the hash later on. */
|
||||
int skip = session->remote.mac->mac_len;
|
||||
|
||||
/* if what we have plus numbytes is bigger than the
|
||||
total minus the skip margin, we should lower the
|
||||
amount to decrypt even more */
|
||||
if ((p->data_num + numbytes) > (p->total_num - skip)) {
|
||||
numdecrypt = (p->total_num - skip) - p->data_num;
|
||||
} else {
|
||||
int frac;
|
||||
numdecrypt = numbytes;
|
||||
frac = numdecrypt % blocksize;
|
||||
if (frac) {
|
||||
/* not an aligned amount of blocks,
|
||||
align it */
|
||||
numdecrypt -= frac;
|
||||
/* and make it no unencrypted data
|
||||
after it */
|
||||
numbytes = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* unencrypted data should not be decrypted at all */
|
||||
numdecrypt = 0;
|
||||
}
|
||||
|
||||
/* if there are bytes to decrypt, do that */
|
||||
if (numdecrypt > 0) {
|
||||
/* now decrypt the lot */
|
||||
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
||||
if (rc != LIBSSH2_ERROR_NONE) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* advance the read pointer */
|
||||
p->readidx += numdecrypt;
|
||||
/* advance write pointer */
|
||||
p->wptr += numdecrypt;
|
||||
/* increse data_num */
|
||||
p->data_num += numdecrypt;
|
||||
|
||||
/* bytes left to take care of without decryption */
|
||||
numbytes -= numdecrypt;
|
||||
}
|
||||
|
||||
/* if there are bytes to copy that aren't decrypted, simply
|
||||
copy them as-is to the target buffer */
|
||||
if (numbytes > 0) {
|
||||
memcpy(p->wptr, &p->buf[p->readidx], numbytes);
|
||||
|
||||
/* advance the read pointer */
|
||||
p->readidx += numbytes;
|
||||
/* advance write pointer */
|
||||
p->wptr += numbytes;
|
||||
/* increse data_num */
|
||||
p->data_num += numbytes;
|
||||
}
|
||||
|
||||
/* now check how much data there's left to read to finish the
|
||||
current packet */
|
||||
remainpack = p->total_num - p->data_num;
|
||||
|
||||
if (!remainpack) {
|
||||
/* we have a full packet */
|
||||
libssh2_transport_read_point1:
|
||||
rc = fullpacket(session, encrypted);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
|
||||
if (session->packAdd_state != libssh2_NB_state_idle)
|
||||
{
|
||||
/* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
|
||||
* libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that
|
||||
* returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle,
|
||||
* then the packet has been added to the brigade, but some
|
||||
* immediate action that was taken based on the packet
|
||||
* type (such as key re-exchange) is not yet complete.
|
||||
* Clear the way for a new packet to be read in.
|
||||
*/
|
||||
session->readPack_encrypted = encrypted;
|
||||
session->readPack_state = libssh2_NB_state_jump1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
p->total_num = 0; /* no packet buffer available */
|
||||
|
||||
return rc;
|
||||
}
|
||||
} while (1); /* loop */
|
||||
|
||||
return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */
|
||||
}
|
||||
|
||||
static int
|
||||
send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
|
||||
size_t data_len, ssize_t *ret)
|
||||
{
|
||||
ssize_t rc;
|
||||
ssize_t length;
|
||||
struct transportpacket *p = &session->packet;
|
||||
|
||||
if (!p->olen) {
|
||||
*ret = 0;
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
/* send as much as possible of the existing packet */
|
||||
if ((data != p->odata) || (data_len != p->olen)) {
|
||||
/* When we are about to complete the sending of a packet, it is vital
|
||||
that the caller doesn't try to send a new/different packet since
|
||||
we don't add this one up until the previous one has been sent. To
|
||||
make the caller really notice his/hers flaw, we return error for
|
||||
this case */
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
}
|
||||
|
||||
*ret = 1; /* set to make our parent return */
|
||||
|
||||
/* number of bytes left to send */
|
||||
length = p->ototal_num - p->osent;
|
||||
|
||||
rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
if (rc < 0)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Error sending %d bytes: %d", length, -rc);
|
||||
else {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
|
||||
p->osent);
|
||||
debugdump(session, "libssh2_transport_write send()",
|
||||
&p->outbuf[p->osent], rc);
|
||||
}
|
||||
|
||||
if (rc == length) {
|
||||
/* the remainder of the package was sent */
|
||||
p->ototal_num = 0;
|
||||
p->olen = 0;
|
||||
/* we leave *ret set so that the parent returns as we MUST return back
|
||||
a send success now, so that we don't risk sending EAGAIN later
|
||||
which then would confuse the parent function */
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
|
||||
}
|
||||
else if (rc < 0) {
|
||||
/* nothing was sent */
|
||||
if (rc != -EAGAIN)
|
||||
/* send failure! */
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
|
||||
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
p->osent += rc; /* we sent away this much data */
|
||||
|
||||
return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_transport_send
|
||||
*
|
||||
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*
|
||||
* The data is provided as _two_ data areas that are combined by this
|
||||
* function. The 'data' part is sent immediately before 'data2'. 'data2' may
|
||||
* be set to NULL to only use a single part.
|
||||
*
|
||||
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||
* not sent yet. If it does so, the caller should call this function again as
|
||||
* soon as it is likely that more data can be sent, and this function MUST
|
||||
* then be called with the same argument set (same data pointer and same
|
||||
* data_len) until ERROR_NONE or failure is returned.
|
||||
*
|
||||
* This function DOES NOT call _libssh2_error() on any errors.
|
||||
*/
|
||||
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
const unsigned char *data, size_t data_len,
|
||||
const unsigned char *data2, size_t data2_len)
|
||||
{
|
||||
int blocksize =
|
||||
(session->state & LIBSSH2_STATE_NEWKEYS) ?
|
||||
session->local.crypt->blocksize : 8;
|
||||
int padding_length;
|
||||
size_t packet_length;
|
||||
int total_length;
|
||||
#ifdef RANDOM_PADDING
|
||||
int rand_max;
|
||||
int seed = data[0]; /* FIXME: make this random */
|
||||
#endif
|
||||
struct transportpacket *p = &session->packet;
|
||||
int encrypted;
|
||||
ssize_t ret;
|
||||
int rc;
|
||||
const unsigned char *orgdata = data;
|
||||
size_t orgdata_len = data_len;
|
||||
|
||||
/*
|
||||
* If the last read operation was interrupted in the middle of a key
|
||||
* exchange, we must complete that key exchange before continuing to write
|
||||
* further data.
|
||||
*
|
||||
* See the similar block in _libssh2_transport_read for more details.
|
||||
*/
|
||||
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||
/* Don't write any new packets if we're still in the middle of a key
|
||||
* exchange. */
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
|
||||
" key re-exchange from _libssh2_transport_send");
|
||||
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
debugdump(session, "libssh2_transport_write plain", data, data_len);
|
||||
if(data2)
|
||||
debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
|
||||
|
||||
/* FIRST, check if we have a pending write to complete. send_existing
|
||||
only sanity-check data and data_len and not data2 and data2_len!! */
|
||||
rc = send_existing(session, data, data_len, &ret);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
|
||||
if (ret)
|
||||
/* set by send_existing if data was sent */
|
||||
return rc;
|
||||
|
||||
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
|
||||
|
||||
if (encrypted && session->local.comp->compress) {
|
||||
/* the idea here is that these function must fail if the output gets
|
||||
larger than what fits in the assigned buffer so thus they don't
|
||||
check the input size as we don't know how much it compresses */
|
||||
size_t dest_len = MAX_SSH_PACKET_LEN-5-256;
|
||||
size_t dest2_len = dest_len;
|
||||
|
||||
/* compress directly to the target buffer */
|
||||
rc = session->local.comp->comp(session,
|
||||
&p->outbuf[5], &dest_len,
|
||||
data, data_len,
|
||||
&session->local.comp_abstract);
|
||||
if(rc)
|
||||
return rc; /* compression failure */
|
||||
|
||||
if(data2 && data2_len) {
|
||||
/* compress directly to the target buffer right after where the
|
||||
previous call put data */
|
||||
dest2_len -= dest_len;
|
||||
|
||||
rc = session->local.comp->comp(session,
|
||||
&p->outbuf[5+dest_len], &dest2_len,
|
||||
data2, data2_len,
|
||||
&session->local.comp_abstract);
|
||||
}
|
||||
else
|
||||
dest2_len = 0;
|
||||
if(rc)
|
||||
return rc; /* compression failure */
|
||||
|
||||
data_len = dest_len + dest2_len; /* use the combined length */
|
||||
}
|
||||
else {
|
||||
if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100))
|
||||
/* too large packet, return error for this until we make this
|
||||
function split it up and send multiple SSH packets */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
|
||||
/* copy the payload data */
|
||||
memcpy(&p->outbuf[5], data, data_len);
|
||||
if(data2 && data2_len)
|
||||
memcpy(&p->outbuf[5+data_len], data2, data2_len);
|
||||
data_len += data2_len; /* use the combined length */
|
||||
}
|
||||
|
||||
|
||||
/* RFC4253 says: Note that the length of the concatenation of
|
||||
'packet_length', 'padding_length', 'payload', and 'random padding'
|
||||
MUST be a multiple of the cipher block size or 8, whichever is
|
||||
larger. */
|
||||
|
||||
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
|
||||
|
||||
packet_length = data_len + 1 + 4; /* 1 is for padding_length field
|
||||
4 for the packet_length field */
|
||||
|
||||
/* at this point we have it all except the padding */
|
||||
|
||||
/* first figure out our minimum padding amount to make it an even
|
||||
block size */
|
||||
padding_length = blocksize - (packet_length % blocksize);
|
||||
|
||||
/* if the padding becomes too small we add another blocksize worth
|
||||
of it (taken from the original libssh2 where it didn't have any
|
||||
real explanation) */
|
||||
if (padding_length < 4) {
|
||||
padding_length += blocksize;
|
||||
}
|
||||
#ifdef RANDOM_PADDING
|
||||
/* FIXME: we can add padding here, but that also makes the packets
|
||||
bigger etc */
|
||||
|
||||
/* now we can add 'blocksize' to the padding_length N number of times
|
||||
(to "help thwart traffic analysis") but it must be less than 255 in
|
||||
total */
|
||||
rand_max = (255 - padding_length) / blocksize + 1;
|
||||
padding_length += blocksize * (seed % rand_max);
|
||||
#endif
|
||||
|
||||
packet_length += padding_length;
|
||||
|
||||
/* append the MAC length to the total_length size */
|
||||
total_length =
|
||||
packet_length + (encrypted ? session->local.mac->mac_len : 0);
|
||||
|
||||
/* store packet_length, which is the size of the whole packet except
|
||||
the MAC and the packet_length field itself */
|
||||
_libssh2_htonu32(p->outbuf, packet_length - 4);
|
||||
/* store padding_length */
|
||||
p->outbuf[4] = padding_length;
|
||||
|
||||
/* fill the padding area with random junk */
|
||||
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
|
||||
|
||||
if (encrypted) {
|
||||
size_t i;
|
||||
|
||||
/* Calculate MAC hash. Put the output at index packet_length,
|
||||
since that size includes the whole packet. The MAC is
|
||||
calculated on the entire unencrypted packet, including all
|
||||
fields except the MAC field itself. */
|
||||
session->local.mac->hash(session, p->outbuf + packet_length,
|
||||
session->local.seqno, p->outbuf,
|
||||
packet_length, NULL, 0,
|
||||
&session->local.mac_abstract);
|
||||
|
||||
/* Encrypt the whole packet data, one block size at a time.
|
||||
The MAC field is not encrypted. */
|
||||
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||
unsigned char *ptr = &p->outbuf[i];
|
||||
if (session->local.crypt->crypt(session, ptr,
|
||||
&session->local.crypt_abstract))
|
||||
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
|
||||
}
|
||||
}
|
||||
|
||||
session->local.seqno++;
|
||||
|
||||
ret = LIBSSH2_SEND(session, p->outbuf, total_length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
if (ret < 0)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Error sending %d bytes: %d", total_length, -ret);
|
||||
else {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p",
|
||||
ret, total_length, p->outbuf);
|
||||
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
|
||||
}
|
||||
|
||||
if (ret != total_length) {
|
||||
if (ret >= 0 || ret == -EAGAIN) {
|
||||
/* the whole packet could not be sent, save the rest */
|
||||
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
p->odata = orgdata;
|
||||
p->olen = orgdata_len;
|
||||
p->osent = ret <= 0 ? 0 : ret;
|
||||
p->ototal_num = total_length;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
}
|
||||
|
||||
/* the whole thing got sent away */
|
||||
p->odata = NULL;
|
||||
p->olen = 0;
|
||||
|
||||
return LIBSSH2_ERROR_NONE; /* all is good */
|
||||
}
|
||||
87
vendor/libssh2-1.4.2/src/transport.h
vendored
87
vendor/libssh2-1.4.2/src/transport.h
vendored
|
|
@ -1,87 +0,0 @@
|
|||
#ifndef __LIBSSH2_TRANSPORT_H
|
||||
#define __LIBSSH2_TRANSPORT_H
|
||||
|
||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file handles reading and writing to the SECSH transport layer. RFC4253.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
/*
|
||||
* libssh2_transport_send
|
||||
*
|
||||
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*
|
||||
* The data is provided as _two_ data areas that are combined by this
|
||||
* function. The 'data' part is sent immediately before 'data2'. 'data2' can
|
||||
* be set to NULL (or data2_len to 0) to only use a single part.
|
||||
*
|
||||
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||
* not sent yet. If it does so, the caller should call this function again as
|
||||
* soon as it is likely that more data can be sent, and this function MUST
|
||||
* then be called with the same argument set (same data pointer and same
|
||||
* data_len) until ERROR_NONE or failure is returned.
|
||||
*
|
||||
* This function DOES NOT call _libssh2_error() on any errors.
|
||||
*/
|
||||
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
const unsigned char *data, size_t data_len,
|
||||
const unsigned char *data2, size_t data2_len);
|
||||
|
||||
/*
|
||||
* _libssh2_transport_read
|
||||
*
|
||||
* Collect a packet into the input brigade block only controls whether or not
|
||||
* to wait for a packet to start.
|
||||
*
|
||||
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
|
||||
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
|
||||
* packet.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*/
|
||||
int _libssh2_transport_read(LIBSSH2_SESSION * session);
|
||||
|
||||
#endif /* __LIBSSH2_TRANSPORT_H */
|
||||
1687
vendor/libssh2-1.4.2/src/userauth.c
vendored
1687
vendor/libssh2-1.4.2/src/userauth.c
vendored
File diff suppressed because it is too large
Load diff
50
vendor/libssh2-1.4.2/src/userauth.h
vendored
50
vendor/libssh2-1.4.2/src/userauth.h
vendored
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef LIBSSH2_USERAUTH_H
|
||||
#define LIBSSH2_USERAUTH_H
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
unsigned int username_len,
|
||||
const unsigned char *pubkeydata,
|
||||
unsigned long pubkeydata_len,
|
||||
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
|
||||
void *abstract);
|
||||
|
||||
#endif /* LIBSSH2_USERAUTH_H */
|
||||
54
vendor/libssh2-1.4.2/src/version.c
vendored
54
vendor/libssh2-1.4.2/src/version.c
vendored
|
|
@ -1,54 +0,0 @@
|
|||
/* Copyright (C) 2009 Daniel Stenberg. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
/*
|
||||
libssh2_version() can be used like this:
|
||||
|
||||
if (!libssh2_version(LIBSSH2_VERSION_NUM)) {
|
||||
fprintf (stderr, "Runtime libssh2 version too old!\n");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
LIBSSH2_API
|
||||
const char *libssh2_version(int req_version_num)
|
||||
{
|
||||
if(req_version_num <= LIBSSH2_VERSION_NUM)
|
||||
return LIBSSH2_VERSION;
|
||||
return NULL; /* this is not a suitable library! */
|
||||
}
|
||||
Loading…
Reference in a new issue