mirror of
https://github.com/tmate-io/tmate.git
synced 2024-12-23 23:29:15 +01:00
Adding libssh
This commit is contained in:
parent
220b2afb3c
commit
0f7ccda4fb
@ -22,6 +22,7 @@ CFLAGS += -D_GNU_SOURCE
|
||||
endif
|
||||
|
||||
CFLAGS += -Wno-unused-parameter -Wno-unused-variable
|
||||
CFLAGS += -Ilibssh/include/
|
||||
|
||||
# Set flags for gcc. gcc4 whines abouts silly stuff so it needs slightly
|
||||
# different flags.
|
||||
@ -237,3 +238,9 @@ endif
|
||||
if NO_B64_NTOP
|
||||
nodist_tmate_SOURCES += compat/b64_ntop.c
|
||||
endif
|
||||
|
||||
tmate_LDADD = libssh/build/src/libssh.a
|
||||
|
||||
libssh/build/src/libssh.a:
|
||||
cd libssh/build && cmake .. -DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_PCAP=OFF -DWITH_STATIC_LIB=ON
|
||||
+make -C libssh/build ssh_static
|
||||
|
@ -107,8 +107,12 @@ AC_MSG_RESULT($found_glibc)
|
||||
# Look for clock_gettime. Must come before event_init.
|
||||
AC_SEARCH_LIBS(clock_gettime, rt)
|
||||
|
||||
AC_SEARCH_LIBS(ssh_new, ssh)
|
||||
AC_SEARCH_LIBS(msgpack_object_print, msgpack)
|
||||
AC_CHECK_LIB(z, inflate, [],
|
||||
[AC_MSG_ERROR([zlib library required])])
|
||||
AC_CHECK_LIB(crypto,CRYPTO_new_ex_data, [],
|
||||
[AC_MSG_ERROR([OpenSSL library required])])
|
||||
AC_CHECK_LIB(ssl, SSL_library_init, [],
|
||||
[AC_MSG_ERROR([OpenSSL library required])])
|
||||
|
||||
# Look for libevent.
|
||||
PKG_CHECK_MODULES(
|
||||
|
8
libssh/.gitignore
vendored
Normal file
8
libssh/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
*.a
|
||||
*.o
|
||||
.*
|
||||
*.swp
|
||||
*~$
|
||||
build
|
||||
cscope.*
|
||||
tags
|
15
libssh/AUTHORS
Normal file
15
libssh/AUTHORS
Normal file
@ -0,0 +1,15 @@
|
||||
Author(s):
|
||||
Aris Adamantiadis <aris@0xbadc0de.be> (project initiator)
|
||||
|
||||
Andreas Schneider <mail@cynapses.org> (developer)
|
||||
|
||||
Nick Zitzmann <seiryu (at) comcast (dot) net> (mostly client SFTP stuff)
|
||||
|
||||
Norbert Kiesel <nkiesel (at) tbdnetworks (dot) com> (getaddrinfo and other patches)
|
||||
|
||||
Jean-Philippe Garcia Ballester <giga (at) le-pec (dot) org> (Port to libgcrypt and configure.in voodoo, debian packaging)
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Laurent Bigonville <bigon (at) bigon (dot) be> (debian packaging)
|
||||
|
24
libssh/BSD
Normal file
24
libssh/BSD
Normal file
@ -0,0 +1,24 @@
|
||||
Some parts are under the BSDv2 License :
|
||||
|
||||
|
||||
Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
|
136
libssh/CMakeLists.txt
Normal file
136
libssh/CMakeLists.txt
Normal file
@ -0,0 +1,136 @@
|
||||
project(libssh C)
|
||||
|
||||
# Required cmake version
|
||||
cmake_minimum_required(VERSION 2.6.0)
|
||||
|
||||
# global needed variables
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "5")
|
||||
set(APPLICATION_VERSION_PATCH "90")
|
||||
|
||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||
|
||||
# SOVERSION scheme: CURRENT.AGE.REVISION
|
||||
# If there was an incompatible interface change:
|
||||
# Increment CURRENT. Set AGE and REVISION to 0
|
||||
# If there was a compatible interface change:
|
||||
# Increment AGE. Set REVISION to 0
|
||||
# If the source code was changed, but there were no interface changes:
|
||||
# Increment REVISION.
|
||||
set(LIBRARY_VERSION "4.3.0")
|
||||
set(LIBRARY_SOVERSION "4")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
set(CMAKE_MODULE_PATH
|
||||
${CMAKE_SOURCE_DIR}/cmake/Modules
|
||||
)
|
||||
|
||||
# add definitions
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefinePlatformDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
include(DefineInstallationPaths)
|
||||
include(DefineOptions.cmake)
|
||||
include(CPackConfig.cmake)
|
||||
|
||||
# disallow in-source build
|
||||
include(MacroEnsureOutOfSourceBuild)
|
||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
||||
|
||||
# add macros
|
||||
include(MacroAddPlugin)
|
||||
include(MacroCopyFile)
|
||||
|
||||
# search for libraries
|
||||
if (WITH_ZLIB)
|
||||
find_package(ZLIB REQUIRED)
|
||||
endif (WITH_ZLIB)
|
||||
|
||||
if (WITH_GCRYPT)
|
||||
find_package(GCrypt 1.5.0 REQUIRED)
|
||||
if (NOT GCRYPT_FOUND)
|
||||
message(FATAL_ERROR "Could not find GCrypt")
|
||||
endif (NOT GCRYPT_FOUND)
|
||||
else (WITH_GCRYPT)
|
||||
find_package(OpenSSL)
|
||||
if (NOT OPENSSL_FOUND)
|
||||
find_package(GCrypt)
|
||||
if (NOT GCRYPT_FOUND)
|
||||
message(FATAL_ERROR "Could not find OpenSSL or GCrypt")
|
||||
endif (NOT GCRYPT_FOUND)
|
||||
endif (NOT OPENSSL_FOUND)
|
||||
endif(WITH_GCRYPT)
|
||||
|
||||
# Find out if we have threading available
|
||||
set(CMAKE_THREAD_PREFER_PTHREADS ON)
|
||||
find_package(Threads)
|
||||
|
||||
# config.h checks
|
||||
include(ConfigureChecks.cmake)
|
||||
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
# check subdirectories
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(include)
|
||||
add_subdirectory(src)
|
||||
|
||||
# pkg-config file
|
||||
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
|
||||
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/pkgconfig
|
||||
COMPONENT
|
||||
pkgconfig
|
||||
)
|
||||
|
||||
# cmake config files
|
||||
configure_file(libssh-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake @ONLY)
|
||||
configure_file(libssh-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake @ONLY)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DIR}
|
||||
COMPONENT
|
||||
devel
|
||||
)
|
||||
|
||||
# in tree build settings
|
||||
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
|
||||
|
||||
add_subdirectory(examples)
|
||||
|
||||
if (WITH_TESTING)
|
||||
find_package(CMocka REQUIRED)
|
||||
include(AddCMockaTest)
|
||||
add_subdirectory(tests)
|
||||
endif (WITH_TESTING)
|
||||
|
||||
|
||||
message(STATUS "********************************************")
|
||||
message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
||||
|
||||
message(STATUS "zlib support: ${WITH_ZLIB}")
|
||||
message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
|
||||
message(STATUS "SSH-1 support: ${WITH_SSH1}")
|
||||
message(STATUS "SFTP support: ${WITH_SFTP}")
|
||||
message(STATUS "Server support : ${WITH_SERVER}")
|
||||
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
|
||||
message(STATUS "With static library: ${WITH_STATIC_LIB}")
|
||||
message(STATUS "Unit testing: ${WITH_TESTING}")
|
||||
message(STATUS "Client code Unit testing: ${WITH_CLIENT_TESTING}")
|
||||
if (WITH_INTERNAL_DOC)
|
||||
message(STATUS "Internal documentation generation")
|
||||
else (WITH_INTERNAL_DOC)
|
||||
message(STATUS "Public API documentation generation")
|
||||
endif (WITH_INTERNAL_DOC)
|
||||
message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
|
||||
message(STATUS "********************************************")
|
||||
|
460
libssh/COPYING
Normal file
460
libssh/COPYING
Normal file
@ -0,0 +1,460 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
Linking with OpenSSL
|
||||
17. In addition, as a special exception, we give permission to link the code of its release of libssh with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Lesser General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
|
||||
END OF TERMS AND CONDITIONS
|
53
libssh/CPackConfig.cmake
Normal file
53
libssh/CPackConfig.cmake
Normal file
@ -0,0 +1,53 @@
|
||||
# For help take a look at:
|
||||
# http://www.cmake.org/Wiki/CMake:CPackConfiguration
|
||||
|
||||
### general settings
|
||||
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH library")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README")
|
||||
set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
||||
|
||||
|
||||
### versions
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "5")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "90")
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
|
||||
### source generator
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
if (WIN32)
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
|
||||
### nsis generator
|
||||
find_package(NSIS)
|
||||
if (NSIS_MAKE)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
|
||||
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||
endif (NSIS_MAKE)
|
||||
endif (WIN32)
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "libssh")
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME ${APPLICATION_NAME}-${CPACK_PACKAGE_VERSION})
|
||||
|
||||
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
|
||||
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers")
|
||||
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
|
||||
"Libraries used to build programs which use libssh")
|
||||
set(CPACK_COMPONENT_HEADERS_DESCRIPTION
|
||||
"C/C++ header files for use with libssh")
|
||||
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
|
||||
#set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime")
|
||||
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
|
||||
set(CPACK_COMPONENT_HEADERS_GROUP "Development")
|
||||
|
||||
include(CPack)
|
9
libssh/CTestConfig.cmake
Normal file
9
libssh/CTestConfig.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
set(UPDATE_TYPE "true")
|
||||
|
||||
set(CTEST_PROJECT_NAME "libssh")
|
||||
set(CTEST_NIGHTLY_START_TIME "01:00:00 CET")
|
||||
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE "test.libssh.org")
|
||||
set(CTEST_DROP_LOCATION "/submit.php?project=libssh")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
298
libssh/ChangeLog
Normal file
298
libssh/ChangeLog
Normal file
@ -0,0 +1,298 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
version 0.5.x (released 2012-xx-xx)
|
||||
* Added new PKI infrastructure.
|
||||
* Added simplified user auth functions.
|
||||
* Added ECDSA pubkey support.
|
||||
* Added ECDSA hostkey support.
|
||||
* Added diffie-hellman-group14-sha1 support.
|
||||
* Fixed a ton of bugs.
|
||||
|
||||
version 0.5.0 (released 2011-06-01)
|
||||
* Added ssh_ prefix to all functions.
|
||||
* Added complete Windows support.
|
||||
* Added improved server support.
|
||||
* Added unit tests for a lot of functions.
|
||||
* Added asynchronous service request.
|
||||
* Added a multiplatform ssh_getpass() function.
|
||||
* Added a tutorial.
|
||||
* Added a lot of documentation.
|
||||
* Fixed a lot of bugs.
|
||||
* Fixed several memory leaks.
|
||||
|
||||
version 0.4.8 (released 2011-01-15)
|
||||
* Fixed memory leaks in session signing.
|
||||
* Fixed memory leak in ssh_print_hexa.
|
||||
* Fixed problem with ssh_connect w/ timeout and fd > 1024.
|
||||
* Fixed some warnings on OS/2.
|
||||
* Fixed installation path for OS/2.
|
||||
|
||||
version 0.4.7 (released 2010-12-28)
|
||||
* Fixed a possible memory leak in ssh_get_user_home().
|
||||
* Fixed a memory leak in sftp_xstat.
|
||||
* Fixed uninitialized fd->revents member.
|
||||
* Fixed timout value in ssh_channel_accept().
|
||||
* Fixed length checks in ssh_analyze_banner().
|
||||
* Fixed a possible data overread and crash bug.
|
||||
* Fixed setting max_fd which breaks ssh_select().
|
||||
* Fixed some pedantic build warnings.
|
||||
* Fixed a memory leak with session->bindaddr.
|
||||
|
||||
version 0.4.6 (released 2010-09-03)
|
||||
* Added a cleanup function to free the ws2_32 library.
|
||||
* Fixed build with gcc 3.4.
|
||||
* Fixed the Windows build on Vista and newer.
|
||||
* Fixed the usage of WSAPoll() on Windows.
|
||||
* Fixed "@deprecated" in doxygen
|
||||
* Fixed some mingw warnings.
|
||||
* Fixed handling of opened channels.
|
||||
* Fixed keepalive problem on older openssh servers.
|
||||
* Fixed testing for big endian on Windows.
|
||||
* Fixed the Windows preprocessor macros and defines.
|
||||
|
||||
version 0.4.5 (released 2010-07-13)
|
||||
* Added option to bind a client to an ip address.
|
||||
* Fixed the ssh socket polling function.
|
||||
* Fixed Windows related bugs in bsd_poll().
|
||||
* Fixed serveral build warnings.
|
||||
|
||||
version 0.4.4 (released 2010-06-01)
|
||||
* Fixed a bug in the expand function for escape sequences.
|
||||
* Fixed a bug in the tilde expand function.
|
||||
* Fixed a bug in setting the options.
|
||||
|
||||
version 0.4.3 (released 2010-05-18)
|
||||
* Added global/keepalive responses.
|
||||
* Added runtime detection of WSAPoll().
|
||||
* Added a select(2) based poll-emulation if poll(2) is not available.
|
||||
* Added a function to expand an escaped string.
|
||||
* Added a function to expand the tilde from a path.
|
||||
* Added a proxycommand support.
|
||||
* Added ssh_privatekey_type public function
|
||||
* Added the possibility to define _OPENSSL_DIR and _ZLIB_DIR.
|
||||
* Fixed sftp_chown.
|
||||
* Fixed sftp_rename on protocol version 3.
|
||||
* Fixed a blocking bug in channel_poll.
|
||||
* Fixed config parsing wich has overwritten user specified values.
|
||||
* Fixed hashed [host]:port format in knownhosts
|
||||
* Fixed Windows build.
|
||||
* Fixed doublefree happening after a negociation error.
|
||||
* Fixed aes*-ctr with <= OpenSSL 0.9.7b.
|
||||
* Fixed some documentation.
|
||||
* Fixed exec example which has broken read usage.
|
||||
* Fixed broken algorithm choice for server.
|
||||
* Fixed a typo that we don't export all symbols.
|
||||
* Removed the unneeded dependency to doxygen.
|
||||
* Build examples only on the Linux plattform.
|
||||
|
||||
version 0.4.2 (released 2010-03-15)
|
||||
* Added owner and group information in sftp attributes.
|
||||
* Added missing SSH_OPTIONS_FD option.
|
||||
* Added printout of owner and group in the sftp example.
|
||||
* Added a prepend function for ssh_list.
|
||||
* Added send back replies to openssh's keepalives.
|
||||
* Fixed documentation in scp code
|
||||
* Fixed longname parsing, this only workings with readdir.
|
||||
* Fixed and added support for several identity files.
|
||||
* Fixed sftp_parse_longname() on Windows.
|
||||
* Fixed a race condition bug in ssh_scp_close()
|
||||
* Remove config support for SSHv1 Cipher variable.
|
||||
* Rename ssh_list_add to ssh_list_append.
|
||||
* Rename ssh_list_get_head to ssh_list_pop_head
|
||||
|
||||
version 0.4.1 (released 2010-02-13)
|
||||
* Added support for aes128-ctr, aes192-ctr and aes256-ctr encryption.
|
||||
* Added an example for exec.
|
||||
* Added private key type detection feature in privatekey_from_file().
|
||||
* Fixed zlib compression fallback.
|
||||
* Fixed kex bug that client preference should be prioritary
|
||||
* Fixed known_hosts file set by the user.
|
||||
* Fixed a memleak in channel_accept().
|
||||
* Fixed underflow when leave_function() are unbalanced
|
||||
* Fixed memory corruption in handle_channel_request_open().
|
||||
* Fixed closing of a file handle case of errors in privatekey_from_file().
|
||||
* Fixed ssh_get_user_home_dir() to be thread safe.
|
||||
* Fixed the doxygen documentation.
|
||||
|
||||
version 0.4.0 (released 2009-12-10)
|
||||
* Added scp support.
|
||||
* Added support for sending signals (RFC 4254, section 6.9).
|
||||
* Added MSVC support.
|
||||
* Added support for ~/.ssh/config.
|
||||
* Added sftp extension support.
|
||||
* Added X11 forwarding support for client.
|
||||
* Added forward listening.
|
||||
* Added support for openssh extensions (statvfs, fstatvfs).
|
||||
* Added a cleaned up interface for setting options.
|
||||
* Added a generic way to handle sockets asynchronously.
|
||||
* Added logging of the sftp flags used to open a file.
|
||||
* Added full poll() support and poll-emulation for win32.
|
||||
* Added missing 64bit functions in sftp.
|
||||
* Added support for ~/ and SSH_DIR/ in filenames instead of %s/.
|
||||
* Fixed Fix channel_get_exit_status bug.
|
||||
* Fixed calltrace logging to make it optional.
|
||||
* Fixed compilation on Solaris.
|
||||
* Fixed resolving of ip addresses.
|
||||
* Fixed libssh compilation without server support.
|
||||
* Fixed possible memory corruptions (ticket #14).
|
||||
|
||||
version 0.3.4 (released 2009-09-14)
|
||||
* Added ssh_basename and ssh_dirname.
|
||||
* Added a portable ssh_mkdir function.
|
||||
* Added a sftp_tell64() function.
|
||||
* Added missing NULL pointer checks to crypt_set_algorithms_server.
|
||||
* Fixed ssh_write_knownhost if ~/.ssh doesn't exist.
|
||||
* Fixed a possible integer overflow in buffer_get_data().
|
||||
* Fixed possible security bug in packet_decrypt().
|
||||
* Fixed a possible stack overflow in agent code.
|
||||
|
||||
version 0.3.3 (released 2009-08-18)
|
||||
* Fixed double free pointer crash in dsa_public_to_string.
|
||||
* Fixed channel_get_exit_status bug.
|
||||
* Fixed ssh_finalize which didn't clear the flag.
|
||||
* Fixed memory leak introduced by previous bugfix.
|
||||
* Fixed channel_poll broken when delayed EOF recvd.
|
||||
* Fixed stupid "can't parse known host key" bug.
|
||||
* Fixed possible memory corruption (ticket #14).
|
||||
|
||||
version 0.3.2 (released 2009-08-05)
|
||||
* Added ssh_init() function.
|
||||
* Added sftp_readlink() function.
|
||||
* Added sftp_symlink() function.
|
||||
* Fixed ssh_write_knownhost().
|
||||
* Fixed compilation on Solaris.
|
||||
* Fixed SSHv1 compilation.
|
||||
|
||||
version 0.3.1 (released 2009-07-14)
|
||||
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||
* Fixed compilation of SSHv1.
|
||||
* Fixed several memory leaks.
|
||||
* Fixed possible infinite loops.
|
||||
* Fixed a possible crash bug.
|
||||
* Fixed build warnings.
|
||||
* Fixed cmake on BSD.
|
||||
version 0.3.1 (released 2009-07-14)
|
||||
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||
* Fixed compilation of SSHv1.
|
||||
* Fixed several memory leaks.
|
||||
* Fixed possible infinite loops.
|
||||
* Fixed a possible crash bug.
|
||||
* Fixed build warnings.
|
||||
* Fixed cmake on BSD.
|
||||
|
||||
version 0.3 (released 2009-05-21)
|
||||
* Added support for ssh-agent authentication.
|
||||
* Added POSIX like sftp implementation.
|
||||
* Added error checking to all functions.
|
||||
* Added const to arguments where it was needed.
|
||||
* Added a channel_get_exit_status() function.
|
||||
* Added a channel_read_buffer() function, channel_read() is now
|
||||
a POSIX like function.
|
||||
* Added a more generic auth callback function.
|
||||
* Added printf attribute checking for log and error functions.
|
||||
* Added runtime function tracer support.
|
||||
* Added NSIS build support with CPack.
|
||||
* Added openssh hashed host support.
|
||||
* Added API documentation for all public functions.
|
||||
* Added asynchronous SFTP read function.
|
||||
* Added a ssh_bind_set_fd() function.
|
||||
* Fixed known_hosts parsing.
|
||||
* Fixed a lot of build warnings.
|
||||
* Fixed the Windows build.
|
||||
* Fixed a lot of memory leaks.
|
||||
* Fixed a double free corruption in the server support.
|
||||
* Fixed the "ssh_accept:" bug in server support.
|
||||
* Fixed important channel bugs.
|
||||
* Refactored the socket handling.
|
||||
* Switched to CMake build system.
|
||||
* Improved performance.
|
||||
|
||||
version 0.2 (released 2007-11-29)
|
||||
* General cleanup
|
||||
* More comprehensive API
|
||||
* Up-to-date Doxygen documentation of each public function
|
||||
* Basic server-based support
|
||||
* Libgcrypt support (alternative to openssl and its license)
|
||||
* SSH1 support (disabled by default)
|
||||
* Added 3des-cbc
|
||||
* A lot of bugfixes
|
||||
|
||||
version 0.11-dev
|
||||
* Server implementation development.
|
||||
* Small bug corrected when connecting to sun ssh servers.
|
||||
* Channel wierdness corrected (writing huge data packets)
|
||||
* Channel_read_nonblocking added
|
||||
* Channel bug where stderr wasn't correctly read fixed.
|
||||
* Added sftp_file_set_nonblocking(), which is nonblocking SFTP IO
|
||||
* Connect_status callback.
|
||||
* Priv.h contains the internal functions, libssh.h the public interface
|
||||
* Options_set_timeout (thx marcelo) really working.
|
||||
* Tcp tunneling through channel_open_forward.
|
||||
* Channel_request_exec()
|
||||
* Channel_request_env()
|
||||
* Ssh_get_pubkey_hash()
|
||||
* Ssh_is_server_known()
|
||||
* Ssh_write_known_host()
|
||||
* Options_set_ssh_dir
|
||||
* How could this happen ! there weren't any channel_close !
|
||||
* Nasty channel_free bug resolved.
|
||||
* Removed the unsigned long all around the code. use only u8,u32 & u64.
|
||||
* It now compiles and runs under amd64 !
|
||||
* Channel_request_pty_size
|
||||
* Channel_change_pty_size
|
||||
* Options_copy()
|
||||
* Ported the doc to an HTML file.
|
||||
* Small bugfix in packet.c
|
||||
* Prefixed error constants with SSH_
|
||||
* Sftp_stat, sftp_lstat, sftp_fstat. thanks Michel Bardiaux for the patch.
|
||||
* Again channel number mismatch fixed.
|
||||
* Fixed a bug in ssh_select making the select fail when a signal has been
|
||||
caught.
|
||||
* Keyboard-interactive authentication working.
|
||||
|
||||
version 0.1 (released 2004-03-05)
|
||||
* Begining of sftp subsystem implementation.
|
||||
* Some cleanup into channels implementation
|
||||
* Now every channel functions is called by its CHANNEL handler.
|
||||
* Added channel_poll() and channel_read().
|
||||
* Changed the client so it uses the new channel_poll and channel_read interface
|
||||
* Small use-after-free bug with channels resolved
|
||||
* Changed stupidities in lot of function names.
|
||||
* Removed a debug output file opened by default.
|
||||
* Added API.txt, the libssh programmer handbook.
|
||||
* Various bug fixes from Nick Zitzmann.
|
||||
* Developed a cryptographic structure for handling protocols.
|
||||
* An autoconf script which took me half of a day to set up.
|
||||
* A ssh_select wrapper has been written.
|
||||
|
||||
version 0.0.4 (released 2003-10-10)
|
||||
* Some terminal code (eof handling) added
|
||||
* Channels bugfix (it still needs some tweaking though)
|
||||
* Zlib support
|
||||
* Added a wrapper.c file. The goal is to provide a similar API to every
|
||||
cryptographic functions. bignums and sha/md5 are wrapped now.
|
||||
* More work than it first looks.
|
||||
* Support for other crypto libs planed (lighter libs)
|
||||
* Fixed stupid select() bug.
|
||||
* Libssh now compiles and links with openssl 0.9.6
|
||||
* RSA pubkey authentication code now works !
|
||||
|
||||
version 0.0.3 (released 2003-09-15)
|
||||
* Added install target in makefile
|
||||
* Some cleanup in headers files and source code
|
||||
* Change default banner and project name to libssh.
|
||||
* New file auth.c to support more and more authentication ways
|
||||
* Bugfix(read offbyone) in send_kex
|
||||
* A base64 parser. don't read the source, it's awful. pure 0xbadc0de.
|
||||
* Changed the client filename to "ssh". logic isn't it ?
|
||||
* Dss publickey authentication ! still need to wait for the rsa one
|
||||
* Bugfix in packet.c
|
||||
* New misc.c contains misc functions
|
||||
|
||||
version 0.0.2 (released 2003-09-03)
|
||||
* Initial release.
|
||||
* Client supports both ssh and dss hostkey verification, but doesn't compare them to openssh's files. (~/.ssh/known_hosts)
|
||||
* The only supported authentication method is password.
|
||||
* Compiles on linux and openbsd. freebsd and netbsd should work, too
|
||||
* Lot of work which hasn't been discussed here.
|
59
libssh/CodingStyle
Normal file
59
libssh/CodingStyle
Normal file
@ -0,0 +1,59 @@
|
||||
Coding Style Conventions
|
||||
========================
|
||||
|
||||
Coding style guidelines are about reducing the number of unnecessary
|
||||
reformatting patches and making things easier for developers to work together.
|
||||
|
||||
You don't have to like them or even agree with them, but once put in place we
|
||||
all have to abide by them (or vote to change them). However, coding style
|
||||
should never outweigh coding itself and so the guidelines described here are
|
||||
hopefully easy enough to follow as they are very common and supported by tools
|
||||
and editors.
|
||||
|
||||
The basic style for C code is the Linux kernel coding style [1] with one
|
||||
excecption, we use 4 spaces instead of tabs. This closely matches what most
|
||||
libssh developers use already anyways, with a few exceptions as mentioned
|
||||
below.
|
||||
|
||||
To shorthen this here are the highlights:
|
||||
|
||||
* Maximum line width is 80 characters
|
||||
|
||||
The reason is not about people with low-res screens but rather sticking
|
||||
to 80 columns prevents you from easily nesting more than one level of
|
||||
if statements or other code blocks.
|
||||
|
||||
* Use 4 spaces to indent
|
||||
|
||||
* No trailing whitespaces
|
||||
|
||||
* Follow the K&R guidelines. We won't go through all of them here. Do you
|
||||
have a copy of "The C Programming Language" anyways right?
|
||||
|
||||
Editors
|
||||
========
|
||||
|
||||
VIM
|
||||
----
|
||||
|
||||
set ts=4 sw=4 et cindent
|
||||
|
||||
For Vim, the following settings in $HOME/.vimrc will also deal with
|
||||
displaying trailing whitespace:
|
||||
|
||||
if has("syntax") && (&t_Co > 2 || has("gui_running"))
|
||||
syntax on
|
||||
function! ActivateInvisibleCharIndicator()
|
||||
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
|
||||
highlight TrailingSpace ctermbg=Red
|
||||
endf
|
||||
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
|
||||
endif
|
||||
" Show tabs, trailing whitespace, and continued lines visually
|
||||
set list listchars=tab:»·,trail:·,extends:…
|
||||
|
||||
" highlight overly long lines same as TODOs.
|
||||
set textwidth=80
|
||||
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
|
||||
|
||||
[1] https://www.kernel.org/doc/Documentation/CodingStyle
|
179
libssh/ConfigureChecks.cmake
Normal file
179
libssh/ConfigureChecks.cmake
Normal file
@ -0,0 +1,179 @@
|
||||
include(CheckIncludeFile)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckTypeSize)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(TestBigEndian)
|
||||
|
||||
set(PACKAGE ${APPLICATION_NAME})
|
||||
set(VERSION ${APPLICATION_VERSION})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
set(LIBDIR ${LIB_INSTALL_DIR})
|
||||
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
|
||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
function(COMPILER_DUMPVERSION _OUTPUT_VERSION)
|
||||
# Remove whitespaces from the argument.
|
||||
# This is needed for CC="ccache gcc" cmake ..
|
||||
string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}")
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion
|
||||
OUTPUT_VARIABLE _COMPILER_VERSION
|
||||
)
|
||||
|
||||
string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
|
||||
_COMPILER_VERSION "${_COMPILER_VERSION}")
|
||||
|
||||
set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||
compiler_dumpversion(GNUCC_VERSION)
|
||||
if (NOT GNUCC_VERSION EQUAL 34)
|
||||
set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden")
|
||||
check_c_source_compiles(
|
||||
"void __attribute__((visibility(\"default\"))) test() {}
|
||||
int main(void){ return 0; }
|
||||
" WITH_VISIBILITY_HIDDEN)
|
||||
set(CMAKE_REQUIRED_FLAGS "")
|
||||
endif (NOT GNUCC_VERSION EQUAL 34)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||
|
||||
# HEADER FILES
|
||||
check_include_file(argp.h HAVE_ARGP_H)
|
||||
check_include_file(pty.h HAVE_PTY_H)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
|
||||
if (WIN32)
|
||||
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
|
||||
if (NOT HAVE_WSPIAPI_H)
|
||||
message(STATUS "WARNING: Without wspiapi.h, this build will only work on Windows XP and newer versions")
|
||||
endif (NOT HAVE_WSPIAPI_H)
|
||||
check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H)
|
||||
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
|
||||
set(HAVE_GETADDRINFO TRUE)
|
||||
set(HAVE_GETHOSTBYNAME TRUE)
|
||||
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
|
||||
|
||||
set(HAVE_SELECT TRUE)
|
||||
endif (WIN32)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
|
||||
|
||||
if (CMAKE_HAVE_PTHREAD_H)
|
||||
set(HAVE_PTHREAD_H 1)
|
||||
endif (CMAKE_HAVE_PTHREAD_H)
|
||||
|
||||
if (NOT WITH_GCRYPT)
|
||||
if (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H)
|
||||
set(HAVE_OPENSSL_ECC 1)
|
||||
endif (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H)
|
||||
|
||||
if (HAVE_OPENSSL_ECC)
|
||||
set(HAVE_ECC 1)
|
||||
endif (HAVE_OPENSSL_ECC)
|
||||
endif (NOT WITH_GCRYPT)
|
||||
|
||||
# FUNCTIONS
|
||||
|
||||
check_function_exists(strncpy HAVE_STRNCPY)
|
||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
|
||||
if (WIN32)
|
||||
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
|
||||
check_function_exists(_vsnprintf HAVE__VSNPRINTF)
|
||||
check_function_exists(_snprintf HAVE__SNPRINTF)
|
||||
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
|
||||
endif (WIN32)
|
||||
|
||||
if (UNIX)
|
||||
if (NOT LINUX)
|
||||
# libsocket (Solaris)
|
||||
check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET)
|
||||
if (HAVE_LIBSOCKET)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} socket)
|
||||
endif (HAVE_LIBSOCKET)
|
||||
|
||||
# libnsl/inet_pton (Solaris)
|
||||
check_library_exists(nsl inet_pton "" HAVE_LIBNSL)
|
||||
if (HAVE_LIBNSL)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} nsl)
|
||||
endif (HAVE_LIBNSL)
|
||||
|
||||
# librt
|
||||
check_library_exists(rt nanosleep "" HAVE_LIBRT)
|
||||
endif (NOT LINUX)
|
||||
|
||||
check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
|
||||
if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
|
||||
endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
|
||||
|
||||
check_library_exists(util forkpty "" HAVE_LIBUTIL)
|
||||
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
|
||||
check_function_exists(poll HAVE_POLL)
|
||||
check_function_exists(select HAVE_SELECT)
|
||||
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
|
||||
check_function_exists(ntohll HAVE_NTOHLL)
|
||||
check_function_exists(htonll HAVE_HTONLL)
|
||||
check_function_exists(strtoull HAVE_STRTOULL)
|
||||
check_function_exists(__strtoull HAVE___STRTOULL)
|
||||
endif (UNIX)
|
||||
|
||||
set(LIBSSH_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "libssh required system libraries")
|
||||
|
||||
# LIBRARIES
|
||||
if (OPENSSL_FOUND)
|
||||
set(HAVE_LIBCRYPTO 1)
|
||||
endif (OPENSSL_FOUND)
|
||||
|
||||
if (GCRYPT_FOUND)
|
||||
set(HAVE_LIBGCRYPT 1)
|
||||
if (GCRYPT_VERSION VERSION_GREATER "1.4.6")
|
||||
#set(HAVE_GCRYPT_ECC 1)
|
||||
#set(HAVE_ECC 1)
|
||||
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
|
||||
endif (GCRYPT_FOUND)
|
||||
|
||||
if (CMAKE_HAVE_THREADS_LIBRARY)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(HAVE_PTHREAD 1)
|
||||
endif (CMAKE_USE_PTHREADS_INIT)
|
||||
endif (CMAKE_HAVE_THREADS_LIBRARY)
|
||||
|
||||
# OPTIONS
|
||||
if (WITH_DEBUG_CRYPTO)
|
||||
set(DEBUG_CRYPTO 1)
|
||||
endif (WITH_DEBUG_CRYPTO)
|
||||
|
||||
if (WITH_DEBUG_CALLTRACE)
|
||||
set(DEBUG_CALLTRACE 1)
|
||||
endif (WITH_DEBUG_CALLTRACE)
|
||||
|
||||
# ENDIAN
|
||||
if (NOT WIN32)
|
||||
test_big_endian(WORDS_BIGENDIAN)
|
||||
endif (NOT WIN32)
|
27
libssh/DefineOptions.cmake
Normal file
27
libssh/DefineOptions.cmake
Normal file
@ -0,0 +1,27 @@
|
||||
option(WITH_ZLIB "Build with ZLIB support" ON)
|
||||
option(WITH_SSH1 "Build with SSH1 support" OFF)
|
||||
option(WITH_SFTP "Build with SFTP support" ON)
|
||||
option(WITH_SERVER "Build with SSH server support" ON)
|
||||
option(WITH_STATIC_LIB "Build with a static library" OFF)
|
||||
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
|
||||
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
||||
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
||||
option(WITH_PCAP "Compile with Pcap generation support" ON)
|
||||
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
|
||||
option(WITH_TESTING "Build with unit tests" OFF)
|
||||
option(WITH_CLIENT_TESTING "Build with client tests; requires a running sshd" OFF)
|
||||
option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
|
||||
|
||||
if (WITH_ZLIB)
|
||||
set(WITH_LIBZ ON)
|
||||
else (WITH_ZLIB)
|
||||
set(WITH_LIBZ OFF)
|
||||
endif (WITH_ZLIB)
|
||||
|
||||
if(WITH_BENCHMARKS)
|
||||
set(WITH_TESTING ON)
|
||||
endif(WITH_BENCHMARKS)
|
||||
|
||||
if (WITH_TESTING)
|
||||
set(WITH_STATIC_LIB ON)
|
||||
endif (WITH_TESTING)
|
99
libssh/INSTALL
Normal file
99
libssh/INSTALL
Normal file
@ -0,0 +1,99 @@
|
||||
# How to build from source
|
||||
|
||||
## Requirements
|
||||
|
||||
### Common requirements
|
||||
|
||||
In order to build libssh, you need to install several components:
|
||||
|
||||
- A C compiler
|
||||
- [CMake](http://www.cmake.org) >= 2.6.0.
|
||||
- [openssl](http://www.openssl.org) >= 0.9.8
|
||||
or
|
||||
- [gcrypt](http://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
|
||||
|
||||
optional:
|
||||
- [libz](http://www.zlib.net) >= 1.2
|
||||
|
||||
Note that these version numbers are version we know works correctly. If you
|
||||
build and run libssh successfully with an older version, please let us know.
|
||||
|
||||
Windows binaries known to be working:
|
||||
|
||||
- http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
- http://www.winimage.com/zLibDll/index.html
|
||||
|
||||
We installed them in C:\Program Files
|
||||
|
||||
## Building
|
||||
First, you need to configure the compilation, using CMake. Go inside the
|
||||
`build` dir. Create it if it doesn't exist.
|
||||
|
||||
GNU/Linux, MacOS X, MSYS/MinGW:
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
|
||||
make
|
||||
|
||||
On Windows you should choose a makefile gernerator with -G.
|
||||
|
||||
### CMake standard options
|
||||
Here is a list of the most interesting options provided out of the box by
|
||||
CMake.
|
||||
|
||||
- CMAKE_BUILD_TYPE: The type of build (can be Debug Release MinSizeRel
|
||||
RelWithDebInfo)
|
||||
- CMAKE_INSTALL_PREFIX: The prefix to use when running make install (Default
|
||||
to /usr/local on GNU/Linux and MacOS X)
|
||||
- CMAKE_C_COMPILER: The path to the C compiler
|
||||
- CMAKE_CXX_COMPILER: The path to the C++ compiler
|
||||
|
||||
### CMake options defined for libssh
|
||||
|
||||
Options are defined in the following files:
|
||||
|
||||
- DefineOptions.cmake
|
||||
|
||||
They can be changed with the -D option:
|
||||
|
||||
`cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DWITH_ZLIB=OFF ..`
|
||||
|
||||
### Browsing/editing CMake options
|
||||
|
||||
In addition to passing options on the command line, you can browse and edit
|
||||
CMake options using `cmakesetup` (Windows), `cmake-gui` or `ccmake` (GNU/Linux
|
||||
and MacOS X).
|
||||
|
||||
- Go to the build dir
|
||||
- On Windows: run `cmakesetup`
|
||||
- On GNU/Linux and MacOS X: run `ccmake ..`
|
||||
|
||||
### Useful Windows options:
|
||||
|
||||
If you have installed OpenSSL or ZLIB in non standard directories, maybe you
|
||||
want to set:
|
||||
|
||||
OPENSSL_ROOT_DIR
|
||||
|
||||
and
|
||||
|
||||
ZLIB_ROOT_DIR
|
||||
|
||||
## Installing
|
||||
|
||||
If you want to install libssh after compilation run:
|
||||
|
||||
make install
|
||||
|
||||
## Running
|
||||
|
||||
The libssh binary can be found in the `build/libssh` directory.
|
||||
You can use `build/examples/samplessh` which is a sample client to
|
||||
test libssh on UNIX.
|
||||
|
||||
## About this document
|
||||
|
||||
This document is written using [Markdown][] syntax, making it possible to
|
||||
provide usable information in both plain text and HTML format. Whenever
|
||||
modifying this document please use [Markdown][] syntax.
|
||||
|
||||
[markdown]: http://www.daringfireball.net/projects/markdown
|
163
libssh/README
Normal file
163
libssh/README
Normal file
@ -0,0 +1,163 @@
|
||||
_ _ _ _
|
||||
(_) (_) (_) (_)
|
||||
(_) _ (_) _ _ _ _ _ (_) _
|
||||
(_) (_) (_)(_) _ (_)(_) (_)(_) (_)(_) _
|
||||
(_) (_) (_) (_) _ (_) _ (_) (_) (_)
|
||||
(_) (_) (_)(_)(_) (_)(_) (_)(_) (_) (_).org
|
||||
|
||||
The SSH library
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1* Why ?
|
||||
-_-_-_-_-_
|
||||
|
||||
Why not ? :) I've began to work on my own implementation of the ssh protocol
|
||||
because i didn't like the currently public ones.
|
||||
Not any allowed you to import and use the functions as a powerful library,
|
||||
and so i worked on a library-based SSH implementation which was non-existing
|
||||
in the free and open source software world.
|
||||
|
||||
|
||||
2* How/Who ?
|
||||
-_-_-_-_-_-_-_
|
||||
|
||||
If you downloaded this file, you must know what it is : a library for
|
||||
accessing ssh client services through C libraries calls in a simple manner.
|
||||
Everybody can use this software under the terms of the LGPL - see the COPYING
|
||||
file
|
||||
|
||||
If you ask yourself how to compile libssh, please read INSTALL before anything.
|
||||
|
||||
3* Where ?
|
||||
-_-_-_-_-_-_
|
||||
|
||||
http://www.libssh.org
|
||||
|
||||
4* API Changes !
|
||||
-_-_-_-_-_-_-_-_-_
|
||||
|
||||
Changes between 0.4 and 0.5
|
||||
---------------------------
|
||||
|
||||
We use the ssh_ prefix as namespace for every function now. There is a legacy.h
|
||||
which could be used to get the old function names.
|
||||
|
||||
Changes between 0.3 and 0.4
|
||||
---------------------------
|
||||
|
||||
We changed libssh to be typesafe now:
|
||||
|
||||
SSH_SESSION *session -> ssh_session session
|
||||
SFTP_SESSION *sftp -> sftp_session sftp
|
||||
CHANNEL *channel -> ssh_channel channel
|
||||
STRING *string -> ssh_string string
|
||||
...
|
||||
|
||||
The options structure has been removed and there is a new function. This
|
||||
function can set all available options now. You can find the enum in the
|
||||
header file and it is documented. Example:
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||
|
||||
5* Copyright policy
|
||||
-_-_-_-_-_-_-_-_-_-_
|
||||
|
||||
libssh is a project with distributed copyright ownership, which means we prefer
|
||||
the copyright on parts of libssh to be held by individuals rather than
|
||||
corporations if possible. There are historical legal reasons for this, but one
|
||||
of the best ways to explain it is that it’s much easier to work with
|
||||
individuals who have ownership than corporate legal departments if we ever need
|
||||
to make reasonable compromises with people using and working with libssh.
|
||||
|
||||
We track the ownership of every part of libssh via git, our source code control
|
||||
system, so we know the provenance of every piece of code that is committed to
|
||||
libssh.
|
||||
|
||||
So if possible, if you’re doing libssh changes on behalf of a company who
|
||||
normally owns all the work you do please get them to assign personal copyright
|
||||
ownership of your changes to you as an individual, that makes things very easy
|
||||
for us to work with and avoids bringing corporate legal departments into the
|
||||
picture.
|
||||
|
||||
If you can’t do this we can still accept patches from you owned by your
|
||||
employer under a standard employment contract with corporate copyright
|
||||
ownership. It just requires a simple set-up process first.
|
||||
|
||||
We use a process very similar to the way things are done in the Linux Kernel
|
||||
community, so it should be very easy to get a sign off from your corporate
|
||||
legal department. The only changes we’ve made are to accommodate the license we
|
||||
use, which is LGPLv2 (or later) whereas the Linux kernel uses GPLv2.
|
||||
|
||||
The process is called signing.
|
||||
|
||||
How to sign your work
|
||||
----------------------
|
||||
|
||||
Once you have permission to contribute to libssh from your employer, simply
|
||||
email a copy of the following text from your corporate email address to:
|
||||
|
||||
contributing@libssh.org
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
libssh Developer's Certificate of Origin. Version 1.0
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the appropriate
|
||||
version of the GNU General Public License; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of
|
||||
my knowledge, is covered under an appropriate open source license
|
||||
and I have the right under that license to submit that work with
|
||||
modifications, whether created in whole or in part by me, under
|
||||
the GNU General Public License, in the appropriate version; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a) or (b) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are
|
||||
public and that a record of the contribution (including all
|
||||
metadata and personal information I submit with it, including my
|
||||
sign-off) is maintained indefinitely and may be redistributed
|
||||
consistent with the libssh Team's policies and the requirements of
|
||||
the GNU GPL where they are relevant.
|
||||
|
||||
(e) I am granting this work to this project under the terms of the
|
||||
GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2.1 of
|
||||
the License, or (at the option of the project) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
We will maintain a copy of that email as a record that you have the rights to
|
||||
contribute code to libssh under the required licenses whilst working for the
|
||||
company where the email came from.
|
||||
|
||||
Then when sending in a patch via the normal mechanisms described above, add a
|
||||
line that states:
|
||||
|
||||
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
|
||||
|
||||
using your real name and the email address you sent the original email you used
|
||||
to send the libssh Developer’s Certificate of Origin to us (sorry, no
|
||||
pseudonyms or anonymous contributions.)
|
||||
|
||||
That’s it! Such code can then quite happily contain changes that have copyright
|
||||
messages such as:
|
||||
|
||||
|
||||
(c) Example Corporation.
|
||||
|
||||
|
||||
and can be merged into the libssh codebase in the same way as patches from any
|
||||
other individual. You don’t need to send in a copy of the libssh Developer’s
|
||||
Certificate of Origin for each patch, or inside each patch. Just the sign-off
|
||||
message is all that is required once we’ve received the initial email.
|
||||
|
||||
Have fun and happy libssh hacking!
|
||||
|
||||
The libssh Team
|
118
libssh/SubmittingPatches
Normal file
118
libssh/SubmittingPatches
Normal file
@ -0,0 +1,118 @@
|
||||
How to contribute a patch to libssh
|
||||
====================================
|
||||
|
||||
Simple, just make the code change, and email it as either a "diff -u"
|
||||
change, or as a "git format-patch" change against the original source
|
||||
code to libssh@libssh.org, or attach it to a bug report at
|
||||
https://red.libssh.org/
|
||||
|
||||
For larger code changes, breaking the changes up into a set of simple
|
||||
patches, each of which does a single thing, are much easier to review.
|
||||
Patch sets like that will most likely have an easier time being merged
|
||||
into the libssh code than large single patches that make lots of
|
||||
changes in one large diff.
|
||||
|
||||
Ownership of the contributed code
|
||||
==================================
|
||||
|
||||
libssh is a project with distributed copyright ownership, which means
|
||||
we prefer the copyright on parts of libssh to be held by individuals
|
||||
rather than corporations if possible. There are historical legal
|
||||
reasons for this, but one of the best ways to explain it is that it's
|
||||
much easier to work with individuals who have ownership than corporate
|
||||
legal departments if we ever need to make reasonable compromises with
|
||||
people using and working with libssh.
|
||||
|
||||
We track the ownership of every part of libssh via http://git.libssh.org,
|
||||
our source code control system, so we know the provenance of every piece
|
||||
of code that is committed to libssh.
|
||||
|
||||
So if possible, if you're doing libssh changes on behalf of a company
|
||||
who normally owns all the work you do please get them to assign
|
||||
personal copyright ownership of your changes to you as an individual,
|
||||
that makes things very easy for us to work with and avoids bringing
|
||||
corporate legal departments into the picture.
|
||||
|
||||
If you can't do this we can still accept patches from you owned by
|
||||
your employer under a standard employment contract with corporate
|
||||
copyright ownership. It just requires a simple set-up process first.
|
||||
|
||||
We use a process very similar to the way things are done in the Linux
|
||||
Kernel community, so it should be very easy to get a sign off from
|
||||
your corporate legal department. The only changes we've made are to
|
||||
accommodate the license we use, which is LGPLv2 (or later) whereas the
|
||||
Linux kernel uses GPLv2.
|
||||
|
||||
The process is called signing.
|
||||
|
||||
How to sign your work
|
||||
----------------------
|
||||
|
||||
Once you have permission to contribute to libssh from your employer, simply
|
||||
email a copy of the following text from your corporate email address to:
|
||||
|
||||
contributing@libssh.org
|
||||
|
||||
|
||||
|
||||
libssh Developer's Certificate of Origin. Version 1.0
|
||||
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the appropriate
|
||||
version of the GNU General Public License; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of
|
||||
my knowledge, is covered under an appropriate open source license
|
||||
and I have the right under that license to submit that work with
|
||||
modifications, whether created in whole or in part by me, under
|
||||
the GNU General Public License, in the appropriate version; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a) or (b) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are
|
||||
public and that a record of the contribution (including all
|
||||
metadata and personal information I submit with it, including my
|
||||
sign-off) is maintained indefinitely and may be redistributed
|
||||
consistent with the libssh Team's policies and the requirements of
|
||||
the GNU GPL where they are relevant.
|
||||
|
||||
(e) I am granting this work to this project under the terms of the
|
||||
GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2.1 of
|
||||
the License, or (at the option of the project) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
|
||||
We will maintain a copy of that email as a record that you have the
|
||||
rights to contribute code to libssh under the required licenses whilst
|
||||
working for the company where the email came from.
|
||||
|
||||
Then when sending in a patch via the normal mechanisms described
|
||||
above, add a line that states:
|
||||
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
|
||||
using your real name and the email address you sent the original email
|
||||
you used to send the libssh Developer's Certificate of Origin to us
|
||||
(sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
That's it! Such code can then quite happily contain changes that have
|
||||
copyright messages such as:
|
||||
|
||||
(c) Example Corporation.
|
||||
|
||||
and can be merged into the libssh codebase in the same way as patches
|
||||
from any other individual. You don't need to send in a copy of the
|
||||
libssh Developer's Certificate of Origin for each patch, or inside each
|
||||
patch. Just the sign-off message is all that is required once we've
|
||||
received the initial email.
|
||||
|
||||
Have fun and happy libssh hacking !
|
||||
|
||||
The libssh Team
|
||||
|
197
libssh/build/build_make.sh
Executable file
197
libssh/build/build_make.sh
Executable file
@ -0,0 +1,197 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Last Change: 2008-06-18 14:13:46
|
||||
#
|
||||
# Script to build libssh on UNIX.
|
||||
#
|
||||
# Copyright (c) 2006-2007 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
|
||||
SOURCE_DIR=".."
|
||||
|
||||
LANG=C
|
||||
export LANG
|
||||
|
||||
SCRIPT="$0"
|
||||
COUNT=0
|
||||
while [ -L "${SCRIPT}" ]
|
||||
do
|
||||
SCRIPT=$(readlink ${SCRIPT})
|
||||
COUNT=$(expr ${COUNT} + 1)
|
||||
if [ ${COUNT} -gt 100 ]; then
|
||||
echo "Too many symbolic links"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
BUILDDIR=$(dirname ${SCRIPT})
|
||||
|
||||
cleanup_and_exit () {
|
||||
if test "$1" = 0 -o -z "$1" ; then
|
||||
exit 0
|
||||
else
|
||||
exit $1
|
||||
fi
|
||||
}
|
||||
|
||||
function configure() {
|
||||
if [ -n "${CMAKEDIR}" ]; then
|
||||
${CMAKEDIR}/bin/cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||
else
|
||||
cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||
fi
|
||||
}
|
||||
|
||||
function compile() {
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
CPUCOUNT=$(grep -c processor /proc/cpuinfo)
|
||||
elif test `uname` = "SunOS" ; then
|
||||
CPUCOUNT=$(psrinfo -p)
|
||||
else
|
||||
CPUCOUNT="1"
|
||||
fi
|
||||
|
||||
if [ "${CPUCOUNT}" -gt "1" ]; then
|
||||
${MAKE} -j${CPUCOUNT} $1 || cleanup_and_exit $?
|
||||
else
|
||||
${MAKE} $1 || exit $?
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_build_dir() {
|
||||
find ! -path "*.svn*" ! -name "*.bat" ! -name "*.sh" ! -name "." -print0 | xargs -0 rm -rf
|
||||
}
|
||||
|
||||
function usage () {
|
||||
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make
|
||||
(gmake|make)|--ccompiler (gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withssh1|--withserver]"
|
||||
cleanup_and_exit
|
||||
}
|
||||
|
||||
cd ${BUILDDIR}
|
||||
|
||||
# the default CMake options:
|
||||
OPTIONS="--graphviz=${BUILDDIR}/libssh.dot"
|
||||
|
||||
# the default 'make' utility:
|
||||
MAKE="make"
|
||||
|
||||
while test -n "$1"; do
|
||||
PARAM="$1"
|
||||
ARG="$2"
|
||||
shift
|
||||
case ${PARAM} in
|
||||
*-*=*)
|
||||
ARG=${PARAM#*=}
|
||||
PARAM=${PARAM%%=*}
|
||||
set -- "----noarg=${PARAM}" "$@"
|
||||
esac
|
||||
case ${PARAM} in
|
||||
*-help|-h)
|
||||
#echo_help
|
||||
usage
|
||||
cleanup_and_exit
|
||||
;;
|
||||
*-build)
|
||||
DOMAKE="1"
|
||||
BUILD_TYPE="${ARG}"
|
||||
test -n "${BUILD_TYPE}" && shift
|
||||
;;
|
||||
*-clean)
|
||||
clean_build_dir
|
||||
cleanup_and_exit
|
||||
;;
|
||||
*-clang)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
|
||||
;;
|
||||
*-verbose)
|
||||
DOVERBOSE="1"
|
||||
;;
|
||||
*-memtest)
|
||||
OPTIONS="${OPTIONS} -DMEM_NULL_TESTS=ON"
|
||||
;;
|
||||
*-libsuffix)
|
||||
OPTIONS="${OPTIONS} -DLIB_SUFFIX=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-prefix)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_INSTALL_PREFIX=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-sysconfdir)
|
||||
OPTIONS="${OPTIONS} -DSYSCONF_INSTALL_DIR=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-cmakedir)
|
||||
CMAKEDIR="${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-make)
|
||||
MAKE="${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-ccompiler)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-withstaticlib)
|
||||
OPTIONS="${OPTIONS} -DWITH_STATIC_LIB=ON"
|
||||
;;
|
||||
*-unittesting)
|
||||
OPTIONS="${OPTIONS} -DWITH_TESTING=ON"
|
||||
;;
|
||||
*-clientunittesting)
|
||||
OPTIONS="${OPTIONS} -DWITH_CLIENT_TESTING=ON"
|
||||
;;
|
||||
*-withssh1)
|
||||
OPTIONS="${OPTIONS} -DWITH_SSH1=ON"
|
||||
;;
|
||||
*-withserver)
|
||||
OPTIONS="${OPTIONS} -DWITH_SERVER=ON"
|
||||
;;
|
||||
----noarg)
|
||||
echo "$ARG does not take an argument"
|
||||
cleanup_and_exit
|
||||
;;
|
||||
-*)
|
||||
echo Unknown Option "$PARAM". Exit.
|
||||
cleanup_and_exit 1
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "${DOMAKE}" == "1" ]; then
|
||||
OPTIONS="${OPTIONS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE}"
|
||||
fi
|
||||
|
||||
if [ -n "${DOVERBOSE}" ]; then
|
||||
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=1"
|
||||
else
|
||||
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=0"
|
||||
fi
|
||||
|
||||
test -f "${BUILDDIR}/.build.log" && rm -f ${BUILDDIR}/.build.log
|
||||
touch ${BUILDDIR}/.build.log
|
||||
# log everything from here to .build.log
|
||||
exec 1> >(exec -a 'build logging tee' tee -a ${BUILDDIR}/.build.log) 2>&1
|
||||
echo "${HOST} started build at $(date)."
|
||||
echo
|
||||
|
||||
configure ${OPTIONS} "$@"
|
||||
|
||||
if [ -n "${DOMAKE}" ]; then
|
||||
test -n "${DOVERBOSE}" && compile VERBOSE=1 || compile
|
||||
fi
|
||||
|
||||
DOT=$(which dot 2>/dev/null)
|
||||
if [ -n "${DOT}" ]; then
|
||||
${DOT} -Tpng -o${BUILDDIR}/libssh.png ${BUILDDIR}/libssh.dot
|
||||
${DOT} -Tsvg -o${BUILDDIR}/libssh.svg ${BUILDDIR}/libssh.dot
|
||||
fi
|
||||
|
||||
exec >&0 2>&0 # so that the logging tee finishes
|
||||
sleep 1 # wait till tee terminates
|
||||
|
||||
cleanup_and_exit 0
|
23
libssh/cmake/Modules/AddCMockaTest.cmake
Normal file
23
libssh/cmake/Modules/AddCMockaTest.cmake
Normal file
@ -0,0 +1,23 @@
|
||||
# - ADD_CHECK_TEST(test_name test_source linklib1 ... linklibN)
|
||||
|
||||
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
||||
# Copyright (c) 2007-2010 Andreas Schneider <asn@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
enable_testing()
|
||||
include(CTest)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
|
||||
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
|
||||
|
||||
function (ADD_CMOCKA_TEST _testName _testSource)
|
||||
add_executable(${_testName} ${_testSource})
|
||||
target_link_libraries(${_testName} ${ARGN})
|
||||
add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName})
|
||||
endfunction (ADD_CMOCKA_TEST)
|
22
libssh/cmake/Modules/COPYING-CMAKE-SCRIPTS
Normal file
22
libssh/cmake/Modules/COPYING-CMAKE-SCRIPTS
Normal file
@ -0,0 +1,22 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
26
libssh/cmake/Modules/CheckCCompilerFlagSSP.cmake
Normal file
26
libssh/cmake/Modules/CheckCCompilerFlagSSP.cmake
Normal file
@ -0,0 +1,26 @@
|
||||
# - Check whether the C compiler supports a given flag in the
|
||||
# context of a stack checking compiler option.
|
||||
|
||||
# CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE)
|
||||
#
|
||||
# FLAG - the compiler flag
|
||||
# VARIABLE - variable to store the result
|
||||
#
|
||||
# This actually calls check_c_source_compiles.
|
||||
# See help for CheckCSourceCompiles for a listing of variables
|
||||
# that can modify the build.
|
||||
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
|
||||
set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
|
||||
check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
|
||||
endfunction(CHECK_C_COMPILER_FLAG_SSP)
|
27
libssh/cmake/Modules/DefineCMakeDefaults.cmake
Normal file
27
libssh/cmake/Modules/DefineCMakeDefaults.cmake
Normal file
@ -0,0 +1,27 @@
|
||||
# Always include srcdir and builddir in include path
|
||||
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
|
||||
# about every subdir
|
||||
# since cmake 2.4.0
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Put the include dirs which are in the source or build tree
|
||||
# before all other include dirs, so the headers in the sources
|
||||
# are prefered over the already installed ones
|
||||
# since cmake 2.4.1
|
||||
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
|
||||
|
||||
# Use colored output
|
||||
# since cmake 2.4.0
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
# Define the generic version of the libraries here
|
||||
set(GENERIC_LIB_VERSION "0.1.0")
|
||||
set(GENERIC_LIB_SOVERSION "0")
|
||||
|
||||
# Set the default build type to release with debug info
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo
|
||||
CACHE STRING
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
77
libssh/cmake/Modules/DefineCompilerFlags.cmake
Normal file
77
libssh/cmake/Modules/DefineCompilerFlags.cmake
Normal file
@ -0,0 +1,77 @@
|
||||
# define system dependent compiler flags
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCCompilerFlagSSP)
|
||||
|
||||
if (UNIX AND NOT WIN32)
|
||||
#
|
||||
# Define GNUCC compiler flags
|
||||
#
|
||||
if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||
|
||||
# add -Wconversion ?
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
|
||||
|
||||
# with -fPIC
|
||||
check_c_compiler_flag("-fPIC" WITH_FPIC)
|
||||
if (WITH_FPIC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
endif (WITH_FPIC)
|
||||
|
||||
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||
if (WITH_STACK_PROTECTOR)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
|
||||
endif (WITH_STACK_PROTECTOR)
|
||||
|
||||
if (CMAKE_BUILD_TYPE)
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
|
||||
if (NOT CMAKE_BUILD_TYPE_LOWER MATCHES debug)
|
||||
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
|
||||
if (WITH_FORTIFY_SOURCE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2")
|
||||
endif (WITH_FORTIFY_SOURCE)
|
||||
endif()
|
||||
endif()
|
||||
endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||
|
||||
#
|
||||
# Check for large filesystem support
|
||||
#
|
||||
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
# with large file support
|
||||
execute_process(
|
||||
COMMAND
|
||||
getconf LFS64_CFLAGS
|
||||
OUTPUT_VARIABLE
|
||||
_lfs_CFLAGS
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
# with large file support
|
||||
execute_process(
|
||||
COMMAND
|
||||
getconf LFS_CFLAGS
|
||||
OUTPUT_VARIABLE
|
||||
_lfs_CFLAGS
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
if (_lfs_CFLAGS)
|
||||
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}")
|
||||
endif (_lfs_CFLAGS)
|
||||
|
||||
endif (UNIX AND NOT WIN32)
|
||||
|
||||
if (MSVC)
|
||||
# Use secure functions by defaualt and suppress warnings about
|
||||
#"deprecated" functions
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
||||
endif (MSVC)
|
109
libssh/cmake/Modules/DefineInstallationPaths.cmake
Normal file
109
libssh/cmake/Modules/DefineInstallationPaths.cmake
Normal file
@ -0,0 +1,109 @@
|
||||
if (UNIX OR OS2)
|
||||
IF (NOT APPLICATION_NAME)
|
||||
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
|
||||
SET(APPLICATION_NAME ${PROJECT_NAME})
|
||||
ENDIF (NOT APPLICATION_NAME)
|
||||
|
||||
# Suffix for Linux
|
||||
SET(LIB_SUFFIX
|
||||
CACHE STRING "Define suffix of directory name (32/64)"
|
||||
)
|
||||
|
||||
SET(EXEC_INSTALL_PREFIX
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
CACHE PATH "Base directory for executables and libraries"
|
||||
)
|
||||
SET(SHARE_INSTALL_PREFIX
|
||||
"${CMAKE_INSTALL_PREFIX}/share"
|
||||
CACHE PATH "Base directory for files which go to share/"
|
||||
)
|
||||
SET(DATA_INSTALL_PREFIX
|
||||
"${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}"
|
||||
CACHE PATH "The parent directory where applications can install their data")
|
||||
|
||||
# The following are directories where stuff will be installed to
|
||||
SET(BIN_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/bin"
|
||||
CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)"
|
||||
)
|
||||
SET(SBIN_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/sbin"
|
||||
CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)"
|
||||
)
|
||||
SET(LIB_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)"
|
||||
)
|
||||
SET(LIBEXEC_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/libexec"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
|
||||
)
|
||||
SET(PLUGIN_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/${APPLICATION_NAME}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})"
|
||||
)
|
||||
SET(INCLUDE_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_PREFIX}/include"
|
||||
CACHE PATH "The subdirectory to the header prefix (default prefix/include)"
|
||||
)
|
||||
|
||||
set(CMAKE_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/cmake"
|
||||
CACHE PATH "The subdirectory to install cmake config files")
|
||||
|
||||
SET(DATA_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}"
|
||||
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})"
|
||||
)
|
||||
SET(HTML_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/doc/HTML"
|
||||
CACHE PATH "The HTML install dir for documentation (default data/doc/html)"
|
||||
)
|
||||
SET(ICON_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/icons"
|
||||
CACHE PATH "The icon install dir (default data/icons/)"
|
||||
)
|
||||
SET(SOUND_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/sounds"
|
||||
CACHE PATH "The install dir for sound files (default data/sounds)"
|
||||
)
|
||||
|
||||
SET(LOCALE_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/locale"
|
||||
CACHE PATH "The install dir for translations (default prefix/share/locale)"
|
||||
)
|
||||
|
||||
SET(XDG_APPS_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/applications/"
|
||||
CACHE PATH "The XDG apps dir"
|
||||
)
|
||||
SET(XDG_DIRECTORY_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/desktop-directories"
|
||||
CACHE PATH "The XDG directory"
|
||||
)
|
||||
|
||||
SET(SYSCONF_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/etc"
|
||||
CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)"
|
||||
)
|
||||
SET(MAN_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/man"
|
||||
CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)"
|
||||
)
|
||||
SET(INFO_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/info"
|
||||
CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)"
|
||||
)
|
||||
else()
|
||||
# Same same
|
||||
set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
|
||||
set(SBIN_INSTALL_DIR "sbin" CACHE PATH "-")
|
||||
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "-")
|
||||
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
|
||||
set(CMAKE_INSTALL_DIR "CMake" CACHE PATH "-")
|
||||
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
|
||||
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
|
||||
set(ICON_INSTALL_DIR "icons" CACHE PATH "-")
|
||||
set(SOUND_INSTALL_DIR "soudns" CACHE PATH "-")
|
||||
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
|
||||
endif ()
|
28
libssh/cmake/Modules/DefinePlatformDefaults.cmake
Normal file
28
libssh/cmake/Modules/DefinePlatformDefaults.cmake
Normal file
@ -0,0 +1,28 @@
|
||||
# Set system vars
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(LINUX TRUE)
|
||||
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
set(BSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
set(OPENBSD TRUE)
|
||||
set(BSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
set(NETBSD TRUE)
|
||||
set(BSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
set(SOLARIS TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||
set(OS2 TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
60
libssh/cmake/Modules/FindArgp.cmake
Normal file
60
libssh/cmake/Modules/FindArgp.cmake
Normal file
@ -0,0 +1,60 @@
|
||||
# - Try to find Argp
|
||||
# Once done this will define
|
||||
#
|
||||
# ARGP_FOUND - system has Argp
|
||||
# ARGP_INCLUDE_DIRS - the Argp include directory
|
||||
# ARGP_LIBRARIES - Link these to use Argp
|
||||
# ARGP_DEFINITIONS - Compiler switches required for using Argp
|
||||
#
|
||||
# Copyright (c) 2010 Andreas Schneider <asn@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(ARGP_FOUND TRUE)
|
||||
else (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
|
||||
|
||||
find_path(ARGP_INCLUDE_DIR
|
||||
NAMES
|
||||
argp.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
|
||||
find_library(ARGP_LIBRARY
|
||||
NAMES
|
||||
argp
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
set(ARGP_INCLUDE_DIRS
|
||||
${ARGP_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (ARGP_LIBRARY)
|
||||
set(ARGP_LIBRARIES
|
||||
${ARGP_LIBRARIES}
|
||||
${ARGP_LIBRARY}
|
||||
)
|
||||
endif (ARGP_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Argp DEFAULT_MSG ARGP_LIBRARIES ARGP_INCLUDE_DIRS)
|
||||
|
||||
# show the ARGP_INCLUDE_DIRS and ARGP_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(ARGP_INCLUDE_DIRS ARGP_LIBRARIES)
|
||||
|
||||
endif (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
|
||||
|
49
libssh/cmake/Modules/FindCMocka.cmake
Normal file
49
libssh/cmake/Modules/FindCMocka.cmake
Normal file
@ -0,0 +1,49 @@
|
||||
# - Try to find CMocka
|
||||
# Once done this will define
|
||||
#
|
||||
# CMOCKA_ROOT_DIR - Set this variable to the root installation of CMocka
|
||||
#
|
||||
# Read-Only variables:
|
||||
# CMOCKA_FOUND - system has CMocka
|
||||
# CMOCKA_INCLUDE_DIR - the CMocka include directory
|
||||
# CMOCKA_LIBRARIES - Link these to use CMocka
|
||||
# CMOCKA_DEFINITIONS - Compiler switches required for using CMocka
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2011-2012 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
find_path(CMOCKA_INCLUDE_DIR
|
||||
NAMES
|
||||
cmocka.h
|
||||
PATHS
|
||||
${CMOCKA_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
find_library(CMOCKA_LIBRARY
|
||||
NAMES
|
||||
cmocka
|
||||
PATHS
|
||||
${CMOCKA_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
if (CMOCKA_LIBRARY)
|
||||
set(CMOCKA_LIBRARIES
|
||||
${CMOCKA_LIBRARIES}
|
||||
${CMOCKA_LIBRARY}
|
||||
)
|
||||
endif (CMOCKA_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(CMocka DEFAULT_MSG CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
|
||||
|
||||
# show the CMOCKA_INCLUDE_DIR and CMOCKA_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(CMOCKA_INCLUDE_DIR CMOCKA_LIBRARIES)
|
75
libssh/cmake/Modules/FindGCrypt.cmake
Normal file
75
libssh/cmake/Modules/FindGCrypt.cmake
Normal file
@ -0,0 +1,75 @@
|
||||
# - Try to find GCrypt
|
||||
# Once done this will define
|
||||
#
|
||||
# GCRYPT_FOUND - system has GCrypt
|
||||
# GCRYPT_INCLUDE_DIRS - the GCrypt include directory
|
||||
# GCRYPT_LIBRARIES - Link these to use GCrypt
|
||||
# GCRYPT_DEFINITIONS - Compiler switches required for using GCrypt
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2009-2012 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
set(_GCRYPT_ROOT_HINTS
|
||||
$ENV{GCRYTPT_ROOT_DIR}
|
||||
${GCRYPT_ROOT_DIR})
|
||||
|
||||
set(_GCRYPT_ROOT_PATHS
|
||||
"$ENV{PROGRAMFILES}/libgcrypt")
|
||||
|
||||
set(_GCRYPT_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_GCRYPT_ROOT_HINTS}
|
||||
PATHS ${_GCRYPT_ROOT_PATHS})
|
||||
|
||||
|
||||
find_path(GCRYPT_INCLUDE_DIR
|
||||
NAMES
|
||||
gcrypt.h
|
||||
HINTS
|
||||
${_GCRYPT_ROOT_HINTS_AND_PATHS}
|
||||
)
|
||||
|
||||
find_library(GCRYPT_LIBRARY
|
||||
NAMES
|
||||
gcrypt
|
||||
gcrypt11
|
||||
libgcrypt-11
|
||||
HINTS
|
||||
${_GCRYPT_ROOT_HINTS_AND_PATHS}
|
||||
)
|
||||
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})
|
||||
|
||||
if (GCRYPT_INCLUDE_DIR)
|
||||
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+.[0-9]+.[0-9]+\"")
|
||||
|
||||
string(REGEX REPLACE "^.*GCRYPT_VERSION.*([0-9]+.[0-9]+.[0-9]+).*" "\\1" GCRYPT_VERSION "${_gcrypt_version_str}")
|
||||
endif (GCRYPT_INCLUDE_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
if (GCRYPT_VERSION)
|
||||
find_package_handle_standard_args(GCrypt
|
||||
REQUIRED_VARS
|
||||
GCRYPT_INCLUDE_DIR
|
||||
GCRYPT_LIBRARIES
|
||||
VERSION_VAR
|
||||
GCRYPT_VERSION
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find GCrypt, try to set the path to GCrypt root folder in the system variable GCRYPT_ROOT_DIR"
|
||||
)
|
||||
else (GCRYPT_VERSION)
|
||||
find_package_handle_standard_args(GCrypt
|
||||
"Could NOT find GCrypt, try to set the path to GCrypt root folder in the system variable GCRYPT_ROOT_DIR"
|
||||
GCRYPT_INCLUDE_DIR
|
||||
GCRYPT_LIBRARIES)
|
||||
endif (GCRYPT_VERSION)
|
||||
|
||||
# show the GCRYPT_INCLUDE_DIRS and GCRYPT_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(GCRYPT_INCLUDE_DIR GCRYPT_LIBRARIES)
|
39
libssh/cmake/Modules/FindNSIS.cmake
Normal file
39
libssh/cmake/Modules/FindNSIS.cmake
Normal file
@ -0,0 +1,39 @@
|
||||
# - Try to find NSIS
|
||||
# Once done this will define
|
||||
#
|
||||
# NSIS_ROOT_DIR - Set this variable to the root installation of ZLIB
|
||||
#
|
||||
# Read-Only variables:
|
||||
# NSIS_FOUND - system has NSIS
|
||||
# NSIS_MAKE - NSIS creator executable
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2010-2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
set(_NSIS_ROOT_PATHS
|
||||
C:/NSIS/Bin
|
||||
"$ENV{PROGRAMFILES}/NSIS"
|
||||
)
|
||||
|
||||
find_program(NSIS_MAKE
|
||||
NAMES
|
||||
makensis
|
||||
PATHS
|
||||
${NSIS_ROOT_PATH}
|
||||
${NSIS_ROOT_PATH}/Bin
|
||||
${_NSIS_ROOT_PATHS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE)
|
||||
|
||||
mark_as_advanced(NSIS_MAKE)
|
208
libssh/cmake/Modules/FindOpenSSL.cmake
Normal file
208
libssh/cmake/Modules/FindOpenSSL.cmake
Normal file
@ -0,0 +1,208 @@
|
||||
# - Try to find OpenSSL
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
|
||||
#
|
||||
# Read-Only variables:
|
||||
# OPENSSL_FOUND - system has OpenSSL
|
||||
# OPENSSL_INCLUDE_DIRS - the OpenSSL include directory
|
||||
# OPENSSL_LIBRARIES - Link these to use OpenSSL
|
||||
# OPENSSL_DEFINITIONS - Compiler switches required for using OpenSSL
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2006-2009 Kitware, Inc.
|
||||
# Copyright (c) 2006 Alexander Neundorf <neundorf@kde.org>
|
||||
# Copyright (c) 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(OPENSSL_FOUND TRUE)
|
||||
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
|
||||
if (UNIX)
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_OPENSSL openssl)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
endif (UNIX)
|
||||
|
||||
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||
)
|
||||
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"C:/OpenSSL/"
|
||||
"C:/OpenSSL-Win32/"
|
||||
"C:/OpenSSL-Win64/"
|
||||
"$ENV{PROGRAMFILES}/OpenSSL"
|
||||
"$ENV{PROGRAMFILES}/OpenSSL-Win32"
|
||||
"$ENV{PROGRAMFILES}/OpenSSL-Win64"
|
||||
)
|
||||
|
||||
find_path(OPENSSL_ROOT_DIR
|
||||
NAMES
|
||||
include/openssl/ssl.h
|
||||
HINTS
|
||||
${_OPENSSL_ROOT_HINTS}
|
||||
PATHS
|
||||
${_OPENSSL_ROOT_PATHS}
|
||||
)
|
||||
mark_as_advanced(OPENSSL_ROOT_DIR)
|
||||
|
||||
find_path(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
openssl/ssl.h
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
/usr/lib/sfw/include
|
||||
${OPENSSL_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
||||
mark_as_advanced(OPENSSL_INCLUDE_DIRS)
|
||||
|
||||
if (WIN32 AND NOT CYGWIN)
|
||||
# MINGW should go here too
|
||||
if (MSVC)
|
||||
# /MD and /MDd are the standard values - if someone wants to use
|
||||
# others, the libnames have to change here too
|
||||
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
|
||||
# TODO: handle /MT and static lib
|
||||
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
|
||||
# * MD for dynamic-release
|
||||
# * MDd for dynamic-debug
|
||||
# * MT for static-release
|
||||
# * MTd for static-debug
|
||||
|
||||
# Implementation details:
|
||||
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
|
||||
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||
find_library(LIB_EAY_DEBUG
|
||||
NAMES
|
||||
libeay32MDd
|
||||
libeay32
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib/VC
|
||||
)
|
||||
|
||||
find_library(LIB_EAY_RELEASE
|
||||
NAMES
|
||||
libeay32MD
|
||||
libeay32
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib/VC
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_DEBUG
|
||||
NAMES
|
||||
ssleay32MDd
|
||||
ssleay32
|
||||
ssl
|
||||
PATHS ${OPENSSL_ROOT_DIR}/lib/VC
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_RELEASE
|
||||
NAMES
|
||||
ssleay32MD
|
||||
ssleay32
|
||||
ssl
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib/VC
|
||||
)
|
||||
|
||||
if (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||
set(OPENSSL_LIBRARIES
|
||||
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
|
||||
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
|
||||
)
|
||||
else (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||
endif (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||
|
||||
mark_as_advanced(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
||||
mark_as_advanced(LIB_EAY_DEBUG LIB_EAY_RELEASE)
|
||||
elseif (MINGW)
|
||||
# same player, for MingW
|
||||
find_library(LIB_EAY
|
||||
NAMES
|
||||
libeay32
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib/MinGW
|
||||
)
|
||||
|
||||
find_library(SSL_EAY
|
||||
NAMES
|
||||
ssleay32
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib/MinGW
|
||||
)
|
||||
|
||||
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
|
||||
else(MSVC)
|
||||
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
|
||||
find_library(LIB_EAY
|
||||
NAMES
|
||||
libeay32
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
find_library(SSL_EAY
|
||||
NAMES
|
||||
ssleay32
|
||||
PATHS
|
||||
${OPENSSL_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
|
||||
endif(MSVC)
|
||||
else (WIN32 AND NOT CYGWIN)
|
||||
find_library(OPENSSL_SSL_LIBRARIES
|
||||
NAMES
|
||||
ssl
|
||||
ssleay32
|
||||
ssleay32MD
|
||||
PATHS
|
||||
${_OPENSSL_LIBDIR}
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
/usr/sfw/lib/64
|
||||
/usr/sfw/lib
|
||||
)
|
||||
|
||||
find_library(OPENSSL_CRYPTO_LIBRARIES
|
||||
NAMES
|
||||
crypto
|
||||
PATHS
|
||||
${_OPENSSL_LIBDIR}
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
/usr/sfw/lib/64
|
||||
/usr/sfw/lib
|
||||
)
|
||||
|
||||
mark_as_advanced(OPENSSL_CRYPTO_LIBRARIES OPENSSL_SSL_LIBRARIES)
|
||||
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
endif (WIN32 AND NOT CYGWIN)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(OpenSSL DEFAULT_MSG OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIRS)
|
||||
|
||||
endif (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
120
libssh/cmake/Modules/FindZLIB.cmake
Normal file
120
libssh/cmake/Modules/FindZLIB.cmake
Normal file
@ -0,0 +1,120 @@
|
||||
# - Try to find ZLIB
|
||||
# Once done this will define
|
||||
#
|
||||
# ZLIB_ROOT_DIR - Set this variable to the root installation of ZLIB
|
||||
#
|
||||
# Read-Only variables:
|
||||
# ZLIB_FOUND - system has ZLIB
|
||||
# ZLIB_INCLUDE_DIRS - the ZLIB include directory
|
||||
# ZLIB_LIBRARIES - Link these to use ZLIB
|
||||
#
|
||||
# ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
|
||||
# ZLIB_VERSION_MAJOR - The major version of zlib
|
||||
# ZLIB_VERSION_MINOR - The minor version of zlib
|
||||
# ZLIB_VERSION_PATCH - The patch version of zlib
|
||||
# ZLIB_VERSION_TWEAK - The tweak version of zlib
|
||||
#
|
||||
# The following variable are provided for backward compatibility
|
||||
#
|
||||
# ZLIB_MAJOR_VERSION - The major version of zlib
|
||||
# ZLIB_MINOR_VERSION - The minor version of zlib
|
||||
# ZLIB_PATCH_VERSION - The patch version of zlib
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2001-2009 Kitware, Inc.
|
||||
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(ZLIB_FOUND TRUE)
|
||||
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
|
||||
set(_ZLIB_ROOT_HINTS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/include"
|
||||
)
|
||||
|
||||
set(_ZLIB_ROOT_PATHS
|
||||
"$ENV{PROGRAMFILES}/zlib"
|
||||
)
|
||||
|
||||
find_path(ZLIB_ROOT_DIR
|
||||
NAMES
|
||||
include/zlib.h
|
||||
HINTS
|
||||
${_ZLIB_ROOT_HINTS}
|
||||
PATHS
|
||||
${_ZLIB_ROOT_PATHS}
|
||||
)
|
||||
mark_as_advanced(ZLIB_ROOT_DIR)
|
||||
|
||||
# check for header file
|
||||
find_path(ZLIB_INCLUDE_DIR
|
||||
NAMES
|
||||
zlib.h
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
/usr/lib/sfw/include
|
||||
${ZLIB_ROOT_DIR}/include
|
||||
)
|
||||
mark_as_advanced(ZLIB_INCLUDE_DIR)
|
||||
|
||||
# check version number
|
||||
if (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
|
||||
file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$")
|
||||
|
||||
string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}")
|
||||
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}")
|
||||
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}")
|
||||
|
||||
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}")
|
||||
|
||||
# only append a TWEAK version if it exists:
|
||||
set(ZLIB_VERSION_TWEAK "")
|
||||
if ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
|
||||
set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
|
||||
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}")
|
||||
endif ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
|
||||
|
||||
set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
|
||||
set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
|
||||
set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
|
||||
endif (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
|
||||
|
||||
find_library(ZLIB_LIBRARY
|
||||
NAMES
|
||||
z
|
||||
zdll
|
||||
zlib
|
||||
zlib1
|
||||
zlibd
|
||||
PATHS
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
/usr/sfw/lib/64
|
||||
/usr/sfw/lib
|
||||
${ZLIB_ROOT_DIR}/lib
|
||||
)
|
||||
mark_as_advanced(ZLIB_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(ZLIB DEFAULT_MSG ZLIB_INCLUDE_DIR ZLIB_LIBRARY)
|
||||
#find_package_handle_standard_args(ZLIB REQUIRED_VARS ZLIB_INCLUDE_DIR ZLIB_LIBRARY
|
||||
# VERSION_VAR ZLIB_VERSION_STRING)
|
||||
|
||||
if (ZLIB_FOUND)
|
||||
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
|
||||
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
|
||||
endif (ZLIB_FOUND)
|
||||
endif (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
21
libssh/cmake/Modules/MacroAddCompileFlags.cmake
Normal file
21
libssh/cmake/Modules/MacroAddCompileFlags.cmake
Normal file
@ -0,0 +1,21 @@
|
||||
# - MACRO_ADD_COMPILE_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_COMPILE_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} COMPILE_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags ${_flags} ${ARGN})
|
||||
else (_flags)
|
||||
set(_flags ${ARGN})
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_FLAGS ${_flags})
|
||||
|
||||
endmacro (MACRO_ADD_COMPILE_FLAGS)
|
20
libssh/cmake/Modules/MacroAddLinkFlags.cmake
Normal file
20
libssh/cmake/Modules/MacroAddLinkFlags.cmake
Normal file
@ -0,0 +1,20 @@
|
||||
# - MACRO_ADD_LINK_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ADD_LINK_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} LINK_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags "${_flags} ${ARGN}")
|
||||
else (_flags)
|
||||
set(_flags "${ARGN}")
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${_flags}")
|
||||
|
||||
endmacro (MACRO_ADD_LINK_FLAGS)
|
30
libssh/cmake/Modules/MacroAddPlugin.cmake
Normal file
30
libssh/cmake/Modules/MacroAddPlugin.cmake
Normal file
@ -0,0 +1,30 @@
|
||||
# - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN)
|
||||
#
|
||||
# Create a plugin from the given source files.
|
||||
# If WITH_PREFIX is given, the resulting plugin will have the
|
||||
# prefix "lib", otherwise it won't.
|
||||
#
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX)
|
||||
|
||||
if (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC)
|
||||
else (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC ${_with_PREFIX})
|
||||
endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
|
||||
add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN})
|
||||
|
||||
if (_first_SRC)
|
||||
set_target_properties(${_target_NAME} PROPERTIES PREFIX "")
|
||||
endif (_first_SRC)
|
||||
|
||||
endmacro (MACRO_ADD_PLUGIN _name _sources)
|
||||
|
33
libssh/cmake/Modules/MacroCopyFile.cmake
Normal file
33
libssh/cmake/Modules/MacroCopyFile.cmake
Normal file
@ -0,0 +1,33 @@
|
||||
# - macro_copy_file(_src _dst)
|
||||
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
|
||||
#
|
||||
# Example:
|
||||
# macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.)
|
||||
# Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory
|
||||
#
|
||||
# Copyright (c) 2006-2007 Wengo
|
||||
# Copyright (c) 2006-2008 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING file.
|
||||
|
||||
|
||||
macro (macro_copy_file _src _dst)
|
||||
# Removes all path containing .svn or CVS or CMakeLists.txt during the copy
|
||||
if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
|
||||
if (CMAKE_VERBOSE_MAKEFILE)
|
||||
message(STATUS "Copy file from ${_src} to ${_dst}")
|
||||
endif (CMAKE_VERBOSE_MAKEFILE)
|
||||
|
||||
# Creates directory if necessary
|
||||
get_filename_component(_path ${_dst} PATH)
|
||||
file(MAKE_DIRECTORY ${_path})
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst}
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
endmacro (macro_copy_file)
|
17
libssh/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake
Normal file
17
libssh/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake
Normal file
@ -0,0 +1,17 @@
|
||||
# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage)
|
||||
|
||||
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource)
|
||||
if (_insource)
|
||||
message(SEND_ERROR "${_errorMessage}")
|
||||
message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.")
|
||||
endif (_insource)
|
||||
|
||||
endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)
|
100
libssh/cmake/Modules/UseDoxygen.cmake
Normal file
100
libssh/cmake/Modules/UseDoxygen.cmake
Normal file
@ -0,0 +1,100 @@
|
||||
# - Run Doxygen
|
||||
#
|
||||
# Adds a doxygen target that runs doxygen to generate the html
|
||||
# and optionally the LaTeX API documentation.
|
||||
# The doxygen target is added to the doc target as dependency.
|
||||
# i.e.: the API documentation is built with:
|
||||
# make doc
|
||||
#
|
||||
# USAGE: INCLUDE IN PROJECT
|
||||
#
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
# include(UseDoxygen)
|
||||
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
|
||||
#
|
||||
#
|
||||
# Variables you may define are:
|
||||
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. Defaults to "doc".
|
||||
#
|
||||
# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is stored. Defaults to "latex".
|
||||
#
|
||||
# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is stored. Defaults to "html".
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2009-2010 Tobias Rautenkranz <tobias@rautenkranz.ch>
|
||||
# Copyright (c) 2010 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
macro(usedoxygen_set_default name value)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${value}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
find_package(Doxygen)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
find_file(DOXYFILE_IN
|
||||
NAMES
|
||||
doxy.config.in
|
||||
PATHS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_ROOT}/Modules/
|
||||
NO_DEFAULT_PATH)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
|
||||
endif()
|
||||
|
||||
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
|
||||
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
|
||||
|
||||
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
usedoxygen_set_default(DOXYFILE_HTML_DIR "html")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
|
||||
|
||||
set(DOXYFILE_LATEX FALSE)
|
||||
set(DOXYFILE_PDFLATEX FALSE)
|
||||
set(DOXYFILE_DOT FALSE)
|
||||
|
||||
find_package(LATEX)
|
||||
if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
|
||||
set(DOXYFILE_LATEX TRUE)
|
||||
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
|
||||
if(PDFLATEX_COMPILER)
|
||||
set(DOXYFILE_PDFLATEX TRUE)
|
||||
endif()
|
||||
if(DOXYGEN_DOT_EXECUTABLE)
|
||||
set(DOXYFILE_DOT TRUE)
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET doxygen
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
endif()
|
||||
|
||||
configure_file(${DOXYFILE_IN} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
add_custom_target(doxygen-trac ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac)
|
||||
endif()
|
||||
|
||||
get_target_property(DOC_TARGET doc TYPE)
|
||||
if(NOT DOC_TARGET)
|
||||
add_custom_target(doc)
|
||||
endif()
|
||||
|
||||
add_dependencies(doc doxygen)
|
||||
endif()
|
148
libssh/config.h.cmake
Normal file
148
libssh/config.h.cmake
Normal file
@ -0,0 +1,148 @@
|
||||
/* Name of package */
|
||||
#cmakedefine PACKAGE "${APPLICATION_NAME}"
|
||||
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION "${APPLICATION_VERSION}"
|
||||
|
||||
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
|
||||
#cmakedefine DATADIR "${DATADIR}"
|
||||
#cmakedefine LIBDIR "${LIBDIR}"
|
||||
#cmakedefine PLUGINDIR "${PLUGINDIR}"
|
||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
||||
#cmakedefine BINARYDIR "${BINARYDIR}"
|
||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||
|
||||
/************************** HEADER FILES *************************/
|
||||
|
||||
/* Define to 1 if you have the <argp.h> header file. */
|
||||
#cmakedefine HAVE_ARGP_H 1
|
||||
|
||||
/* Define to 1 if you have the <pty.h> header file. */
|
||||
#cmakedefine HAVE_PTY_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#cmakedefine HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/aes.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_AES_H 1
|
||||
|
||||
/* Define to 1 if you have the <wspiapi.h> header file. */
|
||||
#cmakedefine HAVE_WSPIAPI_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_BLOWFISH_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/des.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_DES_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/ecdh.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_ECDH_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/ec.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_EC_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/ecdsa.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_ECDSA_H 1
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#cmakedefine HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to 1 if you have eliptic curve cryptography in openssl */
|
||||
#cmakedefine HAVE_OPENSSL_ECC 1
|
||||
|
||||
/* Define to 1 if you have eliptic curve cryptography in gcrypt */
|
||||
#cmakedefine HAVE_GCRYPT_ECC 1
|
||||
|
||||
/* Define to 1 if you have eliptic curve cryptography */
|
||||
#cmakedefine HAVE_ECC 1
|
||||
|
||||
/*************************** FUNCTIONS ***************************/
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_snprintf' function. */
|
||||
#cmakedefine HAVE__SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_snprintf_s' function. */
|
||||
#cmakedefine HAVE__SNPRINTF_S 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#cmakedefine HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf' function. */
|
||||
#cmakedefine HAVE__VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||
#cmakedefine HAVE__VSNPRINTF_S 1
|
||||
|
||||
/* Define to 1 if you have the `strncpy' function. */
|
||||
#cmakedefine HAVE_STRNCPY 1
|
||||
|
||||
/* Define to 1 if you have the `cfmakeraw' function. */
|
||||
#cmakedefine HAVE_CFMAKERAW 1
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#cmakedefine HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#cmakedefine HAVE_POLL 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#cmakedefine HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#cmakedefine HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the `ntohll' function. */
|
||||
#cmakedefine HAVE_NTOHLL 1
|
||||
|
||||
/* Define to 1 if you have the `htonll' function. */
|
||||
#cmakedefine HAVE_HTONLL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoull' function. */
|
||||
#cmakedefine HAVE_STRTOULL 1
|
||||
|
||||
/* Define to 1 if you have the `__strtoull' function. */
|
||||
#cmakedefine HAVE___STRTOULL 1
|
||||
|
||||
/*************************** LIBRARIES ***************************/
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#cmakedefine HAVE_LIBCRYPTO 1
|
||||
|
||||
/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
|
||||
#cmakedefine HAVE_LIBGCRYPT 1
|
||||
|
||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||
#cmakedefine HAVE_PTHREAD 1
|
||||
|
||||
|
||||
/**************************** OPTIONS ****************************/
|
||||
|
||||
/* Define to 1 if you want to enable ZLIB */
|
||||
#cmakedefine WITH_ZLIB 1
|
||||
|
||||
/* Define to 1 if you want to enable SFTP */
|
||||
#cmakedefine WITH_SFTP 1
|
||||
|
||||
/* Define to 1 if you want to enable SSH1 */
|
||||
#cmakedefine WITH_SSH1 1
|
||||
|
||||
/* Define to 1 if you want to enable server support */
|
||||
#cmakedefine WITH_SERVER 1
|
||||
|
||||
/* Define to 1 if you want to enable debug output for crypto functions */
|
||||
#cmakedefine DEBUG_CRYPTO 1
|
||||
|
||||
/* Define to 1 if you want to enable pcap output support (experimental) */
|
||||
#cmakedefine WITH_PCAP 1
|
||||
|
||||
/* Define to 1 if you want to enable calltrace debug output */
|
||||
#cmakedefine DEBUG_CALLTRACE 1
|
||||
|
||||
/*************************** ENDIAN *****************************/
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#cmakedefine WORDS_BIGENDIAN 1
|
5
libssh/doc/CMakeLists.txt
Normal file
5
libssh/doc/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Build the documentation
|
||||
#
|
||||
include(UseDoxygen OPTIONAL)
|
||||
|
1
libssh/doc/TracFooter.html
Normal file
1
libssh/doc/TracFooter.html
Normal file
@ -0,0 +1 @@
|
||||
<!-- Doxygen TracFooter -->
|
4
libssh/doc/TracHeader.html
Normal file
4
libssh/doc/TracHeader.html
Normal file
@ -0,0 +1,4 @@
|
||||
<!-- Doxygen TracHeader -->
|
||||
<style>@import url(/chrome/site/doxygen.css);</style>
|
||||
<style>@import url(/chrome/site/tabs.css);</style>
|
||||
<!-- /Doxygen TracHeader -->
|
375
libssh/doc/authentication.dox
Normal file
375
libssh/doc/authentication.dox
Normal file
@ -0,0 +1,375 @@
|
||||
/**
|
||||
@page libssh_tutor_authentication Chapter 2: A deeper insight on authentication
|
||||
@section authentication_details A deeper insight on authentication
|
||||
|
||||
In our guided tour, we merely mentioned that the user needed to authenticate.
|
||||
We didn't explain much in detail how that was supposed to happen.
|
||||
This chapter explains better the four authentication methods: with public keys,
|
||||
with a password, with challenges and responses (keyboard-interactive), and with
|
||||
no authentication at all.
|
||||
|
||||
If your software is supposed to connect to an arbitrary server, then you
|
||||
might need to support all authentication methods. If your software will
|
||||
connect only to a given server, then it might be enough for your software
|
||||
to support only the authentication methods used by that server. If you are
|
||||
the administrator of the server, it might be your call to choose those
|
||||
authentication methods.
|
||||
|
||||
It is not the purpose of this document to review in detail the advantages
|
||||
and drawbacks of each authentication method. You are therefore invited
|
||||
to read the abundant documentation on this topic to fully understand the
|
||||
advantages and security risks linked to each method.
|
||||
|
||||
|
||||
@subsection pubkeys Authenticating with public keys
|
||||
|
||||
libssh is fully compatible with the openssh public and private keys. You
|
||||
can either use the automatic public key authentication method provided by
|
||||
libssh, or roll your own using the public key functions.
|
||||
|
||||
The process of authenticating by public key to a server is the following:
|
||||
- you scan a list of files that contain public keys. each key is sent to
|
||||
the SSH server, until the server acknowledges a key (a key it knows can be
|
||||
used to authenticate the user).
|
||||
- then, you retrieve the private key for this key and send a message
|
||||
proving that you know that private key.
|
||||
|
||||
The function ssh_userauth_autopubkey() does this using the available keys in
|
||||
"~/.ssh/". The return values are the following:
|
||||
- SSH_AUTH_ERROR: some serious error happened during authentication
|
||||
- SSH_AUTH_DENIED: no key matched
|
||||
- SSH_AUTH_SUCCESS: you are now authenticated
|
||||
- SSH_AUTH_PARTIAL: some key matched but you still have to provide an other
|
||||
mean of authentication (like a password).
|
||||
|
||||
The ssh_userauth_publickey_auto() function also tries to authenticate using the
|
||||
SSH agent, if you have one running, or the "none" method otherwise.
|
||||
|
||||
If you wish to authenticate with public key by your own, follow these steps:
|
||||
- Retrieve the public key with ssh_import_pubkey_file().
|
||||
- Offer the public key to the SSH server using ssh_userauth_try_publickey().
|
||||
If the return value is SSH_AUTH_SUCCESS, the SSH server accepts to
|
||||
authenticate using the public key and you can go to the next step.
|
||||
- Retrieve the private key, using the ssh_pki_import_privkey_file() function.
|
||||
If a passphrase is needed, either the passphrase specified as argument or
|
||||
a callback will be used.
|
||||
- Authenticate using ssh_userauth_publickey() with your private key.
|
||||
- Do not forget cleaning up memory using ssh_key_free().
|
||||
|
||||
Here is a minimalistic example of public key authentication:
|
||||
|
||||
@code
|
||||
int authenticate_pubkey(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_userauth_publickey_auto(session, NULL);
|
||||
|
||||
if (rc == SSH_AUTH_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Authentication failed: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see ssh_userauth_publickey_auto()
|
||||
@see ssh_userauth_try_publickey()
|
||||
@see ssh_userauth_publickey()
|
||||
@see ssh_pki_import_pubkey_file()
|
||||
@see ssh_pki_import_privkey_file()
|
||||
@see ssh_key_free()
|
||||
|
||||
|
||||
@subsection password Authenticating with a password
|
||||
|
||||
The function ssh_userauth_password() serves the purpose of authenticating
|
||||
using a password. It will return SSH_AUTH_SUCCESS if the password worked,
|
||||
or one of other constants otherwise. It's your work to ask the password
|
||||
and to deallocate it in a secure manner.
|
||||
|
||||
If your server complains that the password is wrong, but you can still
|
||||
authenticate using openssh's client (issuing password), it's probably
|
||||
because openssh only accept keyboard-interactive. Switch to
|
||||
keyboard-interactive authentication, or try to configure plain text passwords
|
||||
on the SSH server.
|
||||
|
||||
Here is a small example of password authentication:
|
||||
|
||||
@code
|
||||
int authenticate_password(ssh_session session)
|
||||
{
|
||||
char *password;
|
||||
int rc;
|
||||
|
||||
password = getpass("Enter your password: ");
|
||||
rc = ssh_userauth_password(session, NULL, password);
|
||||
if (rc == SSH_AUTH_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Authentication failed: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see ssh_userauth_password
|
||||
|
||||
|
||||
@subsection keyb_int The keyboard-interactive authentication method
|
||||
|
||||
The keyboard-interactive method is, as its name tells, interactive. The
|
||||
server will issue one or more challenges that the user has to answer,
|
||||
until the server takes an authentication decision.
|
||||
|
||||
ssh_userauth_kbdint() is the the main keyboard-interactive function.
|
||||
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
|
||||
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
|
||||
|
||||
The keyboard-interactive authentication method of SSH2 is a feature that
|
||||
permits the server to ask a certain number of questions in an interactive
|
||||
manner to the client, until it decides to accept or deny the login.
|
||||
|
||||
To begin, you call ssh_userauth_kbdint() (just set user and submethods to
|
||||
NULL) and store the answer.
|
||||
|
||||
If the answer is SSH_AUTH_INFO, it means that the server has sent a few
|
||||
questions that you should ask the user. You can retrieve these questions
|
||||
with the following functions: ssh_userauth_kbdint_getnprompts(),
|
||||
ssh_userauth_kbdint_getname(), ssh_userauth_kbdint_getinstruction(), and
|
||||
ssh_userauth_kbdint_getprompt().
|
||||
|
||||
Set the answer for each question in the challenge using
|
||||
ssh_userauth_kbdint_setanswer().
|
||||
|
||||
Then, call again ssh_userauth_kbdint() and start the process again until
|
||||
these functions returns something else than SSH_AUTH_INFO.
|
||||
|
||||
Here are a few remarks:
|
||||
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
|
||||
- The server can send an empty question set (this is the default behavior
|
||||
on my system) after you have sent the answers to the first questions.
|
||||
You must still parse the answer, it might contain some
|
||||
message from the server saying hello or such things. Just call
|
||||
ssh_userauth_kbdint() until needed.
|
||||
- The meaning of "name", "prompt", "instruction" may be a little
|
||||
confusing. An explanation is given in the RFC section that follows.
|
||||
|
||||
Here is a little note about how to use the information from
|
||||
keyboard-interactive authentication, coming from the RFC itself (rfc4256):
|
||||
|
||||
@verbatim
|
||||
|
||||
3.3 User Interface Upon receiving a request message, the client SHOULD
|
||||
prompt the user as follows: A command line interface (CLI) client SHOULD
|
||||
print the name and instruction (if non-empty), adding newlines. Then for
|
||||
each prompt in turn, the client SHOULD display the prompt and read the
|
||||
user input.
|
||||
|
||||
A graphical user interface (GUI) client has many choices on how to prompt
|
||||
the user. One possibility is to use the name field (possibly prefixed
|
||||
with the application's name) as the title of a dialog window in which
|
||||
the prompt(s) are presented. In that dialog window, the instruction field
|
||||
would be a text message, and the prompts would be labels for text entry
|
||||
fields. All fields SHOULD be presented to the user, for example an
|
||||
implementation SHOULD NOT discard the name field because its windows lack
|
||||
titles; it SHOULD instead find another way to display this information. If
|
||||
prompts are presented in a dialog window, then the client SHOULD NOT
|
||||
present each prompt in a separate window.
|
||||
|
||||
All clients MUST properly handle an instruction field with embedded
|
||||
newlines. They SHOULD also be able to display at least 30 characters for
|
||||
the name and prompts. If the server presents names or prompts longer than 30
|
||||
characters, the client MAY truncate these fields to the length it can
|
||||
display. If the client does truncate any fields, there MUST be an obvious
|
||||
indication that such truncation has occured.
|
||||
|
||||
The instruction field SHOULD NOT be truncated. Clients SHOULD use control
|
||||
character filtering as discussed in [SSH-ARCH] to avoid attacks by
|
||||
including terminal control characters in the fields to be displayed.
|
||||
|
||||
For each prompt, the corresponding echo field indicates whether or not
|
||||
the user input should be echoed as characters are typed. Clients SHOULD
|
||||
correctly echo/mask user input for each prompt independently of other
|
||||
prompts in the request message. If a client does not honor the echo field
|
||||
for whatever reason, then the client MUST err on the side of
|
||||
masking input. A GUI client might like to have a checkbox toggling
|
||||
echo/mask. Clients SHOULD NOT add any additional characters to the prompt
|
||||
such as ": " (colon-space); the server is responsible for supplying all
|
||||
text to be displayed to the user. Clients MUST also accept empty responses
|
||||
from the user and pass them on as empty strings.
|
||||
@endverbatim
|
||||
|
||||
The following example shows how to perform keyboard-interactive authentication:
|
||||
|
||||
@code
|
||||
int authenticate_kbdint(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_userauth_kbdint(session, NULL, NULL);
|
||||
while (rc == SSH_AUTH_INFO)
|
||||
{
|
||||
const char *name, *instruction;
|
||||
int nprompts, iprompt;
|
||||
|
||||
name = ssh_userauth_kbdint_getname(session);
|
||||
instruction = ssh_userauth_kbdint_getinstruction(session);
|
||||
nprompts = ssh_userauth_kbdint_getnprompts(session);
|
||||
|
||||
if (strlen(name) > 0)
|
||||
printf("%s\n", name);
|
||||
if (strlen(instruction) > 0)
|
||||
printf("%s\n", instruction);
|
||||
for (iprompt = 0; iprompt < nprompts; iprompt++)
|
||||
{
|
||||
const char *prompt;
|
||||
char echo;
|
||||
|
||||
prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo);
|
||||
if (echo)
|
||||
{
|
||||
char buffer[128], *ptr;
|
||||
|
||||
printf("%s", prompt);
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL)
|
||||
return SSH_AUTH_ERROR;
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
if (ssh_userauth_kbdint_setanswer(session, iprompt, buffer) < 0)
|
||||
return SSH_AUTH_ERROR;
|
||||
memset(buffer, 0, strlen(buffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = getpass(prompt);
|
||||
if (ssh_userauth_kbdint_setanswer(session, iprompt, ptr) < 0)
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
}
|
||||
rc = ssh_userauth_kbdint(session, NULL, NULL);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see ssh_userauth_kbdint()
|
||||
@see ssh_userauth_kbdint_getnprompts()
|
||||
@see ssh_userauth_kbdint_getname()
|
||||
@see ssh_userauth_kbdint_getinstruction()
|
||||
@see ssh_userauth_kbdint_getprompt()
|
||||
@see ssh_userauth_kbdint_setanswer()
|
||||
|
||||
|
||||
@subsection none Authenticating with "none" method
|
||||
|
||||
The primary purpose of the "none" method is to get authenticated **without**
|
||||
any credential. Don't do that, use one of the other authentication methods,
|
||||
unless you really want to grant anonymous access.
|
||||
|
||||
If the account has no password, and if the server is configured to let you
|
||||
pass, ssh_userauth_none() might answer SSH_AUTH_SUCCESS.
|
||||
|
||||
The following example shows how to perform "none" authentication:
|
||||
|
||||
@code
|
||||
int authenticate_kbdint(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_userauth_none(session, NULL, NULL);
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@subsection auth_list Getting the list of supported authentications
|
||||
|
||||
You are not meant to choose a given authentication method, you can
|
||||
let the server tell you which methods are available. Once you know them,
|
||||
you try them one after the other.
|
||||
|
||||
The following example shows how to get the list of available authentication
|
||||
methods with ssh_userauth_list() and how to use the result:
|
||||
|
||||
@code
|
||||
int test_several_auth_methods(ssh_session session)
|
||||
{
|
||||
int method, rc;
|
||||
|
||||
rc = ssh_userauth_none(session, NULL, NULL);
|
||||
if (rc != SSH_AUTH_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
method = ssh_userauth_list(session, NULL);
|
||||
|
||||
if (method & SSH_AUTH_METHOD_NONE)
|
||||
{ // For the source code of function authenticate_none(),
|
||||
// refer to the corresponding example
|
||||
rc = authenticate_none(session);
|
||||
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||
}
|
||||
if (method & SSH_AUTH_METHOD_PUBLICKEY)
|
||||
{ // For the source code of function authenticate_pubkey(),
|
||||
// refer to the corresponding example
|
||||
rc = authenticate_pubkey(session);
|
||||
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||
}
|
||||
if (method & SSH_AUTH_METHOD_INTERACTIVE)
|
||||
{ // For the source code of function authenticate_kbdint(),
|
||||
// refer to the corresponding example
|
||||
rc = authenticate_kbdint(session);
|
||||
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||
}
|
||||
if (method & SSH_AUTH_METHOD_PASSWORD)
|
||||
{ // For the source code of function authenticate_password(),
|
||||
// refer to the corresponding example
|
||||
rc = authenticate_password(session);
|
||||
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||
}
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection banner Getting the banner
|
||||
|
||||
The SSH server might send a banner, which you can retrieve with
|
||||
ssh_get_issue_banner(), then display to the user.
|
||||
|
||||
The following example shows how to retrieve and dispose the issue banner:
|
||||
|
||||
@code
|
||||
int display_banner(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
char *banner;
|
||||
|
||||
/*
|
||||
*** Does not work without calling ssh_userauth_none() first ***
|
||||
*** That will be fixed ***
|
||||
*/
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
if (rc == SSH_AUTH_ERROR)
|
||||
return rc;
|
||||
|
||||
banner = ssh_get_issue_banner(session);
|
||||
if (banner)
|
||||
{
|
||||
printf("%s\n", banner);
|
||||
free(banner);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
94
libssh/doc/command.dox
Normal file
94
libssh/doc/command.dox
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
@page libssh_tutor_command Chapter 4: Passing a remote command
|
||||
@section remote_command Passing a remote command
|
||||
|
||||
Previous chapter has shown how to open a full shell session, with an attached
|
||||
terminal or not. If you only need to execute a command on the remote end,
|
||||
you don't need all that complexity.
|
||||
|
||||
The method described here is suited for executing only one remote command.
|
||||
If you need to issue several commands in a row, you should consider using
|
||||
a non-interactive remote shell, as explained in previous chapter.
|
||||
|
||||
@see shell
|
||||
|
||||
|
||||
@subsection exec_remote Executing a remote command
|
||||
|
||||
The first steps for executing a remote command are identical to those
|
||||
for opening remote shells. You first need a SSH channel, and then
|
||||
a SSH session that uses this channel:
|
||||
|
||||
@code
|
||||
int show_remote_files(ssh_session session)
|
||||
{
|
||||
ssh_channel channel;
|
||||
int rc;
|
||||
|
||||
channel = ssh_channel_new(session);
|
||||
if (channel == NULL) return SSH_ERROR;
|
||||
|
||||
rc = ssh_channel_open_session(channel);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
ssh_channel_free(channel);
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Once a session is open, you can start the remote command with
|
||||
ssh_channel_request_exec():
|
||||
|
||||
@code
|
||||
rc = ssh_channel_request_exec(channel, "ls -l");
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
If the remote command displays data, you get them with ssh_channel_read().
|
||||
This function returns the number of bytes read. If there is no more
|
||||
data to read on the channel, this function returns 0, and you can go to next step.
|
||||
If an error has been encountered, it returns a negative value:
|
||||
|
||||
@code
|
||||
char buffer[256];
|
||||
unsigned int nbytes;
|
||||
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
while (nbytes > 0)
|
||||
{
|
||||
if (fwrite(buffer, 1, nbytes, stdout) != nbytes)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
}
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Once you read the result of the remote command, you send an
|
||||
end-of-file to the channel, close it, and free the memory
|
||||
that it used:
|
||||
|
||||
@code
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
1835
libssh/doc/doxy.config.in
Normal file
1835
libssh/doc/doxy.config.in
Normal file
File diff suppressed because it is too large
Load Diff
1546
libssh/doc/doxy.trac.in
Normal file
1546
libssh/doc/doxy.trac.in
Normal file
File diff suppressed because it is too large
Load Diff
229
libssh/doc/forwarding.dox
Normal file
229
libssh/doc/forwarding.dox
Normal file
@ -0,0 +1,229 @@
|
||||
/**
|
||||
@page libssh_tutor_forwarding Chapter 7: Forwarding connections (tunnel)
|
||||
@section forwarding_connections Forwarding connections
|
||||
|
||||
Port forwarding comes in SSH protocol in two different flavours:
|
||||
direct or reverse port forwarding. Direct port forwarding is also
|
||||
named local port forwardind, and reverse port forwarding is also called
|
||||
remote port forwarding. SSH also allows X11 tunnels.
|
||||
|
||||
|
||||
|
||||
@subsection forwarding_direct Direct port forwarding
|
||||
|
||||
Direct port forwarding is from client to server. The client opens a tunnel,
|
||||
and forwards whatever data to the server. Then, the server connects to an
|
||||
end point. The end point can reside on another machine or on the SSH
|
||||
server itself.
|
||||
|
||||
Example of use of direct port forwarding:
|
||||
@verbatim
|
||||
Mail client application Google Mail
|
||||
| ^
|
||||
5555 (arbitrary) |
|
||||
| 143 (IMAP2)
|
||||
V |
|
||||
SSH client =====> SSH server
|
||||
|
||||
Legend:
|
||||
--P-->: port connexion through port P
|
||||
=====>: SSH tunnel
|
||||
@endverbatim
|
||||
A mail client connects to port 5555 of a client. An encrypted tunnel is
|
||||
established to the server. The server connects to port 143 of Google Mail (the
|
||||
end point). Now the local mail client can retreive mail.
|
||||
|
||||
|
||||
@subsection forwarding_reverse Reverse port forwarding
|
||||
|
||||
The reverse forwarding is slightly different. It goes from server to client,
|
||||
even though the client has the initiative of establishing the tunnel.
|
||||
Once the tunnel is established, the server will listen on a port. Whenever
|
||||
a connection to this port is made, the server forwards the data to the client.
|
||||
|
||||
Example of use of reverse port forwarding:
|
||||
@verbatim
|
||||
Local mail server Mail client application
|
||||
^ |
|
||||
| 5555 (arbitrary)
|
||||
143 (IMAP2) |
|
||||
| V
|
||||
SSH client <===== SSH server
|
||||
|
||||
Legend:
|
||||
--P-->: port connexion through port P
|
||||
=====>: SSH tunnel
|
||||
@endverbatim
|
||||
In this example, the SSH client establishes the tunnel,
|
||||
but it is used to forward the connections established at
|
||||
the server to the client.
|
||||
|
||||
|
||||
@subsection forwarding_x11 X11 tunnels
|
||||
|
||||
X11 tunnels allow a remote application to display locally.
|
||||
|
||||
Example of use of X11 tunnels:
|
||||
@verbatim
|
||||
Local display Graphical application
|
||||
(X11 server) (X11 client)
|
||||
^ |
|
||||
| V
|
||||
SSH client <===== SSH server
|
||||
|
||||
Legend:
|
||||
----->: X11 connection through X11 display number
|
||||
=====>: SSH tunnel
|
||||
@endverbatim
|
||||
The SSH tunnel is established by the client.
|
||||
|
||||
How to establish X11 tunnels with libssh has already been described in
|
||||
this tutorial.
|
||||
|
||||
@see x11
|
||||
|
||||
|
||||
@subsection libssh_direct Doing direct port forwarding with libssh
|
||||
|
||||
To do direct port forwarding, call function ssh_channel_open_forward():
|
||||
- you need a separate channel for the tunnel as first parameter;
|
||||
- second and third parameters are the remote endpoint;
|
||||
- fourth and fifth parameters are sent to the remote server
|
||||
so that they can be logged on that server.
|
||||
|
||||
If you don't plan to forward the data you will receive to any local port,
|
||||
just put fake values like "localhost" and 5555 as your local host and port.
|
||||
|
||||
The example below shows how to open a direct channel that would be
|
||||
used to retrieve google's home page from the remote SSH server.
|
||||
|
||||
@code
|
||||
int direct_forwarding(ssh_session session)
|
||||
{
|
||||
ssh_channel forwarding_channel;
|
||||
int rc;
|
||||
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
|
||||
int nbytes, nwritten;
|
||||
|
||||
forwarding_channel = ssh_channel_new(session);
|
||||
if (forwarding_channel == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_channel_open_forward(forwarding_channel,
|
||||
"www.google.com", 80,
|
||||
"localhost", 5555);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
ssh_channel_free(forwarding_channel);
|
||||
return rc;
|
||||
}
|
||||
|
||||
nbytes = strlen(http_get);
|
||||
nwritten = ssh_channel_write(forwarding_channel,
|
||||
http_get,
|
||||
nbytes);
|
||||
if (nbytes != nwritten)
|
||||
{
|
||||
ssh_channel_free(forwarding_channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
ssh_channel_free(forwarding_channel);
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
The data sent by Google can be retrieved for example with ssh_select()
|
||||
and ssh_channel_read(). Goggle's home page can then be displayed on the
|
||||
local SSH client, saved into a local file, made available on a local port,
|
||||
or whatever use you have for it.
|
||||
|
||||
|
||||
@subsection libssh_reverse Doing reverse port forwarding with libssh
|
||||
|
||||
To do reverse port forwarding, call ssh_forward_listen(),
|
||||
then ssh_forward_accept().
|
||||
|
||||
When you call ssh_forward_listen(), you can let the remote server
|
||||
chose the non-priviledged port it should listen to. Otherwise, you can chose
|
||||
your own priviledged or non-priviledged port. Beware that you should have
|
||||
administrative priviledges on the remote server to open a priviledged port
|
||||
(port number < 1024).
|
||||
|
||||
Below is an example of a very rough web server waiting for connections on port
|
||||
8080 of remote SSH server. The incoming connections are passed to the
|
||||
local libssh application, which handles them:
|
||||
|
||||
@code
|
||||
int web_server(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
ssh_channel channel;
|
||||
char buffer[256];
|
||||
int nbytes, nwritten;
|
||||
char *helloworld = ""
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Content-Length: 113\n"
|
||||
"\n"
|
||||
"<html>\n"
|
||||
" <head>\n"
|
||||
" <title>Hello, World!</title>\n"
|
||||
" </head>\n"
|
||||
" <body>\n"
|
||||
" <h1>Hello, World!</h1>\n"
|
||||
" </body>\n"
|
||||
"</html>\n";
|
||||
|
||||
rc = ssh_forward_listen(session, NULL, 8080, NULL);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error opening remote port: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
channel = ssh_forward_accept(session, 60000);
|
||||
if (channel == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error waiting for incoming connection: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
if (nbytes < 0)
|
||||
{
|
||||
fprintf(stderr, "Error reading incoming data: %s\n",
|
||||
ssh_get_error(session));
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (strncmp(buffer, "GET /", 5)) continue;
|
||||
|
||||
nbytes = strlen(helloworld);
|
||||
nwritten = ssh_channel_write(channel, helloworld, nbytes);
|
||||
if (nwritten != nbytes)
|
||||
{
|
||||
fprintf(stderr, "Error sending answer: %s\n",
|
||||
ssh_get_error(session));
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
printf("Sent answer\n");
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
455
libssh/doc/guided_tour.dox
Normal file
455
libssh/doc/guided_tour.dox
Normal file
@ -0,0 +1,455 @@
|
||||
/**
|
||||
@page libssh_tutor_guided_tour Chapter 1: A typical SSH session
|
||||
@section ssh_session A typical SSH session
|
||||
|
||||
A SSH session goes through the following steps:
|
||||
|
||||
- Before connecting to the server, you can set up if you wish one or other
|
||||
server public key authentication, i.e. DSA or RSA. You can choose
|
||||
cryptographic algorithms you trust and compression algorithms if any. You
|
||||
must of course set up the hostname.
|
||||
|
||||
- The connection is established. A secure handshake is made, and resulting from
|
||||
it, a public key from the server is gained. You MUST verify that the public
|
||||
key is legitimate, using for instance the MD5 fingerprint or the known hosts
|
||||
file.
|
||||
|
||||
- The client must authenticate: the classical ways are password, or
|
||||
public keys (from dsa and rsa key-pairs generated by openssh).
|
||||
If a SSH agent is running, it is possible to use it.
|
||||
|
||||
- Now that the user has been authenticated, you must open one or several
|
||||
channels. Channels are different subways for information into a single ssh
|
||||
connection. Each channel has a standard stream (stdout) and an error stream
|
||||
(stderr). You can theoretically open an infinity of channels.
|
||||
|
||||
- With the channel you opened, you can do several things:
|
||||
- Execute a single command.
|
||||
- Open a shell. You may want to request a pseudo-terminal before.
|
||||
- Invoke the sftp subsystem to transfer files.
|
||||
- Invoke the scp subsystem to transfer files.
|
||||
- Invoke your own subsystem. This is outside the scope of this document,
|
||||
but can be done.
|
||||
|
||||
- When everything is finished, just close the channels, and then the connection.
|
||||
|
||||
The sftp and scp subsystems use channels, but libssh hides them to
|
||||
the programmer. If you want to use those subsystems, instead of a channel,
|
||||
you'll usually open a "sftp session" or a "scp session".
|
||||
|
||||
|
||||
@subsection setup Creating the session and setting options
|
||||
|
||||
The most important object in a SSH connection is the SSH session. In order
|
||||
to allocate a new SSH session, you use ssh_new(). Don't forget to
|
||||
always verify that the allocation successed.
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ssh_session my_ssh_session = ssh_new();
|
||||
if (my_ssh_session == NULL)
|
||||
exit(-1);
|
||||
...
|
||||
ssh_free(my_ssh_session);
|
||||
}
|
||||
@endcode
|
||||
|
||||
libssh follows the allocate-it-deallocate-it pattern. Each object that you allocate
|
||||
using xxxxx_new() must be deallocated using xxxxx_free(). In this case, ssh_new()
|
||||
does the allocation and ssh_free() does the contrary.
|
||||
|
||||
The ssh_options_set() function sets the options of the session. The most important options are:
|
||||
- SSH_OPTIONS_HOST: the name of the host you want to connect to
|
||||
- SSH_OPTIONS_PORT: the used port (default is port 22)
|
||||
- SSH_OPTIONS_USER: the system user under which you want to connect
|
||||
- SSH_OPTIONS_LOG_VERBOSITY: the quantity of messages that are printed
|
||||
|
||||
The complete list of options can be found in the documentation of ssh_options_set().
|
||||
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
|
||||
the local username of your account will be used.
|
||||
|
||||
Here is a small example of how to use it:
|
||||
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ssh_session my_ssh_session;
|
||||
int verbosity = SSH_LOG_PROTOCOL;
|
||||
int port = 22;
|
||||
|
||||
my_ssh_session = ssh_new();
|
||||
if (my_ssh_session == NULL)
|
||||
exit(-1);
|
||||
|
||||
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
|
||||
ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
|
||||
|
||||
...
|
||||
|
||||
ssh_free(my_ssh_session);
|
||||
}
|
||||
@endcode
|
||||
|
||||
Please notice that all parameters are passed to ssh_options_set() as pointers,
|
||||
even if you need to set an integer value.
|
||||
|
||||
@see ssh_new
|
||||
@see ssh_free
|
||||
@see ssh_options_set
|
||||
@see ssh_options_parse_config
|
||||
@see ssh_options_copy
|
||||
@see ssh_options_getopt
|
||||
|
||||
|
||||
@subsection connect Connecting to the server
|
||||
|
||||
Once all settings have been made, you can connect using ssh_connect(). That
|
||||
function will return SSH_OK if the connection worked, SSH_ERROR otherwise.
|
||||
|
||||
You can get the English error string with ssh_get_error() in order to show the
|
||||
user what went wrong. Then, use ssh_disconnect() when you want to stop
|
||||
the session.
|
||||
|
||||
Here's an example:
|
||||
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ssh_session my_ssh_session;
|
||||
int rc;
|
||||
|
||||
my_ssh_session = ssh_new();
|
||||
if (my_ssh_session == NULL)
|
||||
exit(-1);
|
||||
|
||||
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
|
||||
|
||||
rc = ssh_connect(my_ssh_session);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error connecting to localhost: %s\n",
|
||||
ssh_get_error(my_ssh_session));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
ssh_disconnect(my_ssh_session);
|
||||
ssh_free(my_ssh_session);
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection serverauth Authenticating the server
|
||||
|
||||
Once you're connected, the following step is mandatory: you must check that the server
|
||||
you just connected to is known and safe to use (remember, SSH is about security and
|
||||
authentication).
|
||||
|
||||
There are two ways of doing this:
|
||||
- The first way (recommended) is to use the ssh_is_server_known()
|
||||
function. This function will look into the known host file
|
||||
(~/.ssh/known_hosts on UNIX), look for the server hostname's pattern,
|
||||
and determine whether this host is present or not in the list.
|
||||
- The second way is to use ssh_get_pubkey_hash() to get a binary version
|
||||
of the public key hash value. You can then use your own database to check
|
||||
if this public key is known and secure.
|
||||
|
||||
You can also use the ssh_get_pubkey_hash() to show the public key hash
|
||||
value to the user, in case he knows what the public key hash value is
|
||||
(some paranoid people write their public key hash values on paper before
|
||||
going abroad, just in case ...).
|
||||
|
||||
If the remote host is being used to for the first time, you can ask the user whether
|
||||
he/she trusts it. Once he/she concluded that the host is valid and worth being
|
||||
added in the known hosts file, you use ssh_write_knownhost() to register it in
|
||||
the known hosts file, or any other way if you use your own database.
|
||||
|
||||
The following example is part of the examples suite available in the
|
||||
examples/ directory:
|
||||
|
||||
@code
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int verify_knownhost(ssh_session session)
|
||||
{
|
||||
int state, hlen;
|
||||
unsigned char *hash = NULL;
|
||||
char *hexa;
|
||||
char buf[10];
|
||||
|
||||
state = ssh_is_server_known(session);
|
||||
|
||||
hlen = ssh_get_pubkey_hash(session, &hash);
|
||||
if (hlen < 0)
|
||||
return -1;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SSH_SERVER_KNOWN_OK:
|
||||
break; /* ok */
|
||||
|
||||
case SSH_SERVER_KNOWN_CHANGED:
|
||||
fprintf(stderr, "Host key for server changed: it is now:\n");
|
||||
ssh_print_hexa("Public key hash", hash, hlen);
|
||||
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
||||
free(hash);
|
||||
return -1;
|
||||
|
||||
case SSH_SERVER_FOUND_OTHER:
|
||||
fprintf(stderr, "The host key for this server was not found but an other"
|
||||
"type of key exists.\n");
|
||||
fprintf(stderr, "An attacker might change the default server key to"
|
||||
"confuse your client into thinking the key does not exist\n");
|
||||
free(hash);
|
||||
return -1;
|
||||
|
||||
case SSH_SERVER_FILE_NOT_FOUND:
|
||||
fprintf(stderr, "Could not find known host file.\n");
|
||||
fprintf(stderr, "If you accept the host key here, the file will be"
|
||||
"automatically created.\n");
|
||||
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
||||
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
hexa = ssh_get_hexa(hash, hlen);
|
||||
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||
free(hexa);
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
||||
{
|
||||
free(hash);
|
||||
return -1;
|
||||
}
|
||||
if (strncasecmp(buf, "yes", 3) != 0)
|
||||
{
|
||||
free(hash);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_write_knownhost(session) < 0)
|
||||
{
|
||||
fprintf(stderr, "Error %s\n", strerror(errno));
|
||||
free(hash);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SSH_SERVER_ERROR:
|
||||
fprintf(stderr, "Error %s", ssh_get_error(session));
|
||||
free(hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(hash);
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see ssh_connect
|
||||
@see ssh_disconnect
|
||||
@see ssh_get_error
|
||||
@see ssh_get_error_code
|
||||
@see ssh_get_pubkey_hash
|
||||
@see ssh_is_server_known
|
||||
@see ssh_write_knownhost
|
||||
|
||||
|
||||
@subsection auth Authenticating the user
|
||||
|
||||
The authentication process is the way a service provider can identify a
|
||||
user and verify his/her identity. The authorization process is about enabling
|
||||
the authenticated user the access to ressources. In SSH, the two concepts
|
||||
are linked. After authentication, the server can grant the user access to
|
||||
several ressources such as port forwarding, shell, sftp subsystem, and so on.
|
||||
|
||||
libssh supports several methods of authentication:
|
||||
- "none" method. This method allows to get the available authentications
|
||||
methods. It also gives the server a chance to authenticate the user with
|
||||
just his/her login. Some very old hardware uses this feature to fallback
|
||||
the user on a "telnet over SSH" style of login.
|
||||
- password method. A password is sent to the server, which accepts it or not.
|
||||
- keyboard-interactive method. The server sends several challenges to the
|
||||
user, who must answer correctly. This makes possible the authentication
|
||||
via a codebook for instance ("give code at 23:R on page 3").
|
||||
- public key method. The host knows the public key of the user, and the
|
||||
user must prove he knows the associated private key. This can be done
|
||||
manually, or delegated to the SSH agent as we'll see later.
|
||||
|
||||
All these methods can be combined. You can for instance force the user to
|
||||
authenticate with at least two of the authentication methods. In that case,
|
||||
one speaks of "Partial authentication". A partial authentication is a
|
||||
response from authentication functions stating that your credential was
|
||||
accepted, but yet another one is required to get in.
|
||||
|
||||
The example below shows an authentication with password:
|
||||
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ssh_session my_ssh_session;
|
||||
int rc;
|
||||
char *password;
|
||||
|
||||
// Open session and set options
|
||||
my_ssh_session = ssh_new();
|
||||
if (my_ssh_session == NULL)
|
||||
exit(-1);
|
||||
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
|
||||
|
||||
// Connect to server
|
||||
rc = ssh_connect(my_ssh_session);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error connecting to localhost: %s\n",
|
||||
ssh_get_error(my_ssh_session));
|
||||
ssh_free(my_ssh_session);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Verify the server's identity
|
||||
// For the source code of verify_knowhost(), check previous example
|
||||
if (verify_knownhost(my_ssh_session) < 0)
|
||||
{
|
||||
ssh_disconnect(my_ssh_session);
|
||||
ssh_free(my_ssh_session);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Authenticate ourselves
|
||||
password = getpass("Password: ");
|
||||
rc = ssh_userauth_password(my_ssh_session, NULL, password);
|
||||
if (rc != SSH_AUTH_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "Error authenticating with password: %s\n",
|
||||
ssh_get_error(my_ssh_session));
|
||||
ssh_disconnect(my_ssh_session);
|
||||
ssh_free(my_ssh_session);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
ssh_disconnect(my_ssh_session);
|
||||
ssh_free(my_ssh_session);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see @ref authentication_details
|
||||
|
||||
|
||||
@subsection using_ssh Doing something
|
||||
|
||||
At this point, the authenticity of both server and client is established.
|
||||
Time has come to take advantage of the many possibilities offered by the SSH
|
||||
protocol: execute a remote command, open remote shells, transfer files,
|
||||
forward ports, etc.
|
||||
|
||||
The example below shows how to execute a remote command:
|
||||
|
||||
@code
|
||||
int show_remote_processes(ssh_session session)
|
||||
{
|
||||
ssh_channel channel;
|
||||
int rc;
|
||||
char buffer[256];
|
||||
unsigned int nbytes;
|
||||
|
||||
channel = ssh_channel_new(session);
|
||||
if (channel == NULL)
|
||||
return SSH_ERROR;
|
||||
|
||||
rc = ssh_channel_open_session(channel);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
ssh_channel_free(channel);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_channel_request_exec(channel, "ps aux");
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return rc;
|
||||
}
|
||||
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
while (nbytes > 0)
|
||||
{
|
||||
if (write(1, buffer, nbytes) != nbytes)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
}
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see @ref opening_shell
|
||||
@see @ref remote_command
|
||||
@see @ref sftp_subsystem
|
||||
@see @ref scp_subsystem
|
||||
|
||||
|
||||
@subsection errors Handling the errors
|
||||
|
||||
All the libssh functions which return an error value also set an English error message
|
||||
describing the problem.
|
||||
|
||||
Error values are typically SSH_ERROR for integer values, or NULL for pointers.
|
||||
|
||||
The function ssh_get_error() returns a pointer to the static error message.
|
||||
|
||||
ssh_error_code() returns the error code number : SSH_NO_ERROR,
|
||||
SSH_REQUEST_DENIED, SSH_INVALID_REQUEST, SSH_CONNECTION_LOST, SSH_FATAL,
|
||||
or SSH_INVALID_DATA. SSH_REQUEST_DENIED means the ssh server refused your
|
||||
request, but the situation is recoverable. The others mean something happened
|
||||
to the connection (some encryption problems, server problems, ...).
|
||||
SSH_INVALID_REQUEST means the library got some garbage from server, but
|
||||
might be recoverable. SSH_FATAL means the connection has an important
|
||||
problem and isn't probably recoverable.
|
||||
|
||||
Most of time, the error returned are SSH_FATAL, but some functions
|
||||
(generaly the ssh_request_xxx ones) may fail because of server denying request.
|
||||
In these cases, SSH_REQUEST_DENIED is returned.
|
||||
|
||||
ssh_get_error() and ssh_get_error_code() take a ssh_session as a parameter.
|
||||
That's for thread safety, error messages that can be attached to a session
|
||||
aren't static anymore. Any error that happens during ssh_options_xxx()
|
||||
or ssh_connect() (i.e., outside of any session) can be retrieved by
|
||||
giving NULL as argument.
|
||||
|
||||
The SFTP subsystem has its own error codes, in addition to libssh ones.
|
||||
|
||||
|
||||
*/
|
49
libssh/doc/introduction.dox
Normal file
49
libssh/doc/introduction.dox
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
@page libssh_tutorial The Tutorial
|
||||
@section introduction Introduction
|
||||
|
||||
libssh is a C library that enables you to write a program that uses the
|
||||
SSH protocol. With it, you can remotely execute programs, transfer
|
||||
files, or use a secure and transparent tunnel for your remote programs.
|
||||
The SSH protocol is encrypted, ensures data integrity, and provides strong
|
||||
means of authenticating both the server of the client. The library hides
|
||||
a lot of technical details from the SSH protocol, but this does not
|
||||
mean that you should not try to know about and understand these details.
|
||||
|
||||
libssh is a Free Software / Open Source project. The libssh library
|
||||
is distributed under LGPL license. The libssh project has nothing to do with
|
||||
"libssh2", which is a completly different and independant project.
|
||||
|
||||
libssh can run on top of either libgcrypt or libcrypto,
|
||||
two general-purpose cryptographic libraries.
|
||||
|
||||
This tutorial concentrates for its main part on the "client" side of libssh.
|
||||
To learn how to accept incoming SSH connexions (how to write a SSH server),
|
||||
you'll have to jump to the end of this document.
|
||||
|
||||
This tutorial describes libssh version 0.5.0. This version is a little different
|
||||
from the 0.4.X series. However, the examples should work with
|
||||
little changes on versions like 0.4.2 and later.
|
||||
|
||||
|
||||
Table of contents:
|
||||
|
||||
@subpage libssh_tutor_guided_tour
|
||||
|
||||
@subpage libssh_tutor_authentication
|
||||
|
||||
@subpage libssh_tutor_shell
|
||||
|
||||
@subpage libssh_tutor_command
|
||||
|
||||
@subpage libssh_tutor_sftp
|
||||
|
||||
@subpage libssh_tutor_scp
|
||||
|
||||
@subpage libssh_tutor_forwarding
|
||||
|
||||
@subpage libssh_tutor_threads
|
||||
|
||||
@subpage libssh_tutor_todo
|
||||
|
||||
*/
|
24
libssh/doc/linking.dox
Normal file
24
libssh/doc/linking.dox
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
|
||||
@page libssh_linking The Linking HowTo
|
||||
|
||||
@section dynamic Dynamic Linking
|
||||
|
||||
On UNIX and Windows systems its the same, you need at least the libssh.h
|
||||
header file and the libssh shared library.
|
||||
|
||||
@section static Static Linking
|
||||
|
||||
@warning <b>The libssh library is licensed under the LGPL! Make sure you
|
||||
understand what this means to your codebase if you want to distribute
|
||||
binaries and link statically against LGPL code!</b>
|
||||
|
||||
On UNIX systems linking against the static version of the library is the
|
||||
same as linking against the shared library. Both have the same name. Some
|
||||
build system require to use the full path to the static library.
|
||||
|
||||
On Windows you need to define LIBSSH_STATIC in the compiler command
|
||||
line. This is required cause the dynamic library needs to specify the
|
||||
dllimport attribute.
|
||||
|
||||
*/
|
211
libssh/doc/mainpage.dox
Normal file
211
libssh/doc/mainpage.dox
Normal file
@ -0,0 +1,211 @@
|
||||
/**
|
||||
|
||||
@mainpage
|
||||
|
||||
This is the online reference for developing with the libssh library. It
|
||||
documents the libssh C API and the C++ wrapper.
|
||||
|
||||
@section main-linking Linking
|
||||
|
||||
We created a small howto how to link libssh against your application, read
|
||||
@subpage libssh_linking.
|
||||
|
||||
@section main-tutorial Tutorial
|
||||
|
||||
You should start by reading @subpage libssh_tutorial, then reading the documentation of
|
||||
the interesting functions as you go.
|
||||
|
||||
@section main-features Features
|
||||
|
||||
The libssh library provides:
|
||||
|
||||
- Full C library functions for manipulating a client-side SSH connection
|
||||
- SSH2 and SSH1 protocol compliant
|
||||
- Fully configurable sessions
|
||||
- Server support
|
||||
- SSH agent authentication support
|
||||
- Support for AES-128, AES-192, AES-256, Blowfish, 3DES in CBC mode, and AES in CTR mode
|
||||
- Supports OpenSSL and GCrypt
|
||||
- Use multiple SSH connections in a same process, at same time
|
||||
- Use multiple channels in the same connection
|
||||
- Thread safety when using different sessions at same time
|
||||
- POSIX-like SFTP (Secure File Transfer) implementation with openssh extension support
|
||||
- SCP implementation
|
||||
- Large file system support (files bigger than 4GB)
|
||||
- RSA and DSS server public key supported
|
||||
- Compression support (with zlib)
|
||||
- Public key (RSA and DSS), password and keyboard-interactive authentication
|
||||
- Full poll()/WSAPoll() support and a poll-emulation for Win32.
|
||||
- Runs and tested under x86_64, x86, ARM, Sparc32, PPC under Linux, BSD, MacOSX, Solaris and Windows
|
||||
|
||||
@section main-copyright Copyright Policy
|
||||
|
||||
libssh is a project with distributed copyright ownership, which means we prefer
|
||||
the copyright on parts of libssh to be held by individuals rather than
|
||||
corporations if possible. There are historical legal reasons for this, but one
|
||||
of the best ways to explain it is that it’s much easier to work with
|
||||
individuals who have ownership than corporate legal departments if we ever need
|
||||
to make reasonable compromises with people using and working with libssh.
|
||||
|
||||
We track the ownership of every part of libssh via git, our source code control
|
||||
system, so we know the provenance of every piece of code that is committed to
|
||||
libssh.
|
||||
|
||||
So if possible, if you’re doing libssh changes on behalf of a company who
|
||||
normally owns all the work you do please get them to assign personal copyright
|
||||
ownership of your changes to you as an individual, that makes things very easy
|
||||
for us to work with and avoids bringing corporate legal departments into the
|
||||
picture.
|
||||
|
||||
If you can’t do this we can still accept patches from you owned by your
|
||||
employer under a standard employment contract with corporate copyright
|
||||
ownership. It just requires a simple set-up process first.
|
||||
|
||||
We use a process very similar to the way things are done in the Linux Kernel
|
||||
community, so it should be very easy to get a sign off from your corporate
|
||||
legal department. The only changes we’ve made are to accommodate the license we
|
||||
use, which is LGPLv2 (or later) whereas the Linux kernel uses GPLv2.
|
||||
|
||||
The process is called signing.
|
||||
|
||||
How to sign your work
|
||||
----------------------
|
||||
|
||||
Once you have permission to contribute to libssh from your employer, simply
|
||||
email a copy of the following text from your corporate email address to:
|
||||
|
||||
contributing@libssh.org
|
||||
|
||||
@verbatim
|
||||
libssh Developer's Certificate of Origin. Version 1.0
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the appropriate
|
||||
version of the GNU General Public License; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of
|
||||
my knowledge, is covered under an appropriate open source license
|
||||
and I have the right under that license to submit that work with
|
||||
modifications, whether created in whole or in part by me, under
|
||||
the GNU General Public License, in the appropriate version; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a) or (b) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are
|
||||
public and that a record of the contribution (including all
|
||||
metadata and personal information I submit with it, including my
|
||||
sign-off) is maintained indefinitely and may be redistributed
|
||||
consistent with the libssh Team's policies and the requirements of
|
||||
the GNU GPL where they are relevant.
|
||||
|
||||
(e) I am granting this work to this project under the terms of the
|
||||
GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2.1 of
|
||||
the License, or (at the option of the project) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
@endverbatim
|
||||
|
||||
We will maintain a copy of that email as a record that you have the rights to
|
||||
contribute code to libssh under the required licenses whilst working for the
|
||||
company where the email came from.
|
||||
|
||||
Then when sending in a patch via the normal mechanisms described above, add a
|
||||
line that states:
|
||||
|
||||
@verbatim
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
@endverbatim
|
||||
|
||||
using your real name and the email address you sent the original email you used
|
||||
to send the libssh Developer’s Certificate of Origin to us (sorry, no
|
||||
pseudonyms or anonymous contributions.)
|
||||
|
||||
That’s it! Such code can then quite happily contain changes that have copyright
|
||||
messages such as:
|
||||
|
||||
@verbatim
|
||||
(c) Example Corporation.
|
||||
@endverbatim
|
||||
|
||||
and can be merged into the libssh codebase in the same way as patches from any
|
||||
other individual. You don’t need to send in a copy of the libssh Developer’s
|
||||
Certificate of Origin for each patch, or inside each patch. Just the sign-off
|
||||
message is all that is required once we’ve received the initial email.
|
||||
|
||||
Have fun and happy libssh hacking!
|
||||
|
||||
The libssh Team
|
||||
|
||||
@section main-rfc Internet standard
|
||||
|
||||
@subsection main-rfc-secsh Secure Shell (SSH)
|
||||
|
||||
The following RFC documents described SSH-2 protcol as an Internet standard.
|
||||
|
||||
- <a href="http://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
|
||||
The Secure Shell (SSH) Protocol Assigned Numbers
|
||||
- <a href="http://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
|
||||
The Secure Shell (SSH) Protocol Architecture
|
||||
- <a href="http://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
|
||||
The Secure Shell (SSH) Authentication Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
|
||||
The Secure Shell (SSH) Transport Layer Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
|
||||
The Secure Shell (SSH) Connection Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
|
||||
Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
||||
- <a href="http://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
|
||||
Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
|
||||
- <a href="http://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
|
||||
The Secure Shell (SSH) Session Channel Break Extension
|
||||
- <a href="http://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
|
||||
The Secure Shell (SSH) Transport Layer Encryption Modes
|
||||
- <a href="http://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
|
||||
Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
|
||||
|
||||
It was later modified and expanded by the following RFCs.
|
||||
|
||||
- <a href="http://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
|
||||
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
|
||||
Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
|
||||
RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
|
||||
Generic Security Service Application Program Interface (GSS-API)
|
||||
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
||||
The Secure Shell (SSH) Public Key File Format
|
||||
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
||||
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
||||
|
||||
Interesting cryptography documents:
|
||||
|
||||
- <a href="http://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
|
||||
|
||||
@subsection main-rfc-sftp Secure Shell File Transfer Protocol (SFTP)
|
||||
|
||||
The protocol is not an Internet standard but it is still widely implemented.
|
||||
OpenSSH and most other implementation implement Version 3 of the protocol. We
|
||||
do the same in libssh.
|
||||
|
||||
- <a href="http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
|
||||
draft-ietf-secsh-filexfer-02.txt</a>,
|
||||
SSH File Transfer Protocol
|
||||
|
||||
@subsection main-rfc-extensions Secure Shell Extensions
|
||||
|
||||
The OpenSSH project has defined some extensions to the protocol. We support some of
|
||||
them like the statvfs calls in SFTP or the ssh-agent.
|
||||
|
||||
- <a href="http://api.libssh.org/rfc/PROTOCOL" target="_blank">
|
||||
OpenSSH's deviations and extensions</a>
|
||||
- <a href="http://api.libssh.org/rfc/PROTOCOL.agent" target="_blank">
|
||||
OpenSSH's ssh-agent</a>
|
||||
- <a href="http://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
|
||||
OpenSSH's pubkey certificate authentication</a>
|
||||
|
||||
*/
|
268
libssh/doc/scp.dox
Normal file
268
libssh/doc/scp.dox
Normal file
@ -0,0 +1,268 @@
|
||||
/**
|
||||
@page libssh_tutor_scp Chapter 6: The SCP subsystem
|
||||
@section scp_subsystem The SCP subsystem
|
||||
|
||||
The SCP subsystem has far less functionnality than the SFTP subsystem.
|
||||
However, if you only need to copy files from and to the remote system,
|
||||
it does its job.
|
||||
|
||||
|
||||
@subsection scp_session Opening and closing a SCP session
|
||||
|
||||
Like in the SFTP subsystem, you don't handle the SSH channels directly.
|
||||
Instead, you open a "SCP session".
|
||||
|
||||
When you open your SCP session, you have to choose between read or write mode.
|
||||
You can't do both in the same session. So you specify either SSH_SCP_READ or
|
||||
SSH_SCP_WRITE as the second parameter of function ssh_scp_new().
|
||||
|
||||
Another important mode flag for opening your SCP session is SSH_SCP_RECURSIVE.
|
||||
When you use SSH_SCP_RECURSIVE, you declare that you are willing to emulate
|
||||
the behaviour of "scp -r" command in your program, no matter it is for
|
||||
reading or for writing.
|
||||
|
||||
Once your session is created, you initialize it with ssh_scp_init(). When
|
||||
you have finished transferring files, you terminate the SCP connection with
|
||||
ssh_scp_close(). Finally, you can dispose the SCP connection with
|
||||
ssh_scp_free().
|
||||
|
||||
The example below does the maintenance work to open a SCP connection for writing in
|
||||
recursive mode:
|
||||
|
||||
@code
|
||||
int scp_write(ssh_session session)
|
||||
{
|
||||
ssh_scp scp;
|
||||
int rc;
|
||||
|
||||
scp = ssh_scp_new
|
||||
(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
|
||||
if (scp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error allocating scp session: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_scp_init(scp);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error initializing scp session: %s\n",
|
||||
ssh_get_error(session));
|
||||
ssh_scp_free(scp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
ssh_scp_close(scp);
|
||||
ssh_scp_free(scp);
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
The example below shows how to open a connection to read a single file:
|
||||
|
||||
@code
|
||||
int scp_read(ssh_session session)
|
||||
{
|
||||
ssh_scp scp;
|
||||
int rc;
|
||||
|
||||
scp = ssh_scp_new
|
||||
(session, SSH_SCP_READ, "helloworld/helloworld.txt");
|
||||
if (scp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error allocating scp session: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_scp_init(scp);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error initializing scp session: %s\n",
|
||||
ssh_get_error(session));
|
||||
ssh_scp_free(scp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
ssh_scp_close(scp);
|
||||
ssh_scp_free(scp);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection scp_write Creating files and directories
|
||||
|
||||
You create directories with ssh_scp_push_directory(). In recursive mode,
|
||||
you are placed in this directory once it is created. If the directory
|
||||
already exists and if you are in recursive mode, you simply enter that
|
||||
directory.
|
||||
|
||||
Creating files is done in two steps. First, you prepare the writing with
|
||||
ssh_scp_push_file(). Then, you write the data with ssh_scp_write().
|
||||
The length of the data to write must be identical between both function calls.
|
||||
There's no need to "open" nor "close" the file, this is done automatically
|
||||
on the remote end. If the file already exists, it is overwritten and truncated.
|
||||
|
||||
The following example creates a new directory named "helloworld/", then creates
|
||||
a file named "helloworld.txt" in that directory:
|
||||
|
||||
@code
|
||||
int scp_helloworld(ssh_session session, ssh_scp scp)
|
||||
{
|
||||
int rc;
|
||||
const char *helloworld = "Hello, world!\n";
|
||||
int length = strlen(helloworld);
|
||||
|
||||
rc = ssh_scp_push_directory(scp, "helloworld", S_IRWXU);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't create remote directory: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_scp_push_file
|
||||
(scp, "helloworld.txt", length, S_IRUSR | S_IWUSR);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't open remote file: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_scp_write(scp, helloworld, length);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't write to remote file: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection scp_recursive_write Copying full directory trees to the remote server
|
||||
|
||||
Let's say you want to copy the following tree of files to the remote site:
|
||||
|
||||
@verbatim
|
||||
+-- file1
|
||||
+-- B --+
|
||||
| +-- file2
|
||||
-- A --+
|
||||
| +-- file3
|
||||
+-- C --+
|
||||
+-- file4
|
||||
@endverbatim
|
||||
|
||||
You would do it that way:
|
||||
- open the session in recursive mode
|
||||
- enter directory A
|
||||
- enter its subdirectory B
|
||||
- create file1 in B
|
||||
- create file2 in B
|
||||
- leave directory B
|
||||
- enter subdirectory C
|
||||
- create file3 in C
|
||||
- create file4 in C
|
||||
- leave directory C
|
||||
- leave directory A
|
||||
|
||||
To leave a directory, call ssh_scp_leave_directory().
|
||||
|
||||
|
||||
@subsection scp_read Reading files and directories
|
||||
|
||||
|
||||
To receive files, you pull requests from the other side with ssh_scp_pull_request().
|
||||
If this function returns SSH_SCP_REQUEST_NEWFILE, then you must get ready for
|
||||
the reception. You can get the size of the data to receive with ssh_scp_request_get_size()
|
||||
and allocate a buffer accordingly. When you are ready, you accept the request with
|
||||
ssh_scp_accept_request(), then read the data with ssh_scp_read().
|
||||
|
||||
The following example receives a single file. The name of the file to
|
||||
receive has been given earlier, when the scp session was opened:
|
||||
|
||||
@code
|
||||
int scp_receive(ssh_session session, ssh_scp scp)
|
||||
{
|
||||
int rc;
|
||||
int size, mode;
|
||||
char *filename, *buffer;
|
||||
|
||||
rc = ssh_scp_pull_request(scp);
|
||||
if (rc != SSH_SCP_REQUEST_NEWFILE)
|
||||
{
|
||||
fprintf(stderr, "Error receiving information about file: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
size = ssh_scp_request_get_size(scp);
|
||||
filename = strdup(ssh_scp_request_get_filename(scp));
|
||||
mode = ssh_scp_request_get_permissions(scp);
|
||||
printf("Receiving file %s, size %d, permisssions 0%o\n",
|
||||
filename, size, mode);
|
||||
free(filename);
|
||||
|
||||
buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation error\n");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
ssh_scp_accept_request(scp);
|
||||
rc = ssh_scp_read(scp, buffer, size);
|
||||
if (rc == SSH_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Error receiving file data: %s\n",
|
||||
ssh_get_error(session));
|
||||
free(buffer);
|
||||
return rc;
|
||||
}
|
||||
printf("Done\n");
|
||||
|
||||
write(1, buffer, size);
|
||||
free(buffer);
|
||||
|
||||
rc = ssh_scp_pull_request(scp);
|
||||
if (rc != SSH_SCP_REQUEST_EOF)
|
||||
{
|
||||
fprintf(stderr, "Unexpected request: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
In this example, since we just requested a single file, we expect ssh_scp_request()
|
||||
to return SSH_SCP_REQUEST_NEWFILE first, then SSH_SCP_REQUEST_EOF. That's quite a
|
||||
naive approach; for example, the remote server might send a warning as well
|
||||
(return code SSH_SCP_REQUEST_WARNING) and the example would fail. A more comprehensive
|
||||
reception program would receive the requests in a loop and analyze them carefully
|
||||
until SSH_SCP_REQUEST_EOF has been received.
|
||||
|
||||
|
||||
@subsection scp_recursive_read Receiving full directory trees from the remote server
|
||||
|
||||
If you opened the SCP session in recursive mode, the remote end will be
|
||||
telling you when to change directory.
|
||||
|
||||
In that case, when ssh_scp_pull_request() answers
|
||||
SSH_SCP_REQUEST_NEWDIRECTORY, you should make that local directory (if
|
||||
it does not exist yet) and enter it. When ssh_scp_pull_request() answers
|
||||
SSH_SCP_REQUEST_ENDDIRECTORY, you should leave the current directory.
|
||||
|
||||
*/
|
415
libssh/doc/sftp.dox
Normal file
415
libssh/doc/sftp.dox
Normal file
@ -0,0 +1,415 @@
|
||||
/**
|
||||
@page libssh_tutor_sftp Chapter 5: The SFTP subsystem
|
||||
@section sftp_subsystem The SFTP subsystem
|
||||
|
||||
SFTP stands for "Secure File Transfer Protocol". It enables you to safely
|
||||
transfer files between the local and the remote computer. It reminds a lot
|
||||
of the old FTP protocol.
|
||||
|
||||
SFTP is a rich protocol. It lets you do over the network almost everything
|
||||
that you can do with local files:
|
||||
- send files
|
||||
- modify only a portion of a file
|
||||
- receive files
|
||||
- receive only a portion of a file
|
||||
- get file owner and group
|
||||
- get file permissions
|
||||
- set file owner and group
|
||||
- set file permissions
|
||||
- remove files
|
||||
- rename files
|
||||
- create a directory
|
||||
- remove a directory
|
||||
- retrieve the list of files in a directory
|
||||
- get the target of a symbolic link
|
||||
- create symbolic links
|
||||
- get information about mounted filesystems.
|
||||
|
||||
The current implemented version of the SFTP protocol is version 3. All functions
|
||||
aren't implemented yet, but the most important are.
|
||||
|
||||
|
||||
@subsection sftp_session Opening and closing a SFTP session
|
||||
|
||||
Unlike with remote shells and remote commands, when you use the SFTP subsystem,
|
||||
you don't handle directly the SSH channels. Instead, you open a "SFTP session".
|
||||
|
||||
The function sftp_new() creates a new SFTP session. The function sftp_init()
|
||||
initializes it. The function sftp_free() deletes it.
|
||||
|
||||
As you see, all the SFTP-related functions start with the "sftp_" prefix
|
||||
instead of the usual "ssh_" prefix.
|
||||
|
||||
The example below shows how to use these functions:
|
||||
|
||||
@code
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
int sftp_helloworld(ssh_session session)
|
||||
{
|
||||
sftp_session sftp;
|
||||
int rc;
|
||||
|
||||
sftp = sftp_new(session);
|
||||
if (sftp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error allocating SFTP session: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = sftp_init(sftp);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error initializing SFTP session: %s.\n",
|
||||
sftp_get_error(sftp));
|
||||
sftp_free(sftp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
sftp_free(sftp);
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection sftp_errors Analyzing SFTP errors
|
||||
|
||||
In case of a problem, the function sftp_get_error() returns a SFTP-specific
|
||||
error number, in addition to the regular SSH error number returned by
|
||||
ssh_get_error_number().
|
||||
|
||||
Possible errors are:
|
||||
- SSH_FX_OK: no error
|
||||
- SSH_FX_EOF: end-of-file encountered
|
||||
- SSH_FX_NO_SUCH_FILE: file does not exist
|
||||
- SSH_FX_PERMISSION_DENIED: permission denied
|
||||
- SSH_FX_FAILURE: generic failure
|
||||
- SSH_FX_BAD_MESSAGE: garbage received from server
|
||||
- SSH_FX_NO_CONNECTION: no connection has been set up
|
||||
- SSH_FX_CONNECTION_LOST: there was a connection, but we lost it
|
||||
- SSH_FX_OP_UNSUPPORTED: operation not supported by libssh yet
|
||||
- SSH_FX_INVALID_HANDLE: invalid file handle
|
||||
- SSH_FX_NO_SUCH_PATH: no such file or directory path exists
|
||||
- SSH_FX_FILE_ALREADY_EXISTS: an attempt to create an already existing file or directory has been made
|
||||
- SSH_FX_WRITE_PROTECT: write-protected filesystem
|
||||
- SSH_FX_NO_MEDIA: no media was in remote drive
|
||||
|
||||
|
||||
@subsection sftp_mkdir Creating a directory
|
||||
|
||||
The function sftp_mkdir() tahes the "SFTP session" we juste created as
|
||||
its first argument. It also needs the name of the file to create, and the
|
||||
desired permissions. The permissions are the same as for the usual mkdir()
|
||||
function. To get a comprehensive list of the available permissions, use the
|
||||
"man 2 stat" command. The desired permissions are combined with the remote
|
||||
user's mask to determine the effective permissions.
|
||||
|
||||
The code below creates a directory named "helloworld" in the current directory that
|
||||
can be read and written only by its owner:
|
||||
|
||||
@code
|
||||
#include <libssh/sftp.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int sftp_helloworld(ssh_session session, sftp_session sftp)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = sftp_mkdir(sftp, "helloworld", S_IRWXU);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
if (sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS)
|
||||
{
|
||||
fprintf(stderr, "Can't create directory: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Unlike its equivalent in the SCP subsystem, this function does NOT change the
|
||||
current directory to the newly created subdirectory.
|
||||
|
||||
|
||||
@subsection sftp_write Copying a file to the remote computer
|
||||
|
||||
You handle the contents of a remote file just like you would do with a
|
||||
local file: you open the file in a given mode, move the file pointer in it,
|
||||
read or write data, and close the file.
|
||||
|
||||
The sftp_open() function is very similar to the regular open() function,
|
||||
excepted that it returns a file handle of type sftp_file. This file handle
|
||||
is then used by the other file manipulation functions and remains valid
|
||||
until you close the remote file with sftp_close().
|
||||
|
||||
The example below creates a new file named "helloworld.txt" in the
|
||||
newly created "helloworld" directory. If the file already exists, it will
|
||||
be truncated. It then writes the famous "Hello, World!" sentence to the
|
||||
file, followed by a new line character. Finally, the file is closed:
|
||||
|
||||
@code
|
||||
#include <libssh/sftp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int sftp_helloworld(ssh_session session, sftp_session sftp)
|
||||
{
|
||||
int access_type = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
sftp_file file;
|
||||
const char *helloworld = "Hello, World!\n";
|
||||
int length = strlen(helloworld);
|
||||
int rc, nwritten;
|
||||
|
||||
...
|
||||
|
||||
file = sftp_open(sftp, "helloworld/helloworld.txt",
|
||||
access_type, S_IRWXU);
|
||||
if (file == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't open file for writing: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
nwritten = sftp_write(file, helloworld, length);
|
||||
if (nwritten != length)
|
||||
{
|
||||
fprintf(stderr, "Can't write data to file: %s\n",
|
||||
ssh_get_error(session));
|
||||
sftp_close(file);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = sftp_close(file);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't close the written file: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection sftp_read Reading a file from the remote computer
|
||||
|
||||
The nice thing with reading a file over the network through SFTP is that it
|
||||
can be done both in a synchronous way or an asynchronous way. If you read the file
|
||||
asynchronously, your program can do something else while it waits for the
|
||||
results to come.
|
||||
|
||||
Synchronous read is done with sftp_read().
|
||||
|
||||
The following example prints the contents of remote file "/etc/profile". For
|
||||
each 1024 bytes of information read, it waits until the end of the read operation:
|
||||
|
||||
@code
|
||||
int sftp_read_sync(ssh_session session, sftp_session sftp)
|
||||
{
|
||||
int access_type;
|
||||
sftp_file file;
|
||||
char buffer[1024];
|
||||
int nbytes, rc;
|
||||
|
||||
access_type = O_RDONLY;
|
||||
file = sftp_open(sftp, "/etc/profile",
|
||||
access_type, 0);
|
||||
if (file == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't open file for reading: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
||||
while (nbytes > 0)
|
||||
{
|
||||
if (write(1, buffer, nbytes) != nbytes)
|
||||
{
|
||||
sftp_close(file);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
fprintf(stderr, "Error while reading file: %s\n",
|
||||
ssh_get_error(session));
|
||||
sftp_close(file);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = sftp_close(file);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't close the read file: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Asynchronous read is done in two steps, first sftp_async_read_begin(), which
|
||||
returns a "request handle", and then sftp_async_read(), which uses that request handle.
|
||||
If the file has been opened in nonblocking mode, then sftp_async_read()
|
||||
might return SSH_AGAIN, which means that the request hasn't completed yet
|
||||
and that the function should be called again later on. Otherwise,
|
||||
sftp_async_read() waits for the data to come. To open a file in nonblocking mode,
|
||||
call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode.
|
||||
|
||||
The example below reads a very big file in asynchronous, nonblocking, mode. Each
|
||||
time the data are not ready yet, a counter is incrementer.
|
||||
|
||||
@code
|
||||
int sftp_read_async(ssh_session session, sftp_session sftp)
|
||||
{
|
||||
int access_type;
|
||||
sftp_file file;
|
||||
char buffer[1024];
|
||||
int async_request;
|
||||
int nbytes;
|
||||
long counter;
|
||||
int rc;
|
||||
|
||||
access_type = O_RDONLY;
|
||||
file = sftp_open(sftp, "some_very_big_file",
|
||||
access_type, 0);
|
||||
if (file == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't open file for reading: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
sftp_file_set_nonblocking(file);
|
||||
|
||||
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
||||
counter = 0L;
|
||||
usleep(10000);
|
||||
if (async_request >= 0)
|
||||
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
|
||||
async_request);
|
||||
else nbytes = -1;
|
||||
while (nbytes > 0 || nbytes == SSH_AGAIN)
|
||||
{
|
||||
if (nbytes > 0)
|
||||
{
|
||||
write(1, buffer, nbytes);
|
||||
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
||||
}
|
||||
else counter++;
|
||||
usleep(10000);
|
||||
if (async_request >= 0)
|
||||
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
|
||||
async_request);
|
||||
else nbytes = -1;
|
||||
}
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
fprintf(stderr, "Error while reading file: %s\n",
|
||||
ssh_get_error(session));
|
||||
sftp_close(file);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
printf("The counter has reached value: %ld\n", counter);
|
||||
|
||||
rc = sftp_close(file);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't close the read file: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@subsection sftp_ls Listing the contents of a directory
|
||||
|
||||
The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(),
|
||||
and sftp_closedir() enable to list the contents of a directory.
|
||||
They use a new handle_type, "sftp_dir", which gives access to the
|
||||
directory being read.
|
||||
|
||||
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
|
||||
to a structure with informations about a directory entry:
|
||||
- name: the name of the file or directory
|
||||
- size: its size in bytes
|
||||
- etc.
|
||||
|
||||
sftp_readdir() might return NULL under two conditions:
|
||||
- when the end of the directory has been met
|
||||
- when an error occured
|
||||
|
||||
To tell the difference, call sftp_dir_eof().
|
||||
|
||||
The attributes must be freed with sftp_attributes_free() when no longer
|
||||
needed.
|
||||
|
||||
The following example reads the contents of some remote directory:
|
||||
|
||||
@code
|
||||
int sftp_list_dir(ssh_session session, sftp_session sftp)
|
||||
{
|
||||
sftp_dir dir;
|
||||
sftp_attributes attributes;
|
||||
int rc;
|
||||
|
||||
dir = sftp_opendir(sftp, "/var/log");
|
||||
if (!dir)
|
||||
{
|
||||
fprintf(stderr, "Directory not opened: %s\n",
|
||||
ssh_get_error(session));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
printf("Name Size Perms Owner\tGroup\n");
|
||||
|
||||
while ((attributes = sftp_readdir(sftp, dir)) != NULL)
|
||||
{
|
||||
printf("%-20s %10llu %.8o %s(%d)\t%s(%d)\n",
|
||||
attributes->name,
|
||||
(long long unsigned int) attributes->size,
|
||||
attributes->permissions,
|
||||
attributes->owner,
|
||||
attributes->uid,
|
||||
attributes->group,
|
||||
attributes->gid);
|
||||
|
||||
sftp_attributes_free(attributes);
|
||||
}
|
||||
|
||||
if (!sftp_dir_eof(dir))
|
||||
{
|
||||
fprintf(stderr, "Can't list directory: %s\n",
|
||||
ssh_get_error(session));
|
||||
sftp_closedir(dir);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = sftp_closedir(dir);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Can't close directory: %s\n",
|
||||
ssh_get_error(session));
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
361
libssh/doc/shell.dox
Normal file
361
libssh/doc/shell.dox
Normal file
@ -0,0 +1,361 @@
|
||||
/**
|
||||
@page libssh_tutor_shell Chapter 3: Opening a remote shell
|
||||
@section opening_shell Opening a remote shell
|
||||
|
||||
We already mentioned that a single SSH connection can be shared
|
||||
between several "channels". Channels can be used for different purposes.
|
||||
|
||||
This chapter shows how to open one of these channels, and how to use it to
|
||||
start a command interpreter on a remote computer.
|
||||
|
||||
|
||||
@subsection open_channel Opening and closing a channel
|
||||
|
||||
The ssh_channel_new() function creates a channel. It returns the channel as
|
||||
a variable of type ssh_channel.
|
||||
|
||||
Once you have this channel, you open a SSH session that uses it with
|
||||
ssh_channel_open_session().
|
||||
|
||||
Once you don't need the channel anymore, you can send an end-of-file
|
||||
to it with ssh_channel_close(). At this point, you can destroy the channel
|
||||
with ssh_channel_free().
|
||||
|
||||
The code sample below achieves these tasks:
|
||||
|
||||
@code
|
||||
int shell_session(ssh_session session)
|
||||
{
|
||||
ssh_channel channel;
|
||||
int rc;
|
||||
|
||||
channel = ssh_channel_new(session);
|
||||
if (channel == NULL)
|
||||
return SSH_ERROR;
|
||||
|
||||
rc = ssh_channel_open_session(channel);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
ssh_channel_free(channel);
|
||||
return rc;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_free(channel);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection interactive Interactive and non-interactive sessions
|
||||
|
||||
A "shell" is a command interpreter. It is said to be "interactive"
|
||||
if there is a human user typing the commands, one after the
|
||||
other. The contrary, a non-interactive shell, is similar to
|
||||
the execution of commands in the background: there is no attached
|
||||
terminal.
|
||||
|
||||
If you plan using an interactive shell, you need to create a
|
||||
pseud-terminal on the remote side. A remote terminal is usually referred
|
||||
to as a "pty", for "pseudo-teletype". The remote processes won't see the
|
||||
difference with a real text-oriented terminal.
|
||||
|
||||
If needed, you request the pty with the function ssh_channel_request_pty().
|
||||
Then you define its dimensions (number of rows and columns)
|
||||
with ssh_channel_change_pty_size().
|
||||
|
||||
Be your session interactive or not, the next step is to request a
|
||||
shell with ssh_channel_request_shell().
|
||||
|
||||
@code
|
||||
int interactive_shell_session(ssh_channel channel)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_channel_request_pty(channel);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_change_pty_size(channel, 80, 24);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_request_shell(channel);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
...
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection read_data Displaying the data sent by the remote computer
|
||||
|
||||
In your program, you will usually need to receive all the data "displayed"
|
||||
into the remote pty. You will usually analyse, log, or display this data.
|
||||
|
||||
ssh_channel_read() and ssh_channel_read_nonblocking() are the simplest
|
||||
way to read data from a channel. If you only need to read from a single
|
||||
channel, they should be enough.
|
||||
|
||||
The example below shows how to wait for remote data using ssh_channel_read():
|
||||
|
||||
@code
|
||||
int interactive_shell_session(ssh_channel channel)
|
||||
{
|
||||
int rc;
|
||||
char buffer[256];
|
||||
int nbytes;
|
||||
|
||||
rc = ssh_channel_request_pty(channel);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_change_pty_size(channel, 80, 24);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_request_shell(channel);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
while (ssh_channel_is_open(channel) &&
|
||||
!ssh_channel_is_eof(channel))
|
||||
{
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
if (nbytes < 0)
|
||||
return SSH_ERROR;
|
||||
|
||||
if (nbytes > 0)
|
||||
write(1, buffer, nbytes);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Unlike ssh_channel_read(), ssh_channel_read_nonblocking() never waits for
|
||||
remote data to be ready. It returns immediately.
|
||||
|
||||
If you plan to use ssh_channel_read_nonblocking() repeatedly in a loop,
|
||||
you should use a "passive wait" function like usleep(3) in the same
|
||||
loop. Otherwise, your program will consume all the CPU time, and your
|
||||
computer might become unresponsive.
|
||||
|
||||
|
||||
@subsection write_data Sending user input to the remote computer
|
||||
|
||||
User's input is sent to the remote site with ssh_channel_write().
|
||||
|
||||
The following example shows how to combine a nonblocking read from a SSH
|
||||
channel with a nonblocking read from the keyboard. The local input is then
|
||||
sent to the remote computer:
|
||||
|
||||
@code
|
||||
/* Under Linux, this function determines whether a key has been pressed.
|
||||
Under Windows, it is a standard function, so you need not redefine it.
|
||||
*/
|
||||
int kbhit()
|
||||
{
|
||||
struct timeval tv = { 0L, 0L };
|
||||
fd_set fds;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
|
||||
return select(1, &fds, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
/* A very simple terminal emulator:
|
||||
- print data received from the remote computer
|
||||
- send keyboard input to the remote computer
|
||||
*/
|
||||
int interactive_shell_session(ssh_channel channel)
|
||||
{
|
||||
/* Session and terminal initialization skipped */
|
||||
...
|
||||
|
||||
char buffer[256];
|
||||
int nbytes, nwritten;
|
||||
|
||||
while (ssh_channel_is_open(channel) &&
|
||||
!ssh_channel_is_eof(channel))
|
||||
{
|
||||
nbytes = ssh_channel_read_nonblocking(channel, buffer, sizeof(buffer), 0);
|
||||
if (nbytes < 0) return SSH_ERROR;
|
||||
if (nbytes > 0)
|
||||
{
|
||||
nwritten = write(1, buffer, nbytes);
|
||||
if (nwritten != nbytes) return SSH_ERROR;
|
||||
|
||||
if (!kbhit())
|
||||
{
|
||||
usleep(50000L); // 0.05 second
|
||||
continue;
|
||||
}
|
||||
|
||||
nbytes = read(0, buffer, sizeof(buffer));
|
||||
if (nbytes < 0) return SSH_ERROR;
|
||||
if (nbytes > 0)
|
||||
{
|
||||
nwritten = ssh_channel_write(channel, buffer, nbytes);
|
||||
if (nwritten != nbytes) return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Of course, this is a poor terminal emulator, since the echo from the keys
|
||||
pressed should not be done locally, but should be done by the remote side.
|
||||
Also, user's input should not be sent once "Enter" key is pressed, but
|
||||
immediately after each key is pressed. This can be accomplished
|
||||
by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
|
||||
cfmakeraw() is a standard function under Linux, on other systems you can
|
||||
recode it with:
|
||||
|
||||
@code
|
||||
static void cfmakeraw(struct termios *termios_p)
|
||||
{
|
||||
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||
termios_p->c_oflag &= ~OPOST;
|
||||
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
termios_p->c_cflag &= ~(CSIZE|PARENB);
|
||||
termios_p->c_cflag |= CS8;
|
||||
}
|
||||
@endcode
|
||||
|
||||
If you are not using a local terminal, but some kind of graphical
|
||||
environment, the solution to this kind of "echo" problems will be different.
|
||||
|
||||
|
||||
@subsection select_loop A more elaborate way to get the remote data
|
||||
|
||||
*** Warning: ssh_select() and ssh_channel_select() are not relevant anymore,
|
||||
since libssh is about to provide an easier system for asynchronous
|
||||
communications. This subsection should be removed then. ***
|
||||
|
||||
ssh_channel_read() and ssh_channel_read_nonblocking() functions are simple,
|
||||
but they are not adapted when you expect data from more than one SSH channel,
|
||||
or from other file descriptors. Last example showed how getting data from
|
||||
the standard input (the keyboard) at the same time as data from the SSH
|
||||
channel was complicated. The functions ssh_select() and ssh_channel_select()
|
||||
provide a more elegant way to wait for data coming from many sources.
|
||||
|
||||
The functions ssh_select() and ssh_channel_select() remind of the standard
|
||||
UNIX select(2) function. The idea is to wait for "something" to happen:
|
||||
incoming data to be read, outcoming data to block, or an exception to
|
||||
occur. Both these functions do a "passive wait", i.e. you can safely use
|
||||
them repeatedly in a loop, it will not consume exaggerate processor time
|
||||
and make your computer unresponsive. It is quite common to use these
|
||||
functions in your application's main loop.
|
||||
|
||||
The difference between ssh_select() and ssh_channel_select() is that
|
||||
ssh_channel_select() is simpler, but allows you only to watch SSH channels.
|
||||
ssh_select() is more complete and enables watching regular file descriptors
|
||||
as well, in the same function call.
|
||||
|
||||
Below is an example of a function that waits both for remote SSH data to come,
|
||||
as well as standard input from the keyboard:
|
||||
|
||||
@code
|
||||
int interactive_shell_session(ssh_session session, ssh_channel channel)
|
||||
{
|
||||
/* Session and terminal initialization skipped */
|
||||
...
|
||||
|
||||
char buffer[256];
|
||||
int nbytes, nwritten;
|
||||
|
||||
while (ssh_channel_is_open(channel) &&
|
||||
!ssh_channel_is_eof(channel))
|
||||
{
|
||||
struct timeval timeout;
|
||||
ssh_channel in_channels[2], out_channels[2];
|
||||
fd_set fds;
|
||||
int maxfd;
|
||||
|
||||
timeout.tv_sec = 30;
|
||||
timeout.tv_usec = 0;
|
||||
in_channels[0] = channel;
|
||||
in_channels[1] = NULL;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
FD_SET(ssh_get_fd(session), &fds);
|
||||
maxfd = ssh_get_fd(session) + 1;
|
||||
|
||||
ssh_select(in_channels, out_channels, maxfd, &fds, &timeout);
|
||||
|
||||
if (out_channels[0] != NULL)
|
||||
{
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
if (nbytes < 0) return SSH_ERROR;
|
||||
if (nbytes > 0)
|
||||
{
|
||||
nwritten = write(1, buffer, nbytes);
|
||||
if (nwritten != nbytes) return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(0, &fds))
|
||||
{
|
||||
nbytes = read(0, buffer, sizeof(buffer));
|
||||
if (nbytes < 0) return SSH_ERROR;
|
||||
if (nbytes > 0)
|
||||
{
|
||||
nwritten = ssh_channel_write(channel, buffer, nbytes);
|
||||
if (nbytes != nwritten) return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection x11 Using graphical applications on the remote side
|
||||
|
||||
If your remote application is graphical, you can forward the X11 protocol to
|
||||
your local computer.
|
||||
|
||||
To do that, you first declare that you accept X11 connections with
|
||||
ssh_channel_accept_x11(). Then you create the forwarding tunnel for
|
||||
the X11 protocol with ssh_channel_request_x11().
|
||||
|
||||
The following code performs channel initialization and shell session
|
||||
opening, and handles a parallel X11 connection:
|
||||
|
||||
@code
|
||||
int interactive_shell_session(ssh_channel channel)
|
||||
{
|
||||
int rc;
|
||||
ssh_channel x11channel;
|
||||
|
||||
rc = ssh_channel_request_pty(channel);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_change_pty_size(channel, 80, 24);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_request_x11(channel, 0, NULL, NULL, 0);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
rc = ssh_channel_request_shell(channel);
|
||||
if (rc != SSH_OK) return rc;
|
||||
|
||||
/* Read the data sent by the remote computer here */
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
Don't forget to set the $DISPLAY environment variable on the remote
|
||||
side, or the remote applications won't try using the X11 tunnel:
|
||||
|
||||
@code
|
||||
$ export DISPLAY=:0
|
||||
$ xclock &
|
||||
@endcode
|
||||
|
||||
*/
|
14
libssh/doc/tbd.dox
Normal file
14
libssh/doc/tbd.dox
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
@page libssh_tutor_todo To be done
|
||||
|
||||
*** To be written ***
|
||||
|
||||
@section sshd Writing a libssh-based server
|
||||
|
||||
*** To be written ***
|
||||
|
||||
@section cpp The libssh C++ wrapper
|
||||
|
||||
*** To be written ***
|
||||
|
||||
*/
|
65
libssh/doc/threading.dox
Normal file
65
libssh/doc/threading.dox
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
@page libssh_tutor_threads Chapter 8: Threads with libssh
|
||||
@section threads_with_libssh How to use libssh with threads
|
||||
|
||||
libssh may be used in multithreaded applications, but under several conditions :
|
||||
- Threading must be initialized during the initialization of libssh. This
|
||||
initialization must be done outside of any threading context.
|
||||
- If pthreads is being used by your application (or your framework's backend),
|
||||
you must link with libssh_threads dynamic library and initialize
|
||||
threading with the ssh_threads_pthreads threading object.
|
||||
- If an other threading library is being used by your application, you must
|
||||
implement all the methods of the ssh_threads_callbacks_struct structure
|
||||
and initialize libssh with it.
|
||||
- At all times, you may use different sessions inside threads, make parallel
|
||||
connections, read/write on different sessions and so on. You *cannot* use a
|
||||
single session (or channels for a single session) in several threads at the same
|
||||
time. This will most likely lead to internal state corruption. This limitation is
|
||||
being worked out and will maybe disappear later.
|
||||
|
||||
@subsection threads_init Initialization of threads
|
||||
|
||||
To initialize threading, you must first select the threading model you want to
|
||||
use, using ssh_threads_set_callbacks(), then call ssh_init().
|
||||
|
||||
@code
|
||||
#include <libssh/callbacks.h>
|
||||
...
|
||||
ssh_threads_set_callbacks(ssh_threads_get_noop());
|
||||
ssh_init();
|
||||
@endcode
|
||||
|
||||
ssh_threads_noop is the threading structure that does nothing. It's the
|
||||
threading callbacks being used by default when you're not using threading.
|
||||
|
||||
@subsection threads_pthread Using libpthread with libssh
|
||||
|
||||
If your application is using libpthread, you may simply use the libpthread
|
||||
threading backend:
|
||||
|
||||
@code
|
||||
#include <libssh/callbacks.h>
|
||||
...
|
||||
ssh_threads_set_callbacks(ssh_threads_get_pthread());
|
||||
ssh_init();
|
||||
@endcode
|
||||
|
||||
However, you must be sure to link with the library ssh_threads. If
|
||||
you're using gcc, you must use the commandline
|
||||
@code
|
||||
gcc -o output input.c -lssh -lssh_threads
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection threads_other Using another threading library
|
||||
|
||||
You must find your way in the ssh_threads_callbacks_struct structure. You must
|
||||
implement the following methods :
|
||||
- mutex_lock
|
||||
- mutex_unlock
|
||||
- mutex_init
|
||||
- mutex_destroy
|
||||
- thread_id
|
||||
|
||||
Good luck !
|
||||
*/
|
57
libssh/examples/CMakeLists.txt
Normal file
57
libssh/examples/CMakeLists.txt
Normal file
@ -0,0 +1,57 @@
|
||||
project(libssh-examples C CXX)
|
||||
|
||||
set(examples_SRCS
|
||||
authentication.c
|
||||
knownhosts.c
|
||||
connect_ssh.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
||||
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(scp_download scp_download.c ${examples_SRCS})
|
||||
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(samplessh sample.c ${examples_SRCS})
|
||||
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
||||
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
if (WITH_SFTP)
|
||||
add_executable(samplesftp samplesftp.c ${examples_SRCS})
|
||||
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
|
||||
endif (WITH_SFTP)
|
||||
|
||||
if (WITH_SERVER)
|
||||
add_executable(samplesshd samplesshd.c)
|
||||
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(samplesshd-kbdint samplesshd-kbdint.c)
|
||||
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
if (HAVE_LIBUTIL)
|
||||
add_executable(samplesshd-tty samplesshd-tty.c)
|
||||
target_link_libraries(samplesshd-tty ${LIBSSH_SHARED_LIBRARY} util)
|
||||
endif (HAVE_LIBUTIL)
|
||||
|
||||
endif (WITH_SERVER)
|
||||
endif (LINUX)
|
||||
|
||||
add_executable(exec exec.c ${examples_SRCS})
|
||||
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(senddata senddata.c ${examples_SRCS})
|
||||
target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(libsshpp libsshpp.cpp)
|
||||
target_link_libraries(libsshpp ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
|
||||
target_link_libraries(libsshpp_noexcept ${LIBSSH_SHARED_LIBRARY})
|
167
libssh/examples/authentication.c
Normal file
167
libssh/examples/authentication.c
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* authentication.c
|
||||
* This file contains an example of how to do an authentication to a
|
||||
* SSH server using libssh
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
|
||||
int authenticate_kbdint(ssh_session session, const char *password) {
|
||||
int err;
|
||||
|
||||
err = ssh_userauth_kbdint(session, NULL, NULL);
|
||||
while (err == SSH_AUTH_INFO) {
|
||||
const char *instruction;
|
||||
const char *name;
|
||||
char buffer[128];
|
||||
int i, n;
|
||||
|
||||
name = ssh_userauth_kbdint_getname(session);
|
||||
instruction = ssh_userauth_kbdint_getinstruction(session);
|
||||
n = ssh_userauth_kbdint_getnprompts(session);
|
||||
|
||||
if (name && strlen(name) > 0) {
|
||||
printf("%s\n", name);
|
||||
}
|
||||
|
||||
if (instruction && strlen(instruction) > 0) {
|
||||
printf("%s\n", instruction);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
const char *answer;
|
||||
const char *prompt;
|
||||
char echo;
|
||||
|
||||
prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
|
||||
if (prompt == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (echo) {
|
||||
char *p;
|
||||
|
||||
printf("%s", prompt);
|
||||
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
if ((p = strchr(buffer, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if (ssh_userauth_kbdint_setanswer(session, i, buffer) < 0) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
memset(buffer, 0, strlen(buffer));
|
||||
} else {
|
||||
if (password && strstr(prompt, "Password:")) {
|
||||
answer = password;
|
||||
} else {
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (ssh_getpass(prompt, buffer, sizeof(buffer), 0, 0) < 0) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
answer = buffer;
|
||||
}
|
||||
err = ssh_userauth_kbdint_setanswer(session, i, answer);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
if (err < 0) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
err=ssh_userauth_kbdint(session,NULL,NULL);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void error(ssh_session session){
|
||||
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
|
||||
}
|
||||
|
||||
int authenticate_console(ssh_session session){
|
||||
int rc;
|
||||
int method;
|
||||
char password[128] = {0};
|
||||
char *banner;
|
||||
|
||||
// Try to authenticate
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
error(session);
|
||||
return rc;
|
||||
}
|
||||
|
||||
method = ssh_auth_list(session);
|
||||
while (rc != SSH_AUTH_SUCCESS) {
|
||||
// Try to authenticate with public key first
|
||||
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
|
||||
rc = ssh_userauth_autopubkey(session, NULL);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
error(session);
|
||||
return rc;
|
||||
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to authenticate with keyboard interactive";
|
||||
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
|
||||
rc = authenticate_kbdint(session, NULL);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
error(session);
|
||||
return rc;
|
||||
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
// Try to authenticate with password
|
||||
if (method & SSH_AUTH_METHOD_PASSWORD) {
|
||||
rc = ssh_userauth_password(session, NULL, password);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
error(session);
|
||||
return rc;
|
||||
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
memset(password, 0, sizeof(password));
|
||||
}
|
||||
|
||||
banner = ssh_get_issue_banner(session);
|
||||
if (banner) {
|
||||
printf("%s\n",banner);
|
||||
ssh_string_free_char(banner);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
67
libssh/examples/connect_ssh.c
Normal file
67
libssh/examples/connect_ssh.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* connect_ssh.c
|
||||
* This file contains an example of how to connect to a
|
||||
* SSH server using libssh
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
ssh_session connect_ssh(const char *host, const char *user,int verbosity){
|
||||
ssh_session session;
|
||||
int auth=0;
|
||||
|
||||
session=ssh_new();
|
||||
if (session == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(user != NULL){
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
|
||||
ssh_free(session);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
|
||||
ssh_free(session);
|
||||
return NULL;
|
||||
}
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
if(ssh_connect(session)){
|
||||
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
return NULL;
|
||||
}
|
||||
if(verify_knownhost(session)<0){
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
return NULL;
|
||||
}
|
||||
auth=authenticate_console(session);
|
||||
if(auth==SSH_AUTH_SUCCESS){
|
||||
return session;
|
||||
} else if(auth==SSH_AUTH_DENIED){
|
||||
fprintf(stderr,"Authentication failed\n");
|
||||
} else {
|
||||
fprintf(stderr,"Error while authenticating : %s\n",ssh_get_error(session));
|
||||
}
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
return NULL;
|
||||
}
|
22
libssh/examples/examples_common.h
Normal file
22
libssh/examples/examples_common.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
#ifndef EXAMPLES_COMMON_H_
|
||||
#define EXAMPLES_COMMON_H_
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
int authenticate_console(ssh_session session);
|
||||
int authenticate_kbdint(ssh_session session, const char *password);
|
||||
int verify_knownhost(ssh_session session);
|
||||
ssh_session connect_ssh(const char *hostname, const char *user, int verbosity);
|
||||
|
||||
#endif /* EXAMPLES_COMMON_H_ */
|
66
libssh/examples/exec.c
Normal file
66
libssh/examples/exec.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* simple exec example */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
|
||||
int main(void) {
|
||||
ssh_session session;
|
||||
ssh_channel channel;
|
||||
char buffer[256];
|
||||
int nbytes;
|
||||
int rc;
|
||||
|
||||
session = connect_ssh("localhost", NULL, 0);
|
||||
if (session == NULL) {
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
channel = ssh_channel_new(session);;
|
||||
if (channel == NULL) {
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = ssh_channel_open_session(channel);
|
||||
if (rc < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = ssh_channel_request_exec(channel, "lsof");
|
||||
if (rc < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
while (nbytes > 0) {
|
||||
if (fwrite(buffer, 1, nbytes, stdout) != (unsigned int) nbytes) {
|
||||
goto failed;
|
||||
}
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
}
|
||||
|
||||
if (nbytes < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
ssh_finalize();
|
||||
|
||||
return 0;
|
||||
failed:
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
ssh_finalize();
|
||||
|
||||
return 1;
|
||||
}
|
98
libssh/examples/knownhosts.c
Normal file
98
libssh/examples/knownhosts.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* knownhosts.c
|
||||
* This file contains an example of how verify the identity of a
|
||||
* SSH server using libssh
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
int verify_knownhost(ssh_session session){
|
||||
char *hexa;
|
||||
int state;
|
||||
char buf[10];
|
||||
unsigned char *hash = NULL;
|
||||
int hlen;
|
||||
|
||||
state=ssh_is_server_known(session);
|
||||
|
||||
hlen = ssh_get_pubkey_hash(session, &hash);
|
||||
if (hlen < 0) {
|
||||
return -1;
|
||||
}
|
||||
switch(state){
|
||||
case SSH_SERVER_KNOWN_OK:
|
||||
break; /* ok */
|
||||
case SSH_SERVER_KNOWN_CHANGED:
|
||||
fprintf(stderr,"Host key for server changed : server's one is now :\n");
|
||||
ssh_print_hexa("Public key hash",hash, hlen);
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||
return -1;
|
||||
case SSH_SERVER_FOUND_OTHER:
|
||||
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
|
||||
fprintf(stderr,"An attacker might change the default server key to confuse your client"
|
||||
"into thinking the key does not exist\n"
|
||||
"We advise you to rerun the client with -d or -r for more safety.\n");
|
||||
return -1;
|
||||
case SSH_SERVER_FILE_NOT_FOUND:
|
||||
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
|
||||
fprintf(stderr,"the file will be automatically created.\n");
|
||||
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
hexa = ssh_get_hexa(hash, hlen);
|
||||
fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");
|
||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||
ssh_string_free_char(hexa);
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
if(strncasecmp(buf,"yes",3)!=0){
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
if(strncasecmp(buf,"yes",3)==0){
|
||||
if (ssh_write_knownhost(session) < 0) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr, "error %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case SSH_SERVER_ERROR:
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"%s",ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return 0;
|
||||
}
|
304
libssh/examples/libssh_scp.c
Normal file
304
libssh/examples/libssh_scp.c
Normal file
@ -0,0 +1,304 @@
|
||||
/* libssh_scp.c
|
||||
* Sample implementation of a SCP client
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
|
||||
static char **sources;
|
||||
static int nsources;
|
||||
static char *destination;
|
||||
static int verbosity=0;
|
||||
|
||||
struct location {
|
||||
int is_ssh;
|
||||
char *user;
|
||||
char *host;
|
||||
char *path;
|
||||
ssh_session session;
|
||||
ssh_scp scp;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
enum {
|
||||
READ,
|
||||
WRITE
|
||||
};
|
||||
|
||||
static void usage(const char *argv0){
|
||||
fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n"
|
||||
" [[user@]host2:]destination\n"
|
||||
"sample scp client - libssh-%s\n",
|
||||
// "Options :\n",
|
||||
// " -r : use RSA to verify host public key\n",
|
||||
argv0,
|
||||
ssh_version(0));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
while((i=getopt(argc,argv,"v"))!=-1){
|
||||
switch(i){
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"unknown option %c\n",optopt);
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
nsources=argc-optind-1;
|
||||
if(nsources < 1){
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
sources=malloc((nsources + 1) * sizeof(char *));
|
||||
if(sources == NULL)
|
||||
return -1;
|
||||
for(i=0;i<nsources;++i){
|
||||
sources[i] = argv[optind];
|
||||
optind++;
|
||||
}
|
||||
sources[i]=NULL;
|
||||
destination=argv[optind];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct location *parse_location(char *loc){
|
||||
struct location *location=malloc(sizeof(struct location));
|
||||
char *ptr;
|
||||
|
||||
location->host=location->user=NULL;
|
||||
ptr=strchr(loc,':');
|
||||
if(ptr != NULL){
|
||||
location->is_ssh=1;
|
||||
location->path=strdup(ptr+1);
|
||||
*ptr='\0';
|
||||
ptr=strchr(loc,'@');
|
||||
if(ptr != NULL){
|
||||
location->host=strdup(ptr+1);
|
||||
*ptr='\0';
|
||||
location->user=strdup(loc);
|
||||
} else {
|
||||
location->host=strdup(loc);
|
||||
}
|
||||
} else {
|
||||
location->is_ssh=0;
|
||||
location->path=strdup(loc);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
static int open_location(struct location *loc, int flag){
|
||||
if(loc->is_ssh && flag==WRITE){
|
||||
loc->session=connect_ssh(loc->host,loc->user,verbosity);
|
||||
if(!loc->session){
|
||||
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
|
||||
return -1;
|
||||
}
|
||||
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path);
|
||||
if(!loc->scp){
|
||||
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||
return -1;
|
||||
}
|
||||
if(ssh_scp_init(loc->scp)==SSH_ERROR){
|
||||
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||
ssh_scp_free(loc->scp);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if(loc->is_ssh && flag==READ){
|
||||
loc->session=connect_ssh(loc->host, loc->user,verbosity);
|
||||
if(!loc->session){
|
||||
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
|
||||
return -1;
|
||||
}
|
||||
loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path);
|
||||
if(!loc->scp){
|
||||
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||
return -1;
|
||||
}
|
||||
if(ssh_scp_init(loc->scp)==SSH_ERROR){
|
||||
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||
ssh_scp_free(loc->scp);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
loc->file=fopen(loc->path,flag==READ ? "r":"w");
|
||||
if(!loc->file){
|
||||
if(errno==EISDIR){
|
||||
if(chdir(loc->path)){
|
||||
fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @brief copies files from source location to destination
|
||||
* @param src source location
|
||||
* @param dest destination location
|
||||
* @param recursive Copy also directories
|
||||
*/
|
||||
static int do_copy(struct location *src, struct location *dest, int recursive){
|
||||
int size;
|
||||
socket_t fd;
|
||||
struct stat s;
|
||||
int w,r;
|
||||
char buffer[16384];
|
||||
int total=0;
|
||||
int mode;
|
||||
char *filename;
|
||||
/* recursive mode doesn't work yet */
|
||||
(void)recursive;
|
||||
/* Get the file name and size*/
|
||||
if(!src->is_ssh){
|
||||
fd=fileno(src->file);
|
||||
fstat(fd,&s);
|
||||
size=s.st_size;
|
||||
mode = s.st_mode & ~S_IFMT;
|
||||
filename=ssh_basename(src->path);
|
||||
} else {
|
||||
size=0;
|
||||
do {
|
||||
r=ssh_scp_pull_request(src->scp);
|
||||
if(r==SSH_SCP_REQUEST_NEWDIR){
|
||||
ssh_scp_deny_request(src->scp,"Not in recursive mode");
|
||||
continue;
|
||||
}
|
||||
if(r==SSH_SCP_REQUEST_NEWFILE){
|
||||
size=ssh_scp_request_get_size(src->scp);
|
||||
filename=strdup(ssh_scp_request_get_filename(src->scp));
|
||||
mode=ssh_scp_request_get_permissions(src->scp);
|
||||
//ssh_scp_accept_request(src->scp);
|
||||
break;
|
||||
}
|
||||
if(r==SSH_ERROR){
|
||||
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
|
||||
return -1;
|
||||
}
|
||||
} while(r != SSH_SCP_REQUEST_NEWFILE);
|
||||
}
|
||||
|
||||
if(dest->is_ssh){
|
||||
r=ssh_scp_push_file(dest->scp,src->path, size, mode);
|
||||
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
|
||||
if(r==SSH_ERROR){
|
||||
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
|
||||
ssh_scp_free(dest->scp);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if(!dest->file){
|
||||
dest->file=fopen(filename,"w");
|
||||
if(!dest->file){
|
||||
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
|
||||
if(src->is_ssh)
|
||||
ssh_scp_deny_request(src->scp,"Cannot open local file");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(src->is_ssh){
|
||||
ssh_scp_accept_request(src->scp);
|
||||
}
|
||||
}
|
||||
do {
|
||||
if(src->is_ssh){
|
||||
r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
|
||||
if(r==SSH_ERROR){
|
||||
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
|
||||
return -1;
|
||||
}
|
||||
if(r==0)
|
||||
break;
|
||||
} else {
|
||||
r=fread(buffer,1,sizeof(buffer),src->file);
|
||||
if(r==0)
|
||||
break;
|
||||
if(r<0){
|
||||
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(dest->is_ssh){
|
||||
w=ssh_scp_write(dest->scp,buffer,r);
|
||||
if(w == SSH_ERROR){
|
||||
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
|
||||
ssh_scp_free(dest->scp);
|
||||
dest->scp=NULL;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
w=fwrite(buffer,r,1,dest->file);
|
||||
if(w<=0){
|
||||
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
total+=r;
|
||||
|
||||
} while(total < size);
|
||||
printf("wrote %d bytes\n",total);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
struct location *dest, *src;
|
||||
int i;
|
||||
int r;
|
||||
if(opts(argc,argv)<0)
|
||||
return EXIT_FAILURE;
|
||||
dest=parse_location(destination);
|
||||
if(open_location(dest,WRITE)<0)
|
||||
return EXIT_FAILURE;
|
||||
for(i=0;i<nsources;++i){
|
||||
src=parse_location(sources[i]);
|
||||
if(open_location(src,READ)<0){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if(do_copy(src,dest,0) < 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dest->is_ssh){
|
||||
r=ssh_scp_close(dest->scp);
|
||||
if(r == SSH_ERROR){
|
||||
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
|
||||
ssh_scp_free(dest->scp);
|
||||
dest->scp=NULL;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fclose(dest->file);
|
||||
dest->file=NULL;
|
||||
}
|
||||
ssh_disconnect(dest->session);
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
33
libssh/examples/libsshpp.cpp
Normal file
33
libssh/examples/libsshpp.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2010 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
*/
|
||||
|
||||
/* This file demonstrates the use of the C++ wrapper to libssh */
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <libssh/libsshpp.hpp>
|
||||
|
||||
int main(int argc, const char **argv){
|
||||
ssh::Session session;
|
||||
try {
|
||||
if(argc>1)
|
||||
session.setOption(SSH_OPTIONS_HOST,argv[1]);
|
||||
else
|
||||
session.setOption(SSH_OPTIONS_HOST,"localhost");
|
||||
session.connect();
|
||||
session.userauthPublickeyAuto();
|
||||
session.disconnect();
|
||||
} catch (ssh::SshException e){
|
||||
std::cout << "Error during connection : ";
|
||||
std::cout << e.getError() << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
41
libssh/examples/libsshpp_noexcept.cpp
Normal file
41
libssh/examples/libsshpp_noexcept.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2010 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
*/
|
||||
|
||||
/* This file demonstrates the use of the C++ wrapper to libssh
|
||||
* specifically, without C++ exceptions
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#define SSH_NO_CPP_EXCEPTIONS
|
||||
#include <libssh/libsshpp.hpp>
|
||||
|
||||
int main(int argc, const char **argv){
|
||||
ssh::Session session,s2;
|
||||
int err;
|
||||
if(argc>1)
|
||||
err=session.setOption(SSH_OPTIONS_HOST,argv[1]);
|
||||
else
|
||||
err=session.setOption(SSH_OPTIONS_HOST,"localhost");
|
||||
if(err==SSH_ERROR)
|
||||
goto error;
|
||||
err=session.connect();
|
||||
if(err==SSH_ERROR)
|
||||
goto error;
|
||||
err=session.userauthPublickeyAuto();
|
||||
if(err==SSH_ERROR)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
std::cout << "Error during connection : ";
|
||||
std::cout << session.getError() << std::endl;
|
||||
return 1;
|
||||
}
|
519
libssh/examples/sample.c
Normal file
519
libssh/examples/sample.c
Normal file
@ -0,0 +1,519 @@
|
||||
/* client.c */
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <libssh/callbacks.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "examples_common.h"
|
||||
#define MAXCMD 10
|
||||
|
||||
static char *host;
|
||||
static char *user;
|
||||
static char *cmds[MAXCMD];
|
||||
static struct termios terminal;
|
||||
|
||||
static char *pcap_file=NULL;
|
||||
|
||||
static char *proxycommand;
|
||||
|
||||
static int auth_callback(const char *prompt, char *buf, size_t len,
|
||||
int echo, int verify, void *userdata) {
|
||||
(void) verify;
|
||||
(void) userdata;
|
||||
|
||||
return ssh_getpass(prompt, buf, len, echo, verify);
|
||||
}
|
||||
|
||||
struct ssh_callbacks_struct cb = {
|
||||
.auth_function=auth_callback,
|
||||
.userdata=NULL
|
||||
};
|
||||
|
||||
static void add_cmd(char *cmd){
|
||||
int n;
|
||||
for(n=0;cmds[n] && (n<MAXCMD);n++);
|
||||
if(n==MAXCMD)
|
||||
return;
|
||||
cmds[n]=strdup(cmd);
|
||||
}
|
||||
|
||||
static void usage(){
|
||||
fprintf(stderr,"Usage : ssh [options] [login@]hostname\n"
|
||||
"sample client - libssh-%s\n"
|
||||
"Options :\n"
|
||||
" -l user : log in as user\n"
|
||||
" -p port : connect to port\n"
|
||||
" -d : use DSS to verify host public key\n"
|
||||
" -r : use RSA to verify host public key\n"
|
||||
#ifdef WITH_PCAP
|
||||
" -P file : create a pcap debugging file\n"
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
" -T proxycommand : command to execute as a socket proxy\n"
|
||||
#endif
|
||||
,
|
||||
ssh_version(0));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
// for(i=0;i<argc;i++)
|
||||
// printf("%d : %s\n",i,argv[i]);
|
||||
/* insert your own arguments here */
|
||||
while((i=getopt(argc,argv,"T:P:"))!=-1){
|
||||
switch(i){
|
||||
case 'P':
|
||||
pcap_file=optarg;
|
||||
break;
|
||||
#ifndef _WIN32
|
||||
case 'T':
|
||||
proxycommand=optarg;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr,"unknown option %c\n",optopt);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(optind < argc)
|
||||
host=argv[optind++];
|
||||
while(optind < argc)
|
||||
add_cmd(argv[optind++]);
|
||||
if(host==NULL)
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef HAVE_CFMAKERAW
|
||||
static void cfmakeraw(struct termios *termios_p){
|
||||
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||
termios_p->c_oflag &= ~OPOST;
|
||||
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
termios_p->c_cflag &= ~(CSIZE|PARENB);
|
||||
termios_p->c_cflag |= CS8;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void do_cleanup(int i) {
|
||||
/* unused variable */
|
||||
(void) i;
|
||||
|
||||
tcsetattr(0,TCSANOW,&terminal);
|
||||
}
|
||||
|
||||
static void do_exit(int i) {
|
||||
/* unused variable */
|
||||
(void) i;
|
||||
|
||||
do_cleanup(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ssh_channel chan;
|
||||
int signal_delayed=0;
|
||||
|
||||
static void sigwindowchanged(int i){
|
||||
(void) i;
|
||||
signal_delayed=1;
|
||||
}
|
||||
|
||||
static void setsignal(void){
|
||||
signal(SIGWINCH, sigwindowchanged);
|
||||
signal_delayed=0;
|
||||
}
|
||||
|
||||
static void sizechanged(void){
|
||||
struct winsize win = { 0, 0, 0, 0 };
|
||||
ioctl(1, TIOCGWINSZ, &win);
|
||||
ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row);
|
||||
// printf("Changed pty size\n");
|
||||
setsignal();
|
||||
}
|
||||
|
||||
/* There are two flavors of select loop: the one based on
|
||||
* ssh_select and the one based on channel_select.
|
||||
* The ssh_select one permits you to give your own file descriptors to
|
||||
* follow. It is thus a complete select loop.
|
||||
* The second one only selects on channels. It is simplier to use
|
||||
* but doesn't permit you to fill in your own file descriptor. It is
|
||||
* more adapted if you can't use ssh_select as a main loop (because
|
||||
* you already have another main loop system).
|
||||
*/
|
||||
|
||||
#ifdef USE_CHANNEL_SELECT
|
||||
|
||||
/* channel_select base main loop, with a standard select(2)
|
||||
*/
|
||||
static void select_loop(ssh_session session,ssh_channel channel){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
char buffer[4096];
|
||||
ssh_buffer readbuf=ssh_buffer_new();
|
||||
ssh_channel channels[2];
|
||||
int lus;
|
||||
int eof=0;
|
||||
int maxfd;
|
||||
int ret;
|
||||
while(channel){
|
||||
/* when a signal is caught, ssh_select will return
|
||||
* with SSH_EINTR, which means it should be started
|
||||
* again. It lets you handle the signal the faster you
|
||||
* can, like in this window changed example. Of course, if
|
||||
* your signal handler doesn't call libssh at all, you're
|
||||
* free to handle signals directly in sighandler.
|
||||
*/
|
||||
do{
|
||||
FD_ZERO(&fds);
|
||||
if(!eof)
|
||||
FD_SET(0,&fds);
|
||||
timeout.tv_sec=30;
|
||||
timeout.tv_usec=0;
|
||||
FD_SET(ssh_get_fd(session),&fds);
|
||||
maxfd=ssh_get_fd(session)+1;
|
||||
ret=select(maxfd,&fds,NULL,NULL,&timeout);
|
||||
if(ret==EINTR)
|
||||
continue;
|
||||
if(FD_ISSET(0,&fds)){
|
||||
lus=read(0,buffer,sizeof(buffer));
|
||||
if(lus)
|
||||
ssh_channel_write(channel,buffer,lus);
|
||||
else {
|
||||
eof=1;
|
||||
ssh_channel_send_eof(channel);
|
||||
}
|
||||
}
|
||||
if(FD_ISSET(ssh_get_fd(session),&fds)){
|
||||
ssh_set_fd_toread(session);
|
||||
}
|
||||
channels[0]=channel; // set the first channel we want to read from
|
||||
channels[1]=NULL;
|
||||
ret=ssh_channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll
|
||||
if(signal_delayed)
|
||||
sizechanged();
|
||||
} while (ret==EINTR || ret==SSH_EINTR);
|
||||
|
||||
// we already looked for input from stdin. Now, we are looking for input from the channel
|
||||
|
||||
if(channel && ssh_channel_is_closed(channel)){
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
channels[0]=NULL;
|
||||
}
|
||||
if(channels[0]){
|
||||
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)>0){
|
||||
lus=channel_read_buffer(channel,readbuf,0,0);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||
|
||||
ssh_channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
if (write(1,ssh_buffer_get_begin(readbuf),lus) < 0) {
|
||||
fprintf(stderr, "Error writing to buffer\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)>0){ /* stderr */
|
||||
lus=channel_read_buffer(channel,readbuf,0,1);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||
ssh_channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
if (write(2,ssh_buffer_get_begin(readbuf),lus) < 0) {
|
||||
fprintf(stderr, "Error writing to buffer\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(channel && ssh_channel_is_closed(channel)){
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
}
|
||||
}
|
||||
ssh_buffer_free(readbuf);
|
||||
}
|
||||
#else /* CHANNEL_SELECT */
|
||||
|
||||
static void select_loop(ssh_session session,ssh_channel channel){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
char buffer[4096];
|
||||
/* channels will be set to the channels to poll.
|
||||
* outchannels will contain the result of the poll
|
||||
*/
|
||||
ssh_channel channels[2], outchannels[2];
|
||||
int lus;
|
||||
int eof=0;
|
||||
int maxfd;
|
||||
unsigned int r;
|
||||
int ret;
|
||||
while(channel){
|
||||
do{
|
||||
FD_ZERO(&fds);
|
||||
if(!eof)
|
||||
FD_SET(0,&fds);
|
||||
timeout.tv_sec=30;
|
||||
timeout.tv_usec=0;
|
||||
FD_SET(ssh_get_fd(session),&fds);
|
||||
maxfd=ssh_get_fd(session)+1;
|
||||
channels[0]=channel; // set the first channel we want to read from
|
||||
channels[1]=NULL;
|
||||
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
|
||||
if(signal_delayed)
|
||||
sizechanged();
|
||||
if(ret==EINTR)
|
||||
continue;
|
||||
if(FD_ISSET(0,&fds)){
|
||||
lus=read(0,buffer,sizeof(buffer));
|
||||
if(lus)
|
||||
ssh_channel_write(channel,buffer,lus);
|
||||
else {
|
||||
eof=1;
|
||||
ssh_channel_send_eof(channel);
|
||||
}
|
||||
}
|
||||
if(channel && ssh_channel_is_closed(channel)){
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
channels[0]=NULL;
|
||||
}
|
||||
if(outchannels[0]){
|
||||
while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,0))!=0){
|
||||
lus=ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),0);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||
|
||||
ssh_channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
if (write(1,buffer,lus) < 0) {
|
||||
fprintf(stderr, "Error writing to buffer\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,1))!=0){ /* stderr */
|
||||
lus=ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),1);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||
ssh_channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
if (write(2,buffer,lus) < 0) {
|
||||
fprintf(stderr, "Error writing to buffer\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(channel && ssh_channel_is_closed(channel)){
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
}
|
||||
} while (ret==EINTR || ret==SSH_EINTR);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void shell(ssh_session session){
|
||||
ssh_channel channel;
|
||||
struct termios terminal_local;
|
||||
int interactive=isatty(0);
|
||||
channel = ssh_channel_new(session);
|
||||
if(interactive){
|
||||
tcgetattr(0,&terminal_local);
|
||||
memcpy(&terminal,&terminal_local,sizeof(struct termios));
|
||||
}
|
||||
if(ssh_channel_open_session(channel)){
|
||||
printf("error opening channel : %s\n",ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
chan=channel;
|
||||
if(interactive){
|
||||
ssh_channel_request_pty(channel);
|
||||
sizechanged();
|
||||
}
|
||||
if(ssh_channel_request_shell(channel)){
|
||||
printf("Requesting shell : %s\n",ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(interactive){
|
||||
cfmakeraw(&terminal_local);
|
||||
tcsetattr(0,TCSANOW,&terminal_local);
|
||||
setsignal();
|
||||
}
|
||||
signal(SIGTERM,do_cleanup);
|
||||
select_loop(session,channel);
|
||||
if(interactive)
|
||||
do_cleanup(0);
|
||||
}
|
||||
|
||||
static void batch_shell(ssh_session session){
|
||||
ssh_channel channel;
|
||||
char buffer[1024];
|
||||
int i,s=0;
|
||||
for(i=0;i<MAXCMD && cmds[i];++i) {
|
||||
s+=snprintf(buffer+s,sizeof(buffer)-s,"%s ",cmds[i]);
|
||||
free(cmds[i]);
|
||||
cmds[i] = NULL;
|
||||
}
|
||||
channel=ssh_channel_new(session);
|
||||
ssh_channel_open_session(channel);
|
||||
if(ssh_channel_request_exec(channel,buffer)){
|
||||
printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
select_loop(session,channel);
|
||||
}
|
||||
|
||||
static int client(ssh_session session){
|
||||
int auth=0;
|
||||
char *banner;
|
||||
int state;
|
||||
if (user)
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0)
|
||||
return -1;
|
||||
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
|
||||
return -1;
|
||||
if (proxycommand != NULL){
|
||||
if(ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand))
|
||||
return -1;
|
||||
}
|
||||
ssh_options_parse_config(session, NULL);
|
||||
|
||||
if(ssh_connect(session)){
|
||||
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
state=verify_knownhost(session);
|
||||
if (state != 0)
|
||||
return -1;
|
||||
ssh_userauth_none(session, NULL);
|
||||
banner=ssh_get_issue_banner(session);
|
||||
if(banner){
|
||||
printf("%s\n",banner);
|
||||
free(banner);
|
||||
}
|
||||
auth=authenticate_console(session);
|
||||
if(auth != SSH_AUTH_SUCCESS){
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
|
||||
if(!cmds[0])
|
||||
shell(session);
|
||||
else
|
||||
batch_shell(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssh_pcap_file pcap;
|
||||
void set_pcap(ssh_session session);
|
||||
void set_pcap(ssh_session session){
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(!pcap)
|
||||
return;
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
void cleanup_pcap(void);
|
||||
void cleanup_pcap(){
|
||||
if(pcap)
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
|
||||
session = ssh_new();
|
||||
|
||||
ssh_callbacks_init(&cb);
|
||||
ssh_set_callbacks(session,&cb);
|
||||
|
||||
if(ssh_options_getopt(session, &argc, argv)) {
|
||||
fprintf(stderr, "error parsing command line :%s\n",
|
||||
ssh_get_error(session));
|
||||
usage();
|
||||
}
|
||||
opts(argc,argv);
|
||||
signal(SIGTERM, do_exit);
|
||||
|
||||
set_pcap(session);
|
||||
client(session);
|
||||
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
cleanup_pcap();
|
||||
|
||||
ssh_finalize();
|
||||
|
||||
return 0;
|
||||
}
|
266
libssh/examples/samplesftp.c
Normal file
266
libssh/examples/samplesftp.c
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
#include "examples_common.h"
|
||||
#ifdef WITH_SFTP
|
||||
|
||||
static int verbosity;
|
||||
static char *destination;
|
||||
|
||||
#define DATALEN 65536
|
||||
static void do_sftp(ssh_session session){
|
||||
sftp_session sftp=sftp_new(session);
|
||||
sftp_dir dir;
|
||||
sftp_attributes file;
|
||||
sftp_statvfs_t sftpstatvfs;
|
||||
struct statvfs sysstatvfs;
|
||||
sftp_file fichier;
|
||||
sftp_file to;
|
||||
int len=1;
|
||||
unsigned int i;
|
||||
char data[DATALEN]={0};
|
||||
char *lnk;
|
||||
|
||||
unsigned int count;
|
||||
|
||||
if(!sftp){
|
||||
fprintf(stderr, "sftp error initialising channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(sftp_init(sftp)){
|
||||
fprintf(stderr, "error initialising sftp: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Additional SFTP extensions provided by the server:\n");
|
||||
count = sftp_extensions_get_count(sftp);
|
||||
for (i = 0; i < count; i++) {
|
||||
printf("\t%s, version: %s\n",
|
||||
sftp_extensions_get_name(sftp, i),
|
||||
sftp_extensions_get_data(sftp, i));
|
||||
}
|
||||
|
||||
/* test symlink and readlink */
|
||||
if (sftp_symlink(sftp, "/tmp/this_is_the_link",
|
||||
"/tmp/sftp_symlink_test") < 0) {
|
||||
fprintf(stderr, "Could not create link (%s)\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
|
||||
lnk = sftp_readlink(sftp, "/tmp/sftp_symlink_test");
|
||||
if (lnk == NULL) {
|
||||
fprintf(stderr, "Could not read link (%s)\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
printf("readlink /tmp/sftp_symlink_test: %s\n", lnk);
|
||||
|
||||
sftp_unlink(sftp, "/tmp/sftp_symlink_test");
|
||||
|
||||
if (sftp_extension_supported(sftp, "statvfs@openssh.com", "2")) {
|
||||
sftpstatvfs = sftp_statvfs(sftp, "/tmp");
|
||||
if (sftpstatvfs == NULL) {
|
||||
fprintf(stderr, "statvfs failed (%s)\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
|
||||
printf("sftp statvfs:\n"
|
||||
"\tfile system block size: %llu\n"
|
||||
"\tfundamental fs block size: %llu\n"
|
||||
"\tnumber of blocks (unit f_frsize): %llu\n"
|
||||
"\tfree blocks in file system: %llu\n"
|
||||
"\tfree blocks for non-root: %llu\n"
|
||||
"\ttotal file inodes: %llu\n"
|
||||
"\tfree file inodes: %llu\n"
|
||||
"\tfree file inodes for to non-root: %llu\n"
|
||||
"\tfile system id: %llu\n"
|
||||
"\tbit mask of f_flag values: %llu\n"
|
||||
"\tmaximum filename length: %llu\n",
|
||||
(unsigned long long) sftpstatvfs->f_bsize,
|
||||
(unsigned long long) sftpstatvfs->f_frsize,
|
||||
(unsigned long long) sftpstatvfs->f_blocks,
|
||||
(unsigned long long) sftpstatvfs->f_bfree,
|
||||
(unsigned long long) sftpstatvfs->f_bavail,
|
||||
(unsigned long long) sftpstatvfs->f_files,
|
||||
(unsigned long long) sftpstatvfs->f_ffree,
|
||||
(unsigned long long) sftpstatvfs->f_favail,
|
||||
(unsigned long long) sftpstatvfs->f_fsid,
|
||||
(unsigned long long) sftpstatvfs->f_flag,
|
||||
(unsigned long long) sftpstatvfs->f_namemax);
|
||||
|
||||
sftp_statvfs_free(sftpstatvfs);
|
||||
|
||||
if (statvfs("/tmp", &sysstatvfs) < 0) {
|
||||
fprintf(stderr, "statvfs failed (%s)\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
printf("sys statvfs:\n"
|
||||
"\tfile system block size: %llu\n"
|
||||
"\tfundamental fs block size: %llu\n"
|
||||
"\tnumber of blocks (unit f_frsize): %llu\n"
|
||||
"\tfree blocks in file system: %llu\n"
|
||||
"\tfree blocks for non-root: %llu\n"
|
||||
"\ttotal file inodes: %llu\n"
|
||||
"\tfree file inodes: %llu\n"
|
||||
"\tfree file inodes for to non-root: %llu\n"
|
||||
"\tfile system id: %llu\n"
|
||||
"\tbit mask of f_flag values: %llu\n"
|
||||
"\tmaximum filename length: %llu\n",
|
||||
(unsigned long long) sysstatvfs.f_bsize,
|
||||
(unsigned long long) sysstatvfs.f_frsize,
|
||||
(unsigned long long) sysstatvfs.f_blocks,
|
||||
(unsigned long long) sysstatvfs.f_bfree,
|
||||
(unsigned long long) sysstatvfs.f_bavail,
|
||||
(unsigned long long) sysstatvfs.f_files,
|
||||
(unsigned long long) sysstatvfs.f_ffree,
|
||||
(unsigned long long) sysstatvfs.f_favail,
|
||||
(unsigned long long) sysstatvfs.f_fsid,
|
||||
(unsigned long long) sysstatvfs.f_flag,
|
||||
(unsigned long long) sysstatvfs.f_namemax);
|
||||
}
|
||||
|
||||
/* the connection is made */
|
||||
/* opening a directory */
|
||||
dir=sftp_opendir(sftp,"./");
|
||||
if(!dir) {
|
||||
fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session));
|
||||
return ;
|
||||
}
|
||||
/* reading the whole directory, file by file */
|
||||
while((file=sftp_readdir(sftp,dir))){
|
||||
fprintf(stderr, "%30s(%.8o) : %s(%.5d) %s(%.5d) : %.10llu bytes\n",
|
||||
file->name,
|
||||
file->permissions,
|
||||
file->owner,
|
||||
file->uid,
|
||||
file->group,
|
||||
file->gid,
|
||||
(long long unsigned int) file->size);
|
||||
sftp_attributes_free(file);
|
||||
}
|
||||
/* when file=NULL, an error has occured OR the directory listing is end of file */
|
||||
if(!sftp_dir_eof(dir)){
|
||||
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(sftp_closedir(dir)){
|
||||
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
/* this will open a file and copy it into your /home directory */
|
||||
/* the small buffer size was intended to stress the library. of course, you can use a buffer till 20kbytes without problem */
|
||||
|
||||
fichier=sftp_open(sftp,"/usr/bin/ssh",O_RDONLY, 0);
|
||||
if(!fichier){
|
||||
fprintf(stderr, "Error opening /usr/bin/ssh: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
/* open a file for writing... */
|
||||
to=sftp_open(sftp,"ssh-copy",O_WRONLY | O_CREAT, 0700);
|
||||
if(!to){
|
||||
fprintf(stderr, "Error opening ssh-copy for writing: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
while((len=sftp_read(fichier,data,4096)) > 0){
|
||||
if(sftp_write(to,data,len)!=len){
|
||||
fprintf(stderr, "Error writing %d bytes: %s\n",
|
||||
len, ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("finished\n");
|
||||
if(len<0)
|
||||
fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session));
|
||||
sftp_close(fichier);
|
||||
sftp_close(to);
|
||||
printf("fichiers ferm\n");
|
||||
to=sftp_open(sftp,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644);
|
||||
for(i=0;i<1000;++i){
|
||||
len=sftp_write(to,data,DATALEN);
|
||||
printf("wrote %d bytes\n",len);
|
||||
if(len != DATALEN){
|
||||
printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session));
|
||||
}
|
||||
}
|
||||
sftp_close(to);
|
||||
|
||||
/* close the sftp session */
|
||||
sftp_free(sftp);
|
||||
printf("sftp session terminated\n");
|
||||
}
|
||||
|
||||
static void usage(const char *argv0){
|
||||
fprintf(stderr,"Usage : %s [-v] remotehost\n"
|
||||
"sample sftp test client - libssh-%s\n"
|
||||
"Options :\n"
|
||||
" -v : increase log verbosity\n",
|
||||
argv0,
|
||||
ssh_version(0));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
while((i=getopt(argc,argv,"v"))!=-1){
|
||||
switch(i){
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"unknown option %c\n",optopt);
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
destination=argv[optind];
|
||||
if(destination == NULL){
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
if(opts(argc,argv)<0)
|
||||
return EXIT_FAILURE;
|
||||
session=connect_ssh(destination,NULL,verbosity);
|
||||
if(session == NULL)
|
||||
return EXIT_FAILURE;
|
||||
do_sftp(session);
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
413
libssh/examples/samplesshd-kbdint.c
Normal file
413
libssh/examples/samplesshd-kbdint.c
Normal file
@ -0,0 +1,413 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2003-2011 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define SSHD_USER "libssh"
|
||||
#define SSHD_PASSWORD "libssh"
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
static const char *pcap_file = "debug.server.pcap";
|
||||
static ssh_pcap_file pcap;
|
||||
|
||||
static void set_pcap(ssh_session session){
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
static void cleanup_pcap(void) {
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int auth_password(const char *user, const char *password){
|
||||
if(strcmp(user, SSHD_USER))
|
||||
return 0;
|
||||
if(strcmp(password, SSHD_PASSWORD))
|
||||
return 0;
|
||||
return 1; // authenticated
|
||||
}
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
static int port = 22;
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the host key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure.
|
||||
*/
|
||||
ssh_bind sshbind = state->input;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
port = atoi(arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
static const char *name;
|
||||
static const char *instruction;
|
||||
static const char *prompts[2];
|
||||
static char echo[] = { 1, 0 };
|
||||
|
||||
static int kbdint_check_response(ssh_session session) {
|
||||
int count;
|
||||
|
||||
count = ssh_userauth_kbdint_getnanswers(session);
|
||||
if(count != 2) {
|
||||
instruction = "Something weird happened :(";
|
||||
return 0;
|
||||
}
|
||||
if(strcasecmp("Arthur Dent",
|
||||
ssh_userauth_kbdint_getanswer(session, 0)) != 0) {
|
||||
instruction = "OK, this is not YOUR name, "
|
||||
"but it's a reference to the HGTG...";
|
||||
prompts[0] = "The main character's full name: ";
|
||||
return 0;
|
||||
}
|
||||
if(strcmp("42", ssh_userauth_kbdint_getanswer(session, 1)) != 0) {
|
||||
instruction = "Make an effort !!! What is the Answer to the Ultimate "
|
||||
"Question of Life, the Universe, and Everything ?";
|
||||
prompts[1] = "Answer to the Ultimate Question of Life, the Universe, "
|
||||
"and Everything: ";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int authenticate(ssh_session session) {
|
||||
ssh_message message;
|
||||
|
||||
name = "\n\nKeyboard-Interactive Fancy Authentication\n";
|
||||
instruction = "Please enter your real name and your password";
|
||||
prompts[0] = "Real name: ";
|
||||
prompts[1] = "Password: ";
|
||||
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(!message)
|
||||
break;
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_AUTH:
|
||||
switch(ssh_message_subtype(message)){
|
||||
case SSH_AUTH_METHOD_PASSWORD:
|
||||
printf("User %s wants to auth with pass %s\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message));
|
||||
if(auth_password(ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message))){
|
||||
ssh_message_auth_reply_success(message,0);
|
||||
ssh_message_free(message);
|
||||
return 1;
|
||||
}
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
// not authenticated, send default message
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
|
||||
case SSH_AUTH_METHOD_INTERACTIVE:
|
||||
if(!ssh_message_auth_kbdint_is_response(message)) {
|
||||
printf("User %s wants to auth with kbdint\n",
|
||||
ssh_message_auth_user(message));
|
||||
ssh_message_auth_interactive_request(message, name,
|
||||
instruction, 2, prompts, echo);
|
||||
} else {
|
||||
if(kbdint_check_response(session)) {
|
||||
ssh_message_auth_reply_success(message,0);
|
||||
ssh_message_free(message);
|
||||
return 1;
|
||||
}
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
break;
|
||||
case SSH_AUTH_METHOD_NONE:
|
||||
default:
|
||||
printf("User %s wants to auth with unknown auth %d\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_subtype(message));
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
ssh_message message;
|
||||
ssh_channel chan=0;
|
||||
char buf[2048];
|
||||
int auth=0;
|
||||
int shell=0;
|
||||
int i;
|
||||
int r;
|
||||
|
||||
sshbind=ssh_bind_new();
|
||||
session=ssh_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
|
||||
KEYS_FOLDER "ssh_host_dsa_key");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
|
||||
KEYS_FOLDER "ssh_host_rsa_key");
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
/*
|
||||
* Parse our arguments; every option seen by parse_opt will
|
||||
* be reflected in arguments.
|
||||
*/
|
||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
#endif
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
|
||||
if(ssh_bind_listen(sshbind)<0){
|
||||
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
printf("Started sample libssh sshd on port %d\n", port);
|
||||
printf("You can login as the user %s with the password %s\n", SSHD_USER,
|
||||
SSHD_PASSWORD);
|
||||
r = ssh_bind_accept(sshbind, session);
|
||||
if(r==SSH_ERROR){
|
||||
printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* proceed to authentication */
|
||||
auth = authenticate(session);
|
||||
if(!auth){
|
||||
printf("Authentication error: %s\n", ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* wait for a channel session */
|
||||
do {
|
||||
message = ssh_message_get(session);
|
||||
if(message){
|
||||
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
|
||||
ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
|
||||
chan = ssh_message_channel_request_open_reply_accept(message);
|
||||
ssh_message_free(message);
|
||||
break;
|
||||
} else {
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(!chan);
|
||||
|
||||
if(!chan) {
|
||||
printf("Error: cleint did not ask for a channel session (%s)\n",
|
||||
ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* wait for a shell */
|
||||
do {
|
||||
message = ssh_message_get(session);
|
||||
if(message != NULL) {
|
||||
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL &&
|
||||
ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
|
||||
shell = 1;
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
ssh_message_free(message);
|
||||
break;
|
||||
}
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(!shell);
|
||||
|
||||
if(!shell) {
|
||||
printf("Error: No shell requested (%s)\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
printf("it works !\n");
|
||||
do{
|
||||
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||
if(i>0) {
|
||||
if(*buf == '' || *buf == '')
|
||||
break;
|
||||
if(i == 1 && *buf == '\r')
|
||||
ssh_channel_write(chan, "\r\n", 2);
|
||||
else
|
||||
ssh_channel_write(chan, buf, i);
|
||||
if (write(1,buf,i) < 0) {
|
||||
printf("error writing to buffer\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} while (i>0);
|
||||
ssh_channel_close(chan);
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
453
libssh/examples/samplesshd-tty.c
Normal file
453
libssh/examples/samplesshd-tty.c
Normal file
@ -0,0 +1,453 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2003-2011 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <pty.h>
|
||||
|
||||
#define SSHD_USER "libssh"
|
||||
#define SSHD_PASSWORD "libssh"
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
const char *pcap_file="debug.server.pcap";
|
||||
ssh_pcap_file pcap;
|
||||
|
||||
static void set_pcap(ssh_session session){
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
static void cleanup_pcap(){
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int auth_password(const char *user, const char *password){
|
||||
if(strcmp(user, SSHD_USER))
|
||||
return 0;
|
||||
if(strcmp(password, SSHD_PASSWORD))
|
||||
return 0;
|
||||
return 1; // authenticated
|
||||
}
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
static int port = 22;
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the host key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure.
|
||||
*/
|
||||
ssh_bind sshbind = state->input;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
port = atoi(arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
static int authenticate(ssh_session session) {
|
||||
ssh_message message;
|
||||
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(!message)
|
||||
break;
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_AUTH:
|
||||
switch(ssh_message_subtype(message)){
|
||||
case SSH_AUTH_METHOD_PASSWORD:
|
||||
printf("User %s wants to auth with pass %s\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message));
|
||||
if(auth_password(ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message))){
|
||||
ssh_message_auth_reply_success(message,0);
|
||||
ssh_message_free(message);
|
||||
return 1;
|
||||
}
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
// not authenticated, send default message
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
|
||||
case SSH_AUTH_METHOD_NONE:
|
||||
default:
|
||||
printf("User %s wants to auth with unknown auth %d\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_subtype(message));
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) {
|
||||
ssh_channel chan = (ssh_channel)userdata;
|
||||
char buf[2048];
|
||||
int sz = 0;
|
||||
|
||||
if(!chan) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
if(revents & POLLIN) {
|
||||
sz = read(fd, buf, 2048);
|
||||
if(sz > 0) {
|
||||
ssh_channel_write(chan, buf, sz);
|
||||
}
|
||||
}
|
||||
if(revents & POLLHUP) {
|
||||
ssh_channel_close(chan);
|
||||
sz = -1;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int copy_chan_to_fd(ssh_session session,
|
||||
ssh_channel channel,
|
||||
void *data,
|
||||
uint32_t len,
|
||||
int is_stderr,
|
||||
void *userdata) {
|
||||
int fd = *(int*)userdata;
|
||||
int sz;
|
||||
(void)session;
|
||||
(void)channel;
|
||||
(void)is_stderr;
|
||||
|
||||
sz = write(fd, data, len);
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void chan_close(ssh_session session, ssh_channel channel, void *userdata) {
|
||||
int fd = *(int*)userdata;
|
||||
(void)session;
|
||||
(void)channel;
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
struct ssh_channel_callbacks_struct cb = {
|
||||
.channel_data_function = copy_chan_to_fd,
|
||||
.channel_eof_function = chan_close,
|
||||
.channel_close_function = chan_close,
|
||||
.userdata = NULL
|
||||
};
|
||||
|
||||
static int main_loop(ssh_channel chan) {
|
||||
ssh_session session = ssh_channel_get_session(chan);
|
||||
socket_t fd;
|
||||
struct termios *term = NULL;
|
||||
struct winsize *win = NULL;
|
||||
pid_t childpid;
|
||||
ssh_event event;
|
||||
short events;
|
||||
|
||||
|
||||
childpid = forkpty(&fd, NULL, term, win);
|
||||
if(childpid == 0) {
|
||||
execl("/bin/bash", "/bin/bash", (char *)NULL);
|
||||
abort();
|
||||
}
|
||||
|
||||
cb.userdata = &fd;
|
||||
ssh_callbacks_init(&cb);
|
||||
ssh_set_channel_callbacks(chan, &cb);
|
||||
|
||||
events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
|
||||
|
||||
event = ssh_event_new();
|
||||
if(event == NULL) {
|
||||
printf("Couldn't get a event\n");
|
||||
return -1;
|
||||
}
|
||||
if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) {
|
||||
printf("Couldn't add an fd to the event\n");
|
||||
return -1;
|
||||
}
|
||||
if(ssh_event_add_session(event, session) != SSH_OK) {
|
||||
printf("Couldn't add the session to the event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
ssh_event_dopoll(event, 1000);
|
||||
} while(!ssh_channel_is_closed(chan));
|
||||
|
||||
ssh_event_remove_fd(event, fd);
|
||||
|
||||
ssh_event_remove_session(event, session);
|
||||
|
||||
ssh_event_free(event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
ssh_message message;
|
||||
ssh_channel chan=0;
|
||||
int auth=0;
|
||||
int shell=0;
|
||||
int r;
|
||||
|
||||
sshbind=ssh_bind_new();
|
||||
session=ssh_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
|
||||
KEYS_FOLDER "ssh_host_dsa_key");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
|
||||
KEYS_FOLDER "ssh_host_rsa_key");
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
/*
|
||||
* Parse our arguments; every option seen by parse_opt will
|
||||
* be reflected in arguments.
|
||||
*/
|
||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
#endif
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
|
||||
if(ssh_bind_listen(sshbind)<0){
|
||||
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
printf("Started sample libssh sshd on port %d\n", port);
|
||||
printf("You can login as the user %s with the password %s\n", SSHD_USER,
|
||||
SSHD_PASSWORD);
|
||||
r = ssh_bind_accept(sshbind, session);
|
||||
if(r==SSH_ERROR){
|
||||
printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* proceed to authentication */
|
||||
auth = authenticate(session);
|
||||
if(!auth){
|
||||
printf("Authentication error: %s\n", ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* wait for a channel session */
|
||||
do {
|
||||
message = ssh_message_get(session);
|
||||
if(message){
|
||||
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
|
||||
ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
|
||||
chan = ssh_message_channel_request_open_reply_accept(message);
|
||||
ssh_message_free(message);
|
||||
break;
|
||||
} else {
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(!chan);
|
||||
|
||||
if(!chan) {
|
||||
printf("Error: cleint did not ask for a channel session (%s)\n",
|
||||
ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* wait for a shell */
|
||||
do {
|
||||
message = ssh_message_get(session);
|
||||
if(message != NULL) {
|
||||
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL) {
|
||||
if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
|
||||
shell = 1;
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
ssh_message_free(message);
|
||||
break;
|
||||
} else if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_PTY) {
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
ssh_message_free(message);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(!shell);
|
||||
|
||||
if(!shell) {
|
||||
printf("Error: No shell requested (%s)\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("it works !\n");
|
||||
|
||||
main_loop(chan);
|
||||
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
314
libssh/examples/samplesshd.c
Normal file
314
libssh/examples/samplesshd.c
Normal file
@ -0,0 +1,314 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
static const char *pcap_file="debug.server.pcap";
|
||||
static ssh_pcap_file pcap;
|
||||
|
||||
static void set_pcap(ssh_session session) {
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
static void cleanup_pcap(void) {
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int auth_password(const char *user, const char *password){
|
||||
if(strcmp(user,"aris"))
|
||||
return 0;
|
||||
if(strcmp(password,"lala"))
|
||||
return 0;
|
||||
return 1; // authenticated
|
||||
}
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the host key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure.
|
||||
*/
|
||||
ssh_bind sshbind = state->input;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
ssh_message message;
|
||||
ssh_channel chan=0;
|
||||
char buf[2048];
|
||||
int auth=0;
|
||||
int sftp=0;
|
||||
int i;
|
||||
int r;
|
||||
|
||||
sshbind=ssh_bind_new();
|
||||
session=ssh_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
/*
|
||||
* Parse our arguments; every option seen by parse_opt will
|
||||
* be reflected in arguments.
|
||||
*/
|
||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
#endif
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
|
||||
if(ssh_bind_listen(sshbind)<0){
|
||||
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
r=ssh_bind_accept(sshbind,session);
|
||||
if(r==SSH_ERROR){
|
||||
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(!message)
|
||||
break;
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_AUTH:
|
||||
switch(ssh_message_subtype(message)){
|
||||
case SSH_AUTH_METHOD_PASSWORD:
|
||||
printf("User %s wants to auth with pass %s\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message));
|
||||
if(auth_password(ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message))){
|
||||
auth=1;
|
||||
ssh_message_auth_reply_success(message,0);
|
||||
break;
|
||||
}
|
||||
// not authenticated, send default message
|
||||
case SSH_AUTH_METHOD_NONE:
|
||||
default:
|
||||
ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (!auth);
|
||||
if(!auth){
|
||||
printf("auth error: %s\n",ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(message){
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_CHANNEL_OPEN:
|
||||
if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
|
||||
chan=ssh_message_channel_request_open_reply_accept(message);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
}
|
||||
} while(message && !chan);
|
||||
if(!chan){
|
||||
printf("error : %s\n",ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
|
||||
(ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL ||
|
||||
ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_PTY)) {
|
||||
// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
|
||||
sftp=1;
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
break;
|
||||
// }
|
||||
}
|
||||
if(!sftp){
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (message && !sftp);
|
||||
if(!sftp){
|
||||
printf("error : %s\n",ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
printf("it works !\n");
|
||||
do{
|
||||
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||
if(i>0) {
|
||||
ssh_channel_write(chan, buf, i);
|
||||
if (write(1,buf,i) < 0) {
|
||||
printf("error writing to buffer\n");
|
||||
return 1;
|
||||
}
|
||||
if (buf[0] == '\x0d') {
|
||||
if (write(1, "\n", 1) < 0) {
|
||||
printf("error writing to buffer\n");
|
||||
return 1;
|
||||
}
|
||||
ssh_channel_write(chan, "\n", 1);
|
||||
}
|
||||
}
|
||||
} while (i>0);
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
165
libssh/examples/scp_download.c
Normal file
165
libssh/examples/scp_download.c
Normal file
@ -0,0 +1,165 @@
|
||||
/* scp_download.c
|
||||
* Sample implementation of a tiny SCP downloader client
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
|
||||
int verbosity=0;
|
||||
const char *createcommand="rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
|
||||
char *host=NULL;
|
||||
static void usage(const char *argv0){
|
||||
fprintf(stderr,"Usage : %s [options] host\n"
|
||||
"sample tiny scp downloader client - libssh-%s\n"
|
||||
"This program will create files in /tmp and try to fetch them\n",
|
||||
// "Options :\n",
|
||||
// " -r : use RSA to verify host public key\n",
|
||||
argv0,
|
||||
ssh_version(0));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
while((i=getopt(argc,argv,"v"))!=-1){
|
||||
switch(i){
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"unknown option %c\n",optopt);
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
host = argv[optind];
|
||||
if(host == NULL)
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void create_files(ssh_session session){
|
||||
ssh_channel channel=ssh_channel_new(session);
|
||||
char buffer[1];
|
||||
if(channel == NULL){
|
||||
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(ssh_channel_open_session(channel) != SSH_OK){
|
||||
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
||||
ssh_channel_free(channel);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(ssh_channel_request_exec(channel,createcommand) != SSH_OK){
|
||||
fprintf(stderr,"Error executing command: %s\n",ssh_get_error(session));
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
while(!ssh_channel_is_eof(channel)){
|
||||
ssh_channel_read(channel,buffer,1,1);
|
||||
if (write(1,buffer,1) < 0) {
|
||||
fprintf(stderr, "Error writing to buffer\n");
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
|
||||
static int fetch_files(ssh_session session){
|
||||
int size;
|
||||
char buffer[16384];
|
||||
int mode;
|
||||
char *filename;
|
||||
int r;
|
||||
ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*");
|
||||
if(ssh_scp_init(scp) != SSH_OK){
|
||||
fprintf(stderr,"error initializing scp: %s\n",ssh_get_error(session));
|
||||
ssh_scp_free(scp);
|
||||
return -1;
|
||||
}
|
||||
printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n");
|
||||
do {
|
||||
|
||||
r=ssh_scp_pull_request(scp);
|
||||
switch(r){
|
||||
case SSH_SCP_REQUEST_NEWFILE:
|
||||
size=ssh_scp_request_get_size(scp);
|
||||
filename=strdup(ssh_scp_request_get_filename(scp));
|
||||
mode=ssh_scp_request_get_permissions(scp);
|
||||
printf("downloading file %s, size %d, perms 0%o\n",filename,size,mode);
|
||||
free(filename);
|
||||
ssh_scp_accept_request(scp);
|
||||
r=ssh_scp_read(scp,buffer,sizeof(buffer));
|
||||
if(r==SSH_ERROR){
|
||||
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(session));
|
||||
ssh_scp_close(scp);
|
||||
ssh_scp_free(scp);
|
||||
return -1;
|
||||
}
|
||||
printf("done\n");
|
||||
break;
|
||||
case SSH_ERROR:
|
||||
fprintf(stderr,"Error: %s\n",ssh_get_error(session));
|
||||
ssh_scp_close(scp);
|
||||
ssh_scp_free(scp);
|
||||
return -1;
|
||||
case SSH_SCP_REQUEST_WARNING:
|
||||
fprintf(stderr,"Warning: %s\n",ssh_scp_request_get_warning(scp));
|
||||
break;
|
||||
case SSH_SCP_REQUEST_NEWDIR:
|
||||
filename=strdup(ssh_scp_request_get_filename(scp));
|
||||
mode=ssh_scp_request_get_permissions(scp);
|
||||
printf("downloading directory %s, perms 0%o\n",filename,mode);
|
||||
free(filename);
|
||||
ssh_scp_accept_request(scp);
|
||||
break;
|
||||
case SSH_SCP_REQUEST_ENDDIR:
|
||||
printf("End of directory\n");
|
||||
break;
|
||||
case SSH_SCP_REQUEST_EOF:
|
||||
printf("End of requests\n");
|
||||
goto end;
|
||||
}
|
||||
} while (1);
|
||||
end:
|
||||
ssh_scp_close(scp);
|
||||
ssh_scp_free(scp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
if(opts(argc,argv)<0)
|
||||
return EXIT_FAILURE;
|
||||
session=connect_ssh(host,NULL,verbosity);
|
||||
if(session == NULL)
|
||||
return EXIT_FAILURE;
|
||||
create_files(session);
|
||||
fetch_files(session);
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
64
libssh/examples/senddata.c
Normal file
64
libssh/examples/senddata.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "examples_common.h"
|
||||
|
||||
#define LIMIT 0x100000000
|
||||
|
||||
int main(void) {
|
||||
ssh_session session;
|
||||
ssh_channel channel;
|
||||
char buffer[1024*1024];
|
||||
int rc;
|
||||
uint64_t total=0;
|
||||
uint64_t lastshown=4096;
|
||||
session = connect_ssh("localhost", NULL, 0);
|
||||
if (session == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
channel = ssh_channel_new(session);;
|
||||
if (channel == NULL) {
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = ssh_channel_open_session(channel);
|
||||
if (rc < 0) {
|
||||
ssh_channel_close(channel);
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = ssh_channel_request_exec(channel, "cat > /dev/null");
|
||||
if (rc < 0) {
|
||||
ssh_channel_close(channel);
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
while ((rc = ssh_channel_write(channel, buffer, sizeof(buffer))) > 0) {
|
||||
total += rc;
|
||||
if(total/2 >= lastshown){
|
||||
printf("written %llx\n", (long long unsigned int) total);
|
||||
lastshown=total;
|
||||
}
|
||||
if(total > LIMIT)
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
printf("error : %s\n",ssh_get_error(session));
|
||||
ssh_channel_close(channel);
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
|
||||
ssh_disconnect(session);
|
||||
|
||||
return 0;
|
||||
}
|
258
libssh/examples/sshnetcat.c
Normal file
258
libssh/examples/sshnetcat.c
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
Copyright 2010 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <libssh/callbacks.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "examples_common.h"
|
||||
char *host;
|
||||
const char *desthost="localhost";
|
||||
const char *port="22";
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
#include <libssh/pcap.h>
|
||||
char *pcap_file=NULL;
|
||||
#endif
|
||||
|
||||
static void usage(){
|
||||
fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
while((i=getopt(argc,argv,"P:"))!=-1){
|
||||
switch(i){
|
||||
#ifdef WITH_PCAP
|
||||
case 'P':
|
||||
pcap_file=optarg;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr,"unknown option %c\n",optopt);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(optind < argc)
|
||||
host=argv[optind++];
|
||||
if(optind < argc)
|
||||
desthost=argv[optind++];
|
||||
if(optind < argc)
|
||||
port=argv[optind++];
|
||||
if(host==NULL)
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void select_loop(ssh_session session,ssh_channel channel){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
char buffer[4096];
|
||||
/* channels will be set to the channels to poll.
|
||||
* outchannels will contain the result of the poll
|
||||
*/
|
||||
ssh_channel channels[2], outchannels[2];
|
||||
int lus;
|
||||
int eof=0;
|
||||
int maxfd;
|
||||
int ret;
|
||||
while(channel){
|
||||
do{
|
||||
FD_ZERO(&fds);
|
||||
if(!eof)
|
||||
FD_SET(0,&fds);
|
||||
timeout.tv_sec=30;
|
||||
timeout.tv_usec=0;
|
||||
FD_SET(ssh_get_fd(session),&fds);
|
||||
maxfd=ssh_get_fd(session)+1;
|
||||
channels[0]=channel; // set the first channel we want to read from
|
||||
channels[1]=NULL;
|
||||
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
|
||||
if(ret==EINTR)
|
||||
continue;
|
||||
if(FD_ISSET(0,&fds)){
|
||||
lus=read(0,buffer,sizeof(buffer));
|
||||
if(lus)
|
||||
channel_write(channel,buffer,lus);
|
||||
else {
|
||||
eof=1;
|
||||
channel_send_eof(channel);
|
||||
}
|
||||
}
|
||||
if(channel && channel_is_closed(channel)){
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
|
||||
channel_free(channel);
|
||||
channel=NULL;
|
||||
channels[0]=NULL;
|
||||
}
|
||||
if(outchannels[0]){
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
|
||||
lus=channel_read(channel,buffer,sizeof(buffer),0);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
|
||||
channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else {
|
||||
ret = write(1, buffer, lus);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error writing to stdin: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
|
||||
lus=channel_read(channel,buffer,sizeof(buffer),1);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
ret = write(2, buffer, lus);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error writing to stderr: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(channel && channel_is_closed(channel)){
|
||||
channel_free(channel);
|
||||
channel=NULL;
|
||||
}
|
||||
} while (ret==EINTR || ret==SSH_EINTR);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void forwarding(ssh_session session){
|
||||
ssh_channel channel;
|
||||
int r;
|
||||
channel=channel_new(session);
|
||||
r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
|
||||
if(r<0) {
|
||||
printf("error forwarding port : %s\n",ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
select_loop(session,channel);
|
||||
}
|
||||
|
||||
static int client(ssh_session session){
|
||||
int auth=0;
|
||||
char *banner;
|
||||
int state;
|
||||
|
||||
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
|
||||
return -1;
|
||||
ssh_options_parse_config(session, NULL);
|
||||
|
||||
if(ssh_connect(session)){
|
||||
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
state=verify_knownhost(session);
|
||||
if (state != 0)
|
||||
return -1;
|
||||
ssh_userauth_none(session, NULL);
|
||||
banner=ssh_get_issue_banner(session);
|
||||
if(banner){
|
||||
printf("%s\n",banner);
|
||||
free(banner);
|
||||
}
|
||||
auth=authenticate_console(session);
|
||||
if(auth != SSH_AUTH_SUCCESS){
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
|
||||
forwarding(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
ssh_pcap_file pcap;
|
||||
void set_pcap(ssh_session session);
|
||||
void set_pcap(ssh_session session){
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
void cleanup_pcap(void);
|
||||
void cleanup_pcap(){
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
|
||||
session = ssh_new();
|
||||
|
||||
if(ssh_options_getopt(session, &argc, argv)) {
|
||||
fprintf(stderr, "error parsing command line :%s\n",
|
||||
ssh_get_error(session));
|
||||
usage();
|
||||
}
|
||||
opts(argc,argv);
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
client(session);
|
||||
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
|
||||
ssh_finalize();
|
||||
|
||||
return 0;
|
||||
}
|
3
libssh/include/CMakeLists.txt
Normal file
3
libssh/include/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
project(headers C)
|
||||
|
||||
add_subdirectory(libssh)
|
39
libssh/include/libssh/CMakeLists.txt
Normal file
39
libssh/include/libssh/CMakeLists.txt
Normal file
@ -0,0 +1,39 @@
|
||||
project(libssh-headers C)
|
||||
|
||||
set(libssh_HDRS
|
||||
callbacks.h
|
||||
libssh.h
|
||||
ssh2.h
|
||||
legacy.h
|
||||
)
|
||||
|
||||
if (WITH_SFTP)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
sftp.h
|
||||
)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
if (WITH_SSH1)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
ssh1.h
|
||||
)
|
||||
endif (WITH_SSH1)
|
||||
|
||||
if (WITH_SERVER)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
server.h
|
||||
)
|
||||
endif (WITH_SERVER)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${libssh_HDRS}
|
||||
DESTINATION
|
||||
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||
COMPONENT
|
||||
headers
|
||||
)
|
||||
|
117
libssh/include/libssh/agent.h
Normal file
117
libssh/include/libssh/agent.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2008-2009 Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __AGENT_H
|
||||
#define __AGENT_H
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
|
||||
/* Messages for the authentication agent connection. */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||
#define SSH_AGENTC_RSA_CHALLENGE 3
|
||||
#define SSH_AGENT_RSA_RESPONSE 4
|
||||
#define SSH_AGENT_FAILURE 5
|
||||
#define SSH_AGENT_SUCCESS 6
|
||||
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
|
||||
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
|
||||
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
|
||||
|
||||
/* private OpenSSH extensions for SSH2 */
|
||||
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
|
||||
#define SSH2_AGENT_IDENTITIES_ANSWER 12
|
||||
#define SSH2_AGENTC_SIGN_REQUEST 13
|
||||
#define SSH2_AGENT_SIGN_RESPONSE 14
|
||||
#define SSH2_AGENTC_ADD_IDENTITY 17
|
||||
#define SSH2_AGENTC_REMOVE_IDENTITY 18
|
||||
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
|
||||
|
||||
/* smartcard */
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
|
||||
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||
|
||||
/* lock/unlock the agent */
|
||||
#define SSH_AGENTC_LOCK 22
|
||||
#define SSH_AGENTC_UNLOCK 23
|
||||
|
||||
/* add key with constraints */
|
||||
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
|
||||
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
/* extended failure messages */
|
||||
#define SSH2_AGENT_FAILURE 30
|
||||
|
||||
/* additional error code for ssh.com's ssh-agent2 */
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
|
||||
#define SSH_AGENT_OLD_SIGNATURE 0x01
|
||||
|
||||
struct ssh_agent_struct {
|
||||
struct ssh_socket_struct *sock;
|
||||
ssh_buffer ident;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
/* agent.c */
|
||||
/**
|
||||
* @brief Create a new ssh agent structure.
|
||||
*
|
||||
* @return An allocated ssh agent structure or NULL on error.
|
||||
*/
|
||||
struct ssh_agent_struct *agent_new(struct ssh_session_struct *session);
|
||||
|
||||
void agent_close(struct ssh_agent_struct *agent);
|
||||
|
||||
/**
|
||||
* @brief Free an allocated ssh agent structure.
|
||||
*
|
||||
* @param agent The ssh agent structure to free.
|
||||
*/
|
||||
void agent_free(struct ssh_agent_struct *agent);
|
||||
|
||||
/**
|
||||
* @brief Check if the ssh agent is running.
|
||||
*
|
||||
* @param session The ssh session to check for the agent.
|
||||
*
|
||||
* @return 1 if it is running, 0 if not.
|
||||
*/
|
||||
int agent_is_running(struct ssh_session_struct *session);
|
||||
|
||||
int ssh_agent_get_ident_count(struct ssh_session_struct *session);
|
||||
|
||||
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||
char **comment);
|
||||
|
||||
ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
|
||||
char **comment);
|
||||
|
||||
ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
const ssh_key pubkey,
|
||||
struct ssh_buffer_struct *data);
|
||||
#endif
|
||||
|
||||
#endif /* __AGENT_H */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
106
libssh/include/libssh/auth.h
Normal file
106
libssh/include/libssh/auth.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AUTH_H_
|
||||
#define AUTH_H_
|
||||
#include "config.h"
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_success);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response);
|
||||
|
||||
/** @internal
|
||||
* kdbint structure must be shared with message.c
|
||||
* and server.c
|
||||
*/
|
||||
struct ssh_kbdint_struct {
|
||||
uint32_t nprompts;
|
||||
uint32_t nanswers;
|
||||
char *name;
|
||||
char *instruction;
|
||||
char **prompts;
|
||||
unsigned char *echo; /* bool array */
|
||||
char **answers;
|
||||
};
|
||||
typedef struct ssh_kbdint_struct* ssh_kbdint;
|
||||
|
||||
ssh_kbdint ssh_kbdint_new(void);
|
||||
void ssh_kbdint_clean(ssh_kbdint kbd);
|
||||
void ssh_kbdint_free(ssh_kbdint kbd);
|
||||
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
void ssh_auth1_handler(ssh_session session, uint8_t type);
|
||||
|
||||
/* auth1.c */
|
||||
int ssh_userauth1_none(ssh_session session, const char *username);
|
||||
int ssh_userauth1_offer_pubkey(ssh_session session, const char *username,
|
||||
int type, ssh_string pubkey);
|
||||
int ssh_userauth1_password(ssh_session session, const char *username,
|
||||
const char *password);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/** @internal
|
||||
* States of authentication in the client-side. They describe
|
||||
* what was the last response from the server
|
||||
*/
|
||||
enum ssh_auth_state_e {
|
||||
/** No authentication asked */
|
||||
SSH_AUTH_STATE_NONE=0,
|
||||
/** Last authentication response was a partial success */
|
||||
SSH_AUTH_STATE_PARTIAL,
|
||||
/** Last authentication response was a success */
|
||||
SSH_AUTH_STATE_SUCCESS,
|
||||
/** Last authentication response was failed */
|
||||
SSH_AUTH_STATE_FAILED,
|
||||
/** Last authentication was erroneous */
|
||||
SSH_AUTH_STATE_ERROR,
|
||||
/** Last state was a keyboard-interactive ask for info */
|
||||
SSH_AUTH_STATE_INFO,
|
||||
/** Last state was a public key accepted for authentication */
|
||||
SSH_AUTH_STATE_PK_OK,
|
||||
/** We asked for a keyboard-interactive authentication */
|
||||
SSH_AUTH_STATE_KBDINT_SENT
|
||||
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief states of the authentication service request
|
||||
*/
|
||||
enum ssh_auth_service_state_e {
|
||||
/** initial state */
|
||||
SSH_AUTH_SERVICE_NONE=0,
|
||||
/** Authentication service request packet sent */
|
||||
SSH_AUTH_SERVICE_SENT,
|
||||
/** Service accepted */
|
||||
SSH_AUTH_SERVICE_ACCEPTED,
|
||||
/** Access to service denied (fatal) */
|
||||
SSH_AUTH_SERVICE_DENIED,
|
||||
/** Specific to SSH1 */
|
||||
SSH_AUTH_SERVICE_USER_SENT
|
||||
};
|
||||
|
||||
#endif /* AUTH_H_ */
|
53
libssh/include/libssh/bind.h
Normal file
53
libssh/include/libssh/bind.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BIND_H_
|
||||
#define BIND_H_
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/session.h"
|
||||
|
||||
struct ssh_bind_struct {
|
||||
struct ssh_common_struct common; /* stuff common to ssh_bind and ssh_session */
|
||||
struct ssh_bind_callbacks_struct *bind_callbacks;
|
||||
void *bind_callbacks_userdata;
|
||||
|
||||
struct ssh_poll_handle_struct *poll;
|
||||
/* options */
|
||||
char *wanted_methods[10];
|
||||
char *banner;
|
||||
char *ecdsakey;
|
||||
char *dsakey;
|
||||
char *rsakey;
|
||||
ssh_key ecdsa;
|
||||
ssh_key dsa;
|
||||
ssh_key rsa;
|
||||
char *bindaddr;
|
||||
socket_t bindfd;
|
||||
unsigned int bindport;
|
||||
int blocking;
|
||||
int toaccept;
|
||||
};
|
||||
|
||||
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
||||
*sshbind);
|
||||
|
||||
|
||||
#endif /* BIND_H_ */
|
72
libssh/include/libssh/buffer.h
Normal file
72
libssh/include/libssh/buffer.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BUFFER_H_
|
||||
#define BUFFER_H_
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
/*
|
||||
* Describes a buffer state
|
||||
* [XXXXXXXXXXXXDATA PAYLOAD XXXXXXXXXXXXXXXXXXXXXXXX]
|
||||
* ^ ^ ^ ^]
|
||||
* \_data points\_pos points here \_used points here | /
|
||||
* here Allocated
|
||||
*/
|
||||
struct ssh_buffer_struct {
|
||||
char *data;
|
||||
uint32_t used;
|
||||
uint32_t allocated;
|
||||
uint32_t pos;
|
||||
};
|
||||
|
||||
LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
|
||||
LIBSSH_API void *ssh_buffer_get_begin(ssh_buffer buffer);
|
||||
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
|
||||
LIBSSH_API ssh_buffer ssh_buffer_new(void);
|
||||
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
||||
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
||||
int buffer_add_u16(ssh_buffer buffer, uint16_t data);
|
||||
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
|
||||
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
|
||||
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||
int buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||
int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
|
||||
int buffer_reinit(ssh_buffer buffer);
|
||||
|
||||
/* buffer_get_rest returns a pointer to the current position into the buffer */
|
||||
void *buffer_get_rest(ssh_buffer buffer);
|
||||
/* buffer_get_rest_len returns the number of bytes which can be read */
|
||||
uint32_t buffer_get_rest_len(ssh_buffer buffer);
|
||||
|
||||
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
|
||||
int buffer_get_u8(ssh_buffer buffer, uint8_t *data);
|
||||
int buffer_get_u32(ssh_buffer buffer, uint32_t *data);
|
||||
int buffer_get_u64(ssh_buffer buffer, uint64_t *data);
|
||||
|
||||
uint32_t buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
|
||||
/* buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
|
||||
ssh_string buffer_get_ssh_string(ssh_buffer buffer);
|
||||
/* gets a string out of a SSH-1 mpint */
|
||||
ssh_string buffer_get_mpint(ssh_buffer buffer);
|
||||
/* buffer_pass_bytes acts as if len bytes have been read (used for padding) */
|
||||
uint32_t buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
|
||||
uint32_t buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
|
||||
|
||||
#endif /* BUFFER_H_ */
|
447
libssh/include/libssh/callbacks.h
Normal file
447
libssh/include/libssh/callbacks.h
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 Aris Adamantiadis <aris@0xbadc0de.be>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* callback.h
|
||||
* This file includes the public declarations for the libssh callback mechanism
|
||||
*/
|
||||
|
||||
#ifndef _SSH_CALLBACK_H
|
||||
#define _SSH_CALLBACK_H
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup libssh_callbacks The libssh callbacks
|
||||
* @ingroup libssh
|
||||
*
|
||||
* Callback which can be replaced in libssh.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @internal
|
||||
* @brief callback to process simple codes
|
||||
* @param code value to transmit
|
||||
* @param user Userdata to pass in callback
|
||||
*/
|
||||
typedef void (*ssh_callback_int) (int code, void *user);
|
||||
|
||||
/** @internal
|
||||
* @brief callback for data received messages.
|
||||
* @param data data retrieved from the socket or stream
|
||||
* @param len number of bytes available from this stream
|
||||
* @param user user-supplied pointer sent along with all callback messages
|
||||
* @returns number of bytes processed by the callee. The remaining bytes will
|
||||
* be sent in the next callback message, when more data is available.
|
||||
*/
|
||||
typedef int (*ssh_callback_data) (const void *data, size_t len, void *user);
|
||||
|
||||
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
|
||||
|
||||
typedef int (*ssh_message_callback) (ssh_session, ssh_message message, void *user);
|
||||
typedef int (*ssh_channel_callback_int) (ssh_channel channel, int code, void *user);
|
||||
typedef int (*ssh_channel_callback_data) (ssh_channel channel, int code, void *data, size_t len, void *user);
|
||||
|
||||
/**
|
||||
* @brief SSH log callback. All logging messages will go through this callback
|
||||
* @param session Current session handler
|
||||
* @param priority Priority of the log, the smaller being the more important
|
||||
* @param message the actual message
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_log_callback) (ssh_session session, int priority,
|
||||
const char *message, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH Connection status callback.
|
||||
* @param session Current session handler
|
||||
* @param status Percentage of connection status, going from 0.0 to 1.0
|
||||
* once connection is done.
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_status_callback) (ssh_session session, float status,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH global request callback. All global request will go through this
|
||||
* callback.
|
||||
* @param session Current session handler
|
||||
* @param message the actual message
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_global_request_callback) (ssh_session session,
|
||||
ssh_message message, void *userdata);
|
||||
|
||||
/**
|
||||
* The structure to replace libssh functions with appropriate callbacks.
|
||||
*/
|
||||
struct ssh_callbacks_struct {
|
||||
/** DON'T SET THIS use ssh_callbacks_init() instead. */
|
||||
size_t size;
|
||||
/**
|
||||
* User-provided data. User is free to set anything he wants here
|
||||
*/
|
||||
void *userdata;
|
||||
/**
|
||||
* This functions will be called if e.g. a keyphrase is needed.
|
||||
*/
|
||||
ssh_auth_callback auth_function;
|
||||
/**
|
||||
* This function will be called each time a loggable event happens.
|
||||
*/
|
||||
ssh_log_callback log_function;
|
||||
/**
|
||||
* This function gets called during connection time to indicate the
|
||||
* percentage of connection steps completed.
|
||||
*/
|
||||
void (*connect_status_function)(void *userdata, float status);
|
||||
/**
|
||||
* This function will be called each time a global request is received.
|
||||
*/
|
||||
ssh_global_request_callback global_request_function;
|
||||
};
|
||||
typedef struct ssh_callbacks_struct *ssh_callbacks;
|
||||
|
||||
/**
|
||||
* These are the callbacks exported by the socket structure
|
||||
* They are called by the socket module when a socket event appears
|
||||
*/
|
||||
struct ssh_socket_callbacks_struct {
|
||||
/**
|
||||
* User-provided data. User is free to set anything he wants here
|
||||
*/
|
||||
void *userdata;
|
||||
/**
|
||||
* This function will be called each time data appears on socket. The data
|
||||
* not consumed will appear on the next data event.
|
||||
*/
|
||||
ssh_callback_data data;
|
||||
/** This function will be called each time a controlflow state changes, i.e.
|
||||
* the socket is available for reading or writing.
|
||||
*/
|
||||
ssh_callback_int controlflow;
|
||||
/** This function will be called each time an exception appears on socket. An
|
||||
* exception can be a socket problem (timeout, ...) or an end-of-file.
|
||||
*/
|
||||
ssh_callback_int_int exception;
|
||||
/** This function is called when the ssh_socket_connect was used on the socket
|
||||
* on nonblocking state, and the connection successed.
|
||||
*/
|
||||
ssh_callback_int_int connected;
|
||||
};
|
||||
typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
|
||||
|
||||
#define SSH_SOCKET_FLOW_WRITEWILLBLOCK 1
|
||||
#define SSH_SOCKET_FLOW_WRITEWONTBLOCK 2
|
||||
|
||||
#define SSH_SOCKET_EXCEPTION_EOF 1
|
||||
#define SSH_SOCKET_EXCEPTION_ERROR 2
|
||||
|
||||
#define SSH_SOCKET_CONNECTED_OK 1
|
||||
#define SSH_SOCKET_CONNECTED_ERROR 2
|
||||
#define SSH_SOCKET_CONNECTED_TIMEOUT 3
|
||||
|
||||
/**
|
||||
* @brief Initializes an ssh_callbacks_struct
|
||||
* A call to this macro is mandatory when you have set a new
|
||||
* ssh_callback_struct structure. Its goal is to maintain the binary
|
||||
* compatibility with future versions of libssh as the structure
|
||||
* evolves with time.
|
||||
*/
|
||||
#define ssh_callbacks_init(p) do {\
|
||||
(p)->size=sizeof(*(p)); \
|
||||
} while(0);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief tests if a callback can be called without crash
|
||||
* verifies that the struct size if big enough
|
||||
* verifies that the callback pointer exists
|
||||
* @param p callback pointer
|
||||
* @param c callback name
|
||||
* @returns nonzero if callback can be called
|
||||
*/
|
||||
#define ssh_callbacks_exists(p,c) (\
|
||||
(p != NULL) && ( (char *)&((p)-> c) < (char *)(p) + (p)->size ) && \
|
||||
((p)-> c != NULL) \
|
||||
)
|
||||
|
||||
/** @brief Prototype for a packet callback, to be called when a new packet arrives
|
||||
* @param session The current session of the packet
|
||||
* @param type packet type (see ssh2.h)
|
||||
* @param packet buffer containing the packet, excluding size, type and padding fields
|
||||
* @param user user argument to the callback
|
||||
* and are called each time a packet shows up
|
||||
* @returns SSH_PACKET_USED Packet was parsed and used
|
||||
* @returns SSH_PACKET_NOT_USED Packet was not used or understood, processing must continue
|
||||
*/
|
||||
typedef int (*ssh_packet_callback) (ssh_session session, uint8_t type, ssh_buffer packet, void *user);
|
||||
|
||||
/** return values for a ssh_packet_callback */
|
||||
/** Packet was used and should not be parsed by another callback */
|
||||
#define SSH_PACKET_USED 1
|
||||
/** Packet was not used and should be passed to any other callback
|
||||
* available */
|
||||
#define SSH_PACKET_NOT_USED 2
|
||||
|
||||
|
||||
/** @brief This macro declares a packet callback handler
|
||||
* @code
|
||||
* SSH_PACKET_CALLBACK(mycallback){
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#define SSH_PACKET_CALLBACK(name) \
|
||||
int name (ssh_session session, uint8_t type, ssh_buffer packet, void *user)
|
||||
|
||||
struct ssh_packet_callbacks_struct {
|
||||
/** Index of the first packet type being handled */
|
||||
uint8_t start;
|
||||
/** Number of packets being handled by this callback struct */
|
||||
uint8_t n_callbacks;
|
||||
/** A pointer to n_callbacks packet callbacks */
|
||||
ssh_packet_callback *callbacks;
|
||||
/**
|
||||
* User-provided data. User is free to set anything he wants here
|
||||
*/
|
||||
void *user;
|
||||
};
|
||||
|
||||
typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
|
||||
|
||||
/**
|
||||
* @brief Set the session callback functions.
|
||||
*
|
||||
* This functions sets the callback structure to use your own callback
|
||||
* functions for auth, logging and status.
|
||||
*
|
||||
* @code
|
||||
* struct ssh_callbacks_struct cb = {
|
||||
* .userdata = data,
|
||||
* .auth_function = my_auth_function
|
||||
* };
|
||||
* ssh_callbacks_init(&cb);
|
||||
* ssh_set_callbacks(session, &cb);
|
||||
* @endcode
|
||||
*
|
||||
* @param session The session to set the callback structure.
|
||||
*
|
||||
* @param cb The callback structure itself.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
|
||||
|
||||
/**
|
||||
* @brief SSH channel data callback. Called when data is available on a channel
|
||||
* @param session Current session handler
|
||||
* @param channel the actual channel
|
||||
* @param data the data that has been read on the channel
|
||||
* @param len the length of the data
|
||||
* @param is_stderr is 0 for stdout or 1 for stderr
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef int (*ssh_channel_data_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
void *data,
|
||||
uint32_t len,
|
||||
int is_stderr,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH channel eof callback. Called when a channel receives EOF
|
||||
* @param session Current session handler
|
||||
* @param channel the actual channel
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_channel_eof_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH channel close callback. Called when a channel is closed by remote peer
|
||||
* @param session Current session handler
|
||||
* @param channel the actual channel
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_channel_close_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH channel signal callback. Called when a channel has received a signal
|
||||
* @param session Current session handler
|
||||
* @param channel the actual channel
|
||||
* @param signal the signal name (without the SIG prefix)
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_channel_signal_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
const char *signal,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH channel exit status callback. Called when a channel has received an exit status
|
||||
* @param session Current session handler
|
||||
* @param channel the actual channel
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
int exit_status,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH channel exit signal callback. Called when a channel has received an exit signal
|
||||
* @param session Current session handler
|
||||
* @param channel the actual channel
|
||||
* @param signal the signal name (without the SIG prefix)
|
||||
* @param core a boolean telling wether a core has been dumped or not
|
||||
* @param errmsg the description of the exception
|
||||
* @param lang the language of the description (format: RFC 3066)
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*/
|
||||
typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
const char *signal,
|
||||
int core,
|
||||
const char *errmsg,
|
||||
const char *lang,
|
||||
void *userdata);
|
||||
|
||||
struct ssh_channel_callbacks_struct {
|
||||
/** DON'T SET THIS use ssh_callbacks_init() instead. */
|
||||
size_t size;
|
||||
/**
|
||||
* User-provided data. User is free to set anything he wants here
|
||||
*/
|
||||
void *userdata;
|
||||
/**
|
||||
* This functions will be called when there is data available.
|
||||
*/
|
||||
ssh_channel_data_callback channel_data_function;
|
||||
/**
|
||||
* This functions will be called when the channel has received an EOF.
|
||||
*/
|
||||
ssh_channel_eof_callback channel_eof_function;
|
||||
/**
|
||||
* This functions will be called when the channel has been closed by remote
|
||||
*/
|
||||
ssh_channel_close_callback channel_close_function;
|
||||
/**
|
||||
* This functions will be called when a signal has been received
|
||||
*/
|
||||
ssh_channel_signal_callback channel_signal_function;
|
||||
/**
|
||||
* This functions will be called when an exit status has been received
|
||||
*/
|
||||
ssh_channel_exit_status_callback channel_exit_status_function;
|
||||
/**
|
||||
* This functions will be called when an exit signal has been received
|
||||
*/
|
||||
ssh_channel_exit_signal_callback channel_exit_signal_function;
|
||||
};
|
||||
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
|
||||
|
||||
/**
|
||||
* @brief Set the channel callback functions.
|
||||
*
|
||||
* This functions sets the callback structure to use your own callback
|
||||
* functions for channel data and exceptions
|
||||
*
|
||||
* @code
|
||||
* struct ssh_channel_callbacks_struct cb = {
|
||||
* .userdata = data,
|
||||
* .channel_data = my_channel_data_function
|
||||
* };
|
||||
* ssh_callbacks_init(&cb);
|
||||
* ssh_set_channel_callbacks(channel, &cb);
|
||||
* @endcode
|
||||
*
|
||||
* @param channel The channel to set the callback structure.
|
||||
*
|
||||
* @param cb The callback structure itself.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel,
|
||||
ssh_channel_callbacks cb);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @group libssh_threads
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef int (*ssh_thread_callback) (void **lock);
|
||||
|
||||
typedef unsigned long (*ssh_thread_id_callback) (void);
|
||||
struct ssh_threads_callbacks_struct {
|
||||
const char *type;
|
||||
ssh_thread_callback mutex_init;
|
||||
ssh_thread_callback mutex_destroy;
|
||||
ssh_thread_callback mutex_lock;
|
||||
ssh_thread_callback mutex_unlock;
|
||||
ssh_thread_id_callback thread_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief sets the thread callbacks necessary if your program is using
|
||||
* libssh in a multithreaded fashion. This function must be called first,
|
||||
* outside of any threading context (in your main() for instance), before
|
||||
* ssh_init().
|
||||
* @param cb pointer to a ssh_threads_callbacks_struct structure, which contains
|
||||
* the different callbacks to be set.
|
||||
* @see ssh_threads_callbacks_struct
|
||||
* @see SSH_THREADS_PTHREAD
|
||||
*/
|
||||
LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
|
||||
*cb);
|
||||
|
||||
/**
|
||||
* @brief returns a pointer on the pthread threads callbacks, to be used with
|
||||
* ssh_threads_set_callbacks.
|
||||
* @warning you have to link with the library ssh_threads.
|
||||
* @see ssh_threads_set_callbacks
|
||||
*/
|
||||
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
|
||||
|
||||
/**
|
||||
* @brief returns a pointer on the noop threads callbacks, to be used with
|
||||
* ssh_threads_set_callbacks. These callbacks do nothing and are being used by
|
||||
* default.
|
||||
* @see ssh_threads_set_callbacks
|
||||
*/
|
||||
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void);
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_SSH_CALLBACK_H */
|
||||
|
||||
/* @} */
|
118
libssh/include/libssh/channels.h
Normal file
118
libssh/include/libssh/channels.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef CHANNELS_H_
|
||||
#define CHANNELS_H_
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/** @internal
|
||||
* Describes the different possible states in a
|
||||
* outgoing (client) channel request
|
||||
*/
|
||||
enum ssh_channel_request_state_e {
|
||||
/** No request has been made */
|
||||
SSH_CHANNEL_REQ_STATE_NONE = 0,
|
||||
/** A request has been made and answer is pending */
|
||||
SSH_CHANNEL_REQ_STATE_PENDING,
|
||||
/** A request has been replied and accepted */
|
||||
SSH_CHANNEL_REQ_STATE_ACCEPTED,
|
||||
/** A request has been replied and refused */
|
||||
SSH_CHANNEL_REQ_STATE_DENIED,
|
||||
/** A request has been replied and an error happend */
|
||||
SSH_CHANNEL_REQ_STATE_ERROR
|
||||
};
|
||||
|
||||
enum ssh_channel_state_e {
|
||||
SSH_CHANNEL_STATE_NOT_OPEN = 0,
|
||||
SSH_CHANNEL_STATE_OPENING,
|
||||
SSH_CHANNEL_STATE_OPEN_DENIED,
|
||||
SSH_CHANNEL_STATE_OPEN,
|
||||
SSH_CHANNEL_STATE_CLOSED
|
||||
};
|
||||
|
||||
/* The channel has been closed by the remote side */
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x1
|
||||
/* The channel has been freed by the calling program */
|
||||
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x2
|
||||
/* the channel has not yet been bound to a remote one */
|
||||
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x4
|
||||
|
||||
struct ssh_channel_struct {
|
||||
ssh_session session; /* SSH_SESSION pointer */
|
||||
uint32_t local_channel;
|
||||
uint32_t local_window;
|
||||
int local_eof;
|
||||
uint32_t local_maxpacket;
|
||||
|
||||
uint32_t remote_channel;
|
||||
uint32_t remote_window;
|
||||
int remote_eof; /* end of file received */
|
||||
uint32_t remote_maxpacket;
|
||||
enum ssh_channel_state_e state;
|
||||
int delayed_close;
|
||||
int flags;
|
||||
ssh_buffer stdout_buffer;
|
||||
ssh_buffer stderr_buffer;
|
||||
void *userarg;
|
||||
int version;
|
||||
int exit_status;
|
||||
enum ssh_channel_request_state_e request_state;
|
||||
ssh_channel_callbacks callbacks;
|
||||
};
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_success);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_failure);
|
||||
SSH_PACKET_CALLBACK(ssh_request_success);
|
||||
SSH_PACKET_CALLBACK(ssh_request_denied);
|
||||
|
||||
SSH_PACKET_CALLBACK(channel_rcv_change_window);
|
||||
SSH_PACKET_CALLBACK(channel_rcv_eof);
|
||||
SSH_PACKET_CALLBACK(channel_rcv_close);
|
||||
SSH_PACKET_CALLBACK(channel_rcv_request);
|
||||
SSH_PACKET_CALLBACK(channel_rcv_data);
|
||||
|
||||
ssh_channel ssh_channel_new(ssh_session session);
|
||||
int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||
int is_stderr);
|
||||
int ssh_channel_flush(ssh_channel channel);
|
||||
uint32_t ssh_channel_new_id(ssh_session session);
|
||||
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
||||
int channel_write_common(ssh_channel channel, const void *data,
|
||||
uint32_t len, int is_stderr);
|
||||
void ssh_channel_do_free(ssh_channel channel);
|
||||
#ifdef WITH_SSH1
|
||||
SSH_PACKET_CALLBACK(ssh_packet_data1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_close1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_exist_status1);
|
||||
|
||||
/* channels1.c */
|
||||
int channel_open_session1(ssh_channel channel);
|
||||
int channel_request_pty_size1(ssh_channel channel, const char *terminal,
|
||||
int cols, int rows);
|
||||
int channel_change_pty_size1(ssh_channel channel, int cols, int rows);
|
||||
int channel_request_shell1(ssh_channel channel);
|
||||
int channel_request_exec1(ssh_channel channel, const char *cmd);
|
||||
int channel_write1(ssh_channel channel, const void *data, int len);
|
||||
ssh_channel ssh_get_channel1(ssh_session session);
|
||||
#endif
|
||||
|
||||
#endif /* CHANNELS_H_ */
|
28
libssh/include/libssh/crc32.h
Normal file
28
libssh/include/libssh/crc32.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* crc32.c - simple CRC32 code
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CRC32_H
|
||||
#define _CRC32_H
|
||||
|
||||
uint32_t ssh_crc32(const char *buf, uint32_t len);
|
||||
|
||||
#endif /* _CRC32_H */
|
113
libssh/include/libssh/crypto.h
Normal file
113
libssh/include/libssh/crypto.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* crypto.h is an include file for internal cryptographic structures of libssh
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_H_
|
||||
#define _CRYPTO_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
#include "libssh/wrapper.h"
|
||||
|
||||
#ifdef cbc_encrypt
|
||||
#undef cbc_encrypt
|
||||
#endif
|
||||
#ifdef cbc_decrypt
|
||||
#undef cbc_decrypt
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_ECDH_H
|
||||
#include <openssl/ecdh.h>
|
||||
#endif
|
||||
#include "libssh/ecdh.h"
|
||||
#include "libssh/kex.h"
|
||||
|
||||
enum ssh_key_exchange_e {
|
||||
/* diffie-hellman-group1-sha1 */
|
||||
SSH_KEX_DH_GROUP1_SHA1=1,
|
||||
/* diffie-hellman-group14-sha1 */
|
||||
SSH_KEX_DH_GROUP14_SHA1,
|
||||
/* ecdh-sha2-nistp256 */
|
||||
SSH_KEX_ECDH_SHA2_NISTP256
|
||||
};
|
||||
|
||||
struct ssh_crypto_struct {
|
||||
bignum e,f,x,k,y;
|
||||
#ifdef HAVE_ECDH
|
||||
EC_KEY *ecdh_privkey;
|
||||
ssh_string ecdh_client_pubkey;
|
||||
ssh_string ecdh_server_pubkey;
|
||||
#endif
|
||||
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
||||
size_t digest_len; /* len of all the fields below */
|
||||
unsigned char *session_id;
|
||||
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
|
||||
unsigned char *encryptIV;
|
||||
unsigned char *decryptIV;
|
||||
unsigned char *decryptkey;
|
||||
unsigned char *encryptkey;
|
||||
unsigned char *encryptMAC;
|
||||
unsigned char *decryptMAC;
|
||||
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
|
||||
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
||||
ssh_string server_pubkey;
|
||||
const char *server_pubkey_type;
|
||||
int do_compress_out; /* idem */
|
||||
int do_compress_in; /* don't set them, set the option instead */
|
||||
int delayed_compress_in; /* Use of zlib@openssh.org */
|
||||
int delayed_compress_out;
|
||||
void *compress_out_ctx; /* don't touch it */
|
||||
void *compress_in_ctx; /* really, don't */
|
||||
/* kex sent by server, client, and mutually elected methods */
|
||||
struct ssh_kex_struct server_kex;
|
||||
struct ssh_kex_struct client_kex;
|
||||
char *kex_methods[SSH_KEX_METHODS];
|
||||
enum ssh_key_exchange_e kex_type;
|
||||
enum ssh_mac_e mac_type; /* Mac operations to use for key gen */
|
||||
};
|
||||
|
||||
struct ssh_cipher_struct {
|
||||
const char *name; /* ssh name of the algorithm */
|
||||
unsigned int blocksize; /* blocksize of the algo */
|
||||
unsigned int keylen; /* length of the key structure */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_cipher_hd_t *key;
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
void *key; /* a key buffer allocated for the algo */
|
||||
void *IV;
|
||||
#endif
|
||||
unsigned int keysize; /* bytes of key used. != keylen */
|
||||
/* sets the new key for immediate use */
|
||||
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||
void (*cbc_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
void (*cbc_decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
};
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
#endif /* _CRYPTO_H_ */
|
55
libssh/include/libssh/dh.h
Normal file
55
libssh/include/libssh/dh.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef DH_H_
|
||||
#define DH_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
void ssh_print_bignum(const char *which,bignum num);
|
||||
int dh_generate_e(ssh_session session);
|
||||
int dh_generate_f(ssh_session session);
|
||||
int dh_generate_x(ssh_session session);
|
||||
int dh_generate_y(ssh_session session);
|
||||
|
||||
int ssh_crypto_init(void);
|
||||
void ssh_crypto_finalize(void);
|
||||
|
||||
ssh_string dh_get_e(ssh_session session);
|
||||
ssh_string dh_get_f(ssh_session session);
|
||||
int dh_import_f(ssh_session session,ssh_string f_string);
|
||||
int dh_import_e(ssh_session session, ssh_string e_string);
|
||||
void dh_import_pubkey(ssh_session session,ssh_string pubkey_string);
|
||||
int dh_build_k(ssh_session session);
|
||||
int ssh_client_dh_init(ssh_session session);
|
||||
int ssh_client_dh_reply(ssh_session session, ssh_buffer packet);
|
||||
|
||||
int make_sessionid(ssh_session session);
|
||||
/* add data for the final cookie */
|
||||
int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||
int hashbufout_add_cookie(ssh_session session);
|
||||
int generate_session_keys(ssh_session session);
|
||||
bignum make_string_bn(ssh_string string);
|
||||
ssh_string make_bignum_string(bignum num);
|
||||
|
||||
|
||||
#endif /* DH_H_ */
|
41
libssh/include/libssh/ecdh.h
Normal file
41
libssh/include/libssh/ecdh.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2011 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ECDH_H_
|
||||
#define ECDH_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
#ifdef HAVE_OPENSSL_ECDH_H
|
||||
|
||||
#define HAVE_ECDH
|
||||
|
||||
#endif /* HAVE_OPENSSL_ECDH_H */
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
||||
int ssh_client_ecdh_init(ssh_session session);
|
||||
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet);
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
#endif /* ECDH_H_ */
|
50
libssh/include/libssh/kex.h
Normal file
50
libssh/include/libssh/kex.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef KEX_H_
|
||||
#define KEX_H_
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
#define SSH_KEX_METHODS 10
|
||||
|
||||
struct ssh_kex_struct {
|
||||
unsigned char cookie[16];
|
||||
char *methods[SSH_KEX_METHODS];
|
||||
};
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
|
||||
#ifdef WITH_SSH1
|
||||
SSH_PACKET_CALLBACK(ssh_packet_publickey1);
|
||||
#endif
|
||||
|
||||
int ssh_send_kex(ssh_session session, int server_kex);
|
||||
void ssh_list_kex(ssh_session session, struct ssh_kex_struct *kex);
|
||||
int set_client_kex(ssh_session session);
|
||||
int ssh_kex_select_methods(ssh_session session);
|
||||
int verify_existing_algo(int algo, const char *name);
|
||||
char **space_tokenize(const char *chain);
|
||||
int ssh_get_kex1(ssh_session session);
|
||||
char *ssh_find_matching(const char *in_d, const char *what_d);
|
||||
const char *ssh_kex_get_supported_method(uint32_t algo);
|
||||
const char *ssh_kex_get_description(uint32_t algo);
|
||||
|
||||
#endif /* KEX_H_ */
|
56
libssh/include/libssh/keys.h
Normal file
56
libssh/include/libssh/keys.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef KEYS_H_
|
||||
#define KEYS_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/wrapper.h"
|
||||
|
||||
struct ssh_public_key_struct {
|
||||
int type;
|
||||
const char *type_c; /* Don't free it ! it is static */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa_pub;
|
||||
gcry_sexp_t rsa_pub;
|
||||
#elif HAVE_LIBCRYPTO
|
||||
DSA *dsa_pub;
|
||||
RSA *rsa_pub;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ssh_private_key_struct {
|
||||
int type;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa_priv;
|
||||
gcry_sexp_t rsa_priv;
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
DSA *dsa_priv;
|
||||
RSA *rsa_priv;
|
||||
#endif
|
||||
};
|
||||
|
||||
const char *ssh_type_to_char(int type);
|
||||
int ssh_type_from_name(const char *name);
|
||||
|
||||
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s);
|
||||
|
||||
#endif /* KEYS_H_ */
|
120
libssh/include/libssh/legacy.h
Normal file
120
libssh/include/libssh/legacy.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Since libssh.h includes legacy.h, it's important that libssh.h is included
|
||||
* first. we don't define LEGACY_H now because we want it to be defined when
|
||||
* included from libssh.h
|
||||
* All function calls declared in this header are deprecated and meant to be
|
||||
* removed in future.
|
||||
*/
|
||||
|
||||
#ifndef LEGACY_H_
|
||||
#define LEGACY_H_
|
||||
|
||||
typedef struct ssh_private_key_struct* ssh_private_key;
|
||||
typedef struct ssh_public_key_struct* ssh_public_key;
|
||||
|
||||
LIBSSH_API int ssh_auth_list(ssh_session session);
|
||||
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
|
||||
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
|
||||
#ifndef _WIN32
|
||||
LIBSSH_API int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
|
||||
ssh_public_key publickey);
|
||||
#endif
|
||||
LIBSSH_API int ssh_userauth_autopubkey(ssh_session session, const char *passphrase);
|
||||
LIBSSH_API int ssh_userauth_privatekey_file(ssh_session session, const char *username,
|
||||
const char *filename, const char *passphrase);
|
||||
|
||||
LIBSSH_API void buffer_free(ssh_buffer buffer);
|
||||
LIBSSH_API void *buffer_get(ssh_buffer buffer);
|
||||
LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer);
|
||||
LIBSSH_API ssh_buffer buffer_new(void);
|
||||
|
||||
LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
|
||||
LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows);
|
||||
LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms);
|
||||
LIBSSH_API int channel_close(ssh_channel channel);
|
||||
LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port);
|
||||
LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
LIBSSH_API void channel_free(ssh_channel channel);
|
||||
LIBSSH_API int channel_get_exit_status(ssh_channel channel);
|
||||
LIBSSH_API ssh_session channel_get_session(ssh_channel channel);
|
||||
LIBSSH_API int channel_is_closed(ssh_channel channel);
|
||||
LIBSSH_API int channel_is_eof(ssh_channel channel);
|
||||
LIBSSH_API int channel_is_open(ssh_channel channel);
|
||||
LIBSSH_API ssh_channel channel_new(ssh_session session);
|
||||
LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport);
|
||||
LIBSSH_API int channel_open_session(ssh_channel channel);
|
||||
LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr);
|
||||
LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
|
||||
|
||||
LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
||||
int is_stderr);
|
||||
|
||||
LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
int is_stderr);
|
||||
LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value);
|
||||
LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd);
|
||||
LIBSSH_API int channel_request_pty(ssh_channel channel);
|
||||
LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term,
|
||||
int cols, int rows);
|
||||
LIBSSH_API int channel_request_shell(ssh_channel channel);
|
||||
LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum);
|
||||
LIBSSH_API int channel_request_sftp(ssh_channel channel);
|
||||
LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem);
|
||||
LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
|
||||
const char *cookie, int screen_number);
|
||||
LIBSSH_API int channel_send_eof(ssh_channel channel);
|
||||
LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
||||
timeval * timeout);
|
||||
LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
|
||||
LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||
|
||||
LIBSSH_API void privatekey_free(ssh_private_key prv);
|
||||
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
|
||||
int type, const char *passphrase);
|
||||
LIBSSH_API void publickey_free(ssh_public_key key);
|
||||
LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
|
||||
ssh_string pubkey, int type);
|
||||
LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
|
||||
int *type);
|
||||
LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
|
||||
LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
|
||||
LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
|
||||
ssh_string *publickey, int *type);
|
||||
LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
|
||||
|
||||
LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
|
||||
|
||||
LIBSSH_API ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype);
|
||||
LIBSSH_API ssh_public_key ssh_message_auth_publickey(ssh_message msg);
|
||||
|
||||
LIBSSH_API void string_burn(ssh_string str);
|
||||
LIBSSH_API ssh_string string_copy(ssh_string str);
|
||||
LIBSSH_API void *string_data(ssh_string str);
|
||||
LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len);
|
||||
LIBSSH_API void string_free(ssh_string str);
|
||||
LIBSSH_API ssh_string string_from_char(const char *what);
|
||||
LIBSSH_API size_t string_len(ssh_string str);
|
||||
LIBSSH_API ssh_string string_new(size_t size);
|
||||
LIBSSH_API char *string_to_char(ssh_string str);
|
||||
|
||||
#endif /* LEGACY_H_ */
|
86
libssh/include/libssh/libcrypto.h
Normal file
86
libssh/include/libssh/libcrypto.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef LIBCRYPTO_H_
|
||||
#define LIBCRYPTO_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/hmac.h>
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
|
||||
typedef SHA_CTX* SHACTX;
|
||||
typedef SHA256_CTX* SHA256CTX;
|
||||
typedef MD5_CTX* MD5CTX;
|
||||
typedef HMAC_CTX* HMACCTX;
|
||||
|
||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||
#ifdef MD5_DIGEST_LEN
|
||||
#undef MD5_DIGEST_LEN
|
||||
#endif
|
||||
#define MD5_DIGEST_LEN MD5_DIGEST_LENGTH
|
||||
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||
#endif
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#define OPENSSL_0_9_7b 0x0090702fL
|
||||
#if (OPENSSL_VERSION_NUMBER <= OPENSSL_0_9_7b)
|
||||
#define BROKEN_AES_CTR
|
||||
#endif
|
||||
typedef BIGNUM* bignum;
|
||||
typedef BN_CTX* bignum_CTX;
|
||||
|
||||
#define bignum_new() BN_new()
|
||||
#define bignum_free(num) BN_clear_free(num)
|
||||
#define bignum_set_word(bn,n) BN_set_word(bn,n)
|
||||
#define bignum_bin2bn(bn,datalen,data) BN_bin2bn(bn,datalen,data)
|
||||
#define bignum_bn2dec(num) BN_bn2dec(num)
|
||||
#define bignum_dec2bn(bn,data) BN_dec2bn(data,bn)
|
||||
#define bignum_bn2hex(num) BN_bn2hex(num)
|
||||
#define bignum_rand(rnd, bits, top, bottom) BN_rand(rnd,bits,top,bottom)
|
||||
#define bignum_ctx_new() BN_CTX_new()
|
||||
#define bignum_ctx_free(num) BN_CTX_free(num)
|
||||
#define bignum_mod_exp(dest,generator,exp,modulo,ctx) BN_mod_exp(dest,generator,exp,modulo,ctx)
|
||||
#define bignum_num_bytes(num) BN_num_bytes(num)
|
||||
#define bignum_num_bits(num) BN_num_bits(num)
|
||||
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num,bit)
|
||||
#define bignum_bn2bin(num,ptr) BN_bn2bin(num,ptr)
|
||||
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
|
||||
|
||||
SHA256CTX sha256_init(void);
|
||||
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
|
||||
void sha256_final(unsigned char *md, SHA256CTX c);
|
||||
|
||||
struct ssh_cipher_struct *ssh_get_ciphertab(void);
|
||||
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
||||
#endif /* LIBCRYPTO_H_ */
|
71
libssh/include/libssh/libgcrypt.h
Normal file
71
libssh/include/libssh/libgcrypt.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef LIBGCRYPT_H_
|
||||
#define LIBGCRYPT_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
|
||||
#include <gcrypt.h>
|
||||
typedef gcry_md_hd_t SHACTX;
|
||||
typedef gcry_md_hd_t MD5CTX;
|
||||
typedef gcry_md_hd_t HMACCTX;
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||
#define MD5_DIGEST_LEN 16
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
|
||||
#ifndef EVP_MAX_MD_SIZE
|
||||
#define EVP_MAX_MD_SIZE 36
|
||||
#endif
|
||||
|
||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||
|
||||
typedef gcry_mpi_t bignum;
|
||||
|
||||
/* missing gcrypt functions */
|
||||
int my_gcry_dec2bn(bignum *bn, const char *data);
|
||||
char *my_gcry_bn2dec(bignum bn);
|
||||
|
||||
#define bignum_new() gcry_mpi_new(0)
|
||||
#define bignum_free(num) gcry_mpi_release(num)
|
||||
#define bignum_set_word(bn,n) gcry_mpi_set_ui(bn,n)
|
||||
#define bignum_bin2bn(bn,datalen,data) gcry_mpi_scan(data,GCRYMPI_FMT_USG,bn,datalen,NULL)
|
||||
#define bignum_bn2dec(num) my_gcry_bn2dec(num)
|
||||
#define bignum_dec2bn(num, data) my_gcry_dec2bn(data, num)
|
||||
#define bignum_bn2hex(num,data) gcry_mpi_aprint(GCRYMPI_FMT_HEX,data,NULL,num)
|
||||
#define bignum_hex2bn(num,datalen,data) gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,datalen,NULL)
|
||||
#define bignum_rand(num,bits) gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
|
||||
#define bignum_mod_exp(dest,generator,exp,modulo) gcry_mpi_powm(dest,generator,exp,modulo)
|
||||
#define bignum_num_bits(num) gcry_mpi_get_nbits(num)
|
||||
#define bignum_num_bytes(num) ((gcry_mpi_get_nbits(num)+7)/8)
|
||||
#define bignum_is_bit_set(num,bit) gcry_mpi_test_bit(num,bit)
|
||||
#define bignum_bn2bin(num,datalen,data) gcry_mpi_print(GCRYMPI_FMT_USG,data,datalen,NULL,num)
|
||||
#define bignum_cmp(num1,num2) gcry_mpi_cmp(num1,num2)
|
||||
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
|
||||
struct ssh_cipher_struct *ssh_get_ciphertab(void);
|
||||
|
||||
#endif /* LIBGCRYPT_H_ */
|
596
libssh/include/libssh/libssh.h
Normal file
596
libssh/include/libssh/libssh.h
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LIBSSH_H
|
||||
#define _LIBSSH_H
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#ifdef LIBSSH_STATIC
|
||||
#define LIBSSH_API
|
||||
#else
|
||||
#ifdef LIBSSH_EXPORTS
|
||||
#ifdef __GNUC__
|
||||
#define LIBSSH_API __attribute__((dllexport))
|
||||
#else
|
||||
#define LIBSSH_API __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define LIBSSH_API __attribute__((dllimport))
|
||||
#else
|
||||
#define LIBSSH_API __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#if __GNUC__ >= 4 && !defined(__OS2__)
|
||||
#define LIBSSH_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define LIBSSH_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Visual Studio hasn't inttypes.h so it doesn't know uint32_t */
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef int mode_t;
|
||||
#else /* _MSC_VER */
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else /* _WIN32 */
|
||||
#include <sys/select.h> /* for fd_set * */
|
||||
#include <netdb.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define SSH_STRINGIFY(s) SSH_TOSTRING(s)
|
||||
#define SSH_TOSTRING(s) #s
|
||||
|
||||
/* libssh version macros */
|
||||
#define SSH_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
|
||||
#define SSH_VERSION_DOT(a, b, c) a ##.## b ##.## c
|
||||
#define SSH_VERSION(a, b, c) SSH_VERSION_DOT(a, b, c)
|
||||
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 6
|
||||
#define LIBSSH_VERSION_MICRO 0
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
|
||||
/* GCC have printf type attribute check. */
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE(a,b)
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define SSH_DEPRECATED __attribute__ ((deprecated))
|
||||
#else
|
||||
#define SSH_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ssh_agent_struct* ssh_agent;
|
||||
typedef struct ssh_buffer_struct* ssh_buffer;
|
||||
typedef struct ssh_channel_struct* ssh_channel;
|
||||
typedef struct ssh_message_struct* ssh_message;
|
||||
typedef struct ssh_pcap_file_struct* ssh_pcap_file;
|
||||
typedef struct ssh_key_struct* ssh_key;
|
||||
typedef struct ssh_scp_struct* ssh_scp;
|
||||
typedef struct ssh_session_struct* ssh_session;
|
||||
typedef struct ssh_string_struct* ssh_string;
|
||||
typedef struct ssh_event_struct* ssh_event;
|
||||
|
||||
/* Socket type */
|
||||
#ifdef _WIN32
|
||||
#ifndef socket_t
|
||||
typedef SOCKET socket_t;
|
||||
#endif /* socket_t */
|
||||
#else /* _WIN32 */
|
||||
#ifndef socket_t
|
||||
typedef int socket_t;
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define SSH_INVALID_SOCKET ((socket_t) -1)
|
||||
|
||||
/* the offsets of methods */
|
||||
enum ssh_kex_types_e {
|
||||
SSH_KEX=0,
|
||||
SSH_HOSTKEYS,
|
||||
SSH_CRYPT_C_S,
|
||||
SSH_CRYPT_S_C,
|
||||
SSH_MAC_C_S,
|
||||
SSH_MAC_S_C,
|
||||
SSH_COMP_C_S,
|
||||
SSH_COMP_S_C,
|
||||
SSH_LANG_C_S,
|
||||
SSH_LANG_S_C
|
||||
};
|
||||
|
||||
#define SSH_CRYPT 2
|
||||
#define SSH_MAC 3
|
||||
#define SSH_COMP 4
|
||||
#define SSH_LANG 5
|
||||
|
||||
enum ssh_auth_e {
|
||||
SSH_AUTH_SUCCESS=0,
|
||||
SSH_AUTH_DENIED,
|
||||
SSH_AUTH_PARTIAL,
|
||||
SSH_AUTH_INFO,
|
||||
SSH_AUTH_AGAIN,
|
||||
SSH_AUTH_ERROR=-1
|
||||
};
|
||||
|
||||
/* auth flags */
|
||||
#define SSH_AUTH_METHOD_UNKNOWN 0
|
||||
#define SSH_AUTH_METHOD_NONE 0x0001
|
||||
#define SSH_AUTH_METHOD_PASSWORD 0x0002
|
||||
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004
|
||||
#define SSH_AUTH_METHOD_HOSTBASED 0x0008
|
||||
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010
|
||||
|
||||
/* messages */
|
||||
enum ssh_requests_e {
|
||||
SSH_REQUEST_AUTH=1,
|
||||
SSH_REQUEST_CHANNEL_OPEN,
|
||||
SSH_REQUEST_CHANNEL,
|
||||
SSH_REQUEST_SERVICE,
|
||||
SSH_REQUEST_GLOBAL
|
||||
};
|
||||
|
||||
enum ssh_channel_type_e {
|
||||
SSH_CHANNEL_UNKNOWN=0,
|
||||
SSH_CHANNEL_SESSION,
|
||||
SSH_CHANNEL_DIRECT_TCPIP,
|
||||
SSH_CHANNEL_FORWARDED_TCPIP,
|
||||
SSH_CHANNEL_X11
|
||||
};
|
||||
|
||||
enum ssh_channel_requests_e {
|
||||
SSH_CHANNEL_REQUEST_UNKNOWN=0,
|
||||
SSH_CHANNEL_REQUEST_PTY,
|
||||
SSH_CHANNEL_REQUEST_EXEC,
|
||||
SSH_CHANNEL_REQUEST_SHELL,
|
||||
SSH_CHANNEL_REQUEST_ENV,
|
||||
SSH_CHANNEL_REQUEST_SUBSYSTEM,
|
||||
SSH_CHANNEL_REQUEST_WINDOW_CHANGE,
|
||||
SSH_CHANNEL_REQUEST_X11
|
||||
};
|
||||
|
||||
enum ssh_global_requests_e {
|
||||
SSH_GLOBAL_REQUEST_UNKNOWN=0,
|
||||
SSH_GLOBAL_REQUEST_TCPIP_FORWARD,
|
||||
SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD,
|
||||
};
|
||||
|
||||
enum ssh_publickey_state_e {
|
||||
SSH_PUBLICKEY_STATE_ERROR=-1,
|
||||
SSH_PUBLICKEY_STATE_NONE=0,
|
||||
SSH_PUBLICKEY_STATE_VALID=1,
|
||||
SSH_PUBLICKEY_STATE_WRONG=2
|
||||
};
|
||||
|
||||
/* status flags */
|
||||
#define SSH_CLOSED 0x01
|
||||
#define SSH_READ_PENDING 0x02
|
||||
#define SSH_CLOSED_ERROR 0x04
|
||||
#define SSH_WRITE_PENDING 0x08
|
||||
|
||||
enum ssh_server_known_e {
|
||||
SSH_SERVER_ERROR=-1,
|
||||
SSH_SERVER_NOT_KNOWN=0,
|
||||
SSH_SERVER_KNOWN_OK,
|
||||
SSH_SERVER_KNOWN_CHANGED,
|
||||
SSH_SERVER_FOUND_OTHER,
|
||||
SSH_SERVER_FILE_NOT_FOUND
|
||||
};
|
||||
|
||||
#ifndef MD5_DIGEST_LEN
|
||||
#define MD5_DIGEST_LEN 16
|
||||
#endif
|
||||
/* errors */
|
||||
|
||||
enum ssh_error_types_e {
|
||||
SSH_NO_ERROR=0,
|
||||
SSH_REQUEST_DENIED,
|
||||
SSH_FATAL,
|
||||
SSH_EINTR
|
||||
};
|
||||
|
||||
/* some types for keys */
|
||||
enum ssh_keytypes_e{
|
||||
SSH_KEYTYPE_UNKNOWN=0,
|
||||
SSH_KEYTYPE_DSS=1,
|
||||
SSH_KEYTYPE_RSA,
|
||||
SSH_KEYTYPE_RSA1,
|
||||
SSH_KEYTYPE_ECDSA
|
||||
};
|
||||
|
||||
enum ssh_keycmp_e {
|
||||
SSH_KEY_CMP_PUBLIC = 0,
|
||||
SSH_KEY_CMP_PRIVATE
|
||||
};
|
||||
|
||||
/* Error return codes */
|
||||
#define SSH_OK 0 /* No error */
|
||||
#define SSH_ERROR -1 /* Error of some kind */
|
||||
#define SSH_AGAIN -2 /* The nonblocking call must be repeated */
|
||||
#define SSH_EOF -127 /* We have already a eof */
|
||||
|
||||
/**
|
||||
* @addtogroup libssh_log
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
enum {
|
||||
/** No logging at all
|
||||
*/
|
||||
SSH_LOG_NOLOG=0,
|
||||
/** Only warnings
|
||||
*/
|
||||
SSH_LOG_WARNING,
|
||||
/** High level protocol information
|
||||
*/
|
||||
SSH_LOG_PROTOCOL,
|
||||
/** Lower level protocol infomations, packet level
|
||||
*/
|
||||
SSH_LOG_PACKET,
|
||||
/** Every function path
|
||||
*/
|
||||
SSH_LOG_FUNCTIONS
|
||||
};
|
||||
/** @} */
|
||||
#define SSH_LOG_RARE SSH_LOG_WARNING
|
||||
|
||||
/**
|
||||
* @name Logging levels
|
||||
*
|
||||
* @brief Debug levels for logging.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** No logging at all */
|
||||
#define SSH_LOG_NONE 0
|
||||
/** Show only warnings */
|
||||
#define SSH_LOG_WARN 1
|
||||
/** Get some information what's going on */
|
||||
#define SSH_LOG_INFO 2
|
||||
/** Get detailed debuging information **/
|
||||
#define SSH_LOG_DEBUG 3
|
||||
/** Get trace output, packet information, ... */
|
||||
#define SSH_LOG_TRACE 4
|
||||
|
||||
/** @} */
|
||||
|
||||
enum ssh_options_e {
|
||||
SSH_OPTIONS_HOST,
|
||||
SSH_OPTIONS_PORT,
|
||||
SSH_OPTIONS_PORT_STR,
|
||||
SSH_OPTIONS_FD,
|
||||
SSH_OPTIONS_USER,
|
||||
SSH_OPTIONS_SSH_DIR,
|
||||
SSH_OPTIONS_IDENTITY,
|
||||
SSH_OPTIONS_ADD_IDENTITY,
|
||||
SSH_OPTIONS_KNOWNHOSTS,
|
||||
SSH_OPTIONS_TIMEOUT,
|
||||
SSH_OPTIONS_TIMEOUT_USEC,
|
||||
SSH_OPTIONS_SSH1,
|
||||
SSH_OPTIONS_SSH2,
|
||||
SSH_OPTIONS_LOG_VERBOSITY,
|
||||
SSH_OPTIONS_LOG_VERBOSITY_STR,
|
||||
SSH_OPTIONS_CIPHERS_C_S,
|
||||
SSH_OPTIONS_CIPHERS_S_C,
|
||||
SSH_OPTIONS_COMPRESSION_C_S,
|
||||
SSH_OPTIONS_COMPRESSION_S_C,
|
||||
SSH_OPTIONS_PROXYCOMMAND,
|
||||
SSH_OPTIONS_BINDADDR,
|
||||
SSH_OPTIONS_STRICTHOSTKEYCHECK,
|
||||
SSH_OPTIONS_COMPRESSION,
|
||||
SSH_OPTIONS_COMPRESSION_LEVEL,
|
||||
SSH_OPTIONS_KEY_EXCHANGE,
|
||||
SSH_OPTIONS_HOSTKEYS
|
||||
};
|
||||
|
||||
enum {
|
||||
/** Code is going to write/create remote files */
|
||||
SSH_SCP_WRITE,
|
||||
/** Code is going to read remote files */
|
||||
SSH_SCP_READ,
|
||||
SSH_SCP_RECURSIVE=0x10
|
||||
};
|
||||
|
||||
enum ssh_scp_request_types {
|
||||
/** A new directory is going to be pulled */
|
||||
SSH_SCP_REQUEST_NEWDIR=1,
|
||||
/** A new file is going to be pulled */
|
||||
SSH_SCP_REQUEST_NEWFILE,
|
||||
/** End of requests */
|
||||
SSH_SCP_REQUEST_EOF,
|
||||
/** End of directory */
|
||||
SSH_SCP_REQUEST_ENDDIR,
|
||||
/** Warning received */
|
||||
SSH_SCP_REQUEST_WARNING
|
||||
};
|
||||
|
||||
LIBSSH_API int ssh_blocking_flush(ssh_session session, int timeout);
|
||||
LIBSSH_API ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms);
|
||||
LIBSSH_API int ssh_channel_change_pty_size(ssh_channel channel,int cols,int rows);
|
||||
LIBSSH_API int ssh_channel_close(ssh_channel channel);
|
||||
LIBSSH_API void ssh_channel_free(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
|
||||
LIBSSH_API ssh_session ssh_channel_get_session(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_is_closed(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_is_open(ssh_channel channel);
|
||||
LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
|
||||
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport);
|
||||
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
int is_stderr);
|
||||
LIBSSH_API int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value);
|
||||
LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd);
|
||||
LIBSSH_API int ssh_channel_request_pty(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_request_pty_size(ssh_channel channel, const char *term,
|
||||
int cols, int rows);
|
||||
LIBSSH_API int ssh_channel_request_shell(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_request_send_signal(ssh_channel channel, const char *signum);
|
||||
LIBSSH_API int ssh_channel_request_sftp(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_request_subsystem(ssh_channel channel, const char *subsystem);
|
||||
LIBSSH_API int ssh_channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
|
||||
const char *cookie, int screen_number);
|
||||
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
||||
timeval * timeout);
|
||||
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
|
||||
LIBSSH_API int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||
LIBSSH_API uint32_t ssh_channel_window_size(ssh_channel channel);
|
||||
|
||||
LIBSSH_API char *ssh_basename (const char *path);
|
||||
LIBSSH_API void ssh_clean_pubkey_hash(unsigned char **hash);
|
||||
LIBSSH_API int ssh_connect(ssh_session session);
|
||||
LIBSSH_API const char *ssh_copyright(void);
|
||||
LIBSSH_API void ssh_disconnect(ssh_session session);
|
||||
LIBSSH_API char *ssh_dirname (const char *path);
|
||||
LIBSSH_API int ssh_finalize(void);
|
||||
LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms);
|
||||
LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
||||
LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
LIBSSH_API void ssh_free(ssh_session session);
|
||||
LIBSSH_API const char *ssh_get_disconnect_message(ssh_session session);
|
||||
LIBSSH_API const char *ssh_get_error(void *error);
|
||||
LIBSSH_API int ssh_get_error_code(void *error);
|
||||
LIBSSH_API socket_t ssh_get_fd(ssh_session session);
|
||||
LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len);
|
||||
LIBSSH_API char *ssh_get_issue_banner(ssh_session session);
|
||||
LIBSSH_API int ssh_get_openssh_version(ssh_session session);
|
||||
LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
|
||||
LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash);
|
||||
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
||||
LIBSSH_API int ssh_get_version(ssh_session session);
|
||||
LIBSSH_API int ssh_get_status(ssh_session session);
|
||||
LIBSSH_API int ssh_init(void);
|
||||
LIBSSH_API int ssh_is_blocking(ssh_session session);
|
||||
LIBSSH_API int ssh_is_connected(ssh_session session);
|
||||
LIBSSH_API int ssh_is_server_known(ssh_session session);
|
||||
|
||||
/* legacy */
|
||||
LIBSSH_API void ssh_log(ssh_session session,
|
||||
int prioriry,
|
||||
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||
|
||||
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
|
||||
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
|
||||
LIBSSH_API void ssh_message_free(ssh_message msg);
|
||||
LIBSSH_API ssh_message ssh_message_get(ssh_session session);
|
||||
LIBSSH_API int ssh_message_subtype(ssh_message msg);
|
||||
LIBSSH_API int ssh_message_type(ssh_message msg);
|
||||
LIBSSH_API int ssh_mkdir (const char *pathname, mode_t mode);
|
||||
LIBSSH_API ssh_session ssh_new(void);
|
||||
|
||||
LIBSSH_API int ssh_options_copy(ssh_session src, ssh_session *dest);
|
||||
LIBSSH_API int ssh_options_getopt(ssh_session session, int *argcptr, char **argv);
|
||||
LIBSSH_API int ssh_options_parse_config(ssh_session session, const char *filename);
|
||||
LIBSSH_API int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
const void *value);
|
||||
LIBSSH_API int ssh_options_get(ssh_session session, enum ssh_options_e type,
|
||||
char **value);
|
||||
LIBSSH_API int ssh_options_get_port(ssh_session session, unsigned int * port_target);
|
||||
LIBSSH_API int ssh_pcap_file_close(ssh_pcap_file pcap);
|
||||
LIBSSH_API void ssh_pcap_file_free(ssh_pcap_file pcap);
|
||||
LIBSSH_API ssh_pcap_file ssh_pcap_file_new(void);
|
||||
LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
||||
|
||||
/**
|
||||
* @brief SSH authentication callback.
|
||||
*
|
||||
* @param prompt Prompt to be displayed.
|
||||
* @param buf Buffer to save the password. You should null-terminate it.
|
||||
* @param len Length of the buffer.
|
||||
* @param echo Enable or disable the echo of what you type.
|
||||
* @param verify Should the password be verified?
|
||||
* @param userdata Userdata to be passed to the callback function. Useful
|
||||
* for GUI applications.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
|
||||
int echo, int verify, void *userdata);
|
||||
|
||||
LIBSSH_API ssh_key ssh_key_new(void);
|
||||
LIBSSH_API void ssh_key_free (ssh_key key);
|
||||
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
|
||||
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);
|
||||
LIBSSH_API enum ssh_keytypes_e ssh_key_type_from_name(const char *name);
|
||||
LIBSSH_API int ssh_key_is_public(const ssh_key k);
|
||||
LIBSSH_API int ssh_key_is_private(const ssh_key k);
|
||||
LIBSSH_API int ssh_key_cmp(const ssh_key k1,
|
||||
const ssh_key k2,
|
||||
enum ssh_keycmp_e what);
|
||||
|
||||
LIBSSH_API int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
||||
ssh_key *pkey);
|
||||
LIBSSH_API int ssh_pki_import_privkey_base64(const char *b64_key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data,
|
||||
ssh_key *pkey);
|
||||
LIBSSH_API int ssh_pki_import_privkey_file(const char *filename,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data,
|
||||
ssh_key *pkey);
|
||||
|
||||
LIBSSH_API int ssh_pki_import_pubkey_base64(const char *b64_key,
|
||||
enum ssh_keytypes_e type,
|
||||
ssh_key *pkey);
|
||||
LIBSSH_API int ssh_pki_import_pubkey_file(const char *filename,
|
||||
ssh_key *pkey);
|
||||
|
||||
LIBSSH_API int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey,
|
||||
ssh_key *pkey);
|
||||
LIBSSH_API int ssh_pki_export_pubkey_base64(const ssh_key key,
|
||||
char **b64_key);
|
||||
LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
|
||||
const char *filename);
|
||||
|
||||
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
|
||||
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
|
||||
LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_close(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
|
||||
LIBSSH_API void ssh_scp_free(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_init(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
|
||||
LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
|
||||
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
|
||||
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
|
||||
LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
|
||||
LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
|
||||
LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
|
||||
LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
|
||||
LIBSSH_API uint64_t ssh_scp_request_get_size64(ssh_scp scp);
|
||||
LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
|
||||
LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
|
||||
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
fd_set *readfds, struct timeval *timeout);
|
||||
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
|
||||
LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking);
|
||||
LIBSSH_API void ssh_set_fd_except(ssh_session session);
|
||||
LIBSSH_API void ssh_set_fd_toread(ssh_session session);
|
||||
LIBSSH_API void ssh_set_fd_towrite(ssh_session session);
|
||||
LIBSSH_API void ssh_silent_disconnect(ssh_session session);
|
||||
LIBSSH_API int ssh_set_pcap_file(ssh_session session, ssh_pcap_file pcapfile);
|
||||
|
||||
/* USERAUTH */
|
||||
LIBSSH_API int ssh_userauth_none(ssh_session session, const char *username);
|
||||
LIBSSH_API int ssh_userauth_list(ssh_session session, const char *username);
|
||||
LIBSSH_API int ssh_userauth_try_publickey(ssh_session session,
|
||||
const char *username,
|
||||
const ssh_key pubkey);
|
||||
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
|
||||
const char *username,
|
||||
const ssh_key privkey);
|
||||
#ifndef _WIN32
|
||||
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
||||
const char *username);
|
||||
#endif
|
||||
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
||||
const char *username,
|
||||
const char *passphrase);
|
||||
LIBSSH_API int ssh_userauth_password(ssh_session session,
|
||||
const char *username,
|
||||
const char *password);
|
||||
|
||||
LIBSSH_API int ssh_userauth_kbdint(ssh_session session, const char *user, const char *submethods);
|
||||
LIBSSH_API const char *ssh_userauth_kbdint_getinstruction(ssh_session session);
|
||||
LIBSSH_API const char *ssh_userauth_kbdint_getname(ssh_session session);
|
||||
LIBSSH_API int ssh_userauth_kbdint_getnprompts(ssh_session session);
|
||||
LIBSSH_API const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i, char *echo);
|
||||
LIBSSH_API int ssh_userauth_kbdint_getnanswers(ssh_session session);
|
||||
LIBSSH_API const char *ssh_userauth_kbdint_getanswer(ssh_session session, unsigned int i);
|
||||
LIBSSH_API int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i,
|
||||
const char *answer);
|
||||
LIBSSH_API const char *ssh_version(int req_version);
|
||||
LIBSSH_API int ssh_write_knownhost(ssh_session session);
|
||||
|
||||
LIBSSH_API void ssh_string_burn(ssh_string str);
|
||||
LIBSSH_API ssh_string ssh_string_copy(ssh_string str);
|
||||
LIBSSH_API void *ssh_string_data(ssh_string str);
|
||||
LIBSSH_API int ssh_string_fill(ssh_string str, const void *data, size_t len);
|
||||
LIBSSH_API void ssh_string_free(ssh_string str);
|
||||
LIBSSH_API ssh_string ssh_string_from_char(const char *what);
|
||||
LIBSSH_API size_t ssh_string_len(ssh_string str);
|
||||
LIBSSH_API ssh_string ssh_string_new(size_t size);
|
||||
LIBSSH_API const char *ssh_string_get_char(ssh_string str);
|
||||
LIBSSH_API char *ssh_string_to_char(ssh_string str);
|
||||
LIBSSH_API void ssh_string_free_char(char *s);
|
||||
|
||||
LIBSSH_API int ssh_getpass(const char *prompt, char *buf, size_t len, int echo,
|
||||
int verify);
|
||||
|
||||
|
||||
typedef int (*ssh_event_callback)(socket_t fd, int revents, void *userdata);
|
||||
|
||||
LIBSSH_API ssh_event ssh_event_new(void);
|
||||
LIBSSH_API int ssh_event_add_fd(ssh_event event, socket_t fd, short events,
|
||||
ssh_event_callback cb, void *userdata);
|
||||
LIBSSH_API int ssh_event_add_session(ssh_event event, ssh_session session);
|
||||
LIBSSH_API int ssh_event_dopoll(ssh_event event, int timeout);
|
||||
LIBSSH_API int ssh_event_remove_fd(ssh_event event, socket_t fd);
|
||||
LIBSSH_API int ssh_event_remove_session(ssh_event event, ssh_session session);
|
||||
LIBSSH_API void ssh_event_free(ssh_event event);
|
||||
LIBSSH_API const char* ssh_get_serverbanner(ssh_session session);
|
||||
|
||||
#ifndef LIBSSH_LEGACY_0_4
|
||||
#include "libssh/legacy.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _LIBSSH_H */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
596
libssh/include/libssh/libsshpp.hpp
Normal file
596
libssh/include/libssh/libsshpp.hpp
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef LIBSSHPP_HPP_
|
||||
#define LIBSSHPP_HPP_
|
||||
|
||||
/**
|
||||
* @defgroup ssh_cpp The libssh C++ wrapper
|
||||
*
|
||||
* The C++ bindings for libssh are completely embedded in a single .hpp file, and
|
||||
* this for two reasons:
|
||||
* - C++ is hard to keep binary compatible, C is easy. We try to keep libssh C version
|
||||
* as much as possible binary compatible between releases, while this would be hard for
|
||||
* C++. If you compile your program with these headers, you will only link to the C version
|
||||
* of libssh which will be kept ABI compatible. No need to recompile your C++ program
|
||||
* each time a new binary-compatible version of libssh is out
|
||||
* - Most of the functions in this file are really short and are probably worth the "inline"
|
||||
* linking mode, which the compiler can decide to do in some case. There would be nearly no
|
||||
* performance penalty of using the wrapper rather than native calls.
|
||||
*
|
||||
* Please visit the documentation of ssh::Session and ssh::Channel
|
||||
* @see ssh::Session
|
||||
* @see ssh::Channel
|
||||
*
|
||||
* If you wish not to use C++ exceptions, please define SSH_NO_CPP_EXCEPTIONS:
|
||||
* @code
|
||||
* #define SSH_NO_CPP_EXCEPTIONS
|
||||
* #include <libssh/libsshpp.hpp>
|
||||
* @endcode
|
||||
* All functions will then return SSH_ERROR in case of error.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* do not use deprecated functions */
|
||||
#define LIBSSH_LEGACY_0_4
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace ssh {
|
||||
|
||||
class Channel;
|
||||
/** Some people do not like C++ exceptions. With this define, we give
|
||||
* the choice to use or not exceptions.
|
||||
* @brief if defined, disable C++ exceptions for libssh c++ wrapper
|
||||
*/
|
||||
#ifndef SSH_NO_CPP_EXCEPTIONS
|
||||
|
||||
/** @brief This class describes a SSH Exception object. This object can be thrown
|
||||
* by several SSH functions that interact with the network, and may fail because of
|
||||
* socket, protocol or memory errors.
|
||||
*/
|
||||
class SshException{
|
||||
public:
|
||||
SshException(ssh_session csession){
|
||||
code=ssh_get_error_code(csession);
|
||||
description=std::string(ssh_get_error(csession));
|
||||
}
|
||||
SshException(const SshException &e){
|
||||
code=e.code;
|
||||
description=e.description;
|
||||
}
|
||||
/** @brief returns the Error code
|
||||
* @returns SSH_FATAL Fatal error happened (not recoverable)
|
||||
* @returns SSH_REQUEST_DENIED Request was denied by remote host
|
||||
* @see ssh_get_error_code
|
||||
*/
|
||||
int getCode(){
|
||||
return code;
|
||||
}
|
||||
/** @brief returns the error message of the last exception
|
||||
* @returns pointer to a c string containing the description of error
|
||||
* @see ssh_get_error
|
||||
*/
|
||||
std::string getError(){
|
||||
return description;
|
||||
}
|
||||
private:
|
||||
int code;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief Macro to throw exception if there was an error
|
||||
*/
|
||||
#define ssh_throw(x) if((x)==SSH_ERROR) throw SshException(getCSession())
|
||||
#define ssh_throw_null(CSession,x) if((x)==NULL) throw SshException(CSession)
|
||||
#define void_throwable void
|
||||
#define return_throwable return
|
||||
|
||||
#else
|
||||
|
||||
/* No exception at all. All functions will return an error code instead
|
||||
* of an exception
|
||||
*/
|
||||
#define ssh_throw(x) if((x)==SSH_ERROR) return SSH_ERROR
|
||||
#define ssh_throw_null(CSession,x) if((x)==NULL) return NULL
|
||||
#define void_throwable int
|
||||
#define return_throwable return SSH_OK
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The ssh::Session class contains the state of a SSH connection.
|
||||
*/
|
||||
class Session {
|
||||
friend class Channel;
|
||||
public:
|
||||
Session(){
|
||||
c_session=ssh_new();
|
||||
}
|
||||
~Session(){
|
||||
ssh_free(c_session);
|
||||
c_session=NULL;
|
||||
}
|
||||
/** @brief sets an SSH session options
|
||||
* @param type Type of option
|
||||
* @param option cstring containing the value of option
|
||||
* @throws SshException on error
|
||||
* @see ssh_options_set
|
||||
*/
|
||||
void_throwable setOption(enum ssh_options_e type, const char *option){
|
||||
ssh_throw(ssh_options_set(c_session,type,option));
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief sets an SSH session options
|
||||
* @param type Type of option
|
||||
* @param option long integer containing the value of option
|
||||
* @throws SshException on error
|
||||
* @see ssh_options_set
|
||||
*/
|
||||
void_throwable setOption(enum ssh_options_e type, long int option){
|
||||
ssh_throw(ssh_options_set(c_session,type,&option));
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief sets an SSH session options
|
||||
* @param type Type of option
|
||||
* @param option void pointer containing the value of option
|
||||
* @throws SshException on error
|
||||
* @see ssh_options_set
|
||||
*/
|
||||
void_throwable setOption(enum ssh_options_e type, void *option){
|
||||
ssh_throw(ssh_options_set(c_session,type,option));
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief connects to the remote host
|
||||
* @throws SshException on error
|
||||
* @see ssh_connect
|
||||
*/
|
||||
void_throwable connect(){
|
||||
int ret=ssh_connect(c_session);
|
||||
ssh_throw(ret);
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief Authenticates automatically using public key
|
||||
* @throws SshException on error
|
||||
* @returns SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED
|
||||
* @see ssh_userauth_autopubkey
|
||||
*/
|
||||
int userauthPublickeyAuto(void){
|
||||
int ret=ssh_userauth_publickey_auto(c_session, NULL, NULL);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
/** @brief Authenticates using the "none" method. Prefer using autopubkey if
|
||||
* possible.
|
||||
* @throws SshException on error
|
||||
* @returns SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED
|
||||
* @see ssh_userauth_none
|
||||
* @see Session::userauthAutoPubkey
|
||||
*/
|
||||
int userauthNone(){
|
||||
int ret=ssh_userauth_none(c_session,NULL);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
/** @brief Authenticates using the password method.
|
||||
* @param[in] password password to use for authentication
|
||||
* @throws SshException on error
|
||||
* @returns SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED
|
||||
* @see ssh_userauth_password
|
||||
*/
|
||||
int userauthPassword(const char *password){
|
||||
int ret=ssh_userauth_password(c_session,NULL,password);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
/** @brief Try to authenticate using the publickey method.
|
||||
* @param[in] pubkey public key to use for authentication
|
||||
* @throws SshException on error
|
||||
* @returns SSH_AUTH_SUCCESS if the pubkey is accepted,
|
||||
* @returns SSH_AUTH_DENIED if the pubkey is denied
|
||||
* @see ssh_userauth_try_pubkey
|
||||
*/
|
||||
int userauthTryPublickey(ssh_key pubkey){
|
||||
int ret=ssh_userauth_try_publickey(c_session, NULL, pubkey);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
/** @brief Authenticates using the publickey method.
|
||||
* @param[in] privkey private key to use for authentication
|
||||
* @throws SshException on error
|
||||
* @returns SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED
|
||||
* @see ssh_userauth_pubkey
|
||||
*/
|
||||
int userauthPublickey(ssh_key privkey){
|
||||
int ret=ssh_userauth_publickey(c_session, NULL, privkey);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
int userauthPrivatekeyFile(const char *filename,
|
||||
const char *passphrase);
|
||||
/** @brief Returns the available authentication methods from the server
|
||||
* @throws SshException on error
|
||||
* @returns Bitfield of available methods.
|
||||
* @see ssh_userauth_list
|
||||
*/
|
||||
int getAuthList(){
|
||||
int ret=ssh_userauth_list(c_session, NULL);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
/** @brief Disconnects from the SSH server and closes connection
|
||||
* @see ssh_disconnect
|
||||
*/
|
||||
void disconnect(){
|
||||
ssh_disconnect(c_session);
|
||||
}
|
||||
/** @brief Returns the disconnect message from the server, if any
|
||||
* @returns pointer to the message, or NULL. Do not attempt to free
|
||||
* the pointer.
|
||||
*/
|
||||
const char *getDisconnectMessage(){
|
||||
const char *msg=ssh_get_disconnect_message(c_session);
|
||||
return msg;
|
||||
}
|
||||
/** @internal
|
||||
* @brief gets error message
|
||||
*/
|
||||
const char *getError(){
|
||||
return ssh_get_error(c_session);
|
||||
}
|
||||
/** @internal
|
||||
* @brief returns error code
|
||||
*/
|
||||
int getErrorCode(){
|
||||
return ssh_get_error_code(c_session);
|
||||
}
|
||||
/** @brief returns the file descriptor used for the communication
|
||||
* @returns the file descriptor
|
||||
* @warning if a proxycommand is used, this function will only return
|
||||
* one of the two file descriptors being used
|
||||
* @see ssh_get_fd
|
||||
*/
|
||||
socket_t getSocket(){
|
||||
return ssh_get_fd(c_session);
|
||||
}
|
||||
/** @brief gets the Issue banner from the ssh server
|
||||
* @returns the issue banner. This is generally a MOTD from server
|
||||
* @see ssh_get_issue_banner
|
||||
*/
|
||||
std::string getIssueBanner(){
|
||||
char *banner=ssh_get_issue_banner(c_session);
|
||||
std::string ret= std::string(banner);
|
||||
::free(banner);
|
||||
return ret;
|
||||
}
|
||||
/** @brief returns the OpenSSH version (server) if possible
|
||||
* @returns openssh version code
|
||||
* @see ssh_get_openssh_version
|
||||
*/
|
||||
int getOpensshVersion(){
|
||||
return ssh_get_openssh_version(c_session);
|
||||
}
|
||||
/** @brief returns the version of the SSH protocol being used
|
||||
* @returns the SSH protocol version
|
||||
* @see ssh_get_version
|
||||
*/
|
||||
int getVersion(){
|
||||
return ssh_get_version(c_session);
|
||||
}
|
||||
/** @brief verifies that the server is known
|
||||
* @throws SshException on error
|
||||
* @returns Integer value depending on the knowledge of the
|
||||
* server key
|
||||
* @see ssh_is_server_known
|
||||
*/
|
||||
int isServerKnown(){
|
||||
int ret=ssh_is_server_known(c_session);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
void log(int priority, const char *format, ...){
|
||||
char buffer[1024];
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
vsnprintf(buffer, sizeof(buffer), format, va);
|
||||
va_end(va);
|
||||
ssh_log(c_session,priority, "%s", buffer);
|
||||
}
|
||||
|
||||
/** @brief copies options from a session to another
|
||||
* @throws SshException on error
|
||||
* @see ssh_options_copy
|
||||
*/
|
||||
void_throwable optionsCopy(const Session &source){
|
||||
ssh_throw(ssh_options_copy(source.c_session,&c_session));
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief parses a configuration file for options
|
||||
* @throws SshException on error
|
||||
* @param[in] file configuration file name
|
||||
* @see ssh_options_parse_config
|
||||
*/
|
||||
void_throwable optionsParseConfig(const char *file){
|
||||
ssh_throw(ssh_options_parse_config(c_session,file));
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief silently disconnect from remote host
|
||||
* @see ssh_silent_disconnect
|
||||
*/
|
||||
void silentDisconnect(){
|
||||
ssh_silent_disconnect(c_session);
|
||||
}
|
||||
/** @brief Writes the known host file with current
|
||||
* host key
|
||||
* @throws SshException on error
|
||||
* @see ssh_write_knownhost
|
||||
*/
|
||||
int writeKnownhost(){
|
||||
int ret = ssh_write_knownhost(c_session);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @brief accept an incoming forward connection
|
||||
* @param[in] timeout_ms timeout for waiting, in ms
|
||||
* @returns new Channel pointer on the forward connection
|
||||
* @returns NULL in case of error
|
||||
* @warning you have to delete this pointer after use
|
||||
* @see ssh_channel_forward_accept
|
||||
* @see Session::listenForward
|
||||
*/
|
||||
Channel *acceptForward(int timeout_ms);
|
||||
/* acceptForward is implemented later in this file */
|
||||
|
||||
void_throwable cancelForward(const char *address, int port){
|
||||
int err=ssh_forward_cancel(c_session, address, port);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
void_throwable listenForward(const char *address, int port,
|
||||
int &boundport){
|
||||
int err=ssh_forward_listen(c_session, address, port, &boundport);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
private:
|
||||
ssh_session c_session;
|
||||
ssh_session getCSession(){
|
||||
return c_session;
|
||||
}
|
||||
/* No copy constructor, no = operator */
|
||||
Session(const Session &);
|
||||
Session& operator=(const Session &);
|
||||
};
|
||||
|
||||
/** @brief the ssh::Channel class describes the state of an SSH
|
||||
* channel.
|
||||
* @see ssh_channel
|
||||
*/
|
||||
class Channel {
|
||||
friend class Session;
|
||||
public:
|
||||
Channel(Session &session){
|
||||
channel=ssh_channel_new(session.getCSession());
|
||||
this->session=&session;
|
||||
}
|
||||
~Channel(){
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
}
|
||||
|
||||
/** @brief accept an incoming X11 connection
|
||||
* @param[in] timeout_ms timeout for waiting, in ms
|
||||
* @returns new Channel pointer on the X11 connection
|
||||
* @returns NULL in case of error
|
||||
* @warning you have to delete this pointer after use
|
||||
* @see ssh_channel_accept_x11
|
||||
* @see Channel::requestX11
|
||||
*/
|
||||
Channel *acceptX11(int timeout_ms){
|
||||
ssh_channel x11chan = ssh_channel_accept_x11(channel,timeout_ms);
|
||||
ssh_throw_null(getCSession(),x11chan);
|
||||
Channel *newchan = new Channel(getSession(),x11chan);
|
||||
return newchan;
|
||||
}
|
||||
/** @brief change the size of a pseudoterminal
|
||||
* @param[in] cols number of columns
|
||||
* @param[in] rows number of rows
|
||||
* @throws SshException on error
|
||||
* @see ssh_channel_change_pty_size
|
||||
*/
|
||||
void_throwable changePtySize(int cols, int rows){
|
||||
int err=ssh_channel_change_pty_size(channel,cols,rows);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
/** @brief closes a channel
|
||||
* @throws SshException on error
|
||||
* @see ssh_channel_close
|
||||
*/
|
||||
void_throwable close(){
|
||||
ssh_throw(ssh_channel_close(channel));
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
int getExitStatus(){
|
||||
return ssh_channel_get_exit_status(channel);
|
||||
}
|
||||
Session &getSession(){
|
||||
return *session;
|
||||
}
|
||||
/** @brief returns true if channel is in closed state
|
||||
* @see ssh_channel_is_closed
|
||||
*/
|
||||
bool isClosed(){
|
||||
return ssh_channel_is_closed(channel) != 0;
|
||||
}
|
||||
/** @brief returns true if channel is in EOF state
|
||||
* @see ssh_channel_is_eof
|
||||
*/
|
||||
bool isEof(){
|
||||
return ssh_channel_is_eof(channel) != 0;
|
||||
}
|
||||
/** @brief returns true if channel is in open state
|
||||
* @see ssh_channel_is_open
|
||||
*/
|
||||
bool isOpen(){
|
||||
return ssh_channel_is_open(channel) != 0;
|
||||
}
|
||||
int openForward(const char *remotehost, int remoteport,
|
||||
const char *sourcehost=NULL, int localport=0){
|
||||
int err=ssh_channel_open_forward(channel,remotehost,remoteport,
|
||||
sourcehost, localport);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
/* TODO: completely remove this ? */
|
||||
void_throwable openSession(){
|
||||
int err=ssh_channel_open_session(channel);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
int poll(bool is_stderr=false){
|
||||
int err=ssh_channel_poll(channel,is_stderr);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, bool is_stderr=false){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read(channel,dest,count,is_stderr);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int readNonblocking(void *dest, size_t count, bool is_stderr=false){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read_nonblocking(channel,dest,count,is_stderr);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
void_throwable requestEnv(const char *name, const char *value){
|
||||
int err=ssh_channel_request_env(channel,name,value);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
void_throwable requestExec(const char *cmd){
|
||||
int err=ssh_channel_request_exec(channel,cmd);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0){
|
||||
int err;
|
||||
if(term != NULL && cols != 0 && rows != 0)
|
||||
err=ssh_channel_request_pty_size(channel,term,cols,rows);
|
||||
else
|
||||
err=ssh_channel_request_pty(channel);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
void_throwable requestShell(){
|
||||
int err=ssh_channel_request_shell(channel);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
void_throwable requestSendSignal(const char *signum){
|
||||
int err=ssh_channel_request_send_signal(channel, signum);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
void_throwable requestSubsystem(const char *subsystem){
|
||||
int err=ssh_channel_request_subsystem(channel,subsystem);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
int requestX11(bool single_connection,
|
||||
const char *protocol, const char *cookie, int screen_number){
|
||||
int err=ssh_channel_request_x11(channel,single_connection,
|
||||
protocol, cookie, screen_number);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
void_throwable sendEof(){
|
||||
int err=ssh_channel_send_eof(channel);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
/** @brief Writes on a channel
|
||||
* @param data data to write.
|
||||
* @param len number of bytes to write.
|
||||
* @param is_stderr write should be done on the stderr channel (server only)
|
||||
* @returns number of bytes written
|
||||
* @throws SshException in case of error
|
||||
* @see channel_write
|
||||
* @see channel_write_stderr
|
||||
*/
|
||||
int write(const void *data, size_t len, bool is_stderr=false){
|
||||
int ret;
|
||||
if(is_stderr){
|
||||
ret=ssh_channel_write_stderr(channel,data,len);
|
||||
} else {
|
||||
ret=ssh_channel_write(channel,data,len);
|
||||
}
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
ssh_session getCSession(){
|
||||
return session->getCSession();
|
||||
}
|
||||
Channel (Session &session, ssh_channel c_channel){
|
||||
this->channel=c_channel;
|
||||
this->session=&session;
|
||||
}
|
||||
Session *session;
|
||||
ssh_channel channel;
|
||||
/* No copy and no = operator */
|
||||
Channel(const Channel &);
|
||||
Channel &operator=(const Channel &);
|
||||
};
|
||||
|
||||
|
||||
/* This code cannot be put inline due to references to Channel */
|
||||
Channel *Session::acceptForward(int timeout_ms){
|
||||
ssh_channel forward = ssh_forward_accept(c_session,
|
||||
timeout_ms);
|
||||
ssh_throw_null(c_session,forward);
|
||||
Channel *newchan = new Channel(*this,forward);
|
||||
return newchan;
|
||||
}
|
||||
|
||||
} // namespace ssh
|
||||
|
||||
/** @} */
|
||||
#endif /* LIBSSHPP_HPP_ */
|
104
libssh/include/libssh/messages.h
Normal file
104
libssh/include/libssh/messages.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MESSAGES_H_
|
||||
#define MESSAGES_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
struct ssh_auth_request {
|
||||
char *username;
|
||||
int method;
|
||||
char *password;
|
||||
struct ssh_key_struct *pubkey;
|
||||
char signature_state;
|
||||
char kbdint_response;
|
||||
};
|
||||
|
||||
struct ssh_channel_request_open {
|
||||
int type;
|
||||
uint32_t sender;
|
||||
uint32_t window;
|
||||
uint32_t packet_size;
|
||||
char *originator;
|
||||
uint16_t originator_port;
|
||||
char *destination;
|
||||
uint16_t destination_port;
|
||||
};
|
||||
|
||||
struct ssh_service_request {
|
||||
char *service;
|
||||
};
|
||||
|
||||
struct ssh_global_request {
|
||||
int type;
|
||||
uint8_t want_reply;
|
||||
char *bind_address;
|
||||
uint16_t bind_port;
|
||||
};
|
||||
|
||||
struct ssh_channel_request {
|
||||
int type;
|
||||
ssh_channel channel;
|
||||
uint8_t want_reply;
|
||||
/* pty-req type specifics */
|
||||
char *TERM;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pxwidth;
|
||||
uint32_t pxheight;
|
||||
ssh_string modes;
|
||||
|
||||
/* env type request */
|
||||
char *var_name;
|
||||
char *var_value;
|
||||
/* exec type request */
|
||||
char *command;
|
||||
/* subsystem */
|
||||
char *subsystem;
|
||||
|
||||
/* X11 */
|
||||
uint8_t x11_single_connection;
|
||||
const char *x11_auth_protocol;
|
||||
const char *x11_auth_cookie;
|
||||
uint32_t x11_screen_number;
|
||||
};
|
||||
|
||||
struct ssh_message_struct {
|
||||
ssh_session session;
|
||||
int type;
|
||||
struct ssh_auth_request auth_request;
|
||||
struct ssh_channel_request_open channel_request_open;
|
||||
struct ssh_channel_request channel_request;
|
||||
struct ssh_service_request service_request;
|
||||
struct ssh_global_request global_request;
|
||||
};
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_service_request);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_request);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_global_request);
|
||||
|
||||
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
|
||||
const char *request, uint8_t want_reply);
|
||||
void ssh_message_queue(ssh_session session, ssh_message message);
|
||||
ssh_message ssh_message_pop_head(ssh_session session);
|
||||
|
||||
#endif /* MESSAGES_H_ */
|
92
libssh/include/libssh/misc.h
Normal file
92
libssh/include/libssh/misc.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MISC_H_
|
||||
#define MISC_H_
|
||||
|
||||
/* in misc.c */
|
||||
/* gets the user home dir. */
|
||||
char *ssh_get_user_home_dir(void);
|
||||
char *ssh_get_local_username(void);
|
||||
int ssh_file_readaccess_ok(const char *file);
|
||||
|
||||
char *ssh_path_expand_tilde(const char *d);
|
||||
char *ssh_path_expand_escape(ssh_session session, const char *s);
|
||||
int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2);
|
||||
int ssh_is_ipaddr_v4(const char *str);
|
||||
int ssh_is_ipaddr(const char *str);
|
||||
|
||||
#ifndef HAVE_NTOHLL
|
||||
/* macro for byte ordering */
|
||||
uint64_t ntohll(uint64_t);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_HTONLL
|
||||
#define htonll(x) ntohll((x))
|
||||
#endif
|
||||
|
||||
/* list processing */
|
||||
|
||||
struct ssh_list {
|
||||
struct ssh_iterator *root;
|
||||
struct ssh_iterator *end;
|
||||
};
|
||||
|
||||
struct ssh_iterator {
|
||||
struct ssh_iterator *next;
|
||||
const void *data;
|
||||
};
|
||||
|
||||
struct ssh_timestamp {
|
||||
long seconds;
|
||||
long useconds;
|
||||
};
|
||||
|
||||
struct ssh_list *ssh_list_new(void);
|
||||
void ssh_list_free(struct ssh_list *list);
|
||||
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
||||
struct ssh_iterator *ssh_list_find(const struct ssh_list *list, void *value);
|
||||
int ssh_list_append(struct ssh_list *list, const void *data);
|
||||
int ssh_list_prepend(struct ssh_list *list, const void *data);
|
||||
void ssh_list_remove(struct ssh_list *list, struct ssh_iterator *iterator);
|
||||
char *ssh_lowercase(const char* str);
|
||||
char *ssh_hostport(const char *host, int port);
|
||||
|
||||
const void *_ssh_list_pop_head(struct ssh_list *list);
|
||||
|
||||
#define ssh_iterator_value(type, iterator)\
|
||||
((type)((iterator)->data))
|
||||
|
||||
/** @brief fetch the head element of a list and remove it from list
|
||||
* @param type type of the element to return
|
||||
* @param list the ssh_list to use
|
||||
* @return the first element of the list, or NULL if the list is empty
|
||||
*/
|
||||
#define ssh_list_pop_head(type, ssh_list)\
|
||||
((type)_ssh_list_pop_head(ssh_list))
|
||||
|
||||
int ssh_make_milliseconds(long sec, long usec);
|
||||
void ssh_timestamp_init(struct ssh_timestamp *ts);
|
||||
int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout);
|
||||
int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
||||
|
||||
int ssh_match_group(const char *group, const char *object);
|
||||
|
||||
#endif /* MISC_H_ */
|
28
libssh/include/libssh/options.h
Normal file
28
libssh/include/libssh/options.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _OPTIONS_H
|
||||
#define _OPTIONS_H
|
||||
|
||||
int ssh_config_parse_file(ssh_session session, const char *filename);
|
||||
int ssh_options_set_algo(ssh_session session, int algo, const char *list);
|
||||
int ssh_options_apply(ssh_session session);
|
||||
|
||||
#endif /* _OPTIONS_H */
|
87
libssh/include/libssh/packet.h
Normal file
87
libssh/include/libssh/packet.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef PACKET_H_
|
||||
#define PACKET_H_
|
||||
|
||||
struct ssh_socket_struct;
|
||||
|
||||
/* this structure should go someday */
|
||||
typedef struct packet_struct {
|
||||
int valid;
|
||||
uint32_t len;
|
||||
uint8_t type;
|
||||
} PACKET;
|
||||
|
||||
/** different state of packet reading. */
|
||||
enum ssh_packet_state_e {
|
||||
/** Packet not initialized, must read the size of packet */
|
||||
PACKET_STATE_INIT,
|
||||
/** Size was read, waiting for the rest of data */
|
||||
PACKET_STATE_SIZEREAD,
|
||||
/** Full packet was read and callbacks are being called. Future packets
|
||||
* should wait for the end of the callback. */
|
||||
PACKET_STATE_PROCESSING
|
||||
};
|
||||
|
||||
int packet_send(ssh_session session);
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
int packet_send1(ssh_session session) ;
|
||||
void ssh_packet_set_default_callbacks1(ssh_session session);
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_smsg_success1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_smsg_failure1);
|
||||
int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user);
|
||||
|
||||
#endif
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_dh_reply);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_newkeys);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_service_accept);
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
|
||||
#endif
|
||||
|
||||
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum);
|
||||
int ssh_packet_parse_type(ssh_session session);
|
||||
//int packet_flush(ssh_session session, int enforce_blocking);
|
||||
|
||||
int ssh_packet_socket_callback(const void *data, size_t len, void *user);
|
||||
void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s);
|
||||
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
|
||||
void ssh_packet_set_default_callbacks(ssh_session session);
|
||||
void ssh_packet_process(ssh_session session, uint8_t type);
|
||||
|
||||
/* PACKET CRYPT */
|
||||
uint32_t packet_decrypt_len(ssh_session session, char *crypted);
|
||||
int packet_decrypt(ssh_session session, void *packet, unsigned int len);
|
||||
unsigned char *packet_encrypt(ssh_session session,
|
||||
void *packet,
|
||||
unsigned int len);
|
||||
int packet_hmac_verify(ssh_session session,ssh_buffer buffer,
|
||||
unsigned char *mac);
|
||||
|
||||
#endif /* PACKET_H_ */
|
46
libssh/include/libssh/pcap.h
Normal file
46
libssh/include/libssh/pcap.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef PCAP_H_
|
||||
#define PCAP_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/libssh.h"
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
typedef struct ssh_pcap_context_struct* ssh_pcap_context;
|
||||
|
||||
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len);
|
||||
|
||||
ssh_pcap_context ssh_pcap_context_new(ssh_session session);
|
||||
void ssh_pcap_context_free(ssh_pcap_context ctx);
|
||||
|
||||
enum ssh_pcap_direction{
|
||||
SSH_PCAP_DIR_IN,
|
||||
SSH_PCAP_DIR_OUT
|
||||
};
|
||||
void ssh_pcap_context_set_file(ssh_pcap_context, ssh_pcap_file);
|
||||
int ssh_pcap_context_write(ssh_pcap_context,enum ssh_pcap_direction direction, void *data,
|
||||
uint32_t len, uint32_t origlen);
|
||||
|
||||
|
||||
#endif /* WITH_PCAP */
|
||||
#endif /* PCAP_H_ */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
121
libssh/include/libssh/pki.h
Normal file
121
libssh/include/libssh/pki.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef PKI_H_
|
||||
#define PKI_H_
|
||||
|
||||
#ifdef HAVE_OPENSSL_EC_H
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ECDSA_H
|
||||
#include <openssl/ecdsa.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
|
||||
|
||||
#define SSH_KEY_FLAG_EMPTY 0x0
|
||||
#define SSH_KEY_FLAG_PUBLIC 0x0001
|
||||
#define SSH_KEY_FLAG_PRIVATE 0x0002
|
||||
|
||||
struct ssh_key_struct {
|
||||
enum ssh_keytypes_e type;
|
||||
int flags;
|
||||
const char *type_c; /* Don't free it ! it is static */
|
||||
int ecdsa_nid;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa;
|
||||
gcry_sexp_t rsa;
|
||||
void *ecdsa;
|
||||
#elif HAVE_LIBCRYPTO
|
||||
DSA *dsa;
|
||||
RSA *rsa;
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
EC_KEY *ecdsa;
|
||||
#else
|
||||
void *ecdsa;
|
||||
#endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif
|
||||
void *cert;
|
||||
};
|
||||
|
||||
struct ssh_signature_struct {
|
||||
enum ssh_keytypes_e type;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa_sig;
|
||||
gcry_sexp_t rsa_sig;
|
||||
void *ecdsa_sig;
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
DSA_SIG *dsa_sig;
|
||||
ssh_string rsa_sig;
|
||||
# ifdef HAVE_OPENSSL_ECC
|
||||
ECDSA_SIG *ecdsa_sig;
|
||||
# else
|
||||
void *ecdsa_sig;
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct ssh_signature_struct *ssh_signature;
|
||||
|
||||
/* SSH Key Functions */
|
||||
ssh_key ssh_key_dup(const ssh_key key);
|
||||
void ssh_key_clean (ssh_key key);
|
||||
|
||||
/* SSH Signature Functions */
|
||||
ssh_signature ssh_signature_new(void);
|
||||
void ssh_signature_free(ssh_signature sign);
|
||||
|
||||
int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||
ssh_string *sign_blob);
|
||||
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
const ssh_key pubkey,
|
||||
ssh_signature *psig);
|
||||
int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
ssh_string sig_blob,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
size_t dlen);
|
||||
|
||||
/* SSH Public Key Functions */
|
||||
int ssh_pki_export_pubkey_blob(const ssh_key key,
|
||||
ssh_string *pblob);
|
||||
int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
|
||||
ssh_key *pkey);
|
||||
int ssh_pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len);
|
||||
|
||||
/* SSH Signing Functions */
|
||||
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
|
||||
ssh_key privatekey);
|
||||
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||
struct ssh_buffer_struct *buf,
|
||||
const ssh_key pubkey);
|
||||
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
const ssh_key privkey);
|
||||
|
||||
/* Temporary functions, to be removed after migration to ssh_key */
|
||||
ssh_public_key ssh_pki_convert_key_to_publickey(ssh_key key);
|
||||
ssh_private_key ssh_pki_convert_key_to_privatekey(ssh_key key);
|
||||
|
||||
#endif /* PKI_H_ */
|
88
libssh/include/libssh/pki_priv.h
Normal file
88
libssh/include/libssh/pki_priv.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef PKI_PRIV_H_
|
||||
#define PKI_PRIV_H_
|
||||
|
||||
#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
|
||||
#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
|
||||
#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
|
||||
#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
|
||||
#define ECDSA_HEADER_BEGIN "-----BEGIN EC PRIVATE KEY-----"
|
||||
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
|
||||
|
||||
#define ssh_pki_log(...) \
|
||||
_ssh_pki_log(__FUNCTION__, __VA_ARGS__)
|
||||
void _ssh_pki_log(const char *function,
|
||||
const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||
|
||||
int pki_key_ecdsa_nid_from_name(const char *name);
|
||||
|
||||
/* SSH Key Functions */
|
||||
ssh_key pki_key_dup(const ssh_key key, int demote);
|
||||
int pki_key_generate_rsa(ssh_key key, int parameter);
|
||||
int pki_key_generate_dss(ssh_key key, int parameter);
|
||||
int pki_key_generate_ecdsa(ssh_key key, int parameter);
|
||||
int pki_key_compare(const ssh_key k1,
|
||||
const ssh_key k2,
|
||||
enum ssh_keycmp_e what);
|
||||
|
||||
/* SSH Private Key Functions */
|
||||
enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey);
|
||||
ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data);
|
||||
|
||||
/* SSH Public Key Functions */
|
||||
int pki_pubkey_build_dss(ssh_key key,
|
||||
ssh_string p,
|
||||
ssh_string q,
|
||||
ssh_string g,
|
||||
ssh_string pubkey);
|
||||
int pki_pubkey_build_rsa(ssh_key key,
|
||||
ssh_string e,
|
||||
ssh_string n);
|
||||
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e);
|
||||
ssh_string pki_publickey_to_blob(const ssh_key key);
|
||||
int pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len);
|
||||
|
||||
/* SSH Signature Functions */
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
||||
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
enum ssh_keytypes_e type);
|
||||
int pki_signature_verify(ssh_session session,
|
||||
const ssh_signature sig,
|
||||
const ssh_key key,
|
||||
const unsigned char *hash,
|
||||
size_t hlen);
|
||||
|
||||
/* SSH Signing Functions */
|
||||
ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
const unsigned char *hash,
|
||||
size_t hlen);
|
||||
ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
const unsigned char *hash,
|
||||
size_t hlen);
|
||||
#endif /* PKI_PRIV_H_ */
|
159
libssh/include/libssh/poll.h
Normal file
159
libssh/include/libssh/poll.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef POLL_H_
|
||||
#define POLL_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
|
||||
#include <poll.h>
|
||||
typedef struct pollfd ssh_pollfd_t;
|
||||
|
||||
#else /* HAVE_POLL */
|
||||
|
||||
/* poll emulation support */
|
||||
|
||||
typedef struct ssh_pollfd_struct {
|
||||
socket_t fd; /* file descriptor */
|
||||
short events; /* requested events */
|
||||
short revents; /* returned events */
|
||||
} ssh_pollfd_t;
|
||||
|
||||
typedef unsigned long int nfds_t;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef POLLRDNORM
|
||||
#define POLLRDNORM 0x0100
|
||||
#endif
|
||||
#ifndef POLLRDBAND
|
||||
#define POLLRDBAND 0x0200
|
||||
#endif
|
||||
#ifndef POLLIN
|
||||
#define POLLIN (POLLRDNORM | POLLRDBAND)
|
||||
#endif
|
||||
#ifndef POLLPRI
|
||||
#define POLLPRI 0x0400
|
||||
#endif
|
||||
|
||||
#ifndef POLLWRNORM
|
||||
#define POLLWRNORM 0x0010
|
||||
#endif
|
||||
#ifndef POLLOUT
|
||||
#define POLLOUT (POLLWRNORM)
|
||||
#endif
|
||||
#ifndef POLLWRBAND
|
||||
#define POLLWRBAND 0x0020
|
||||
#endif
|
||||
|
||||
#ifndef POLLERR
|
||||
#define POLLERR 0x0001
|
||||
#endif
|
||||
#ifndef POLLHUP
|
||||
#define POLLHUP 0x0002
|
||||
#endif
|
||||
#ifndef POLLNVAL
|
||||
#define POLLNVAL 0x0004
|
||||
#endif
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
/* poll.c */
|
||||
#ifndef POLLIN
|
||||
#define POLLIN 0x001 /* There is data to read. */
|
||||
#endif
|
||||
#ifndef POLLPRI
|
||||
#define POLLPRI 0x002 /* There is urgent data to read. */
|
||||
#endif
|
||||
#ifndef POLLOUT
|
||||
#define POLLOUT 0x004 /* Writing now will not block. */
|
||||
#endif
|
||||
|
||||
#ifndef POLLERR
|
||||
#define POLLERR 0x008 /* Error condition. */
|
||||
#endif
|
||||
#ifndef POLLHUP
|
||||
#define POLLHUP 0x010 /* Hung up. */
|
||||
#endif
|
||||
#ifndef POLLNVAL
|
||||
#define POLLNVAL 0x020 /* Invalid polling request. */
|
||||
#endif
|
||||
|
||||
#ifndef POLLRDNORM
|
||||
#define POLLRDNORM 0x040 /* mapped to read fds_set */
|
||||
#endif
|
||||
#ifndef POLLRDBAND
|
||||
#define POLLRDBAND 0x080 /* mapped to exception fds_set */
|
||||
#endif
|
||||
#ifndef POLLWRNORM
|
||||
#define POLLWRNORM 0x100 /* mapped to write fds_set */
|
||||
#endif
|
||||
#ifndef POLLWRBAND
|
||||
#define POLLWRBAND 0x200 /* mapped to write fds_set */
|
||||
#endif
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
void ssh_poll_init(void);
|
||||
void ssh_poll_cleanup(void);
|
||||
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout);
|
||||
typedef struct ssh_poll_ctx_struct *ssh_poll_ctx;
|
||||
typedef struct ssh_poll_handle_struct *ssh_poll_handle;
|
||||
|
||||
/**
|
||||
* @brief SSH poll callback. This callback will be used when an event
|
||||
* caught on the socket.
|
||||
*
|
||||
* @param p Poll object this callback belongs to.
|
||||
* @param fd The raw socket.
|
||||
* @param revents The current poll events on the socket.
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
*
|
||||
* @return 0 on success, < 0 if you removed the poll object from
|
||||
* its poll context.
|
||||
*/
|
||||
typedef int (*ssh_poll_callback)(ssh_poll_handle p, socket_t fd, int revents,
|
||||
void *userdata);
|
||||
|
||||
struct ssh_socket_struct;
|
||||
|
||||
ssh_poll_handle ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb,
|
||||
void *userdata);
|
||||
void ssh_poll_free(ssh_poll_handle p);
|
||||
ssh_poll_ctx ssh_poll_get_ctx(ssh_poll_handle p);
|
||||
short ssh_poll_get_events(ssh_poll_handle p);
|
||||
void ssh_poll_set_events(ssh_poll_handle p, short events);
|
||||
void ssh_poll_add_events(ssh_poll_handle p, short events);
|
||||
void ssh_poll_remove_events(ssh_poll_handle p, short events);
|
||||
socket_t ssh_poll_get_fd(ssh_poll_handle p);
|
||||
void ssh_poll_set_fd(ssh_poll_handle p, socket_t fd);
|
||||
void ssh_poll_set_callback(ssh_poll_handle p, ssh_poll_callback cb, void *userdata);
|
||||
ssh_poll_ctx ssh_poll_ctx_new(size_t chunk_size);
|
||||
void ssh_poll_ctx_free(ssh_poll_ctx ctx);
|
||||
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p);
|
||||
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s);
|
||||
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p);
|
||||
int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout);
|
||||
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session);
|
||||
|
||||
#endif /* POLL_H_ */
|
247
libssh/include/libssh/priv.h
Normal file
247
libssh/include/libssh/priv.h
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* priv.h file
|
||||
* This include file contains everything you shouldn't deal with in
|
||||
* user programs. Consider that anything in this file might change
|
||||
* without notice; libssh.h file will keep backward compatibility
|
||||
* on binary & source
|
||||
*/
|
||||
|
||||
#ifndef _LIBSSH_PRIV_H
|
||||
#define _LIBSSH_PRIV_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Imitate define of inttypes.h */
|
||||
# ifndef PRIdS
|
||||
# define PRIdS "Id"
|
||||
# endif
|
||||
|
||||
# ifndef PRIu64
|
||||
# if __WORDSIZE == 64
|
||||
# define PRIu64 "lu"
|
||||
# else
|
||||
# define PRIu64 "llu"
|
||||
# endif /* __WORDSIZE */
|
||||
# endif /* PRIu64 */
|
||||
|
||||
#if !defined(HAVE_STRTOULL)
|
||||
# if defined(HAVE___STRTOULL)
|
||||
# define strtoull __strtoull
|
||||
# elif defined(__hpux) && defined(__LP64__)
|
||||
# define strtoull strtoul
|
||||
# else
|
||||
# error "no strtoull function found"
|
||||
# endif
|
||||
#endif /* !defined(HAVE_STRTOULL) */
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# include <stdio.h>
|
||||
|
||||
/* On Microsoft compilers define inline to __inline on all others use inline */
|
||||
# undef inline
|
||||
# define inline __inline
|
||||
|
||||
# define strcasecmp _stricmp
|
||||
# define strncasecmp _strnicmp
|
||||
# if !defined(HAVE_STRTOULL)
|
||||
# define strtoull _strtoui64
|
||||
# endif
|
||||
# define isblank(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n' || (ch) == '\r')
|
||||
|
||||
# define usleep(X) Sleep(((X)+1000)/1000)
|
||||
|
||||
# undef strtok_r
|
||||
# define strtok_r strtok_s
|
||||
|
||||
# if defined(HAVE__SNPRINTF_S)
|
||||
# undef snprintf
|
||||
# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__)
|
||||
# else /* HAVE__SNPRINTF_S */
|
||||
# if defined(HAVE__SNPRINTF)
|
||||
# undef snprintf
|
||||
# define snprintf _snprintf
|
||||
# else /* HAVE__SNPRINTF */
|
||||
# if !defined(HAVE_SNPRINTF)
|
||||
# error "no snprintf compatible function found"
|
||||
# endif /* HAVE_SNPRINTF */
|
||||
# endif /* HAVE__SNPRINTF */
|
||||
# endif /* HAVE__SNPRINTF_S */
|
||||
|
||||
# if defined(HAVE__VSNPRINTF_S)
|
||||
# undef vsnprintf
|
||||
# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v))
|
||||
# else /* HAVE__VSNPRINTF_S */
|
||||
# if defined(HAVE__VSNPRINTF)
|
||||
# undef vsnprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# else
|
||||
# if !defined(HAVE_VSNPRINTF)
|
||||
# error "No vsnprintf compatible function found"
|
||||
# endif /* HAVE_VSNPRINTF */
|
||||
# endif /* HAVE__VSNPRINTF */
|
||||
# endif /* HAVE__VSNPRINTF_S */
|
||||
|
||||
# endif /* _MSC_VER */
|
||||
|
||||
int gettimeofday(struct timeval *__p, void *__t);
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <unistd.h>
|
||||
#define PRIdS "zd"
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
/* some constants */
|
||||
#define MAX_PACKET_LEN 262144
|
||||
#define ERROR_BUFFERLEN 1024
|
||||
#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#if defined(__SUNPRO_C)
|
||||
#define __FUNCTION__ __func__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define enter_function() (void)session
|
||||
#define leave_function() (void)session
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/* forward declarations */
|
||||
struct ssh_common_struct;
|
||||
struct ssh_kex_struct;
|
||||
|
||||
int ssh_get_key_params(ssh_session session, ssh_key *privkey);
|
||||
|
||||
/* LOGGING */
|
||||
#define SSH_LOG(session, priority, ...) \
|
||||
ssh_log_common(&session->common, priority, __FUNCTION__, __VA_ARGS__)
|
||||
void ssh_log_common(struct ssh_common_struct *common,
|
||||
int verbosity,
|
||||
const char *function,
|
||||
const char *format, ...) PRINTF_ATTRIBUTE(4, 5);
|
||||
void ssh_log_function(int verbosity,
|
||||
const char *function,
|
||||
const char *buffer);
|
||||
|
||||
|
||||
/* ERROR HANDLING */
|
||||
|
||||
/* error handling structure */
|
||||
struct error_struct {
|
||||
int error_code;
|
||||
char error_buffer[ERROR_BUFFERLEN];
|
||||
};
|
||||
|
||||
#define ssh_set_error(error, code, ...) \
|
||||
_ssh_set_error(error, code, __FUNCTION__, __VA_ARGS__)
|
||||
void _ssh_set_error(void *error,
|
||||
int code,
|
||||
const char *function,
|
||||
const char *descr, ...) PRINTF_ATTRIBUTE(4, 5);
|
||||
|
||||
#define ssh_set_error_oom(error) \
|
||||
_ssh_set_error_oom(error, __FUNCTION__)
|
||||
void _ssh_set_error_oom(void *error, const char *function);
|
||||
|
||||
#define ssh_set_error_invalid(error) \
|
||||
_ssh_set_error_invalid(error, __FUNCTION__)
|
||||
void _ssh_set_error_invalid(void *error, const char *function);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* client.c */
|
||||
|
||||
int ssh_send_banner(ssh_session session, int is_server);
|
||||
|
||||
/* connect.c */
|
||||
socket_t ssh_connect_host(ssh_session session, const char *host,const char
|
||||
*bind_addr, int port, long timeout, long usec);
|
||||
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
||||
const char *bind_addr, int port);
|
||||
|
||||
/* in base64.c */
|
||||
ssh_buffer base64_to_bin(const char *source);
|
||||
unsigned char *bin_to_base64(const unsigned char *source, int len);
|
||||
|
||||
/* gzip.c */
|
||||
int compress_buffer(ssh_session session,ssh_buffer buf);
|
||||
int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen);
|
||||
|
||||
/* match.c */
|
||||
int match_hostname(const char *host, const char *pattern, unsigned int len);
|
||||
|
||||
|
||||
|
||||
|
||||
/** Free memory space */
|
||||
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
|
||||
|
||||
/** Zero a structure */
|
||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
|
||||
|
||||
/** Zero a structure given a pointer to the structure */
|
||||
#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
|
||||
|
||||
/** Get the size of an array */
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
/** Overwrite a string with '\0' */
|
||||
#define BURN_STRING(x) do { if ((x) != NULL) memset((x), '\0', strlen((x))); __asm__ volatile ("" : : : "memory"); } while(0)
|
||||
|
||||
/** Overwrite the buffer with '\0' */
|
||||
#define BURN_BUFFER(x, size) do { if ((x) != NULL) memset((x), '\0', (size))); __asm__ volatile ("") : : : "memory"; } while(0)
|
||||
|
||||
/**
|
||||
* This is a hack to fix warnings. The idea is to use this everywhere that we
|
||||
* get the "discarding const" warning by the compiler. That doesn't actually
|
||||
* fix the real issue, but marks the place and you can search the code for
|
||||
* discard_const.
|
||||
*
|
||||
* Please use this macro only when there is no other way to fix the warning.
|
||||
* We should use this function in only in a very few places.
|
||||
*
|
||||
* Also, please call this via the discard_const_p() macro interface, as that
|
||||
* makes the return type safe.
|
||||
*/
|
||||
#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
|
||||
|
||||
/**
|
||||
* Type-safe version of discard_const
|
||||
*/
|
||||
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
|
||||
|
||||
#endif /* _LIBSSH_PRIV_H */
|
||||
/* vim: set ts=4 sw=4 et cindent: */
|
55
libssh/include/libssh/scp.h
Normal file
55
libssh/include/libssh/scp.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCP_H
|
||||
#define _SCP_H
|
||||
|
||||
enum ssh_scp_states {
|
||||
SSH_SCP_NEW, //Data structure just created
|
||||
SSH_SCP_WRITE_INITED, //Gave our intention to write
|
||||
SSH_SCP_WRITE_WRITING,//File was opened and currently writing
|
||||
SSH_SCP_READ_INITED, //Gave our intention to read
|
||||
SSH_SCP_READ_REQUESTED, //We got a read request
|
||||
SSH_SCP_READ_READING, //File is opened and reading
|
||||
SSH_SCP_ERROR, //Something bad happened
|
||||
SSH_SCP_TERMINATED //Transfer finished
|
||||
};
|
||||
|
||||
struct ssh_scp_struct {
|
||||
ssh_session session;
|
||||
int mode;
|
||||
int recursive;
|
||||
ssh_channel channel;
|
||||
char *location;
|
||||
enum ssh_scp_states state;
|
||||
uint64_t filelen;
|
||||
uint64_t processed;
|
||||
enum ssh_scp_request_types request_type;
|
||||
char *request_name;
|
||||
char *warning;
|
||||
int request_mode;
|
||||
};
|
||||
|
||||
int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len);
|
||||
int ssh_scp_integer_mode(const char *mode);
|
||||
char *ssh_scp_string_mode(int mode);
|
||||
int ssh_scp_response(ssh_scp scp, char **response);
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user