diff --git a/Makefile.am b/Makefile.am index 2b510e6a..502b97ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,8 +22,9 @@ CFLAGS += -D_GNU_SOURCE endif CFLAGS += -Wno-unused-parameter -Wno-unused-variable -CFLAGS += -Ilibssh/include/ -Imsgpack/src +if IS_GCC CFLAGS += -rdynamic # for stack traces +endif if IS_DEVENV CFLAGS += -DDEVENV @@ -247,19 +248,3 @@ endif if NO_B64_NTOP nodist_tmate_slave_SOURCES += compat/b64_ntop.c endif - -tmate_slave_LDADD = \ - libssh/build/src/libssh.a \ - msgpack/src/.libs/libmsgpackc.a - -*.c: $(tmate_slave_LDADD) - -libssh/build/src/libssh.a: - cd libssh/build; ([ -f Makefile ] || cmake .. -DWITH_SFTP=OFF -DWITH_SERVER=ON -DWITH_PCAP=OFF -DWITH_STATIC_LIB=ON -DWITH_GSSAPI=OFF) - +make -C libssh/build ssh_static - -msgpack/src/.libs/libmsgpackc.a: - cd msgpack; ([ -f Makefile ] || (./bootstrap && ./configure)) - +make -C msgpack/src libmsgpackc.la - -.PHONY: libssh/build/src/libssh.a msgpack/src/.libs/libmsgpackc.a diff --git a/configure.ac b/configure.ac index 5856e556..5d89d7c9 100644 --- a/configure.ac +++ b/configure.ac @@ -154,6 +154,35 @@ if test "x$found_curses" = xno; then AC_MSG_ERROR("curses not found") fi +PKG_CHECK_MODULES( + MSGPACK, + msgpack, + [ + CPPFLAGS="$MSGPACK_CFLAGS $CPPFLAGS" + LIBS="$MSGPACK_LIBS $LIBS" + found_msgpack=yes + ], + found_msgpack=no +) +if test "x$found_msgpack" = xno; then + AC_MSG_ERROR("msgpack not found") +fi + + +PKG_CHECK_MODULES( + LIBSSH, + libssh, + [ + CPPFLAGS="$LIBSSH_CFLAGS $CPPFLAGS" + LIBS="$LIBSSH_LIBS $LIBS" + found_libssh=yes + ], + found_libssh=no +) +if test "x$found_libssh" = xno; then + AC_MSG_ERROR("libssh not found") +fi + # Check for b64_ntop. AC_MSG_CHECKING(for b64_ntop) AC_TRY_LINK( diff --git a/libssh/.gitignore b/libssh/.gitignore deleted file mode 100644 index c3c0e572..00000000 --- a/libssh/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.a -*.o -.* -*.swp -*~$ -build -cscope.* -tags diff --git a/libssh/AUTHORS b/libssh/AUTHORS deleted file mode 100644 index 51b3e46f..00000000 --- a/libssh/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -Author(s): -Aris Adamantiadis (project initiator) - -Andreas Schneider (developer) - -Nick Zitzmann (mostly client SFTP stuff) - -Norbert Kiesel (getaddrinfo and other patches) - -Jean-Philippe Garcia Ballester (Port to libgcrypt and configure.in voodoo, debian packaging) - -Contributor(s): - -Laurent Bigonville (debian packaging) - diff --git a/libssh/BSD b/libssh/BSD deleted file mode 100644 index b8dba0d2..00000000 --- a/libssh/BSD +++ /dev/null @@ -1,24 +0,0 @@ -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. - diff --git a/libssh/CMakeLists.txt b/libssh/CMakeLists.txt deleted file mode 100644 index 48559f37..00000000 --- a/libssh/CMakeLists.txt +++ /dev/null @@ -1,151 +0,0 @@ -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 "7") -set(APPLICATION_VERSION_PATCH "0") - -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.") - -# 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) - -if (WITH_GSSAPI) - find_package(GSSAPI) -endif (WITH_GSSAPI) - -if (WITH_NACL) - find_package(NaCl) - if (NOT NACL_FOUND) - set(WITH_NACL OFF) - endif (NOT NACL_FOUND) -endif (WITH_NACL) - -# 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 -set(LIBSSH_LIBRARY_NAME @CMAKE_SHARED_LIBRARY_PREFIX@ssh@CMAKE_SHARED_LIBRARY_SUFFIX@) -set(LIBSSH_THREADS_LIBRARY_NAME @CMAKE_SHARED_LIBRARY_PREFIX@ssh@CMAKE_SHARED_LIBRARY_SUFFIX@) - -configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY) -configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY) -install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake - DESTINATION - ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} - COMPONENT - devel -) - - -# in tree build settings -configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY) - -if (WITH_EXAMPLES) - add_subdirectory(examples) -endif (WITH_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 "libnacl support: ${WITH_NACL}") -message(STATUS "SSH-1 support: ${WITH_SSH1}") -message(STATUS "SFTP support: ${WITH_SFTP}") -message(STATUS "Server support : ${WITH_SERVER}") -message(STATUS "GSSAPI support : ${WITH_GSSAPI}") -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 "********************************************") - diff --git a/libssh/COPYING b/libssh/COPYING deleted file mode 100644 index cb7d9b73..00000000 --- a/libssh/COPYING +++ /dev/null @@ -1,460 +0,0 @@ - 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 diff --git a/libssh/CPackConfig.cmake b/libssh/CPackConfig.cmake deleted file mode 100644 index 2c4c3b5b..00000000 --- a/libssh/CPackConfig.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# 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/;/obj/;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) diff --git a/libssh/CTestConfig.cmake b/libssh/CTestConfig.cmake deleted file mode 100644 index 20d2e8f5..00000000 --- a/libssh/CTestConfig.cmake +++ /dev/null @@ -1,9 +0,0 @@ -set(UPDATE_TYPE "true") - -set(CTEST_PROJECT_NAME "libssh") -set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") - -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) diff --git a/libssh/ChangeLog b/libssh/ChangeLog deleted file mode 100644 index 6f4d906c..00000000 --- a/libssh/ChangeLog +++ /dev/null @@ -1,360 +0,0 @@ -ChangeLog -========== - -version 0.6.0 (released 2013-XX-XX) - * Added new publicy key API. - * Added new userauth API. - * Added gssapi-mic userauth. - * Added new callback based server API. - * Added Elliptic Curve DSA (ECDSA) support (with OpenSSL). - * Added Elliptic Curve Diffie Hellman (ECDH) support. - * Added improved logging system. - * Added SSH-agent forwarding. - * Added key-reexchange. - * Improved documentation. - * Fixed timeout handling. - -version 0.5.5 (released 2013-07-26) - * BUG 103: Fix ProxyCommand parsing. - * Fix setting -D_FORTIFY_SOURCE=2. - * Fix pollset error return if emtpy. - * Fix NULL pointer checks in channel functions. - * Several bugfixes. - -version 0.5.4 (released 2013-01-22) - * CVE-2013-0176 - NULL dereference leads to denial of service - * Fixed several NULL pointer dereferences in SSHv1. - * Fixed a free crash bug in options parsing. - -version 0.5.3 (released 2012-11-20) - * CVE-2012-4559 Fixed multiple double free() flaws. - * CVE-2012-4560 Fixed multiple buffer overflow flaws. - * CVE-2012-4561 Fixed multiple invalid free() flaws. - * BUG #84 - Fix bug in sftp_mkdir not returning on error. - * BUG #85 - Fixed a possible channel infinite loop if the connection dropped. - * BUG #88 - Added missing channel request_state and set it to accepted. - * BUG #89 - Reset error state to no error on successful SSHv1 authentiction. - * Fixed a possible use after free in ssh_free(). - * Fixed multiple possible NULL pointer dereferences. - * Fixed multiple memory leaks in error paths. - * Fixed timeout handling. - * Fixed regression in pre-connected socket setting. - * Handle all unknown global messages. - -version 0.5.2 (released 2011-09-17) - * Increased window size x10. - * Fixed SSHv1. - * Fixed bugged lists. - * Fixed use-after-free + inconsistent callbacks call in poll. - * Fixed scp documentation. - * Fixed possible infinite loop in channel_read(). - * Fixed handling of short reads of sftp_async_read(). - * Fixed handling request service timeout in blocking mode. - * Fixed ssh_auth_list() documentation. - * Fixed incorrect return values in ssh_channel_write(). - * Fixed an infinite loop in the termination callback. - * Fixed handling of SSH_AGAIN in channel_open(). - * Fixed "status -5 inflating zlib packet" - -version 0.5.1 (released 2011-08-09) - * Added checks for NULL pointers in string.c. - * Set the channel max packet size to 32768. - * Don't (de)compress empty buffers. - * Fixed ssh_scp_write so it works when doing recursive copy. - * Fixed another source of endless wait. - * Fixed an endless loop in case of a channel_open error. - * Fixed session timeout handling. - * Fixed ssh_channel_from_local() loop. - * Fixed permissions of scp example when we copy a file. - * Workaround ssh_get_user_home_dir on LDAP users. - * Added pkg-config support for libssh_threads. - * Fixed compilation without server and sftp modes. - * Fix static .lib overwriting on Windows. - -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. diff --git a/libssh/CodingStyle b/libssh/CodingStyle deleted file mode 100644 index 93cc382c..00000000 --- a/libssh/CodingStyle +++ /dev/null @@ -1,59 +0,0 @@ -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 diff --git a/libssh/ConfigureChecks.cmake b/libssh/ConfigureChecks.cmake deleted file mode 100644 index 5701bc39..00000000 --- a/libssh/ConfigureChecks.cmake +++ /dev/null @@ -1,220 +0,0 @@ -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(utmp.h HAVE_UTMP_H) -check_include_file(termios.h HAVE_TERMIOS_H) -check_include_file(unistd.h HAVE_UNISTD_H) -check_include_file(util.h HAVE_UTIL_H) -check_include_file(libutil.h HAVE_LIBUTIL_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) -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(isblank HAVE_ISBLANK) -check_function_exists(strncpy HAVE_STRNCPY) -check_function_exists(vsnprintf HAVE_VSNPRINTF) -check_function_exists(snprintf HAVE_SNPRINTF) -check_function_exists(poll HAVE_POLL) -check_function_exists(select HAVE_SELECT) -check_function_exists(getaddrinfo HAVE_GETADDRINFO) -check_function_exists(ntohll HAVE_NTOHLL) -check_function_exists(htonll HAVE_HTONLL) - -if (WIN32) - check_function_exists(_strtoui64 HAVE__STRTOUI64) - - 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) - - if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H) - set(HAVE_GETADDRINFO TRUE) - set(HAVE_GETHOSTBYNAME TRUE) - if (MSVC) - set(HAVE_NTOHLL TRUE) - set(HAVE_HTONLL TRUE) - endif (MSVC) - endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H) - - set(HAVE_SELECT TRUE) -endif (WIN32) - -if (UNIX) - if (NOT LINUX) - # libsocket (Solaris) - check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET) - if (HAVE_LIBSOCKET) - set(HAVE_GETADDRINFO TRUE) - 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(cfmakeraw HAVE_CFMAKERAW) - 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_USE_PTHREADS_INIT) - set(HAVE_PTHREAD 1) -endif (CMAKE_USE_PTHREADS_INIT) - -# OPTIONS -check_c_source_compiles(" -__thread int tls; - -int main(void) { - return 0; -}" HAVE_GCC_THREAD_LOCAL_STORAGE) - -check_c_source_compiles(" -__declspec(thread) int tls; - -int main(void) { - return 0; -}" HAVE_MSC_THREAD_LOCAL_STORAGE) - -check_c_source_compiles(" -#include - -int main(void) -{ - char buf[] = \"This is some content\"; - - memset(buf, '\\\\0', sizeof(buf)); __asm__ volatile(\"\" : : \"r\"(&buf) : \"memory\"); - - return 0; -}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION) - -if (WITH_DEBUG_CRYPTO) - set(DEBUG_CRYPTO 1) -endif (WITH_DEBUG_CRYPTO) - -if (WITH_DEBUG_CALLTRACE) - set(DEBUG_CALLTRACE 1) -endif (WITH_DEBUG_CALLTRACE) - -if (WITH_GSSAPI AND NOT GSSAPI_FOUND) - set(WITH_GSSAPI 0) -endif (WITH_GSSAPI AND NOT GSSAPI_FOUND) - -# ENDIAN -if (NOT WIN32) - test_big_endian(WORDS_BIGENDIAN) -endif (NOT WIN32) diff --git a/libssh/DefineOptions.cmake b/libssh/DefineOptions.cmake deleted file mode 100644 index ab7819a5..00000000 --- a/libssh/DefineOptions.cmake +++ /dev/null @@ -1,33 +0,0 @@ -option(WITH_GSSAPI "Build with GSSAPI support" ON) -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) -option(WITH_EXAMPLES "Build examples" ON) -option(WITH_NACL "Build with libnacl (curve25519" ON) -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) - -if (WITH_NACL) - set(WITH_NACL ON) -endif (WITH_NACL) \ No newline at end of file diff --git a/libssh/INSTALL b/libssh/INSTALL deleted file mode 100644 index 25960367..00000000 --- a/libssh/INSTALL +++ /dev/null @@ -1,101 +0,0 @@ -# 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://zlib.net/ -> zlib compiled DLL - -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 or use - - cmake-gui.exe .. - -### 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/src` 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 diff --git a/libssh/README b/libssh/README deleted file mode 100644 index e3170ce3..00000000 --- a/libssh/README +++ /dev/null @@ -1,163 +0,0 @@ - _ _ _ _ - (_) (_) (_) (_) - (_) _ (_) _ _ _ _ _ (_) _ - (_) (_) (_)(_) _ (_)(_) (_)(_) (_)(_) _ - (_) (_) (_) (_) _ (_) _ (_) (_) (_) - (_) (_) (_)(_)(_) (_)(_) (_)(_) (_) (_).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 - - -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 diff --git a/libssh/SubmittingPatches b/libssh/SubmittingPatches deleted file mode 100644 index 66b54e76..00000000 --- a/libssh/SubmittingPatches +++ /dev/null @@ -1,118 +0,0 @@ -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 - -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 - diff --git a/libssh/build/.gitkeep b/libssh/build/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/libssh/cmake/Modules/AddCMockaTest.cmake b/libssh/cmake/Modules/AddCMockaTest.cmake deleted file mode 100644 index 19eff622..00000000 --- a/libssh/cmake/Modules/AddCMockaTest.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# - ADD_CHECK_TEST(test_name test_source linklib1 ... linklibN) - -# Copyright (c) 2007 Daniel Gollub -# Copyright (c) 2007-2010 Andreas Schneider -# -# 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) diff --git a/libssh/cmake/Modules/COPYING-CMAKE-SCRIPTS b/libssh/cmake/Modules/COPYING-CMAKE-SCRIPTS deleted file mode 100644 index 4b417765..00000000 --- a/libssh/cmake/Modules/COPYING-CMAKE-SCRIPTS +++ /dev/null @@ -1,22 +0,0 @@ -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. diff --git a/libssh/cmake/Modules/CheckCCompilerFlagSSP.cmake b/libssh/cmake/Modules/CheckCCompilerFlagSSP.cmake deleted file mode 100644 index 2fe43954..00000000 --- a/libssh/cmake/Modules/CheckCCompilerFlagSSP.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# - 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, -# -# 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) diff --git a/libssh/cmake/Modules/DefineCMakeDefaults.cmake b/libssh/cmake/Modules/DefineCMakeDefaults.cmake deleted file mode 100644 index 22eda6fa..00000000 --- a/libssh/cmake/Modules/DefineCMakeDefaults.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# 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) - -# Create the compile command database for clang by default -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/libssh/cmake/Modules/DefineCompilerFlags.cmake b/libssh/cmake/Modules/DefineCompilerFlags.cmake deleted file mode 100644 index bfbc38fc..00000000 --- a/libssh/cmake/Modules/DefineCompilerFlags.cmake +++ /dev/null @@ -1,84 +0,0 @@ -# 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 (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel)) - check_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE) - if (WITH_FORTIFY_SOURCE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-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) - -# This removes this annoying warning -# "warning: 'BN_CTX_free' is deprecated: first deprecated in OS X 10.7 [-Wdeprecated-declarations]" -if (OSX) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations") -endif (OSX) - diff --git a/libssh/cmake/Modules/DefineInstallationPaths.cmake b/libssh/cmake/Modules/DefineInstallationPaths.cmake deleted file mode 100644 index 88e08cad..00000000 --- a/libssh/cmake/Modules/DefineInstallationPaths.cmake +++ /dev/null @@ -1,109 +0,0 @@ -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 () diff --git a/libssh/cmake/Modules/DefinePlatformDefaults.cmake b/libssh/cmake/Modules/DefinePlatformDefaults.cmake deleted file mode 100644 index 77f8a461..00000000 --- a/libssh/cmake/Modules/DefinePlatformDefaults.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# 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") - -if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - set (OSX TRUE) -endif (CMAKE_SYSTEM_NAME MATCHES "Darwin") diff --git a/libssh/cmake/Modules/FindArgp.cmake b/libssh/cmake/Modules/FindArgp.cmake deleted file mode 100644 index 8dedc855..00000000 --- a/libssh/cmake/Modules/FindArgp.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# - 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 -# -# 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) - diff --git a/libssh/cmake/Modules/FindCMocka.cmake b/libssh/cmake/Modules/FindCMocka.cmake deleted file mode 100644 index 76b4ba74..00000000 --- a/libssh/cmake/Modules/FindCMocka.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# - 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 -# -# 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(_CMOCKA_ROOT_HINTS -) - -set(_CMOCKA_ROOT_PATHS - "$ENV{PROGRAMFILES}/cmocka" -) - -find_path(CMOCKA_ROOT_DIR - NAMES - include/cmocka.h - HINTS - ${_CMOCKA_ROOT_HINTS} - PATHS - ${_CMOCKA_ROOT_PATHS} -) -mark_as_advanced(CMOCKA_ROOT_DIR) - -find_path(CMOCKA_INCLUDE_DIR - NAMES - cmocka.h - PATHS - ${CMOCKA_ROOT_DIR}/include -) - -find_library(CMOCKA_LIBRARY - NAMES - cmocka - PATHS - ${CMOCKA_ROOT_DIR}/lib -) - -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) diff --git a/libssh/cmake/Modules/FindGCrypt.cmake b/libssh/cmake/Modules/FindGCrypt.cmake deleted file mode 100644 index 5f1fe40b..00000000 --- a/libssh/cmake/Modules/FindGCrypt.cmake +++ /dev/null @@ -1,75 +0,0 @@ -# - 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 -# -# 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) diff --git a/libssh/cmake/Modules/FindGSSAPI.cmake b/libssh/cmake/Modules/FindGSSAPI.cmake deleted file mode 100644 index 8520d35d..00000000 --- a/libssh/cmake/Modules/FindGSSAPI.cmake +++ /dev/null @@ -1,324 +0,0 @@ -# - Try to find GSSAPI -# Once done this will define -# -# KRB5_CONFIG - Path to krb5-config -# GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI -# -# Read-Only variables: -# GSSAPI_FLAVOR_MIT - set to TURE if MIT Kerberos has been found -# GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Keberos has been found -# GSSAPI_FOUND - system has GSSAPI -# GSSAPI_INCLUDE_DIR - the GSSAPI include directory -# GSSAPI_LIBRARIES - Link these to use GSSAPI -# GSSAPI_DEFINITIONS - Compiler switches required for using GSSAPI -# -#============================================================================= -# Copyright (c) 2013 Andreas Schneider -# -# 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(GSSAPI_ROOT_DIR - NAMES - include/gssapi.h - include/gssapi/gssapi.h - HINTS - ${_GSSAPI_ROOT_HINTS} - PATHS - ${_GSSAPI_ROOT_PATHS} -) -mark_as_advanced(GSSAPI_ROOT_DIR) - -if (UNIX) - find_program(KRB5_CONFIG - NAMES - krb5-config - PATHS - ${GSSAPI_ROOT_DIR}/bin - /opt/local/bin) - mark_as_advanced(KRB5_CONFIG) - - if (KRB5_CONFIG) - # Check if we have MIT KRB5 - execute_process( - COMMAND - ${KRB5_CONFIG} --vendor - RESULT_VARIABLE - _GSSAPI_VENDOR_RESULT - OUTPUT_VARIABLE - _GSSAPI_VENDOR_STRING) - - if (_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*") - set(GSSAPI_FLAVOR_MIT TRUE) - else() - execute_process( - COMMAND - ${KRB5_CONFIG} --libs gssapi - RESULT_VARIABLE - _GSSAPI_LIBS_RESULT - OUTPUT_VARIABLE - _GSSAPI_LIBS_STRING) - - if (_GSSAPI_LIBS_STRING MATCHES ".*roken.*") - set(GSSAPI_FLAVOR_HEIMDAL TRUE) - endif() - endif() - - # Get the include dir - execute_process( - COMMAND - ${KRB5_CONFIG} --cflags gssapi - RESULT_VARIABLE - _GSSAPI_INCLUDE_RESULT - OUTPUT_VARIABLE - _GSSAPI_INCLUDE_STRING) - string(REGEX REPLACE "(\r?\n)+$" "" _GSSAPI_INCLUDE_STRING "${_GSSAPI_INCLUDE_STRING}") - string(REGEX REPLACE " *-I" "" _GSSAPI_INCLUDEDIR "${_GSSAPI_INCLUDE_STRING}") - endif() - - if (NOT GSSAPI_FLAVOR_MIT AND NOT GSSAPI_FLAVOR_HEIMDAL) - # Check for HEIMDAL - find_package(PkgConfig) - if (PKG_CONFIG_FOUND) - pkg_check_modules(_GSSAPI heimdal-gssapi) - endif (PKG_CONFIG_FOUND) - - if (_GSSAPI_FOUND) - set(GSSAPI_FLAVOR_HEIMDAL TRUE) - else() - find_path(_GSSAPI_ROKEN - NAMES - roken.h - PATHS - ${GSSAPI_ROOT_DIR}/include - ${_GSSAPI_INCLUDEDIR}) - if (_GSSAPI_ROKEN) - set(GSSAPI_FLAVOR_HEIMDAL TRUE) - endif() - endif () - endif() -endif (UNIX) - -find_path(GSSAPI_INCLUDE_DIR - NAMES - gssapi.h - gssapi/gssapi.h - PATHS - ${GSSAPI_ROOT_DIR}/include - ${_GSSAPI_INCLUDEDIR} -) - -if (GSSAPI_FLAVOR_MIT) - find_library(GSSAPI_LIBRARY - NAMES - gssapi_krb5 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(KRB5_LIBRARY - NAMES - krb5 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(K5CRYPTO_LIBRARY - NAMES - k5crypto - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(COM_ERR_LIBRARY - NAMES - com_err - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - if (GSSAPI_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${GSSAPI_LIBRARY} - ) - endif (GSSAPI_LIBRARY) - - if (KRB5_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${KRB5_LIBRARY} - ) - endif (KRB5_LIBRARY) - - if (K5CRYPTO_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${K5CRYPTO_LIBRARY} - ) - endif (K5CRYPTO_LIBRARY) - - if (COM_ERR_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${COM_ERR_LIBRARY} - ) - endif (COM_ERR_LIBRARY) -endif (GSSAPI_FLAVOR_MIT) - -if (GSSAPI_FLAVOR_HEIMDAL) - find_library(GSSAPI_LIBRARY - NAMES - gssapi - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(KRB5_LIBRARY - NAMES - krb5 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(HCRYPTO_LIBRARY - NAMES - hcrypto - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(COM_ERR_LIBRARY - NAMES - com_err - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(HEIMNTLM_LIBRARY - NAMES - heimntlm - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(HX509_LIBRARY - NAMES - hx509 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(ASN1_LIBRARY - NAMES - asn1 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(WIND_LIBRARY - NAMES - wind - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(ROKEN_LIBRARY - NAMES - roken - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - if (GSSAPI_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${GSSAPI_LIBRARY} - ) - endif (GSSAPI_LIBRARY) - - if (KRB5_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${KRB5_LIBRARY} - ) - endif (KRB5_LIBRARY) - - if (HCRYPTO_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${HCRYPTO_LIBRARY} - ) - endif (HCRYPTO_LIBRARY) - - if (COM_ERR_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${COM_ERR_LIBRARY} - ) - endif (COM_ERR_LIBRARY) - - if (HEIMNTLM_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${HEIMNTLM_LIBRARY} - ) - endif (HEIMNTLM_LIBRARY) - - if (HX509_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${HX509_LIBRARY} - ) - endif (HX509_LIBRARY) - - if (ASN1_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${ASN1_LIBRARY} - ) - endif (ASN1_LIBRARY) - - if (WIND_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${WIND_LIBRARY} - ) - endif (WIND_LIBRARY) - - if (ROKEN_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${WIND_LIBRARY} - ) - endif (ROKEN_LIBRARY) -endif (GSSAPI_FLAVOR_HEIMDAL) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GSSAPI DEFAULT_MSG GSSAPI_LIBRARIES GSSAPI_INCLUDE_DIR) - -if (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES) - set(GSSAPI_FOUND TRUE) -endif (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES) - -# show the GSSAPI_INCLUDE_DIRS and GSSAPI_LIBRARIES variables only in the advanced view -mark_as_advanced(GSSAPI_INCLUDE_DIRS GSSAPI_LIBRARIES) diff --git a/libssh/cmake/Modules/FindNSIS.cmake b/libssh/cmake/Modules/FindNSIS.cmake deleted file mode 100644 index 21f80d86..00000000 --- a/libssh/cmake/Modules/FindNSIS.cmake +++ /dev/null @@ -1,55 +0,0 @@ -# - Try to find NSIS -# Once done this will define -# -# NSIS_ROOT_PATH - Set this variable to the root installation of NSIS -# -# Read-Only variables: -# -# NSIS_FOUND - system has NSIS -# NSIS_MAKE - NSIS creator executable -# -#============================================================================= -# Copyright (c) 2010-2013 Andreas Schneider -# -# 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 (WIN32) - set(_NSIS_ROOT_HINTS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]") - - set(_NSIS_ROOT_PATHS - $ENV{PROGRAMFILES}/NSIS) - - find_path(NSIS_ROOT_PATH - NAMES - Include/Library.nsh - HINTS - ${_NSIS_ROOT_HINTS} - PATHS - ${_NSIS_ROOT_PATHS} - ) - mark_as_advanced(NSIS_ROOT_PATH) -endif (WIN32) - -find_program(NSIS_MAKE - NAMES - makensis - PATHS - ${NSIS_ROOT_PATH} -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE) - -if (NSIS_MAKE) - set(NSIS_FOUND TRUE) -endif (NSIS_MAKE) - -mark_as_advanced(NSIS_MAKE) diff --git a/libssh/cmake/Modules/FindNaCl.cmake b/libssh/cmake/Modules/FindNaCl.cmake deleted file mode 100644 index b1a8da45..00000000 --- a/libssh/cmake/Modules/FindNaCl.cmake +++ /dev/null @@ -1,61 +0,0 @@ -# - Try to find NaCl -# Once done this will define -# -# NACL_FOUND - system has NaCl -# NACL_INCLUDE_DIRS - the NaCl include directory -# NACL_LIBRARIES - Link these to use NaCl -# NACL_DEFINITIONS - Compiler switches required for using NaCl -# -# Copyright (c) 2010 Andreas Schneider -# Copyright (c) 2013 Aris Adamantiadis -# -# Redistribution and use is allowed according to the terms of the New -# BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# - - -if (NACL_LIBRARIES AND NACL_INCLUDE_DIRS) - # in cache already - set(NACL_FOUND TRUE) -else (NACL_LIBRARIES AND NACL_INCLUDE_DIRS) - - find_path(NACL_INCLUDE_DIR - NAMES - nacl/crypto_box_curve25519xsalsa20poly1305.h - PATHS - /usr/include - /usr/local/include - /opt/local/include - /sw/include - ) - - find_library(NACL_LIBRARY - NAMES - nacl - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /sw/lib - ) - - set(NACL_INCLUDE_DIRS - ${NACL_INCLUDE_DIR} - ) - - if (NACL_LIBRARY) - set(NACL_LIBRARIES - ${NACL_LIBRARIES} - ${NACL_LIBRARY} - ) - endif (NACL_LIBRARY) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(NaCl DEFAULT_MSG NACL_LIBRARIES NACL_INCLUDE_DIRS) - - # show the NACL_INCLUDE_DIRS and NACL_LIBRARIES variables only in the advanced view - mark_as_advanced(NACL_INCLUDE_DIRS NACL_LIBRARIES) - -endif (NACL_LIBRARIES AND NACL_INCLUDE_DIRS) - diff --git a/libssh/cmake/Modules/FindOpenSSL.cmake b/libssh/cmake/Modules/FindOpenSSL.cmake deleted file mode 100644 index 565190c6..00000000 --- a/libssh/cmake/Modules/FindOpenSSL.cmake +++ /dev/null @@ -1,208 +0,0 @@ -# - 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 -# Copyright (c) 2009-2010 Mathieu Malaterre -# Copyright (c) 2011 Andreas Schneider -# -# 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) diff --git a/libssh/cmake/Modules/FindZLIB.cmake b/libssh/cmake/Modules/FindZLIB.cmake deleted file mode 100644 index f68207e4..00000000 --- a/libssh/cmake/Modules/FindZLIB.cmake +++ /dev/null @@ -1,120 +0,0 @@ -# - 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 -# -# 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) diff --git a/libssh/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake b/libssh/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake deleted file mode 100644 index a2e94809..00000000 --- a/libssh/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() -# MACRO_ENSURE_OUT_OF_SOURCE_BUILD() - -# Copyright (c) 2006, Alexander Neundorf, -# -# 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) diff --git a/libssh/cmake/Modules/UseDoxygen.cmake b/libssh/cmake/Modules/UseDoxygen.cmake deleted file mode 100644 index 72c384d2..00000000 --- a/libssh/cmake/Modules/UseDoxygen.cmake +++ /dev/null @@ -1,140 +0,0 @@ -# - 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 a dependency. -# i.e.: the API documentation is built with: -# make doc -# -# USAGE: GLOBAL INSTALL -# -# Install it with: -# cmake ./ && sudo make install -# Add the following to the CMakeLists.txt of your project: -# include(UseDoxygen OPTIONAL) -# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it. -# -# 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. -# -# -# CONFIGURATION -# -# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake. -# Variables you may define are: -# DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are. -# Defaults to the current source directory. -# DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan. -# The Paths should be in double quotes and separated by space. e.g.: -# "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/" -# -# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. -# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc". -# -# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation -# to be built. -# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where -# the Doxygen LaTeX output is stored. Defaults to "latex". -# -# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where -# the Doxygen html output is stored. Defaults to "html". -# - -# -# Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz -# -# 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 type docstring) - if(NOT DEFINED "${name}") - set("${name}" "${value}" CACHE "${type}" "${docstring}") - endif() -endmacro() - -find_package(Doxygen) - -if(DOXYGEN_FOUND) - find_file(DOXYFILE_IN "Doxyfile.in" - PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/" - NO_DEFAULT_PATH - DOC "Path to the doxygen configuration template file") - set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile") - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN") -endif() - -if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND) - usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc" - PATH "Doxygen output directory") - usedoxygen_set_default(DOXYFILE_HTML_DIR "html" - STRING "Doxygen HTML output directory") - usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" - PATH "Input files source directory") - usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS "" - STRING "Additional source files/directories separated by space") - set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}") - - usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF) - usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory") - - mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR - DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN) - - - set_property(DIRECTORY - APPEND PROPERTY - ADDITIONAL_MAKE_CLEAN_FILES - "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}") - - add_custom_target(doxygen - COMMAND "${DOXYGEN_EXECUTABLE}" - "${DOXYFILE}" - COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..." - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") - - set(DOXYFILE_DOT "NO") - if(DOXYGEN_DOT_EXECUTABLE) - set(DOXYFILE_DOT "YES") - endif() - - ## LaTeX - set(DOXYFILE_PDFLATEX "NO") - - set_property(DIRECTORY APPEND PROPERTY - ADDITIONAL_MAKE_CLEAN_FILES - "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}") - - if(DOXYFILE_LATEX STREQUAL "ON") - set(DOXYFILE_GENERATE_LATEX "YES") - find_package(LATEX) - find_program(DOXYFILE_MAKE make) - mark_as_advanced(DOXYFILE_MAKE) - if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE) - if(PDFLATEX_COMPILER) - set(DOXYFILE_PDFLATEX "YES") - endif() - - add_custom_command(TARGET doxygen - POST_BUILD - COMMAND "${DOXYFILE_MAKE}" - COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..." - WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}") - else() - set(DOXYGEN_LATEX "NO") - endif() - else() - set(DOXYFILE_GENERATE_LATEX "NO") - endif() - - - configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY) - - add_custom_target(doc) - add_dependencies(doc doxygen) -endif() diff --git a/libssh/config.h.cmake b/libssh/config.h.cmake deleted file mode 100644 index 55e37aca..00000000 --- a/libssh/config.h.cmake +++ /dev/null @@ -1,176 +0,0 @@ -/* 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 header file. */ -#cmakedefine HAVE_ARGP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PTY_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UTMP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UTIL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBUTIL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TERMIOS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_AES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_WSPIAPI_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_BLOWFISH_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_DES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_ECDH_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_EC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_ECDSA_H 1 - -/* Define to 1 if you have the 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 `isblank' function. */ -#cmakedefine HAVE_ISBLANK 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 - -/* Define to 1 if you have the `_strtoui64' function. */ -#cmakedefine HAVE__STRTOUI64 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 ****************************/ - -#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1 -#cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1 - -#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1 - -/* Define to 1 if you want to enable GSSAPI */ -#cmakedefine WITH_GSSAPI 1 - -/* 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 - -/* Define to 1 if you want to enable NaCl support */ -#cmakedefine WITH_NACL 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 diff --git a/libssh/doc/CMakeLists.txt b/libssh/doc/CMakeLists.txt deleted file mode 100644 index 31242811..00000000 --- a/libssh/doc/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# -# Build the documentation -# -include(UseDoxygen OPTIONAL) - diff --git a/libssh/doc/Doxyfile.in b/libssh/doc/Doxyfile.in deleted file mode 100644 index a7a9ffbb..00000000 --- a/libssh/doc/Doxyfile.in +++ /dev/null @@ -1,1917 +0,0 @@ -# Doxyfile 1.8.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed -# in front of the TAG it is preceding . -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = @APPLICATION_NAME@ - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = @APPLICATION_VERSION@ - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@ - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, -# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, -# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. Note that you specify absolute paths here, but also -# relative paths, which will be relative from the directory where doxygen is -# started. - -STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@ - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@ - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 2 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, -# and language is one of the parsers supported by doxygen: IDL, Java, -# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, -# C++. For instance to make doxygen treat .inc files as Fortran files (default -# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note -# that for custom extensions you also need to set FILE_PATTERNS otherwise the -# files are not read by doxygen. - -EXTENSION_MAPPING = - -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES (the -# default) will make doxygen replace the get and set methods by a property in -# the documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields or simple typedef fields will be shown -# inline in the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO (the default), structs, classes, and unions are shown on a separate -# page (for HTML and Man pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = YES - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can -# be an expensive process and often the same symbol appear multiple times in -# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too -# small doxygen will become slower. If the cache is too large, memory is wasted. -# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid -# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 -# symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = @CMAKE_INTERNAL_DOC@ - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = YES - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if section-label ... \endif -# and \cond section-label ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. Do not use -# file names with spaces, bibtex cannot handle them. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = @CMAKE_SOURCE_DIR@/include/libssh \ - @CMAKE_SOURCE_DIR@/src \ - @CMAKE_SOURCE_DIR@/doc - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.cpp \ - *.cc \ - *.c \ - *.h \ - *.hh \ - *.hpp \ - *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = */.git/* \ - */.svn/* \ - */cmake/* \ - */obj/* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/examples - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = *.c \ - *.h \ - INSTALL \ - DEPENDENCIES \ - CHANGELOG \ - LICENSE \ - LGPL - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = YES - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be ignored. -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 2 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If left blank doxygen will -# generate a default style sheet. Note that it is recommended to use -# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this -# tag will in the future become obsolete. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional -# user-defined cascading style sheet that is included after the standard -# style sheets created by doxygen. Using this option one can overrule -# certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more -# robust against future updates. Doxygen will copy the style sheet file to -# the output directory. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and -# SVG. The default value is HTML-CSS, which is slower, but has the best -# compatibility. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript -# pieces of code that will be used on startup of the MathJax code. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. -# There are two flavours of web server based search depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. -# See the manual for details. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain -# the search results. Doxygen ships with an example indexer (doxyindexer) and -# search engine (doxysearch.cgi) which are based on the open source search -# engine library Xapian. See the manual for configuration details. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will returned the search results when EXTERNAL_SEARCH is enabled. -# Doxygen ships with an example search engine (doxysearch) which is based on -# the open source search engine library Xapian. See the manual for configuration -# details. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id -# of to a relative location where the documentation can be found. -# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = @LATEX_COMPILER@ - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = @MAKEINDEX_COMPILER@ - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4 will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images -# or other source files which should be copied to the LaTeX output directory. -# Note that the files will be copied as-is; there are no commands or markers -# available. - -LATEX_EXTRA_FILES = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = YES - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = YES - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- - -# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files -# that can be used to generate PDF. - -GENERATE_DOCBOOK = NO - -# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in -# front of it. If left blank docbook will be used as the default path. - -DOCBOOK_OUTPUT = docbook - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = WITH_SERVER WITH_SFTP WITH_PCAP - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. The -# format of a tag file without this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths -# or URLs. Note that each tag file must have a unique name (where the name does -# NOT include the path). If a tag file is not located in the directory in which -# doxygen is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = @CMAKE_CURRENT_BINARY_DIR@/html/@PROJECT_NAME@.TAGFILE - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = YES - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed -# in the related pages index. If set to NO, only the current project's -# pages will be listed. - -EXTERNAL_PAGES = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = NO - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = @DOXYGEN_DOT_FOUND@ - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# manageable. Set this to 0 for no limit. Note that the threshold may be -# exceeded by 50% before the limit is enforced. - -UML_LIMIT_NUM_FIELDS = 10 - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = @DOXYGEN_DOT_EXECUTABLE_PATH@ - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/libssh/doc/authentication.dox b/libssh/doc/authentication.dox deleted file mode 100644 index 30690e8c..00000000 --- a/libssh/doc/authentication.dox +++ /dev/null @@ -1,375 +0,0 @@ -/** -@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); - 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); - 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 - -*/ diff --git a/libssh/doc/command.dox b/libssh/doc/command.dox deleted file mode 100644 index 76113543..00000000 --- a/libssh/doc/command.dox +++ /dev/null @@ -1,94 +0,0 @@ -/** -@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 - -*/ diff --git a/libssh/doc/curve25519-sha256@libssh.org.txt b/libssh/doc/curve25519-sha256@libssh.org.txt deleted file mode 100644 index e68dc5e6..00000000 --- a/libssh/doc/curve25519-sha256@libssh.org.txt +++ /dev/null @@ -1,119 +0,0 @@ -curve25519-sha256@libssh.org.txt Aris Adamantiadis - 21/9/2013 - -1. Introduction - -This document describes the key exchange methode curve25519-sha256@libssh.org -for SSH version 2 protocol. It is provided as an alternative to the existing -key exchange mechanisms based on either Diffie-Hellman or Elliptic Curve Diffie- -Hellman [RFC5656]. -The reason is the following : During summer of 2013, revelations from ex- -consultant at NSA Edward Snowden gave proof that NSA willingly inserts backdoors -into softwares, hardware components and published standards. While it is still -believed that the mathematics behind ECC cryptography are still sound and solid, -some people (including Bruce Schneier [SCHNEIER]), showed their lack of confidence -in NIST-published curves such as nistp256, nistp384, nistp521, for which constant -parameters (including the generator point) are defined without explanation. It -is also believed that NSA had a word to say in their definition. These curves -are not the most secure or fastest possible for their key sizes [DJB], and -researchers think it is possible that NSA have ways of cracking NIST curves. -It is also interesting to note that SSH belongs to the list of protocols the NSA -claims to be able to eavesdrop. Having a secure replacement would make passive -attacks much harder if such a backdoor exists. - -However an alternative exists in the form of Curve25519. This algorithm has been -proposed in 2006 by DJB [Curve25519]. Its main stengths are its speed, its -constant-time run time (and resistance against side-channel attacks), and its -lack of nebulous hard-coded constants. - -The reference version being used in this document is the one described in -[Curve25519] as implemented in the library NaCl [NaCl]. -This document does not attempts to provide alternatives to the ecdsa-sha1-* -authentication keys. - -2. Key exchange - -The key exchange procedure is very similar to the one described chapter 4 of -[RFC5656]. Public ephemeral keys are transmitted over SSH encapsulated into -standard SSH strings. - -The following is an overview of the key exchange process: - -Client Server ------- ------ -Generate ephemeral key pair. -SSH_MSG_KEX_ECDH_INIT --------> - Verify that client public key - length is 32 bytes. - Generate ephemeral key pair. - Compute shared secret. - Generate and sign exchange hash. - <-------- SSH_MSG_KEX_ECDH_REPLY -Verify that server public key length is 32 bytes. -* Verify host keys belong to server. -Compute shared secret. -Generate exchange hash. -Verify server's signature. - -* Optional but strongly recommanded as this protects against MITM attacks. - -This is implemented using the same messages as described in RFC5656 chapter 4 - -3. Method Name - -The name of this key exchange method is "curve25519-sha256@libssh.org". - -4. Implementation considerations - -The whole method is based on the curve25519 scalar multiplication. In this -method, a private key is a scalar of 256 bits, and a public key is a point -of 256 bits. - -4.1. Private key generation - -A 32 bytes private key should be generated for each new connection, - using a secure PRNG. The following actions must be done on the private key: - mysecret[0] &= 248; - mysecret[31] &= 127; - mysecret[31] |= 64; -In order to keep the key valid. However, many cryptographic libraries will do -this automatically. -It should be noted that, in opposition to NIST curves, no special validation -should be done to ensure the result is a valid and secure private key. - -4.2 Public key generation - -The 32 bytes public key of either a client or a server must be generated using -the 32 bytes private key and a common generator base. This base is defined as 9 -followed by all zeroes: - const unsigned char basepoint[32] = {9}; - -The public key is calculated using the cryptographic scalar multiplication: - const unsigned char privkey[32]; - unsigned char pubkey[32]; - crypto_scalarmult (pubkey, privkey, basepoint); -However some cryptographic libraries may provide a combined function: - crypto_scalarmult_base (pubkey, privkey); - -It should be noted that, in opposition to NIST curves, no special validation -should be done to ensure the received public keys are valid curves point. The -Curve25519 algorithm ensure that every possible public key maps to a valid -ECC Point. - -4.3 Shared secret generation - -The shared secret, k, is defined in SSH specifications to be a big integer. -This number is calculated using the following procedure: - - X is the 32 bytes point obtained by the scalar multiplication of the other - side's public key and the local private key scalar. - - The whole 32 bytes of the number X are then converted into a big integer k. - This conversion follows the network byte order. This step differs from - RFC5656. - -[RFC5656] http://tools.ietf.org/html/rfc5656 -[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929 -[DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf -[Curve25519] "Curve25519: new Diffie-Hellman speed records." - http://cr.yp.to/ecdh/curve25519-20060209.pdf \ No newline at end of file diff --git a/libssh/doc/forwarding.dox b/libssh/doc/forwarding.dox deleted file mode 100644 index be4ab94e..00000000 --- a/libssh/doc/forwarding.dox +++ /dev/null @@ -1,230 +0,0 @@ -/** -@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_channel_listen_forward(), -then ssh_channel_accept_forward(). - -When you call ssh_channel_listen_forward(), 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; - int port = 0; - char *helloworld = "" -"HTTP/1.1 200 OK\n" -"Content-Type: text/html\n" -"Content-Length: 113\n" -"\n" -"\n" -" \n" -" Hello, World!\n" -" \n" -" \n" -"

Hello, World!

\n" -" \n" -"\n"; - - rc = ssh_channel_listen_forward(session, NULL, 8080, NULL); - if (rc != SSH_OK) - { - fprintf(stderr, "Error opening remote port: %s\n", - ssh_get_error(session)); - return rc; - } - - channel = ssh_channel_accept_forward(session, 60000, &port); - 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 - -*/ diff --git a/libssh/doc/guided_tour.dox b/libssh/doc/guided_tour.dox deleted file mode 100644 index 2fa906e0..00000000 --- a/libssh/doc/guided_tour.dox +++ /dev/null @@ -1,455 +0,0 @@ -/** -@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 -#include - -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 -#include - -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 -#include -#include - -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 -#include - -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 -#include -#include - -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. - - -*/ diff --git a/libssh/doc/introduction.dox b/libssh/doc/introduction.dox deleted file mode 100644 index cd786497..00000000 --- a/libssh/doc/introduction.dox +++ /dev/null @@ -1,49 +0,0 @@ -/** -@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 - -*/ diff --git a/libssh/doc/linking.dox b/libssh/doc/linking.dox deleted file mode 100644 index 8cbc415c..00000000 --- a/libssh/doc/linking.dox +++ /dev/null @@ -1,30 +0,0 @@ -/** - -@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 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! - -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. - -To be able to compile the application you're developing you need to either pass -LIBSSH_STATIC as a define in the compiler command line or define it before you -include libssh.h. This is required cause the dynamic library needs to specify -the dllimport attribute. - -@code -#define LIBSSH_STATIC 1 -#include -@endcode - -*/ diff --git a/libssh/doc/mainpage.dox b/libssh/doc/mainpage.dox deleted file mode 100644 index 70f774ad..00000000 --- a/libssh/doc/mainpage.dox +++ /dev/null @@ -1,224 +0,0 @@ -/** - -@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: - - - Key Exchange Methods: curve25519-sha256@libssh.org, ecdh-sha2-nistp256, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1 - - Hostkey Types: ecdsa-sha2-nistp256, ssh-dss, ssh-rsa - - Ciphers: aes256-ctr, aes192-ctr, aes128-ctr, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, des-cbc-ssh1, blowfish-cbc, none - - Compression Schemes: zlib, zlib@openssh.com, none - - MAC hashes: hmac-sha1, none - - Authentication: none, password, public-key, hostbased, keyboard-interactive, gssapi-with-mic - - Channels: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, auth-agent-req@openssh.com - - Global Requests: tcpip-forward, forwarded-tcpip - - Channel Requests: x11, pty, exit-status, signal, exit-signal, keepalive@openssh.com, auth-agent-req@openssh.com - - Subsystems: sftp(version 3), publickey(version 2), OpenSSH Extensions - - SFTP: statvfs@openssh.com, fstatvfs@openssh.com - - Thread-safe: Just don't share sessions - - Non-blocking: it can be used both blocking and non-blocking - - Your sockets: the app hands over the socket, or uses libssh sockets - - OpenSSL or gcrypt: builds with either - -@section main-additional-features Additional Features - - - Client and server support - - SSHv2 and SSHv1 protocol support - - Supports Linux, UNIX, BSD, Solaris, OS/2 and Windows - - Automated test cases with nightly tests - - Event model based on poll(2), or a poll(2)-emulation. - -@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 -@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. - - - RFC 4250, - The Secure Shell (SSH) Protocol Assigned Numbers - - RFC 4251, - The Secure Shell (SSH) Protocol Architecture - - RFC 4252, - The Secure Shell (SSH) Authentication Protocol - - RFC 4253, - The Secure Shell (SSH) Transport Layer Protocol - - RFC 4254, - The Secure Shell (SSH) Connection Protocol - - RFC 4255, - Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints - - RFC 4256, - Generic Message Exchange Authentication for the Secure Shell Protocol (SSH) - - RFC 4335, - The Secure Shell (SSH) Session Channel Break Extension - - RFC 4344, - The Secure Shell (SSH) Transport Layer Encryption Modes - - RFC 4345, - Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol - -It was later modified and expanded by the following RFCs. - - - RFC 4419, - Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer - Protocol - - RFC 4432, - RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol - - RFC 4462, - Generic Security Service Application Program Interface (GSS-API) - Authentication and Key Exchange for the Secure Shell (SSH) Protocol - - RFC 4716, - The Secure Shell (SSH) Public Key File Format - - RFC 5647, - AES Galois Counter Mode for the Secure Shell Transport Layer Protocol - - RFC 5656, - Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer - -Interesting cryptography documents: - - - PKCS #11, 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. - - - - draft-ietf-secsh-filexfer-02.txt, - SSH File Transfer Protocol - -@subsection main-rfc-extensions Secure Shell Extensions - -The libssh project has an extension to support Curve25519 which is also supported by -the OpenSSH project. - - - curve25519-sha256@libssh.org, - Curve25519-SHA256 for ECDH KEX - -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. - - - - OpenSSH's deviations and extensions - - - OpenSSH's ssh-agent - - - OpenSSH's pubkey certificate authentication - -*/ diff --git a/libssh/doc/scp.dox b/libssh/doc/scp.dox deleted file mode 100644 index 1e7db780..00000000 --- a/libssh/doc/scp.dox +++ /dev/null @@ -1,268 +0,0 @@ -/** -@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. - -*/ diff --git a/libssh/doc/sftp.dox b/libssh/doc/sftp.dox deleted file mode 100644 index 8b7c7e1a..00000000 --- a/libssh/doc/sftp.dox +++ /dev/null @@ -1,431 +0,0 @@ -/** -@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 - -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 -#include - -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 -#include -#include - -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(). - -Files are normally transferred in chunks. A good chunk size is 16 KB. The following -example transfers the remote file "/etc/profile" in 16 KB chunks. For each chunk we -request, sftp_read blocks till the data has been received: - -@code -// Good chunk size -#define MAX_XFER_BUF_SIZE 16384 - -int sftp_read_sync(ssh_session session, sftp_session sftp) -{ - int access_type; - sftp_file file; - char buffer[MAX_XFER_BUF_SIZE]; - int nbytes, nwritten, rc; - int fd; - - 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; - } - - fd = open("/path/to/profile", O_CREAT); - if (fd < 0) { - fprintf(stderr, "Can't open file for writing: %s\n", - strerror(errno)); - return SSH_ERROR; - } - - for (;;) { - nbytes = sftp_read(file, buffer, sizeof(buffer)); - if (nbytes == 0) { - break; // EOF - } else if (nbytes < 0) { - fprintf(stderr, "Error while reading file: %s\n", - ssh_get_error(session)); - sftp_close(file); - return SSH_ERROR; - } - - nwritten = write(fd, buf, nbytes); - if (nwritten != nbytes) { - fprintf(stderr, "Error writing: %s\n", - strerror(errno)); - 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 -// Good chunk size -#define MAX_XFER_BUF_SIZE 16384 - -int sftp_read_async(ssh_session session, sftp_session sftp) -{ - int access_type; - sftp_file file; - char buffer[MAX_XFER_BUF_SIZE]; - 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 - -*/ diff --git a/libssh/doc/shell.dox b/libssh/doc/shell.dox deleted file mode 100644 index 35fdfc82..00000000 --- a/libssh/doc/shell.dox +++ /dev/null @@ -1,361 +0,0 @@ -/** -@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 - -*/ diff --git a/libssh/doc/tbd.dox b/libssh/doc/tbd.dox deleted file mode 100644 index 921337ed..00000000 --- a/libssh/doc/tbd.dox +++ /dev/null @@ -1,14 +0,0 @@ -/** -@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 *** - -*/ diff --git a/libssh/doc/threading.dox b/libssh/doc/threading.dox deleted file mode 100644 index 95eee6bb..00000000 --- a/libssh/doc/threading.dox +++ /dev/null @@ -1,66 +0,0 @@ -/** -@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 -... -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 -... -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 - -libgcrypt 1.6 and bigger backend does not support custom callback. Using anything else than pthreads (ssh_threads_get_pthread()) here will fail. -Good luck ! -*/ diff --git a/libssh/examples/CMakeLists.txt b/libssh/examples/CMakeLists.txt deleted file mode 100644 index 4998f041..00000000 --- a/libssh/examples/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -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 (BSD OR SOLARIS OR OSX) - find_package(Argp) -endif (BSD OR SOLARIS OR OSX) - -if (UNIX AND NOT WIN32) - 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(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) - - add_executable(samplessh sample.c ${examples_SRCS}) - target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY}) - - if (WITH_SERVER) - if (HAVE_LIBUTIL) - add_executable(ssh_server_fork ssh_server_fork.c) - target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util) - endif (HAVE_LIBUTIL) - - if (WITH_GSSAPI AND GSSAPI_FOUND) - add_executable(samplesshd-cb samplesshd-cb.c) - target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES}) - - add_executable(proxy proxy.c) - target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES}) - endif (WITH_GSSAPI AND GSSAPI_FOUND) - - add_executable(samplesshd-kbdint samplesshd-kbdint.c) - target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES}) - - endif (WITH_SERVER) -endif (UNIX AND NOT WIN32) - -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}) diff --git a/libssh/examples/authentication.c b/libssh/examples/authentication.c deleted file mode 100644 index b9f70f5b..00000000 --- a/libssh/examples/authentication.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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 -#include -#include - -#include -#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_userauth_list(session, NULL); - while (rc != SSH_AUTH_SUCCESS) { - if (method & SSH_AUTH_METHOD_GSSAPI_MIC){ - rc = ssh_userauth_gssapi(session); - if(rc == SSH_AUTH_ERROR) { - error(session); - return rc; - } else if (rc == SSH_AUTH_SUCCESS) { - break; - } - } - // Try to authenticate with public key first - if (method & SSH_AUTH_METHOD_PUBLICKEY) { - rc = ssh_userauth_publickey_auto(session, NULL, 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; -} diff --git a/libssh/examples/connect_ssh.c b/libssh/examples/connect_ssh.c deleted file mode 100644 index c9e4ef6e..00000000 --- a/libssh/examples/connect_ssh.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 -#include "examples_common.h" -#include - -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; -} diff --git a/libssh/examples/examples_common.h b/libssh/examples/examples_common.h deleted file mode 100644 index 13eb455c..00000000 --- a/libssh/examples/examples_common.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -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 -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_ */ diff --git a/libssh/examples/exec.c b/libssh/examples/exec.c deleted file mode 100644 index 4d5e0c1a..00000000 --- a/libssh/examples/exec.c +++ /dev/null @@ -1,66 +0,0 @@ -/* simple exec example */ -#include - -#include -#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; -} diff --git a/libssh/examples/knownhosts.c b/libssh/examples/knownhosts.c deleted file mode 100644 index 5097cd93..00000000 --- a/libssh/examples/knownhosts.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include -#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; - size_t hlen; - ssh_key srv_pubkey; - int rc; - - state=ssh_is_server_known(session); - - rc = ssh_get_publickey(session, &srv_pubkey); - if (rc < 0) { - return -1; - } - - rc = ssh_get_publickey_hash(srv_pubkey, - SSH_PUBLICKEY_HASH_SHA1, - &hash, - &hlen); - ssh_key_free(srv_pubkey); - if (rc < 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; -} diff --git a/libssh/examples/libssh_scp.c b/libssh/examples/libssh_scp.c deleted file mode 100644 index 99281db8..00000000 --- a/libssh/examples/libssh_scp.c +++ /dev/null @@ -1,327 +0,0 @@ -/* 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 -#include -#include -#include -#include - -#include -#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;ihost=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); - loc->scp = NULL; - 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); - loc->scp = NULL; - 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 = NULL; - /* recursive mode doesn't work yet */ - (void)recursive; - /* Get the file name and size*/ - if(!src->is_ssh){ - fd = fileno(src->file); - if (fd < 0) { - fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno)); - return -1; - } - r = fstat(fd, &s); - if (r < 0) { - return -1; - } - 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)); - ssh_string_free_char(filename); - 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_string_free_char(filename); - 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"); - ssh_string_free_char(filename); - 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)); - ssh_string_free_char(filename); - 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)); - ssh_string_free_char(filename); - 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; - ssh_string_free_char(filename); - return -1; - } - } else { - w=fwrite(buffer,r,1,dest->file); - if(w<=0){ - fprintf(stderr,"Error writing in local file: %s\n",strerror(errno)); - ssh_string_free_char(filename); - return -1; - } - } - total+=r; - - } while(total < size); - ssh_string_free_char(filename); - 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;iis_ssh && dest->scp != NULL) { - 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; -} diff --git a/libssh/examples/libsshpp.cpp b/libssh/examples/libsshpp.cpp deleted file mode 100644 index 8f042a45..00000000 --- a/libssh/examples/libsshpp.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* -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 -#include -#include - -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; -} diff --git a/libssh/examples/libsshpp_noexcept.cpp b/libssh/examples/libsshpp_noexcept.cpp deleted file mode 100644 index eff8cc19..00000000 --- a/libssh/examples/libsshpp_noexcept.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -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 -#define SSH_NO_CPP_EXCEPTIONS -#include - -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; -} diff --git a/libssh/examples/proxy.c b/libssh/examples/proxy.c deleted file mode 100644 index dcf4d0d7..00000000 --- a/libssh/examples/proxy.c +++ /dev/null @@ -1,347 +0,0 @@ -/* This is a sample implementation of a libssh based SSH proxy */ -/* -Copyright 2003-2013 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 -#include -#include - -#ifdef HAVE_ARGP_H -#include -#endif -#include -#include -#include - -#define USER "myuser" -#define PASSWORD "mypassword" - -static int authenticated=0; -static int tries = 0; -static int error = 0; -static ssh_channel chan=NULL; -static char *username; -static ssh_gssapi_creds client_creds = NULL; - -static int auth_password(ssh_session session, const char *user, - const char *password, void *userdata){ - - (void)userdata; - - printf("Authenticating user %s pwd %s\n",user, password); - if(strcmp(user,USER) == 0 && strcmp(password, PASSWORD) == 0){ - authenticated = 1; - printf("Authenticated\n"); - return SSH_AUTH_SUCCESS; - } - if (tries >= 3){ - printf("Too many authentication tries\n"); - ssh_disconnect(session); - error = 1; - return SSH_AUTH_DENIED; - } - tries++; - return SSH_AUTH_DENIED; -} - -static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata){ - (void)userdata; - client_creds = ssh_gssapi_get_creds(session); - printf("Authenticating user %s with gssapi principal %s\n",user, principal); - if (client_creds != NULL) - printf("Received some gssapi credentials\n"); - else - printf("Not received any forwardable creds\n"); - printf("authenticated\n"); - authenticated = 1; - username = strdup(principal); - return SSH_AUTH_SUCCESS; -} - -static int pty_request(ssh_session session, ssh_channel channel, const char *term, - int x,int y, int px, int py, void *userdata){ - (void) session; - (void) channel; - (void) term; - (void) x; - (void) y; - (void) px; - (void) py; - (void) userdata; - printf("Allocated terminal\n"); - return 0; -} - -static int shell_request(ssh_session session, ssh_channel channel, void *userdata){ - (void)session; - (void)channel; - (void)userdata; - printf("Allocated shell\n"); - return 0; -} -struct ssh_channel_callbacks_struct channel_cb = { - .channel_pty_request_function = pty_request, - .channel_shell_request_function = shell_request -}; - -static ssh_channel new_session_channel(ssh_session session, void *userdata){ - (void) session; - (void) userdata; - if(chan != NULL) - return NULL; - printf("Allocated session channel\n"); - chan = ssh_channel_new(session); - ssh_callbacks_init(&channel_cb); - ssh_set_channel_callbacks(chan, &channel_cb); - return chan; -} - - -#ifdef HAVE_ARGP_H -const char *argp_program_version = "libssh proxy example " -SSH_STRINGIFY(LIBSSH_VERSION); -const char *argp_program_bug_address = ""; - -/* 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_event mainloop; - ssh_session client_session; - - struct ssh_server_callbacks_struct cb = { - .userdata = NULL, - .auth_password_function = auth_password, - .auth_gssapi_mic_function = auth_gssapi_mic, - .channel_open_request_session_function = new_session_channel - }; - - char buf[2048]; - char host[128]=""; - char *ptr; - int i,r, rc; - - sshbind=ssh_bind_new(); - session=ssh_new(); - - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, "sshd_rsa"); - -#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 - - 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; - } - ssh_callbacks_init(&cb); - ssh_set_server_callbacks(session, &cb); - - if (ssh_handle_key_exchange(session)) { - printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); - return 1; - } - ssh_set_auth_methods(session,SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC); - mainloop = ssh_event_new(); - ssh_event_add_session(mainloop, session); - - while (!(authenticated && chan != NULL)){ - if(error) - break; - r = ssh_event_dopoll(mainloop, -1); - if (r == SSH_ERROR){ - printf("Error : %s\n",ssh_get_error(session)); - ssh_disconnect(session); - return 1; - } - } - if(error){ - printf("Error, exiting loop\n"); - return 1; - } else - printf("Authenticated and got a channel\n"); - if (!client_creds){ - snprintf(buf,sizeof(buf), "Sorry, but you do not have forwardable tickets. Try again with -K\r\n"); - ssh_channel_write(chan,buf,strlen(buf)); - printf("%s",buf); - ssh_disconnect(session); - return 1; - } - snprintf(buf,sizeof(buf), "Hello %s, welcome to the Sample SSH proxy.\r\nPlease select your destination: ", username); - ssh_channel_write(chan, buf, strlen(buf)); - do{ - i=ssh_channel_read(chan,buf, 2048, 0); - if(i>0) { - ssh_channel_write(chan, buf, i); - if(strlen(host) + i < sizeof(host)){ - strncat(host, buf, i); - } - if (strchr(host, '\x0d')) { - *strchr(host, '\x0d')='\0'; - ssh_channel_write(chan, "\n", 1); - break; - } - } else { - printf ("Error: %s\n", ssh_get_error(session) ); - return 1; - } - } while (i>0); - snprintf(buf,sizeof(buf),"Trying to connect to \"%s\"\r\n", host); - ssh_channel_write(chan, buf, strlen(buf)); - printf("%s",buf); - - client_session = ssh_new(); - - /* ssh servers expect username without realm */ - ptr = strchr(username,'@'); - if(ptr) - *ptr= '\0'; - ssh_options_set(client_session, SSH_OPTIONS_HOST, host); - ssh_options_set(client_session, SSH_OPTIONS_USER, username); - ssh_gssapi_set_creds(client_session, client_creds); - rc = ssh_connect(client_session); - if (rc != SSH_OK){ - printf("Error connecting to %s: %s", host, ssh_get_error(client_session)); - return 1; - } - rc = ssh_userauth_none(client_session, NULL); - if(rc == SSH_AUTH_SUCCESS){ - printf("Authenticated using method none\n"); - } else { - rc = ssh_userauth_gssapi(client_session); - if(rc != SSH_AUTH_SUCCESS){ - printf("GSSAPI Authentication failed: %s\n",ssh_get_error(client_session)); - return 1; - } - } - snprintf(buf,sizeof(buf), "Authentication success\r\n"); - printf("%s",buf); - ssh_channel_write(chan,buf,strlen(buf)); - ssh_disconnect(client_session); - ssh_disconnect(session); - ssh_bind_free(sshbind); - ssh_finalize(); - return 0; -} - diff --git a/libssh/examples/sample.c b/libssh/examples/sample.c deleted file mode 100644 index 616372cb..00000000 --- a/libssh/examples/sample.c +++ /dev/null @@ -1,514 +0,0 @@ -/* 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 -#include -#include - -#include -#include - -#ifdef HAVE_TERMIOS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_PTY_H -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include - - -#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; (n < MAXCMD) && cmds[n] != NULL; 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;ic_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_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_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_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_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_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_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 -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include - -#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 diff --git a/libssh/examples/samplesshd-cb.c b/libssh/examples/samplesshd-cb.c deleted file mode 100644 index f93ab4b4..00000000 --- a/libssh/examples/samplesshd-cb.c +++ /dev/null @@ -1,306 +0,0 @@ -/* 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 -#include -#include - -#ifdef HAVE_ARGP_H -#include -#endif -#include -#include -#include - -#ifndef KEYS_FOLDER -#ifdef _WIN32 -#define KEYS_FOLDER -#else -#define KEYS_FOLDER "/etc/ssh/" -#endif -#endif - -#define USER "myuser" -#define PASSWORD "mypassword" - -static int authenticated=0; -static int tries = 0; -static int error = 0; -static ssh_channel chan=NULL; - -static int auth_password(ssh_session session, const char *user, - const char *password, void *userdata){ - (void)userdata; - printf("Authenticating user %s pwd %s\n",user, password); - if(strcmp(user,USER) == 0 && strcmp(password, PASSWORD) == 0){ - authenticated = 1; - printf("Authenticated\n"); - return SSH_AUTH_SUCCESS; - } - if (tries >= 3){ - printf("Too many authentication tries\n"); - ssh_disconnect(session); - error = 1; - return SSH_AUTH_DENIED; - } - tries++; - return SSH_AUTH_DENIED; -} - -static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata){ - ssh_gssapi_creds creds = ssh_gssapi_get_creds(session); - (void)userdata; - printf("Authenticating user %s with gssapi principal %s\n",user, principal); - if (creds != NULL) - printf("Received some gssapi credentials\n"); - else - printf("Not received any forwardable creds\n"); - printf("authenticated\n"); - authenticated = 1; - return SSH_AUTH_SUCCESS; -} - -static int pty_request(ssh_session session, ssh_channel channel, const char *term, - int x,int y, int px, int py, void *userdata){ - (void) session; - (void) channel; - (void) term; - (void) x; - (void) y; - (void) px; - (void) py; - (void) userdata; - printf("Allocated terminal\n"); - return 0; -} - -static int shell_request(ssh_session session, ssh_channel channel, void *userdata){ - (void)session; - (void)channel; - (void)userdata; - printf("Allocated shell\n"); - return 0; -} -struct ssh_channel_callbacks_struct channel_cb = { - .channel_pty_request_function = pty_request, - .channel_shell_request_function = shell_request -}; - -static ssh_channel new_session_channel(ssh_session session, void *userdata){ - (void) session; - (void) userdata; - if(chan != NULL) - return NULL; - printf("Allocated session channel\n"); - chan = ssh_channel_new(session); - ssh_callbacks_init(&channel_cb); - ssh_set_channel_callbacks(chan, &channel_cb); - return chan; -} - - -#ifdef HAVE_ARGP_H -const char *argp_program_version = "libssh server example " -SSH_STRINGIFY(LIBSSH_VERSION); -const char *argp_program_bug_address = ""; - -/* 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_event mainloop; - struct ssh_server_callbacks_struct cb = { - .userdata = NULL, - .auth_password_function = auth_password, - .auth_gssapi_mic_function = auth_gssapi_mic, - .channel_open_request_session_function = new_session_channel - }; - - char buf[2048]; - 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 - - 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; - } - ssh_callbacks_init(&cb); - ssh_set_server_callbacks(session, &cb); - - if (ssh_handle_key_exchange(session)) { - printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); - return 1; - } - ssh_set_auth_methods(session,SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC); - mainloop = ssh_event_new(); - ssh_event_add_session(mainloop, session); - - while (!(authenticated && chan != NULL)){ - if(error) - break; - r = ssh_event_dopoll(mainloop, -1); - if (r == SSH_ERROR){ - printf("Error : %s\n",ssh_get_error(session)); - ssh_disconnect(session); - return 1; - } - } - if(error){ - printf("Error, exiting loop\n"); - } else - printf("Authenticated and got a channel\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); - ssh_finalize(); - return 0; -} - diff --git a/libssh/examples/samplesshd-kbdint.c b/libssh/examples/samplesshd-kbdint.c deleted file mode 100644 index 5c2c461e..00000000 --- a/libssh/examples/samplesshd-kbdint.c +++ /dev/null @@ -1,413 +0,0 @@ -/* 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 -#include - -#ifdef HAVE_ARGP_H -#include -#endif -#include -#include -#include - -#define SSHD_USER "libssh" -#define SSHD_PASSWORD "libssh" - -#ifndef KEYS_FOLDER -#ifdef _WIN32 -#define KEYS_FOLDER -#else -#define KEYS_FOLDER "/etc/ssh/" -#endif -#endif - -static int port = 22; - -#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 = ""; - -/* 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, 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; -} - diff --git a/libssh/examples/scp_download.c b/libssh/examples/scp_download.c deleted file mode 100644 index ba8782a7..00000000 --- a/libssh/examples/scp_download.c +++ /dev/null @@ -1,175 +0,0 @@ -/* 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 -#include -#include -#include -#include - -#include -#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]; - int rc; - - 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)){ - rc = ssh_channel_read(channel,buffer,1,1); - if (rc != 1) { - fprintf(stderr, "Error reading from channel\n"); - ssh_channel_close(channel); - ssh_channel_free(channel); - return; - } - - rc = write(1, buffer, 1); - if (rc < 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; -} diff --git a/libssh/examples/senddata.c b/libssh/examples/senddata.c deleted file mode 100644 index acc1bebc..00000000 --- a/libssh/examples/senddata.c +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include -#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; -} diff --git a/libssh/examples/ssh_server_fork.c b/libssh/examples/ssh_server_fork.c deleted file mode 100644 index 837db6fe..00000000 --- a/libssh/examples/ssh_server_fork.c +++ /dev/null @@ -1,697 +0,0 @@ -/* This is a sample implementation of a libssh based SSH server */ -/* -Copyright 2014 Audrius Butkevicius - -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. -*/ - -#include "config.h" - -#include -#include -#include - -#ifdef HAVE_ARGP_H -#include -#endif -#include -#ifdef HAVE_LIBUTIL_H -#include -#endif -#ifdef HAVE_PTY_H -#include -#endif -#include -#include -#ifdef HAVE_UTMP_H -#include -#endif -#ifdef HAVE_UTIL_H -#include -#endif -#include -#include -#include - -#ifndef KEYS_FOLDER -#ifdef _WIN32 -#define KEYS_FOLDER -#else -#define KEYS_FOLDER "/etc/ssh/" -#endif -#endif - -#define USER "myuser" -#define PASS "mypassword" -#define BUF_SIZE 1048576 -#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR) -#define SFTP_SERVER_PATH "/usr/lib/sftp-server" - -static void set_default_keys(ssh_bind sshbind, - int rsa_already_set, - int dsa_already_set, - int ecdsa_already_set) { - if (!rsa_already_set) { - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, - KEYS_FOLDER "ssh_host_rsa_key"); - } - if (!dsa_already_set) { - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, - KEYS_FOLDER "ssh_host_dsa_key"); - } - if (!ecdsa_already_set) { - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, - KEYS_FOLDER "ssh_host_ecdsa_key"); - } -} - -#ifdef HAVE_ARGP_H -const char *argp_program_version = "libssh server example " -SSH_STRINGIFY(LIBSSH_VERSION); -const char *argp_program_bug_address = ""; - -/* 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 a host key. Can be used multiple times. " - "Implies no default keys.", - .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 = "ecdsakey", - .key = 'e', - .arg = "FILE", - .flags = 0, - .doc = "Set the ecdsa key.", - .group = 0 - }, - { - .name = "no-default-keys", - .key = 'n', - .arg = NULL, - .flags = 0, - .doc = "Do not set default key locations.", - .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; - static int no_default_keys = 0; - static int rsa_already_set = 0, dsa_already_set = 0, ecdsa_already_set = 0; - - switch (key) { - case 'n': - no_default_keys = 1; - break; - 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); - dsa_already_set = 1; - break; - case 'k': - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg); - /* We can't track the types of keys being added with this - option, so let's ensure we keep the keys we're adding - by just not setting the default keys */ - no_default_keys = 1; - break; - case 'r': - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg); - rsa_already_set = 1; - break; - case 'e': - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg); - ecdsa_already_set = 1; - 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); - } - - if (!no_default_keys) { - set_default_keys(sshbind, - rsa_already_set, - dsa_already_set, - ecdsa_already_set); - } - - 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 */ - -/* A userdata struct for channel. */ -struct channel_data_struct { - /* pid of the child process the channel will spawn. */ - pid_t pid; - /* For PTY allocation */ - socket_t pty_master; - socket_t pty_slave; - /* For communication with the child process. */ - socket_t stdin; - socket_t stdout; - /* Only used for subsystem and exec requests. */ - socket_t stderr; - /* Event which is used to poll the above descriptors. */ - ssh_event event; - /* Terminal size struct. */ - struct winsize *winsize; -}; - -/* A userdata struct for session. */ -struct session_data_struct { - /* Pointer to the channel the session will allocate. */ - ssh_channel channel; - int auth_attempts; - int authenticated; -}; - -static int data_function(ssh_session session, ssh_channel channel, void *data, - uint32_t len, int is_stderr, void *userdata) { - struct channel_data_struct *cdata = (struct channel_data_struct *) userdata; - - (void) session; - (void) channel; - (void) is_stderr; - - if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) { - return 0; - } - - return write(cdata->stdin, (char *) data, len); -} - -static int pty_request(ssh_session session, ssh_channel channel, - const char *term, int cols, int rows, int py, int px, - void *userdata) { - struct channel_data_struct *cdata = (struct channel_data_struct *)userdata; - - (void) session; - (void) channel; - (void) term; - - cdata->winsize->ws_row = rows; - cdata->winsize->ws_col = cols; - cdata->winsize->ws_xpixel = px; - cdata->winsize->ws_ypixel = py; - - if (openpty(&cdata->pty_master, &cdata->pty_slave, NULL, NULL, - cdata->winsize) != 0) { - fprintf(stderr, "Failed to open pty\n"); - return SSH_ERROR; - } - return SSH_OK; -} - -static int pty_resize(ssh_session session, ssh_channel channel, int cols, - int rows, int py, int px, void *userdata) { - struct channel_data_struct *cdata = (struct channel_data_struct *)userdata; - - (void) session; - (void) channel; - - cdata->winsize->ws_row = rows; - cdata->winsize->ws_col = cols; - cdata->winsize->ws_xpixel = px; - cdata->winsize->ws_ypixel = py; - - if (cdata->pty_master != -1) { - return ioctl(cdata->pty_master, TIOCSWINSZ, cdata->winsize); - } - - return SSH_ERROR; -} - -static int exec_pty(const char *mode, const char *command, - struct channel_data_struct *cdata) { - switch(cdata->pid = fork()) { - case -1: - close(cdata->pty_master); - close(cdata->pty_slave); - fprintf(stderr, "Failed to fork\n"); - return SSH_ERROR; - case 0: - close(cdata->pty_master); - if (login_tty(cdata->pty_slave) != 0) { - exit(1); - } - execl("/bin/sh", "sh", mode, command, NULL); - exit(0); - default: - close(cdata->pty_slave); - /* pty fd is bi-directional */ - cdata->stdout = cdata->stdin = cdata->pty_master; - } - return SSH_OK; -} - -static int exec_nopty(const char *command, struct channel_data_struct *cdata) { - int in[2], out[2], err[2]; - - /* Do the plumbing to be able to talk with the child process. */ - if (pipe(in) != 0) { - goto stdin_failed; - } - if (pipe(out) != 0) { - goto stdout_failed; - } - if (pipe(err) != 0) { - goto stderr_failed; - } - - switch(cdata->pid = fork()) { - case -1: - goto fork_failed; - case 0: - /* Finish the plumbing in the child process. */ - close(in[1]); - close(out[0]); - close(err[0]); - dup2(in[0], STDIN_FILENO); - dup2(out[1], STDOUT_FILENO); - dup2(err[1], STDERR_FILENO); - close(in[0]); - close(out[1]); - close(err[1]); - /* exec the requested command. */ - execl("/bin/sh", "sh", "-c", command, NULL); - exit(0); - } - - close(in[0]); - close(out[1]); - close(err[1]); - - cdata->stdin = in[1]; - cdata->stdout = out[0]; - cdata->stderr = err[0]; - - return SSH_OK; - -fork_failed: - close(err[0]); - close(err[1]); -stderr_failed: - close(out[0]); - close(out[1]); -stdout_failed: - close(in[0]); - close(in[1]); -stdin_failed: - return SSH_ERROR; -} - -static int exec_request(ssh_session session, ssh_channel channel, - const char *command, void *userdata) { - struct channel_data_struct *cdata = (struct channel_data_struct *) userdata; - - - (void) session; - (void) channel; - - if(cdata->pid > 0) { - return SSH_ERROR; - } - - if (cdata->pty_master != -1 && cdata->pty_slave != -1) { - return exec_pty("-c", command, cdata); - } - return exec_nopty(command, cdata); -} - -static int shell_request(ssh_session session, ssh_channel channel, - void *userdata) { - struct channel_data_struct *cdata = (struct channel_data_struct *) userdata; - - (void) session; - (void) channel; - - if(cdata->pid > 0) { - return SSH_ERROR; - } - - if (cdata->pty_master != -1 && cdata->pty_slave != -1) { - return exec_pty("-l", NULL, cdata); - } - /* Client requested a shell without a pty, let's pretend we allow that */ - return SSH_OK; -} - -static int subsystem_request(ssh_session session, ssh_channel channel, - const char *subsystem, void *userdata) { - /* subsystem requests behave simillarly to exec requests. */ - if (strcmp(subsystem, "sftp") == 0) { - return exec_request(session, channel, SFTP_SERVER_PATH, userdata); - } - return SSH_ERROR; -} - -static int auth_password(ssh_session session, const char *user, - const char *pass, void *userdata) { - struct session_data_struct *sdata = (struct session_data_struct *) userdata; - - (void) session; - - if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0) { - sdata->authenticated = 1; - return SSH_AUTH_SUCCESS; - } - - sdata->auth_attempts++; - return SSH_AUTH_DENIED; -} - -static ssh_channel channel_open(ssh_session session, void *userdata) { - struct session_data_struct *sdata = (struct session_data_struct *) userdata; - - sdata->channel = ssh_channel_new(session); - return sdata->channel; -} - -static int process_stdout(socket_t fd, int revents, void *userdata) { - char buf[BUF_SIZE]; - int n = -1; - ssh_channel channel = (ssh_channel) userdata; - - if (channel != NULL && (revents & POLLIN) != 0) { - n = read(fd, buf, BUF_SIZE); - if (n > 0) { - ssh_channel_write(channel, buf, n); - } - } - - return n; -} - -static int process_stderr(socket_t fd, int revents, void *userdata) { - char buf[BUF_SIZE]; - int n = -1; - ssh_channel channel = (ssh_channel) userdata; - - if (channel != NULL && (revents & POLLIN) != 0) { - n = read(fd, buf, BUF_SIZE); - if (n > 0) { - ssh_channel_write_stderr(channel, buf, n); - } - } - - return n; -} - -static void handle_session(ssh_event event, ssh_session session) { - int n, rc; - - /* Structure for storing the pty size. */ - struct winsize wsize = { - .ws_row = 0, - .ws_col = 0, - .ws_xpixel = 0, - .ws_ypixel = 0 - }; - - /* Our struct holding information about the channel. */ - struct channel_data_struct cdata = { - .pid = 0, - .pty_master = -1, - .pty_slave = -1, - .stdin = -1, - .stdout = -1, - .stderr = -1, - .event = NULL, - .winsize = &wsize - }; - - /* Our struct holding information about the session. */ - struct session_data_struct sdata = { - .channel = NULL, - .auth_attempts = 0, - .authenticated = 0 - }; - - struct ssh_channel_callbacks_struct channel_cb = { - .userdata = &cdata, - .channel_pty_request_function = pty_request, - .channel_pty_window_change_function = pty_resize, - .channel_shell_request_function = shell_request, - .channel_exec_request_function = exec_request, - .channel_data_function = data_function, - .channel_subsystem_request_function = subsystem_request - }; - - struct ssh_server_callbacks_struct server_cb = { - .userdata = &sdata, - .auth_password_function = auth_password, - .channel_open_request_session_function = channel_open, - }; - - ssh_callbacks_init(&server_cb); - ssh_callbacks_init(&channel_cb); - - ssh_set_server_callbacks(session, &server_cb); - - if (ssh_handle_key_exchange(session) != SSH_OK) { - fprintf(stderr, "%s\n", ssh_get_error(session)); - return; - } - - ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD); - ssh_event_add_session(event, session); - - n = 0; - while (sdata.authenticated == 0 || sdata.channel == NULL) { - /* If the user has used up all attempts, or if he hasn't been able to - * authenticate in 10 seconds (n * 100ms), disconnect. */ - if (sdata.auth_attempts >= 3 || n >= 100) { - return; - } - - if (ssh_event_dopoll(event, 100) == SSH_ERROR) { - fprintf(stderr, "%s\n", ssh_get_error(session)); - return; - } - n++; - } - - ssh_set_channel_callbacks(sdata.channel, &channel_cb); - - do { - /* Poll the main event which takes care of the session, the channel and - * even our child process's stdout/stderr (once it's started). */ - if (ssh_event_dopoll(event, -1) == SSH_ERROR) { - ssh_channel_close(sdata.channel); - } - - /* If child process's stdout/stderr has been registered with the event, - * or the child process hasn't started yet, continue. */ - if (cdata.event != NULL || cdata.pid == 0) { - continue; - } - /* Executed only once, once the child process starts. */ - cdata.event = event; - /* If stdout valid, add stdout to be monitored by the poll event. */ - if (cdata.stdout != -1) { - if (ssh_event_add_fd(event, cdata.stdout, POLLIN, process_stdout, - sdata.channel) != SSH_OK) { - fprintf(stderr, "Failed to register stdout to poll context\n"); - ssh_channel_close(sdata.channel); - } - } - - /* If stderr valid, add stderr to be monitored by the poll event. */ - if (cdata.stderr != -1){ - if (ssh_event_add_fd(event, cdata.stderr, POLLIN, process_stderr, - sdata.channel) != SSH_OK) { - fprintf(stderr, "Failed to register stderr to poll context\n"); - ssh_channel_close(sdata.channel); - } - } - } while(ssh_channel_is_open(sdata.channel) && - (cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0)); - - close(cdata.pty_master); - close(cdata.stdin); - close(cdata.stdout); - close(cdata.stderr); - - /* Remove the descriptors from the polling context, since they are now - * closed, they will always trigger during the poll calls. */ - ssh_event_remove_fd(event, cdata.stdout); - ssh_event_remove_fd(event, cdata.stderr); - - /* If the child process exited. */ - if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) { - rc = WEXITSTATUS(rc); - ssh_channel_request_send_exit_status(sdata.channel, rc); - /* If client terminated the channel or the process did not exit nicely, - * but only if something has been forked. */ - } else if (cdata.pid > 0) { - kill(cdata.pid, SIGKILL); - } - - ssh_channel_send_eof(sdata.channel); - ssh_channel_close(sdata.channel); - - /* Wait up to 5 seconds for the client to terminate the session. */ - for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) { - ssh_event_dopoll(event, 100); - } -} - -/* SIGCHLD handler for cleaning up dead children. */ -static void sigchld_handler(int signo) { - (void) signo; - while (waitpid(-1, NULL, WNOHANG) > 0); -} - -int main(int argc, char **argv) { - ssh_bind sshbind; - ssh_session session; - ssh_event event; - struct sigaction sa; - - /* Set up SIGCHLD handler. */ - sa.sa_handler = sigchld_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; - if (sigaction(SIGCHLD, &sa, NULL) != 0) { - fprintf(stderr, "Failed to register SIGCHLD handler\n"); - return 1; - } - - ssh_init(); - sshbind = ssh_bind_new(); - -#ifdef HAVE_ARGP_H - argp_parse(&argp, argc, argv, 0, 0, sshbind); -#else - (void) argc; - (void) argv; - - set_default_keys(sshbind, 0, 0, 0); -#endif /* HAVE_ARGP_H */ - - if(ssh_bind_listen(sshbind) < 0) { - fprintf(stderr, "%s\n", ssh_get_error(sshbind)); - return 1; - } - - while (1) { - session = ssh_new(); - if (session == NULL) { - fprintf(stderr, "Failed to allocate session\n"); - continue; - } - - /* Blocks until there is a new incoming connection. */ - if(ssh_bind_accept(sshbind, session) != SSH_ERROR) { - switch(fork()) { - case 0: - /* Remove the SIGCHLD handler inherited from parent. */ - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - /* Remove socket binding, which allows us to restart the - * parent process, without terminating existing sessions. */ - ssh_bind_free(sshbind); - - event = ssh_event_new(); - if (event != NULL) { - /* Blocks until the SSH session ends by either - * child process exiting, or client disconnecting. */ - handle_session(event, session); - ssh_event_free(event); - } else { - fprintf(stderr, "Could not create polling context\n"); - } - ssh_disconnect(session); - ssh_free(session); - - exit(0); - case -1: - fprintf(stderr, "Failed to fork\n"); - } - } else { - fprintf(stderr, "%s\n", ssh_get_error(sshbind)); - } - /* Since the session has been passed to a child fork, do some cleaning - * up at the parent process. */ - ssh_disconnect(session); - ssh_free(session); - } - - ssh_bind_free(sshbind); - ssh_finalize(); - return 0; -} diff --git a/libssh/examples/sshnetcat.c b/libssh/examples/sshnetcat.c deleted file mode 100644 index 8ac5a212..00000000 --- a/libssh/examples/sshnetcat.c +++ /dev/null @@ -1,265 +0,0 @@ -/* -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 -#include -#include -#ifdef HAVE_TERMIOS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "examples_common.h" -char *host; -const char *desthost="localhost"; -const char *port="22"; - -#ifdef WITH_PCAP -#include -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{ - int fd; - - FD_ZERO(&fds); - if(!eof) - FD_SET(0,&fds); - timeout.tv_sec=30; - timeout.tv_usec=0; - - fd = ssh_get_fd(session); - if (fd == -1) { - fprintf(stderr, "Error getting the session file descriptor: %s\n", - ssh_get_error(session)); - return; - } - FD_SET(fd, &fds); - maxfd = fd + 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) - ssh_channel_write(channel,buffer,lus); - else { - eof=1; - ssh_channel_send_eof(channel); - } - } - if(channel && ssh_channel_is_closed(channel)){ - ssh_channel_free(channel); - channel=NULL; - channels[0]=NULL; - } - if(outchannels[0]){ - while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)){ - lus = ssh_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_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 && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)){ /* stderr */ - lus = ssh_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_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 && ssh_channel_is_closed(channel)){ - ssh_channel_free(channel); - channel=NULL; - } - } while (ret==EINTR || ret==SSH_EINTR); - - } -} - -static void forwarding(ssh_session session){ - ssh_channel channel; - int r; - channel = ssh_channel_new(session); - r = ssh_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; - } - 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; -} diff --git a/libssh/include/CMakeLists.txt b/libssh/include/CMakeLists.txt deleted file mode 100644 index cb3bd962..00000000 --- a/libssh/include/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -project(headers C) - -add_subdirectory(libssh) diff --git a/libssh/include/libssh/CMakeLists.txt b/libssh/include/libssh/CMakeLists.txt deleted file mode 100644 index 78ee1c61..00000000 --- a/libssh/include/libssh/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -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 -) - diff --git a/libssh/include/libssh/agent.h b/libssh/include/libssh/agent.h deleted file mode 100644 index 77209d0f..00000000 --- a/libssh/include/libssh/agent.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2008-2009 Andreas Schneider - * - * 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; - ssh_channel channel; -}; - -#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: */ diff --git a/libssh/include/libssh/auth.h b/libssh/include/libssh/auth.h deleted file mode 100644 index 2c0012b0..00000000 --- a/libssh/include/libssh/auth.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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, - /** We have sent an userauth request with gssapi-with-mic */ - SSH_AUTH_STATE_GSSAPI_REQUEST_SENT, - /** We are exchanging tokens until authentication */ - SSH_AUTH_STATE_GSSAPI_TOKEN, - /** We have sent the MIC and expecting to be authenticated */ - SSH_AUTH_STATE_GSSAPI_MIC_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_ */ diff --git a/libssh/include/libssh/bignum.h b/libssh/include/libssh/bignum.h deleted file mode 100644 index e5f2a472..00000000 --- a/libssh/include/libssh/bignum.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2014 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 BIGNUM_H_ -#define BIGNUM_H_ - -#include "libssh/libcrypto.h" -#include "libssh/libgcrypt.h" - -bignum make_string_bn(ssh_string string); -ssh_string make_bignum_string(bignum num); -void ssh_print_bignum(const char *which,bignum num); - - -#endif /* BIGNUM_H_ */ diff --git a/libssh/include/libssh/bind.h b/libssh/include/libssh/bind.h deleted file mode 100644 index ced1c494..00000000 --- a/libssh/include/libssh/bind.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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_ */ diff --git a/libssh/include/libssh/buffer.h b/libssh/include/libssh/buffer.h deleted file mode 100644 index 2aebe7e7..00000000 --- a/libssh/include/libssh/buffer.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 - -#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; - int secure; -}; - -#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3) - -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); -void ssh_buffer_set_secure(ssh_buffer buffer); -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 ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len); -int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap); -int _ssh_buffer_pack(struct ssh_buffer_struct *buffer, const char *format, ...); -#define ssh_buffer_pack(buffer, format, ...) _ssh_buffer_pack((buffer),(format), __VA_ARGS__, SSH_BUFFER_PACK_END) -int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap); -int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer, const char *format, ...); -#define ssh_buffer_unpack(buffer, format, ...) _ssh_buffer_unpack((buffer),(format), __VA_ARGS__, SSH_BUFFER_PACK_END) - -int buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len); -int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source); -int ssh_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_ */ diff --git a/libssh/include/libssh/callbacks.h b/libssh/include/libssh/callbacks.h deleted file mode 100644 index 6bd8c573..00000000 --- a/libssh/include/libssh/callbacks.h +++ /dev/null @@ -1,855 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2009 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 - */ - -/* callback.h - * This file includes the public declarations for the libssh callback mechanism - */ - -#ifndef _SSH_CALLBACK_H -#define _SSH_CALLBACK_H - -#include -#include - -#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 log callback. - * - * All logging messages will go through this callback. - * - * @param priority Priority of the log, the smaller being the more important. - * - * @param function The function name calling the the logging fucntions. - * - * @param message The actual message - * - * @param userdata Userdata to be passed to the callback function. - */ -typedef void (*ssh_logging_callback) (int priority, - const char *function, - const char *buffer, - 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); - -/** - * @brief Handles an SSH new channel open X11 request. This happens when the server - * sends back an X11 connection attempt. This is a client-side API - * @param session current session handler - * @param userdata Userdata to be passed to the callback function. - * @returns a valid ssh_channel handle if the request is to be allowed - * @returns NULL if the request should not be allowed - * @warning The channel pointer returned by this callback must be closed by the application. - */ -typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session session, - const char * originator_address, int originator_port, 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; - /** This function will be called when an incoming X11 request is received. - */ - ssh_channel_open_request_x11_callback channel_open_request_x11_function; -}; -typedef struct ssh_callbacks_struct *ssh_callbacks; - -/** These are callbacks used specifically in SSH servers. - */ - -/** - * @brief SSH authentication callback. - * @param session Current session handler - * @param user User that wants to authenticate - * @param password Password used for authentication - * @param userdata Userdata to be passed to the callback function. - * @returns SSH_AUTH_SUCCESS Authentication is accepted. - * @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed. - * @returns SSH_AUTH_DENIED Authentication failed. - */ -typedef int (*ssh_auth_password_callback) (ssh_session session, const char *user, const char *password, - void *userdata); - -/** - * @brief SSH authentication callback. Tries to authenticates user with the "none" method - * which is anonymous or passwordless. - * @param session Current session handler - * @param user User that wants to authenticate - * @param userdata Userdata to be passed to the callback function. - * @returns SSH_AUTH_SUCCESS Authentication is accepted. - * @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed. - * @returns SSH_AUTH_DENIED Authentication failed. - */ -typedef int (*ssh_auth_none_callback) (ssh_session session, const char *user, void *userdata); - -/** - * @brief SSH authentication callback. Tries to authenticates user with the "gssapi-with-mic" method - * @param session Current session handler - * @param user Username of the user (can be spoofed) - * @param principal Authenticated principal of the user, including realm. - * @param userdata Userdata to be passed to the callback function. - * @returns SSH_AUTH_SUCCESS Authentication is accepted. - * @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed. - * @returns SSH_AUTH_DENIED Authentication failed. - * @warning Implementations should verify that parameter user matches in some way the principal. - * user and principal can be different. Only the latter is guaranteed to be safe. - */ -typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *user, const char *principal, - void *userdata); - -/** - * @brief SSH authentication callback. - * @param session Current session handler - * @param user User that wants to authenticate - * @param pubkey public key used for authentication - * @param signature_state SSH_PUBLICKEY_STATE_NONE if the key is not signed (simple public key probe), - * SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be - * replied with a SSH_AUTH_DENIED. - * @param userdata Userdata to be passed to the callback function. - * @returns SSH_AUTH_SUCCESS Authentication is accepted. - * @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed. - * @returns SSH_AUTH_DENIED Authentication failed. - */ -typedef int (*ssh_auth_pubkey_callback) (ssh_session session, const char *user, struct ssh_key_struct *pubkey, - char signature_state, void *userdata); - - -/** - * @brief Handles an SSH service request - * @param session current session handler - * @param service name of the service (e.g. "ssh-userauth") requested - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the request is to be allowed - * @returns -1 if the request should not be allowed - */ - -typedef int (*ssh_service_request_callback) (ssh_session session, const char *service, void *userdata); - -/** - * @brief Handles an SSH new channel open session request - * @param session current session handler - * @param userdata Userdata to be passed to the callback function. - * @returns a valid ssh_channel handle if the request is to be allowed - * @returns NULL if the request should not be allowed - * @warning The channel pointer returned by this callback must be closed by the application. - */ -typedef ssh_channel (*ssh_channel_open_request_session_callback) (ssh_session session, void *userdata); - -/* - * @brief handle the beginning of a GSSAPI authentication, server side. - * @param session current session handler - * @param user the username of the client - * @param n_oid number of available oids - * @param oids OIDs provided by the client - * @returns an ssh_string containing the chosen OID, that's supported by both - * client and server. - * @warning It is not necessary to fill this callback in if libssh is linked - * with libgssapi. - */ -typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const char *user, - int n_oid, ssh_string *oids, void *userdata); - -/* - * @brief handle the negociation of a security context, server side. - * @param session current session handler - * @param[in] input_token input token provided by client - * @param[out] output_token output of the gssapi accept_sec_context method, - * NULL after completion. - * @returns SSH_OK if the token was generated correctly or accept_sec_context - * returned GSS_S_COMPLETE - * @returns SSH_ERROR in case of error - * @warning It is not necessary to fill this callback in if libssh is linked - * with libgssapi. - */ -typedef int (*ssh_gssapi_accept_sec_ctx_callback) (ssh_session session, - ssh_string input_token, ssh_string *output_token, void *userdata); - -/* - * @brief Verify and authenticates a MIC, server side. - * @param session current session handler - * @param[in] mic input mic to be verified provided by client - * @param[in] mic_buffer buffer of data to be signed. - * @param[in] mic_buffer_size size of mic_buffer - * @returns SSH_OK if the MIC was authenticated correctly - * @returns SSH_ERROR in case of error - * @warning It is not necessary to fill this callback in if libssh is linked - * with libgssapi. - */ -typedef int (*ssh_gssapi_verify_mic_callback) (ssh_session session, - ssh_string mic, void *mic_buffer, size_t mic_buffer_size, void *userdata); - - -/** - * This structure can be used to implement a libssh server, with appropriate callbacks. - */ - -struct ssh_server_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 function gets called when a client tries to authenticate through - * password method. - */ - ssh_auth_password_callback auth_password_function; - - /** This function gets called when a client tries to authenticate through - * none method. - */ - ssh_auth_none_callback auth_none_function; - - /** This function gets called when a client tries to authenticate through - * gssapi-mic method. - */ - ssh_auth_gssapi_mic_callback auth_gssapi_mic_function; - - /** this function gets called when a client tries to authenticate or offer - * a public key. - */ - ssh_auth_pubkey_callback auth_pubkey_function; - - /** This functions gets called when a service request is issued by the - * client - */ - ssh_service_request_callback service_request_function; - /** This functions gets called when a new channel request is issued by - * the client - */ - ssh_channel_open_request_session_callback channel_open_request_session_function; - /** This function will be called when a new gssapi authentication is attempted. - */ - ssh_gssapi_select_oid_callback gssapi_select_oid_function; - /** This function will be called when a gssapi token comes in. - */ - ssh_gssapi_accept_sec_ctx_callback gssapi_accept_sec_ctx_function; - /* This function will be called when a MIC needs to be verified. - */ - ssh_gssapi_verify_mic_callback gssapi_verify_mic_function; -}; -typedef struct ssh_server_callbacks_struct *ssh_server_callbacks; - -/** - * @brief Set the session server callback functions. - * - * This functions sets the callback structure to use your own callback - * functions for user authentication, new channels and requests. - * - * @code - * struct ssh_server_callbacks_struct cb = { - * .userdata = data, - * .auth_password_function = my_auth_function - * }; - * ssh_callbacks_init(&cb); - * ssh_set_server_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_server_callbacks(ssh_session session, ssh_server_callbacks cb); - -/** - * 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. - * @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_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); - -/** - * @brief SSH channel PTY request from a client. - * @param channel the channel - * @param term The type of terminal emulation - * @param width width of the terminal, in characters - * @param height height of the terminal, in characters - * @param pxwidth width of the terminal, in pixels - * @param pxheight height of the terminal, in pixels - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the pty request is accepted - * @returns -1 if the request is denied - */ -typedef int (*ssh_channel_pty_request_callback) (ssh_session session, - ssh_channel channel, - const char *term, - int width, int height, - int pxwidth, int pwheight, - void *userdata); - -/** - * @brief SSH channel Shell request from a client. - * @param channel the channel - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the shell request is accepted - * @returns 1 if the request is denied - */ -typedef int (*ssh_channel_shell_request_callback) (ssh_session session, - ssh_channel channel, - void *userdata); -/** - * @brief SSH auth-agent-request from the client. This request is - * sent by a client when agent forwarding is available. - * Server is free to ignore this callback, no answer is expected. - * @param channel the channel - * @param userdata Userdata to be passed to the callback function. - */ -typedef void (*ssh_channel_auth_agent_req_callback) (ssh_session session, - ssh_channel channel, - void *userdata); - -/** - * @brief SSH X11 request from the client. This request is - * sent by a client when X11 forwarding is requested(and available). - * Server is free to ignore this callback, no answer is expected. - * @param channel the channel - * @param userdata Userdata to be passed to the callback function. - */ -typedef void (*ssh_channel_x11_req_callback) (ssh_session session, - ssh_channel channel, - int single_connection, - const char *auth_protocol, - const char *auth_cookie, - uint32_t screen_number, - void *userdata); -/** - * @brief SSH channel PTY windows change (terminal size) from a client. - * @param channel the channel - * @param width width of the terminal, in characters - * @param height height of the terminal, in characters - * @param pxwidth width of the terminal, in pixels - * @param pxheight height of the terminal, in pixels - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the pty request is accepted - * @returns -1 if the request is denied - */ -typedef int (*ssh_channel_pty_window_change_callback) (ssh_session session, - ssh_channel channel, - int width, int height, - int pxwidth, int pwheight, - void *userdata); - -/** - * @brief SSH channel Exec request from a client. - * @param channel the channel - * @param command the shell command to be executed - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the exec request is accepted - * @returns 1 if the request is denied - */ -typedef int (*ssh_channel_exec_request_callback) (ssh_session session, - ssh_channel channel, - const char *command, - void *userdata); - -/** - * @brief SSH channel environment request from a client. - * @param channel the channel - * @param env_name name of the environment value to be set - * @param env_value value of the environment value to be set - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the env request is accepted - * @returns 1 if the request is denied - * @warning some environment variables can be dangerous if changed (e.g. - * LD_PRELOAD) and should not be fulfilled. - */ -typedef int (*ssh_channel_env_request_callback) (ssh_session session, - ssh_channel channel, - const char *env_name, - const char *env_value, - void *userdata); -/** - * @brief SSH channel subsystem request from a client. - * @param channel the channel - * @param subsystem the subsystem required - * @param userdata Userdata to be passed to the callback function. - * @returns 0 if the subsystem request is accepted - * @returns 1 if the request is denied - */ -typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session, - ssh_channel channel, - const char *subsystem, - 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; - /** - * This function will be called when a client requests a PTY - */ - ssh_channel_pty_request_callback channel_pty_request_function; - /** - * This function will be called when a client requests a shell - */ - ssh_channel_shell_request_callback channel_shell_request_function; - /** This function will be called when a client requests agent - * authentication forwarding. - */ - ssh_channel_auth_agent_req_callback channel_auth_agent_req_function; - /** This function will be called when a client requests X11 - * forwarding. - */ - ssh_channel_x11_req_callback channel_x11_req_function; - /** This function will be called when a client requests a - * window change. - */ - ssh_channel_pty_window_change_callback channel_pty_window_change_function; - /** This function will be called when a client requests a - * command execution. - */ - ssh_channel_exec_request_callback channel_exec_request_function; - /** This function will be called when a client requests an environment - * variable to be set. - */ - ssh_channel_env_request_callback channel_env_request_function; - /** This function will be called when a client requests a subsystem - * (like sftp). - */ - ssh_channel_subsystem_request_callback channel_subsystem_request_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 Set the thread callbacks structure. - * - * This is 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() function for instance), before you call ssh_init(). - * - * @param[in] cb A pointer to a ssh_threads_callbacks_struct structure, which - * contains the different callbacks to be set. - * - * @returns Always returns SSH_OK. - * - * @see ssh_threads_callbacks_struct - * @see SSH_THREADS_PTHREAD - * @bug libgcrypt 1.6 and bigger backend does not support custom callback. - * Using anything else than pthreads here will fail. - */ -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 Get the noop threads callbacks structure - * - * This can be used with ssh_threads_set_callbacks. These callbacks do nothing - * and are being used by default. - * - * @return Always returns a valid pointer to the noop callbacks structure. - * - * @see ssh_threads_set_callbacks - */ -LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void); - -/** - * @brief Set the logging callback function. - * - * @param[in] cb The callback to set. - * - * @return 0 on success, < 0 on errror. - */ -LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb); - -/** - * @brief Get the pointer to the logging callback function. - * - * @return The pointer the the callback or NULL if none set. - */ -LIBSSH_API ssh_logging_callback ssh_get_log_callback(void); - -/** @} */ -#ifdef __cplusplus -} -#endif - -#endif /*_SSH_CALLBACK_H */ - -/* @} */ diff --git a/libssh/include/libssh/channels.h b/libssh/include/libssh/channels.h deleted file mode 100644 index b05c4c02..00000000 --- a/libssh/include/libssh/channels.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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; - /* counters */ - ssh_counter counter; -}; - -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); -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_ */ diff --git a/libssh/include/libssh/crc32.h b/libssh/include/libssh/crc32.h deleted file mode 100644 index 07c0cafc..00000000 --- a/libssh/include/libssh/crc32.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 */ diff --git a/libssh/include/libssh/crypto.h b/libssh/include/libssh/crypto.h deleted file mode 100644 index 61a2b27b..00000000 --- a/libssh/include/libssh/crypto.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 -#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 -#endif -#include "libssh/ecdh.h" -#include "libssh/kex.h" -#include "libssh/curve25519.h" - -#define DIGEST_MAX_LEN 64 - -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, - /* curve25519-sha256@libssh.org */ - SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG -}; - -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 -#ifdef HAVE_CURVE25519 - ssh_curve25519_privkey curve25519_privkey; - ssh_curve25519_pubkey curve25519_client_pubkey; - ssh_curve25519_pubkey curve25519_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[DIGEST_MAX_LEN]; - struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */ - enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */ - - 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 (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len); - void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len); -}; - -/* vim: set ts=2 sw=2 et cindent: */ -#endif /* _CRYPTO_H_ */ diff --git a/libssh/include/libssh/curve25519.h b/libssh/include/libssh/curve25519.h deleted file mode 100644 index 0406b9ee..00000000 --- a/libssh/include/libssh/curve25519.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2013 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, - * version 2.1 of the License. - * - * 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 CURVE25519_H_ -#define CURVE25519_H_ - -#include "config.h" -#include "libssh.h" - -#ifdef WITH_NACL - -#include -#define CURVE25519_PUBKEY_SIZE crypto_scalarmult_curve25519_BYTES -#define CURVE25519_PRIVKEY_SIZE crypto_scalarmult_curve25519_SCALARBYTES -#define crypto_scalarmult_base crypto_scalarmult_curve25519_base -#define crypto_scalarmult crypto_scalarmult_curve25519 -#else - -#define CURVE25519_PUBKEY_SIZE 32 -#define CURVE25519_PRIVKEY_SIZE 32 -int crypto_scalarmult_base(unsigned char *q, const unsigned char *n); -int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p); -#endif /* WITH_NACL */ - -#ifdef HAVE_ECC -#define HAVE_CURVE25519 1 -#endif - -typedef unsigned char ssh_curve25519_pubkey[CURVE25519_PUBKEY_SIZE]; -typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE]; - - -int ssh_client_curve25519_init(ssh_session session); -int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet); - -#ifdef WITH_SERVER -int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet); -#endif /* WITH_SERVER */ - -#endif /* CURVE25519_H_ */ diff --git a/libssh/include/libssh/dh.h b/libssh/include/libssh/dh.h deleted file mode 100644 index 95b76cdd..00000000 --- a/libssh/include/libssh/dh.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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" - -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); - -#endif /* DH_H_ */ diff --git a/libssh/include/libssh/ecdh.h b/libssh/include/libssh/ecdh.h deleted file mode 100644 index 8d1e7515..00000000 --- a/libssh/include/libssh/ecdh.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 - -#ifdef HAVE_ECC -#define HAVE_ECDH 1 -#endif - -#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_ */ diff --git a/libssh/include/libssh/ed25519.h b/libssh/include/libssh/ed25519.h deleted file mode 100644 index 7b48856c..00000000 --- a/libssh/include/libssh/ed25519.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2014 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 ED25519_H_ -#define ED25519_H_ -#include "libssh/priv.h" - -/** - * @defgroup ed25519 ed25519 API - * @internal - * @brief API for DJB's ed25519 - * - * @{ */ - -#define ED25519_PK_LEN 32 -#define ED25519_SK_LEN 64 -#define ED25519_SIG_LEN 64 - -typedef uint8_t ed25519_pubkey[ED25519_PK_LEN]; -typedef uint8_t ed25519_privkey[ED25519_SK_LEN]; -typedef uint8_t ed25519_signature[ED25519_SIG_LEN]; - -/** @internal - * @brief generate an ed25519 key pair - * @param[out] pk generated public key - * @param[out] sk generated secret key - * @return 0 on success, -1 on error. - * */ -int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk); - -/** @internal - * @brief sign a message with ed25519 - * @param[out] sm location to store the signed message. - * Its length should be mlen + 64. - * @param[out] smlen pointer to the size of the signed message - * @param[in] m message to be signed - * @param[in] mlen length of the message to be signed - * @param[in] sk secret key to sign the message with - * @return 0 on success. - */ -int crypto_sign_ed25519( - unsigned char *sm,unsigned long long *smlen, - const unsigned char *m,unsigned long long mlen, - const ed25519_privkey sk); - -/** @internal - * @brief "open" and verify the signature of a signed message - * @param[out] m location to store the verified message. - * Its length should be equal to smlen. - * @param[out] mlen pointer to the size of the verified message - * @param[in] sm signed message to verify - * @param[in] smlen length of the signed message to verify - * @param[in] pk public key used to sign the message - * @returns 0 on success (supposedly). - */ -int crypto_sign_ed25519_open( - unsigned char *m,unsigned long long *mlen, - const unsigned char *sm,unsigned long long smlen, - const ed25519_pubkey pk); - -/** @} */ -#endif /* ED25519_H_ */ diff --git a/libssh/include/libssh/fe25519.h b/libssh/include/libssh/fe25519.h deleted file mode 100644 index e959912e..00000000 --- a/libssh/include/libssh/fe25519.h +++ /dev/null @@ -1,68 +0,0 @@ -/* $OpenBSD: fe25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */ - -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h - */ - -#ifndef FE25519_H -#define FE25519_H - -#include "libssh/priv.h" - -#define fe25519 crypto_sign_ed25519_ref_fe25519 -#define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze -#define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack -#define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack -#define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero -#define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime -#define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov -#define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone -#define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero -#define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg -#define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity -#define fe25519_add crypto_sign_ed25519_ref_fe25519_add -#define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub -#define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul -#define fe25519_square crypto_sign_ed25519_ref_fe25519_square -#define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert -#define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523 - -typedef struct { - uint32_t v[32]; -} fe25519; - -void fe25519_freeze(fe25519 *r); - -void fe25519_unpack(fe25519 *r, const unsigned char x[32]); - -void fe25519_pack(unsigned char r[32], const fe25519 *x); - -int fe25519_iszero(const fe25519 *x); - -int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y); - -void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b); - -void fe25519_setone(fe25519 *r); - -void fe25519_setzero(fe25519 *r); - -void fe25519_neg(fe25519 *r, const fe25519 *x); - -unsigned char fe25519_getparity(const fe25519 *x); - -void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y); - -void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); - -void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y); - -void fe25519_square(fe25519 *r, const fe25519 *x); - -void fe25519_invert(fe25519 *r, const fe25519 *x); - -void fe25519_pow2523(fe25519 *r, const fe25519 *x); - -#endif diff --git a/libssh/include/libssh/ge25519.h b/libssh/include/libssh/ge25519.h deleted file mode 100644 index 64f63c6f..00000000 --- a/libssh/include/libssh/ge25519.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $OpenBSD: ge25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */ - -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h - */ - -#ifndef GE25519_H -#define GE25519_H - -#include "fe25519.h" -#include "sc25519.h" - -#define ge25519 crypto_sign_ed25519_ref_ge25519 -#define ge25519_base crypto_sign_ed25519_ref_ge25519_base -#define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime -#define ge25519_pack crypto_sign_ed25519_ref_pack -#define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime -#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime -#define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base - -typedef struct -{ - fe25519 x; - fe25519 y; - fe25519 z; - fe25519 t; -} ge25519; - -const ge25519 ge25519_base; - -int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]); - -void ge25519_pack(unsigned char r[32], const ge25519 *p); - -int ge25519_isneutral_vartime(const ge25519 *p); - -void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2); - -void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s); - -#endif diff --git a/libssh/include/libssh/gssapi.h b/libssh/include/libssh/gssapi.h deleted file mode 100644 index ccd83664..00000000 --- a/libssh/include/libssh/gssapi.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2013 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 GSSAPI_H_ -#define GSSAPI_H_ - -#include "config.h" -#include "session.h" - -/* all OID begin with the tag identifier + length */ -#define SSH_OID_TAG 06 - -typedef struct ssh_gssapi_struct *ssh_gssapi; - -#ifdef WITH_SERVER -int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids); -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server); -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic); -#endif /* WITH_SERVER */ - -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token); -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client); -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response); - - -int ssh_gssapi_auth_mic(ssh_session session); - -#endif /* GSSAPI_H */ diff --git a/libssh/include/libssh/kex.h b/libssh/include/libssh/kex.h deleted file mode 100644 index 1a5b6d41..00000000 --- a/libssh/include/libssh/kex.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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(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_ */ diff --git a/libssh/include/libssh/keys.h b/libssh/include/libssh/keys.h deleted file mode 100644 index 6f08e070..00000000 --- a/libssh/include/libssh/keys.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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_ */ diff --git a/libssh/include/libssh/knownhosts.h b/libssh/include/libssh/knownhosts.h deleted file mode 100644 index 723c7ebc..00000000 --- a/libssh/include/libssh/knownhosts.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 20014 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. - * - * 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 KNOWNHOSTS_H_ -#define KNOWNHOSTS_H_ - -char **ssh_knownhosts_algorithms(ssh_session session); - -#endif /* KNOWNHOSTS_H_ */ diff --git a/libssh/include/libssh/legacy.h b/libssh/include/libssh/legacy.h deleted file mode 100644 index 911173ee..00000000 --- a/libssh/include/libssh/legacy.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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); - -SSH_DEPRECATED LIBSSH_API void buffer_free(ssh_buffer buffer); -SSH_DEPRECATED LIBSSH_API void *buffer_get(ssh_buffer buffer); -SSH_DEPRECATED LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer); -SSH_DEPRECATED LIBSSH_API ssh_buffer buffer_new(void); - -SSH_DEPRECATED LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms); -SSH_DEPRECATED LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows); -SSH_DEPRECATED LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms); -SSH_DEPRECATED LIBSSH_API int channel_close(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port); -SSH_DEPRECATED LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port); -SSH_DEPRECATED LIBSSH_API void channel_free(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_get_exit_status(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API ssh_session channel_get_session(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_is_closed(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_is_eof(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_is_open(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API ssh_channel channel_new(ssh_session session); -SSH_DEPRECATED LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost, - int remoteport, const char *sourcehost, int localport); -SSH_DEPRECATED LIBSSH_API int channel_open_session(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr); -SSH_DEPRECATED LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr); - -SSH_DEPRECATED LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count, - int is_stderr); - -SSH_DEPRECATED LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count, - int is_stderr); -SSH_DEPRECATED LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value); -SSH_DEPRECATED LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd); -SSH_DEPRECATED LIBSSH_API int channel_request_pty(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term, - int cols, int rows); -SSH_DEPRECATED LIBSSH_API int channel_request_shell(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum); -SSH_DEPRECATED LIBSSH_API int channel_request_sftp(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem); -SSH_DEPRECATED LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol, - const char *cookie, int screen_number); -SSH_DEPRECATED LIBSSH_API int channel_send_eof(ssh_channel channel); -SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct - timeval * timeout); -SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking); -SSH_DEPRECATED 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); - -SSH_DEPRECATED LIBSSH_API void string_burn(ssh_string str); -SSH_DEPRECATED LIBSSH_API ssh_string string_copy(ssh_string str); -SSH_DEPRECATED LIBSSH_API void *string_data(ssh_string str); -SSH_DEPRECATED LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len); -SSH_DEPRECATED LIBSSH_API void string_free(ssh_string str); -SSH_DEPRECATED LIBSSH_API ssh_string string_from_char(const char *what); -SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str); -SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size); -SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str); - -#endif /* LEGACY_H_ */ diff --git a/libssh/include/libssh/libcrypto.h b/libssh/include/libssh/libcrypto.h deleted file mode 100644 index c3783880..00000000 --- a/libssh/include/libssh/libcrypto.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#ifdef HAVE_OPENSSL_ECC -#include -#endif - -typedef SHA_CTX* SHACTX; -typedef SHA256_CTX* SHA256CTX; -typedef SHA512_CTX* SHA384CTX; -typedef SHA512_CTX* SHA512CTX; -typedef MD5_CTX* MD5CTX; -typedef HMAC_CTX* HMACCTX; -#ifdef HAVE_ECC -typedef EVP_MD_CTX *EVPCTX; -#else -typedef void *EVPCTX; -#endif - -#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH -#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH -#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH -#define SHA512_DIGEST_LEN SHA512_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 -#include -#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); - -SHA384CTX sha384_init(void); -void sha384_update(SHA384CTX c, const void *data, unsigned long len); -void sha384_final(unsigned char *md, SHA384CTX c); - -SHA512CTX sha512_init(void); -void sha512_update(SHA512CTX c, const void *data, unsigned long len); -void sha512_final(unsigned char *md, SHA512CTX c); - -struct ssh_cipher_struct *ssh_get_ciphertab(void); - -#endif /* HAVE_LIBCRYPTO */ - -#endif /* LIBCRYPTO_H_ */ diff --git a/libssh/include/libssh/libgcrypt.h b/libssh/include/libssh/libgcrypt.h deleted file mode 100644 index 8e52a681..00000000 --- a/libssh/include/libssh/libgcrypt.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 -typedef gcry_md_hd_t SHACTX; -typedef gcry_md_hd_t SHA256CTX; -typedef gcry_md_hd_t SHA384CTX; -typedef gcry_md_hd_t SHA512CTX; -typedef gcry_md_hd_t MD5CTX; -typedef gcry_md_hd_t HMACCTX; -typedef void *EVPCTX; -#define SHA_DIGEST_LENGTH 20 -#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH -#define MD5_DIGEST_LEN 16 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH -#define SHA384_DIGEST_LENGTH 48 -#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH - -#ifndef EVP_MAX_MD_SIZE -#define EVP_MAX_MD_SIZE 64 -#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_ */ diff --git a/libssh/include/libssh/libssh.h b/libssh/include/libssh/libssh.h deleted file mode 100644 index ba4f5f44..00000000 --- a/libssh/include/libssh/libssh.h +++ /dev/null @@ -1,674 +0,0 @@ -/* - * 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 - #include -#endif /* _MSC_VER */ - -#ifdef _WIN32 - #include -#else /* _WIN32 */ - #include /* for fd_set * */ - #include -#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 - -struct ssh_counter_struct { - uint64_t in_bytes; - uint64_t out_bytes; - uint64_t in_packets; - uint64_t out_packets; -}; -typedef struct ssh_counter_struct *ssh_counter; - -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; -typedef void* ssh_gssapi_creds; - -/* 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 -#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020 - -/* 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 */ -/** Socket is closed */ -#define SSH_CLOSED 0x01 -/** Reading to socket won't block */ -#define SSH_READ_PENDING 0x02 -/** Session was closed due to an error */ -#define SSH_CLOSED_ERROR 0x04 -/** Output buffer not empty */ -#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, - SSH_KEYTYPE_ED25519 -}; - -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, - SSH_OPTIONS_GSSAPI_SERVER_IDENTITY, - SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY, - SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS, - SSH_OPTIONS_HMAC_C_S, - SSH_OPTIONS_HMAC_S_C, -}; - -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_auth_agent(ssh_channel channel); -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_open_x11(ssh_channel channel, const char *orig_addr, int orig_port); -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_timeout(ssh_channel channel, void *dest, uint32_t count, int is_stderr, int timeout_ms); -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 void ssh_channel_set_counter(ssh_channel channel, - ssh_counter counter); -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); - -/* REVERSE PORT FORWARDING */ -LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session, - int timeout_ms, - int *destination_port); -LIBSSH_API int ssh_channel_cancel_forward(ssh_session session, - const char *address, - int port); -LIBSSH_API int ssh_channel_listen_forward(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); - -enum ssh_publickey_hash_type { - SSH_PUBLICKEY_HASH_SHA1, - SSH_PUBLICKEY_HASH_MD5 -}; -LIBSSH_API int ssh_get_publickey_hash(const ssh_key key, - enum ssh_publickey_hash_type type, - unsigned char **hash, - size_t *hlen); - -/* DEPRECATED FUNCTIONS */ -SSH_DEPRECATED LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash); -SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms); -SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port); -SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port); - - -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_get_poll_flags(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); - -/* LOGGING */ -LIBSSH_API int ssh_set_log_level(int level); -LIBSSH_API int ssh_get_log_level(void); -LIBSSH_API void *ssh_get_log_userdata(void); -LIBSSH_API int ssh_set_log_userdata(void *data); -LIBSSH_API void _ssh_log(int verbosity, - const char *function, - const char *format, ...) PRINTF_ATTRIBUTE(3, 4); - -/* legacy */ -SSH_DEPRECATED 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_export_privkey_file(const ssh_key privkey, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data, - const char *filename); - -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 const char *ssh_pki_key_ecdsa_name(const ssh_key key); - -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 void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds); -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 int ssh_set_agent_channel(ssh_session session, ssh_channel channel); -LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking); -LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter, - ssh_counter rcounter); -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 int ssh_userauth_gssapi(ssh_session session); -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_clientbanner(ssh_session session); -LIBSSH_API const char* ssh_get_serverbanner(ssh_session session); -LIBSSH_API const char* ssh_get_cipher_in(ssh_session session); -LIBSSH_API const char* ssh_get_cipher_out(ssh_session session); -LIBSSH_API const char* ssh_get_hmac_in(ssh_session session); -LIBSSH_API const char* ssh_get_hmac_out(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: */ diff --git a/libssh/include/libssh/libsshpp.hpp b/libssh/include/libssh/libsshpp.hpp deleted file mode 100644 index af08a914..00000000 --- a/libssh/include/libssh/libsshpp.hpp +++ /dev/null @@ -1,614 +0,0 @@ -/* - * 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 - * @endcode - * All functions will then return SSH_ERROR in case of error. - * @{ - */ - -/* do not use deprecated functions */ -#define LIBSSH_LEGACY_0_4 - -#include -#include -#include -#include -#include -#include - -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(priority, "libsshpp", "%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 - */ - inline Channel *acceptForward(int timeout_ms); - /* implemented outside the class due Channel references */ - - void_throwable cancelForward(const char *address, int port){ - int err=ssh_channel_cancel_forward(c_session, address, port); - ssh_throw(err); - return_throwable; - } - - void_throwable listenForward(const char *address, int port, - int &boundport){ - int err=ssh_channel_listen_forward(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){ - int err; - /* handle int overflow */ - if(count > 0x7fffffff) - count = 0x7fffffff; - err=ssh_channel_read_timeout(channel,dest,count,is_stderr,-1); - ssh_throw(err); - return err; - } - int read(void *dest, size_t count, int timeout){ - int err; - /* handle int overflow */ - if(count > 0x7fffffff) - count = 0x7fffffff; - err=ssh_channel_read_timeout(channel,dest,count,false,timeout); - ssh_throw(err); - return err; - } - int read(void *dest, size_t count, bool is_stderr=false, int timeout=-1){ - int err; - /* handle int overflow */ - if(count > 0x7fffffff) - count = 0x7fffffff; - err=ssh_channel_read_timeout(channel,dest,count,is_stderr,timeout); - 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 &); -}; - - -inline Channel *Session::acceptForward(int timeout_ms){ - ssh_channel forward = - ssh_channel_accept_forward(c_session, timeout_ms, NULL); - ssh_throw_null(c_session,forward); - Channel *newchan = new Channel(*this,forward); - return newchan; - } - -} // namespace ssh - -/** @} */ -#endif /* LIBSSHPP_HPP_ */ diff --git a/libssh/include/libssh/messages.h b/libssh/include/libssh/messages.h deleted file mode 100644 index e766d08b..00000000 --- a/libssh/include/libssh/messages.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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_global_request); - -#ifdef WITH_SERVER -SSH_PACKET_CALLBACK(ssh_packet_service_request); -SSH_PACKET_CALLBACK(ssh_packet_userauth_request); -#endif /* WITH_SERVER */ - -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); -int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan); - -#endif /* MESSAGES_H_ */ diff --git a/libssh/include/libssh/misc.h b/libssh/include/libssh/misc.h deleted file mode 100644 index 1e69b069..00000000 --- a/libssh/include/libssh/misc.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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_ */ diff --git a/libssh/include/libssh/options.h b/libssh/include/libssh/options.h deleted file mode 100644 index 4078ad08..00000000 --- a/libssh/include/libssh/options.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2011 Andreas Schneider - * - * 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 */ diff --git a/libssh/include/libssh/packet.h b/libssh/include/libssh/packet.h deleted file mode 100644 index d8ef35bb..00000000 --- a/libssh/include/libssh/packet.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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_ - -#include "libssh/wrapper.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, enum ssh_hmac_e type); - -#endif /* PACKET_H_ */ diff --git a/libssh/include/libssh/pcap.h b/libssh/include/libssh/pcap.h deleted file mode 100644 index ca57156b..00000000 --- a/libssh/include/libssh/pcap.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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: */ diff --git a/libssh/include/libssh/pki.h b/libssh/include/libssh/pki.h deleted file mode 100644 index 9f9ddf4a..00000000 --- a/libssh/include/libssh/pki.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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_ - -#include "libssh/priv.h" -#ifdef HAVE_OPENSSL_EC_H -#include -#endif -#ifdef HAVE_OPENSSL_ECDSA_H -#include -#endif - -#include "libssh/crypto.h" -#include "libssh/ed25519.h" - -#define MAX_PUBKEY_SIZE 0x100000 /* 1M */ -#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */ - -#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 - ed25519_pubkey *ed25519_pubkey; - ed25519_privkey *ed25519_privkey; - void *cert; -}; - -struct ssh_signature_struct { - enum ssh_keytypes_e type; - const char *type_c; -#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 - ed25519_signature *ed25519_sig; -}; - -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, - const 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(const ssh_key key); -ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key); - -#endif /* PKI_H_ */ diff --git a/libssh/include/libssh/pki_priv.h b/libssh/include/libssh/pki_priv.h deleted file mode 100644 index 0aaadb60..00000000 --- a/libssh/include/libssh/pki_priv.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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); -const char *pki_key_ecdsa_nid_to_name(int nid); - -/* 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_generate_ed25519(ssh_key key); - -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_string pki_private_key_to_pem(const ssh_key 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); -int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig, - const unsigned char *hash, size_t hlen); -int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig, - const unsigned char *hash, size_t hlen); -int pki_ed25519_key_cmp(const ssh_key k1, - const ssh_key k2, - enum ssh_keycmp_e what); -int pki_ed25519_key_dup(ssh_key new, const ssh_key key); -int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key); -ssh_string pki_ed25519_sig_to_blob(ssh_signature sig); -int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob); - -#endif /* PKI_PRIV_H_ */ diff --git a/libssh/include/libssh/poll.h b/libssh/include/libssh/poll.h deleted file mode 100644 index bbc03a95..00000000 --- a/libssh/include/libssh/poll.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 -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_ */ diff --git a/libssh/include/libssh/priv.h b/libssh/include/libssh/priv.h deleted file mode 100644 index 0e3bab5b..00000000 --- a/libssh/include/libssh/priv.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * 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" - -#if !defined(HAVE_STRTOULL) -# if defined(HAVE___STRTOULL) -# define strtoull __strtoull -# elif defined(HAVE__STRTOUI64) -# define strtoull _strtoui64 -# elif defined(__hpux) && defined(__LP64__) -# define strtoull strtoul -# else -# error "no strtoull function found" -# endif -#endif /* !defined(HAVE_STRTOULL) */ - -#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 */ - -# ifdef _MSC_VER -# include - -/* 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_ISBLANK) -# define isblank(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n' || (ch) == '\r') -# endif - -# 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 */ - -struct timeval; -int gettimeofday(struct timeval *__p, void *__t); - -#else /* _WIN32 */ - -#include -#define PRIdS "zd" - -#endif /* _WIN32 */ - -#include "libssh/libssh.h" -#include "libssh/callbacks.h" - -/* some constants */ -#ifndef MAX_PACKAT_LEN -#define MAX_PACKET_LEN 262144 -#endif -#ifndef ERROR_BUFFERLEN -#define ERROR_BUFFERLEN 1024 -#endif -#ifndef CLIENTBANNER1 -#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION) -#endif -#ifndef CLIENTBANNER2 -#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION) -#endif -#ifndef KBDINT_MAX_PROMPT -#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */ -#endif -#ifndef MAX_BUF_SIZE -#define MAX_BUF_SIZE 4096 -#endif - -#ifndef __FUNCTION__ -#if defined(__SUNPRO_C) -#define __FUNCTION__ __func__ -#endif -#endif - -#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) -# define LIBSSH_THREAD __thread -#elif defined(HAVE_MSC_THREAD_LOCAL_STORAGE) -# define LIBSSH_THREAD __declspec(thread) -#else -# define LIBSSH_THREAD -#endif - -/* - * This makes sure that the compiler doesn't optimize out the code - * - * Use it in a macro where the provided variable is 'x'. - */ -#if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION) -# define LIBSSH_MEM_PROTECTION __asm__ volatile("" : : "r"(&(x)) : "memory") -#else -# define LIBSSH_MEM_PROTECTION -#endif - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -/* forward declarations */ -struct ssh_common_struct; -struct ssh_kex_struct; - -int ssh_get_key_params(ssh_session session, ssh_key *privkey); - -/* LOGGING */ -void ssh_log_function(int verbosity, - const char *function, - const char *buffer); -#define SSH_LOG(priority, ...) \ - _ssh_log(priority, __FUNCTION__, __VA_ARGS__) - -/* LEGACY */ -void ssh_log_common(struct ssh_common_struct *common, - int verbosity, - const char *function, - const char *format, ...) PRINTF_ATTRIBUTE(4, 5); - - -/* 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); - - -/* server.c */ -#ifdef WITH_SERVER -int ssh_auth_reply_default(ssh_session session,int partial); -int ssh_auth_reply_success(ssh_session session, int partial); -#endif -/* 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); - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/** 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])) - -/* - * See http://llvm.org/bugs/show_bug.cgi?id=15495 - */ -#if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION) -/** Overwrite a string with '\0' */ -# define BURN_STRING(x) do { \ - if ((x) != NULL) \ - memset((x), '\0', strlen((x))); __asm__ volatile("" : : "r"(&(x)) : "memory"); \ - } while(0) - -/** Overwrite the buffer with '\0' */ -# define BURN_BUFFER(x, size) do { \ - if ((x) != NULL) \ - memset((x), '\0', (size)); __asm__ volatile("" : : "r"(&(x)) : "memory"); \ - } while(0) -#else /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */ -/** Overwrite a string with '\0' */ -# define BURN_STRING(x) do { \ - if ((x) != NULL) memset((x), '\0', strlen((x))); \ - } while(0) - -/** Overwrite the buffer with '\0' */ -# define BURN_BUFFER(x, size) do { \ - if ((x) != NULL) \ - memset((x), '\0', (size)); \ - } while(0) -#endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */ - -/** - * 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: */ diff --git a/libssh/include/libssh/sc25519.h b/libssh/include/libssh/sc25519.h deleted file mode 100644 index 5a2c1b85..00000000 --- a/libssh/include/libssh/sc25519.h +++ /dev/null @@ -1,74 +0,0 @@ -/* $OpenBSD: sc25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */ - -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h - */ - -#ifndef SC25519_H -#define SC25519_H - -#define sc25519 crypto_sign_ed25519_ref_sc25519 -#define shortsc25519 crypto_sign_ed25519_ref_shortsc25519 -#define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes -#define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes -#define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes -#define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc -#define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes -#define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime -#define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime -#define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime -#define sc25519_add crypto_sign_ed25519_ref_sc25519_add -#define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored -#define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul -#define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc -#define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3 -#define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5 -#define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2 - -typedef struct { - uint32_t v[32]; -} sc25519; - -typedef struct { - uint32_t v[16]; -} shortsc25519; - -void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]); - -void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]); - -void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]); - -void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x); - -void sc25519_to32bytes(unsigned char r[32], const sc25519 *x); - -int sc25519_iszero_vartime(const sc25519 *x); - -int sc25519_isshort_vartime(const sc25519 *x); - -int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y); - -void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y); - -void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y); - -void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y); - -void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y); - -/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3 - * with r[i] in {-4,...,3} - */ -void sc25519_window3(signed char r[85], const sc25519 *s); - -/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5 - * with r[i] in {-16,...,15} - */ -void sc25519_window5(signed char r[51], const sc25519 *s); - -void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2); - -#endif diff --git a/libssh/include/libssh/scp.h b/libssh/include/libssh/scp.h deleted file mode 100644 index d356d89b..00000000 --- a/libssh/include/libssh/scp.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 diff --git a/libssh/include/libssh/server.h b/libssh/include/libssh/server.h deleted file mode 100644 index 385a10a7..00000000 --- a/libssh/include/libssh/server.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Public include file for server support */ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 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 - */ - -/** - * @defgroup libssh_server The libssh server API - * - * @{ - */ - -#ifndef SERVER_H -#define SERVER_H - -#include "libssh/libssh.h" -#define SERVERBANNER CLIENTBANNER - -#ifdef __cplusplus -extern "C" { -#endif - -enum ssh_bind_options_e { - SSH_BIND_OPTIONS_BINDADDR, - SSH_BIND_OPTIONS_BINDPORT, - SSH_BIND_OPTIONS_BINDPORT_STR, - SSH_BIND_OPTIONS_HOSTKEY, - SSH_BIND_OPTIONS_DSAKEY, - SSH_BIND_OPTIONS_RSAKEY, - SSH_BIND_OPTIONS_BANNER, - SSH_BIND_OPTIONS_LOG_VERBOSITY, - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, - SSH_BIND_OPTIONS_ECDSAKEY -}; - -typedef struct ssh_bind_struct* ssh_bind; - -/* Callback functions */ - -/** - * @brief Incoming connection callback. This callback is called when a ssh_bind - * has a new incoming connection. - * @param sshbind Current sshbind session handler - * @param userdata Userdata to be passed to the callback function. - */ -typedef void (*ssh_bind_incoming_connection_callback) (ssh_bind sshbind, - void *userdata); - -/** - * @brief These are the callbacks exported by the ssh_bind structure. - * - * They are called by the server module when events appear on the network. - */ -struct ssh_bind_callbacks_struct { - /** DON'T SET THIS use ssh_callbacks_init() instead. */ - size_t size; - /** A new connection is available. */ - ssh_bind_incoming_connection_callback incoming_connection; -}; -typedef struct ssh_bind_callbacks_struct *ssh_bind_callbacks; - -/** - * @brief Creates a new SSH server bind. - * - * @return A newly allocated ssh_bind session pointer. - */ -LIBSSH_API ssh_bind ssh_bind_new(void); - -LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind, - enum ssh_bind_options_e type, const void *value); - -/** - * @brief Start listening to the socket. - * - * @param ssh_bind_o The ssh server bind to use. - * - * @return 0 on success, < 0 on error. - */ -LIBSSH_API int ssh_bind_listen(ssh_bind ssh_bind_o); - -/** - * @brief Set the callback for this bind. - * - * @param[in] sshbind The bind to set the callback on. - * - * @param[in] callbacks An already set up ssh_bind_callbacks instance. - * - * @param[in] userdata A pointer to private data to pass to the callbacks. - * - * @return SSH_OK on success, SSH_ERROR if an error occured. - * - * @code - * struct ssh_callbacks_struct cb = { - * .userdata = data, - * .auth_function = my_auth_function - * }; - * ssh_callbacks_init(&cb); - * ssh_bind_set_callbacks(session, &cb); - * @endcode - */ -LIBSSH_API int ssh_bind_set_callbacks(ssh_bind sshbind, ssh_bind_callbacks callbacks, - void *userdata); - -/** - * @brief Set the session to blocking/nonblocking mode. - * - * @param ssh_bind_o The ssh server bind to use. - * - * @param blocking Zero for nonblocking mode. - */ -LIBSSH_API void ssh_bind_set_blocking(ssh_bind ssh_bind_o, int blocking); - -/** - * @brief Recover the file descriptor from the session. - * - * @param ssh_bind_o The ssh server bind to get the fd from. - * - * @return The file descriptor. - */ -LIBSSH_API socket_t ssh_bind_get_fd(ssh_bind ssh_bind_o); - -/** - * @brief Set the file descriptor for a session. - * - * @param ssh_bind_o The ssh server bind to set the fd. - * - * @param fd The file descriptssh_bind B - */ -LIBSSH_API void ssh_bind_set_fd(ssh_bind ssh_bind_o, socket_t fd); - -/** - * @brief Allow the file descriptor to accept new sessions. - * - * @param ssh_bind_o The ssh server bind to use. - */ -LIBSSH_API void ssh_bind_fd_toaccept(ssh_bind ssh_bind_o); - -/** - * @brief Accept an incoming ssh connection and initialize the session. - * - * @param ssh_bind_o The ssh server bind to accept a connection. - * @param session A preallocated ssh session - * @see ssh_new - * @return SSH_OK when a connection is established - */ -LIBSSH_API int ssh_bind_accept(ssh_bind ssh_bind_o, ssh_session session); - -/** - * @brief Accept an incoming ssh connection on the given file descriptor - * and initialize the session. - * - * @param ssh_bind_o The ssh server bind to accept a connection. - * @param session A preallocated ssh session - * @param fd A file descriptor of an already established TCP - * inbound connection - * @see ssh_new - * @see ssh_bind_accept - * @return SSH_OK when a connection is established - */ -LIBSSH_API int ssh_bind_accept_fd(ssh_bind ssh_bind_o, ssh_session session, - socket_t fd); - -LIBSSH_API ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session); - -/** - * @brief Handles the key exchange and set up encryption - * - * @param session A connected ssh session - * @see ssh_bind_accept - * @return SSH_OK if the key exchange was successful - */ -LIBSSH_API int ssh_handle_key_exchange(ssh_session session); - -/** - * @brief Free a ssh servers bind. - * - * @param ssh_bind_o The ssh server bind to free. - */ -LIBSSH_API void ssh_bind_free(ssh_bind ssh_bind_o); - -LIBSSH_API void ssh_set_auth_methods(ssh_session session, int auth_methods); - -/********************************************************** - * SERVER MESSAGING - **********************************************************/ - -/** - * @brief Reply with a standard reject message. - * - * Use this function if you don't know what to respond or if you want to reject - * a request. - * - * @param[in] msg The message to use for the reply. - * - * @return 0 on success, -1 on error. - * - * @see ssh_message_get() - */ -LIBSSH_API int ssh_message_reply_default(ssh_message msg); - -/** - * @brief Get the name of the authenticated user. - * - * @param[in] msg The message to get the username from. - * - * @return The username or NULL if an error occured. - * - * @see ssh_message_get() - * @see ssh_message_type() - */ -LIBSSH_API const char *ssh_message_auth_user(ssh_message msg); - -/** - * @brief Get the password of the authenticated user. - * - * @param[in] msg The message to get the password from. - * - * @return The username or NULL if an error occured. - * - * @see ssh_message_get() - * @see ssh_message_type() - */ -LIBSSH_API const char *ssh_message_auth_password(ssh_message msg); - -/** - * @brief Get the publickey of the authenticated user. - * - * If you need the key for later user you should duplicate it. - * - * @param[in] msg The message to get the public key from. - * - * @return The public key or NULL. - * - * @see ssh_key_dup() - * @see ssh_key_cmp() - * @see ssh_message_get() - * @see ssh_message_type() - */ -LIBSSH_API ssh_key ssh_message_auth_pubkey(ssh_message msg); - -LIBSSH_API int ssh_message_auth_kbdint_is_response(ssh_message msg); -LIBSSH_API enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg); -LIBSSH_API int ssh_message_auth_reply_success(ssh_message msg,int partial); -LIBSSH_API int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey); -LIBSSH_API int ssh_message_auth_reply_pk_ok_simple(ssh_message msg); - -LIBSSH_API int ssh_message_auth_set_methods(ssh_message msg, int methods); - -LIBSSH_API int ssh_message_auth_interactive_request(ssh_message msg, - const char *name, const char *instruction, - unsigned int num_prompts, const char **prompts, char *echo); - -LIBSSH_API int ssh_message_service_reply_success(ssh_message msg); -LIBSSH_API const char *ssh_message_service_service(ssh_message msg); - -LIBSSH_API int ssh_message_global_request_reply_success(ssh_message msg, - uint16_t bound_port); - -LIBSSH_API void ssh_set_message_callback(ssh_session session, - int(*ssh_bind_message_callback)(ssh_session session, ssh_message msg, void *data), - void *data); -LIBSSH_API int ssh_execute_message_callbacks(ssh_session session); - -LIBSSH_API const char *ssh_message_channel_request_open_originator(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_open_originator_port(ssh_message msg); -LIBSSH_API const char *ssh_message_channel_request_open_destination(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_open_destination_port(ssh_message msg); - -LIBSSH_API ssh_channel ssh_message_channel_request_channel(ssh_message msg); - -LIBSSH_API const char *ssh_message_channel_request_pty_term(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_pty_width(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_pty_height(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_pty_pxwidth(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_pty_pxheight(ssh_message msg); - -LIBSSH_API const char *ssh_message_channel_request_env_name(ssh_message msg); -LIBSSH_API const char *ssh_message_channel_request_env_value(ssh_message msg); - -LIBSSH_API const char *ssh_message_channel_request_command(ssh_message msg); - -LIBSSH_API const char *ssh_message_channel_request_subsystem(ssh_message msg); - -LIBSSH_API int ssh_message_channel_request_x11_single_connection(ssh_message msg); -LIBSSH_API const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg); -LIBSSH_API const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg); -LIBSSH_API int ssh_message_channel_request_x11_screen_number(ssh_message msg); - -LIBSSH_API const char *ssh_message_global_request_address(ssh_message msg); -LIBSSH_API int ssh_message_global_request_port(ssh_message msg); - -LIBSSH_API int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost, - int remoteport, const char *sourcehost, int localport); -LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, - const char *orig_addr, int orig_port); - -LIBSSH_API int ssh_channel_request_send_exit_status(ssh_channel channel, - int exit_status); -LIBSSH_API int ssh_channel_request_send_exit_signal(ssh_channel channel, - const char *signum, - int core, - const char *errmsg, - const char *lang); -LIBSSH_API int ssh_channel_write_stderr(ssh_channel channel, - const void *data, - uint32_t len); - -LIBSSH_API int ssh_send_keepalive(ssh_session session); - -/* deprecated functions */ -SSH_DEPRECATED LIBSSH_API int ssh_accept(ssh_session session); -SSH_DEPRECATED LIBSSH_API int channel_write_stderr(ssh_channel channel, - const void *data, uint32_t len); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* SERVER_H */ - -/** @} */ diff --git a/libssh/include/libssh/session.h b/libssh/include/libssh/session.h deleted file mode 100644 index 29bdd60b..00000000 --- a/libssh/include/libssh/session.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * 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 SESSION_H_ -#define SESSION_H_ -#include "libssh/priv.h" -#include "libssh/kex.h" -#include "libssh/packet.h" -#include "libssh/pcap.h" -#include "libssh/auth.h" -#include "libssh/channels.h" -#include "libssh/poll.h" - -/* These are the different states a SSH session can be into its life */ -enum ssh_session_state_e { - SSH_SESSION_STATE_NONE=0, - SSH_SESSION_STATE_CONNECTING, - SSH_SESSION_STATE_SOCKET_CONNECTED, - SSH_SESSION_STATE_BANNER_RECEIVED, - SSH_SESSION_STATE_INITIAL_KEX, - SSH_SESSION_STATE_KEXINIT_RECEIVED, - SSH_SESSION_STATE_DH, - SSH_SESSION_STATE_AUTHENTICATING, - SSH_SESSION_STATE_AUTHENTICATED, - SSH_SESSION_STATE_ERROR, - SSH_SESSION_STATE_DISCONNECTED -}; - -enum ssh_dh_state_e { - DH_STATE_INIT=0, - DH_STATE_INIT_SENT, - DH_STATE_NEWKEYS_SENT, - DH_STATE_FINISHED -}; - -enum ssh_pending_call_e { - SSH_PENDING_CALL_NONE = 0, - SSH_PENDING_CALL_CONNECT, - SSH_PENDING_CALL_AUTH_NONE, - SSH_PENDING_CALL_AUTH_PASSWORD, - SSH_PENDING_CALL_AUTH_OFFER_PUBKEY, - SSH_PENDING_CALL_AUTH_PUBKEY, - SSH_PENDING_CALL_AUTH_AGENT, - SSH_PENDING_CALL_AUTH_KBDINT_INIT, - SSH_PENDING_CALL_AUTH_KBDINT_SEND, - SSH_PENDING_CALL_AUTH_GSSAPI_MIC -}; - -/* libssh calls may block an undefined amount of time */ -#define SSH_SESSION_FLAG_BLOCKING 1 - -/* Client successfully authenticated */ -#define SSH_SESSION_FLAG_AUTHENTICATED 2 - -/* codes to use with ssh_handle_packets*() */ -/* Infinite timeout */ -#define SSH_TIMEOUT_INFINITE -1 -/* Use the timeout defined by user if any. Mostly used with new connections */ -#define SSH_TIMEOUT_USER -2 -/* Use the default timeout, depending on ssh_is_blocking() */ -#define SSH_TIMEOUT_DEFAULT -3 -/* Don't block at all */ -#define SSH_TIMEOUT_NONBLOCKING 0 - -/* members that are common to ssh_session and ssh_bind */ -struct ssh_common_struct { - struct error_struct error; - ssh_callbacks callbacks; /* Callbacks to user functions */ - int log_verbosity; /* verbosity of the log functions */ -}; - -struct ssh_session_struct { - struct ssh_common_struct common; - struct ssh_socket_struct *socket; - char *serverbanner; - char *clientbanner; - int protoversion; - int server; - int client; - int openssh; - uint32_t send_seq; - uint32_t recv_seq; - - int connected; - /* !=0 when the user got a session handle */ - int alive; - /* two previous are deprecated */ - /* int auth_service_asked; */ - - /* session flags (SSH_SESSION_FLAG_*) */ - int flags; - - ssh_string banner; /* that's the issue banner from - the server */ - char *discon_msg; /* disconnect message from - the remote host */ - ssh_buffer in_buffer; - PACKET in_packet; - ssh_buffer out_buffer; - - /* the states are used by the nonblocking stuff to remember */ - /* where it was before being interrupted */ - enum ssh_pending_call_e pending_call_state; - enum ssh_session_state_e session_state; - int packet_state; - enum ssh_dh_state_e dh_handshake_state; - enum ssh_auth_service_state_e auth_service_state; - enum ssh_auth_state_e auth_state; - enum ssh_channel_request_state_e global_req_state; - struct ssh_agent_state_struct *agent_state; - struct ssh_auth_auto_state_struct *auth_auto_state; - - /* - * RFC 4253, 7.1: if the first_kex_packet_follows flag was set in - * the received SSH_MSG_KEXINIT, but the guess was wrong, this - * field will be set such that the following guessed packet will - * be ignored. Once that packet has been received and ignored, - * this field is cleared. - */ - int first_kex_follows_guess_wrong; - - ssh_buffer in_hashbuf; - ssh_buffer out_hashbuf; - struct ssh_crypto_struct *current_crypto; - struct ssh_crypto_struct *next_crypto; /* next_crypto is going to be used after a SSH2_MSG_NEWKEYS */ - - struct ssh_list *channels; /* linked list of channels */ - int maxchannel; - int exec_channel_opened; /* version 1 only. more - info in channels1.c */ - ssh_agent agent; /* ssh agent */ - -/* keyb interactive data */ - struct ssh_kbdint_struct *kbdint; - struct ssh_gssapi_struct *gssapi; - int version; /* 1 or 2 */ - /* server host keys */ - struct { - ssh_key rsa_key; - ssh_key dsa_key; - ssh_key ecdsa_key; - - /* The type of host key wanted by client */ - enum ssh_keytypes_e hostkey; - } srv; - /* auths accepted by server */ - int auth_methods; - struct ssh_list *ssh_message_list; /* list of delayed SSH messages */ - int (*ssh_message_callback)( struct ssh_session_struct *session, ssh_message msg, void *userdata); - void *ssh_message_callback_data; - ssh_server_callbacks server_callbacks; - void (*ssh_connection_callback)( struct ssh_session_struct *session); - struct ssh_packet_callbacks_struct default_packet_callbacks; - struct ssh_list *packet_callbacks; - struct ssh_socket_callbacks_struct socket_callbacks; - ssh_poll_ctx default_poll_ctx; - /* options */ -#ifdef WITH_PCAP - ssh_pcap_context pcap_ctx; /* pcap debugging context */ -#endif - struct { - struct ssh_list *identity; - char *username; - char *host; - char *bindaddr; /* bind the client to an ip addr */ - char *sshdir; - char *knownhosts; - char *wanted_methods[10]; - char *ProxyCommand; - char *custombanner; - unsigned long timeout; /* seconds */ - unsigned long timeout_usec; - unsigned int port; - socket_t fd; - int StrictHostKeyChecking; - int ssh2; - int ssh1; - char compressionlevel; - char *gss_server_identity; - char *gss_client_identity; - int gss_delegate_creds; - } opts; - /* counters */ - ssh_counter socket_counter; - ssh_counter raw_counter; -}; - -/** @internal - * @brief a termination function evaluates the status of an object - * @param user[in] object to evaluate - * @returns 1 if the polling routine should terminate, 0 instead - */ -typedef int (*ssh_termination_function)(void *user); -int ssh_handle_packets(ssh_session session, int timeout); -int ssh_handle_packets_termination(ssh_session session, int timeout, - ssh_termination_function fct, void *user); -void ssh_socket_exception_callback(int code, int errno_code, void *user); - -#endif /* SESSION_H_ */ diff --git a/libssh/include/libssh/sftp.h b/libssh/include/libssh/sftp.h deleted file mode 100644 index 8fb8f116..00000000 --- a/libssh/include/libssh/sftp.h +++ /dev/null @@ -1,1000 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 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 - */ - -/** - * @defgroup libssh_sftp The libssh SFTP API - * - * @brief SFTP handling functions - * - * SFTP commands are channeled by the ssh sftp subsystem. Every packet is - * sent/read using a sftp_packet type structure. Related to these packets, - * most of the server answers are messages having an ID and a message - * specific part. It is described by sftp_message when reading a message, - * the sftp system puts it into the queue, so the process having asked for - * it can fetch it, while continuing to read for other messages (it is - * unspecified in which order messages may be sent back to the client - * - * @{ - */ - -#ifndef SFTP_H -#define SFTP_H - -#include - -#include "libssh.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WIN32 -#ifndef uid_t - typedef uint32_t uid_t; -#endif /* uid_t */ -#ifndef gid_t - typedef uint32_t gid_t; -#endif /* gid_t */ -#ifdef _MSC_VER -#ifndef ssize_t - typedef _W64 SSIZE_T ssize_t; -#endif /* ssize_t */ -#endif /* _MSC_VER */ -#endif /* _WIN32 */ - -#define LIBSFTP_VERSION 3 - -typedef struct sftp_attributes_struct* sftp_attributes; -typedef struct sftp_client_message_struct* sftp_client_message; -typedef struct sftp_dir_struct* sftp_dir; -typedef struct sftp_ext_struct *sftp_ext; -typedef struct sftp_file_struct* sftp_file; -typedef struct sftp_message_struct* sftp_message; -typedef struct sftp_packet_struct* sftp_packet; -typedef struct sftp_request_queue_struct* sftp_request_queue; -typedef struct sftp_session_struct* sftp_session; -typedef struct sftp_status_message_struct* sftp_status_message; -typedef struct sftp_statvfs_struct* sftp_statvfs_t; - -struct sftp_session_struct { - ssh_session session; - ssh_channel channel; - int server_version; - int client_version; - int version; - sftp_request_queue queue; - uint32_t id_counter; - int errnum; - void **handles; - sftp_ext ext; -}; - -struct sftp_packet_struct { - sftp_session sftp; - uint8_t type; - ssh_buffer payload; -}; - -/* file handler */ -struct sftp_file_struct { - sftp_session sftp; - char *name; - uint64_t offset; - ssh_string handle; - int eof; - int nonblocking; -}; - -struct sftp_dir_struct { - sftp_session sftp; - char *name; - ssh_string handle; /* handle to directory */ - ssh_buffer buffer; /* contains raw attributes from server which haven't been parsed */ - uint32_t count; /* counts the number of following attributes structures into buffer */ - int eof; /* end of directory listing */ -}; - -struct sftp_message_struct { - sftp_session sftp; - uint8_t packet_type; - ssh_buffer payload; - uint32_t id; -}; - -/* this is a bunch of all data that could be into a message */ -struct sftp_client_message_struct { - sftp_session sftp; - uint8_t type; - uint32_t id; - char *filename; /* can be "path" */ - uint32_t flags; - sftp_attributes attr; - ssh_string handle; - uint64_t offset; - uint32_t len; - int attr_num; - ssh_buffer attrbuf; /* used by sftp_reply_attrs */ - ssh_string data; /* can be newpath of rename() */ - ssh_buffer complete_message; /* complete message in case of retransmission*/ - char *str_data; /* cstring version of data */ -}; - -struct sftp_request_queue_struct { - sftp_request_queue next; - sftp_message message; -}; - -/* SSH_FXP_MESSAGE described into .7 page 26 */ -struct sftp_status_message_struct { - uint32_t id; - uint32_t status; - ssh_string error_unused; /* not used anymore */ - ssh_string lang_unused; /* not used anymore */ - char *errormsg; - char *langmsg; -}; - -struct sftp_attributes_struct { - char *name; - char *longname; /* ls -l output on openssh, not reliable else */ - uint32_t flags; - uint8_t type; - uint64_t size; - uint32_t uid; - uint32_t gid; - char *owner; /* set if openssh and version 4 */ - char *group; /* set if openssh and version 4 */ - uint32_t permissions; - uint64_t atime64; - uint32_t atime; - uint32_t atime_nseconds; - uint64_t createtime; - uint32_t createtime_nseconds; - uint64_t mtime64; - uint32_t mtime; - uint32_t mtime_nseconds; - ssh_string acl; - uint32_t extended_count; - ssh_string extended_type; - ssh_string extended_data; -}; - -/** - * @brief SFTP statvfs structure. - */ -struct sftp_statvfs_struct { - uint64_t f_bsize; /** file system block size */ - uint64_t f_frsize; /** fundamental fs block size */ - uint64_t f_blocks; /** number of blocks (unit f_frsize) */ - uint64_t f_bfree; /** free blocks in file system */ - uint64_t f_bavail; /** free blocks for non-root */ - uint64_t f_files; /** total file inodes */ - uint64_t f_ffree; /** free file inodes */ - uint64_t f_favail; /** free file inodes for to non-root */ - uint64_t f_fsid; /** file system id */ - uint64_t f_flag; /** bit mask of f_flag values */ - uint64_t f_namemax; /** maximum filename length */ -}; - -/** - * @brief Start a new sftp session. - * - * @param session The ssh session to use. - * - * @return A new sftp session or NULL on error. - * - * @see sftp_free() - */ -LIBSSH_API sftp_session sftp_new(ssh_session session); - -/** - * @brief Start a new sftp session with an existing channel. - * - * @param session The ssh session to use. - * @param channel An open session channel with subsystem already allocated - * - * @return A new sftp session or NULL on error. - * - * @see sftp_free() - */ -LIBSSH_API sftp_session sftp_new_channel(ssh_session session, ssh_channel channel); - - -/** - * @brief Close and deallocate a sftp session. - * - * @param sftp The sftp session handle to free. - */ -LIBSSH_API void sftp_free(sftp_session sftp); - -/** - * @brief Initialize the sftp session with the server. - * - * @param sftp The sftp session to initialize. - * - * @return 0 on success, < 0 on error with ssh error set. - * - * @see sftp_new() - */ -LIBSSH_API int sftp_init(sftp_session sftp); - -/** - * @brief Get the last sftp error. - * - * Use this function to get the latest error set by a posix like sftp function. - * - * @param sftp The sftp session where the error is saved. - * - * @return The saved error (see server responses), < 0 if an error - * in the function occured. - * - * @see Server responses - */ -LIBSSH_API int sftp_get_error(sftp_session sftp); - -/** - * @brief Get the count of extensions provided by the server. - * - * @param sftp The sftp session to use. - * - * @return The count of extensions provided by the server, 0 on error or - * not available. - */ -LIBSSH_API unsigned int sftp_extensions_get_count(sftp_session sftp); - -/** - * @brief Get the name of the extension provided by the server. - * - * @param sftp The sftp session to use. - * - * @param indexn The index number of the extension name you want. - * - * @return The name of the extension. - */ -LIBSSH_API const char *sftp_extensions_get_name(sftp_session sftp, unsigned int indexn); - -/** - * @brief Get the data of the extension provided by the server. - * - * This is normally the version number of the extension. - * - * @param sftp The sftp session to use. - * - * @param indexn The index number of the extension data you want. - * - * @return The data of the extension. - */ -LIBSSH_API const char *sftp_extensions_get_data(sftp_session sftp, unsigned int indexn); - -/** - * @brief Check if the given extension is supported. - * - * @param sftp The sftp session to use. - * - * @param name The name of the extension. - * - * @param data The data of the extension. - * - * @return 1 if supported, 0 if not. - * - * Example: - * - * @code - * sftp_extension_supported(sftp, "statvfs@openssh.com", "2"); - * @endcode - */ -LIBSSH_API int sftp_extension_supported(sftp_session sftp, const char *name, - const char *data); - -/** - * @brief Open a directory used to obtain directory entries. - * - * @param session The sftp session handle to open the directory. - * @param path The path of the directory to open. - * - * @return A sftp directory handle or NULL on error with ssh and - * sftp error set. - * - * @see sftp_readdir - * @see sftp_closedir - */ -LIBSSH_API sftp_dir sftp_opendir(sftp_session session, const char *path); - -/** - * @brief Get a single file attributes structure of a directory. - * - * @param session The sftp session handle to read the directory entry. - * @param dir The opened sftp directory handle to read from. - * - * @return A file attribute structure or NULL at the end of the - * directory. - * - * @see sftp_opendir() - * @see sftp_attribute_free() - * @see sftp_closedir() - */ -LIBSSH_API sftp_attributes sftp_readdir(sftp_session session, sftp_dir dir); - -/** - * @brief Tell if the directory has reached EOF (End Of File). - * - * @param dir The sftp directory handle. - * - * @return 1 if the directory is EOF, 0 if not. - * - * @see sftp_readdir() - */ -LIBSSH_API int sftp_dir_eof(sftp_dir dir); - -/** - * @brief Get information about a file or directory. - * - * @param session The sftp session handle. - * @param path The path to the file or directory to obtain the - * information. - * - * @return The sftp attributes structure of the file or directory, - * NULL on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API sftp_attributes sftp_stat(sftp_session session, const char *path); - -/** - * @brief Get information about a file or directory. - * - * Identical to sftp_stat, but if the file or directory is a symbolic link, - * then the link itself is stated, not the file that it refers to. - * - * @param session The sftp session handle. - * @param path The path to the file or directory to obtain the - * information. - * - * @return The sftp attributes structure of the file or directory, - * NULL on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API sftp_attributes sftp_lstat(sftp_session session, const char *path); - -/** - * @brief Get information about a file or directory from a file handle. - * - * @param file The sftp file handle to get the stat information. - * - * @return The sftp attributes structure of the file or directory, - * NULL on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API sftp_attributes sftp_fstat(sftp_file file); - -/** - * @brief Free a sftp attribute structure. - * - * @param file The sftp attribute structure to free. - */ -LIBSSH_API void sftp_attributes_free(sftp_attributes file); - -/** - * @brief Close a directory handle opened by sftp_opendir(). - * - * @param dir The sftp directory handle to close. - * - * @return Returns SSH_NO_ERROR or SSH_ERROR if an error occured. - */ -LIBSSH_API int sftp_closedir(sftp_dir dir); - -/** - * @brief Close an open file handle. - * - * @param file The open sftp file handle to close. - * - * @return Returns SSH_NO_ERROR or SSH_ERROR if an error occured. - * - * @see sftp_open() - */ -LIBSSH_API int sftp_close(sftp_file file); - -/** - * @brief Open a file on the server. - * - * @param session The sftp session handle. - * - * @param file The file to be opened. - * - * @param accesstype Is one of O_RDONLY, O_WRONLY or O_RDWR which request - * opening the file read-only,write-only or read/write. - * Acesss may also be bitwise-or'd with one or more of - * the following: - * O_CREAT - If the file does not exist it will be - * created. - * O_EXCL - When used with O_CREAT, if the file already - * exists it is an error and the open will fail. - * O_TRUNC - If the file already exists it will be - * truncated. - * - * @param mode Mode specifies the permissions to use if a new file is - * created. It is modified by the process's umask in - * the usual way: The permissions of the created file are - * (mode & ~umask) - * - * @return A sftp file handle, NULL on error with ssh and sftp - * error set. - * - * @see sftp_get_error() - */ -LIBSSH_API sftp_file sftp_open(sftp_session session, const char *file, int accesstype, - mode_t mode); - -/** - * @brief Make the sftp communication for this file handle non blocking. - * - * @param[in] handle The file handle to set non blocking. - */ -LIBSSH_API void sftp_file_set_nonblocking(sftp_file handle); - -/** - * @brief Make the sftp communication for this file handle blocking. - * - * @param[in] handle The file handle to set blocking. - */ -LIBSSH_API void sftp_file_set_blocking(sftp_file handle); - -/** - * @brief Read from a file using an opened sftp file handle. - * - * @param file The opened sftp file handle to be read from. - * - * @param buf Pointer to buffer to recieve read data. - * - * @param count Size of the buffer in bytes. - * - * @return Number of bytes written, < 0 on error with ssh and sftp - * error set. - * - * @see sftp_get_error() - */ -LIBSSH_API ssize_t sftp_read(sftp_file file, void *buf, size_t count); - -/** - * @brief Start an asynchronous read from a file using an opened sftp file handle. - * - * Its goal is to avoid the slowdowns related to the request/response pattern - * of a synchronous read. To do so, you must call 2 functions: - * - * sftp_async_read_begin() and sftp_async_read(). - * - * The first step is to call sftp_async_read_begin(). This function returns a - * request identifier. The second step is to call sftp_async_read() using the - * returned identifier. - * - * @param file The opened sftp file handle to be read from. - * - * @param len Size to read in bytes. - * - * @return An identifier corresponding to the sent request, < 0 on - * error. - * - * @warning When calling this function, the internal offset is - * updated corresponding to the len parameter. - * - * @warning A call to sftp_async_read_begin() sends a request to - * the server. When the server answers, libssh allocates - * memory to store it until sftp_async_read() is called. - * Not calling sftp_async_read() will lead to memory - * leaks. - * - * @see sftp_async_read() - * @see sftp_open() - */ -LIBSSH_API int sftp_async_read_begin(sftp_file file, uint32_t len); - -/** - * @brief Wait for an asynchronous read to complete and save the data. - * - * @param file The opened sftp file handle to be read from. - * - * @param data Pointer to buffer to recieve read data. - * - * @param len Size of the buffer in bytes. It should be bigger or - * equal to the length parameter of the - * sftp_async_read_begin() call. - * - * @param id The identifier returned by the sftp_async_read_begin() - * function. - * - * @return Number of bytes read, 0 on EOF, SSH_ERROR if an error - * occured, SSH_AGAIN if the file is opened in nonblocking - * mode and the request hasn't been executed yet. - * - * @warning A call to this function with an invalid identifier - * will never return. - * - * @see sftp_async_read_begin() - */ -LIBSSH_API int sftp_async_read(sftp_file file, void *data, uint32_t len, uint32_t id); - -/** - * @brief Write to a file using an opened sftp file handle. - * - * @param file Open sftp file handle to write to. - * - * @param buf Pointer to buffer to write data. - * - * @param count Size of buffer in bytes. - * - * @return Number of bytes written, < 0 on error with ssh and sftp - * error set. - * - * @see sftp_open() - * @see sftp_read() - * @see sftp_close() - */ -LIBSSH_API ssize_t sftp_write(sftp_file file, const void *buf, size_t count); - -/** - * @brief Seek to a specific location in a file. - * - * @param file Open sftp file handle to seek in. - * - * @param new_offset Offset in bytes to seek. - * - * @return 0 on success, < 0 on error. - */ -LIBSSH_API int sftp_seek(sftp_file file, uint32_t new_offset); - -/** - * @brief Seek to a specific location in a file. This is the - * 64bit version. - * - * @param file Open sftp file handle to seek in. - * - * @param new_offset Offset in bytes to seek. - * - * @return 0 on success, < 0 on error. - */ -LIBSSH_API int sftp_seek64(sftp_file file, uint64_t new_offset); - -/** - * @brief Report current byte position in file. - * - * @param file Open sftp file handle. - * - * @return The offset of the current byte relative to the beginning - * of the file associated with the file descriptor. < 0 on - * error. - */ -LIBSSH_API unsigned long sftp_tell(sftp_file file); - -/** - * @brief Report current byte position in file. - * - * @param file Open sftp file handle. - * - * @return The offset of the current byte relative to the beginning - * of the file associated with the file descriptor. < 0 on - * error. - */ -LIBSSH_API uint64_t sftp_tell64(sftp_file file); - -/** - * @brief Rewinds the position of the file pointer to the beginning of the - * file. - * - * @param file Open sftp file handle. - */ -LIBSSH_API void sftp_rewind(sftp_file file); - -/** - * @brief Unlink (delete) a file. - * - * @param sftp The sftp session handle. - * - * @param file The file to unlink/delete. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_unlink(sftp_session sftp, const char *file); - -/** - * @brief Remove a directoy. - * - * @param sftp The sftp session handle. - * - * @param directory The directory to remove. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_rmdir(sftp_session sftp, const char *directory); - -/** - * @brief Create a directory. - * - * @param sftp The sftp session handle. - * - * @param directory The directory to create. - * - * @param mode Specifies the permissions to use. It is modified by the - * process's umask in the usual way: - * The permissions of the created file are (mode & ~umask) - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode); - -/** - * @brief Rename or move a file or directory. - * - * @param sftp The sftp session handle. - * - * @param original The original url (source url) of file or directory to - * be moved. - * - * @param newname The new url (destination url) of the file or directory - * after the move. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_rename(sftp_session sftp, const char *original, const char *newname); - -/** - * @brief Set file attributes on a file, directory or symbolic link. - * - * @param sftp The sftp session handle. - * - * @param file The file which attributes should be changed. - * - * @param attr The file attributes structure with the attributes set - * which should be changed. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr); - -/** - * @brief Change the file owner and group - * - * @param sftp The sftp session handle. - * - * @param file The file which owner and group should be changed. - * - * @param owner The new owner which should be set. - * - * @param group The new group which should be set. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_chown(sftp_session sftp, const char *file, uid_t owner, gid_t group); - -/** - * @brief Change permissions of a file - * - * @param sftp The sftp session handle. - * - * @param file The file which owner and group should be changed. - * - * @param mode Specifies the permissions to use. It is modified by the - * process's umask in the usual way: - * The permissions of the created file are (mode & ~umask) - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_chmod(sftp_session sftp, const char *file, mode_t mode); - -/** - * @brief Change the last modification and access time of a file. - * - * @param sftp The sftp session handle. - * - * @param file The file which owner and group should be changed. - * - * @param times A timeval structure which contains the desired access - * and modification time. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_utimes(sftp_session sftp, const char *file, const struct timeval *times); - -/** - * @brief Create a symbolic link. - * - * @param sftp The sftp session handle. - * - * @param target Specifies the target of the symlink. - * - * @param dest Specifies the path name of the symlink to be created. - * - * @return 0 on success, < 0 on error with ssh and sftp error set. - * - * @see sftp_get_error() - */ -LIBSSH_API int sftp_symlink(sftp_session sftp, const char *target, const char *dest); - -/** - * @brief Read the value of a symbolic link. - * - * @param sftp The sftp session handle. - * - * @param path Specifies the path name of the symlink to be read. - * - * @return The target of the link, NULL on error. - * - * @see sftp_get_error() - */ -LIBSSH_API char *sftp_readlink(sftp_session sftp, const char *path); - -/** - * @brief Get information about a mounted file system. - * - * @param sftp The sftp session handle. - * - * @param path The pathname of any file within the mounted file system. - * - * @return A statvfs structure or NULL on error. - * - * @see sftp_get_error() - */ -LIBSSH_API sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path); - -/** - * @brief Get information about a mounted file system. - * - * @param file An opened file. - * - * @return A statvfs structure or NULL on error. - * - * @see sftp_get_error() - */ -LIBSSH_API sftp_statvfs_t sftp_fstatvfs(sftp_file file); - -/** - * @brief Free the memory of an allocated statvfs. - * - * @param statvfs_o The statvfs to free. - */ -LIBSSH_API void sftp_statvfs_free(sftp_statvfs_t statvfs_o); - -/** - * @brief Canonicalize a sftp path. - * - * @param sftp The sftp session handle. - * - * @param path The path to be canonicalized. - * - * @return The canonicalize path, NULL on error. - */ -LIBSSH_API char *sftp_canonicalize_path(sftp_session sftp, const char *path); - -/** - * @brief Get the version of the SFTP protocol supported by the server - * - * @param sftp The sftp session handle. - * - * @return The server version. - */ -LIBSSH_API int sftp_server_version(sftp_session sftp); - -#ifdef WITH_SERVER -/** - * @brief Create a new sftp server session. - * - * @param session The ssh session to use. - * - * @param chan The ssh channel to use. - * - * @return A new sftp server session. - */ -LIBSSH_API sftp_session sftp_server_new(ssh_session session, ssh_channel chan); - -/** - * @brief Intialize the sftp server. - * - * @param sftp The sftp session to init. - * - * @return 0 on success, < 0 on error. - */ -LIBSSH_API int sftp_server_init(sftp_session sftp); -#endif /* WITH_SERVER */ - -/* this is not a public interface */ -#define SFTP_HANDLES 256 -sftp_packet sftp_packet_read(sftp_session sftp); -int sftp_packet_write(sftp_session sftp,uint8_t type, ssh_buffer payload); -void sftp_packet_free(sftp_packet packet); -int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr); -sftp_attributes sftp_parse_attr(sftp_session session, ssh_buffer buf,int expectname); -/* sftpserver.c */ - -LIBSSH_API sftp_client_message sftp_get_client_message(sftp_session sftp); -LIBSSH_API void sftp_client_message_free(sftp_client_message msg); -LIBSSH_API uint8_t sftp_client_message_get_type(sftp_client_message msg); -LIBSSH_API const char *sftp_client_message_get_filename(sftp_client_message msg); -LIBSSH_API void sftp_client_message_set_filename(sftp_client_message msg, const char *newname); -LIBSSH_API const char *sftp_client_message_get_data(sftp_client_message msg); -LIBSSH_API uint32_t sftp_client_message_get_flags(sftp_client_message msg); -LIBSSH_API int sftp_send_client_message(sftp_session sftp, sftp_client_message msg); -int sftp_reply_name(sftp_client_message msg, const char *name, - sftp_attributes attr); -int sftp_reply_handle(sftp_client_message msg, ssh_string handle); -ssh_string sftp_handle_alloc(sftp_session sftp, void *info); -int sftp_reply_attr(sftp_client_message msg, sftp_attributes attr); -void *sftp_handle(sftp_session sftp, ssh_string handle); -int sftp_reply_status(sftp_client_message msg, uint32_t status, const char *message); -int sftp_reply_names_add(sftp_client_message msg, const char *file, - const char *longname, sftp_attributes attr); -int sftp_reply_names(sftp_client_message msg); -int sftp_reply_data(sftp_client_message msg, const void *data, int len); -void sftp_handle_remove(sftp_session sftp, void *handle); - -/* SFTP commands and constants */ -#define SSH_FXP_INIT 1 -#define SSH_FXP_VERSION 2 -#define SSH_FXP_OPEN 3 -#define SSH_FXP_CLOSE 4 -#define SSH_FXP_READ 5 -#define SSH_FXP_WRITE 6 -#define SSH_FXP_LSTAT 7 -#define SSH_FXP_FSTAT 8 -#define SSH_FXP_SETSTAT 9 -#define SSH_FXP_FSETSTAT 10 -#define SSH_FXP_OPENDIR 11 -#define SSH_FXP_READDIR 12 -#define SSH_FXP_REMOVE 13 -#define SSH_FXP_MKDIR 14 -#define SSH_FXP_RMDIR 15 -#define SSH_FXP_REALPATH 16 -#define SSH_FXP_STAT 17 -#define SSH_FXP_RENAME 18 -#define SSH_FXP_READLINK 19 -#define SSH_FXP_SYMLINK 20 - -#define SSH_FXP_STATUS 101 -#define SSH_FXP_HANDLE 102 -#define SSH_FXP_DATA 103 -#define SSH_FXP_NAME 104 -#define SSH_FXP_ATTRS 105 - -#define SSH_FXP_EXTENDED 200 -#define SSH_FXP_EXTENDED_REPLY 201 - -/* attributes */ -/* sftp draft is completely braindead : version 3 and 4 have different flags for same constants */ -/* and even worst, version 4 has same flag for 2 different constants */ -/* follow up : i won't develop any sftp4 compliant library before having a clarification */ - -#define SSH_FILEXFER_ATTR_SIZE 0x00000001 -#define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004 -#define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008 -#define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008 -#define SSH_FILEXFER_ATTR_CREATETIME 0x00000010 -#define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020 -#define SSH_FILEXFER_ATTR_ACL 0x00000040 -#define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080 -#define SSH_FILEXFER_ATTR_SUBSECOND_TIMES 0x00000100 -#define SSH_FILEXFER_ATTR_EXTENDED 0x80000000 -#define SSH_FILEXFER_ATTR_UIDGID 0x00000002 - -/* types */ -#define SSH_FILEXFER_TYPE_REGULAR 1 -#define SSH_FILEXFER_TYPE_DIRECTORY 2 -#define SSH_FILEXFER_TYPE_SYMLINK 3 -#define SSH_FILEXFER_TYPE_SPECIAL 4 -#define SSH_FILEXFER_TYPE_UNKNOWN 5 - -/** - * @name Server responses - * - * @brief Responses returned by the sftp server. - * @{ - */ - -/** No error */ -#define SSH_FX_OK 0 -/** End-of-file encountered */ -#define SSH_FX_EOF 1 -/** File doesn't exist */ -#define SSH_FX_NO_SUCH_FILE 2 -/** Permission denied */ -#define SSH_FX_PERMISSION_DENIED 3 -/** Generic failure */ -#define SSH_FX_FAILURE 4 -/** Garbage received from server */ -#define SSH_FX_BAD_MESSAGE 5 -/** No connection has been set up */ -#define SSH_FX_NO_CONNECTION 6 -/** There was a connection, but we lost it */ -#define SSH_FX_CONNECTION_LOST 7 -/** Operation not supported by the server */ -#define SSH_FX_OP_UNSUPPORTED 8 -/** Invalid file handle */ -#define SSH_FX_INVALID_HANDLE 9 -/** No such file or directory path exists */ -#define SSH_FX_NO_SUCH_PATH 10 -/** An attempt to create an already existing file or directory has been made */ -#define SSH_FX_FILE_ALREADY_EXISTS 11 -/** We are trying to write on a write-protected filesystem */ -#define SSH_FX_WRITE_PROTECT 12 -/** No media in remote drive */ -#define SSH_FX_NO_MEDIA 13 - -/** @} */ - -/* file flags */ -#define SSH_FXF_READ 0x01 -#define SSH_FXF_WRITE 0x02 -#define SSH_FXF_APPEND 0x04 -#define SSH_FXF_CREAT 0x08 -#define SSH_FXF_TRUNC 0x10 -#define SSH_FXF_EXCL 0x20 -#define SSH_FXF_TEXT 0x40 - -/* rename flags */ -#define SSH_FXF_RENAME_OVERWRITE 0x00000001 -#define SSH_FXF_RENAME_ATOMIC 0x00000002 -#define SSH_FXF_RENAME_NATIVE 0x00000004 - -#define SFTP_OPEN SSH_FXP_OPEN -#define SFTP_CLOSE SSH_FXP_CLOSE -#define SFTP_READ SSH_FXP_READ -#define SFTP_WRITE SSH_FXP_WRITE -#define SFTP_LSTAT SSH_FXP_LSTAT -#define SFTP_FSTAT SSH_FXP_FSTAT -#define SFTP_SETSTAT SSH_FXP_SETSTAT -#define SFTP_FSETSTAT SSH_FXP_FSETSTAT -#define SFTP_OPENDIR SSH_FXP_OPENDIR -#define SFTP_READDIR SSH_FXP_READDIR -#define SFTP_REMOVE SSH_FXP_REMOVE -#define SFTP_MKDIR SSH_FXP_MKDIR -#define SFTP_RMDIR SSH_FXP_RMDIR -#define SFTP_REALPATH SSH_FXP_REALPATH -#define SFTP_STAT SSH_FXP_STAT -#define SFTP_RENAME SSH_FXP_RENAME -#define SFTP_READLINK SSH_FXP_READLINK -#define SFTP_SYMLINK SSH_FXP_SYMLINK - -/* openssh flags */ -#define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */ -#define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */ - -#ifdef __cplusplus -} ; -#endif - -#endif /* SFTP_H */ - -/** @} */ -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/include/libssh/socket.h b/libssh/include/libssh/socket.h deleted file mode 100644 index 8e1eac21..00000000 --- a/libssh/include/libssh/socket.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 SOCKET_H_ -#define SOCKET_H_ - -#include "libssh/callbacks.h" -struct ssh_poll_handle_struct; -/* socket.c */ - -struct ssh_socket_struct; -typedef struct ssh_socket_struct* ssh_socket; - -int ssh_socket_init(void); -void ssh_socket_cleanup(void); -ssh_socket ssh_socket_new(ssh_session session); -void ssh_socket_reset(ssh_socket s); -void ssh_socket_free(ssh_socket s); -void ssh_socket_set_fd(ssh_socket s, socket_t fd); -socket_t ssh_socket_get_fd_in(ssh_socket s); -#ifndef _WIN32 -int ssh_socket_unix(ssh_socket s, const char *path); -void ssh_execute_command(const char *command, socket_t in, socket_t out); -int ssh_socket_connect_proxycommand(ssh_socket s, const char *command); -#endif -void ssh_socket_close(ssh_socket s); -int ssh_socket_write(ssh_socket s,const void *buffer, int len); -int ssh_socket_is_open(ssh_socket s); -int ssh_socket_fd_isset(ssh_socket s, fd_set *set); -void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd); -void ssh_socket_set_fd_in(ssh_socket s, socket_t fd); -void ssh_socket_set_fd_out(ssh_socket s, socket_t fd); -int ssh_socket_nonblocking_flush(ssh_socket s); -void ssh_socket_set_write_wontblock(ssh_socket s); -void ssh_socket_set_read_wontblock(ssh_socket s); -void ssh_socket_set_except(ssh_socket s); -int ssh_socket_get_status(ssh_socket s); -int ssh_socket_get_poll_flags(ssh_socket s); -int ssh_socket_buffered_write_bytes(ssh_socket s); -int ssh_socket_data_available(ssh_socket s); -int ssh_socket_data_writable(ssh_socket s); -int ssh_socket_set_nonblocking(socket_t fd); -int ssh_socket_set_blocking(socket_t fd); - -void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks); -int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s); -struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_in(ssh_socket s); -struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_out(ssh_socket s); - -int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr); - -#endif /* SOCKET_H_ */ diff --git a/libssh/include/libssh/ssh1.h b/libssh/include/libssh/ssh1.h deleted file mode 100644 index ce67f20b..00000000 --- a/libssh/include/libssh/ssh1.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __SSH1_H -#define __SSH1_H - -#define SSH_MSG_NONE 0 /* no message */ -#define SSH_MSG_DISCONNECT 1 /* cause (string) */ -#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */ -#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */ -#define SSH_CMSG_USER 4 /* user (string) */ -#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */ -#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */ -#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */ -#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */ -#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */ -#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */ -#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */ -#define SSH_CMSG_EXEC_SHELL 12 /* */ -#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */ -#define SSH_SMSG_SUCCESS 14 /* */ -#define SSH_SMSG_FAILURE 15 /* */ -#define SSH_CMSG_STDIN_DATA 16 /* data (string) */ -#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */ -#define SSH_SMSG_STDERR_DATA 18 /* data (string) */ -#define SSH_CMSG_EOF 19 /* */ -#define SSH_SMSG_EXITSTATUS 20 /* status (int) */ -#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */ -#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */ -#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */ -#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */ -#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */ -/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */ -#define SSH_SMSG_X11_OPEN 27 /* channel (int) */ -#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */ -#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */ -#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */ -#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */ -#define SSH_MSG_IGNORE 32 /* string */ -#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */ -#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */ -#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */ -#define SSH_MSG_DEBUG 36 /* string */ -#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */ -#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */ -#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */ -#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */ -#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */ -#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */ -#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */ -#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */ -#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */ - -/* protocol version 1.5 overloads some version 1.3 message types */ -#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE -#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION - -/* - * Authentication methods. New types can be added, but old types should not - * be removed for compatibility. The maximum allowed value is 31. - */ -#define SSH_AUTH_RHOSTS 1 -#define SSH_AUTH_RSA 2 -#define SSH_AUTH_PASSWORD 3 -#define SSH_AUTH_RHOSTS_RSA 4 -#define SSH_AUTH_TIS 5 -#define SSH_AUTH_KERBEROS 6 -#define SSH_PASS_KERBEROS_TGT 7 - /* 8 to 15 are reserved */ -#define SSH_PASS_AFS_TOKEN 21 - -/* Protocol flags. These are bit masks. */ -#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */ -#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */ - -/* cipher flags. they are bit numbers */ -#define SSH_CIPHER_NONE 0 /* No encryption */ -#define SSH_CIPHER_IDEA 1 /* IDEA in CFB mode */ -#define SSH_CIPHER_DES 2 /* DES in CBC mode */ -#define SSH_CIPHER_3DES 3 /* Triple-DES in CBC mode */ -#define SSH_CIPHER_RC4 5 /* RC4 */ -#define SSH_CIPHER_BLOWFISH 6 - -#endif - diff --git a/libssh/include/libssh/ssh2.h b/libssh/include/libssh/ssh2.h deleted file mode 100644 index 8b39b9a6..00000000 --- a/libssh/include/libssh/ssh2.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef __SSH2_H -#define __SSH2_H - -#define SSH2_MSG_DISCONNECT 1 -#define SSH2_MSG_IGNORE 2 -#define SSH2_MSG_UNIMPLEMENTED 3 -#define SSH2_MSG_DEBUG 4 -#define SSH2_MSG_SERVICE_REQUEST 5 -#define SSH2_MSG_SERVICE_ACCEPT 6 - -#define SSH2_MSG_KEXINIT 20 -#define SSH2_MSG_NEWKEYS 21 - -#define SSH2_MSG_KEXDH_INIT 30 -#define SSH2_MSG_KEXDH_REPLY 31 -#define SSH2_MSG_KEX_ECDH_INIT 30 -#define SSH2_MSG_KEX_ECDH_REPLY 31 -#define SSH2_MSG_ECMQV_INIT 30 -#define SSH2_MSG_ECMQV_REPLY 31 - -#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30 -#define SSH2_MSG_KEX_DH_GEX_GROUP 31 -#define SSH2_MSG_KEX_DH_GEX_INIT 32 -#define SSH2_MSG_KEX_DH_GEX_REPLY 33 -#define SSH2_MSG_KEX_DH_GEX_REQUEST 34 -#define SSH2_MSG_USERAUTH_REQUEST 50 -#define SSH2_MSG_USERAUTH_FAILURE 51 -#define SSH2_MSG_USERAUTH_SUCCESS 52 -#define SSH2_MSG_USERAUTH_BANNER 53 -#define SSH2_MSG_USERAUTH_PK_OK 60 -#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 -#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 -#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 -#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 -#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 -#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 -#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 -#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 -#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66 - -#define SSH2_MSG_GLOBAL_REQUEST 80 -#define SSH2_MSG_REQUEST_SUCCESS 81 -#define SSH2_MSG_REQUEST_FAILURE 82 -#define SSH2_MSG_CHANNEL_OPEN 90 -#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 -#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 -#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 -#define SSH2_MSG_CHANNEL_DATA 94 -#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 -#define SSH2_MSG_CHANNEL_EOF 96 -#define SSH2_MSG_CHANNEL_CLOSE 97 -#define SSH2_MSG_CHANNEL_REQUEST 98 -#define SSH2_MSG_CHANNEL_SUCCESS 99 -#define SSH2_MSG_CHANNEL_FAILURE 100 - -#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 -#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 -#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 -#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 -#define SSH2_DISCONNECT_RESERVED 4 -#define SSH2_DISCONNECT_MAC_ERROR 5 -#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 -#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 -#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 -#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 -#define SSH2_DISCONNECT_CONNECTION_LOST 10 -#define SSH2_DISCONNECT_BY_APPLICATION 11 -#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 -#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 -#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 -#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 - -#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 -#define SSH2_OPEN_CONNECT_FAILED 2 -#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 -#define SSH2_OPEN_RESOURCE_SHORTAGE 4 - -#define SSH2_EXTENDED_DATA_STDERR 1 - -#endif diff --git a/libssh/include/libssh/string.h b/libssh/include/libssh/string.h deleted file mode 100644 index 8c7db1df..00000000 --- a/libssh/include/libssh/string.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 STRING_H_ -#define STRING_H_ -#include "libssh/priv.h" - -/* must be 32 bits number + immediately our data */ -#ifdef _MSC_VER -#pragma pack(1) -#endif -struct ssh_string_struct { - uint32_t size; - unsigned char data[1]; -} -#if defined(__GNUC__) -__attribute__ ((packed)) -#endif -#ifdef _MSC_VER -#pragma pack() -#endif -; - -#endif /* STRING_H_ */ diff --git a/libssh/include/libssh/threads.h b/libssh/include/libssh/threads.h deleted file mode 100644 index 70072648..00000000 --- a/libssh/include/libssh/threads.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 THREADS_H_ -#define THREADS_H_ - -#include -#include - -int ssh_threads_init(void); -void ssh_threads_finalize(void); -const char *ssh_threads_get_type(void); - -#endif /* THREADS_H_ */ diff --git a/libssh/include/libssh/wrapper.h b/libssh/include/libssh/wrapper.h deleted file mode 100644 index a327e188..00000000 --- a/libssh/include/libssh/wrapper.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 WRAPPER_H_ -#define WRAPPER_H_ - -#include "config.h" -#include "libssh/libssh.h" -#include "libssh/libcrypto.h" -#include "libssh/libgcrypt.h" - -enum ssh_mac_e { - SSH_MAC_SHA1=1, - SSH_MAC_SHA256, - SSH_MAC_SHA384, - SSH_MAC_SHA512 -}; - -enum ssh_hmac_e { - SSH_HMAC_SHA1 = 1, - SSH_HMAC_SHA256, - SSH_HMAC_SHA384, - SSH_HMAC_SHA512, - SSH_HMAC_MD5 -}; - -enum ssh_des_e { - SSH_3DES, - SSH_DES -}; - -struct ssh_hmac_struct { - const char* name; - enum ssh_hmac_e hmac_type; -}; - -typedef struct ssh_mac_ctx_struct *ssh_mac_ctx; -MD5CTX md5_init(void); -void md5_update(MD5CTX c, const void *data, unsigned long len); -void md5_final(unsigned char *md,MD5CTX c); - -SHACTX sha1_init(void); -void sha1_update(SHACTX c, const void *data, unsigned long len); -void sha1_final(unsigned char *md,SHACTX c); -void sha1(unsigned char *digest,int len,unsigned char *hash); - -SHA256CTX sha256_init(void); -void sha256_update(SHA256CTX c, const void *data, unsigned long len); -void sha256_final(unsigned char *md,SHA256CTX c); -void sha256(unsigned char *digest, int len, unsigned char *hash); - -SHA384CTX sha384_init(void); -void sha384_update(SHA384CTX c, const void *data, unsigned long len); -void sha384_final(unsigned char *md,SHA384CTX c); -void sha384(unsigned char *digest, int len, unsigned char *hash); - -SHA512CTX sha512_init(void); -void sha512_update(SHA512CTX c, const void *data, unsigned long len); -void sha512_final(unsigned char *md,SHA512CTX c); -void sha512(unsigned char *digest, int len, unsigned char *hash); - -void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen); -EVPCTX evp_init(int nid); -void evp_update(EVPCTX ctx, const void *data, unsigned long len); -void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen); - -ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type); -void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len); -void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx); - -HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type); -void hmac_update(HMACCTX c, const void *data, unsigned long len); -void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len); -size_t hmac_digest_len(enum ssh_hmac_e type); - -int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type); -int crypt_set_algorithms_server(ssh_session session); -struct ssh_crypto_struct *crypto_new(void); -void crypto_free(struct ssh_crypto_struct *crypto); - -void ssh_reseed(void); - -struct ssh_hmac_struct *ssh_get_hmactab(void); -const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type); - -#endif /* WRAPPER_H_ */ diff --git a/libssh/libssh-build-tree-settings.cmake.in b/libssh/libssh-build-tree-settings.cmake.in deleted file mode 100644 index 16b406aa..00000000 --- a/libssh/libssh-build-tree-settings.cmake.in +++ /dev/null @@ -1 +0,0 @@ -set(LIBSSH_INLUDE_DIR @PROJECT_SOURCE_DIR@/include) diff --git a/libssh/libssh-config-version.cmake.in b/libssh/libssh-config-version.cmake.in deleted file mode 100644 index 98f292c0..00000000 --- a/libssh/libssh-config-version.cmake.in +++ /dev/null @@ -1,11 +0,0 @@ -set(PACKAGE_VERSION @APPLICATION_VERSION@) - -# Check whether the requested PACKAGE_FIND_VERSION is compatible -if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_COMPATIBLE FALSE) -else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_EXACT TRUE) - endif() -endif() diff --git a/libssh/libssh-config.cmake.in b/libssh/libssh-config.cmake.in deleted file mode 100644 index fa9cecf8..00000000 --- a/libssh/libssh-config.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -get_filename_component(LIBSSH_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - -if (EXISTS "${LIBSSH_CMAKE_DIR}/CMakeCache.txt") - # In build tree - include(${LIBSSH_CMAKE_DIR}/libssh-build-tree-settings.cmake) -else() - set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@) -endif() - -set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@) -set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@) - -set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@) diff --git a/libssh/libssh.pc.cmake b/libssh/libssh.pc.cmake deleted file mode 100644 index 3b1cb8dc..00000000 --- a/libssh/libssh.pc.cmake +++ /dev/null @@ -1,6 +0,0 @@ -Name: ${APPLICATION_NAME} -Description: The SSH Library -Version: ${APPLICATION_VERSION} -Libs: -L${LIB_INSTALL_DIR} -lssh -Cflags: -I${INCLUDE_INSTALL_DIR} - diff --git a/libssh/libssh_threads.pc.cmake b/libssh/libssh_threads.pc.cmake deleted file mode 100644 index 5479c34f..00000000 --- a/libssh/libssh_threads.pc.cmake +++ /dev/null @@ -1,6 +0,0 @@ -Name: ${APPLICATION_NAME}_threads -Description: The SSH Library Thread Extension -Version: ${APPLICATION_VERSION} -Libs: -L${LIB_INSTALL_DIR} -lssh_threads -Cflags: -I${INCLUDE_INSTALL_DIR} - diff --git a/libssh/obj/build_make.sh b/libssh/obj/build_make.sh deleted file mode 100755 index 2f2e4a6c..00000000 --- a/libssh/obj/build_make.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/bin/bash -# -# Last Change: 2008-06-18 14:13:46 -# -# Script to build libssh on UNIX. -# -# Copyright (c) 2006-2007 Andreas Schneider -# - -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 diff --git a/libssh/src/CMakeLists.txt b/libssh/src/CMakeLists.txt deleted file mode 100644 index a4bc8595..00000000 --- a/libssh/src/CMakeLists.txt +++ /dev/null @@ -1,299 +0,0 @@ -project(libssh-library C) - -set(LIBSSH_PUBLIC_INCLUDE_DIRS - ${CMAKE_SOURCE_DIR}/include - CACHE INTERNAL "libssh public include directories" -) - -set(LIBSSH_PRIVATE_INCLUDE_DIRS - ${CMAKE_BINARY_DIR} - ${OPENSSL_INCLUDE_DIRS} -) - -set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_REQUIRED_LIBRARIES} -) - -if (WIN32) - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - ws2_32 - ) -endif (WIN32) - -if (HAVE_LIBSOCKET) - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - socket - ) -endif (HAVE_LIBSOCKET) - -if (OPENSSL_CRYPTO_LIBRARIES) - set(LIBSSH_PRIVATE_INCLUDE_DIRS - ${LIBSSH_PRIVATE_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIRS} - ) - - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - ${OPENSSL_CRYPTO_LIBRARIES} - ) -endif (OPENSSL_CRYPTO_LIBRARIES) - -if (GCRYPT_LIBRARY) - set(LIBSSH_PRIVATE_INCLUDE_DIRS - ${LIBSSH_PRIVATE_INCLUDE_DIRS} - ${GCRYPT_INCLUDE_DIR} - ) - - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - ${GCRYPT_LIBRARY} - ) -endif (GCRYPT_LIBRARY) - -if (WITH_ZLIB) - set(LIBSSH_PRIVATE_INCLUDE_DIRS - ${LIBSSH_PRIVATE_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} - ) - - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - ${ZLIB_LIBRARY} - ) -endif (WITH_ZLIB) - -if (WITH_GSSAPI AND GSSAPI_FOUND) - set(LIBSSH_PRIVATE_INCLUDE_DIRS - ${LIBSSH_PRIVATE_INCLUDE_DIRS} - ${GSSAPI_INCLUDE_DIR} - ) - - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - ${GSSAPI_LIBRARIES} - ) -endif (WITH_GSSAPI AND GSSAPI_FOUND) - -if (WITH_NACL AND NACL_FOUND) - set(LIBSSH_PRIVATE_INCLUDE_DIRS - ${LIBSSH_PRIVATE_INCLUDE_DIRS} - ${NACL_INCLUDE_DIR} - ) - - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - ${NACL_LIBRARY} - ) -endif (WITH_NACL AND NACL_FOUND) - -set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} - CACHE INTERNAL "libssh link libraries" -) - -set(LIBSSH_SHARED_LIBRARY - ssh_shared - CACHE INTERNAL "libssh shared library" -) - -if (WITH_STATIC_LIB) - set(LIBSSH_STATIC_LIBRARY - ssh_static - CACHE INTERNAL "libssh static library" - ) -endif (WITH_STATIC_LIB) - -set(libssh_SRCS - agent.c - auth.c - base64.c - bignum.c - buffer.c - callbacks.c - channels.c - client.c - config.c - connect.c - curve25519.c - dh.c - ecdh.c - ed25519.c - error.c - fe25519.c - ge25519.c - getpass.c - init.c - kex.c - known_hosts.c - legacy.c - libcrypto.c - log.c - match.c - messages.c - misc.c - options.c - packet.c - packet_cb.c - packet_crypt.c - pcap.c - pki.c - pki_ed25519.c - poll.c - session.c - sc25519.c - scp.c - socket.c - string.c - threads.c - wrapper.c -) - -if (WITH_GCRYPT) - set(libssh_SRCS - ${libssh_SRCS} - libgcrypt.c - gcrypt_missing.c - pki_gcrypt.c - ) -else (WITH_GCRYPT) - set(libssh_SRCS - ${libssh_SRCS} - pki_crypto.c - ) -endif (WITH_GCRYPT) - -if (WITH_SFTP) - set(libssh_SRCS - ${libssh_SRCS} - sftp.c - ) - - if (WITH_SERVER) - set(libssh_SRCS - ${libssh_SRCS} - sftpserver.c - ) - endif (WITH_SERVER) -endif (WITH_SFTP) - -if (WITH_SSH1) - set(libssh_SRCS - ${libssh_SRCS} - auth1.c - channels1.c - crc32.c - kex1.c - packet1.c - ) -endif (WITH_SSH1) - -if (WITH_SERVER) - set(libssh_SRCS - ${libssh_SRCS} - server.c - bind.c - ) -endif (WITH_SERVER) - -if (WITH_ZLIB) - set(libssh_SRCS - ${libssh_SRCS} - gzip.c - ) -endif(WITH_ZLIB) - -if (WITH_GSSAPI AND GSSAPI_FOUND) - set(libssh_SRCS - ${libssh_SRCS} - gssapi.c - ) -endif (WITH_GSSAPI AND GSSAPI_FOUND) - -if (NOT WITH_NACL) - set(libssh_SRCS - ${libssh_SRCS} - curve25519_ref.c - ) -endif (NOT WITH_NACL) - -include_directories( - ${LIBSSH_PUBLIC_INCLUDE_DIRS} - ${LIBSSH_PRIVATE_INCLUDE_DIRS} -) - -add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS}) - -target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES}) - -set_target_properties( - ${LIBSSH_SHARED_LIBRARY} - PROPERTIES - VERSION - ${LIBRARY_VERSION} - SOVERSION - ${LIBRARY_SOVERSION} - OUTPUT_NAME - ssh - DEFINE_SYMBOL - LIBSSH_EXPORTS -) - -if (WITH_VISIBILITY_HIDDEN) - set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") -endif (WITH_VISIBILITY_HIDDEN) - - -install( - TARGETS - ${LIBSSH_SHARED_LIBRARY} - RUNTIME DESTINATION ${BIN_INSTALL_DIR} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} - COMPONENT libraries -) - -if (WITH_STATIC_LIB) - add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS}) - - if (MSVC) - set(OUTPUT_SUFFIX static) - else (MSVC) - set(OUTPUT_SUFFIX ) - endif (MSVC) - set_target_properties( - ${LIBSSH_STATIC_LIBRARY} - PROPERTIES - VERSION - ${LIBRARY_VERSION} - SOVERSION - ${LIBRARY_SOVERSION} - OUTPUT_NAME - ssh - ARCHIVE_OUTPUT_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX} - ) - - if (WIN32) - set_target_properties( - ${LIBSSH_STATIC_LIBRARY} - PROPERTIES - COMPILE_FLAGS - "-DLIBSSH_STATIC" - ) - endif (WIN32) - - install( - TARGETS - ${LIBSSH_STATIC_LIBRARY} - DESTINATION - ${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX} - COMPONENT - libraries - ) -endif (WITH_STATIC_LIB) - -if (Threads_FOUND) - add_subdirectory(threads) -endif (Threads_FOUND) diff --git a/libssh/src/agent.c b/libssh/src/agent.c deleted file mode 100644 index d5257604..00000000 --- a/libssh/src/agent.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - * agent.c - ssh agent functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * 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 - */ - -/* This file is based on authfd.c from OpenSSH */ - -/* - * How does the ssh-agent work? - * - * a) client sends a request to get a list of all keys - * the agent returns the count and all public keys - * b) iterate over them to check if the server likes one - * c) the client sends a sign request to the agent - * type, pubkey as blob, data to sign, flags - * the agent returns the signed data - */ - -#ifndef _WIN32 - -#include "config.h" - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include - -#include "libssh/agent.h" -#include "libssh/priv.h" -#include "libssh/socket.h" -#include "libssh/buffer.h" -#include "libssh/session.h" -#include "libssh/poll.h" -#include "libssh/pki.h" - -/* macro to check for "agent failure" message */ -#define agent_failed(x) \ - (((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \ - ((x) == SSH2_AGENT_FAILURE)) - -static uint32_t agent_get_u32(const void *vp) { - const uint8_t *p = (const uint8_t *)vp; - uint32_t v; - - v = (uint32_t)p[0] << 24; - v |= (uint32_t)p[1] << 16; - v |= (uint32_t)p[2] << 8; - v |= (uint32_t)p[3]; - - return v; -} - -static void agent_put_u32(void *vp, uint32_t v) { - uint8_t *p = (uint8_t *)vp; - - p[0] = (uint8_t)(v >> 24) & 0xff; - p[1] = (uint8_t)(v >> 16) & 0xff; - p[2] = (uint8_t)(v >> 8) & 0xff; - p[3] = (uint8_t)v & 0xff; -} - -static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) { - char *b = buf; - size_t pos = 0; - ssize_t res; - ssh_pollfd_t pfd; - ssh_channel channel = agent->channel; - socket_t fd; - - /* Using a socket ? */ - if (channel == NULL) { - fd = ssh_socket_get_fd_in(agent->sock); - pfd.fd = fd; - pfd.events = do_read ? POLLIN : POLLOUT; - - while (n > pos) { - if (do_read) { - res = read(fd, b + pos, n - pos); - } else { - res = write(fd, b + pos, n - pos); - } - switch (res) { - case -1: - if (errno == EINTR) { - continue; - } -#ifdef EWOULDBLOCK - if (errno == EAGAIN || errno == EWOULDBLOCK) { -#else - if (errno == EAGAIN) { -#endif - (void) ssh_poll(&pfd, 1, -1); - continue; - } - return 0; - case 0: - /* read returns 0 on end-of-file */ - errno = do_read ? 0 : EPIPE; - return pos; - default: - pos += (size_t) res; - } - } - return pos; - } else { - /* using an SSH channel */ - while (n > pos){ - if (do_read) - res = ssh_channel_read(channel,b + pos, n-pos, 0); - else - res = ssh_channel_write(channel, b+pos, n-pos); - if (res == SSH_AGAIN) - continue; - if (res == SSH_ERROR) - return 0; - pos += (size_t)res; - } - return pos; - } -} - -ssh_agent agent_new(struct ssh_session_struct *session) { - ssh_agent agent = NULL; - - agent = malloc(sizeof(struct ssh_agent_struct)); - if (agent == NULL) { - return NULL; - } - ZERO_STRUCTP(agent); - - agent->count = 0; - agent->sock = ssh_socket_new(session); - if (agent->sock == NULL) { - SAFE_FREE(agent); - return NULL; - } - agent->channel = NULL; - return agent; -} - -static void agent_set_channel(struct ssh_agent_struct *agent, ssh_channel channel){ - agent->channel = channel; -} - -/** @brief sets the SSH agent channel. - * The SSH agent channel will be used to authenticate this client using - * an agent through a channel, from another session. The most likely use - * is to implement SSH Agent forwarding into a SSH proxy. - * @param[in] channel a SSH channel from another session. - * @returns SSH_OK in case of success - * SSH_ERROR in case of an error - */ -int ssh_set_agent_channel(ssh_session session, ssh_channel channel){ - if (!session) - return SSH_ERROR; - if (!session->agent){ - ssh_set_error(session, SSH_REQUEST_DENIED, "Session has no active agent"); - return SSH_ERROR; - } - agent_set_channel(session->agent, channel); - return SSH_OK; -} - - -void agent_close(struct ssh_agent_struct *agent) { - if (agent == NULL) { - return; - } - - if (getenv("SSH_AUTH_SOCK")) { - ssh_socket_close(agent->sock); - } -} - -void agent_free(ssh_agent agent) { - if (agent) { - if (agent->ident) { - ssh_buffer_free(agent->ident); - } - if (agent->sock) { - agent_close(agent); - ssh_socket_free(agent->sock); - } - SAFE_FREE(agent); - } -} - -static int agent_connect(ssh_session session) { - const char *auth_sock = NULL; - - if (session == NULL || session->agent == NULL) { - return -1; - } - - if (session->agent->channel != NULL) - return 0; - - auth_sock = getenv("SSH_AUTH_SOCK"); - - if (auth_sock && *auth_sock) { - if (ssh_socket_unix(session->agent->sock, auth_sock) < 0) { - return -1; - } - return 0; - } - - return -1; -} - -#if 0 -static int agent_decode_reply(struct ssh_session_struct *session, int type) { - switch (type) { - case SSH_AGENT_FAILURE: - case SSH2_AGENT_FAILURE: - case SSH_COM_AGENT2_FAILURE: - ssh_log(session, SSH_LOG_RARE, "SSH_AGENT_FAILURE"); - return 0; - case SSH_AGENT_SUCCESS: - return 1; - default: - ssh_set_error(session, SSH_FATAL, - "Bad response from authentication agent: %d", type); - break; - } - - return -1; -} -#endif - -static int agent_talk(struct ssh_session_struct *session, - struct ssh_buffer_struct *request, struct ssh_buffer_struct *reply) { - uint32_t len = 0; - uint8_t payload[1024] = {0}; - - len = buffer_get_rest_len(request); - SSH_LOG(SSH_LOG_TRACE, "Request length: %u", len); - agent_put_u32(payload, len); - - /* send length and then the request packet */ - if (atomicio(session->agent, payload, 4, 0) == 4) { - if (atomicio(session->agent, buffer_get_rest(request), len, 0) - != len) { - SSH_LOG(SSH_LOG_WARN, "atomicio sending request failed: %s", - strerror(errno)); - return -1; - } - } else { - SSH_LOG(SSH_LOG_WARN, - "atomicio sending request length failed: %s", - strerror(errno)); - return -1; - } - - /* wait for response, read the length of the response packet */ - if (atomicio(session->agent, payload, 4, 1) != 4) { - SSH_LOG(SSH_LOG_WARN, "atomicio read response length failed: %s", - strerror(errno)); - return -1; - } - - len = agent_get_u32(payload); - if (len > 256 * 1024) { - ssh_set_error(session, SSH_FATAL, - "Authentication response too long: %u", len); - return -1; - } - SSH_LOG(SSH_LOG_TRACE, "Response length: %u", len); - - while (len > 0) { - size_t n = len; - if (n > sizeof(payload)) { - n = sizeof(payload); - } - if (atomicio(session->agent, payload, n, 1) != n) { - SSH_LOG(SSH_LOG_WARN, - "Error reading response from authentication socket."); - return -1; - } - if (ssh_buffer_add_data(reply, payload, n) < 0) { - SSH_LOG(SSH_LOG_WARN, "Not enough space"); - return -1; - } - len -= n; - } - - return 0; -} - -int ssh_agent_get_ident_count(struct ssh_session_struct *session) { - ssh_buffer request = NULL; - ssh_buffer reply = NULL; - unsigned int type = 0; - unsigned int c1 = 0, c2 = 0; - uint8_t buf[4] = {0}; - int rc; - - switch (session->version) { - case 1: - c1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES; - c2 = SSH_AGENT_RSA_IDENTITIES_ANSWER; - break; - case 2: - c1 = SSH2_AGENTC_REQUEST_IDENTITIES; - c2 = SSH2_AGENT_IDENTITIES_ANSWER; - break; - default: - return 0; - } - - /* send message to the agent requesting the list of identities */ - request = ssh_buffer_new(); - if (request == NULL) { - ssh_set_error_oom(session); - return -1; - } - if (buffer_add_u8(request, c1) < 0) { - ssh_set_error_oom(session); - ssh_buffer_free(request); - return -1; - } - - reply = ssh_buffer_new(); - if (reply == NULL) { - ssh_buffer_free(request); - ssh_set_error(session, SSH_FATAL, "Not enough space"); - return -1; - } - - if (agent_talk(session, request, reply) < 0) { - ssh_buffer_free(request); - ssh_buffer_free(reply); - return 0; - } - ssh_buffer_free(request); - - /* get message type and verify the answer */ - rc = buffer_get_u8(reply, (uint8_t *) &type); - if (rc != sizeof(uint8_t)) { - ssh_set_error(session, SSH_FATAL, - "Bad authentication reply size: %d", rc); - ssh_buffer_free(reply); - return -1; - } - - SSH_LOG(SSH_LOG_WARN, - "Answer type: %d, expected answer: %d", - type, c2); - - if (agent_failed(type)) { - ssh_buffer_free(reply); - return 0; - } else if (type != c2) { - ssh_set_error(session, SSH_FATAL, - "Bad authentication reply message type: %d", type); - ssh_buffer_free(reply); - return -1; - } - - buffer_get_u32(reply, (uint32_t *) buf); - session->agent->count = agent_get_u32(buf); - SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d", - session->agent->count); - if (session->agent->count > 1024) { - ssh_set_error(session, SSH_FATAL, - "Too many identities in authentication reply: %d", - session->agent->count); - ssh_buffer_free(reply); - return -1; - } - - if (session->agent->ident) { - ssh_buffer_reinit(session->agent->ident); - } - session->agent->ident = reply; - - return session->agent->count; -} - -/* caller has to free commment */ -ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session, - char **comment) { - if (ssh_agent_get_ident_count(session) > 0) { - return ssh_agent_get_next_ident(session, comment); - } - - return NULL; -} - -/* caller has to free commment */ -ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session, - char **comment) { - struct ssh_key_struct *key; - struct ssh_string_struct *blob = NULL; - struct ssh_string_struct *tmp = NULL; - int rc; - - if (session->agent->count == 0) { - return NULL; - } - - switch(session->version) { - case 1: - return NULL; - case 2: - /* get the blob */ - blob = buffer_get_ssh_string(session->agent->ident); - if (blob == NULL) { - return NULL; - } - - /* get the comment */ - tmp = buffer_get_ssh_string(session->agent->ident); - if (tmp == NULL) { - ssh_string_free(blob); - - return NULL; - } - - if (comment) { - *comment = ssh_string_to_char(tmp); - } else { - ssh_string_free(blob); - ssh_string_free(tmp); - - return NULL; - } - ssh_string_free(tmp); - - /* get key from blob */ - rc = ssh_pki_import_pubkey_blob(blob, &key); - ssh_string_free(blob); - if (rc == SSH_ERROR) { - return NULL; - } - break; - default: - return NULL; - } - - return key; -} - -int agent_is_running(ssh_session session) { - if (session == NULL || session->agent == NULL) { - return 0; - } - - if (ssh_socket_is_open(session->agent->sock)) { - return 1; - } else { - if (agent_connect(session) < 0) { - return 0; - } else { - return 1; - } - } - - return 0; -} - -ssh_string ssh_agent_sign_data(ssh_session session, - const ssh_key pubkey, - struct ssh_buffer_struct *data) -{ - ssh_buffer request; - ssh_buffer reply; - ssh_string key_blob; - ssh_string sig_blob; - int type = SSH2_AGENT_FAILURE; - int flags = 0; - uint32_t dlen; - int rc; - - request = ssh_buffer_new(); - if (request == NULL) { - return NULL; - } - - /* create request */ - if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) { - ssh_buffer_free(request); - return NULL; - } - - rc = ssh_pki_export_pubkey_blob(pubkey, &key_blob); - if (rc < 0) { - ssh_buffer_free(request); - return NULL; - } - - /* adds len + blob */ - rc = buffer_add_ssh_string(request, key_blob); - ssh_string_free(key_blob); - if (rc < 0) { - ssh_buffer_free(request); - return NULL; - } - - /* Add data */ - dlen = buffer_get_rest_len(data); - if (buffer_add_u32(request, htonl(dlen)) < 0) { - ssh_buffer_free(request); - return NULL; - } - if (ssh_buffer_add_data(request, buffer_get_rest(data), dlen) < 0) { - ssh_buffer_free(request); - return NULL; - } - - if (buffer_add_u32(request, htonl(flags)) < 0) { - ssh_buffer_free(request); - return NULL; - } - - reply = ssh_buffer_new(); - if (reply == NULL) { - ssh_buffer_free(request); - return NULL; - } - - /* send the request */ - if (agent_talk(session, request, reply) < 0) { - ssh_buffer_free(request); - ssh_buffer_free(reply); - return NULL; - } - ssh_buffer_free(request); - - /* check if reply is valid */ - if (buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) { - ssh_buffer_free(reply); - return NULL; - } - - if (agent_failed(type)) { - SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key"); - ssh_buffer_free(reply); - return NULL; - } else if (type != SSH2_AGENT_SIGN_RESPONSE) { - ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type); - ssh_buffer_free(reply); - return NULL; - } - - sig_blob = buffer_get_ssh_string(reply); - ssh_buffer_free(reply); - - return sig_blob; -} - -#endif /* _WIN32 */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/auth.c b/libssh/src/auth.c deleted file mode 100644 index d56111d2..00000000 --- a/libssh/src/auth.c +++ /dev/null @@ -1,1810 +0,0 @@ -/* - * auth.c - Authentication with SSH protocols - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * Copyright (c) 2008-2013 Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/crypto.h" -#include "libssh/ssh2.h" -#include "libssh/buffer.h" -#include "libssh/agent.h" -#include "libssh/misc.h" -#include "libssh/packet.h" -#include "libssh/session.h" -#include "libssh/keys.h" -#include "libssh/auth.h" -#include "libssh/pki.h" -#include "libssh/gssapi.h" -#include "libssh/legacy.h" - -/** - * @defgroup libssh_auth The SSH authentication functions. - * @ingroup libssh - * - * Functions to authenticate with a server. - * - * @{ - */ - -/** - * @internal - * - * @brief Ask access to the ssh-userauth service. - * - * @param[in] session The SSH session handle. - * - * @returns SSH_OK on success, SSH_ERROR on error. - * @returns SSH_AGAIN on nonblocking mode, if calling that function - * again is necessary - */ -static int ssh_userauth_request_service(ssh_session session) { - int rc; - - rc = ssh_service_request(session, "ssh-userauth"); - if (rc != SSH_OK) { - SSH_LOG(SSH_LOG_WARN, - "Failed to request \"ssh-userauth\" service"); - } - - return rc; -} - -static int ssh_auth_response_termination(void *user){ - ssh_session session=(ssh_session)user; - switch(session->auth_state){ - case SSH_AUTH_STATE_NONE: - case SSH_AUTH_STATE_KBDINT_SENT: - case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: - case SSH_AUTH_STATE_GSSAPI_TOKEN: - case SSH_AUTH_STATE_GSSAPI_MIC_SENT: - return 0; - default: - return 1; - } -} - -/** - * @internal - * @brief Wait for a response of an authentication function. - * - * @param[in] session The SSH session. - * - * @returns SSH_AUTH_SUCCESS Authentication success, or pubkey accepted - * SSH_AUTH_PARTIAL Authentication succeeded but another mean - * of authentication is needed. - * SSH_AUTH_INFO Data for keyboard-interactive - * SSH_AUTH_AGAIN In nonblocking mode, call has to be made again - * SSH_AUTH_ERROR Error during the process. - */ -static int ssh_userauth_get_response(ssh_session session) { - int rc = SSH_AUTH_ERROR; - - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_USER, - ssh_auth_response_termination, session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - if (!ssh_auth_response_termination(session)){ - return SSH_AUTH_AGAIN; - } - - switch(session->auth_state) { - case SSH_AUTH_STATE_ERROR: - rc = SSH_AUTH_ERROR; - break; - case SSH_AUTH_STATE_FAILED: - rc = SSH_AUTH_DENIED; - break; - case SSH_AUTH_STATE_INFO: - rc = SSH_AUTH_INFO; - break; - case SSH_AUTH_STATE_PARTIAL: - rc = SSH_AUTH_PARTIAL; - break; - case SSH_AUTH_STATE_PK_OK: - case SSH_AUTH_STATE_SUCCESS: - rc = SSH_AUTH_SUCCESS; - break; - case SSH_AUTH_STATE_KBDINT_SENT: - case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: - case SSH_AUTH_STATE_GSSAPI_TOKEN: - case SSH_AUTH_STATE_GSSAPI_MIC_SENT: - case SSH_AUTH_STATE_NONE: - /* not reached */ - rc = SSH_AUTH_ERROR; - break; - } - - return rc; -} - -/** - * @internal - * - * @brief Handles a SSH_USERAUTH_BANNER packet. - * - * This banner should be shown to user prior to authentication - */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_banner){ - ssh_string banner; - (void)type; - (void)user; - - banner = buffer_get_ssh_string(packet); - if (banner == NULL) { - SSH_LOG(SSH_LOG_WARN, - "Invalid SSH_USERAUTH_BANNER packet"); - } else { - SSH_LOG(SSH_LOG_DEBUG, - "Received SSH_USERAUTH_BANNER packet"); - if(session->banner != NULL) - ssh_string_free(session->banner); - session->banner = banner; - } - - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handles a SSH_USERAUTH_FAILURE packet. - * - * This handles the complete or partial authentication failure. - */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){ - char *auth_methods = NULL; - uint8_t partial = 0; - int rc; - (void) type; - (void) user; - - rc = ssh_buffer_unpack(packet, "sb", &auth_methods, &partial); - if (rc != SSH_OK) { - ssh_set_error(session, SSH_FATAL, - "Invalid SSH_MSG_USERAUTH_FAILURE message"); - session->auth_state=SSH_AUTH_STATE_ERROR; - goto end; - } - - if (partial) { - session->auth_state=SSH_AUTH_STATE_PARTIAL; - SSH_LOG(SSH_LOG_INFO, - "Partial success. Authentication that can continue: %s", - auth_methods); - } else { - session->auth_state=SSH_AUTH_STATE_FAILED; - SSH_LOG(SSH_LOG_INFO, - "Access denied. Authentication that can continue: %s", - auth_methods); - ssh_set_error(session, SSH_REQUEST_DENIED, - "Access denied. Authentication that can continue: %s", - auth_methods); - - session->auth_methods = 0; - } - if (strstr(auth_methods, "password") != NULL) { - session->auth_methods |= SSH_AUTH_METHOD_PASSWORD; - } - if (strstr(auth_methods, "keyboard-interactive") != NULL) { - session->auth_methods |= SSH_AUTH_METHOD_INTERACTIVE; - } - if (strstr(auth_methods, "publickey") != NULL) { - session->auth_methods |= SSH_AUTH_METHOD_PUBLICKEY; - } - if (strstr(auth_methods, "hostbased") != NULL) { - session->auth_methods |= SSH_AUTH_METHOD_HOSTBASED; - } - if (strstr(auth_methods, "gssapi-with-mic") != NULL) { - session->auth_methods |= SSH_AUTH_METHOD_GSSAPI_MIC; - } - -end: - SAFE_FREE(auth_methods); - - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handles a SSH_USERAUTH_SUCCESS packet. - * - * It is also used to communicate the new to the upper levels. - */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_success){ - (void)packet; - (void)type; - (void)user; - - SSH_LOG(SSH_LOG_DEBUG, "Authentication successful"); - SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_SUCCESS"); - - session->auth_state=SSH_AUTH_STATE_SUCCESS; - session->session_state=SSH_SESSION_STATE_AUTHENTICATED; - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED; - - if(session->current_crypto && session->current_crypto->delayed_compress_out){ - SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression OUT"); - session->current_crypto->do_compress_out=1; - } - if(session->current_crypto && session->current_crypto->delayed_compress_in){ - SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression IN"); - session->current_crypto->do_compress_in=1; - } - - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handles a SSH_USERAUTH_PK_OK or SSH_USERAUTH_INFO_REQUEST packet. - * - * Since the two types of packets share the same code, additional work is done - * to understand if we are in a public key or keyboard-interactive context. - */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok){ - int rc; - - SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE"); - - if(session->auth_state==SSH_AUTH_STATE_KBDINT_SENT){ - /* Assuming we are in keyboard-interactive context */ - SSH_LOG(SSH_LOG_TRACE, - "keyboard-interactive context, assuming SSH_USERAUTH_INFO_REQUEST"); - rc=ssh_packet_userauth_info_request(session,type,packet,user); -#ifdef WITH_GSSAPI - } else if (session->auth_state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT){ - rc = ssh_packet_userauth_gssapi_response(session, type, packet, user); -#endif - } else { - session->auth_state=SSH_AUTH_STATE_PK_OK; - SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK"); - rc=SSH_PACKET_USED; - } - - return rc; -} - -/** - * @brief Get available authentication methods from the server. - * - * This requires the function ssh_userauth_none() to be called before the - * methods are available. The server MAY return a list of methods that may - * continue. - * - * @param[in] session The SSH session. - * - * @param[in] username Deprecated, set to NULL. - * - * @returns A bitfield of the fllowing values: - * - SSH_AUTH_METHOD_PASSWORD - * - SSH_AUTH_METHOD_PUBLICKEY - * - SSH_AUTH_METHOD_HOSTBASED - * - SSH_AUTH_METHOD_INTERACTIVE - * - * @warning Other reserved flags may appear in future versions. - * @see ssh_userauth_none() - */ -int ssh_userauth_list(ssh_session session, const char *username) -{ - (void) username; /* unused */ - - if (session == NULL) { - return 0; - } - -#ifdef WITH_SSH1 - if(session->version == 1) { - return SSH_AUTH_METHOD_PASSWORD; - } -#endif - - return session->auth_methods; -} - -/** - * @brief Try to authenticate through the "none" method. - * - * @param[in] session The ssh session to use. - * - * @param[in] username The username, this SHOULD be NULL. - * - * @returns SSH_AUTH_ERROR: A serious error happened.\n - * SSH_AUTH_DENIED: Authentication failed: use another method\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method\n - * SSH_AUTH_SUCCESS: Authentication success\n - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @note Most server implementations do not permit changing the username during - * authentication. The username should only be set with ssh_options_set() only - * before you connect to the server. - */ -int ssh_userauth_none(ssh_session session, const char *username) { - int rc; - -#ifdef WITH_SSH1 - if (session->version == 1) { - return ssh_userauth1_none(session, username); - } -#endif - - switch(session->pending_call_state){ - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_AUTH_NONE: - goto pending; - default: - ssh_set_error(session, SSH_FATAL, - "Wrong state during pending SSH call"); - return SSH_AUTH_ERROR; - } - - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) { - return SSH_AUTH_AGAIN; - } else if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - - /* request */ - rc = ssh_buffer_pack(session->out_buffer, "bsss", - SSH2_MSG_USERAUTH_REQUEST, - username ? username : session->opts.username, - "ssh-connection", - "none" - ); - if (rc < 0) { - goto fail; - } - - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE; - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) { - session->pending_call_state = SSH_PENDING_CALL_NONE; - } - - return rc; -fail: - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - - return SSH_AUTH_ERROR; -} - -/** - * @brief Try to authenticate with the given public key. - * - * To avoid unnecessary processing and user interaction, the following method - * is provided for querying whether authentication using the 'pubkey' would - * be possible. - * - * @param[in] session The SSH session. - * - * @param[in] username The username, this SHOULD be NULL. - * - * @param[in] pubkey The public key to try. - * - * @return SSH_AUTH_ERROR: A serious error happened.\n - * SSH_AUTH_DENIED: The server doesn't accept that public key as an - * authentication token. Try another key or another - * method.\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method.\n - * SSH_AUTH_SUCCESS: The public key is accepted, you want now to use - * ssh_userauth_pubkey(). - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @note Most server implementations do not permit changing the username during - * authentication. The username should only be set with ssh_options_set() only - * before you connect to the server. - */ -int ssh_userauth_try_publickey(ssh_session session, - const char *username, - const ssh_key pubkey) -{ - ssh_string pubkey_s = NULL; - int rc; - - if (session == NULL) { - return SSH_AUTH_ERROR; - } - - if (pubkey == NULL || !ssh_key_is_public(pubkey)) { - ssh_set_error(session, SSH_FATAL, "Invalid pubkey"); - return SSH_AUTH_ERROR; - } - -#ifdef WITH_SSH1 - if (session->version == 1) { - return SSH_AUTH_DENIED; - } -#endif - - switch(session->pending_call_state) { - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_AUTH_OFFER_PUBKEY: - goto pending; - default: - ssh_set_error(session, - SSH_FATAL, - "Wrong state during pending SSH call"); - return SSH_ERROR; - } - - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) { - return SSH_AUTH_AGAIN; - } else if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - - /* public key */ - rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s); - if (rc < 0) { - goto fail; - } - - /* request */ - rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", - SSH2_MSG_USERAUTH_REQUEST, - username ? username : session->opts.username, - "ssh-connection", - "publickey", - 0, /* private key ? */ - pubkey->type_c, /* algo */ - pubkey_s /* public key */ - ); - if (rc < 0) { - goto fail; - } - - ssh_string_free(pubkey_s); - - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY; - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) { - session->pending_call_state = SSH_PENDING_CALL_NONE; - } - - return rc; -fail: - ssh_string_free(pubkey_s); - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - - return SSH_AUTH_ERROR; -} - -/** - * @brief Authenticate with public/private key. - * - * @param[in] session The SSH session. - * - * @param[in] username The username, this SHOULD be NULL. - * - * @param[in] privkey The private key for authentication. - * - * @return SSH_AUTH_ERROR: A serious error happened.\n - * SSH_AUTH_DENIED: The server doesn't accept that public key as an - * authentication token. Try another key or another - * method.\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method.\n - * SSH_AUTH_SUCCESS: The public key is accepted, you want now to use - * ssh_userauth_pubkey(). - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @note Most server implementations do not permit changing the username during - * authentication. The username should only be set with ssh_options_set() only - * before you connect to the server. - */ -int ssh_userauth_publickey(ssh_session session, - const char *username, - const ssh_key privkey) -{ - ssh_string str = NULL; - int rc; - - if (session == NULL) { - return SSH_AUTH_ERROR; - } - - if (privkey == NULL || !ssh_key_is_private(privkey)) { - ssh_set_error(session, SSH_FATAL, "Invalid private key"); - return SSH_AUTH_ERROR; - } - -#ifdef WITH_SSH1 - if (session->version == 1) { - return SSH_AUTH_DENIED; - } -#endif - - switch(session->pending_call_state) { - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_AUTH_PUBKEY: - goto pending; - default: - ssh_set_error(session, - SSH_FATAL, - "Bad call during pending SSH call in ssh_userauth_try_pubkey"); - return SSH_AUTH_ERROR; - } - - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) { - return SSH_AUTH_AGAIN; - } else if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - - /* public key */ - rc = ssh_pki_export_pubkey_blob(privkey, &str); - if (rc < 0) { - goto fail; - } - - /* request */ - rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", - SSH2_MSG_USERAUTH_REQUEST, - username ? username : session->opts.username, - "ssh-connection", - "publickey", - 1, /* private key */ - privkey->type_c, /* algo */ - str /* public key */ - ); - if (rc < 0) { - goto fail; - } - ssh_string_free(str); - - /* sign the buffer with the private key */ - str = ssh_pki_do_sign(session, session->out_buffer, privkey); - if (str == NULL) { - goto fail; - } - - rc = buffer_add_ssh_string(session->out_buffer, str); - ssh_string_free(str); - str = NULL; - if (rc < 0) { - goto fail; - } - - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY; - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) { - session->pending_call_state = SSH_PENDING_CALL_NONE; - } - - return rc; -fail: - ssh_string_free(str); - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - - return SSH_AUTH_ERROR; -} - -#ifndef _WIN32 -static int ssh_userauth_agent_publickey(ssh_session session, - const char *username, - ssh_key pubkey) -{ - ssh_string str = NULL; - int rc; - - switch(session->pending_call_state) { - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_AUTH_AGENT: - goto pending; - default: - ssh_set_error(session, - SSH_FATAL, - "Bad call during pending SSH call in ssh_userauth_try_pubkey"); - return SSH_ERROR; - } - - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) { - return SSH_AUTH_AGAIN; - } else if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - - - /* public key */ - rc = ssh_pki_export_pubkey_blob(pubkey, &str); - if (rc < 0) { - goto fail; - } - - /* request */ - rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", - SSH2_MSG_USERAUTH_REQUEST, - username ? username : session->opts.username, - "ssh-connection", - "publickey", - 1, /* private key */ - pubkey->type_c, /* algo */ - str /* public key */ - ); - if (rc < 0) { - goto fail; - } - - ssh_string_free(str); - - /* sign the buffer with the private key */ - str = ssh_pki_do_sign_agent(session, session->out_buffer, pubkey); - if (str == NULL) { - goto fail; - } - - rc = buffer_add_ssh_string(session->out_buffer, str); - ssh_string_free(str); - if (rc < 0) { - goto fail; - } - - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT; - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) { - session->pending_call_state = SSH_PENDING_CALL_NONE; - } - - return rc; -fail: - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - ssh_string_free(str); - - return SSH_AUTH_ERROR; -} - -enum ssh_agent_state_e { - SSH_AGENT_STATE_NONE = 0, - SSH_AGENT_STATE_PUBKEY, - SSH_AGENT_STATE_AUTH -}; - -struct ssh_agent_state_struct { - enum ssh_agent_state_e state; - ssh_key pubkey; - char *comment; -}; - - -/** - * @brief Try to do public key authentication with ssh agent. - * - * @param[in] session The ssh session to use. - * - * @param[in] username The username, this SHOULD be NULL. - * - * @return SSH_AUTH_ERROR: A serious error happened.\n - * SSH_AUTH_DENIED: The server doesn't accept that public key as an - * authentication token. Try another key or another - * method.\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method.\n - * SSH_AUTH_SUCCESS: The public key is accepted, you want now to use - * ssh_userauth_pubkey(). - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @note Most server implementations do not permit changing the username during - * authentication. The username should only be set with ssh_options_set() only - * before you connect to the server. - */ -int ssh_userauth_agent(ssh_session session, - const char *username) { - int rc = SSH_AUTH_ERROR; - struct ssh_agent_state_struct *state; - if (session == NULL) { - return SSH_AUTH_ERROR; - } - - if (!agent_is_running(session)) { - return SSH_AUTH_DENIED; - } - if (!session->agent_state){ - session->agent_state = malloc(sizeof(struct ssh_agent_state_struct)); - if (!session->agent_state){ - ssh_set_error_oom(session); - return SSH_AUTH_ERROR; - } - ZERO_STRUCTP(session->agent_state); - session->agent_state->state=SSH_AGENT_STATE_NONE; - } - state = session->agent_state; - if (state->pubkey == NULL) - state->pubkey = ssh_agent_get_first_ident(session, &state->comment); - while (state->pubkey != NULL) { - if(state->state == SSH_AGENT_STATE_NONE){ - SSH_LOG(SSH_LOG_DEBUG, - "Trying identity %s", state->comment); - } - if(state->state == SSH_AGENT_STATE_NONE || - state->state == SSH_AGENT_STATE_PUBKEY){ - rc = ssh_userauth_try_publickey(session, username, state->pubkey); - if (rc == SSH_AUTH_ERROR) { - ssh_string_free_char(state->comment); - ssh_key_free(state->pubkey); - SAFE_FREE(session->agent_state); - return rc; - } else if (rc == SSH_AUTH_AGAIN) { - state->state = SSH_AGENT_STATE_PUBKEY; - return rc; - } else if (rc != SSH_AUTH_SUCCESS) { - SSH_LOG(SSH_LOG_DEBUG, - "Public key of %s refused by server", state->comment); - ssh_string_free_char(state->comment); - ssh_key_free(state->pubkey); - state->pubkey = ssh_agent_get_next_ident(session, &state->comment); - state->state = SSH_AGENT_STATE_NONE; - continue; - } - - SSH_LOG(SSH_LOG_DEBUG, - "Public key of %s accepted by server", state->comment); - state->state = SSH_AGENT_STATE_AUTH; - } - if (state->state == SSH_AGENT_STATE_AUTH){ - rc = ssh_userauth_agent_publickey(session, username, state->pubkey); - if (rc == SSH_AUTH_AGAIN) - return rc; - ssh_string_free_char(state->comment); - ssh_key_free(state->pubkey); - if (rc == SSH_AUTH_ERROR) { - SAFE_FREE(session->agent_state); - return rc; - } else if (rc != SSH_AUTH_SUCCESS) { - SSH_LOG(SSH_LOG_INFO, - "Server accepted public key but refused the signature"); - state->pubkey = ssh_agent_get_next_ident(session, &state->comment); - state->state = SSH_AGENT_STATE_NONE; - continue; - } - SAFE_FREE(session->agent_state); - return SSH_AUTH_SUCCESS; - } - } - - SAFE_FREE(session->agent_state); - return rc; -} -#endif - -enum ssh_auth_auto_state_e { - SSH_AUTH_AUTO_STATE_NONE=0, - SSH_AUTH_AUTO_STATE_PUBKEY, - SSH_AUTH_AUTO_STATE_KEY_IMPORTED, - SSH_AUTH_AUTO_STATE_PUBKEY_ACCEPTED -}; - -struct ssh_auth_auto_state_struct { - enum ssh_auth_auto_state_e state; - struct ssh_iterator *it; - ssh_key privkey; - ssh_key pubkey; -}; - -/** - * @brief Tries to automatically authenticate with public key and "none" - * - * It may fail, for instance it doesn't ask for a password and uses a default - * asker for passphrases (in case the private key is encrypted). - * - * @param[in] session The SSH session. - * - * @param[in] username The username, this SHOULD be NULL. - * - * @param[in] passphrase Use this passphrase to unlock the privatekey. Use NULL - * if you don't want to use a passphrase or the user - * should be asked. - * - * @return SSH_AUTH_ERROR: A serious error happened.\n - * SSH_AUTH_DENIED: The server doesn't accept that public key as an - * authentication token. Try another key or another - * method.\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method.\n - * SSH_AUTH_SUCCESS: The public key is accepted, you want now to use - * ssh_userauth_pubkey(). - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @note Most server implementations do not permit changing the username during - * authentication. The username should only be set with ssh_options_set() only - * before you connect to the server. - */ -int ssh_userauth_publickey_auto(ssh_session session, - const char *username, - const char *passphrase) -{ - ssh_auth_callback auth_fn = NULL; - void *auth_data = NULL; - struct ssh_auth_auto_state_struct *state; - int rc; - - if (session == NULL) { - return SSH_AUTH_ERROR; - } - - if (session->common.callbacks) { - auth_fn = session->common.callbacks->auth_function; - auth_data = session->common.callbacks->userdata; - } - if (!session->auth_auto_state){ - session->auth_auto_state = - malloc(sizeof(struct ssh_auth_auto_state_struct)); - if (!session->auth_auto_state){ - ssh_set_error_oom(session); - return SSH_AUTH_ERROR; - } - ZERO_STRUCTP(session->auth_auto_state); - } - state = session->auth_auto_state; - if (state->state == SSH_AUTH_AUTO_STATE_NONE) { -#ifndef _WIN32 - /* Try authentication with ssh-agent first */ - rc = ssh_userauth_agent(session, username); - if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_AGAIN) { - return rc; - } -#endif - state->state = SSH_AUTH_AUTO_STATE_PUBKEY; - } - if (state->it == NULL) { - state->it = ssh_list_get_iterator(session->opts.identity); - } - - while (state->it != NULL){ - const char *privkey_file = state->it->data; - char pubkey_file[1024] = {0}; - if (state->state == SSH_AUTH_AUTO_STATE_PUBKEY){ - SSH_LOG(SSH_LOG_DEBUG, - "Trying to authenticate with %s", privkey_file); - state->privkey = NULL; - state->pubkey = NULL; - snprintf(pubkey_file, sizeof(pubkey_file), "%s.pub", privkey_file); - - rc = ssh_pki_import_pubkey_file(pubkey_file, &state->pubkey); - if (rc == SSH_ERROR) { - ssh_set_error(session, - SSH_FATAL, - "Failed to import public key: %s", - pubkey_file); - SAFE_FREE(session->auth_auto_state); - return SSH_AUTH_ERROR; - } else if (rc == SSH_EOF) { - /* Read the private key and save the public key to file */ - rc = ssh_pki_import_privkey_file(privkey_file, - passphrase, - auth_fn, - auth_data, - &state->privkey); - if (rc == SSH_ERROR) { - ssh_set_error(session, - SSH_FATAL, - "Failed to read private key: %s", - privkey_file); - state->it=state->it->next; - continue; - } else if (rc == SSH_EOF) { - /* If the file doesn't exist, continue */ - SSH_LOG(SSH_LOG_DEBUG, - "Private key %s doesn't exist.", - privkey_file); - state->it=state->it->next; - continue; - } - - rc = ssh_pki_export_privkey_to_pubkey(state->privkey, &state->pubkey); - if (rc == SSH_ERROR) { - ssh_key_free(state->privkey); - SAFE_FREE(session->auth_auto_state); - return SSH_AUTH_ERROR; - } - - rc = ssh_pki_export_pubkey_file(state->pubkey, pubkey_file); - if (rc == SSH_ERROR) { - SSH_LOG(SSH_LOG_WARN, - "Could not write public key to file: %s", - pubkey_file); - } - } - state->state = SSH_AUTH_AUTO_STATE_KEY_IMPORTED; - } - if (state->state == SSH_AUTH_AUTO_STATE_KEY_IMPORTED){ - rc = ssh_userauth_try_publickey(session, username, state->pubkey); - if (rc == SSH_AUTH_ERROR) { - SSH_LOG(SSH_LOG_WARN, - "Public key authentication error for %s", - privkey_file); - ssh_key_free(state->privkey); - ssh_key_free(state->pubkey); - SAFE_FREE(session->auth_auto_state); - return rc; - } else if (rc == SSH_AUTH_AGAIN){ - return rc; - } else if (rc != SSH_AUTH_SUCCESS) { - SSH_LOG(SSH_LOG_DEBUG, - "Public key for %s refused by server", - privkey_file); - ssh_key_free(state->privkey); - state->privkey = NULL; - ssh_key_free(state->pubkey); - state->pubkey = NULL; - state->it=state->it->next; - state->state = SSH_AUTH_AUTO_STATE_PUBKEY; - continue; - } - state->state = SSH_AUTH_AUTO_STATE_PUBKEY_ACCEPTED; - } - if (state->state == SSH_AUTH_AUTO_STATE_PUBKEY_ACCEPTED){ - /* Public key has been accepted by the server */ - if (state->privkey == NULL) { - rc = ssh_pki_import_privkey_file(privkey_file, - passphrase, - auth_fn, - auth_data, - &state->privkey); - if (rc == SSH_ERROR) { - ssh_key_free(state->pubkey); - state->pubkey=NULL; - ssh_set_error(session, - SSH_FATAL, - "Failed to read private key: %s", - privkey_file); - state->it=state->it->next; - state->state = SSH_AUTH_AUTO_STATE_PUBKEY; - continue; - } else if (rc == SSH_EOF) { - /* If the file doesn't exist, continue */ - ssh_key_free(state->pubkey); - state->pubkey=NULL; - SSH_LOG(SSH_LOG_INFO, - "Private key %s doesn't exist.", - privkey_file); - state->it=state->it->next; - state->state = SSH_AUTH_AUTO_STATE_PUBKEY; - continue; - } - } - - rc = ssh_userauth_publickey(session, username, state->privkey); - if (rc != SSH_AUTH_AGAIN && rc != SSH_AUTH_DENIED) { - ssh_key_free(state->privkey); - ssh_key_free(state->pubkey); - SAFE_FREE(session->auth_auto_state); - } - if (rc == SSH_AUTH_ERROR) { - return rc; - } else if (rc == SSH_AUTH_SUCCESS) { - SSH_LOG(SSH_LOG_INFO, - "Successfully authenticated using %s", - privkey_file); - return rc; - } else if (rc == SSH_AUTH_AGAIN){ - return rc; - } - - SSH_LOG(SSH_LOG_WARN, - "The server accepted the public key but refused the signature"); - state->it=state->it->next; - state->state=SSH_AUTH_AUTO_STATE_PUBKEY; - /* continue */ - } - } - SSH_LOG(SSH_LOG_INFO, - "Tried every public key, none matched"); - SAFE_FREE(session->auth_auto_state); - return SSH_AUTH_DENIED; -} - -/** - * @brief Try to authenticate by password. - * - * This authentication method is normally disabled on SSHv2 server. You should - * use keyboard-interactive mode. - * - * The 'password' value MUST be encoded UTF-8. It is up to the server how to - * interpret the password and validate it against the password database. - * However, if you read the password in some other encoding, you MUST convert - * the password to UTF-8. - * - * @param[in] session The ssh session to use. - * - * @param[in] username The username, this SHOULD be NULL. - * - * @param[in] password The password to authenticate in UTF-8. - * - * @returns SSH_AUTH_ERROR: A serious error happened.\n - * SSH_AUTH_DENIED: Authentication failed: use another method\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method\n - * SSH_AUTH_SUCCESS: Authentication success\n - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @note Most server implementations do not permit changing the username during - * authentication. The username should only be set with ssh_options_set() only - * before you connect to the server. - * - * @see ssh_userauth_none() - * @see ssh_userauth_kbdint() - */ -int ssh_userauth_password(ssh_session session, - const char *username, - const char *password) { - int rc; - -#ifdef WITH_SSH1 - if (session->version == 1) { - rc = ssh_userauth1_password(session, username, password); - return rc; - } -#endif - - switch(session->pending_call_state) { - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_AUTH_OFFER_PUBKEY: - goto pending; - default: - ssh_set_error(session, - SSH_FATAL, - "Wrong state during pending SSH call"); - return SSH_ERROR; - } - - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) { - return SSH_AUTH_AGAIN; - } else if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - - /* request */ - rc = ssh_buffer_pack(session->out_buffer, "bsssbs", - SSH2_MSG_USERAUTH_REQUEST, - username ? username : session->opts.username, - "ssh-connection", - "password", - 0, /* false */ - password - ); - if (rc < 0) { - goto fail; - } - - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY; - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) { - session->pending_call_state = SSH_PENDING_CALL_NONE; - } - - return rc; -fail: - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - - return SSH_AUTH_ERROR; -} - -#ifndef _WIN32 -/* LEGACY */ -int ssh_userauth_agent_pubkey(ssh_session session, - const char *username, - ssh_public_key publickey) -{ - ssh_key key; - int rc; - - key = ssh_key_new(); - if (key == NULL) { - return SSH_AUTH_ERROR; - } - - key->type = publickey->type; - key->type_c = ssh_key_type_to_char(key->type); - key->flags = SSH_KEY_FLAG_PUBLIC; - key->dsa = publickey->dsa_pub; - key->rsa = publickey->rsa_pub; - - rc = ssh_userauth_agent_publickey(session, username, key); - - key->dsa = NULL; - key->rsa = NULL; - ssh_key_free(key); - - return rc; -} -#endif /* _WIN32 */ - -ssh_kbdint ssh_kbdint_new(void) { - ssh_kbdint kbd; - - kbd = malloc(sizeof(struct ssh_kbdint_struct)); - if (kbd == NULL) { - return NULL; - } - ZERO_STRUCTP(kbd); - - return kbd; -} - - -void ssh_kbdint_free(ssh_kbdint kbd) { - int i, n; - - if (kbd == NULL) { - return; - } - - SAFE_FREE(kbd->name); - SAFE_FREE(kbd->instruction); - SAFE_FREE(kbd->echo); - - n = kbd->nprompts; - if (kbd->prompts) { - for (i = 0; i < n; i++) { - BURN_STRING(kbd->prompts[i]); - SAFE_FREE(kbd->prompts[i]); - } - SAFE_FREE(kbd->prompts); - } - - n = kbd->nanswers; - if (kbd->answers) { - for (i = 0; i < n; i++) { - BURN_STRING(kbd->answers[i]); - SAFE_FREE(kbd->answers[i]); - } - SAFE_FREE(kbd->answers); - } - - SAFE_FREE(kbd); -} - -void ssh_kbdint_clean(ssh_kbdint kbd) { - int i, n; - - if (kbd == NULL) { - return; - } - - SAFE_FREE(kbd->name); - SAFE_FREE(kbd->instruction); - SAFE_FREE(kbd->echo); - - n = kbd->nprompts; - if (kbd->prompts) { - for (i = 0; i < n; i++) { - BURN_STRING(kbd->prompts[i]); - SAFE_FREE(kbd->prompts[i]); - } - SAFE_FREE(kbd->prompts); - } - - n = kbd->nanswers; - - if (kbd->answers) { - for (i = 0; i < n; i++) { - BURN_STRING(kbd->answers[i]); - SAFE_FREE(kbd->answers[i]); - } - SAFE_FREE(kbd->answers); - } - - kbd->nprompts = 0; - kbd->nanswers = 0; -} - -/* - * This function sends the first packet as explained in RFC 3066 section 3.1. - */ -static int ssh_userauth_kbdint_init(ssh_session session, - const char *username, - const char *submethods) -{ - int rc; - if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT) - goto pending; - if (session->pending_call_state != SSH_PENDING_CALL_NONE){ - ssh_set_error_invalid(session); - return SSH_ERROR; - } - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) - return SSH_AUTH_AGAIN; - if (rc != SSH_OK) { - return SSH_AUTH_ERROR; - } - - /* request */ - rc = ssh_buffer_pack(session->out_buffer, "bsssss", - SSH2_MSG_USERAUTH_REQUEST, - username ? username : session->opts.username, - "ssh-connection", - "keyboard-interactive", - "", /* lang (ignore it) */ - submethods ? submethods : "" - ); - if (rc < 0) { - goto fail; - } - - - session->auth_state = SSH_AUTH_STATE_KBDINT_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_INIT; - - SSH_LOG(SSH_LOG_DEBUG, - "Sending keyboard-interactive init request"); - - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) - session->pending_call_state = SSH_PENDING_CALL_NONE; - return rc; -fail: - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - - return SSH_AUTH_ERROR; -} - -/** - * @internal - * - * @brief Send the current challenge response and wait for a reply from the - * server. - * - * @returns SSH_AUTH_INFO if more info is needed - * @returns SSH_AUTH_SUCCESS - * @returns SSH_AUTH_FAILURE - * @returns SSH_AUTH_PARTIAL - */ -static int ssh_userauth_kbdint_send(ssh_session session) -{ - uint32_t i; - int rc; - if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_SEND) - goto pending; - if (session->pending_call_state != SSH_PENDING_CALL_NONE){ - ssh_set_error_invalid(session); - return SSH_ERROR; - } - rc = ssh_buffer_pack(session->out_buffer, "bd", - SSH2_MSG_USERAUTH_INFO_RESPONSE, - session->kbdint->nprompts); - if (rc < 0) { - goto fail; - } - - for (i = 0; i < session->kbdint->nprompts; i++) { - rc = ssh_buffer_pack(session->out_buffer, "s", - session->kbdint->answers && session->kbdint->answers[i] ? - session->kbdint->answers[i]:""); - if (rc < 0) { - goto fail; - } - } - - session->auth_state = SSH_AUTH_STATE_KBDINT_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_SEND; - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - SSH_LOG(SSH_LOG_DEBUG, - "Sending keyboard-interactive response packet"); - - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) - session->pending_call_state = SSH_PENDING_CALL_NONE; - return rc; -fail: - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - - return SSH_AUTH_ERROR; -} - -/** - * @internal - * @brief handles a SSH_USERAUTH_INFO_REQUEST packet, as used in - * keyboard-interactive authentication, and changes the - * authentication state. - */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) { - ssh_string tmp = NULL; - uint32_t nprompts; - uint32_t i; - int rc; - (void)user; - (void)type; - - - if (session->kbdint == NULL) { - session->kbdint = ssh_kbdint_new(); - if (session->kbdint == NULL) { - ssh_set_error_oom(session); - return SSH_PACKET_USED; - } - } else { - ssh_kbdint_clean(session->kbdint); - } - - rc = ssh_buffer_unpack(packet, "ssSd", - &session->kbdint->name, /* name of the "asking" window shown to client */ - &session->kbdint->instruction, - &tmp, /* to ignore */ - &nprompts - ); - - /* We don't care about tmp */ - ssh_string_free(tmp); - - if (rc != SSH_OK) { - ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg"); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_DEBUG, - "%d keyboard-interactive prompts", nprompts); - if (nprompts > KBDINT_MAX_PROMPT) { - ssh_set_error(session, SSH_FATAL, - "Too much prompts requested by the server: %u (0x%.4x)", - nprompts, nprompts); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - return SSH_PACKET_USED; - } - - session->kbdint->nprompts = nprompts; - session->kbdint->nanswers = nprompts; - session->kbdint->prompts = malloc(nprompts * sizeof(char *)); - if (session->kbdint->prompts == NULL) { - session->kbdint->nprompts = 0; - ssh_set_error_oom(session); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - return SSH_PACKET_USED; - } - memset(session->kbdint->prompts, 0, nprompts * sizeof(char *)); - - session->kbdint->echo = malloc(nprompts); - if (session->kbdint->echo == NULL) { - session->kbdint->nprompts = 0; - ssh_set_error_oom(session); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - return SSH_PACKET_USED; - } - memset(session->kbdint->echo, 0, nprompts); - - for (i = 0; i < nprompts; i++) { - rc = ssh_buffer_unpack(packet, "sb", - &session->kbdint->prompts[i], - &session->kbdint->echo[i]); - if (rc == SSH_ERROR) { - ssh_set_error(session, SSH_FATAL, "Short INFO_REQUEST packet"); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - return SSH_PACKET_USED; - } - } - session->auth_state=SSH_AUTH_STATE_INFO; - - return SSH_PACKET_USED; -} - -/** - * @brief Try to authenticate through the "keyboard-interactive" method. - * - * @param[in] session The ssh session to use. - * - * @param[in] user The username to authenticate. You can specify NULL if - * ssh_option_set_username() has been used. You cannot try - * two different logins in a row. - * - * @param[in] submethods Undocumented. Set it to NULL. - * - * @returns SSH_AUTH_ERROR: A serious error happened\n - * SSH_AUTH_DENIED: Authentication failed : use another method\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method\n - * SSH_AUTH_SUCCESS: Authentication success\n - * SSH_AUTH_INFO: The server asked some questions. Use - * ssh_userauth_kbdint_getnprompts() and such.\n - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - * - * @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() - */ -int ssh_userauth_kbdint(ssh_session session, const char *user, - const char *submethods) { - int rc = SSH_AUTH_ERROR; - - if (session == NULL) { - return SSH_AUTH_ERROR; - } - -#ifdef WITH_SSH1 - if (session->version == 1) { - return SSH_AUTH_DENIED; - } -#endif - if ((session->pending_call_state == SSH_PENDING_CALL_NONE && session->kbdint == NULL) || - session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT) - rc = ssh_userauth_kbdint_init(session, user, submethods); - else if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_SEND || - session->kbdint != NULL) { - /* - * If we are at this point, it is because session->kbdint exists. - * It means the user has set some information there we need to send - * the server and then we need to ack the status (new questions or ok - * pass in). - * It is possible that session->kbdint is NULL while we're waiting for - * a reply, hence the test for the pending call. - */ - rc = ssh_userauth_kbdint_send(session); - } else { - /* We are here because session->kbdint == NULL & state != NONE. - * This should not happen - */ - rc = SSH_AUTH_ERROR; - ssh_set_error(session,SSH_FATAL,"Invalid state in %s", __FUNCTION__); - } - return rc; -} - -/** - * @brief Get the number of prompts (questions) the server has given. - * - * Once you have called ssh_userauth_kbdint() and received SSH_AUTH_INFO return - * code, this function can be used to retrieve information about the keyboard - * interactive authentication questions sent by the remote host. - * - * @param[in] session The ssh session to use. - * - * @returns The number of prompts. - */ -int ssh_userauth_kbdint_getnprompts(ssh_session session) { - if(session==NULL) - return SSH_ERROR; - if(session->kbdint == NULL) { - ssh_set_error_invalid(session); - return SSH_ERROR; - } - return session->kbdint->nprompts; -} - -/** - * @brief Get the "name" of the message block. - * - * Once you have called ssh_userauth_kbdint() and received SSH_AUTH_INFO return - * code, this function can be used to retrieve information about the keyboard - * interactive authentication questions sent by the remote host. - * - * @param[in] session The ssh session to use. - * - * @returns The name of the message block. Do not free it. - */ -const char *ssh_userauth_kbdint_getname(ssh_session session) { - if(session==NULL) - return NULL; - if(session->kbdint == NULL) { - ssh_set_error_invalid(session); - return NULL; - } - return session->kbdint->name; -} - -/** - * @brief Get the "instruction" of the message block. - * - * Once you have called ssh_userauth_kbdint() and received SSH_AUTH_INFO return - * code, this function can be used to retrieve information about the keyboard - * interactive authentication questions sent by the remote host. - * - * @param[in] session The ssh session to use. - * - * @returns The instruction of the message block. - */ - -const char *ssh_userauth_kbdint_getinstruction(ssh_session session) { - if(session==NULL) - return NULL; - if(session->kbdint == NULL) { - ssh_set_error_invalid(session); - return NULL; - } - return session->kbdint->instruction; -} - -/** - * @brief Get a prompt from a message block. - * - * Once you have called ssh_userauth_kbdint() and received SSH_AUTH_INFO return - * code, this function can be used to retrieve information about the keyboard - * interactive authentication questions sent by the remote host. - * - * @param[in] session The ssh session to use. - * - * @param[in] i The index number of the i'th prompt. - * - * @param[out] echo This is an optional variable. You can obtain a - * boolean if the user input should be echoed or - * hidden. For passwords it is usually hidden. - * - * @returns A pointer to the prompt. Do not free it. - * - * @code - * const char prompt; - * char echo; - * - * prompt = ssh_userauth_kbdint_getprompt(session, 0, &echo); - * if (echo) ... - * @endcode - */ -const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i, - char *echo) { - if(session==NULL) - return NULL; - if(session->kbdint == NULL) { - ssh_set_error_invalid(session); - return NULL; - } - if (i > session->kbdint->nprompts) { - ssh_set_error_invalid(session); - return NULL; - } - - if (echo) { - *echo = session->kbdint->echo[i]; - } - - return session->kbdint->prompts[i]; -} - -#ifdef WITH_SERVER -/** - * @brief Get the number of answers the client has given. - * - * @param[in] session The ssh session to use. - * - * @returns The number of answers. - */ -int ssh_userauth_kbdint_getnanswers(ssh_session session) { - if(session==NULL || session->kbdint == NULL) - return SSH_ERROR; - return session->kbdint->nanswers; -} - -/** - * @brief Get the answer for a question from a message block. - * - * @param[in] session The ssh session to use. - * - * @param[in] i index The number of the ith answer. - * - * @return 0 on success, < 0 on error. - */ -const char *ssh_userauth_kbdint_getanswer(ssh_session session, unsigned int i) { - if(session==NULL || session->kbdint == NULL - || session->kbdint->answers == NULL) { - return NULL; - } - if (i >= session->kbdint->nanswers) { - return NULL; - } - - return session->kbdint->answers[i]; -} -#endif - -/** - * @brief Set the answer for a question from a message block. - * - * If you have called ssh_userauth_kbdint() and got SSH_AUTH_INFO, this - * function returns the questions from the server. - * - * @param[in] session The ssh session to use. - * - * @param[in] i index The number of the ith prompt. - * - * @param[in] answer The answer to give to the server. The answer MUST be - * encoded UTF-8. It is up to the server how to interpret - * the value and validate it. However, if you read the - * answer in some other encoding, you MUST convert it to - * UTF-8. - * - * @return 0 on success, < 0 on error. - */ -int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i, - const char *answer) { - if (session == NULL) - return -1; - if (answer == NULL || session->kbdint == NULL || - i >= session->kbdint->nprompts) { - ssh_set_error_invalid(session); - return -1; - } - - if (session->kbdint->answers == NULL) { - session->kbdint->answers = malloc(sizeof(char*) * session->kbdint->nprompts); - if (session->kbdint->answers == NULL) { - ssh_set_error_oom(session); - return -1; - } - memset(session->kbdint->answers, 0, sizeof(char *) * session->kbdint->nprompts); - } - - if (session->kbdint->answers[i]) { - BURN_STRING(session->kbdint->answers[i]); - SAFE_FREE(session->kbdint->answers[i]); - } - - session->kbdint->answers[i] = strdup(answer); - if (session->kbdint->answers[i] == NULL) { - ssh_set_error_oom(session); - return -1; - } - - return 0; -} - -/** - * @brief Try to authenticate through the "gssapi-with-mic" method. - * - * @param[in] session The ssh session to use. - * - * @returns SSH_AUTH_ERROR: A serious error happened\n - * SSH_AUTH_DENIED: Authentication failed : use another method\n - * SSH_AUTH_PARTIAL: You've been partially authenticated, you still - * have to use another method\n - * SSH_AUTH_SUCCESS: Authentication success\n - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - */ -int ssh_userauth_gssapi(ssh_session session) { - int rc = SSH_AUTH_DENIED; -#ifdef WITH_GSSAPI - switch(session->pending_call_state) { - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_AUTH_GSSAPI_MIC: - goto pending; - default: - ssh_set_error(session, - SSH_FATAL, - "Wrong state during pending SSH call"); - return SSH_ERROR; - } - - rc = ssh_userauth_request_service(session); - if (rc == SSH_AGAIN) { - return SSH_AUTH_AGAIN; - } else if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi-with-mic"); - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_GSSAPI_MIC; - rc = ssh_gssapi_auth_mic(session); - - if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_DENIED) { - session->auth_state = SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_NONE; - return rc; - } - -pending: - rc = ssh_userauth_get_response(session); - if (rc != SSH_AUTH_AGAIN) { - session->pending_call_state = SSH_PENDING_CALL_NONE; - } -#else - (void) session; /* unused */ -#endif - return rc; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/auth1.c b/libssh/src/auth1.c deleted file mode 100644 index a65c4475..00000000 --- a/libssh/src/auth1.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * auth1.c - authentication with SSH-1 protocol - * - * This file is part of the SSH Library - * - * Copyright (c) 2005-2008 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include - -#include "libssh/priv.h" -#include "libssh/ssh1.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/session.h" -#include "libssh/string.h" - -#ifdef WITH_SSH1 - -static int ssh_auth_status_termination(void *s){ - ssh_session session=s; - if(session->auth_state != SSH_AUTH_STATE_NONE || - session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - return 0; -} - -static int wait_auth1_status(ssh_session session) { - /* wait for a packet */ - if (ssh_handle_packets_termination(session,SSH_TIMEOUT_USER, - ssh_auth_status_termination, session) != SSH_OK){ - - return SSH_AUTH_ERROR; - } - SSH_LOG(SSH_LOG_PROTOCOL,"Auth state : %d",session->auth_state); - - switch(session->auth_state) { - case SSH_AUTH_STATE_SUCCESS: - return SSH_AUTH_SUCCESS; - case SSH_AUTH_STATE_FAILED: - return SSH_AUTH_DENIED; - default: - return SSH_AUTH_AGAIN; - } - return SSH_AUTH_ERROR; -} - -void ssh_auth1_handler(ssh_session session, uint8_t type){ - if(session->session_state != SSH_SESSION_STATE_AUTHENTICATING){ - ssh_set_error(session,SSH_FATAL,"SSH_SMSG_SUCCESS or FAILED received in wrong state"); - return; - } - if(type==SSH_SMSG_SUCCESS){ - session->auth_state=SSH_AUTH_STATE_SUCCESS; - session->session_state=SSH_SESSION_STATE_AUTHENTICATED; - } else if(type==SSH_SMSG_FAILURE) - session->auth_state=SSH_AUTH_STATE_FAILED; -} - -static int send_username(ssh_session session, const char *username) { - ssh_string user = NULL; - int rc; - /* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */ - if(session->auth_service_state == SSH_AUTH_SERVICE_USER_SENT) { - if(session->auth_state == SSH_AUTH_STATE_FAILED) - return SSH_AUTH_DENIED; - if(session->auth_state == SSH_AUTH_STATE_SUCCESS) - return SSH_AUTH_SUCCESS; - return SSH_AUTH_ERROR; - } - if (session->auth_service_state == SSH_AUTH_SERVICE_SENT) - goto pending; - if (!username) { - if(!(username = session->opts.username)) { - if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) { - session->auth_service_state = SSH_AUTH_SERVICE_DENIED; - return SSH_ERROR; - } else { - username = session->opts.username; - } - } - } - user = ssh_string_from_char(username); - if (user == NULL) { - return SSH_AUTH_ERROR; - } - - if (buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) { - ssh_string_free(user); - return SSH_AUTH_ERROR; - } - if (buffer_add_ssh_string(session->out_buffer, user) < 0) { - ssh_string_free(user); - return SSH_AUTH_ERROR; - } - ssh_string_free(user); - session->auth_state=SSH_AUTH_STATE_NONE; - session->auth_service_state = SSH_AUTH_SERVICE_SENT; - if (packet_send(session) == SSH_ERROR) { - return SSH_AUTH_ERROR; - } -pending: - rc = wait_auth1_status(session); - switch (rc){ - case SSH_AUTH_SUCCESS: - session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT; - session->auth_state=SSH_AUTH_STATE_SUCCESS; - ssh_set_error(session, SSH_NO_ERROR, "Authentication successful"); - return SSH_AUTH_SUCCESS; - case SSH_AUTH_DENIED: - session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT; - ssh_set_error(session,SSH_REQUEST_DENIED,"Password authentication necessary for user %s",username); - return SSH_AUTH_DENIED; - case SSH_AUTH_AGAIN: - return SSH_AUTH_AGAIN; - default: - session->auth_service_state = SSH_AUTH_SERVICE_NONE; - session->auth_state=SSH_AUTH_STATE_ERROR; - return SSH_AUTH_ERROR; - } -} - -/* use the "none" authentication question */ -int ssh_userauth1_none(ssh_session session, const char *username){ - return send_username(session, username); -} - -/** \internal - * \todo implement ssh1 public key - */ -int ssh_userauth1_offer_pubkey(ssh_session session, const char *username, - int type, ssh_string pubkey) { - (void) session; - (void) username; - (void) type; - (void) pubkey; - - return SSH_AUTH_DENIED; -} - -int ssh_userauth1_password(ssh_session session, const char *username, - const char *password) { - ssh_string pwd = NULL; - int rc; - - rc = send_username(session, username); - if (rc != SSH_AUTH_DENIED) { - return rc; - } - if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD) - goto pending; - /* we trick a bit here. A known flaw in SSH1 protocol is that it's - * easy to guess password sizes. - * not that sure ... - */ - - /* XXX fix me here ! */ - /* cisco IOS doesn't like when a password is followed by zeroes and random pad. */ - if(1 || strlen(password) >= 128) { - /* not risky to disclose the size of such a big password .. */ - pwd = ssh_string_from_char(password); - if (pwd == NULL) { - return SSH_AUTH_ERROR; - } - } else { - char buf[128] = {0}; - /* fill the password string from random things. the strcpy - * ensure there is at least a nul byte after the password. - * most implementation won't see the garbage at end. - * why garbage ? because nul bytes will be compressed by - * gzip and disclose password len. - */ - pwd = ssh_string_new(sizeof(buf)); - if (pwd == NULL) { - return SSH_AUTH_ERROR; - } - ssh_get_random(buf, sizeof(buf), 0); - strcpy(buf, password); - ssh_string_fill(pwd, buf, sizeof(buf)); - } - - if (buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) { - ssh_string_burn(pwd); - ssh_string_free(pwd); - - return SSH_AUTH_ERROR; - } - if (buffer_add_ssh_string(session->out_buffer, pwd) < 0) { - ssh_string_burn(pwd); - ssh_string_free(pwd); - - return SSH_AUTH_ERROR; - } - - ssh_string_burn(pwd); - ssh_string_free(pwd); - session->auth_state=SSH_AUTH_STATE_NONE; - session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD; - if (packet_send(session) == SSH_ERROR) { - return SSH_AUTH_ERROR; - } -pending: - rc = wait_auth1_status(session); - if (rc != SSH_AUTH_AGAIN) - session->pending_call_state = SSH_PENDING_CALL_NONE; - - return rc; -} - -#endif /* WITH_SSH1 */ -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/base64.c b/libssh/src/base64.c deleted file mode 100644 index 2a162d0b..00000000 --- a/libssh/src/base64.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * base64.c - support for base64 alphabet system, described in RFC1521 - * - * This file is part of the SSH Library - * - * Copyright (c) 2005-2005 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* just the dirtiest part of code i ever made */ -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/buffer.h" - -static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -/* Transformations */ -#define SET_A(n, i) do { (n) |= ((i) & 63) <<18; } while (0) -#define SET_B(n, i) do { (n) |= ((i) & 63) <<12; } while (0) -#define SET_C(n, i) do { (n) |= ((i) & 63) << 6; } while (0) -#define SET_D(n, i) do { (n) |= ((i) & 63); } while (0) - -#define GET_A(n) (unsigned char) (((n) & 0xff0000) >> 16) -#define GET_B(n) (unsigned char) (((n) & 0xff00) >> 8) -#define GET_C(n) (unsigned char) ((n) & 0xff) - -static int _base64_to_bin(unsigned char dest[3], const char *source, int num); -static int get_equals(char *string); - -/* First part: base64 to binary */ - -/** - * @internal - * - * @brief Translates a base64 string into a binary one. - * - * @returns A buffer containing the decoded string, NULL if something went - * wrong (e.g. incorrect char). - */ -ssh_buffer base64_to_bin(const char *source) { - ssh_buffer buffer = NULL; - unsigned char block[3]; - char *base64; - char *ptr; - size_t len; - int equals; - - base64 = strdup(source); - if (base64 == NULL) { - return NULL; - } - ptr = base64; - - /* Get the number of equals signs, which mirrors the padding */ - equals = get_equals(ptr); - if (equals > 2) { - SAFE_FREE(base64); - return NULL; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - SAFE_FREE(base64); - return NULL; - } - /* - * The base64 buffer often contains sensitive data. Make sure we don't leak - * sensitive data - */ - ssh_buffer_set_secure(buffer); - - len = strlen(ptr); - while (len > 4) { - if (_base64_to_bin(block, ptr, 3) < 0) { - goto error; - } - if (ssh_buffer_add_data(buffer, block, 3) < 0) { - goto error; - } - len -= 4; - ptr += 4; - } - - /* - * Depending on the number of bytes resting, there are 3 possibilities - * from the RFC. - */ - switch (len) { - /* - * (1) The final quantum of encoding input is an integral multiple of - * 24 bits. Here, the final unit of encoded output will be an integral - * multiple of 4 characters with no "=" padding - */ - case 4: - if (equals != 0) { - goto error; - } - if (_base64_to_bin(block, ptr, 3) < 0) { - goto error; - } - if (ssh_buffer_add_data(buffer, block, 3) < 0) { - goto error; - } - SAFE_FREE(base64); - - return buffer; - /* - * (2) The final quantum of encoding input is exactly 8 bits; here, the - * final unit of encoded output will be two characters followed by - * two "=" padding characters. - */ - case 2: - if (equals != 2){ - goto error; - } - - if (_base64_to_bin(block, ptr, 1) < 0) { - goto error; - } - if (ssh_buffer_add_data(buffer, block, 1) < 0) { - goto error; - } - SAFE_FREE(base64); - - return buffer; - /* - * The final quantum of encoding input is exactly 16 bits. Here, the final - * unit of encoded output will be three characters followed by one "=" - * padding character. - */ - case 3: - if (equals != 1) { - goto error; - } - if (_base64_to_bin(block, ptr, 2) < 0) { - goto error; - } - if (ssh_buffer_add_data(buffer,block,2) < 0) { - goto error; - } - SAFE_FREE(base64); - - return buffer; - default: - /* 4,3,2 are the only padding size allowed */ - goto error; - } - -error: - SAFE_FREE(base64); - ssh_buffer_free(buffer); - return NULL; -} - -#define BLOCK(letter, n) do {ptr = strchr(alphabet, source[n]); \ - if(!ptr) return -1; \ - i = ptr - alphabet; \ - SET_##letter(*block, i); \ - } while(0) - -/* Returns 0 if ok, -1 if not (ie invalid char into the stuff) */ -static int to_block4(unsigned long *block, const char *source, int num) { - char *ptr; - unsigned int i; - - *block = 0; - if (num < 1) { - return 0; - } - - BLOCK(A, 0); /* 6 bit */ - BLOCK(B,1); /* 12 bit */ - - if (num < 2) { - return 0; - } - - BLOCK(C, 2); /* 18 bit */ - - if (num < 3) { - return 0; - } - - BLOCK(D, 3); /* 24 bit */ - - return 0; -} - -/* num = numbers of final bytes to be decoded */ -static int _base64_to_bin(unsigned char dest[3], const char *source, int num) { - unsigned long block; - - if (to_block4(&block, source, num) < 0) { - return -1; - } - dest[0] = GET_A(block); - dest[1] = GET_B(block); - dest[2] = GET_C(block); - - return 0; -} - -/* Count the number of "=" signs and replace them by zeroes */ -static int get_equals(char *string) { - char *ptr = string; - int num = 0; - - while ((ptr=strchr(ptr,'=')) != NULL) { - num++; - *ptr = '\0'; - ptr++; - } - - return num; -} - -/* thanks sysk for debugging my mess :) */ -#define BITS(n) ((1 << (n)) - 1) -static void _bin_to_base64(unsigned char *dest, const unsigned char source[3], - int len) { - switch (len) { - case 1: - dest[0] = alphabet[(source[0] >> 2)]; - dest[1] = alphabet[((source[0] & BITS(2)) << 4)]; - dest[2] = '='; - dest[3] = '='; - break; - case 2: - dest[0] = alphabet[source[0] >> 2]; - dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)]; - dest[2] = alphabet[(source[1] & BITS(4)) << 2]; - dest[3] = '='; - break; - case 3: - dest[0] = alphabet[(source[0] >> 2)]; - dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)]; - dest[2] = alphabet[ (source[2] >> 6) | (source[1] & BITS(4)) << 2]; - dest[3] = alphabet[source[2] & BITS(6)]; - break; - } -} - -/** - * @internal - * - * @brief Converts binary data to a base64 string. - * - * @returns the converted string - */ -unsigned char *bin_to_base64(const unsigned char *source, int len) { - unsigned char *base64; - unsigned char *ptr; - int flen = len + (3 - (len % 3)); /* round to upper 3 multiple */ - flen = (4 * flen) / 3 + 1; - - base64 = malloc(flen); - if (base64 == NULL) { - return NULL; - } - ptr = base64; - - while(len > 0){ - _bin_to_base64(ptr, source, len > 3 ? 3 : len); - ptr += 4; - source += 3; - len -= 3; - } - ptr[0] = '\0'; - - return base64; -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/bignum.c b/libssh/src/bignum.c deleted file mode 100644 index 14b5aa54..00000000 --- a/libssh/src/bignum.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2014 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include - -#include "libssh/priv.h" -#include "libssh/bignum.h" -#include "libssh/string.h" - -ssh_string make_bignum_string(bignum num) { - ssh_string ptr = NULL; - int pad = 0; - unsigned int len = bignum_num_bytes(num); - unsigned int bits = bignum_num_bits(num); - - if (len == 0) { - return NULL; - } - - /* If the first bit is set we have a negative number */ - if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) { - pad++; - } - -#ifdef DEBUG_CRYPTO - fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad); -#endif /* DEBUG_CRYPTO */ - - ptr = ssh_string_new(len + pad); - if (ptr == NULL) { - return NULL; - } - - /* We have a negative number so we need a leading zero */ - if (pad) { - ptr->data[0] = 0; - } - -#ifdef HAVE_LIBGCRYPT - bignum_bn2bin(num, len, ptr->data + pad); -#elif HAVE_LIBCRYPTO - bignum_bn2bin(num, ptr->data + pad); -#endif - - return ptr; -} - -bignum make_string_bn(ssh_string string){ - bignum bn = NULL; - unsigned int len = ssh_string_len(string); - -#ifdef DEBUG_CRYPTO - fprintf(stderr, "Importing a %d bits, %d bytes object ...\n", - len * 8, len); -#endif /* DEBUG_CRYPTO */ - -#ifdef HAVE_LIBGCRYPT - bignum_bin2bn(string->data, len, &bn); -#elif defined HAVE_LIBCRYPTO - bn = bignum_bin2bn(string->data, len, NULL); -#endif - - return bn; -} - -/* prints the bignum on stderr */ -void ssh_print_bignum(const char *which, bignum num) { -#ifdef HAVE_LIBGCRYPT - unsigned char *hex = NULL; - bignum_bn2hex(num, &hex); -#elif defined HAVE_LIBCRYPTO - char *hex = NULL; - hex = bignum_bn2hex(num); -#endif - fprintf(stderr, "%s value: ", which); - fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex); - SAFE_FREE(hex); -} diff --git a/libssh/src/bind.c b/libssh/src/bind.c deleted file mode 100644 index b3239462..00000000 --- a/libssh/src/bind.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * bind.c : all ssh_bind functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2004-2005 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/bind.h" -#include "libssh/libssh.h" -#include "libssh/server.h" -#include "libssh/pki.h" -#include "libssh/buffer.h" -#include "libssh/socket.h" -#include "libssh/session.h" - -/** - * @addtogroup libssh_server - * - * @{ - */ - - -#ifdef _WIN32 -#include -#include -#include - -/* - * is necessary for getaddrinfo before Windows XP, but it isn't - * available on some platforms like MinGW. - */ -#ifdef HAVE_WSPIAPI_H -# include -#endif - -#define SOCKOPT_TYPE_ARG4 char - -#else /* _WIN32 */ - -#include -#include -#include -#define SOCKOPT_TYPE_ARG4 int - -#endif /* _WIN32 */ - -static socket_t bind_socket(ssh_bind sshbind, const char *hostname, - int port) { - char port_c[6]; - struct addrinfo *ai; - struct addrinfo hints; - int opt = 1; - socket_t s; - int rc; - - ZERO_STRUCT(hints); - - hints.ai_flags = AI_PASSIVE; - hints.ai_socktype = SOCK_STREAM; - - snprintf(port_c, 6, "%d", port); - rc = getaddrinfo(hostname, port_c, &hints, &ai); - if (rc != 0) { - ssh_set_error(sshbind, - SSH_FATAL, - "Resolving %s: %s", hostname, gai_strerror(rc)); - return -1; - } - - s = socket (ai->ai_family, - ai->ai_socktype, - ai->ai_protocol); - if (s == SSH_INVALID_SOCKET) { - ssh_set_error(sshbind, SSH_FATAL, "%s", strerror(errno)); - freeaddrinfo (ai); - return -1; - } - - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (char *)&opt, sizeof(opt)) < 0) { - ssh_set_error(sshbind, - SSH_FATAL, - "Setting socket options failed: %s", - strerror(errno)); - freeaddrinfo (ai); - close(s); - return -1; - } - - if (bind(s, ai->ai_addr, ai->ai_addrlen) != 0) { - ssh_set_error(sshbind, - SSH_FATAL, - "Binding to %s:%d: %s", - hostname, - port, - strerror(errno)); - freeaddrinfo (ai); - close(s); - return -1; - } - - freeaddrinfo (ai); - return s; -} - -ssh_bind ssh_bind_new(void) { - ssh_bind ptr; - - ptr = malloc(sizeof(struct ssh_bind_struct)); - if (ptr == NULL) { - return NULL; - } - ZERO_STRUCTP(ptr); - ptr->bindfd = SSH_INVALID_SOCKET; - ptr->bindport= 22; - ptr->common.log_verbosity = 0; - - return ptr; -} - -static int ssh_bind_import_keys(ssh_bind sshbind) { - int rc; - - if (sshbind->ecdsakey == NULL && - sshbind->dsakey == NULL && - sshbind->rsakey == NULL) { - ssh_set_error(sshbind, SSH_FATAL, - "ECDSA, DSA, or RSA host key file must be set"); - return SSH_ERROR; - } - -#ifdef HAVE_ECC - if (sshbind->ecdsa == NULL && sshbind->ecdsakey != NULL) { - rc = ssh_pki_import_privkey_file(sshbind->ecdsakey, - NULL, - NULL, - NULL, - &sshbind->ecdsa); - if (rc == SSH_ERROR || rc == SSH_EOF) { - ssh_set_error(sshbind, SSH_FATAL, - "Failed to import private ECDSA host key"); - return SSH_ERROR; - } - - if (ssh_key_type(sshbind->ecdsa) != SSH_KEYTYPE_ECDSA) { - ssh_set_error(sshbind, SSH_FATAL, - "The ECDSA host key has the wrong type"); - ssh_key_free(sshbind->ecdsa); - sshbind->ecdsa = NULL; - return SSH_ERROR; - } - } -#endif - - if (sshbind->dsa == NULL && sshbind->dsakey != NULL) { - rc = ssh_pki_import_privkey_file(sshbind->dsakey, - NULL, - NULL, - NULL, - &sshbind->dsa); - if (rc == SSH_ERROR || rc == SSH_EOF) { - ssh_set_error(sshbind, SSH_FATAL, - "Failed to import private DSA host key"); - return SSH_ERROR; - } - - if (ssh_key_type(sshbind->dsa) != SSH_KEYTYPE_DSS) { - ssh_set_error(sshbind, SSH_FATAL, - "The DSA host key has the wrong type: %d", - ssh_key_type(sshbind->dsa)); - ssh_key_free(sshbind->dsa); - sshbind->dsa = NULL; - return SSH_ERROR; - } - } - - if (sshbind->rsa == NULL && sshbind->rsakey != NULL) { - rc = ssh_pki_import_privkey_file(sshbind->rsakey, - NULL, - NULL, - NULL, - &sshbind->rsa); - if (rc == SSH_ERROR || rc == SSH_EOF) { - ssh_set_error(sshbind, SSH_FATAL, - "Failed to import private RSA host key"); - return SSH_ERROR; - } - - if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA && - ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA1) { - ssh_set_error(sshbind, SSH_FATAL, - "The RSA host key has the wrong type"); - ssh_key_free(sshbind->rsa); - sshbind->rsa = NULL; - return SSH_ERROR; - } - } - - return SSH_OK; -} - -int ssh_bind_listen(ssh_bind sshbind) { - const char *host; - socket_t fd; - int rc; - - if (ssh_init() < 0) { - ssh_set_error(sshbind, SSH_FATAL, "ssh_init() failed"); - return -1; - } - - rc = ssh_bind_import_keys(sshbind); - if (rc != SSH_OK) { - return SSH_ERROR; - } - - if (sshbind->bindfd == SSH_INVALID_SOCKET) { - host = sshbind->bindaddr; - if (host == NULL) { - host = "0.0.0.0"; - } - - fd = bind_socket(sshbind, host, sshbind->bindport); - if (fd == SSH_INVALID_SOCKET) { - ssh_key_free(sshbind->dsa); - sshbind->dsa = NULL; - ssh_key_free(sshbind->rsa); - sshbind->rsa = NULL; - return -1; - } - - if (listen(fd, 10) < 0) { - ssh_set_error(sshbind, SSH_FATAL, - "Listening to socket %d: %s", - fd, strerror(errno)); - close(fd); - ssh_key_free(sshbind->dsa); - sshbind->dsa = NULL; - ssh_key_free(sshbind->rsa); - sshbind->rsa = NULL; - return -1; - } - - sshbind->bindfd = fd; - } else { - SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket"); - } - return 0; -} - -int ssh_bind_set_callbacks(ssh_bind sshbind, ssh_bind_callbacks callbacks, - void *userdata){ - if (sshbind == NULL) { - return SSH_ERROR; - } - if (callbacks == NULL) { - ssh_set_error_invalid(sshbind); - return SSH_ERROR; - } - if(callbacks->size <= 0 || callbacks->size > 1024 * sizeof(void *)){ - ssh_set_error(sshbind,SSH_FATAL, - "Invalid callback passed in (badly initialized)"); - return SSH_ERROR; - } - sshbind->bind_callbacks = callbacks; - sshbind->bind_callbacks_userdata=userdata; - return 0; -} - -/** @internal - * @brief callback being called by poll when an event happens - * - */ -static int ssh_bind_poll_callback(ssh_poll_handle sshpoll, - socket_t fd, int revents, void *user){ - ssh_bind sshbind=(ssh_bind)user; - (void)sshpoll; - (void)fd; - - if(revents & POLLIN){ - /* new incoming connection */ - if(ssh_callbacks_exists(sshbind->bind_callbacks,incoming_connection)){ - sshbind->bind_callbacks->incoming_connection(sshbind, - sshbind->bind_callbacks_userdata); - } - } - return 0; -} - -/** @internal - * @brief returns the current poll handle, or create it - * @param sshbind the ssh_bind object - * @returns a ssh_poll handle suitable for operation - */ -ssh_poll_handle ssh_bind_get_poll(ssh_bind sshbind){ - if(sshbind->poll) - return sshbind->poll; - sshbind->poll=ssh_poll_new(sshbind->bindfd,POLLIN, - ssh_bind_poll_callback,sshbind); - return sshbind->poll; -} - -void ssh_bind_set_blocking(ssh_bind sshbind, int blocking) { - sshbind->blocking = blocking ? 1 : 0; -} - -socket_t ssh_bind_get_fd(ssh_bind sshbind) { - return sshbind->bindfd; -} - -void ssh_bind_set_fd(ssh_bind sshbind, socket_t fd) { - sshbind->bindfd = fd; -} - -void ssh_bind_fd_toaccept(ssh_bind sshbind) { - sshbind->toaccept = 1; -} - -void ssh_bind_free(ssh_bind sshbind){ - int i; - - if (sshbind == NULL) { - return; - } - - if (sshbind->bindfd >= 0) { -#ifdef _WIN32 - closesocket(sshbind->bindfd); -#else - close(sshbind->bindfd); -#endif - } - sshbind->bindfd = SSH_INVALID_SOCKET; - - /* options */ - SAFE_FREE(sshbind->banner); - SAFE_FREE(sshbind->bindaddr); - - SAFE_FREE(sshbind->dsakey); - SAFE_FREE(sshbind->rsakey); - SAFE_FREE(sshbind->ecdsakey); - - ssh_key_free(sshbind->dsa); - sshbind->dsa = NULL; - ssh_key_free(sshbind->rsa); - sshbind->rsa = NULL; - ssh_key_free(sshbind->ecdsa); - sshbind->ecdsa = NULL; - - for (i = 0; i < 10; i++) { - if (sshbind->wanted_methods[i]) { - SAFE_FREE(sshbind->wanted_methods[i]); - } - } - - SAFE_FREE(sshbind); -} - -int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){ - int i, rc; - - if (session == NULL){ - ssh_set_error(sshbind, SSH_FATAL,"session is null"); - return SSH_ERROR; - } - - session->server = 1; - session->version = 2; - - /* copy options */ - for (i = 0; i < 10; i++) { - if (sshbind->wanted_methods[i]) { - session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]); - if (session->opts.wanted_methods[i] == NULL) { - return SSH_ERROR; - } - } - } - - if (sshbind->bindaddr == NULL) - session->opts.bindaddr = NULL; - else { - SAFE_FREE(session->opts.bindaddr); - session->opts.bindaddr = strdup(sshbind->bindaddr); - if (session->opts.bindaddr == NULL) { - return SSH_ERROR; - } - } - - session->common.log_verbosity = sshbind->common.log_verbosity; - if(sshbind->banner != NULL) - session->opts.custombanner = strdup(sshbind->banner); - ssh_socket_free(session->socket); - session->socket = ssh_socket_new(session); - if (session->socket == NULL) { - /* perhaps it may be better to copy the error from session to sshbind */ - ssh_set_error_oom(sshbind); - return SSH_ERROR; - } - ssh_socket_set_fd(session->socket, fd); - ssh_socket_get_poll_handle_out(session->socket); - - /* We must try to import any keys that could be imported in case - * we are not using ssh_bind_listen (which is the other place - * where keys can be imported) on this ssh_bind and are instead - * only using ssh_bind_accept_fd to manage sockets ourselves. - */ - rc = ssh_bind_import_keys(sshbind); - if (rc != SSH_OK) { - return SSH_ERROR; - } - -#ifdef HAVE_ECC - if (sshbind->ecdsa) { - session->srv.ecdsa_key = ssh_key_dup(sshbind->ecdsa); - if (session->srv.ecdsa_key == NULL) { - ssh_set_error_oom(sshbind); - return SSH_ERROR; - } - } -#endif - if (sshbind->dsa) { - session->srv.dsa_key = ssh_key_dup(sshbind->dsa); - if (session->srv.dsa_key == NULL) { - ssh_set_error_oom(sshbind); - return SSH_ERROR; - } - } - if (sshbind->rsa) { - session->srv.rsa_key = ssh_key_dup(sshbind->rsa); - if (session->srv.rsa_key == NULL) { - ssh_set_error_oom(sshbind); - return SSH_ERROR; - } - } - /* force PRNG to change state in case we fork after ssh_bind_accept */ - ssh_reseed(); - return SSH_OK; -} - -int ssh_bind_accept(ssh_bind sshbind, ssh_session session) { - socket_t fd = SSH_INVALID_SOCKET; - int rc; - if (sshbind->bindfd == SSH_INVALID_SOCKET) { - ssh_set_error(sshbind, SSH_FATAL, - "Can't accept new clients on a not bound socket."); - return SSH_ERROR; - } - - if (session == NULL){ - ssh_set_error(sshbind, SSH_FATAL,"session is null"); - return SSH_ERROR; - } - - fd = accept(sshbind->bindfd, NULL, NULL); - if (fd == SSH_INVALID_SOCKET) { - ssh_set_error(sshbind, SSH_FATAL, - "Accepting a new connection: %s", - strerror(errno)); - return SSH_ERROR; - } - rc = ssh_bind_accept_fd(sshbind, session, fd); - - if(rc == SSH_ERROR){ -#ifdef _WIN32 - closesocket(fd); -#else - close(fd); -#endif - ssh_socket_free(session->socket); - } - return rc; -} - - -/** - * @} - */ diff --git a/libssh/src/buffer.c b/libssh/src/buffer.c deleted file mode 100644 index be25a32f..00000000 --- a/libssh/src/buffer.c +++ /dev/null @@ -1,996 +0,0 @@ -/* - * buffer.c - buffer functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/misc.h" -#include "libssh/bignum.h" - -/** - * @defgroup libssh_buffer The SSH buffer functions. - * @ingroup libssh - * - * Functions to handle SSH buffers. - * - * @{ - */ - - -#ifdef DEBUG_BUFFER -/** - * @internal - * - * @brief Check that preconditions and postconditions are valid. - * - * @param[in] buf The buffer to check. - */ -static void buffer_verify(ssh_buffer buf){ - int doabort=0; - if(buf->data == NULL) - return; - if(buf->used > buf->allocated){ - fprintf(stderr,"Buffer error : allocated %u, used %u\n",buf->allocated, buf->used); - doabort=1; - } - if(buf->pos > buf->used){ - fprintf(stderr,"Buffer error : position %u, used %u\n",buf->pos, buf->used); - doabort=1; - } - if(buf->pos > buf->allocated){ - fprintf(stderr,"Buffer error : position %u, allocated %u\n",buf->pos, buf->allocated); - doabort=1; - } - if(doabort) - abort(); -} - -#else -#define buffer_verify(x) -#endif - -/** - * @brief Create a new SSH buffer. - * - * @return A newly initialized SSH buffer, NULL on error. - */ -struct ssh_buffer_struct *ssh_buffer_new(void) { - struct ssh_buffer_struct *buf = malloc(sizeof(struct ssh_buffer_struct)); - - if (buf == NULL) { - return NULL; - } - memset(buf, 0, sizeof(struct ssh_buffer_struct)); - buffer_verify(buf); - return buf; -} - -/** - * @brief Deallocate a SSH buffer. - * - * \param[in] buffer The buffer to free. - */ -void ssh_buffer_free(struct ssh_buffer_struct *buffer) { - if (buffer == NULL) { - return; - } - buffer_verify(buffer); - - if (buffer->data) { - /* burn the data */ - BURN_BUFFER(buffer->data, buffer->allocated); - SAFE_FREE(buffer->data); - } - BURN_BUFFER(buffer, sizeof(struct ssh_buffer_struct)); - SAFE_FREE(buffer); -} - -/** - * @brief Sets the buffer as secure. - * - * A secure buffer will never leave cleartext data in the heap - * after being reallocated or freed. - * - * @param[in] buffer buffer to set secure. - */ -void ssh_buffer_set_secure(ssh_buffer buffer){ - buffer->secure = 1; -} - -static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) { - size_t smallest = 1; - char *new; - - buffer_verify(buffer); - - /* Find the smallest power of two which is greater or equal to needed */ - while(smallest <= needed) { - if (smallest == 0) { - return -1; - } - smallest <<= 1; - } - needed = smallest; - if (buffer->secure){ - new = malloc(needed); - if (new == NULL) { - return -1; - } - memcpy(new, buffer->data,buffer->used); - BURN_BUFFER(buffer->data, buffer->used); - SAFE_FREE(buffer->data); - } else { - new = realloc(buffer->data, needed); - if (new == NULL) { - buffer->data = NULL; - return -1; - } - } - buffer->data = new; - buffer->allocated = needed; - buffer_verify(buffer); - return 0; -} - -/** @internal - * @brief shifts a buffer to remove unused data in the beginning - * @param buffer SSH buffer - */ -static void buffer_shift(ssh_buffer buffer){ - uint32_t burn_pos = buffer->pos; - - buffer_verify(buffer); - if(buffer->pos==0) - return; - memmove(buffer->data, buffer->data + buffer->pos, buffer->used - buffer->pos); - buffer->used -= buffer->pos; - buffer->pos=0; - - if (buffer->secure){ - void *ptr = buffer->data + buffer->used; - BURN_BUFFER(ptr, burn_pos); - } - - buffer_verify(buffer); -} - -/** - * @internal - * - * @brief Reinitialize a SSH buffer. - * - * @param[in] buffer The buffer to reinitialize. - * - * @return 0 on success, < 0 on error. - */ -int ssh_buffer_reinit(struct ssh_buffer_struct *buffer) -{ - buffer_verify(buffer); - BURN_BUFFER(buffer->data, buffer->used); - buffer->used = 0; - buffer->pos = 0; - if(buffer->allocated > 127) { - if (realloc_buffer(buffer, 127) < 0) { - return -1; - } - } - buffer_verify(buffer); - return 0; -} - -/** - * @internal - * - * @brief Add data at the tail of a buffer. - * - * @param[in] buffer The buffer to add the data. - * - * @param[in] data A pointer to the data to add. - * - * @param[in] len The length of the data to add. - * - * @return 0 on success, < 0 on error. - */ -int ssh_buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len) -{ - buffer_verify(buffer); - - if (buffer->used + len < len) { - return -1; - } - - if (buffer->allocated < (buffer->used + len)) { - if(buffer->pos > 0) - buffer_shift(buffer); - if (realloc_buffer(buffer, buffer->used + len) < 0) { - return -1; - } - } - - memcpy(buffer->data+buffer->used, data, len); - buffer->used+=len; - buffer_verify(buffer); - return 0; -} - -/** - * @internal - * - * @brief Add a SSH string to the tail of a buffer. - * - * @param[in] buffer The buffer to add the string. - * - * @param[in] string The SSH String to add. - * - * @return 0 on success, < 0 on error. - */ -int buffer_add_ssh_string(struct ssh_buffer_struct *buffer, - struct ssh_string_struct *string) { - uint32_t len = 0; - - len = ssh_string_len(string); - if (ssh_buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) { - return -1; - } - - return 0; -} - -/** - * @internal - * - * @brief Add a 32 bits unsigned integer to the tail of a buffer. - * - * @param[in] buffer The buffer to add the integer. - * - * @param[in] data The 32 bits integer to add. - * - * @return 0 on success, -1 on error. - */ -int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data) -{ - int rc; - - rc = ssh_buffer_add_data(buffer, &data, sizeof(data)); - if (rc < 0) { - return -1; - } - - return 0; -} - -/** - * @internal - * - * @brief Add a 16 bits unsigned integer to the tail of a buffer. - * - * @param[in] buffer The buffer to add the integer. - * - * @param[in] data The 16 bits integer to add. - * - * @return 0 on success, -1 on error. - */ -int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data) -{ - int rc; - - rc = ssh_buffer_add_data(buffer, &data, sizeof(data)); - if (rc < 0) { - return -1; - } - - return 0; -} - -/** - * @internal - * - * @brief Add a 64 bits unsigned integer to the tail of a buffer. - * - * @param[in] buffer The buffer to add the integer. - * - * @param[in] data The 64 bits integer to add. - * - * @return 0 on success, -1 on error. - */ -int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data) -{ - int rc; - - rc = ssh_buffer_add_data(buffer, &data, sizeof(data)); - if (rc < 0) { - return -1; - } - - return 0; -} - -/** - * @internal - * - * @brief Add a 8 bits unsigned integer to the tail of a buffer. - * - * @param[in] buffer The buffer to add the integer. - * - * @param[in] data The 8 bits integer to add. - * - * @return 0 on success, -1 on error. - */ -int buffer_add_u8(struct ssh_buffer_struct *buffer,uint8_t data) -{ - int rc; - - rc = ssh_buffer_add_data(buffer, &data, sizeof(uint8_t)); - if (rc < 0) { - return -1; - } - - return 0; -} - -/** - * @internal - * - * @brief Add data at the head of a buffer. - * - * @param[in] buffer The buffer to add the data. - * - * @param[in] data The data to prepend. - * - * @param[in] len The length of data to prepend. - * - * @return 0 on success, -1 on error. - */ -int buffer_prepend_data(struct ssh_buffer_struct *buffer, const void *data, - uint32_t len) { - buffer_verify(buffer); - - if(len <= buffer->pos){ - /* It's possible to insert data between begin and pos */ - memcpy(buffer->data + (buffer->pos - len), data, len); - buffer->pos -= len; - buffer_verify(buffer); - return 0; - } - /* pos isn't high enough */ - if (buffer->used - buffer->pos + len < len) { - return -1; - } - - if (buffer->allocated < (buffer->used - buffer->pos + len)) { - if (realloc_buffer(buffer, buffer->used - buffer->pos + len) < 0) { - return -1; - } - } - memmove(buffer->data + len, buffer->data + buffer->pos, buffer->used - buffer->pos); - memcpy(buffer->data, data, len); - buffer->used += len - buffer->pos; - buffer->pos = 0; - buffer_verify(buffer); - return 0; -} - -/** - * @internal - * - * @brief Append data from a buffer to the tail of another buffer. - * - * @param[in] buffer The destination buffer. - * - * @param[in] source The source buffer to append. It doesn't take the - * position of the buffer into account. - * - * @return 0 on success, -1 on error. - */ -int buffer_add_buffer(struct ssh_buffer_struct *buffer, - struct ssh_buffer_struct *source) -{ - int rc; - - rc = ssh_buffer_add_data(buffer, - buffer_get_rest(source), - buffer_get_rest_len(source)); - if (rc < 0) { - return -1; - } - - return 0; -} - -/** - * @brief Get a pointer on the head of a buffer. - * - * @param[in] buffer The buffer to get the head pointer. - * - * @return A data pointer on the head. It doesn't take the position - * into account. - * - * @warning Don't expect data to be nul-terminated. - * - * @see buffer_get_rest() - * @see buffer_get_len() - */ -void *ssh_buffer_get_begin(struct ssh_buffer_struct *buffer){ - return buffer->data; -} - -/** - * @internal - * - * @brief Get a pointer to the head of a buffer at the current position. - * - * @param[in] buffer The buffer to get the head pointer. - * - * @return A pointer to the data from current position. - * - * @see buffer_get_rest_len() - * @see buffer_get() - */ -void *buffer_get_rest(struct ssh_buffer_struct *buffer){ - return buffer->data + buffer->pos; -} - -/** - * @brief Get the length of the buffer, not counting position. - * - * @param[in] buffer The buffer to get the length from. - * - * @return The length of the buffer. - * - * @see buffer_get() - */ -uint32_t ssh_buffer_get_len(struct ssh_buffer_struct *buffer){ - return buffer->used; -} - -/** - * @internal - * - * @brief Get the length of the buffer from the current position. - * - * @param[in] buffer The buffer to get the length from. - * - * @return The length of the buffer. - * - * @see buffer_get_rest() - */ -uint32_t buffer_get_rest_len(struct ssh_buffer_struct *buffer){ - buffer_verify(buffer); - return buffer->used - buffer->pos; -} - -/** - * @internal - * - * @brief Advance the position in the buffer. - * - * This has effect to "eat" bytes at head of the buffer. - * - * @param[in] buffer The buffer to advance the position. - * - * @param[in] len The number of bytes to eat. - * - * @return The new size of the buffer. - */ -uint32_t buffer_pass_bytes(struct ssh_buffer_struct *buffer, uint32_t len){ - buffer_verify(buffer); - - if (buffer->pos + len < len || buffer->used < buffer->pos + len) { - return 0; - } - - buffer->pos+=len; - /* if the buffer is empty after having passed the whole bytes into it, we can clean it */ - if(buffer->pos==buffer->used){ - buffer->pos=0; - buffer->used=0; - } - buffer_verify(buffer); - return len; -} - -/** - * @internal - * - * @brief Cut the end of the buffer. - * - * @param[in] buffer The buffer to cut. - * - * @param[in] len The number of bytes to remove from the tail. - * - * @return The new size of the buffer. - */ -uint32_t buffer_pass_bytes_end(struct ssh_buffer_struct *buffer, uint32_t len){ - buffer_verify(buffer); - - if (buffer->used < len) { - return 0; - } - - buffer->used-=len; - buffer_verify(buffer); - return len; -} - -/** - * @internal - * - * @brief Get the remaining data out of the buffer and adjust the read pointer. - * - * @param[in] buffer The buffer to read. - * - * @param[in] data The data buffer where to store the data. - * - * @param[in] len The length to read from the buffer. - * - * @returns 0 if there is not enough data in buffer, len otherwise. - */ -uint32_t buffer_get_data(struct ssh_buffer_struct *buffer, void *data, uint32_t len){ - /* - * Check for a integer overflow first, then check if not enough data is in - * the buffer. - */ - if (buffer->pos + len < len || buffer->pos + len > buffer->used) { - return 0; - } - memcpy(data,buffer->data+buffer->pos,len); - buffer->pos+=len; - return len; /* no yet support for partial reads (is it really needed ?? ) */ -} - -/** - * @internal - * - * @brief Get a 8 bits unsigned int out of the buffer and adjusts the read - * pointer. - * - * @param[in] buffer The buffer to read. - * - * @param[in] data A pointer to a uint8_t where to store the data. - * - * @returns 0 if there is not enough data in buffer, 1 otherwise. - */ -int buffer_get_u8(struct ssh_buffer_struct *buffer, uint8_t *data){ - return buffer_get_data(buffer,data,sizeof(uint8_t)); -} - -/** \internal - * \brief gets a 32 bits unsigned int out of the buffer. Adjusts the read pointer. - * \param buffer Buffer to read - * \param data pointer to a uint32_t where to store the data - * \returns 0 if there is not enough data in buffer - * \returns 4 otherwise. - */ -int buffer_get_u32(struct ssh_buffer_struct *buffer, uint32_t *data){ - return buffer_get_data(buffer,data,sizeof(uint32_t)); -} -/** - * @internal - * - * @brief Get a 64 bits unsigned int out of the buffer and adjusts the read - * pointer. - * - * @param[in] buffer The buffer to read. - * - * @param[in] data A pointer to a uint64_t where to store the data. - * - * @returns 0 if there is not enough data in buffer, 8 otherwise. - */ -int buffer_get_u64(struct ssh_buffer_struct *buffer, uint64_t *data){ - return buffer_get_data(buffer,data,sizeof(uint64_t)); -} - -/** - * @internal - * - * @brief Get a SSH String out of the buffer and adjusts the read pointer. - * - * @param[in] buffer The buffer to read. - * - * @returns The SSH String, NULL on error. - */ -struct ssh_string_struct *buffer_get_ssh_string(struct ssh_buffer_struct *buffer) { - uint32_t stringlen; - uint32_t hostlen; - struct ssh_string_struct *str = NULL; - - if (buffer_get_u32(buffer, &stringlen) == 0) { - return NULL; - } - hostlen = ntohl(stringlen); - /* verify if there is enough space in buffer to get it */ - if (buffer->pos + hostlen < hostlen || buffer->pos + hostlen > buffer->used) { - return NULL; /* it is indeed */ - } - str = ssh_string_new(hostlen); - if (str == NULL) { - return NULL; - } - if (buffer_get_data(buffer, ssh_string_data(str), hostlen) != hostlen) { - /* should never happen */ - SAFE_FREE(str); - return NULL; - } - - return str; -} - -/** - * @internal - * - * @brief Get a mpint out of the buffer and adjusts the read pointer. - * - * @note This function is SSH-1 only. - * - * @param[in] buffer The buffer to read. - * - * @returns The SSH String containing the mpint, NULL on error. - */ -struct ssh_string_struct *buffer_get_mpint(struct ssh_buffer_struct *buffer) { - uint16_t bits; - uint32_t len; - struct ssh_string_struct *str = NULL; - - if (buffer_get_data(buffer, &bits, sizeof(uint16_t)) != sizeof(uint16_t)) { - return NULL; - } - bits = ntohs(bits); - len = (bits + 7) / 8; - if (buffer->pos + len < len || buffer->pos + len > buffer->used) { - return NULL; - } - str = ssh_string_new(len); - if (str == NULL) { - return NULL; - } - if (buffer_get_data(buffer, ssh_string_data(str), len) != len) { - SAFE_FREE(str); - return NULL; - } - return str; -} - -/** @internal - * @brief Add multiple values in a buffer on a single function call - * @param[in] buffer The buffer to add to - * @param[in] format A format string of arguments. - * @param[in] ap A va_list of arguments. - * @returns SSH_OK on success - * SSH_ERROR on error - * @see ssh_buffer_add_format() for format list values. - */ -int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap){ - int rc = SSH_ERROR; - const char *p; - union { - uint8_t byte; - uint16_t word; - uint32_t dword; - uint64_t qword; - ssh_string string; - void *data; - } o; - char *cstring; - bignum b; - size_t len; - - for (p = format; *p != '\0'; p++) { - switch(*p) { - case 'b': - o.byte = (uint8_t)va_arg(ap, unsigned int); - rc = buffer_add_u8(buffer, o.byte); - break; - case 'w': - o.word = (uint16_t)va_arg(ap, unsigned int); - o.word = htons(o.word); - rc = buffer_add_u16(buffer, o.word); - break; - case 'd': - o.dword = va_arg(ap, uint32_t); - o.dword = htonl(o.dword); - rc = buffer_add_u32(buffer, o.dword); - break; - case 'q': - o.qword = va_arg(ap, uint64_t); - o.qword = htonll(o.qword); - rc = buffer_add_u64(buffer, o.qword); - break; - case 'S': - o.string = va_arg(ap, ssh_string); - rc = buffer_add_ssh_string(buffer, o.string); - o.string = NULL; - break; - case 's': - cstring = va_arg(ap, char *); - len = strlen(cstring); - rc = buffer_add_u32(buffer, htonl(len)); - if (rc == SSH_OK){ - rc = ssh_buffer_add_data(buffer, cstring, len); - } - cstring = NULL; - break; - case 'P': - len = va_arg(ap, size_t); - o.data = va_arg(ap, void *); - rc = ssh_buffer_add_data(buffer, o.data, len); - o.data = NULL; - break; - case 'B': - b = va_arg(ap, bignum); - o.string = make_bignum_string(b); - if(o.string == NULL){ - rc = SSH_ERROR; - break; - } - rc = buffer_add_ssh_string(buffer, o.string); - SAFE_FREE(o.string); - break; - case 't': - cstring = va_arg(ap, char *); - len = strlen(cstring); - rc = ssh_buffer_add_data(buffer, cstring, len); - cstring = NULL; - break; - default: - SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p); - rc = SSH_ERROR; - } - if (rc != SSH_OK){ - break; - } - } - - if (rc != SSH_ERROR){ - /* verify that the last hidden argument is correct */ - o.dword = va_arg(ap, uint32_t); - if (o.dword != SSH_BUFFER_PACK_END){ - rc = SSH_ERROR; - } - } - return rc; -} - -/** @internal - * @brief Add multiple values in a buffer on a single function call - * @param[in] buffer The buffer to add to - * @param[in] format A format string of arguments. This string contains single - * letters describing the order and type of arguments: - * 'b': uint8_t (pushed in network byte order) - * 'w': uint16_t (pushed in network byte order) - * 'd': uint32_t (pushed in network byte order) - * 'q': uint64_t (pushed in network byte order) - * 'S': ssh_string - * 's': char * (C string, pushed as SSH string) - * 't': char * (C string, pushed as free text) - * 'P': size_t, void * (len of data, pointer to data) - * only pushes data. - * 'B': bignum (pushed as SSH string) - * @returns SSH_OK on success - * SSH_ERROR on error - * @warning when using 'P' with a constant size (e.g. 8), do not - * forget to cast to (size_t). - */ -int _ssh_buffer_pack(struct ssh_buffer_struct *buffer, const char *format, ...){ - va_list ap; - int rc; - - va_start(ap, format); - rc = ssh_buffer_pack_va(buffer, format, ap); - va_end(ap); - return rc; -} - -/** @internal - * @brief Get multiple values from a buffer on a single function call - * @param[in] buffer The buffer to get from - * @param[in] format A format string of arguments. - * @param[in] ap A va_list of arguments. - * @returns SSH_OK on success - * SSH_ERROR on error - * @see ssh_buffer_get_format() for format list values. - */ -int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap){ - int rc = SSH_ERROR; - const char *p, *last; - union { - uint8_t *byte; - uint16_t *word; - uint32_t *dword; - uint64_t *qword; - ssh_string *string; - char **cstring; - void **data; - } o; - size_t len, rlen; - uint32_t u32len; - va_list ap_copy; - - /* copy the argument list in case a rollback is needed */ - va_copy(ap_copy, ap); - - for (p = format; *p != '\0'; p++) { - switch (*p) { - case 'b': - o.byte = va_arg(ap, uint8_t *); - rlen = buffer_get_u8(buffer, o.byte); - rc = rlen==1 ? SSH_OK : SSH_ERROR; - break; - case 'w': - o.word = va_arg(ap, uint16_t *); - rlen = buffer_get_data(buffer, o.word, sizeof(uint16_t)); - *o.word = ntohs(*o.word); - rc = rlen==2 ? SSH_OK : SSH_ERROR; - break; - case 'd': - o.dword = va_arg(ap, uint32_t *); - rlen = buffer_get_u32(buffer, o.dword); - *o.dword = ntohl(*o.dword); - rc = rlen==4 ? SSH_OK : SSH_ERROR; - break; - case 'q': - o.qword = va_arg(ap, uint64_t*); - rlen = buffer_get_u64(buffer, o.qword); - *o.qword = ntohll(*o.qword); - rc = rlen==8 ? SSH_OK : SSH_ERROR; - break; - case 'S': - o.string = va_arg(ap, ssh_string *); - *o.string = buffer_get_ssh_string(buffer); - rc = *o.string != NULL ? SSH_OK : SSH_ERROR; - o.string = NULL; - break; - case 's': - o.cstring = va_arg(ap, char **); - *o.cstring = NULL; - rc = buffer_get_u32(buffer, &u32len); - if (rc != 4){ - rc = SSH_ERROR; - break; - } - len = ntohl(u32len); - if (len > UINT_MAX - 1){ - rc = SSH_ERROR; - break; - } - *o.cstring = malloc(len + 1); - if (*o.cstring == NULL){ - rc = SSH_ERROR; - break; - } - rlen = buffer_get_data(buffer, *o.cstring, len); - if (rlen != len){ - SAFE_FREE(*o.cstring); - rc = SSH_ERROR; - break; - } - (*o.cstring)[len] = '\0'; - o.cstring = NULL; - rc = SSH_OK; - break; - case 'P': - len = va_arg(ap, size_t); - o.data = va_arg(ap, void **); - *o.data = malloc(len); - if(*o.data == NULL){ - rc = SSH_ERROR; - break; - } - rlen = buffer_get_data(buffer, *o.data, len); - if (rlen != len){ - SAFE_FREE(*o.data); - rc = SSH_ERROR; - break; - } - o.data = NULL; - rc = SSH_OK; - break; - default: - SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p); - rc = SSH_ERROR; - } - if (rc != SSH_OK) { - break; - } - } - if (rc != SSH_ERROR){ - /* verify that the last hidden argument is correct */ - uint32_t canary = va_arg(ap, uint32_t); - if (canary != SSH_BUFFER_PACK_END){ - rc = SSH_ERROR; - } - } - if (rc != SSH_OK){ - /* Reset the format string and erase everything that was allocated */ - last = p; - for(p=format;p - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include "libssh/callbacks.h" -#include "libssh/session.h" - - -/* LEGACY */ -static void ssh_legacy_log_callback(int priority, - const char *function, - const char *buffer, - void *userdata) -{ - ssh_session session = (ssh_session)userdata; - ssh_log_callback log_fn = session->common.callbacks->log_function; - void *log_data = session->common.callbacks->userdata; - - (void)function; /* unused */ - - log_fn(session, priority, buffer, log_data); -} - -int ssh_set_callbacks(ssh_session session, ssh_callbacks cb) { - if (session == NULL || cb == NULL) { - return SSH_ERROR; - } - - if(cb->size <= 0 || cb->size > 1024 * sizeof(void *)){ - ssh_set_error(session,SSH_FATAL, - "Invalid callback passed in (badly initialized)"); - - return SSH_ERROR; - } - session->common.callbacks = cb; - - /* LEGACY */ - if (ssh_get_log_callback() == NULL && cb->log_function) { - ssh_set_log_callback(ssh_legacy_log_callback); - ssh_set_log_userdata(session); - } - - return 0; -} - -int ssh_set_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb) { - ssh_session session = NULL; - if (channel == NULL || cb == NULL) { - return SSH_ERROR; - } - session = channel->session; - - if(cb->size <= 0 || cb->size > 1024 * sizeof(void *)){ - ssh_set_error(session,SSH_FATAL, - "Invalid channel callback passed in (badly initialized)"); - - return SSH_ERROR; - } - channel->callbacks = cb; - - return 0; -} - -int ssh_set_server_callbacks(ssh_session session, ssh_server_callbacks cb){ - if (session == NULL || cb == NULL) { - return SSH_ERROR; - } - - if(cb->size <= 0 || cb->size > 1024 * sizeof(void *)){ - ssh_set_error(session,SSH_FATAL, - "Invalid callback passed in (badly initialized)"); - - return SSH_ERROR; - } - session->server_callbacks = cb; - - return 0; -} diff --git a/libssh/src/channels.c b/libssh/src/channels.c deleted file mode 100644 index 7a4e71fe..00000000 --- a/libssh/src/channels.c +++ /dev/null @@ -1,3418 +0,0 @@ -/* - * channels.c - SSH channel functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * Copyright (c) 2009-2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/ssh2.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/socket.h" -#include "libssh/channels.h" -#include "libssh/session.h" -#include "libssh/misc.h" -#include "libssh/messages.h" -#if WITH_SERVER -#include "libssh/server.h" -#endif - -#define WINDOWBASE 1280000 -#define WINDOWLIMIT (WINDOWBASE/2) - -/* - * All implementations MUST be able to process packets with an - * uncompressed payload length of 32768 bytes or less and a total packet - * size of 35000 bytes or less. - */ -#define CHANNEL_MAX_PACKET 32768 -#define CHANNEL_INITIAL_WINDOW 64000 - -/** - * @defgroup libssh_channel The SSH channel functions - * @ingroup libssh - * - * Functions that manage a SSH channel. - * - * @{ - */ - -static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet); - -/** - * @brief Allocate a new channel. - * - * @param[in] session The ssh session to use. - * - * @return A pointer to a newly allocated channel, NULL on error. - */ -ssh_channel ssh_channel_new(ssh_session session) { - ssh_channel channel = NULL; - - if(session == NULL) { - return NULL; - } - - channel = malloc(sizeof(struct ssh_channel_struct)); - if (channel == NULL) { - ssh_set_error_oom(session); - return NULL; - } - memset(channel,0,sizeof(struct ssh_channel_struct)); - - channel->stdout_buffer = ssh_buffer_new(); - if (channel->stdout_buffer == NULL) { - ssh_set_error_oom(session); - SAFE_FREE(channel); - return NULL; - } - - channel->stderr_buffer = ssh_buffer_new(); - if (channel->stderr_buffer == NULL) { - ssh_set_error_oom(session); - ssh_buffer_free(channel->stdout_buffer); - SAFE_FREE(channel); - return NULL; - } - - channel->session = session; - channel->version = session->version; - channel->exit_status = -1; - channel->flags = SSH_CHANNEL_FLAG_NOT_BOUND; - - if(session->channels == NULL) { - session->channels = ssh_list_new(); - } - ssh_list_prepend(session->channels, channel); - return channel; -} - -/** - * @internal - * - * @brief Create a new channel identifier. - * - * @param[in] session The SSH session to use. - * - * @return The new channel identifier. - */ -uint32_t ssh_channel_new_id(ssh_session session) { - return ++(session->maxchannel); -} - -/** - * @internal - * - * @brief Handle a SSH_PACKET_CHANNEL_OPEN_CONFIRMATION packet. - * - * Constructs the channel object. - */ -SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){ - uint32_t channelid=0; - ssh_channel channel; - int rc; - (void)type; - (void)user; - - SSH_LOG(SSH_LOG_PACKET,"Received SSH2_MSG_CHANNEL_OPEN_CONFIRMATION"); - - rc = ssh_buffer_unpack(packet, "d", &channelid); - if (rc != SSH_OK) - goto error; - channel=ssh_channel_from_local(session,channelid); - if(channel==NULL){ - ssh_set_error(session, SSH_FATAL, - "Unknown channel id %lu", - (long unsigned int) channelid); - /* TODO: Set error marking in channel object */ - - return SSH_PACKET_USED; - } - - rc = ssh_buffer_unpack(packet, "ddd", - &channel->remote_channel, - &channel->remote_window, - &channel->remote_maxpacket); - if (rc != SSH_OK) - goto error; - - SSH_LOG(SSH_LOG_PROTOCOL, - "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d", - channel->local_channel, - channel->remote_channel); - SSH_LOG(SSH_LOG_PROTOCOL, - "Remote window : %lu, maxpacket : %lu", - (long unsigned int) channel->remote_window, - (long unsigned int) channel->remote_maxpacket); - - channel->state = SSH_CHANNEL_STATE_OPEN; - channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND; - return SSH_PACKET_USED; - -error: - ssh_set_error(session, SSH_FATAL, "Invalid packet"); - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handle a SSH_CHANNEL_OPEN_FAILURE and set the state of the channel. - */ -SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){ - - ssh_channel channel; - char *error = NULL; - uint32_t code; - int rc; - (void)user; - (void)type; - - channel=channel_from_msg(session,packet); - if(channel==NULL){ - SSH_LOG(SSH_LOG_RARE,"Invalid channel in packet"); - return SSH_PACKET_USED; - } - - rc = ssh_buffer_unpack(packet, "ds", &code, &error); - if (rc != SSH_OK){ - ssh_set_error(session, SSH_FATAL, "Invalid packet"); - return SSH_PACKET_USED; - } - - ssh_set_error(session, SSH_REQUEST_DENIED, - "Channel opening failure: channel %u error (%lu) %s", - channel->local_channel, - (long unsigned int) code, - error); - SAFE_FREE(error); - channel->state=SSH_CHANNEL_STATE_OPEN_DENIED; - return SSH_PACKET_USED; -} - -static int ssh_channel_open_termination(void *c){ - ssh_channel channel = (ssh_channel) c; - if (channel->state != SSH_CHANNEL_STATE_OPENING || - channel->session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - else - return 0; -} - -/** - * @internal - * - * @brief Open a channel by sending a SSH_OPEN_CHANNEL message and - * wait for the reply. - * - * @param[in] channel The current channel. - * - * @param[in] type A C string describing the kind of channel (e.g. "exec"). - * - * @param[in] window The receiving window of the channel. The window is the - * maximum size of data that can stay in buffers and - * network. - * - * @param[in] maxpacket The maximum packet size allowed (like MTU). - * - * @param[in] payload The buffer containing additional payload for the query. - */ -static int channel_open(ssh_channel channel, const char *type, int window, - int maxpacket, ssh_buffer payload) { - ssh_session session = channel->session; - int err=SSH_ERROR; - int rc; - - switch(channel->state){ - case SSH_CHANNEL_STATE_NOT_OPEN: - break; - case SSH_CHANNEL_STATE_OPENING: - goto pending; - case SSH_CHANNEL_STATE_OPEN: - case SSH_CHANNEL_STATE_CLOSED: - case SSH_CHANNEL_STATE_OPEN_DENIED: - goto end; - default: - ssh_set_error(session,SSH_FATAL,"Bad state in channel_open: %d",channel->state); - } - channel->local_channel = ssh_channel_new_id(session); - channel->local_maxpacket = maxpacket; - channel->local_window = window; - - SSH_LOG(SSH_LOG_PROTOCOL, - "Creating a channel %d with %d window and %d max packet", - channel->local_channel, window, maxpacket); - - rc = ssh_buffer_pack(session->out_buffer, - "bsddd", - SSH2_MSG_CHANNEL_OPEN, - type, - channel->local_channel, - channel->local_window, - channel->local_maxpacket); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - return err; - } - - if (payload != NULL) { - if (buffer_add_buffer(session->out_buffer, payload) < 0) { - ssh_set_error_oom(session); - - return err; - } - } - channel->state = SSH_CHANNEL_STATE_OPENING; - if (packet_send(session) == SSH_ERROR) { - - return err; - } - - SSH_LOG(SSH_LOG_PACKET, - "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d", - type, channel->local_channel); -pending: - /* wait until channel is opened by server */ - err = ssh_handle_packets_termination(session, - SSH_TIMEOUT_DEFAULT, - ssh_channel_open_termination, - channel); - - if (session->session_state == SSH_SESSION_STATE_ERROR) - err = SSH_ERROR; -end: - if(channel->state == SSH_CHANNEL_STATE_OPEN) - err=SSH_OK; - - return err; -} - -/* return channel with corresponding local id, or NULL if not found */ -ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) { - struct ssh_iterator *it; - ssh_channel channel; - - for (it = ssh_list_get_iterator(session->channels); it != NULL ; it=it->next) { - channel = ssh_iterator_value(ssh_channel, it); - if (channel == NULL) { - continue; - } - if (channel->local_channel == id) { - return channel; - } - } - - return NULL; -} - -/** - * @internal - * @brief grows the local window and send a packet to the other party - * @param session SSH session - * @param channel SSH channel - * @param minimumsize The minimum acceptable size for the new window. - */ -static int grow_window(ssh_session session, ssh_channel channel, int minimumsize) { - uint32_t new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE; - int rc; - -#ifdef WITH_SSH1 - if (session->version == 1){ - channel->remote_window = new_window; - - return SSH_OK; - } -#endif - if(new_window <= channel->local_window){ - SSH_LOG(SSH_LOG_PROTOCOL, - "growing window (channel %d:%d) to %d bytes : not needed (%d bytes)", - channel->local_channel, channel->remote_channel, new_window, - channel->local_window); - - return SSH_OK; - } - /* WINDOW_ADJUST packet needs a relative increment rather than an absolute - * value, so we give here the missing bytes needed to reach new_window - */ - rc = ssh_buffer_pack(session->out_buffer, - "bdd", - SSH2_MSG_CHANNEL_WINDOW_ADJUST, - channel->remote_channel, - new_window - channel->local_window); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - if (packet_send(session) == SSH_ERROR) { - goto error; - } - - SSH_LOG(SSH_LOG_PROTOCOL, - "growing window (channel %d:%d) to %d bytes", - channel->local_channel, - channel->remote_channel, - new_window); - - channel->local_window = new_window; - - return SSH_OK; -error: - ssh_buffer_reinit(session->out_buffer); - - return SSH_ERROR; -} - -/** - * @internal - * - * @brief Parse a channel-related packet to resolve it to a ssh_channel. - * - * This works on SSH1 sessions too. - * - * @param[in] session The current SSH session. - * - * @param[in] packet The buffer to parse packet from. The read pointer will - * be moved after the call. - * - * @returns The related ssh_channel, or NULL if the channel is - * unknown or the packet is invalid. - */ -static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) { - ssh_channel channel; - uint32_t chan; - int rc; -#ifdef WITH_SSH1 - /* With SSH1, the channel is always the first one */ - if(session->version==1) - return ssh_get_channel1(session); -#endif - rc = ssh_buffer_unpack(packet,"d",&chan); - if (rc != SSH_OK) { - ssh_set_error(session, SSH_FATAL, - "Getting channel from message: short read"); - return NULL; - } - - channel = ssh_channel_from_local(session, chan); - if (channel == NULL) { - ssh_set_error(session, SSH_FATAL, - "Server specified invalid channel %lu", - (long unsigned int) chan); - } - - return channel; -} - -SSH_PACKET_CALLBACK(channel_rcv_change_window) { - ssh_channel channel; - uint32_t bytes; - int rc; - (void)user; - (void)type; - - channel = channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); - } - - rc = ssh_buffer_unpack(packet, "d", &bytes); - if (channel == NULL || rc != SSH_OK) { - SSH_LOG(SSH_LOG_PACKET, - "Error getting a window adjust message: invalid packet"); - - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PROTOCOL, - "Adding %d bytes to channel (%d:%d) (from %d bytes)", - bytes, - channel->local_channel, - channel->remote_channel, - channel->remote_window); - - channel->remote_window += bytes; - - return SSH_PACKET_USED; -} - -/* is_stderr is set to 1 if the data are extended, ie stderr */ -SSH_PACKET_CALLBACK(channel_rcv_data){ - ssh_channel channel; - ssh_string str; - ssh_buffer buf; - size_t len; - int is_stderr; - int rest; - (void)user; - - if(type==SSH2_MSG_CHANNEL_DATA) - is_stderr=0; - else - is_stderr=1; - - channel = channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, - "%s", ssh_get_error(session)); - - return SSH_PACKET_USED; - } - - if (is_stderr) { - uint32_t ignore; - /* uint32 data type code. we can ignore it */ - buffer_get_u32(packet, &ignore); - } - - str = buffer_get_ssh_string(packet); - if (str == NULL) { - SSH_LOG(SSH_LOG_PACKET, "Invalid data packet!"); - - return SSH_PACKET_USED; - } - len = ssh_string_len(str); - - SSH_LOG(SSH_LOG_PACKET, - "Channel receiving %" PRIdS " bytes data in %d (local win=%d remote win=%d)", - len, - is_stderr, - channel->local_window, - channel->remote_window); - - /* What shall we do in this case? Let's accept it anyway */ - if (len > channel->local_window) { - SSH_LOG(SSH_LOG_RARE, - "Data packet too big for our window(%" PRIdS " vs %d)", - len, - channel->local_window); - } - - if (channel_default_bufferize(channel, ssh_string_data(str), len, - is_stderr) < 0) { - ssh_string_free(str); - - return SSH_PACKET_USED; - } - - if (len <= channel->local_window) { - channel->local_window -= len; - } else { - channel->local_window = 0; /* buggy remote */ - } - - SSH_LOG(SSH_LOG_PACKET, - "Channel windows are now (local win=%d remote win=%d)", - channel->local_window, - channel->remote_window); - - ssh_string_free(str); - - if(ssh_callbacks_exists(channel->callbacks, channel_data_function)) { - if(is_stderr) { - buf = channel->stderr_buffer; - } else { - buf = channel->stdout_buffer; - } - rest = channel->callbacks->channel_data_function(channel->session, - channel, - buffer_get_rest(buf), - buffer_get_rest_len(buf), - is_stderr, - channel->callbacks->userdata); - if(rest > 0) { - if (channel->counter != NULL) { - channel->counter->in_bytes += rest; - } - buffer_pass_bytes(buf, rest); - } - if (channel->local_window + buffer_get_rest_len(buf) < WINDOWLIMIT) { - if (grow_window(session, channel, 0) < 0) { - return -1; - } - } - } - - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(channel_rcv_eof) { - ssh_channel channel; - (void)user; - (void)type; - - channel = channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); - - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PACKET, - "Received eof on channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - /* channel->remote_window = 0; */ - channel->remote_eof = 1; - - if(ssh_callbacks_exists(channel->callbacks, channel_eof_function)) { - channel->callbacks->channel_eof_function(channel->session, - channel, - channel->callbacks->userdata); - } - - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(channel_rcv_close) { - ssh_channel channel; - (void)user; - (void)type; - - channel = channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); - - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PACKET, - "Received close on channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - - if ((channel->stdout_buffer && - buffer_get_rest_len(channel->stdout_buffer) > 0) || - (channel->stderr_buffer && - buffer_get_rest_len(channel->stderr_buffer) > 0)) { - channel->delayed_close = 1; - } else { - channel->state = SSH_CHANNEL_STATE_CLOSED; - } - if (channel->remote_eof == 0) { - SSH_LOG(SSH_LOG_PACKET, - "Remote host not polite enough to send an eof before close"); - } - channel->remote_eof = 1; - /* - * The remote eof doesn't break things if there was still data into read - * buffer because the eof is ignored until the buffer is empty. - */ - - if(ssh_callbacks_exists(channel->callbacks, channel_close_function)) { - channel->callbacks->channel_close_function(channel->session, - channel, - channel->callbacks->userdata); - } - channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE; - if(channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL) - ssh_channel_do_free(channel); - - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(channel_rcv_request) { - ssh_channel channel; - char *request=NULL; - uint8_t status; - int rc; - (void)user; - (void)type; - - channel = channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS,"%s", ssh_get_error(session)); - return SSH_PACKET_USED; - } - - rc = ssh_buffer_unpack(packet, "sb", - &request, - &status); - if (rc != SSH_OK) { - SSH_LOG(SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); - return SSH_PACKET_USED; - } - - if (strcmp(request,"exit-status") == 0) { - uint32_t exit_status = 0; - - SAFE_FREE(request); - rc = ssh_buffer_unpack(packet, "d", &exit_status); - SSH_LOG(SSH_LOG_PACKET, "received exit-status %d", channel->exit_status); - - if(ssh_callbacks_exists(channel->callbacks, channel_exit_status_function)) { - channel->callbacks->channel_exit_status_function(channel->session, - channel, - channel->exit_status, - channel->callbacks->userdata); - } - - return SSH_PACKET_USED; - } - - if (strcmp(request,"signal") == 0) { - char *sig = NULL; - - SAFE_FREE(request); - SSH_LOG(SSH_LOG_PACKET, "received signal"); - - rc = ssh_buffer_unpack(packet, "s", &sig); - if (rc != SSH_OK) { - SSH_LOG(SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PACKET, - "Remote connection sent a signal SIG %s", sig); - if(ssh_callbacks_exists(channel->callbacks, channel_signal_function)) { - channel->callbacks->channel_signal_function(channel->session, - channel, - sig, - channel->callbacks->userdata); - } - SAFE_FREE(sig); - - return SSH_PACKET_USED; - } - - if (strcmp(request, "exit-signal") == 0) { - const char *core = "(core dumped)"; - char *sig = NULL; - char *errmsg = NULL; - char *lang = NULL; - uint8_t core_dumped; - - SAFE_FREE(request); - - rc = ssh_buffer_unpack(packet, "sbs", - &sig, /* signal name */ - &core_dumped, /* core dumped */ - &errmsg, /* error message */ - &lang); - if (rc != SSH_OK) { - SSH_LOG(SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); - return SSH_PACKET_USED; - } - - if (core_dumped == 0) { - core = ""; - } - - SSH_LOG(SSH_LOG_PACKET, - "Remote connection closed by signal SIG %s %s", sig, core); - if(ssh_callbacks_exists(channel->callbacks, channel_exit_signal_function)) { - channel->callbacks->channel_exit_signal_function(channel->session, - channel, - sig, core_dumped, errmsg, lang, - channel->callbacks->userdata); - } - - SAFE_FREE(lang); - SAFE_FREE(errmsg); - SAFE_FREE(sig); - - return SSH_PACKET_USED; - } - if(strcmp(request,"keepalive@openssh.com")==0){ - SAFE_FREE(request); - SSH_LOG(SSH_LOG_PROTOCOL,"Responding to Openssh's keepalive"); - - rc = ssh_buffer_pack(session->out_buffer, - "bd", - SSH2_MSG_CHANNEL_FAILURE, - channel->remote_channel); - if (rc != SSH_OK) { - return SSH_PACKET_USED; - } - packet_send(session); - - return SSH_PACKET_USED; - } - - if (strcmp(request, "auth-agent-req@openssh.com") == 0) { - SAFE_FREE(request); - SSH_LOG(SSH_LOG_PROTOCOL, "Received an auth-agent-req request"); - if(ssh_callbacks_exists(channel->callbacks, channel_auth_agent_req_function)) { - channel->callbacks->channel_auth_agent_req_function(channel->session, channel, - channel->callbacks->userdata); - } - - return SSH_PACKET_USED; - } -#ifdef WITH_SERVER - /* If we are here, that means we have a request that is not in the understood - * client requests. That means we need to create a ssh message to be passed - * to the user code handling ssh messages - */ - ssh_message_handle_channel_request(session,channel,packet,request,status); -#else - SSH_LOG(SSH_LOG_WARNING, "Unhandled channel request %s", request); -#endif - - SAFE_FREE(request); - - return SSH_PACKET_USED; -} - -/* - * When data has been received from the ssh server, it can be applied to the - * known user function, with help of the callback, or inserted here - * - * FIXME is the window changed? - */ -int channel_default_bufferize(ssh_channel channel, void *data, int len, - int is_stderr) { - ssh_session session; - - if(channel == NULL) { - return -1; - } - - session = channel->session; - - if(data == NULL) { - ssh_set_error_invalid(session); - return -1; - } - - SSH_LOG(SSH_LOG_PACKET, - "placing %d bytes into channel buffer (stderr=%d)", len, is_stderr); - if (is_stderr == 0) { - /* stdout */ - if (channel->stdout_buffer == NULL) { - channel->stdout_buffer = ssh_buffer_new(); - if (channel->stdout_buffer == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - - if (ssh_buffer_add_data(channel->stdout_buffer, data, len) < 0) { - ssh_set_error_oom(session); - ssh_buffer_free(channel->stdout_buffer); - channel->stdout_buffer = NULL; - return -1; - } - } else { - /* stderr */ - if (channel->stderr_buffer == NULL) { - channel->stderr_buffer = ssh_buffer_new(); - if (channel->stderr_buffer == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - - if (ssh_buffer_add_data(channel->stderr_buffer, data, len) < 0) { - ssh_set_error_oom(session); - ssh_buffer_free(channel->stderr_buffer); - channel->stderr_buffer = NULL; - return -1; - } - } - - return 0; -} - -/** - * @brief Open a session channel (suited for a shell, not TCP forwarding). - * - * @param[in] channel An allocated channel. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * @see ssh_channel_open_forward() - * @see ssh_channel_request_env() - * @see ssh_channel_request_shell() - * @see ssh_channel_request_exec() - */ -int ssh_channel_open_session(ssh_channel channel) { - if(channel == NULL) { - return SSH_ERROR; - } - -#ifdef WITH_SSH1 - if (channel->session->version == 1) { - return channel_open_session1(channel); - } -#endif - - return channel_open(channel, - "session", - CHANNEL_INITIAL_WINDOW, - CHANNEL_MAX_PACKET, - NULL); -} - -/** - * @brief Open an agent authentication forwarding channel. This type of channel - * can be opened by a server towards a client in order to provide SSH-Agent services - * to the server-side process. This channel can only be opened if the client - * claimed support by sending a channel request beforehand. - * - * @param[in] channel An allocated channel. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * @see ssh_channel_open_forward() - */ -int ssh_channel_open_auth_agent(ssh_channel channel){ - if(channel == NULL) { - return SSH_ERROR; - } - -#ifdef WITH_SSH1 - if (channel->session->version == 1) { - return SSH_ERROR; - } -#endif - - return channel_open(channel, - "auth-agent@openssh.com", - CHANNEL_INITIAL_WINDOW, - CHANNEL_MAX_PACKET, - NULL); -} - - -/** - * @brief Open a TCP/IP forwarding channel. - * - * @param[in] channel An allocated channel. - * - * @param[in] remotehost The remote host to connected (host name or IP). - * - * @param[in] remoteport The remote port. - * - * @param[in] sourcehost The numeric IP address of the machine from where the - * connection request originates. This is mostly for - * logging purposes. - * - * @param[in] localport The port on the host from where the connection - * originated. This is mostly for logging purposes. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * @warning This function does not bind the local port and does not automatically - * forward the content of a socket to the channel. You still have to - * use channel_read and channel_write for this. - */ -int ssh_channel_open_forward(ssh_channel channel, const char *remotehost, - int remoteport, const char *sourcehost, int localport) { - ssh_session session; - ssh_buffer payload = NULL; - ssh_string str = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return rc; - } - - session = channel->session; - - if(remotehost == NULL || sourcehost == NULL) { - ssh_set_error_invalid(session); - return rc; - } - - payload = ssh_buffer_new(); - if (payload == NULL) { - ssh_set_error_oom(session); - goto error; - } - - rc = ssh_buffer_pack(payload, - "sdsd", - remotehost, - remoteport, - sourcehost, - localport); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - rc = channel_open(channel, - "direct-tcpip", - CHANNEL_INITIAL_WINDOW, - CHANNEL_MAX_PACKET, - payload); - -error: - ssh_buffer_free(payload); - ssh_string_free(str); - - return rc; -} - - -/** - * @brief Close and free a channel. - * - * @param[in] channel The channel to free. - * - * @warning Any data unread on this channel will be lost. - */ -void ssh_channel_free(ssh_channel channel) { - ssh_session session; - - if (channel == NULL) { - return; - } - - session = channel->session; - if (session->alive && channel->state == SSH_CHANNEL_STATE_OPEN) { - ssh_channel_close(channel); - } - channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL; - - /* The idea behind the flags is the following : it is well possible - * that a client closes a channel that stills exists on the server side. - * We definitively close the channel when we receive a close message *and* - * the user closed it. - */ - if((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) - || (channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)){ - ssh_channel_do_free(channel); - } -} - -/** - * @internal - * @brief Effectively free a channel, without caring about flags - */ - -void ssh_channel_do_free(ssh_channel channel){ - struct ssh_iterator *it; - ssh_session session = channel->session; - it = ssh_list_find(session->channels, channel); - if(it != NULL){ - ssh_list_remove(session->channels, it); - } - ssh_buffer_free(channel->stdout_buffer); - ssh_buffer_free(channel->stderr_buffer); - - /* debug trick to catch use after frees */ - memset(channel, 'X', sizeof(struct ssh_channel_struct)); - SAFE_FREE(channel); -} - -/** - * @brief Send an end of file on the channel. - * - * This doesn't close the channel. You may still read from it but not write. - * - * @param[in] channel The channel to send the eof to. - * - * @return SSH_OK on success, SSH_ERROR if an error occurred. - * - * Example: -@code - rc = ssh_channel_send_eof(channel); - if (rc == SSH_ERROR) { - return -1; - } - while(!ssh_channel_is_eof(channel)) { - rc = ssh_channel_read(channel, buf, sizeof(buf), 0); - if (rc == SSH_ERROR) { - return -1; - } - } - ssh_channel_close(channel); -@endcode - * - * @see ssh_channel_close() - * @see ssh_channel_free() - * @see ssh_channel_is_eof() - */ -int ssh_channel_send_eof(ssh_channel channel){ - ssh_session session; - int rc = SSH_ERROR; - int err; - - if(channel == NULL) { - return rc; - } - - session = channel->session; - - err = ssh_buffer_pack(session->out_buffer, - "bd", - SSH2_MSG_CHANNEL_EOF, - channel->remote_channel); - if (err != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - rc = packet_send(session); - SSH_LOG(SSH_LOG_PACKET, - "Sent a EOF on client channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - - rc = ssh_channel_flush(channel); - if(rc == SSH_ERROR) - goto error; - - channel->local_eof = 1; - - return rc; -error: - ssh_buffer_reinit(session->out_buffer); - - return rc; -} - -/** - * @brief Close a channel. - * - * This sends an end of file and then closes the channel. You won't be able - * to recover any data the server was going to send or was in buffers. - * - * @param[in] channel The channel to close. - * - * @return SSH_OK on success, SSH_ERROR if an error occurred. - * - * @see ssh_channel_free() - * @see ssh_channel_is_eof() - */ -int ssh_channel_close(ssh_channel channel){ - ssh_session session; - int rc = 0; - - if(channel == NULL) { - return SSH_ERROR; - } - - session = channel->session; - - if (channel->local_eof == 0) { - rc = ssh_channel_send_eof(channel); - } - - if (rc != SSH_OK) { - return rc; - } - - rc = ssh_buffer_pack(session->out_buffer, - "bd", - SSH2_MSG_CHANNEL_CLOSE, - channel->remote_channel); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - rc = packet_send(session); - SSH_LOG(SSH_LOG_PACKET, - "Sent a close on client channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - - if(rc == SSH_OK) { - channel->state=SSH_CHANNEL_STATE_CLOSED; - } - - rc = ssh_channel_flush(channel); - if(rc == SSH_ERROR) - goto error; - - return rc; -error: - ssh_buffer_reinit(session->out_buffer); - - return rc; -} - -/* this termination function waits for a window growing condition */ -static int ssh_channel_waitwindow_termination(void *c){ - ssh_channel channel = (ssh_channel) c; - if (channel->remote_window > 0 || - channel->session->session_state == SSH_SESSION_STATE_ERROR || - channel->state == SSH_CHANNEL_STATE_CLOSED) - return 1; - else - return 0; -} - -/* This termination function waits until the session is not in blocked status - * anymore, e.g. because of a key re-exchange. - */ -static int ssh_waitsession_unblocked(void *s){ - ssh_session session = (ssh_session)s; - switch (session->session_state){ - case SSH_SESSION_STATE_DH: - case SSH_SESSION_STATE_INITIAL_KEX: - case SSH_SESSION_STATE_KEXINIT_RECEIVED: - return 0; - default: - return 1; - } -} -/** - * @internal - * @brief Flushes a channel (and its session) until the output buffer - * is empty, or timeout elapsed. - * @param channel SSH channel - * @returns SSH_OK On success, - * SSH_ERROR on error - * SSH_AGAIN Timeout elapsed (or in nonblocking mode) - */ -int ssh_channel_flush(ssh_channel channel){ - return ssh_blocking_flush(channel->session, SSH_TIMEOUT_DEFAULT); -} - -static int channel_write_common(ssh_channel channel, - const void *data, - uint32_t len, int is_stderr) -{ - ssh_session session; - uint32_t origlen = len; - size_t effectivelen; - size_t maxpacketlen; - int rc; - - if(channel == NULL) { - return -1; - } - session = channel->session; - if(data == NULL) { - ssh_set_error_invalid(session); - return -1; - } - - if (len > INT_MAX) { - SSH_LOG(SSH_LOG_PROTOCOL, - "Length (%u) is bigger than INT_MAX", len); - return SSH_ERROR; - } - - /* - * Handle the max packet len from remote side, be nice - * 10 bytes for the headers - */ - maxpacketlen = channel->remote_maxpacket - 10; - - if (channel->local_eof) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Can't write to channel %d:%d after EOF was sent", - channel->local_channel, - channel->remote_channel); - return -1; - } - - if (channel->state != SSH_CHANNEL_STATE_OPEN || channel->delayed_close != 0) { - ssh_set_error(session, SSH_REQUEST_DENIED, "Remote channel is closed"); - - return -1; - } - - if (channel->session->session_state == SSH_SESSION_STATE_ERROR) { - return SSH_ERROR; - } -#ifdef WITH_SSH1 - if (channel->version == 1) { - rc = channel_write1(channel, data, len); - - return rc; - } -#endif - if (ssh_waitsession_unblocked(session) == 0){ - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT, - ssh_waitsession_unblocked, session); - if (rc == SSH_ERROR || !ssh_waitsession_unblocked(session)) - goto out; - } - while (len > 0) { - if (channel->remote_window < len) { - SSH_LOG(SSH_LOG_PROTOCOL, - "Remote window is %d bytes. going to write %d bytes", - channel->remote_window, - len); - /* What happens when the channel window is zero? */ - if(channel->remote_window == 0) { - /* nothing can be written */ - SSH_LOG(SSH_LOG_PROTOCOL, - "Wait for a growing window message..."); - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT, - ssh_channel_waitwindow_termination,channel); - if (rc == SSH_ERROR || - !ssh_channel_waitwindow_termination(channel) || - channel->session->session_state == SSH_SESSION_STATE_ERROR || - channel->state == SSH_CHANNEL_STATE_CLOSED) - goto out; - continue; - } - effectivelen = MIN(len, channel->remote_window); - } else { - effectivelen = len; - } - - effectivelen = MIN(effectivelen, maxpacketlen);; - - rc = ssh_buffer_pack(session->out_buffer, - "bd", - is_stderr ? SSH2_MSG_CHANNEL_EXTENDED_DATA : SSH2_MSG_CHANNEL_DATA, - channel->remote_channel); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - /* stderr message has an extra field */ - if (is_stderr) { - rc = ssh_buffer_pack(session->out_buffer, - "d", - SSH2_EXTENDED_DATA_STDERR); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - } - - /* append payload data */ - rc = ssh_buffer_pack(session->out_buffer, - "dP", - effectivelen, - (size_t)effectivelen, data); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PACKET, - "channel_write wrote %ld bytes", (long int) effectivelen); - - channel->remote_window -= effectivelen; - len -= effectivelen; - data = ((uint8_t*)data + effectivelen); - if (channel->counter != NULL) { - channel->counter->out_bytes += effectivelen; - } - } - - /* it's a good idea to flush the socket now */ - rc = ssh_channel_flush(channel); - if (rc == SSH_ERROR) { - goto error; - } - -out: - return (int)(origlen - len); - -error: - ssh_buffer_reinit(session->out_buffer); - - return SSH_ERROR; -} - -uint32_t ssh_channel_window_size(ssh_channel channel) { - return channel->remote_window; -} - -/** - * @brief Blocking write on a channel. - * - * @param[in] channel The channel to write to. - * - * @param[in] data A pointer to the data to write. - * - * @param[in] len The length of the buffer to write to. - * - * @return The number of bytes written, SSH_ERROR on error. - * - * @see ssh_channel_read() - */ -int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len) { - return channel_write_common(channel, data, len, 0); -} - -/** - * @brief Check if the channel is open or not. - * - * @param[in] channel The channel to check. - * - * @return 0 if channel is closed, nonzero otherwise. - * - * @see ssh_channel_is_closed() - */ -int ssh_channel_is_open(ssh_channel channel) { - if(channel == NULL) { - return 0; - } - return (channel->state == SSH_CHANNEL_STATE_OPEN && channel->session->alive != 0); -} - -/** - * @brief Check if the channel is closed or not. - * - * @param[in] channel The channel to check. - * - * @return 0 if channel is opened, nonzero otherwise. - * - * @see ssh_channel_is_open() - */ -int ssh_channel_is_closed(ssh_channel channel) { - if(channel == NULL) { - return SSH_ERROR; - } - return (channel->state != SSH_CHANNEL_STATE_OPEN || channel->session->alive == 0); -} - -/** - * @brief Check if remote has sent an EOF. - * - * @param[in] channel The channel to check. - * - * @return 0 if there is no EOF, nonzero otherwise. - */ -int ssh_channel_is_eof(ssh_channel channel) { - if(channel == NULL) { - return SSH_ERROR; - } - if ((channel->stdout_buffer && - buffer_get_rest_len(channel->stdout_buffer) > 0) || - (channel->stderr_buffer && - buffer_get_rest_len(channel->stderr_buffer) > 0)) { - return 0; - } - - return (channel->remote_eof != 0); -} - -/** - * @brief Put the channel into blocking or nonblocking mode. - * - * @param[in] channel The channel to use. - * - * @param[in] blocking A boolean for blocking or nonblocking. - * - * @warning A side-effect of this is to put the whole session - * in non-blocking mode. - * @see ssh_set_blocking() - */ -void ssh_channel_set_blocking(ssh_channel channel, int blocking) { - if(channel == NULL) { - return; - } - ssh_set_blocking(channel->session,blocking); -} - -/** - * @internal - * - * @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state. - * - * This works on SSH1 sessions too. - */ -SSH_PACKET_CALLBACK(ssh_packet_channel_success){ - ssh_channel channel; - (void)type; - (void)user; - - channel=channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PACKET, - "Received SSH_CHANNEL_SUCCESS on channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - if(channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING){ - SSH_LOG(SSH_LOG_RARE, "SSH_CHANNEL_SUCCESS received in incorrect state %d", - channel->request_state); - } else { - channel->request_state=SSH_CHANNEL_REQ_STATE_ACCEPTED; - } - - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state. - * - * This works on SSH1 sessions too. - */ -SSH_PACKET_CALLBACK(ssh_packet_channel_failure){ - ssh_channel channel; - (void)type; - (void)user; - - channel=channel_from_msg(session,packet); - if (channel == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); - - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PACKET, - "Received SSH_CHANNEL_FAILURE on channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - if(channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING){ - SSH_LOG(SSH_LOG_RARE, "SSH_CHANNEL_FAILURE received in incorrect state %d", - channel->request_state); - } else { - channel->request_state=SSH_CHANNEL_REQ_STATE_DENIED; - } - - return SSH_PACKET_USED; -} - -static int ssh_channel_request_termination(void *c){ - ssh_channel channel = (ssh_channel)c; - if(channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING || - channel->session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - else - return 0; -} - -static int channel_request(ssh_channel channel, const char *request, - ssh_buffer buffer, int reply) { - ssh_session session = channel->session; - int rc = SSH_ERROR; - int ret; - - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - - ret = ssh_buffer_pack(session->out_buffer, - "bdsb", - SSH2_MSG_CHANNEL_REQUEST, - channel->remote_channel, - request, - reply == 0 ? 0 : 1); - if (ret != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - if (buffer != NULL) { - if (ssh_buffer_add_data(session->out_buffer, buffer_get_rest(buffer), - buffer_get_rest_len(buffer)) < 0) { - ssh_set_error_oom(session); - goto error; - } - } - channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING; - if (packet_send(session) == SSH_ERROR) { - return rc; - } - - SSH_LOG(SSH_LOG_PACKET, - "Sent a SSH_MSG_CHANNEL_REQUEST %s", request); - if (reply == 0) { - channel->request_state = SSH_CHANNEL_REQ_STATE_NONE; - return SSH_OK; - } -pending: - rc = ssh_handle_packets_termination(session, - SSH_TIMEOUT_DEFAULT, - ssh_channel_request_termination, - channel); - - if(session->session_state == SSH_SESSION_STATE_ERROR || rc == SSH_ERROR) { - channel->request_state = SSH_CHANNEL_REQ_STATE_ERROR; - } - /* we received something */ - switch (channel->request_state){ - case SSH_CHANNEL_REQ_STATE_ERROR: - rc=SSH_ERROR; - break; - case SSH_CHANNEL_REQ_STATE_DENIED: - ssh_set_error(session, SSH_REQUEST_DENIED, - "Channel request %s failed", request); - rc=SSH_ERROR; - break; - case SSH_CHANNEL_REQ_STATE_ACCEPTED: - SSH_LOG(SSH_LOG_PROTOCOL, - "Channel request %s success",request); - rc=SSH_OK; - break; - case SSH_CHANNEL_REQ_STATE_PENDING: - rc = SSH_AGAIN; - return rc; - case SSH_CHANNEL_REQ_STATE_NONE: - /* Never reached */ - ssh_set_error(session, SSH_FATAL, "Invalid state in channel_request()"); - rc=SSH_ERROR; - break; - } - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - - return rc; -error: - ssh_buffer_reinit(session->out_buffer); - - return rc; -} - -/** - * @brief Request a pty with a specific type and size. - * - * @param[in] channel The channel to sent the request. - * - * @param[in] terminal The terminal type ("vt100, xterm,..."). - * - * @param[in] col The number of columns. - * - * @param[in] row The number of rows. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - */ -int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal, - int col, int row) { - ssh_session session; - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - session = channel->session; - - if(terminal == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - -#ifdef WITH_SSH1 - if (channel->version==1) { - rc = channel_request_pty_size1(channel,terminal, col, row); - - return rc; - } -#endif - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(session); - goto error; - } - - rc = ssh_buffer_pack(buffer, - "sdddddb", - terminal, - col, - row, - 0, /* pix */ - 0, /* pix */ - 1, /* add a 0byte string */ - 0); - - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } -pending: - rc = channel_request(channel, "pty-req", buffer, 1); -error: - ssh_buffer_free(buffer); - - return rc; -} - -/** - * @brief Request a PTY. - * - * @param[in] channel The channel to send the request. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * @see ssh_channel_request_pty_size() - */ -int ssh_channel_request_pty(ssh_channel channel) { - return ssh_channel_request_pty_size(channel, "xterm", 80, 24); -} - -/** - * @brief Change the size of the terminal associated to a channel. - * - * @param[in] channel The channel to change the size. - * - * @param[in] cols The new number of columns. - * - * @param[in] rows The new number of rows. - * - * @return SSH_OK on success, SSH_ERROR if an error occurred. - * - * @warning Do not call it from a signal handler if you are not sure any other - * libssh function using the same channel/session is running at same - * time (not 100% threadsafe). - */ -int ssh_channel_change_pty_size(ssh_channel channel, int cols, int rows) { - ssh_session session = channel->session; - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - -#ifdef WITH_SSH1 - if (channel->version == 1) { - rc = channel_change_pty_size1(channel,cols,rows); - - return rc; - } -#endif - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(session); - goto error; - } - - rc = ssh_buffer_pack(buffer, - "dddd", - cols, - rows, - 0, /* pix */ - 0 /* pix */); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - - rc = channel_request(channel, "window-change", buffer, 0); -error: - ssh_buffer_free(buffer); - - return rc; -} - -/** - * @brief Request a shell. - * - * @param[in] channel The channel to send the request. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - */ -int ssh_channel_request_shell(ssh_channel channel) { - if(channel == NULL) { - return SSH_ERROR; - } -#ifdef WITH_SSH1 - if (channel->version == 1) { - return channel_request_shell1(channel); - } -#endif - return channel_request(channel, "shell", NULL, 1); -} - -/** - * @brief Request a subsystem (for example "sftp"). - * - * @param[in] channel The channel to send the request. - * - * @param[in] subsys The subsystem to request (for example "sftp"). - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * @warning You normally don't have to call it for sftp, see sftp_new(). - */ -int ssh_channel_request_subsystem(ssh_channel channel, const char *subsys) { - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - if(subsys == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = ssh_buffer_pack(buffer, "s", subsys); - if (rc != SSH_OK) { - ssh_set_error_oom(channel->session); - goto error; - } -pending: - rc = channel_request(channel, "subsystem", buffer, 1); -error: - ssh_buffer_free(buffer); - - return rc; -} - -int ssh_channel_request_sftp( ssh_channel channel){ - if(channel == NULL) { - return SSH_ERROR; - } - return ssh_channel_request_subsystem(channel, "sftp"); -} - -static char *generate_cookie(void) { - static const char *hex = "0123456789abcdef"; - char s[36]; - unsigned char rnd[16]; - int i; - - ssh_get_random(rnd,sizeof(rnd),0); - for (i = 0; i < 16; i++) { - s[i*2] = hex[rnd[i] & 0x0f]; - s[i*2+1] = hex[rnd[i] >> 4]; - } - s[32] = '\0'; - return strdup(s); -} - -/** - * @brief Sends the "x11-req" channel request over an existing session channel. - * - * This will enable redirecting the display of the remote X11 applications to - * local X server over an secure tunnel. - * - * @param[in] channel An existing session channel where the remote X11 - * applications are going to be executed. - * - * @param[in] single_connection A boolean to mark only one X11 app will be - * redirected. - * - * @param[in] protocol A x11 authentication protocol. Pass NULL to use the - * default value MIT-MAGIC-COOKIE-1. - * - * @param[in] cookie A x11 authentication cookie. Pass NULL to generate - * a random cookie. - * - * @param[in] screen_number The screen number. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - */ -int ssh_channel_request_x11(ssh_channel channel, int single_connection, const char *protocol, - const char *cookie, int screen_number) { - ssh_buffer buffer = NULL; - char *c = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - if (cookie == NULL) { - c = generate_cookie(); - if (c == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - } - - rc = ssh_buffer_pack(buffer, - "bssd", - single_connection == 0 ? 0 : 1, - protocol ? protocol : "MIT-MAGIC-COOKIE-1", - cookie ? cookie : c, - screen_number); - if (c != NULL){ - SAFE_FREE(c); - } - if (rc != SSH_OK) { - ssh_set_error_oom(channel->session); - goto error; - } -pending: - rc = channel_request(channel, "x11-req", buffer, 1); - -error: - ssh_buffer_free(buffer); - return rc; -} - -static ssh_channel ssh_channel_accept(ssh_session session, int channeltype, - int timeout_ms, int *destination_port) { -#ifndef _WIN32 - static const struct timespec ts = { - .tv_sec = 0, - .tv_nsec = 50000000 /* 50ms */ - }; -#endif - ssh_message msg = NULL; - ssh_channel channel = NULL; - struct ssh_iterator *iterator; - int t; - - /* - * We sleep for 50 ms in ssh_handle_packets() and later sleep for - * 50 ms. So we need to decrement by 100 ms. - */ - for (t = timeout_ms; t >= 0; t -= 100) { - if (timeout_ms == 0) { - ssh_handle_packets(session, 0); - } else { - ssh_handle_packets(session, 50); - } - - if (session->ssh_message_list) { - iterator = ssh_list_get_iterator(session->ssh_message_list); - while (iterator) { - msg = (ssh_message)iterator->data; - if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL_OPEN && - ssh_message_subtype(msg) == channeltype) { - ssh_list_remove(session->ssh_message_list, iterator); - channel = ssh_message_channel_request_open_reply_accept(msg); - if(destination_port) { - *destination_port=msg->channel_request_open.destination_port; - } - - ssh_message_free(msg); - return channel; - } - iterator = iterator->next; - } - } - if(t>0){ -#ifdef _WIN32 - Sleep(50); /* 50ms */ -#else - nanosleep(&ts, NULL); -#endif - } - } - - ssh_set_error(session, SSH_NO_ERROR, "No channel request of this type from server"); - return NULL; -} - -/** - * @brief Accept an X11 forwarding channel. - * - * @param[in] channel An x11-enabled session channel. - * - * @param[in] timeout_ms Timeout in milliseconds. - * - * @return A newly created channel, or NULL if no X11 request from - * the server. - */ -ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms) { - return ssh_channel_accept(channel->session, SSH_CHANNEL_X11, timeout_ms, NULL); -} - -/** - * @internal - * - * @brief Handle a SSH_REQUEST_SUCCESS packet normally sent after a global - * request. - */ -SSH_PACKET_CALLBACK(ssh_request_success){ - (void)type; - (void)user; - (void)packet; - - SSH_LOG(SSH_LOG_PACKET, - "Received SSH_REQUEST_SUCCESS"); - if(session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING){ - SSH_LOG(SSH_LOG_RARE, "SSH_REQUEST_SUCCESS received in incorrect state %d", - session->global_req_state); - } else { - session->global_req_state=SSH_CHANNEL_REQ_STATE_ACCEPTED; - } - - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handle a SSH_REQUEST_DENIED packet normally sent after a global - * request. - */ -SSH_PACKET_CALLBACK(ssh_request_denied){ - (void)type; - (void)user; - (void)packet; - - SSH_LOG(SSH_LOG_PACKET, - "Received SSH_REQUEST_FAILURE"); - if(session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING){ - SSH_LOG(SSH_LOG_RARE, "SSH_REQUEST_DENIED received in incorrect state %d", - session->global_req_state); - } else { - session->global_req_state=SSH_CHANNEL_REQ_STATE_DENIED; - } - - return SSH_PACKET_USED; - -} - -static int ssh_global_request_termination(void *s){ - ssh_session session = (ssh_session) s; - if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING || - session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - else - return 0; -} - -/** - * @internal - * - * @brief Send a global request (needed for forward listening) and wait for the - * result. - * - * @param[in] session The SSH session handle. - * - * @param[in] request The type of request (defined in RFC). - * - * @param[in] buffer Additional data to put in packet. - * - * @param[in] reply Set if you expect a reply from server. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - */ -static int global_request(ssh_session session, const char *request, - ssh_buffer buffer, int reply) { - int rc; - - switch (session->global_req_state) { - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - - rc = ssh_buffer_pack(session->out_buffer, - "bsb", - SSH2_MSG_GLOBAL_REQUEST, - request, - reply == 0 ? 0 : 1); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - rc = SSH_ERROR; - goto error; - } - - if (buffer != NULL) { - rc = ssh_buffer_add_data(session->out_buffer, - buffer_get_rest(buffer), - buffer_get_rest_len(buffer)); - if (rc < 0) { - ssh_set_error_oom(session); - rc = SSH_ERROR; - goto error; - } - } - - session->global_req_state = SSH_CHANNEL_REQ_STATE_PENDING; - rc = packet_send(session); - if (rc == SSH_ERROR) { - return rc; - } - - SSH_LOG(SSH_LOG_PACKET, - "Sent a SSH_MSG_GLOBAL_REQUEST %s", request); - - if (reply == 0) { - session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE; - - return SSH_OK; - } -pending: - rc = ssh_handle_packets_termination(session, - SSH_TIMEOUT_DEFAULT, - ssh_global_request_termination, - session); - - if(rc==SSH_ERROR || session->session_state == SSH_SESSION_STATE_ERROR){ - session->global_req_state = SSH_CHANNEL_REQ_STATE_ERROR; - } - switch(session->global_req_state){ - case SSH_CHANNEL_REQ_STATE_ACCEPTED: - SSH_LOG(SSH_LOG_PROTOCOL, "Global request %s success",request); - rc=SSH_OK; - break; - case SSH_CHANNEL_REQ_STATE_DENIED: - SSH_LOG(SSH_LOG_PACKET, - "Global request %s failed", request); - ssh_set_error(session, SSH_REQUEST_DENIED, - "Global request %s failed", request); - rc=SSH_ERROR; - break; - case SSH_CHANNEL_REQ_STATE_ERROR: - case SSH_CHANNEL_REQ_STATE_NONE: - rc = SSH_ERROR; - break; - case SSH_CHANNEL_REQ_STATE_PENDING: - return SSH_AGAIN; - } - session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE; - - return rc; -error: - ssh_buffer_reinit(session->out_buffer); - - return rc; -} - -/** - * @brief Sends the "tcpip-forward" global request to ask the server to begin - * listening for inbound connections. - * - * @param[in] session The ssh session to send the request. - * - * @param[in] address The address to bind to on the server. Pass NULL to bind - * to all available addresses on all protocol families - * supported by the server. - * - * @param[in] port The port to bind to on the server. Pass 0 to ask the - * server to allocate the next available unprivileged port - * number - * - * @param[in] bound_port The pointer to get actual bound port. Pass NULL to - * ignore. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - **/ -int ssh_channel_listen_forward(ssh_session session, - const char *address, - int port, - int *bound_port) -{ - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(session->global_req_state != SSH_CHANNEL_REQ_STATE_NONE) - goto pending; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(session); - goto error; - } - - rc = ssh_buffer_pack(buffer, - "sd", - address ? address : "", - port); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - goto error; - } -pending: - rc = global_request(session, "tcpip-forward", buffer, 1); - - /* TODO: FIXME no guarantee the last packet we received contains - * that info */ - if (rc == SSH_OK && port == 0 && bound_port != NULL) { - rc = ssh_buffer_unpack(session->in_buffer, "d", bound_port); - if (rc != SSH_OK) - *bound_port = 0; - } - -error: - ssh_buffer_free(buffer); - return rc; -} - -/* DEPRECATED */ -ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms) { - return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, NULL); -} - -/** - * @brief Accept an incoming TCP/IP forwarding channel and get information - * about incomming connection - * @param[in] session The ssh session to use. - * - * @param[in] timeout_ms A timeout in milliseconds. - * - * @param[in] destination_port A pointer to destination port or NULL. - * - * @return Newly created channel, or NULL if no incoming channel request from - * the server - */ -ssh_channel ssh_channel_accept_forward(ssh_session session, int timeout_ms, int* destination_port) { - return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, destination_port); -} - -/** - * @brief Sends the "cancel-tcpip-forward" global request to ask the server to - * cancel the tcpip-forward request. - * - * @param[in] session The ssh session to send the request. - * - * @param[in] address The bound address on the server. - * - * @param[in] port The bound port on the server. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - */ -int ssh_channel_cancel_forward(ssh_session session, - const char *address, - int port) -{ - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(session->global_req_state != SSH_CHANNEL_REQ_STATE_NONE) - goto pending; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(session); - goto error; - } - - rc = ssh_buffer_pack(buffer, "sd", - address ? address : "", - port); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - goto error; - } -pending: - rc = global_request(session, "cancel-tcpip-forward", buffer, 1); - -error: - ssh_buffer_free(buffer); - return rc; -} - -int ssh_forward_cancel(ssh_session session, const char *address, int port) { - return ssh_channel_cancel_forward(session, address, port); -} - -/** - * @brief Set environment variables. - * - * @param[in] channel The channel to set the environment variables. - * - * @param[in] name The name of the variable. - * - * @param[in] value The value to set. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * @warning Some environment variables may be refused by security reasons. - */ -int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value) { - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - if(name == NULL || value == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = ssh_buffer_pack(buffer, - "ss", - name, - value); - if (rc != SSH_OK){ - ssh_set_error_oom(channel->session); - goto error; - } -pending: - rc = channel_request(channel, "env", buffer,1); -error: - ssh_buffer_free(buffer); - - return rc; -} - -/** - * @brief Run a shell command without an interactive shell. - * - * This is similar to 'sh -c command'. - * - * @param[in] channel The channel to execute the command. - * - * @param[in] cmd The command to execute - * (e.g. "ls ~/ -al | grep -i reports"). - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * Example: -@code - rc = channel_request_exec(channel, "ps aux"); - if (rc > 0) { - return -1; - } - - while ((rc = channel_read(channel, buffer, sizeof(buffer), 0)) > 0) { - if (fwrite(buffer, 1, rc, stdout) != (unsigned int) rc) { - return -1; - } - } -@endcode - * - * @see ssh_channel_request_shell() - */ -int ssh_channel_request_exec(ssh_channel channel, const char *cmd) { - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - if(cmd == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - -#ifdef WITH_SSH1 - if (channel->version == 1) { - return channel_request_exec1(channel, cmd); - } -#endif - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_NONE: - break; - default: - goto pending; - } - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = ssh_buffer_pack(buffer, "s", cmd); - - if (rc != SSH_OK) { - ssh_set_error_oom(channel->session); - goto error; - } -pending: - rc = channel_request(channel, "exec", buffer, 1); -error: - ssh_buffer_free(buffer); - return rc; -} - - -/** - * @brief Send a signal to remote process (as described in RFC 4254, section 6.9). - * - * Sends a signal 'sig' to the remote process. - * Note, that remote system may not support signals concept. - * In such a case this request will be silently ignored. - * Only SSH-v2 is supported (I'm not sure about SSH-v1). - * - * OpenSSH doesn't support signals yet, see: - * https://bugzilla.mindrot.org/show_bug.cgi?id=1424 - * - * @param[in] channel The channel to send signal. - * - * @param[in] sig The signal to send (without SIG prefix) - * \n\n - * SIGABRT -> ABRT \n - * SIGALRM -> ALRM \n - * SIGFPE -> FPE \n - * SIGHUP -> HUP \n - * SIGILL -> ILL \n - * SIGINT -> INT \n - * SIGKILL -> KILL \n - * SIGPIPE -> PIPE \n - * SIGQUIT -> QUIT \n - * SIGSEGV -> SEGV \n - * SIGTERM -> TERM \n - * SIGUSR1 -> USR1 \n - * SIGUSR2 -> USR2 \n - * - * @return SSH_OK on success, SSH_ERROR if an error occurred - * (including attempts to send signal via SSH-v1 session). - */ -int ssh_channel_request_send_signal(ssh_channel channel, const char *sig) { - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - if(sig == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - -#ifdef WITH_SSH1 - if (channel->version == 1) { - return SSH_ERROR; // TODO: Add support for SSH-v1 if possible. - } -#endif - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = ssh_buffer_pack(buffer, "s", sig); - if (rc != SSH_OK) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = channel_request(channel, "signal", buffer, 0); -error: - ssh_buffer_free(buffer); - return rc; -} - - -/** - * @brief Read data from a channel into a buffer. - * - * @param[in] channel The channel to read from. - * - * @param[in] buffer The buffer which will get the data. - * - * @param[in] count The count of bytes to be read. If it is bigger than 0, - * the exact size will be read, else (bytes=0) it will - * return once anything is available. - * - * @param is_stderr A boolean value to mark reading from the stderr stream. - * - * @return The number of bytes read, 0 on end of file or SSH_ERROR - * on error. - * @deprecated Please use ssh_channel_read instead - * @warning This function doesn't work in nonblocking/timeout mode - * @see ssh_channel_read - */ -int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count, - int is_stderr) { - ssh_session session; - char buffer_tmp[8192]; - int r; - uint32_t total=0; - - if(channel == NULL) { - return SSH_ERROR; - } - session = channel->session; - - if(buffer == NULL) { - ssh_set_error_invalid(channel->session); - return SSH_ERROR; - } - - ssh_buffer_reinit(buffer); - if(count==0){ - do { - r=ssh_channel_poll(channel, is_stderr); - if(r < 0){ - return r; - } - if(r > 0){ - r=ssh_channel_read(channel, buffer_tmp, r, is_stderr); - if(r < 0){ - return r; - } - if(ssh_buffer_add_data(buffer,buffer_tmp,r) < 0){ - ssh_set_error_oom(session); - r = SSH_ERROR; - } - - return r; - } - if(ssh_channel_is_eof(channel)){ - return 0; - } - ssh_handle_packets(channel->session, SSH_TIMEOUT_INFINITE); - } while (r == 0); - } - while(total < count){ - r=ssh_channel_read(channel, buffer_tmp, sizeof(buffer_tmp), is_stderr); - if(r<0){ - return r; - } - if(r==0){ - return total; - } - if (ssh_buffer_add_data(buffer,buffer_tmp,r) < 0) { - ssh_set_error_oom(session); - - return SSH_ERROR; - } - total += r; - } - - return total; -} - -struct ssh_channel_read_termination_struct { - ssh_channel channel; - uint32_t count; - ssh_buffer buffer; -}; - -static int ssh_channel_read_termination(void *s){ - struct ssh_channel_read_termination_struct *ctx = s; - if (buffer_get_rest_len(ctx->buffer) >= ctx->count || - ctx->channel->remote_eof || - ctx->channel->session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - else - return 0; -} - -/* TODO FIXME Fix the delayed close thing */ -/* TODO FIXME Fix the blocking behaviours */ - -/** - * @brief Reads data from a channel. - * - * @param[in] channel The channel to read from. - * - * @param[in] dest The destination buffer which will get the data. - * - * @param[in] count The count of bytes to be read. - * - * @param[in] is_stderr A boolean value to mark reading from the stderr flow. - * - * @return The number of bytes read, 0 on end of file or SSH_ERROR - * on error. In nonblocking mode it Can return 0 if no data - * is available or SSH_AGAIN. - * - * @warning This function may return less than count bytes of data, and won't - * block until count bytes have been read. - * @warning The read function using a buffer has been renamed to - * channel_read_buffer(). - */ -int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr) -{ - return ssh_channel_read_timeout(channel, dest, count, is_stderr, -1); -} - -/** - * @brief Reads data from a channel. - * - * @param[in] channel The channel to read from. - * - * @param[in] dest The destination buffer which will get the data. - * - * @param[in] count The count of bytes to be read. - * - * @param[in] is_stderr A boolean value to mark reading from the stderr flow. - * - * @param[in] timeout_ms A timeout in milliseconds. A value of -1 means - * infinite timeout. - * - * @return The number of bytes read, 0 on end of file or SSH_ERROR - * on error. In nonblocking mode it Can return 0 if no data - * is available or SSH_AGAIN. - * - * @warning This function may return less than count bytes of data, and won't - * block until count bytes have been read. - * @warning The read function using a buffer has been renamed to - * channel_read_buffer(). - */ -int ssh_channel_read_timeout(ssh_channel channel, - void *dest, - uint32_t count, - int is_stderr, - int timeout) -{ - ssh_session session; - ssh_buffer stdbuf; - uint32_t len; - struct ssh_channel_read_termination_struct ctx; - int rc; - - if(channel == NULL) { - return SSH_ERROR; - } - if(dest == NULL) { - ssh_set_error_invalid(channel->session); - return SSH_ERROR; - } - - session = channel->session; - stdbuf = channel->stdout_buffer; - - if (count == 0) { - return 0; - } - - if (is_stderr) { - stdbuf=channel->stderr_buffer; - } - - /* - * We may have problem if the window is too small to accept as much data - * as asked - */ - SSH_LOG(SSH_LOG_PACKET, - "Read (%d) buffered : %d bytes. Window: %d", - count, - buffer_get_rest_len(stdbuf), - channel->local_window); - - if (count > buffer_get_rest_len(stdbuf) + channel->local_window) { - if (grow_window(session, channel, count - buffer_get_rest_len(stdbuf)) < 0) { - return -1; - } - } - - /* block reading until at least one byte has been read - * and ignore the trivial case count=0 - */ - ctx.channel = channel; - ctx.buffer = stdbuf; - ctx.count = 1; - - if (timeout < 0) { - timeout = SSH_TIMEOUT_DEFAULT; - } - - rc = ssh_handle_packets_termination(session, - timeout, - ssh_channel_read_termination, - &ctx); - if (rc == SSH_ERROR){ - return rc; - } - if (channel->session->session_state == SSH_SESSION_STATE_ERROR){ - return SSH_ERROR; - } - if (channel->remote_eof && buffer_get_rest_len(stdbuf) == 0) { - return 0; - } - len = buffer_get_rest_len(stdbuf); - /* Read count bytes if len is greater, everything otherwise */ - len = (len > count ? count : len); - memcpy(dest, buffer_get_rest(stdbuf), len); - buffer_pass_bytes(stdbuf,len); - if (channel->counter != NULL) { - channel->counter->in_bytes += len; - } - /* Authorize some buffering while userapp is busy */ - if (channel->local_window < WINDOWLIMIT) { - if (grow_window(session, channel, 0) < 0) { - return -1; - } - } - - return len; -} - -/** - * @brief Do a nonblocking read on the channel. - * - * A nonblocking read on the specified channel. it will return <= count bytes of - * data read atomically. - * - * @param[in] channel The channel to read from. - * - * @param[in] dest A pointer to a destination buffer. - * - * @param[in] count The count of bytes of data to be read. - * - * @param[in] is_stderr A boolean to select the stderr stream. - * - * @return The number of bytes read, 0 if nothing is available or - * SSH_ERROR on error. - * - * @warning Don't forget to check for EOF as it would return 0 here. - * - * @see ssh_channel_is_eof() - */ -int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count, - int is_stderr) { - ssh_session session; - int to_read; - int rc; - int blocking; - - if(channel == NULL) { - return SSH_ERROR; - } - if(dest == NULL) { - ssh_set_error_invalid(channel->session); - return SSH_ERROR; - } - - session = channel->session; - - to_read = ssh_channel_poll(channel, is_stderr); - - if (to_read <= 0) { - if (channel->session->session_state == SSH_SESSION_STATE_ERROR){ - return SSH_ERROR; - } - - return to_read; /* may be an error code */ - } - - if (to_read > (int)count) { - to_read = (int)count; - } - blocking = ssh_is_blocking(session); - ssh_set_blocking(session, 0); - rc = ssh_channel_read(channel, dest, to_read, is_stderr); - ssh_set_blocking(session,blocking); - - return rc; -} - -/** - * @brief Polls a channel for data to read. - * - * @param[in] channel The channel to poll. - * - * @param[in] is_stderr A boolean to select the stderr stream. - * - * @return The number of bytes available for reading, 0 if nothing - * is available or SSH_ERROR on error. - * - * @warning When the channel is in EOF state, the function returns SSH_EOF. - * - * @see ssh_channel_is_eof() - */ -int ssh_channel_poll(ssh_channel channel, int is_stderr){ - ssh_buffer stdbuf; - - if(channel == NULL) { - return SSH_ERROR; - } - - stdbuf = channel->stdout_buffer; - - if (is_stderr) { - stdbuf = channel->stderr_buffer; - } - - if (buffer_get_rest_len(stdbuf) == 0 && channel->remote_eof == 0) { - if (channel->session->session_state == SSH_SESSION_STATE_ERROR){ - return SSH_ERROR; - } - if (ssh_handle_packets(channel->session, SSH_TIMEOUT_NONBLOCKING)==SSH_ERROR) { - return SSH_ERROR; - } - } - - if (buffer_get_rest_len(stdbuf) > 0){ - return buffer_get_rest_len(stdbuf); - } - - if (channel->remote_eof) { - return SSH_EOF; - } - - return buffer_get_rest_len(stdbuf); -} - -/** - * @brief Polls a channel for data to read, waiting for a certain timeout. - * - * @param[in] channel The channel to poll. - * @param[in] timeout Set an upper limit on the time for which this function - * will block, in milliseconds. Specifying a negative value - * means an infinite timeout. This parameter is passed to - * the poll() function. - * @param[in] is_stderr A boolean to select the stderr stream. - * - * @return The number of bytes available for reading, - * 0 if nothing is available (timeout elapsed), - * SSH_EOF on end of file, - * SSH_ERROR on error. - * - * @warning When the channel is in EOF state, the function returns SSH_EOF. - * - * @see ssh_channel_is_eof() - */ -int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr){ - ssh_session session; - ssh_buffer stdbuf; - struct ssh_channel_read_termination_struct ctx; - int rc; - - if(channel == NULL) { - return SSH_ERROR; - } - - session = channel->session; - stdbuf = channel->stdout_buffer; - - if (is_stderr) { - stdbuf = channel->stderr_buffer; - } - ctx.buffer = stdbuf; - ctx.channel = channel; - ctx.count = 1; - rc = ssh_handle_packets_termination(channel->session, timeout, - ssh_channel_read_termination, &ctx); - if(rc ==SSH_ERROR || session->session_state == SSH_SESSION_STATE_ERROR){ - rc = SSH_ERROR; - goto end; - } - rc = buffer_get_rest_len(stdbuf); - if(rc > 0) - goto end; - if (channel->remote_eof) - rc = SSH_EOF; -end: - return rc; -} - -/** - * @brief Recover the session in which belongs a channel. - * - * @param[in] channel The channel to recover the session from. - * - * @return The session pointer. - */ -ssh_session ssh_channel_get_session(ssh_channel channel) { - if(channel == NULL) { - return NULL; - } - - return channel->session; -} - -static int ssh_channel_exit_status_termination(void *c){ - ssh_channel channel = c; - if(channel->exit_status != -1 || - /* When a channel is closed, no exit status message can - * come anymore */ - (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) || - channel->session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - else - return 0; -} - -/** - * @brief Get the exit status of the channel (error code from the executed - * instruction). - * - * @param[in] channel The channel to get the status from. - * - * @returns The exit status, -1 if no exit status has been returned - * (yet). - * @warning This function may block until a timeout (or never) - * if the other side is not willing to close the channel. - * - * If you're looking for an async handling of this register a callback for the - * exit status. - * - * @see ssh_channel_exit_status_callback - */ -int ssh_channel_get_exit_status(ssh_channel channel) { - int rc; - if(channel == NULL) { - return SSH_ERROR; - } - rc = ssh_handle_packets_termination(channel->session, - SSH_TIMEOUT_DEFAULT, - ssh_channel_exit_status_termination, - channel); - if (rc == SSH_ERROR || channel->session->session_state == - SSH_SESSION_STATE_ERROR) - return SSH_ERROR; - return channel->exit_status; -} - -/* - * This function acts as a meta select. - * - * First, channels are analyzed to seek potential can-write or can-read ones, - * then if no channel has been elected, it goes in a loop with the posix - * select(2). - * This is made in two parts: protocol select and network select. The protocol - * select does not use the network functions at all - */ -static int channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans, - ssh_channel *echans, ssh_channel *rout, ssh_channel *wout, ssh_channel *eout) { - ssh_channel chan; - int i; - int j = 0; - - for (i = 0; rchans[i] != NULL; i++) { - chan = rchans[i]; - - while (ssh_channel_is_open(chan) && ssh_socket_data_available(chan->session->socket)) { - ssh_handle_packets(chan->session, SSH_TIMEOUT_NONBLOCKING); - } - - if ((chan->stdout_buffer && buffer_get_rest_len(chan->stdout_buffer) > 0) || - (chan->stderr_buffer && buffer_get_rest_len(chan->stderr_buffer) > 0) || - chan->remote_eof) { - rout[j] = chan; - j++; - } - } - rout[j] = NULL; - - j = 0; - for(i = 0; wchans[i] != NULL; i++) { - chan = wchans[i]; - /* It's not our business to seek if the file descriptor is writable */ - if (ssh_socket_data_writable(chan->session->socket) && - ssh_channel_is_open(chan) && (chan->remote_window > 0)) { - wout[j] = chan; - j++; - } - } - wout[j] = NULL; - - j = 0; - for (i = 0; echans[i] != NULL; i++) { - chan = echans[i]; - - if (!ssh_socket_is_open(chan->session->socket) || ssh_channel_is_closed(chan)) { - eout[j] = chan; - j++; - } - } - eout[j] = NULL; - - return 0; -} - -/* Just count number of pointers in the array */ -static int count_ptrs(ssh_channel *ptrs) { - int c; - for (c = 0; ptrs[c] != NULL; c++) - ; - - return c; -} - -/** - * @brief Act like the standard select(2) on channels. - * - * The list of pointers are then actualized and will only contain pointers to - * channels that are respectively readable, writable or have an exception to - * trap. - * - * @param[in] readchans A NULL pointer or an array of channel pointers, - * terminated by a NULL. - * - * @param[in] writechans A NULL pointer or an array of channel pointers, - * terminated by a NULL. - * - * @param[in] exceptchans A NULL pointer or an array of channel pointers, - * terminated by a NULL. - * - * @param[in] timeout Timeout as defined by select(2). - * - * @return SSH_OK on a successful operation, SSH_EINTR if the - * select(2) syscall was interrupted, then relaunch the - * function. - */ -int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, - ssh_channel *exceptchans, struct timeval * timeout) { - ssh_channel *rchans, *wchans, *echans; - ssh_channel dummy = NULL; - ssh_event event = NULL; - int rc; - int i; - int tm, tm_base; - int firstround=1; - struct ssh_timestamp ts; - - if (timeout != NULL) - tm_base = timeout->tv_sec * 1000 + timeout->tv_usec/1000; - else - tm_base = SSH_TIMEOUT_INFINITE; - ssh_timestamp_init(&ts); - tm = tm_base; - /* don't allow NULL pointers */ - if (readchans == NULL) { - readchans = &dummy; - } - - if (writechans == NULL) { - writechans = &dummy; - } - - if (exceptchans == NULL) { - exceptchans = &dummy; - } - - if (readchans[0] == NULL && writechans[0] == NULL && exceptchans[0] == NULL) { - /* No channel to poll?? Go away! */ - return 0; - } - - /* Prepare the outgoing temporary arrays */ - rchans = malloc(sizeof(ssh_channel ) * (count_ptrs(readchans) + 1)); - if (rchans == NULL) { - return SSH_ERROR; - } - - wchans = malloc(sizeof(ssh_channel ) * (count_ptrs(writechans) + 1)); - if (wchans == NULL) { - SAFE_FREE(rchans); - return SSH_ERROR; - } - - echans = malloc(sizeof(ssh_channel ) * (count_ptrs(exceptchans) + 1)); - if (echans == NULL) { - SAFE_FREE(rchans); - SAFE_FREE(wchans); - return SSH_ERROR; - } - - /* - * First, try without doing network stuff then, use the ssh_poll - * infrastructure to poll on all sessions. - */ - do { - channel_protocol_select(readchans, writechans, exceptchans, - rchans, wchans, echans); - if (rchans[0] != NULL || wchans[0] != NULL || echans[0] != NULL) { - /* At least one channel has an event */ - break; - } - /* Add all channels' sessions right into an event object */ - if (event == NULL) { - event = ssh_event_new(); - if (event == NULL) { - SAFE_FREE(rchans); - SAFE_FREE(wchans); - SAFE_FREE(echans); - - return SSH_ERROR; - } - for (i = 0; readchans[i] != NULL; i++) { - ssh_poll_get_default_ctx(readchans[i]->session); - ssh_event_add_session(event, readchans[i]->session); - } - for (i = 0; writechans[i] != NULL; i++) { - ssh_poll_get_default_ctx(writechans[i]->session); - ssh_event_add_session(event, writechans[i]->session); - } - for (i = 0; exceptchans[i] != NULL; i++) { - ssh_poll_get_default_ctx(exceptchans[i]->session); - ssh_event_add_session(event, exceptchans[i]->session); - } - } - /* Get out if the timeout has elapsed */ - if (!firstround && ssh_timeout_elapsed(&ts, tm_base)){ - break; - } - /* Here we go */ - rc = ssh_event_dopoll(event,tm); - if (rc != SSH_OK){ - SAFE_FREE(rchans); - SAFE_FREE(wchans); - SAFE_FREE(echans); - ssh_event_free(event); - return rc; - } - tm = ssh_timeout_update(&ts, tm_base); - firstround=0; - } while(1); - - memcpy(readchans, rchans, (count_ptrs(rchans) + 1) * sizeof(ssh_channel )); - memcpy(writechans, wchans, (count_ptrs(wchans) + 1) * sizeof(ssh_channel )); - memcpy(exceptchans, echans, (count_ptrs(echans) + 1) * sizeof(ssh_channel )); - SAFE_FREE(rchans); - SAFE_FREE(wchans); - SAFE_FREE(echans); - if(event) - ssh_event_free(event); - return 0; -} - -/** - * @brief Set the channel data counter. - * - * @code - * struct ssh_counter_struct counter = { - * .in_bytes = 0, - * .out_bytes = 0, - * .in_packets = 0, - * .out_packets = 0 - * }; - * - * ssh_channel_set_counter(channel, &counter); - * @endcode - * - * @param[in] channel The SSH channel. - * - * @param[in] counter Counter for bytes handled by the channel. - */ -void ssh_channel_set_counter(ssh_channel channel, - ssh_counter counter) { - if (channel != NULL) { - channel->counter = counter; - } -} - -#if WITH_SERVER -/** - * @brief Blocking write on a channel stderr. - * - * @param[in] channel The channel to write to. - * - * @param[in] data A pointer to the data to write. - * - * @param[in] len The length of the buffer to write to. - * - * @return The number of bytes written, SSH_ERROR on error. - * - * @see ssh_channel_read() - */ -int ssh_channel_write_stderr(ssh_channel channel, const void *data, uint32_t len) { - return channel_write_common(channel, data, len, 1); -} - -/** - * @brief Open a TCP/IP reverse forwarding channel. - * - * @param[in] channel An allocated channel. - * - * @param[in] remotehost The remote host to connected (host name or IP). - * - * @param[in] remoteport The remote port. - * - * @param[in] sourcehost The source host (your local computer). It's optional - * and for logging purpose. - * - * @param[in] localport The source port (your local computer). It's optional - * and for logging purpose. - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * - * @warning This function does not bind the local port and does not automatically - * forward the content of a socket to the channel. You still have to - * use channel_read and channel_write for this. - */ -int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost, - int remoteport, const char *sourcehost, int localport) { - ssh_session session; - ssh_buffer payload = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return rc; - } - if(remotehost == NULL || sourcehost == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - - session = channel->session; - - if(channel->state != SSH_CHANNEL_STATE_NOT_OPEN) - goto pending; - payload = ssh_buffer_new(); - if (payload == NULL) { - ssh_set_error_oom(session); - goto error; - } - rc = ssh_buffer_pack(payload, - "sdsd", - remotehost, - remoteport, - sourcehost, - localport); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - goto error; - } -pending: - rc = channel_open(channel, - "forwarded-tcpip", - CHANNEL_INITIAL_WINDOW, - CHANNEL_MAX_PACKET, - payload); - -error: - ssh_buffer_free(payload); - - return rc; -} - -/** - * @brief Open a X11 channel. - * - * @param[in] channel An allocated channel. - * - * @param[in] orig_addr The source host (the local server). - * - * @param[in] orig_port The source port (the local server). - * - * @return SSH_OK on success, - * SSH_ERROR if an error occurred, - * SSH_AGAIN if in nonblocking mode and call has - * to be done again. - * @warning This function does not bind the local port and does not automatically - * forward the content of a socket to the channel. You still have to - * use channel_read and channel_write for this. - */ -int ssh_channel_open_x11(ssh_channel channel, - const char *orig_addr, int orig_port) { - ssh_session session; - ssh_buffer payload = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return rc; - } - if(orig_addr == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } - session = channel->session; - - if(channel->state != SSH_CHANNEL_STATE_NOT_OPEN) - goto pending; - - payload = ssh_buffer_new(); - if (payload == NULL) { - ssh_set_error_oom(session); - goto error; - } - - rc = ssh_buffer_pack(payload, - "sd", - orig_addr, - orig_port); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } -pending: - rc = channel_open(channel, - "x11", - CHANNEL_INITIAL_WINDOW, - CHANNEL_MAX_PACKET, - payload); - -error: - ssh_buffer_free(payload); - - return rc; -} - -/** - * @brief Send the exit status to the remote process - * - * Sends the exit status to the remote process (as described in RFC 4254, - * section 6.10). - * Only SSH-v2 is supported (I'm not sure about SSH-v1). - * - * @param[in] channel The channel to send exit status. - * - * @param[in] exit_status The exit status to send - * - * @return SSH_OK on success, SSH_ERROR if an error occurred. - * (including attempts to send exit status via SSH-v1 session). - */ -int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) { - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return SSH_ERROR; - } - -#ifdef WITH_SSH1 - if (channel->version == 1) { - return SSH_ERROR; // TODO: Add support for SSH-v1 if possible. - } -#endif - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = ssh_buffer_pack(buffer, "d", exit_status); - if (rc != SSH_OK) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = channel_request(channel, "exit-status", buffer, 0); -error: - ssh_buffer_free(buffer); - return rc; -} - -/** - * @brief Send an exit signal to remote process (RFC 4254, section 6.10). - * - * This sends the exit status of the remote process. - * Note, that remote system may not support signals concept. - * In such a case this request will be silently ignored. - * Only SSH-v2 is supported (I'm not sure about SSH-v1). - * - * @param[in] channel The channel to send signal. - * - * @param[in] sig The signal to send (without SIG prefix) - * (e.g. "TERM" or "KILL"). - * @param[in] core A boolean to tell if a core was dumped - * @param[in] errmsg A CRLF explanation text about the error condition - * @param[in] lang The language used in the message (format: RFC 3066) - * - * @return SSH_OK on success, SSH_ERROR if an error occurred - * (including attempts to send signal via SSH-v1 session). - */ -int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig, - int core, const char *errmsg, const char *lang) { - ssh_buffer buffer = NULL; - int rc = SSH_ERROR; - - if(channel == NULL) { - return rc; - } - if(sig == NULL || errmsg == NULL || lang == NULL) { - ssh_set_error_invalid(channel->session); - return rc; - } -#ifdef WITH_SSH1 - if (channel->version == 1) { - return SSH_ERROR; // TODO: Add support for SSH-v1 if possible. - } -#endif - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = ssh_buffer_pack(buffer, - "sbss", - sig, - core ? 1 : 0, - errmsg, - lang); - if (rc != SSH_OK) { - ssh_set_error_oom(channel->session); - goto error; - } - - rc = channel_request(channel, "exit-signal", buffer, 0); -error: - ssh_buffer_free(buffer); - return rc; -} - -#endif - -/* @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/channels1.c b/libssh/src/channels1.c deleted file mode 100644 index 4d82c636..00000000 --- a/libssh/src/channels1.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * channels1.c - Support for SSH-1 type channels - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 by Aris Adamantiadis - * Copyright (c) 2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include -#ifndef _WIN32 -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "libssh/priv.h" -#include "libssh/ssh1.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/channels.h" -#include "libssh/session.h" -#include "libssh/misc.h" - -#ifdef WITH_SSH1 - -/* - * This is a big hack. In fact, SSH1 doesn't make a clever use of channels. - * The whole packets concerning shells are sent outside of a channel. - * Thus, an inside limitation of this behavior is that you can't only - * request one shell. - * The question is still how they managed to embed two "channel" into one - * protocol. - */ - -int channel_open_session1(ssh_channel chan) { - ssh_session session; - - if (chan == NULL) { - return -1; - } - session = chan->session; - - /* - * We guess we are requesting an *exec* channel. It can only have one exec - * channel. So we abort with an error if we need more than one. - */ - if (session->exec_channel_opened) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "SSH1 supports only one execution channel. " - "One has already been opened"); - return -1; - } - session->exec_channel_opened = 1; - chan->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED; - chan->state = SSH_CHANNEL_STATE_OPEN; - chan->local_maxpacket = 32000; - chan->local_window = 64000; - SSH_LOG(SSH_LOG_PACKET, "Opened a SSH1 channel session"); - - return 0; -} - -/* 10 SSH_CMSG_REQUEST_PTY - * - * string TERM environment variable value (e.g. vt100) - * 32-bit int terminal height, rows (e.g., 24) - * 32-bit int terminal width, columns (e.g., 80) - * 32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) - * 32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) - * n bytes tty modes encoded in binary - * Some day, someone should have a look at that nasty tty encoded. It's - * much simplier under ssh2. I just hope the defaults values are ok ... - */ - -int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col, - int row) { - ssh_session session; - ssh_string str = NULL; - - if (channel == NULL) { - return SSH_ERROR; - } - session = channel->session; - - if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state"); - return SSH_ERROR; - } - str = ssh_string_from_char(terminal); - if (str == NULL) { - ssh_set_error_oom(session); - return -1; - } - - if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 || - buffer_add_ssh_string(session->out_buffer, str) < 0) { - ssh_string_free(str); - return -1; - } - ssh_string_free(str); - - if (buffer_add_u32(session->out_buffer, ntohl(row)) < 0 || - buffer_add_u32(session->out_buffer, ntohl(col)) < 0 || - buffer_add_u32(session->out_buffer, 0) < 0 || /* x */ - buffer_add_u32(session->out_buffer, 0) < 0 || /* y */ - buffer_add_u8(session->out_buffer, 0) < 0) { /* tty things */ - return -1; - } - - SSH_LOG(SSH_LOG_FUNCTIONS, "Opening a ssh1 pty"); - channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING; - if (packet_send(session) == SSH_ERROR) { - return -1; - } - - while (channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING) { - ssh_handle_packets(session, SSH_TIMEOUT_INFINITE); - } - - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_ERROR: - case SSH_CHANNEL_REQ_STATE_PENDING: - case SSH_CHANNEL_REQ_STATE_NONE: - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - return SSH_ERROR; - case SSH_CHANNEL_REQ_STATE_ACCEPTED: - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - SSH_LOG(SSH_LOG_RARE, "PTY: Success"); - return SSH_OK; - case SSH_CHANNEL_REQ_STATE_DENIED: - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - ssh_set_error(session, SSH_REQUEST_DENIED, - "Server denied PTY allocation"); - SSH_LOG(SSH_LOG_RARE, "PTY: denied\n"); - return SSH_ERROR; - } - // Not reached - return SSH_ERROR; -} - -int channel_change_pty_size1(ssh_channel channel, int cols, int rows) { - ssh_session session; - - if (channel == NULL) { - return SSH_ERROR; - } - session = channel->session; - - if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state"); - return SSH_ERROR; - } - if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 || - buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 || - buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 || - buffer_add_u32(session->out_buffer, 0) < 0 || - buffer_add_u32(session->out_buffer, 0) < 0) { - return SSH_ERROR; - } - channel->request_state=SSH_CHANNEL_REQ_STATE_PENDING; - if (packet_send(session) == SSH_ERROR) { - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PROTOCOL, "Change pty size send"); - while(channel->request_state==SSH_CHANNEL_REQ_STATE_PENDING){ - ssh_handle_packets(session, SSH_TIMEOUT_INFINITE); - } - switch(channel->request_state){ - case SSH_CHANNEL_REQ_STATE_ERROR: - case SSH_CHANNEL_REQ_STATE_PENDING: - case SSH_CHANNEL_REQ_STATE_NONE: - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - return SSH_ERROR; - case SSH_CHANNEL_REQ_STATE_ACCEPTED: - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - SSH_LOG(SSH_LOG_PROTOCOL, "pty size changed"); - return SSH_OK; - case SSH_CHANNEL_REQ_STATE_DENIED: - channel->request_state=SSH_CHANNEL_REQ_STATE_NONE; - SSH_LOG(SSH_LOG_RARE, "pty size change denied"); - ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied"); - return SSH_ERROR; - } - // Not reached - return SSH_ERROR; - -} - -int channel_request_shell1(ssh_channel channel) { - ssh_session session; - - if (channel == NULL) { - return -1; - } - session = channel->session; - - if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) { - return -1; - } - - if (packet_send(session) == SSH_ERROR) { - return -1; - } - - SSH_LOG(SSH_LOG_RARE, "Launched a shell"); - - return 0; -} - -int channel_request_exec1(ssh_channel channel, const char *cmd) { - ssh_session session; - ssh_string command = NULL; - - if (channel == NULL) { - return -1; - } - session = channel->session; - - command = ssh_string_from_char(cmd); - if (command == NULL) { - return -1; - } - - if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 || - buffer_add_ssh_string(session->out_buffer, command) < 0) { - ssh_string_free(command); - return -1; - } - ssh_string_free(command); - - if(packet_send(session) == SSH_ERROR) { - return -1; - } - - SSH_LOG(SSH_LOG_RARE, "Executing %s ...", cmd); - - return 0; -} - -SSH_PACKET_CALLBACK(ssh_packet_data1){ - ssh_channel channel = ssh_get_channel1(session); - ssh_string str = NULL; - int is_stderr=(type==SSH_SMSG_STDOUT_DATA ? 0 : 1); - (void)user; - - if (channel == NULL) { - return SSH_PACKET_NOT_USED; - } - - str = buffer_get_ssh_string(packet); - if (str == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "Invalid data packet !\n"); - return SSH_PACKET_USED; - } - - SSH_LOG(SSH_LOG_PROTOCOL, - "Adding %" PRIdS " bytes data in %d", - ssh_string_len(str), is_stderr); - - if (channel_default_bufferize(channel, ssh_string_data(str), ssh_string_len(str), - is_stderr) < 0) { - ssh_string_free(str); - return SSH_PACKET_USED; - } - ssh_string_free(str); - - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(ssh_packet_close1){ - ssh_channel channel = ssh_get_channel1(session); - uint32_t status; - int rc; - - (void)type; - (void)user; - - if (channel == NULL) { - return SSH_PACKET_NOT_USED; - } - - buffer_get_u32(packet, &status); - /* - * It's much more than a channel closing. spec says it's the last - * message sent by server (strange) - */ - - /* actually status is lost somewhere */ - channel->state = SSH_CHANNEL_STATE_CLOSED; - channel->remote_eof = 1; - - rc = buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION); - if (rc < 0) { - return SSH_PACKET_NOT_USED; - } - packet_send(session); - - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(ssh_packet_exist_status1){ - ssh_channel channel = ssh_get_channel1(session); - uint32_t status; - (void)type; - (void)user; - - if (channel == NULL) { - return SSH_PACKET_NOT_USED; - } - - buffer_get_u32(packet, &status); - channel->state = SSH_CHANNEL_STATE_CLOSED; - channel->remote_eof = 1; - channel->exit_status = ntohl(status); - - return SSH_PACKET_USED; -} - - -int channel_write1(ssh_channel channel, const void *data, int len) { - ssh_session session; - int origlen = len; - int effectivelen; - const unsigned char *ptr=data; - - if (channel == NULL) { - return -1; - } - session = channel->session; - - while (len > 0) { - if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) { - return -1; - } - - effectivelen = len > 32000 ? 32000 : len; - - if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 || - ssh_buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) { - return -1; - } - - ptr += effectivelen; - len -= effectivelen; - - if (packet_send(session) == SSH_ERROR) { - return -1; - } - ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING); - if (channel->counter != NULL) { - channel->counter->out_bytes += effectivelen; - } - } - if (ssh_blocking_flush(session,SSH_TIMEOUT_USER) == SSH_ERROR) - return -1; - return origlen; -} - -ssh_channel ssh_get_channel1(ssh_session session){ - struct ssh_iterator *it; - - if (session == NULL) { - return NULL; - } - - /* With SSH1, the channel is always the first one */ - if(session->channels != NULL){ - it = ssh_list_get_iterator(session->channels); - if(it) - return ssh_iterator_value(ssh_channel, it); - } - return NULL; -} -#endif /* WITH_SSH1 */ -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/client.c b/libssh/src/client.c deleted file mode 100644 index 0a45944c..00000000 --- a/libssh/src/client.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * client.c - SSH client functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/ssh2.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/options.h" -#include "libssh/socket.h" -#include "libssh/session.h" -#include "libssh/dh.h" -#include "libssh/ecdh.h" -#include "libssh/threads.h" -#include "libssh/misc.h" -#include "libssh/pki.h" -#include "libssh/kex.h" - -#define set_status(session, status) do {\ - if (session->common.callbacks && session->common.callbacks->connect_status_function) \ - session->common.callbacks->connect_status_function(session->common.callbacks->userdata, status); \ - } while (0) - -/** - * @internal - * @brief Callback to be called when the socket is connected or had a - * connection error. Changes the state of the session and updates the error - * message. - * @param code one of SSH_SOCKET_CONNECTED_OK or SSH_SOCKET_CONNECTED_ERROR - * @param user is a pointer to session - */ -static void socket_callback_connected(int code, int errno_code, void *user){ - ssh_session session=(ssh_session)user; - - if (session->session_state != SSH_SESSION_STATE_CONNECTING && - session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED) - { - ssh_set_error(session,SSH_FATAL, "Wrong state in socket_callback_connected : %d", - session->session_state); - - return; - } - - SSH_LOG(SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno_code); - if(code == SSH_SOCKET_CONNECTED_OK) - session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED; - else { - session->session_state=SSH_SESSION_STATE_ERROR; - ssh_set_error(session,SSH_FATAL,"%s",strerror(errno_code)); - } - session->ssh_connection_callback(session); -} - -/** - * @internal - * - * @brief Gets the banner from socket and saves it in session. - * Updates the session state - * - * @param data pointer to the beginning of header - * @param len size of the banner - * @param user is a pointer to session - * @returns Number of bytes processed, or zero if the banner is not complete. - */ -static int callback_receive_banner(const void *data, size_t len, void *user) { - char *buffer = (char *)data; - ssh_session session=(ssh_session) user; - char *str = NULL; - size_t i; - int ret=0; - - if(session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED){ - ssh_set_error(session,SSH_FATAL,"Wrong state in callback_receive_banner : %d",session->session_state); - - return SSH_ERROR; - } - for(i=0;ipcap_ctx && buffer[i] == '\n'){ - ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1); - } -#endif - if(buffer[i]=='\r') { - buffer[i]='\0'; - } - if (buffer[i]=='\n') { - buffer[i] = '\0'; - str = strdup(buffer); - if (str == NULL) { - return SSH_ERROR; - } - /* number of bytes read */ - ret = i + 1; - session->serverbanner = str; - session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED; - SSH_LOG(SSH_LOG_PACKET,"Received banner: %s",str); - session->ssh_connection_callback(session); - - return ret; - } - if(i>127){ - /* Too big banner */ - session->session_state=SSH_SESSION_STATE_ERROR; - ssh_set_error(session,SSH_FATAL,"Receiving banner: too large banner"); - - return 0; - } - } - - return ret; -} - -/** @internal - * @brief Sends a SSH banner to the server. - * - * @param session The SSH session to use. - * - * @param server Send client or server banner. - * - * @return 0 on success, < 0 on error. - */ -int ssh_send_banner(ssh_session session, int server) { - const char *banner = NULL; - char buffer[128] = {0}; - int err=SSH_ERROR; - - banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2; - - if (server) { - if(session->opts.custombanner == NULL){ - session->serverbanner = strdup(banner); - } else { - session->serverbanner = malloc(strlen(session->opts.custombanner) + 9); - if(!session->serverbanner) - goto end; - strcpy(session->serverbanner, "SSH-2.0-"); - strcat(session->serverbanner, session->opts.custombanner); - } - if (session->serverbanner == NULL) { - goto end; - } - snprintf(buffer, 128, "%s\n", session->serverbanner); - } else { - session->clientbanner = strdup(banner); - if (session->clientbanner == NULL) { - goto end; - } - snprintf(buffer, 128, "%s\n", session->clientbanner); - } - - if (ssh_socket_write(session->socket, buffer, strlen(buffer)) == SSH_ERROR) { - goto end; - } -#ifdef WITH_PCAP - if(session->pcap_ctx) - ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,buffer,strlen(buffer),strlen(buffer)); -#endif - err=SSH_OK; -end: - - return err; -} - -/** @internal - * @brief launches the DH handshake state machine - * @param session session handle - * @returns SSH_OK or SSH_ERROR - * @warning this function returning is no proof that DH handshake is - * completed - */ -static int dh_handshake(ssh_session session) { - - int rc = SSH_AGAIN; - - switch (session->dh_handshake_state) { - case DH_STATE_INIT: - switch(session->next_crypto->kex_type){ - case SSH_KEX_DH_GROUP1_SHA1: - case SSH_KEX_DH_GROUP14_SHA1: - rc = ssh_client_dh_init(session); - break; -#ifdef HAVE_ECDH - case SSH_KEX_ECDH_SHA2_NISTP256: - rc = ssh_client_ecdh_init(session); - break; -#endif -#ifdef HAVE_CURVE25519 - case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG: - rc = ssh_client_curve25519_init(session); - break; -#endif - default: - rc = SSH_ERROR; - } - - if (rc == SSH_ERROR) { - return SSH_ERROR; - } - - session->dh_handshake_state = DH_STATE_INIT_SENT; - case DH_STATE_INIT_SENT: - /* wait until ssh_packet_dh_reply is called */ - break; - case DH_STATE_NEWKEYS_SENT: - /* wait until ssh_packet_newkeys is called */ - break; - case DH_STATE_FINISHED: - return SSH_OK; - default: - ssh_set_error(session, SSH_FATAL, "Invalid state in dh_handshake(): %d", - session->dh_handshake_state); - - return SSH_ERROR; - } - - return rc; -} - -static int ssh_service_request_termination(void *s){ - ssh_session session = (ssh_session)s; - if(session->session_state == SSH_SESSION_STATE_ERROR || - session->auth_service_state != SSH_AUTH_SERVICE_SENT) - return 1; - else - return 0; -} - -/** - * @internal - * - * @brief Request a service from the SSH server. - * - * Service requests are for example: ssh-userauth, ssh-connection, etc. - * - * @param session The session to use to ask for a service request. - * @param service The service request. - * - * @return SSH_OK on success - * @return SSH_ERROR on error - * @return SSH_AGAIN No response received yet - * @bug actually only works with ssh-userauth - */ -int ssh_service_request(ssh_session session, const char *service) { - int rc=SSH_ERROR; - - if(session->auth_service_state != SSH_AUTH_SERVICE_NONE) - goto pending; - - rc = ssh_buffer_pack(session->out_buffer, - "bs", - SSH2_MSG_SERVICE_REQUEST, - service); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - session->auth_service_state=SSH_AUTH_SERVICE_SENT; - if (packet_send(session) == SSH_ERROR) { - ssh_set_error(session, SSH_FATAL, - "Sending SSH2_MSG_SERVICE_REQUEST failed."); - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PACKET, - "Sent SSH_MSG_SERVICE_REQUEST (service %s)", service); -pending: - rc=ssh_handle_packets_termination(session,SSH_TIMEOUT_USER, - ssh_service_request_termination, session); - if (rc == SSH_ERROR) { - return SSH_ERROR; - } - switch(session->auth_service_state){ - case SSH_AUTH_SERVICE_DENIED: - ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied"); - break; - case SSH_AUTH_SERVICE_ACCEPTED: - rc=SSH_OK; - break; - case SSH_AUTH_SERVICE_SENT: - rc=SSH_AGAIN; - break; - case SSH_AUTH_SERVICE_NONE: - case SSH_AUTH_SERVICE_USER_SENT: - /* Invalid state, SSH1 specific */ - rc=SSH_ERROR; - break; - } - - return rc; -} - -/** - * @addtogroup libssh_session - * - * @{ - */ - -/** - * @internal - * - * @brief A function to be called each time a step has been done in the - * connection. - */ -static void ssh_client_connection_callback(ssh_session session){ - int ssh1,ssh2; - - switch(session->session_state){ - case SSH_SESSION_STATE_NONE: - case SSH_SESSION_STATE_CONNECTING: - case SSH_SESSION_STATE_SOCKET_CONNECTED: - break; - case SSH_SESSION_STATE_BANNER_RECEIVED: - if (session->serverbanner == NULL) { - goto error; - } - set_status(session, 0.4f); - SSH_LOG(SSH_LOG_RARE, - "SSH server banner: %s", session->serverbanner); - - /* Here we analyze the different protocols the server allows. */ - if (ssh_analyze_banner(session, 0, &ssh1, &ssh2) < 0) { - goto error; - } - /* Here we decide which version of the protocol to use. */ - if (ssh2 && session->opts.ssh2) { - session->version = 2; -#ifdef WITH_SSH1 - } else if(ssh1 && session->opts.ssh1) { - session->version = 1; -#endif - } else if(ssh1 && !session->opts.ssh1){ -#ifdef WITH_SSH1 - ssh_set_error(session, SSH_FATAL, - "SSH-1 protocol not available (configure session to allow SSH-1)"); - goto error; -#else - ssh_set_error(session, SSH_FATAL, - "SSH-1 protocol not available (libssh compiled without SSH-1 support)"); - goto error; -#endif - } else { - ssh_set_error(session, SSH_FATAL, - "No version of SSH protocol usable (banner: %s)", - session->serverbanner); - goto error; - } - /* from now, the packet layer is handling incoming packets */ - if(session->version==2) - session->socket_callbacks.data=ssh_packet_socket_callback; -#ifdef WITH_SSH1 - else - session->socket_callbacks.data=ssh_packet_socket_callback1; -#endif - ssh_packet_set_default_callbacks(session); - session->session_state=SSH_SESSION_STATE_INITIAL_KEX; - ssh_send_banner(session, 0); - set_status(session, 0.5f); - break; - case SSH_SESSION_STATE_INITIAL_KEX: - /* TODO: This state should disappear in favor of get_key handle */ -#ifdef WITH_SSH1 - if(session->version==1){ - if (ssh_get_kex1(session) < 0) - goto error; - set_status(session,0.6f); - session->connected = 1; - break; - } -#endif - break; - case SSH_SESSION_STATE_KEXINIT_RECEIVED: - set_status(session,0.6f); - ssh_list_kex(&session->next_crypto->server_kex); - if (set_client_kex(session) < 0) { - goto error; - } - if (ssh_kex_select_methods(session) == SSH_ERROR) - goto error; - if (ssh_send_kex(session, 0) < 0) { - goto error; - } - set_status(session,0.8f); - session->session_state=SSH_SESSION_STATE_DH; - if (dh_handshake(session) == SSH_ERROR) { - goto error; - } - /* FALL THROUGH */ - case SSH_SESSION_STATE_DH: - if(session->dh_handshake_state==DH_STATE_FINISHED){ - set_status(session,1.0f); - session->connected = 1; - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) - session->session_state = SSH_SESSION_STATE_AUTHENTICATED; - else - session->session_state=SSH_SESSION_STATE_AUTHENTICATING; - } - break; - case SSH_SESSION_STATE_AUTHENTICATING: - break; - case SSH_SESSION_STATE_ERROR: - goto error; - default: - ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state); - } - - return; -error: - ssh_socket_close(session->socket); - session->alive = 0; - session->session_state=SSH_SESSION_STATE_ERROR; - -} - -/** @internal - * @brief describe under which conditions the ssh_connect function may stop - */ -static int ssh_connect_termination(void *user){ - ssh_session session = (ssh_session)user; - switch(session->session_state){ - case SSH_SESSION_STATE_ERROR: - case SSH_SESSION_STATE_AUTHENTICATING: - case SSH_SESSION_STATE_DISCONNECTED: - return 1; - default: - return 0; - } -} - -/** - * @brief Connect to the ssh server. - * - * @param[in] session The ssh session to connect. - * - * @returns SSH_OK on success, SSH_ERROR on error. - * @returns SSH_AGAIN, if the session is in nonblocking mode, - * and call must be done again. - * - * @see ssh_new() - * @see ssh_disconnect() - */ -int ssh_connect(ssh_session session) { - int ret; - - if (session == NULL) { - return SSH_ERROR; - } - - switch(session->pending_call_state){ - case SSH_PENDING_CALL_NONE: - break; - case SSH_PENDING_CALL_CONNECT: - goto pending; - default: - ssh_set_error(session,SSH_FATAL,"Bad call during pending SSH call in ssh_connect"); - - return SSH_ERROR; - } - session->alive = 0; - session->client = 1; - - if (ssh_init() < 0) { - return SSH_ERROR; - } - if (session->opts.fd == SSH_INVALID_SOCKET && - session->opts.host == NULL && - session->opts.ProxyCommand == NULL) { - ssh_set_error(session, SSH_FATAL, "Hostname required"); - return SSH_ERROR; - } - - ret = ssh_options_apply(session); - if (ret < 0) { - ssh_set_error(session, SSH_FATAL, "Couldn't apply options"); - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PROTOCOL, - "libssh %s, using threading %s", - ssh_copyright(), - ssh_threads_get_type()); - - session->ssh_connection_callback = ssh_client_connection_callback; - session->session_state=SSH_SESSION_STATE_CONNECTING; - ssh_socket_set_callbacks(session->socket,&session->socket_callbacks); - session->socket_callbacks.connected=socket_callback_connected; - session->socket_callbacks.data=callback_receive_banner; - session->socket_callbacks.exception=ssh_socket_exception_callback; - session->socket_callbacks.userdata=session; - if (session->opts.fd != SSH_INVALID_SOCKET) { - session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED; - ssh_socket_set_fd(session->socket, session->opts.fd); - ret=SSH_OK; -#ifndef _WIN32 - } else if (session->opts.ProxyCommand != NULL){ - ret = ssh_socket_connect_proxycommand(session->socket, - session->opts.ProxyCommand); -#endif - } else { - ret=ssh_socket_connect(session->socket, - session->opts.host, - session->opts.port, - session->opts.bindaddr); - } - if (ret == SSH_ERROR) { - return SSH_ERROR; - } - - set_status(session, 0.2f); - - session->alive = 1; - SSH_LOG(SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work"); -pending: - session->pending_call_state=SSH_PENDING_CALL_CONNECT; - if(ssh_is_blocking(session)) { - int timeout = (session->opts.timeout * 1000) + - (session->opts.timeout_usec / 1000); - if (timeout == 0) { - timeout = 10 * 1000; - } - SSH_LOG(SSH_LOG_PACKET,"Actual timeout : %d", timeout); - ret = ssh_handle_packets_termination(session, timeout, ssh_connect_termination, session); - if (session->session_state != SSH_SESSION_STATE_ERROR && - (ret == SSH_ERROR || !ssh_connect_termination(session))) { - ssh_set_error(session, SSH_FATAL, - "Timeout connecting to %s", session->opts.host); - session->session_state = SSH_SESSION_STATE_ERROR; - } - } - else { - ret = ssh_handle_packets_termination(session, - SSH_TIMEOUT_NONBLOCKING, - ssh_connect_termination, - session); - if (ret == SSH_ERROR) { - session->session_state = SSH_SESSION_STATE_ERROR; - } - } - SSH_LOG(SSH_LOG_PACKET,"current state : %d",session->session_state); - if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){ - return SSH_AGAIN; - } - - session->pending_call_state=SSH_PENDING_CALL_NONE; - if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED) - return SSH_ERROR; - return SSH_OK; -} - -/** - * @brief Get the issue banner from the server. - * - * This is the banner showing a disclaimer to users who log in, - * typically their right or the fact that they will be monitored. - * - * @param[in] session The SSH session to use. - * - * @return A newly allocated string with the banner, NULL on error. - */ -char *ssh_get_issue_banner(ssh_session session) { - if (session == NULL || session->banner == NULL) { - return NULL; - } - - return ssh_string_to_char(session->banner); -} - -/** - * @brief Get the version of the OpenSSH server, if it is not an OpenSSH server - * then 0 will be returned. - * - * You can use the SSH_VERSION_INT macro to compare version numbers. - * - * @param[in] session The SSH session to use. - * - * @return The version number if available, 0 otherwise. - * - * @code - * int openssh = ssh_get_openssh_version(); - * - * if (openssh == SSH_INT_VERSION(6, 1, 0)) { - * printf("Version match!\m"); - * } - * @endcode - */ -int ssh_get_openssh_version(ssh_session session) { - if (session == NULL) { - return 0; - } - - return session->openssh; -} - -/** - * @brief Disconnect from a session (client or server). - * The session can then be reused to open a new session. - * - * @param[in] session The SSH session to use. - */ -void ssh_disconnect(ssh_session session) { - struct ssh_iterator *it; - int rc; - - if (session == NULL) { - return; - } - - if (session->socket != NULL && ssh_socket_is_open(session->socket)) { - rc = ssh_buffer_pack(session->out_buffer, - "bds", - SSH2_MSG_DISCONNECT, - SSH2_DISCONNECT_BY_APPLICATION, - "Bye Bye"); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - goto error; - } - - packet_send(session); - ssh_socket_close(session->socket); - } -error: - session->alive = 0; - if (session->socket != NULL){ - ssh_socket_reset(session->socket); - } - session->opts.fd = SSH_INVALID_SOCKET; - session->session_state=SSH_SESSION_STATE_DISCONNECTED; - - while ((it=ssh_list_get_iterator(session->channels)) != NULL) { - ssh_channel_do_free(ssh_iterator_value(ssh_channel,it)); - ssh_list_remove(session->channels, it); - } - if(session->current_crypto){ - crypto_free(session->current_crypto); - session->current_crypto=NULL; - } - if (session->in_buffer) { - ssh_buffer_reinit(session->in_buffer); - } - if (session->out_buffer) { - ssh_buffer_reinit(session->out_buffer); - } - if (session->in_hashbuf) { - ssh_buffer_reinit(session->in_hashbuf); - } - if (session->out_hashbuf) { - ssh_buffer_reinit(session->out_hashbuf); - } - session->auth_methods = 0; - SAFE_FREE(session->serverbanner); - SAFE_FREE(session->clientbanner); - - if(session->ssh_message_list){ - ssh_message msg; - while((msg=ssh_list_pop_head(ssh_message ,session->ssh_message_list)) - != NULL){ - ssh_message_free(msg); - } - ssh_list_free(session->ssh_message_list); - session->ssh_message_list=NULL; - } - - if (session->packet_callbacks){ - ssh_list_free(session->packet_callbacks); - session->packet_callbacks=NULL; - } -} - -const char *ssh_copyright(void) { - return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2014 Aris Adamantiadis, Andreas Schneider, " - "and libssh contributors. Distributed under the LGPL, please refer to COPYING " - "file for information about your rights"; -} -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/config.c b/libssh/src/config.c deleted file mode 100644 index 4c966ed3..00000000 --- a/libssh/src/config.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * config.c - parse the ssh config file - * - * This file is part of the SSH Library - * - * Copyright (c) 2009-2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/misc.h" -#include "libssh/options.h" - -enum ssh_config_opcode_e { - SOC_UNSUPPORTED = -1, - SOC_HOST, - SOC_HOSTNAME, - SOC_PORT, - SOC_USERNAME, - SOC_IDENTITY, - SOC_CIPHERS, - SOC_COMPRESSION, - SOC_TIMEOUT, - SOC_PROTOCOL, - SOC_STRICTHOSTKEYCHECK, - SOC_KNOWNHOSTS, - SOC_PROXYCOMMAND, - SOC_GSSAPISERVERIDENTITY, - SOC_GSSAPICLIENTIDENTITY, - SOC_GSSAPIDELEGATECREDENTIALS, -}; - -struct ssh_config_keyword_table_s { - const char *name; - enum ssh_config_opcode_e opcode; -}; - -static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = { - { "host", SOC_HOST }, - { "hostname", SOC_HOSTNAME }, - { "port", SOC_PORT }, - { "user", SOC_USERNAME }, - { "identityfile", SOC_IDENTITY }, - { "ciphers", SOC_CIPHERS }, - { "compression", SOC_COMPRESSION }, - { "connecttimeout", SOC_TIMEOUT }, - { "protocol", SOC_PROTOCOL }, - { "stricthostkeychecking", SOC_STRICTHOSTKEYCHECK }, - { "userknownhostsfile", SOC_KNOWNHOSTS }, - { "proxycommand", SOC_PROXYCOMMAND }, - { "gssapiserveridentity", SOC_GSSAPISERVERIDENTITY }, - { "gssapiserveridentity", SOC_GSSAPICLIENTIDENTITY }, - { "gssapidelegatecredentials", SOC_GSSAPIDELEGATECREDENTIALS }, - { NULL, SOC_UNSUPPORTED } -}; - -static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) { - int i; - - for (i = 0; ssh_config_keyword_table[i].name != NULL; i++) { - if (strcasecmp(keyword, ssh_config_keyword_table[i].name) == 0) { - return ssh_config_keyword_table[i].opcode; - } - } - - return SOC_UNSUPPORTED; -} - -static char *ssh_config_get_cmd(char **str) { - register char *c; - char *r; - - /* Ignore leading spaces */ - for (c = *str; *c; c++) { - if (! isblank(*c)) { - break; - } - } - - if (*c == '\"') { - for (r = ++c; *c; c++) { - if (*c == '\"') { - *c = '\0'; - goto out; - } - } - } - - for (r = c; *c; c++) { - if (*c == '\n') { - *c = '\0'; - goto out; - } - } - -out: - *str = c + 1; - - return r; -} - -static char *ssh_config_get_token(char **str) { - register char *c; - char *r; - - c = ssh_config_get_cmd(str); - - for (r = c; *c; c++) { - if (isblank(*c)) { - *c = '\0'; - goto out; - } - } - -out: - *str = c + 1; - - return r; -} - -static int ssh_config_get_int(char **str, int notfound) { - char *p, *endp; - int i; - - p = ssh_config_get_token(str); - if (p && *p) { - i = strtol(p, &endp, 10); - if (p == endp) { - return notfound; - } - return i; - } - - return notfound; -} - -static const char *ssh_config_get_str_tok(char **str, const char *def) { - char *p; - - p = ssh_config_get_token(str); - if (p && *p) { - return p; - } - - return def; -} - -static int ssh_config_get_yesno(char **str, int notfound) { - const char *p; - - p = ssh_config_get_str_tok(str, NULL); - if (p == NULL) { - return notfound; - } - - if (strncasecmp(p, "yes", 3) == 0) { - return 1; - } else if (strncasecmp(p, "no", 2) == 0) { - return 0; - } - - return notfound; -} - -static int ssh_config_parse_line(ssh_session session, const char *line, - unsigned int count, int *parsing) { - enum ssh_config_opcode_e opcode; - const char *p; - char *s, *x; - char *keyword; - char *lowerhost; - size_t len; - int i; - - x = s = strdup(line); - if (s == NULL) { - ssh_set_error_oom(session); - return -1; - } - - /* Remove trailing spaces */ - for (len = strlen(s) - 1; len > 0; len--) { - if (! isspace(s[len])) { - break; - } - s[len] = '\0'; - } - - keyword = ssh_config_get_token(&s); - if (keyword == NULL || *keyword == '#' || - *keyword == '\0' || *keyword == '\n') { - SAFE_FREE(x); - return 0; - } - - opcode = ssh_config_get_opcode(keyword); - - switch (opcode) { - case SOC_HOST: - *parsing = 0; - lowerhost = (session->opts.host) ? ssh_lowercase(session->opts.host) : NULL; - for (p = ssh_config_get_str_tok(&s, NULL); - p != NULL && p[0] != '\0'; - p = ssh_config_get_str_tok(&s, NULL)) { - char *z = ssh_path_expand_escape(session, p); - int ok; - - if (z == NULL) { - z = strdup(p); - } - ok = match_hostname(lowerhost, z, strlen(z)); - if (ok) { - *parsing = 1; - } - free(z); - } - SAFE_FREE(lowerhost); - break; - case SOC_HOSTNAME: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_HOST, p); - } - break; - case SOC_PORT: - if (session->opts.port == 22) { - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_PORT_STR, p); - } - } - break; - case SOC_USERNAME: - if (session->opts.username == NULL) { - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_USER, p); - } - } - break; - case SOC_IDENTITY: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_ADD_IDENTITY, p); - } - break; - case SOC_CIPHERS: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, p); - ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, p); - } - break; - case SOC_COMPRESSION: - i = ssh_config_get_yesno(&s, -1); - if (i >= 0 && *parsing) { - if (i) { - ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "yes"); - } else { - ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "no"); - } - } - break; - case SOC_PROTOCOL: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - char *a, *b; - b = strdup(p); - if (b == NULL) { - SAFE_FREE(x); - ssh_set_error_oom(session); - return -1; - } - i = 0; - ssh_options_set(session, SSH_OPTIONS_SSH1, &i); - ssh_options_set(session, SSH_OPTIONS_SSH2, &i); - - for (a = strtok(b, ","); a; a = strtok(NULL, ",")) { - switch (atoi(a)) { - case 1: - i = 1; - ssh_options_set(session, SSH_OPTIONS_SSH1, &i); - break; - case 2: - i = 1; - ssh_options_set(session, SSH_OPTIONS_SSH2, &i); - break; - default: - break; - } - } - SAFE_FREE(b); - } - break; - case SOC_TIMEOUT: - i = ssh_config_get_int(&s, -1); - if (i >= 0 && *parsing) { - ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &i); - } - break; - case SOC_STRICTHOSTKEYCHECK: - i = ssh_config_get_yesno(&s, -1); - if (i >= 0 && *parsing) { - ssh_options_set(session, SSH_OPTIONS_STRICTHOSTKEYCHECK, &i); - } - break; - case SOC_KNOWNHOSTS: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, p); - } - break; - case SOC_PROXYCOMMAND: - p = ssh_config_get_cmd(&s); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, p); - } - break; - case SOC_GSSAPISERVERIDENTITY: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_GSSAPI_SERVER_IDENTITY, p); - } - break; - case SOC_GSSAPICLIENTIDENTITY: - p = ssh_config_get_str_tok(&s, NULL); - if (p && *parsing) { - ssh_options_set(session, SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY, p); - } - break; - case SOC_GSSAPIDELEGATECREDENTIALS: - i = ssh_config_get_yesno(&s, -1); - if (i >=0 && *parsing) { - ssh_options_set(session, SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS, &i); - } - break; - case SOC_UNSUPPORTED: - SSH_LOG(SSH_LOG_RARE, "Unsupported option: %s, line: %d\n", - keyword, count); - break; - default: - ssh_set_error(session, SSH_FATAL, "ERROR - unimplemented opcode: %d\n", - opcode); - SAFE_FREE(x); - return -1; - break; - } - - SAFE_FREE(x); - return 0; -} - -/* ssh_config_parse_file */ -int ssh_config_parse_file(ssh_session session, const char *filename) { - char line[1024] = {0}; - unsigned int count = 0; - FILE *f; - int parsing; - - if ((f = fopen(filename, "r")) == NULL) { - return 0; - } - - SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename); - - parsing = 1; - while (fgets(line, sizeof(line), f)) { - count++; - if (ssh_config_parse_line(session, line, count, &parsing) < 0) { - fclose(f); - return -1; - } - } - - fclose(f); - return 0; -} diff --git a/libssh/src/connect.c b/libssh/src/connect.c deleted file mode 100644 index 4ef85bc4..00000000 --- a/libssh/src/connect.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * connect.c - handles connections to ssh servers - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "libssh/libssh.h" -#include "libssh/misc.h" - -#ifdef _WIN32 -/* - * Only use Windows API functions available on Windows 2000 SP4 or later. - * The available constants are in . - * http://msdn.microsoft.com/en-us/library/aa383745.aspx - * http://blogs.msdn.com/oldnewthing/archive/2007/04/11/2079137.aspx - */ -#undef _WIN32_WINNT -#ifdef HAVE_WSPIAPI_H -#define _WIN32_WINNT 0x0500 /* _WIN32_WINNT_WIN2K */ -#undef NTDDI_VERSION -#define NTDDI_VERSION 0x05000400 /* NTDDI_WIN2KSP4 */ -#else -#define _WIN32_WINNT 0x0501 /* _WIN32_WINNT_WINXP */ -#undef NTDDI_VERSION -#define NTDDI_VERSION 0x05010000 /* NTDDI_WINXP */ -#endif - -#if _MSC_VER >= 1400 -#include -#undef close -#define close _close -#endif /* _MSC_VER */ -#include -#include - -/* is necessary for getaddrinfo before Windows XP, but it isn't - * available on some platforms like MinGW. */ -#ifdef HAVE_WSPIAPI_H -#include -#endif - -#else /* _WIN32 */ - -#include -#include -#include -#include - -#endif /* _WIN32 */ - -#include "libssh/priv.h" -#include "libssh/socket.h" -#include "libssh/channels.h" -#include "libssh/session.h" -#include "libssh/poll.h" - -#ifndef HAVE_GETADDRINFO -#error "Your system must have getaddrinfo()" -#endif - -#ifdef _WIN32 -#ifndef gai_strerror -char WSAAPI *gai_strerrorA(int code) { - static char buf[256]; - - snprintf(buf, sizeof(buf), "Undetermined error code (%d)", code); - - return buf; -} -#endif /* gai_strerror */ -#endif /* _WIN32 */ - -static int ssh_connect_socket_close(socket_t s){ -#ifdef _WIN32 - return closesocket(s); -#else - return close(s); -#endif -} - - -static int getai(const char *host, int port, struct addrinfo **ai) { - const char *service = NULL; - struct addrinfo hints; - char s_port[10]; - - ZERO_STRUCT(hints); - - hints.ai_protocol = IPPROTO_TCP; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if (port == 0) { - hints.ai_flags = AI_PASSIVE; - } else { - snprintf(s_port, sizeof(s_port), "%hu", (unsigned short)port); - service = s_port; -#ifdef AI_NUMERICSERV - hints.ai_flags=AI_NUMERICSERV; -#endif - } - - if (ssh_is_ipaddr(host)) { - /* this is an IP address */ - SSH_LOG(SSH_LOG_PACKET,"host %s matches an IP address",host); - hints.ai_flags |= AI_NUMERICHOST; - } - - return getaddrinfo(host, service, &hints, ai); -} - -static int ssh_connect_ai_timeout(ssh_session session, const char *host, - int port, struct addrinfo *ai, long timeout, long usec, socket_t s) { - int timeout_ms; - ssh_pollfd_t fds; - int rc = 0; - int ret; - socklen_t len = sizeof(rc); - - /* I know we're losing some precision. But it's not like poll-like family - * type of mechanisms are precise up to the microsecond. - */ - timeout_ms=timeout * 1000 + usec / 1000; - - rc = ssh_socket_set_nonblocking(s); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to set socket non-blocking for %s:%d", host, port); - ssh_connect_socket_close(s); - return -1; - } - - SSH_LOG(SSH_LOG_RARE, "Trying to connect to host: %s:%d with " - "timeout %d ms", host, port, timeout_ms); - - /* The return value is checked later */ - connect(s, ai->ai_addr, ai->ai_addrlen); - freeaddrinfo(ai); - - fds.fd=s; - fds.revents=0; - fds.events=POLLOUT; -#ifdef _WIN32 - fds.events |= POLLWRNORM; -#endif - rc = ssh_poll(&fds,1,timeout_ms); - - if (rc == 0) { - /* timeout */ - ssh_set_error(session, SSH_FATAL, - "Timeout while connecting to %s:%d", host, port); - ssh_connect_socket_close(s); - - return -1; - } - - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, - "poll error: %s", strerror(errno)); - ssh_connect_socket_close(s); - - return -1; - } - rc = -1; - - /* Get connect(2) return code. Zero means no error */ - ret = getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len); - if (ret < 0 || rc != 0) { - ssh_set_error(session, SSH_FATAL, - "Connect to %s:%d failed: %s", host, port, strerror(rc)); - ssh_connect_socket_close(s); - - return -1; - } - - /* s is connected ? */ - SSH_LOG(SSH_LOG_PACKET, "Socket connected with timeout\n"); - ret = ssh_socket_set_blocking(s); - if (ret < 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to set socket as blocking connecting to %s:%d failed: %s", - host, port, strerror(errno)); - ssh_connect_socket_close(s); - return -1; - } - - return s; -} - -/** - * @internal - * - * @brief Connect to an IPv4 or IPv6 host specified by its IP address or - * hostname. - * - * @returns A file descriptor, < 0 on error. - */ -socket_t ssh_connect_host(ssh_session session, const char *host, - const char *bind_addr, int port, long timeout, long usec) { - socket_t s = -1; - int rc; - struct addrinfo *ai; - struct addrinfo *itr; - - rc = getai(host, port, &ai); - if (rc != 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to resolve hostname %s (%s)", host, gai_strerror(rc)); - - return -1; - } - - for (itr = ai; itr != NULL; itr = itr->ai_next){ - /* create socket */ - s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol); - if (s < 0) { - ssh_set_error(session, SSH_FATAL, - "Socket create failed: %s", strerror(errno)); - continue; - } - - if (bind_addr) { - struct addrinfo *bind_ai; - struct addrinfo *bind_itr; - - SSH_LOG(SSH_LOG_PACKET, "Resolving %s\n", bind_addr); - - rc = getai(bind_addr, 0, &bind_ai); - if (rc != 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to resolve bind address %s (%s)", - bind_addr, - gai_strerror(rc)); - freeaddrinfo(ai); - close(s); - - return -1; - } - - for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) { - if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) { - ssh_set_error(session, SSH_FATAL, - "Binding local address: %s", strerror(errno)); - continue; - } else { - break; - } - } - freeaddrinfo(bind_ai); - - /* Cannot bind to any local addresses */ - if (bind_itr == NULL) { - ssh_connect_socket_close(s); - s = -1; - continue; - } - } - - if (timeout || usec) { - socket_t ret = ssh_connect_ai_timeout(session, host, port, itr, - timeout, usec, s); - - return ret; - } - - if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) { - ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno)); - ssh_connect_socket_close(s); - s = -1; - continue; - } else { - /* We are connected */ - break; - } - } - - freeaddrinfo(ai); - - return s; -} - -/** - * @internal - * - * @brief Launches a nonblocking connect to an IPv4 or IPv6 host - * specified by its IP address or hostname. - * - * @returns A file descriptor, < 0 on error. - * @warning very ugly !!! - */ -socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host, - const char *bind_addr, int port) { - socket_t s = -1; - int rc; - struct addrinfo *ai; - struct addrinfo *itr; - - rc = getai(host, port, &ai); - if (rc != 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to resolve hostname %s (%s)", host, gai_strerror(rc)); - - return -1; - } - - for (itr = ai; itr != NULL; itr = itr->ai_next){ - /* create socket */ - s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol); - if (s < 0) { - ssh_set_error(session, SSH_FATAL, - "Socket create failed: %s", strerror(errno)); - continue; - } - - if (bind_addr) { - struct addrinfo *bind_ai; - struct addrinfo *bind_itr; - - SSH_LOG(SSH_LOG_PACKET, "Resolving %s\n", bind_addr); - - rc = getai(bind_addr, 0, &bind_ai); - if (rc != 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to resolve bind address %s (%s)", - bind_addr, - gai_strerror(rc)); - ssh_connect_socket_close(s); - s=-1; - break; - } - - for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) { - if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) { - ssh_set_error(session, SSH_FATAL, - "Binding local address: %s", strerror(errno)); - continue; - } else { - break; - } - } - freeaddrinfo(bind_ai); - - /* Cannot bind to any local addresses */ - if (bind_itr == NULL) { - ssh_connect_socket_close(s); - s = -1; - continue; - } - } - - rc = ssh_socket_set_nonblocking(s); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, - "Failed to set socket non-blocking for %s:%d", host, port); - ssh_connect_socket_close(s); - s = -1; - continue; - } - - rc = connect(s, itr->ai_addr, itr->ai_addrlen); - if (rc == -1 && (errno != EINPROGRESS)) { - ssh_set_error(session, SSH_FATAL, - "Failed to connect: %s", strerror(errno)); - ssh_connect_socket_close(s); - s = -1; - continue; - } - - break; - } - - freeaddrinfo(ai); - - return s; -} - -/** - * @addtogroup libssh_session - * - * @{ - */ - -static int ssh_select_cb (socket_t fd, int revents, void *userdata){ - fd_set *set = (fd_set *)userdata; - if(revents & POLLIN) - FD_SET(fd, set); - return 0; -} - -/** - * @brief A wrapper for the select syscall - * - * This functions acts more or less like the select(2) syscall.\n - * There is no support for writing or exceptions.\n - * - * @param[in] channels Arrays of channels pointers terminated by a NULL. - * It is never rewritten. - * - * @param[out] outchannels Arrays of same size that "channels", there is no need - * to initialize it. - * - * @param[in] maxfd Maximum +1 file descriptor from readfds. - * - * @param[in] readfds A fd_set of file descriptors to be select'ed for - * reading. - * - * @param[in] timeout The timeout in milliseconds. - * - * @return SSH_OK on success, - * SSH_ERROR on error, - * SSH_EINTR if it was interrupted. In that case, - * just restart it. - * - * @warning libssh is not reentrant here. That means that if a signal is caught - * during the processing of this function, you cannot call libssh - * functions on sessions that are busy with ssh_select(). - * - * @see select(2) - */ -int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd, - fd_set *readfds, struct timeval *timeout) { - fd_set origfds; - socket_t fd; - int i,j; - int rc; - int base_tm, tm; - struct ssh_timestamp ts; - ssh_event event = ssh_event_new(); - int firstround=1; - - base_tm = tm=timeout->tv_sec * 1000 + timeout->tv_usec/1000; - for (i=0 ; channels[i] != NULL; ++i){ - ssh_event_add_session(event, channels[i]->session); - } - - FD_ZERO(&origfds); - for (fd = 0; fd < maxfd ; fd++) { - if (FD_ISSET(fd, readfds)) { - ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds); - FD_SET(fd, &origfds); - } - } - outchannels[0] = NULL; - FD_ZERO(readfds); - ssh_timestamp_init(&ts); - do { - /* Poll every channel */ - j = 0; - for (i = 0; channels[i]; i++) { - if(ssh_channel_poll(channels[i], 0) != 0) { - outchannels[j] = channels[i]; - j++; - } else if(ssh_channel_poll(channels[i], 1) != 0) { - outchannels[j] = channels[i]; - j++; - } - } - outchannels[j] = NULL; - if(j != 0) - break; - /* watch if a user socket was triggered */ - for (fd = 0; fd < maxfd; fd++) { - if (FD_ISSET(fd, readfds)) { - goto out; - } - } - - /* If the timeout is elapsed, we should go out */ - if(!firstround && ssh_timeout_elapsed(&ts, base_tm)) - goto out; - /* since there's nothing, let's fire the polling */ - rc = ssh_event_dopoll(event,tm); - if (rc == SSH_ERROR){ - goto out; - } - tm = ssh_timeout_update(&ts, base_tm); - firstround=0; - } while (1); -out: - for (fd = 0; fd < maxfd; fd++) { - if (FD_ISSET(fd, &origfds)) { - ssh_event_remove_fd(event, fd); - } - } - ssh_event_free(event); - return SSH_OK; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/crc32.c b/libssh/src/crc32.c deleted file mode 100644 index cb4e931d..00000000 --- a/libssh/src/crc32.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * crc32.c - simple CRC32 code - * - * This file is part of the SSH Library - * - * Copyright (c) 2005 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include "libssh/priv.h" -#include "libssh/crc32.h" - -static uint32_t crc_table[] = { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -}; - -uint32_t ssh_crc32(const char *buf, uint32_t len) { - uint32_t ret = 0; - while(len > 0) { - ret = crc_table[(ret ^ *buf) & 0xff] ^ (ret >> 8); - --len; - ++buf; - } - - return ret; -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/curve25519.c b/libssh/src/curve25519.c deleted file mode 100644 index 99d7145b..00000000 --- a/libssh/src/curve25519.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * curve25519.c - Curve25519 ECDH functions for key exchange - * curve25519-sha256@libssh.org - * - * This file is part of the SSH Library - * - * Copyright (c) 2013 by Aris Adamantiadis - * - * The SSH 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, version 2.1 of the License. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include "libssh/curve25519.h" -#ifdef HAVE_CURVE25519 - -#ifdef WITH_NACL -#include "nacl/crypto_scalarmult_curve25519.h" -#endif - -#include "libssh/ssh2.h" -#include "libssh/buffer.h" -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/crypto.h" -#include "libssh/dh.h" -#include "libssh/pki.h" -#include "libssh/bignum.h" - -/** @internal - * @brief Starts curve25519-sha256@libssh.org key exchange - */ -int ssh_client_curve25519_init(ssh_session session){ - int rc; - - rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1); - if (rc == 0){ - ssh_set_error(session, SSH_FATAL, "PRNG error"); - return SSH_ERROR; - } - - crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey, - session->next_crypto->curve25519_privkey); - - rc = ssh_buffer_pack(session->out_buffer, - "bdP", - SSH2_MSG_KEX_ECDH_INIT, - CURVE25519_PUBKEY_SIZE, - (size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - - rc = packet_send(session); - - return rc; -} - -static int ssh_curve25519_build_k(ssh_session session) { - ssh_curve25519_pubkey k; - session->next_crypto->k = bignum_new(); - - if (session->next_crypto->k == NULL) { - return SSH_ERROR; - } - - if (session->server) - crypto_scalarmult(k, session->next_crypto->curve25519_privkey, - session->next_crypto->curve25519_client_pubkey); - else - crypto_scalarmult(k, session->next_crypto->curve25519_privkey, - session->next_crypto->curve25519_server_pubkey); - - bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Session server cookie", - session->next_crypto->server_kex.cookie, 16); - ssh_print_hexa("Session client cookie", - session->next_crypto->client_kex.cookie, 16); - ssh_print_bignum("Shared secret key", session->next_crypto->k); -#endif - - return 0; -} - -/** @internal - * @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back - * a SSH_MSG_NEWKEYS - */ -int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){ - ssh_string q_s_string = NULL; - ssh_string pubkey = NULL; - ssh_string signature = NULL; - int rc; - pubkey = buffer_get_ssh_string(packet); - if (pubkey == NULL){ - ssh_set_error(session,SSH_FATAL, "No public key in packet"); - goto error; - } - /* this is the server host key */ - session->next_crypto->server_pubkey = pubkey; - pubkey = NULL; - - q_s_string = buffer_get_ssh_string(packet); - if (q_s_string == NULL) { - ssh_set_error(session,SSH_FATAL, "No Q_S ECC point in packet"); - goto error; - } - if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){ - ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d", - (int)ssh_string_len(q_s_string)); - ssh_string_free(q_s_string); - goto error; - } - memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE); - ssh_string_free(q_s_string); - - signature = buffer_get_ssh_string(packet); - if (signature == NULL) { - ssh_set_error(session, SSH_FATAL, "No signature in packet"); - goto error; - } - session->next_crypto->dh_server_signature = signature; - signature=NULL; /* ownership changed */ - /* TODO: verify signature now instead of waiting for NEWKEYS */ - if (ssh_curve25519_build_k(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot build k number"); - goto error; - } - - /* Send the MSG_NEWKEYS */ - if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { - goto error; - } - - rc=packet_send(session); - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - return rc; -error: - return SSH_ERROR; -} - -#ifdef WITH_SERVER - -/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a - * SSH_MSG_KEXDH_REPLY - */ -int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){ - /* ECDH keys */ - ssh_string q_c_string; - ssh_string q_s_string; - - /* SSH host keys (rsa,dsa,ecdsa) */ - ssh_key privkey; - ssh_string sig_blob = NULL; - int rc; - - /* Extract the client pubkey from the init packet */ - q_c_string = buffer_get_ssh_string(packet); - if (q_c_string == NULL) { - ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet"); - return SSH_ERROR; - } - if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){ - ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d", - (int)ssh_string_len(q_c_string)); - ssh_string_free(q_c_string); - return SSH_ERROR; - } - - memcpy(session->next_crypto->curve25519_client_pubkey, - ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE); - ssh_string_free(q_c_string); - /* Build server's keypair */ - - rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1); - if (rc == 0){ - ssh_set_error(session, SSH_FATAL, "PRNG error"); - return SSH_ERROR; - } - - crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey, - session->next_crypto->curve25519_privkey); - - rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY); - if (rc < 0) { - ssh_set_error_oom(session); - goto error; - } - - /* build k and session_id */ - rc = ssh_curve25519_build_k(session); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot build k number"); - goto error; - } - - /* privkey is not allocated */ - rc = ssh_get_key_params(session, &privkey); - if (rc == SSH_ERROR) { - goto error; - } - - rc = make_sessionid(session); - if (rc != SSH_OK) { - ssh_set_error(session, SSH_FATAL, "Could not create a session id"); - goto error; - } - - /* add host's public key */ - rc = buffer_add_ssh_string(session->out_buffer, - session->next_crypto->server_pubkey); - if (rc < 0) { - ssh_set_error_oom(session); - goto error; - } - - /* add ecdh public key */ - q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE); - if (q_s_string == NULL) { - goto error; - } - - ssh_string_fill(q_s_string, - session->next_crypto->curve25519_server_pubkey, - CURVE25519_PUBKEY_SIZE); - - rc = buffer_add_ssh_string(session->out_buffer, q_s_string); - ssh_string_free(q_s_string); - if (rc < 0) { - ssh_set_error_oom(session); - goto error; - } - /* add signature blob */ - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); - if (sig_blob == NULL) { - ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); - goto error; - } - - rc = buffer_add_ssh_string(session->out_buffer, sig_blob); - ssh_string_free(sig_blob); - if (rc < 0) { - ssh_set_error_oom(session); - goto error; - } - - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_ECDH_REPLY sent"); - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_ERROR; - } - - /* Send the MSG_NEWKEYS */ - rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); - if (rc < 0) { - goto error; - } - - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - rc = packet_send(session); - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - - return rc; -error: - ssh_buffer_reinit(session->out_buffer); - return SSH_ERROR; -} - -#endif /* WITH_SERVER */ - -#endif /* HAVE_CURVE25519 */ diff --git a/libssh/src/curve25519_ref.c b/libssh/src/curve25519_ref.c deleted file mode 100644 index aa4cfa2b..00000000 --- a/libssh/src/curve25519_ref.c +++ /dev/null @@ -1,272 +0,0 @@ -/* -version 20081011 -Matthew Dempsky -Public domain. -Derived from public domain code by D. J. Bernstein. -*/ - -#include "libssh/curve25519.h" -static const unsigned char base[32] = {9}; - -int crypto_scalarmult_base(unsigned char *q, - const unsigned char *n) -{ - return crypto_scalarmult(q,n,base); -} - -static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) -{ - unsigned int j; - unsigned int u; - u = 0; - for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; } - u += a[31] + b[31]; out[31] = u; -} - -static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) -{ - unsigned int j; - unsigned int u; - u = 218; - for (j = 0;j < 31;++j) { - u += a[j] + 65280 - b[j]; - out[j] = u & 255; - u >>= 8; - } - u += a[31] - b[31]; - out[31] = u; -} - -static void squeeze(unsigned int a[32]) -{ - unsigned int j; - unsigned int u; - u = 0; - for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } - u += a[31]; a[31] = u & 127; - u = 19 * (u >> 7); - for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } - u += a[31]; a[31] = u; -} - -static const unsigned int minusp[32] = { - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 -} ; - -static void freeze(unsigned int a[32]) -{ - unsigned int aorig[32]; - unsigned int j; - unsigned int negative; - - for (j = 0;j < 32;++j) aorig[j] = a[j]; - add(a,a,minusp); - negative = -((a[31] >> 7) & 1); - for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]); -} - -static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) -{ - unsigned int i; - unsigned int j; - unsigned int u; - - for (i = 0;i < 32;++i) { - u = 0; - for (j = 0;j <= i;++j) u += a[j] * b[i - j]; - for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j]; - out[i] = u; - } - squeeze(out); -} - -static void mult121665(unsigned int out[32],const unsigned int a[32]) -{ - unsigned int j; - unsigned int u; - - u = 0; - for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; } - u += 121665 * a[31]; out[31] = u & 127; - u = 19 * (u >> 7); - for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; } - u += out[j]; out[j] = u; -} - -static void square(unsigned int out[32],const unsigned int a[32]) -{ - unsigned int i; - unsigned int j; - unsigned int u; - - for (i = 0;i < 32;++i) { - u = 0; - for (j = 0;j < i - j;++j) u += a[j] * a[i - j]; - for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j]; - u *= 2; - if ((i & 1) == 0) { - u += a[i / 2] * a[i / 2]; - u += 38 * a[i / 2 + 16] * a[i / 2 + 16]; - } - out[i] = u; - } - squeeze(out); -} - -static void c_select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b) -{ - unsigned int j; - unsigned int t; - unsigned int bminus1; - - bminus1 = b - 1; - for (j = 0;j < 64;++j) { - t = bminus1 & (r[j] ^ s[j]); - p[j] = s[j] ^ t; - q[j] = r[j] ^ t; - } -} - -static void mainloop(unsigned int work[64],const unsigned char e[32]) -{ - unsigned int xzm1[64]; - unsigned int xzm[64]; - unsigned int xzmb[64]; - unsigned int xzm1b[64]; - unsigned int xznb[64]; - unsigned int xzn1b[64]; - unsigned int a0[64]; - unsigned int a1[64]; - unsigned int b0[64]; - unsigned int b1[64]; - unsigned int c1[64]; - unsigned int r[32]; - unsigned int s[32]; - unsigned int t[32]; - unsigned int u[32]; - unsigned int j; - unsigned int b; - int pos; - - for (j = 0;j < 32;++j) xzm1[j] = work[j]; - xzm1[32] = 1; - for (j = 33;j < 64;++j) xzm1[j] = 0; - - xzm[0] = 1; - for (j = 1;j < 64;++j) xzm[j] = 0; - - for (pos = 254;pos >= 0;--pos) { - b = e[pos / 8] >> (pos & 7); - b &= 1; - c_select(xzmb,xzm1b,xzm,xzm1,b); - add(a0,xzmb,xzmb + 32); - sub(a0 + 32,xzmb,xzmb + 32); - add(a1,xzm1b,xzm1b + 32); - sub(a1 + 32,xzm1b,xzm1b + 32); - square(b0,a0); - square(b0 + 32,a0 + 32); - mult(b1,a1,a0 + 32); - mult(b1 + 32,a1 + 32,a0); - add(c1,b1,b1 + 32); - sub(c1 + 32,b1,b1 + 32); - square(r,c1 + 32); - sub(s,b0,b0 + 32); - mult121665(t,s); - add(u,t,b0); - mult(xznb,b0,b0 + 32); - mult(xznb + 32,s,u); - square(xzn1b,c1); - mult(xzn1b + 32,r,work); - c_select(xzm,xzm1,xznb,xzn1b,b); - } - - for (j = 0;j < 64;++j) work[j] = xzm[j]; -} - -static void recip(unsigned int out[32],const unsigned int z[32]) -{ - unsigned int z2[32]; - unsigned int z9[32]; - unsigned int z11[32]; - unsigned int z2_5_0[32]; - unsigned int z2_10_0[32]; - unsigned int z2_20_0[32]; - unsigned int z2_50_0[32]; - unsigned int z2_100_0[32]; - unsigned int t0[32]; - unsigned int t1[32]; - int i; - - /* 2 */ square(z2,z); - /* 4 */ square(t1,z2); - /* 8 */ square(t0,t1); - /* 9 */ mult(z9,t0,z); - /* 11 */ mult(z11,z9,z2); - /* 22 */ square(t0,z11); - /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9); - - /* 2^6 - 2^1 */ square(t0,z2_5_0); - /* 2^7 - 2^2 */ square(t1,t0); - /* 2^8 - 2^3 */ square(t0,t1); - /* 2^9 - 2^4 */ square(t1,t0); - /* 2^10 - 2^5 */ square(t0,t1); - /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0); - - /* 2^11 - 2^1 */ square(t0,z2_10_0); - /* 2^12 - 2^2 */ square(t1,t0); - /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0); - - /* 2^21 - 2^1 */ square(t0,z2_20_0); - /* 2^22 - 2^2 */ square(t1,t0); - /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0); - - /* 2^41 - 2^1 */ square(t1,t0); - /* 2^42 - 2^2 */ square(t0,t1); - /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); } - /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0); - - /* 2^51 - 2^1 */ square(t0,z2_50_0); - /* 2^52 - 2^2 */ square(t1,t0); - /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0); - - /* 2^101 - 2^1 */ square(t1,z2_100_0); - /* 2^102 - 2^2 */ square(t0,t1); - /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); } - /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0); - - /* 2^201 - 2^1 */ square(t0,t1); - /* 2^202 - 2^2 */ square(t1,t0); - /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } - /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0); - - /* 2^251 - 2^1 */ square(t1,t0); - /* 2^252 - 2^2 */ square(t0,t1); - /* 2^253 - 2^3 */ square(t1,t0); - /* 2^254 - 2^4 */ square(t0,t1); - /* 2^255 - 2^5 */ square(t1,t0); - /* 2^255 - 21 */ mult(out,t1,z11); -} - -int crypto_scalarmult(unsigned char *q, - const unsigned char *n, - const unsigned char *p) -{ - unsigned int work[96]; - unsigned char e[32]; - unsigned int i; - for (i = 0;i < 32;++i) e[i] = n[i]; - e[0] &= 248; - e[31] &= 127; - e[31] |= 64; - for (i = 0;i < 32;++i) work[i] = p[i]; - mainloop(work,e); - recip(work + 32,work + 32); - mult(work + 64,work,work + 32); - freeze(work + 64); - for (i = 0;i < 32;++i) q[i] = work[64 + i]; - return 0; -} - diff --git a/libssh/src/dh.c b/libssh/src/dh.c deleted file mode 100644 index e489a1d5..00000000 --- a/libssh/src/dh.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * dh.c - Diffie-Helman algorithm code against SSH 2 - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * Copyright (c) 2009-2013 by Andreas Schneider - * Copyright (c) 2012 by Dmitriy Kuznetsov - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* - * Let us resume the dh protocol. - * Each side computes a private prime number, x at client side, y at server - * side. - * g and n are two numbers common to every ssh software. - * client's public key (e) is calculated by doing: - * e = g^x mod p - * client sends e to the server. - * the server computes his own public key, f - * f = g^y mod p - * it sends it to the client - * the common key K is calculated by the client by doing - * k = f^x mod p - * the server does the same with the client public key e - * k' = e^y mod p - * if everything went correctly, k and k' are equal - */ - -#include "config.h" -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/crypto.h" -#include "libssh/buffer.h" -#include "libssh/session.h" -#include "libssh/misc.h" -#include "libssh/dh.h" -#include "libssh/ssh2.h" -#include "libssh/pki.h" -#include "libssh/bignum.h" - -/* todo: remove it */ -#include "libssh/string.h" -#ifdef HAVE_LIBCRYPTO -#include -#include -#include -#endif - -static unsigned char p_group1_value[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, - 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, - 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, - 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, - 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, - 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; -#define P_GROUP1_LEN 128 /* Size in bytes of the p number */ - - -static unsigned char p_group14_value[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, - 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, - 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, - 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, - 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, - 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, - 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, - 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, - 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, - 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, - 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF}; - -#define P_GROUP14_LEN 256 /* Size in bytes of the p number for group 14 */ - -static unsigned long g_int = 2 ; /* G is defined as 2 by the ssh2 standards */ -static bignum g; -static bignum p_group1; -static bignum p_group14; -static int ssh_crypto_initialized; - -static bignum select_p(enum ssh_key_exchange_e type) { - return type == SSH_KEX_DH_GROUP14_SHA1 ? p_group14 : p_group1; -} - -int ssh_get_random(void *where, int len, int strong){ - -#ifdef HAVE_LIBGCRYPT - /* variable not used in gcrypt */ - (void) strong; - /* not using GCRY_VERY_STRONG_RANDOM which is a bit overkill */ - gcry_randomize(where,len,GCRY_STRONG_RANDOM); - - return 1; -#elif defined HAVE_LIBCRYPTO - if (strong) { - return RAND_bytes(where,len); - } else { - return RAND_pseudo_bytes(where,len); - } -#endif - - /* never reached */ - return 1; -} - - -/* - * This inits the values g and p which are used for DH key agreement - * FIXME: Make the function thread safe by adding a semaphore or mutex. - */ -int ssh_crypto_init(void) { - if (ssh_crypto_initialized == 0) { -#ifdef HAVE_LIBGCRYPT - gcry_check_version(NULL); - if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) { - gcry_control(GCRYCTL_INIT_SECMEM, 4096); - gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0); - } -#endif - - g = bignum_new(); - if (g == NULL) { - return -1; - } - bignum_set_word(g,g_int); - -#ifdef HAVE_LIBGCRYPT - bignum_bin2bn(p_group1_value, P_GROUP1_LEN, &p_group1); - if (p_group1 == NULL) { - bignum_free(g); - g = NULL; - return -1; - } - bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &p_group14); - if (p_group14 == NULL) { - bignum_free(g); - bignum_free(p_group1); - g = NULL; - p_group1 = NULL; - return -1; - } - -#elif defined HAVE_LIBCRYPTO - p_group1 = bignum_new(); - if (p_group1 == NULL) { - bignum_free(g); - g = NULL; - return -1; - } - bignum_bin2bn(p_group1_value, P_GROUP1_LEN, p_group1); - - p_group14 = bignum_new(); - if (p_group14 == NULL) { - bignum_free(g); - bignum_free(p_group1); - g = NULL; - p_group1 = NULL; - return -1; - } - bignum_bin2bn(p_group14_value, P_GROUP14_LEN, p_group14); - - OpenSSL_add_all_algorithms(); - -#endif - - ssh_crypto_initialized = 1; - } - - return 0; -} - -void ssh_crypto_finalize(void) { - if (ssh_crypto_initialized) { - bignum_free(g); - g = NULL; - bignum_free(p_group1); - p_group1 = NULL; - bignum_free(p_group14); - p_group14 = NULL; -#ifdef HAVE_LIBGCRYPT - gcry_control(GCRYCTL_TERM_SECMEM); -#elif defined HAVE_LIBCRYPTO - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); -#endif - ssh_crypto_initialized=0; - } -} - -int dh_generate_x(ssh_session session) { - session->next_crypto->x = bignum_new(); - if (session->next_crypto->x == NULL) { - return -1; - } - -#ifdef HAVE_LIBGCRYPT - bignum_rand(session->next_crypto->x, 128); -#elif defined HAVE_LIBCRYPTO - bignum_rand(session->next_crypto->x, 128, 0, -1); -#endif - - /* not harder than this */ -#ifdef DEBUG_CRYPTO - ssh_print_bignum("x", session->next_crypto->x); -#endif - - return 0; -} - -/* used by server */ -int dh_generate_y(ssh_session session) { - session->next_crypto->y = bignum_new(); - if (session->next_crypto->y == NULL) { - return -1; - } - -#ifdef HAVE_LIBGCRYPT - bignum_rand(session->next_crypto->y, 128); -#elif defined HAVE_LIBCRYPTO - bignum_rand(session->next_crypto->y, 128, 0, -1); -#endif - - /* not harder than this */ -#ifdef DEBUG_CRYPTO - ssh_print_bignum("y", session->next_crypto->y); -#endif - - return 0; -} - -/* used by server */ -int dh_generate_e(ssh_session session) { -#ifdef HAVE_LIBCRYPTO - bignum_CTX ctx = bignum_ctx_new(); - if (ctx == NULL) { - return -1; - } -#endif - - session->next_crypto->e = bignum_new(); - if (session->next_crypto->e == NULL) { -#ifdef HAVE_LIBCRYPTO - bignum_ctx_free(ctx); -#endif - return -1; - } - -#ifdef HAVE_LIBGCRYPT - bignum_mod_exp(session->next_crypto->e, g, session->next_crypto->x, - select_p(session->next_crypto->kex_type)); -#elif defined HAVE_LIBCRYPTO - bignum_mod_exp(session->next_crypto->e, g, session->next_crypto->x, - select_p(session->next_crypto->kex_type), ctx); -#endif - -#ifdef DEBUG_CRYPTO - ssh_print_bignum("e", session->next_crypto->e); -#endif - -#ifdef HAVE_LIBCRYPTO - bignum_ctx_free(ctx); -#endif - - return 0; -} - -int dh_generate_f(ssh_session session) { -#ifdef HAVE_LIBCRYPTO - bignum_CTX ctx = bignum_ctx_new(); - if (ctx == NULL) { - return -1; - } -#endif - - session->next_crypto->f = bignum_new(); - if (session->next_crypto->f == NULL) { -#ifdef HAVE_LIBCRYPTO - bignum_ctx_free(ctx); -#endif - return -1; - } - -#ifdef HAVE_LIBGCRYPT - bignum_mod_exp(session->next_crypto->f, g, session->next_crypto->y, - select_p(session->next_crypto->kex_type)); -#elif defined HAVE_LIBCRYPTO - bignum_mod_exp(session->next_crypto->f, g, session->next_crypto->y, - select_p(session->next_crypto->kex_type), ctx); -#endif - -#ifdef DEBUG_CRYPTO - ssh_print_bignum("f", session->next_crypto->f); -#endif - -#ifdef HAVE_LIBCRYPTO - bignum_ctx_free(ctx); -#endif - - return 0; -} - -ssh_string dh_get_e(ssh_session session) { - return make_bignum_string(session->next_crypto->e); -} - -/* used by server */ -ssh_string dh_get_f(ssh_session session) { - return make_bignum_string(session->next_crypto->f); -} - -void dh_import_pubkey(ssh_session session, ssh_string pubkey_string) { - session->next_crypto->server_pubkey = pubkey_string; -} - -int dh_import_f(ssh_session session, ssh_string f_string) { - session->next_crypto->f = make_string_bn(f_string); - if (session->next_crypto->f == NULL) { - return -1; - } - -#ifdef DEBUG_CRYPTO - ssh_print_bignum("f",session->next_crypto->f); -#endif - - return 0; -} - -/* used by the server implementation */ -int dh_import_e(ssh_session session, ssh_string e_string) { - session->next_crypto->e = make_string_bn(e_string); - if (session->next_crypto->e == NULL) { - return -1; - } - -#ifdef DEBUG_CRYPTO - ssh_print_bignum("e",session->next_crypto->e); -#endif - - return 0; -} - -int dh_build_k(ssh_session session) { -#ifdef HAVE_LIBCRYPTO - bignum_CTX ctx = bignum_ctx_new(); - if (ctx == NULL) { - return -1; - } -#endif - - session->next_crypto->k = bignum_new(); - if (session->next_crypto->k == NULL) { -#ifdef HAVE_LIBCRYPTO - bignum_ctx_free(ctx); -#endif - return -1; - } - - /* the server and clients don't use the same numbers */ -#ifdef HAVE_LIBGCRYPT - if(session->client) { - bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, - session->next_crypto->x, select_p(session->next_crypto->kex_type)); - } else { - bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, - session->next_crypto->y, select_p(session->next_crypto->kex_type)); - } -#elif defined HAVE_LIBCRYPTO - if (session->client) { - bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, - session->next_crypto->x, select_p(session->next_crypto->kex_type), ctx); - } else { - bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, - session->next_crypto->y, select_p(session->next_crypto->kex_type), ctx); - } -#endif - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Session server cookie", - session->next_crypto->server_kex.cookie, 16); - ssh_print_hexa("Session client cookie", - session->next_crypto->client_kex.cookie, 16); - ssh_print_bignum("Shared secret key", session->next_crypto->k); -#endif - -#ifdef HAVE_LIBCRYPTO - bignum_ctx_free(ctx); -#endif - - return 0; -} - -/** @internal - * @brief Starts diffie-hellman-group1 key exchange - */ -int ssh_client_dh_init(ssh_session session){ - ssh_string e = NULL; - int rc; - - if (dh_generate_x(session) < 0) { - goto error; - } - if (dh_generate_e(session) < 0) { - goto error; - } - - e = dh_get_e(session); - if (e == NULL) { - goto error; - } - - rc = ssh_buffer_pack(session->out_buffer, "bS", SSH2_MSG_KEXDH_INIT, e); - if (rc != SSH_OK) { - goto error; - } - - ssh_string_burn(e); - ssh_string_free(e); - e=NULL; - - rc = packet_send(session); - return rc; - error: - if(e != NULL){ - ssh_string_burn(e); - ssh_string_free(e); - } - - return SSH_ERROR; -} - -int ssh_client_dh_reply(ssh_session session, ssh_buffer packet){ - ssh_string f; - ssh_string pubkey = NULL; - ssh_string signature = NULL; - int rc; - pubkey = buffer_get_ssh_string(packet); - if (pubkey == NULL){ - ssh_set_error(session,SSH_FATAL, "No public key in packet"); - goto error; - } - dh_import_pubkey(session, pubkey); - - f = buffer_get_ssh_string(packet); - if (f == NULL) { - ssh_set_error(session,SSH_FATAL, "No F number in packet"); - goto error; - } - rc = dh_import_f(session, f); - ssh_string_burn(f); - ssh_string_free(f); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot import f number"); - goto error; - } - - signature = buffer_get_ssh_string(packet); - if (signature == NULL) { - ssh_set_error(session, SSH_FATAL, "No signature in packet"); - goto error; - } - session->next_crypto->dh_server_signature = signature; - signature=NULL; /* ownership changed */ - if (dh_build_k(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot build k number"); - goto error; - } - - /* Send the MSG_NEWKEYS */ - if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { - goto error; - } - - rc=packet_send(session); - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - return rc; -error: - return SSH_ERROR; -} - -int make_sessionid(ssh_session session) { - ssh_string num = NULL; - ssh_buffer server_hash = NULL; - ssh_buffer client_hash = NULL; - ssh_buffer buf = NULL; - int rc = SSH_ERROR; - - buf = ssh_buffer_new(); - if (buf == NULL) { - return rc; - } - - rc = ssh_buffer_pack(buf, - "ss", - session->clientbanner, - session->serverbanner); - if (rc == SSH_ERROR) { - goto error; - } - - if (session->client) { - server_hash = session->in_hashbuf; - client_hash = session->out_hashbuf; - } else { - server_hash = session->out_hashbuf; - client_hash = session->in_hashbuf; - } - - /* - * Handle the two final fields for the KEXINIT message (RFC 4253 7.1): - * - * boolean first_kex_packet_follows - * uint32 0 (reserved for future extension) - */ - rc = buffer_add_u8(server_hash, 0); - if (rc < 0) { - goto error; - } - rc = buffer_add_u32(server_hash, 0); - if (rc < 0) { - goto error; - } - - /* These fields are handled for the server case in ssh_packet_kexinit. */ - if (session->client) { - rc = buffer_add_u8(client_hash, 0); - if (rc < 0) { - goto error; - } - rc = buffer_add_u32(client_hash, 0); - if (rc < 0) { - goto error; - } - } - - rc = ssh_buffer_pack(buf, - "dPdPS", - buffer_get_rest_len(client_hash), - buffer_get_rest_len(client_hash), - buffer_get_rest(client_hash), - buffer_get_rest_len(server_hash), - buffer_get_rest_len(server_hash), - buffer_get_rest(server_hash), - session->next_crypto->server_pubkey); - - if(rc != SSH_OK){ - goto error; - } - - if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1 || - session->next_crypto->kex_type == SSH_KEX_DH_GROUP14_SHA1) { - rc = ssh_buffer_pack(buf, - "BB", - session->next_crypto->e, - session->next_crypto->f); - if (rc != SSH_OK) { - goto error; - } - -#ifdef HAVE_ECDH - } else if (session->next_crypto->kex_type == SSH_KEX_ECDH_SHA2_NISTP256) { - if (session->next_crypto->ecdh_client_pubkey == NULL || - session->next_crypto->ecdh_server_pubkey == NULL) { - SSH_LOG(SSH_LOG_WARNING, "ECDH parameted missing"); - goto error; - } - rc = ssh_buffer_pack(buf, - "SS", - session->next_crypto->ecdh_client_pubkey, - session->next_crypto->ecdh_server_pubkey); - if (rc != SSH_OK) { - goto error; - } -#endif -#ifdef HAVE_CURVE25519 - } else if (session->next_crypto->kex_type == SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG) { - rc = ssh_buffer_pack(buf, - "dPdP", - CURVE25519_PUBKEY_SIZE, - (size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey, - CURVE25519_PUBKEY_SIZE, - (size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_server_pubkey); - - if (rc != SSH_OK) { - goto error; - } -#endif - } - rc = ssh_buffer_pack(buf, "B", session->next_crypto->k); - if (rc != SSH_OK) { - goto error; - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf)); -#endif - - switch (session->next_crypto->kex_type) { - case SSH_KEX_DH_GROUP1_SHA1: - case SSH_KEX_DH_GROUP14_SHA1: - session->next_crypto->digest_len = SHA_DIGEST_LENGTH; - session->next_crypto->mac_type = SSH_MAC_SHA1; - session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len); - if (session->next_crypto->secret_hash == NULL) { - ssh_set_error_oom(session); - goto error; - } - sha1(buffer_get_rest(buf), buffer_get_rest_len(buf), - session->next_crypto->secret_hash); - break; - case SSH_KEX_ECDH_SHA2_NISTP256: - case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG: - session->next_crypto->digest_len = SHA256_DIGEST_LENGTH; - session->next_crypto->mac_type = SSH_MAC_SHA256; - session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len); - if (session->next_crypto->secret_hash == NULL) { - ssh_set_error_oom(session); - goto error; - } - sha256(buffer_get_rest(buf), buffer_get_rest_len(buf), - session->next_crypto->secret_hash); - break; - } - /* During the first kex, secret hash and session ID are equal. However, after - * a key re-exchange, a new secret hash is calculated. This hash will not replace - * but complement existing session id. - */ - if (!session->next_crypto->session_id) { - session->next_crypto->session_id = malloc(session->next_crypto->digest_len); - if (session->next_crypto->session_id == NULL) { - ssh_set_error_oom(session); - goto error; - } - memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash, - session->next_crypto->digest_len); - } -#ifdef DEBUG_CRYPTO - printf("Session hash: \n"); - ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len); - ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len); -#endif - - rc = SSH_OK; -error: - ssh_buffer_free(buf); - ssh_buffer_free(client_hash); - ssh_buffer_free(server_hash); - - session->in_hashbuf = NULL; - session->out_hashbuf = NULL; - - ssh_string_free(num); - - return rc; -} - -int hashbufout_add_cookie(ssh_session session) { - session->out_hashbuf = ssh_buffer_new(); - if (session->out_hashbuf == NULL) { - return -1; - } - - if (buffer_add_u8(session->out_hashbuf, 20) < 0) { - ssh_buffer_reinit(session->out_hashbuf); - return -1; - } - - if (session->server) { - if (ssh_buffer_add_data(session->out_hashbuf, - session->next_crypto->server_kex.cookie, 16) < 0) { - ssh_buffer_reinit(session->out_hashbuf); - return -1; - } - } else { - if (ssh_buffer_add_data(session->out_hashbuf, - session->next_crypto->client_kex.cookie, 16) < 0) { - ssh_buffer_reinit(session->out_hashbuf); - return -1; - } - } - - return 0; -} - -int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) { - session->in_hashbuf = ssh_buffer_new(); - if (session->in_hashbuf == NULL) { - return -1; - } - - if (buffer_add_u8(session->in_hashbuf, 20) < 0) { - ssh_buffer_reinit(session->in_hashbuf); - return -1; - } - if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) { - ssh_buffer_reinit(session->in_hashbuf); - return -1; - } - - return 0; -} - -static int generate_one_key(ssh_string k, - struct ssh_crypto_struct *crypto, unsigned char **output, char letter, size_t requested_size) { - ssh_mac_ctx ctx; - unsigned char *tmp; - size_t size = crypto->digest_len; - ctx=ssh_mac_ctx_init(crypto->mac_type); - - if (ctx == NULL) { - return -1; - } - - ssh_mac_update(ctx, k, ssh_string_len(k) + 4); - ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); - ssh_mac_update(ctx, &letter, 1); - ssh_mac_update(ctx, crypto->session_id, crypto->digest_len); - ssh_mac_final(*output, ctx); - - while(requested_size > size) { - tmp = realloc(*output, size + crypto->digest_len); - if (tmp == NULL) { - return -1; - } - *output = tmp; - - ctx = ssh_mac_ctx_init(crypto->mac_type); - if (ctx == NULL) { - return -1; - } - ssh_mac_update(ctx, k, ssh_string_len(k) + 4); - ssh_mac_update(ctx, crypto->secret_hash, - crypto->digest_len); - ssh_mac_update(ctx, tmp, size); - ssh_mac_final(tmp + size, ctx); - size += crypto->digest_len; - } - - return 0; -} - -int generate_session_keys(ssh_session session) { - ssh_string k_string = NULL; - struct ssh_crypto_struct *crypto = session->next_crypto; - int rc = -1; - - k_string = make_bignum_string(crypto->k); - if (k_string == NULL) { - ssh_set_error_oom(session); - goto error; - } - - crypto->encryptIV = malloc(crypto->digest_len); - crypto->decryptIV = malloc(crypto->digest_len); - crypto->encryptkey = malloc(crypto->digest_len); - crypto->decryptkey = malloc(crypto->digest_len); - crypto->encryptMAC = malloc(crypto->digest_len); - crypto->decryptMAC = malloc(crypto->digest_len); - if(crypto->encryptIV == NULL || crypto->decryptIV == NULL || - crypto->encryptkey == NULL || crypto->decryptkey == NULL || - crypto->encryptMAC == NULL || crypto->decryptMAC == NULL){ - ssh_set_error_oom(session); - goto error; - } - - /* IV */ - if (session->client) { - rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'A', crypto->digest_len); - if (rc < 0) { - goto error; - } - rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'B', crypto->digest_len); - if (rc < 0) { - goto error; - } - } else { - rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'A', crypto->digest_len); - if (rc < 0) { - goto error; - } - rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'B', crypto->digest_len); - if (rc < 0) { - goto error; - } - } - if (session->client) { - rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'C', crypto->out_cipher->keysize / 8); - if (rc < 0) { - goto error; - } - rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'D', crypto->in_cipher->keysize / 8); - if (rc < 0) { - goto error; - } - } else { - rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'C', crypto->in_cipher->keysize / 8); - if (rc < 0) { - goto error; - } - rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'D', crypto->out_cipher->keysize / 8); - if (rc < 0) { - goto error; - } - } - - if(session->client) { - rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'E', hmac_digest_len(crypto->out_hmac)); - if (rc < 0) { - goto error; - } - rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'F', hmac_digest_len(crypto->in_hmac)); - if (rc < 0) { - goto error; - } - } else { - rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'E', hmac_digest_len(crypto->in_hmac)); - if (rc < 0) { - goto error; - } - rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'F', hmac_digest_len(crypto->out_hmac)); - if (rc < 0) { - goto error; - } - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Encrypt IV", crypto->encryptIV, crypto->digest_len); - ssh_print_hexa("Decrypt IV", crypto->decryptIV, crypto->digest_len); - ssh_print_hexa("Encryption key", crypto->encryptkey, crypto->out_cipher->keysize / 8); - ssh_print_hexa("Decryption key", crypto->decryptkey, crypto->in_cipher->keysize / 8); - ssh_print_hexa("Encryption MAC", crypto->encryptMAC, hmac_digest_len(crypto->out_hmac)); - ssh_print_hexa("Decryption MAC", crypto->decryptMAC, hmac_digest_len(crypto->in_hmac)); -#endif - - rc = 0; -error: - ssh_string_free(k_string); - - return rc; -} - -/** - * @addtogroup libssh_session - * - * @{ - */ - -/** - * @deprecated Use ssh_get_publickey_hash() - */ -int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) { - ssh_string pubkey; - MD5CTX ctx; - unsigned char *h; - - if (session == NULL || hash == NULL) { - return SSH_ERROR; - } - *hash = NULL; - if (session->current_crypto == NULL || - session->current_crypto->server_pubkey == NULL){ - ssh_set_error(session,SSH_FATAL,"No current cryptographic context"); - return SSH_ERROR; - } - - h = malloc(sizeof(unsigned char) * MD5_DIGEST_LEN); - if (h == NULL) { - return SSH_ERROR; - } - - ctx = md5_init(); - if (ctx == NULL) { - SAFE_FREE(h); - return SSH_ERROR; - } - - pubkey = session->current_crypto->server_pubkey; - - md5_update(ctx, ssh_string_data(pubkey), ssh_string_len(pubkey)); - md5_final(h, ctx); - - *hash = h; - - return MD5_DIGEST_LEN; -} - -/** - * @brief Deallocate the hash obtained by ssh_get_pubkey_hash. - * - * This is required under Microsoft platform as this library might use a - * different C library than your software, hence a different heap. - * - * @param[in] hash The buffer to deallocate. - * - * @see ssh_get_pubkey_hash() - */ -void ssh_clean_pubkey_hash(unsigned char **hash) { - SAFE_FREE(*hash); - *hash = NULL; -} - -/** - * @brief Get the server public key from a session. - * - * @param[in] session The session to get the key from. - * - * @param[out] key A pointer to store the allocated key. You need to free - * the key. - * - * @return SSH_OK on success, SSH_ERROR on errror. - * - * @see ssh_key_free() - */ -int ssh_get_publickey(ssh_session session, ssh_key *key) -{ - if (session==NULL || - session->current_crypto ==NULL || - session->current_crypto->server_pubkey == NULL) { - return SSH_ERROR; - } - - return ssh_pki_import_pubkey_blob(session->current_crypto->server_pubkey, - key); -} - -/** - * @brief Allocates a buffer with the hash of the public key. - * - * This function allows you to get a hash of the public key. You can then - * print this hash in a human-readable form to the user so that he is able to - * verify it. Use ssh_get_hexa() or ssh_print_hexa() to display it. - * - * @param[in] key The public key to create the hash for. - * - * @param[in] type The type of the hash you want. - * - * @param[in] hash A pointer to store the allocated buffer. It can be - * freed using ssh_clean_pubkey_hash(). - * - * @param[in] hlen The length of the hash. - * - * @return 0 on success, -1 if an error occured. - * - * @warning It is very important that you verify at some moment that the hash - * matches a known server. If you don't do it, cryptography wont help - * you at making things secure. - * OpenSSH uses SHA1 to print public key digests. - * - * @see ssh_is_server_known() - * @see ssh_get_hexa() - * @see ssh_print_hexa() - * @see ssh_clean_pubkey_hash() - */ -int ssh_get_publickey_hash(const ssh_key key, - enum ssh_publickey_hash_type type, - unsigned char **hash, - size_t *hlen) -{ - ssh_string blob; - unsigned char *h; - int rc; - - rc = ssh_pki_export_pubkey_blob(key, &blob); - if (rc < 0) { - return rc; - } - - switch (type) { - case SSH_PUBLICKEY_HASH_SHA1: - { - SHACTX ctx; - - h = malloc(SHA_DIGEST_LEN); - if (h == NULL) { - rc = -1; - goto out; - } - - ctx = sha1_init(); - if (ctx == NULL) { - free(h); - rc = -1; - goto out; - } - - sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); - sha1_final(h, ctx); - - *hlen = SHA_DIGEST_LEN; - } - break; - case SSH_PUBLICKEY_HASH_MD5: - { - MD5CTX ctx; - - h = malloc(MD5_DIGEST_LEN); - if (h == NULL) { - rc = -1; - goto out; - } - - ctx = md5_init(); - if (ctx == NULL) { - free(h); - rc = -1; - goto out; - } - - md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); - md5_final(h, ctx); - - *hlen = MD5_DIGEST_LEN; - } - break; - default: - rc = -1; - goto out; - } - - *hash = h; - rc = 0; -out: - ssh_string_free(blob); - return rc; -} - -/** - * @brief Convert a buffer into a colon separated hex string. - * The caller has to free the memory. - * - * @param what What should be converted to a hex string. - * - * @param len Length of the buffer to convert. - * - * @return The hex string or NULL on error. - * - * @see ssh_string_free_char() - */ -char *ssh_get_hexa(const unsigned char *what, size_t len) { - const char h[] = "0123456789abcdef"; - char *hexa; - size_t i; - size_t hlen = len * 3; - - if (len > (UINT_MAX - 1) / 3) { - return NULL; - } - - hexa = malloc(hlen + 1); - if (hexa == NULL) { - return NULL; - } - - for (i = 0; i < len; i++) { - hexa[i * 3] = h[(what[i] >> 4) & 0xF]; - hexa[i * 3 + 1] = h[what[i] & 0xF]; - hexa[i * 3 + 2] = ':'; - } - hexa[hlen - 1] = '\0'; - - return hexa; -} - -/** - * @brief Print a buffer as colon separated hex string. - * - * @param descr Description printed in front of the hex string. - * - * @param what What should be converted to a hex string. - * - * @param len Length of the buffer to convert. - */ -void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len) { - char *hexa = ssh_get_hexa(what, len); - - if (hexa == NULL) { - return; - } - printf("%s: %s\n", descr, hexa); - - free(hexa); -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/ecdh.c b/libssh/src/ecdh.c deleted file mode 100644 index e6310b4c..00000000 --- a/libssh/src/ecdh.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2011-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include "libssh/session.h" -#include "libssh/ecdh.h" -#include "libssh/dh.h" -#include "libssh/buffer.h" -#include "libssh/ssh2.h" -#include "libssh/pki.h" -#include "libssh/bignum.h" - -#ifdef HAVE_ECDH -#include - -#define NISTP256 NID_X9_62_prime256v1 -#define NISTP384 NID_secp384r1 -#define NISTP521 NID_secp521r1 - -/** @internal - * @brief Starts ecdh-sha2-nistp256 key exchange - */ -int ssh_client_ecdh_init(ssh_session session){ - EC_KEY *key; - const EC_GROUP *group; - const EC_POINT *pubkey; - ssh_string client_pubkey; - int len; - int rc; - bignum_CTX ctx = BN_CTX_new(); - - rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT); - if (rc < 0) { - BN_CTX_free(ctx); - return SSH_ERROR; - } - - key = EC_KEY_new_by_curve_name(NISTP256); - if (key == NULL) { - BN_CTX_free(ctx); - return SSH_ERROR; - } - group = EC_KEY_get0_group(key); - - EC_KEY_generate_key(key); - - pubkey=EC_KEY_get0_public_key(key); - len = EC_POINT_point2oct(group,pubkey,POINT_CONVERSION_UNCOMPRESSED, - NULL,0,ctx); - - client_pubkey = ssh_string_new(len); - if (client_pubkey == NULL) { - BN_CTX_free(ctx); - EC_KEY_free(key); - return SSH_ERROR; - } - - EC_POINT_point2oct(group,pubkey,POINT_CONVERSION_UNCOMPRESSED, - ssh_string_data(client_pubkey),len,ctx); - BN_CTX_free(ctx); - - rc = buffer_add_ssh_string(session->out_buffer,client_pubkey); - if (rc < 0) { - EC_KEY_free(key); - ssh_string_free(client_pubkey); - return SSH_ERROR; - } - - session->next_crypto->ecdh_privkey = key; - session->next_crypto->ecdh_client_pubkey = client_pubkey; - - rc = packet_send(session); - - return rc; -} - -static void ecdh_import_pubkey(ssh_session session, ssh_string pubkey_string) { - session->next_crypto->server_pubkey = pubkey_string; -} - -static int ecdh_build_k(ssh_session session) { - const EC_GROUP *group = EC_KEY_get0_group(session->next_crypto->ecdh_privkey); - EC_POINT *pubkey; - void *buffer; - int rc; - int len = (EC_GROUP_get_degree(group) + 7) / 8; - bignum_CTX ctx = bignum_ctx_new(); - if (ctx == NULL) { - return -1; - } - - session->next_crypto->k = bignum_new(); - if (session->next_crypto->k == NULL) { - bignum_ctx_free(ctx); - return -1; - } - - pubkey = EC_POINT_new(group); - if (pubkey == NULL) { - bignum_ctx_free(ctx); - return -1; - } - - if (session->server) { - rc = EC_POINT_oct2point(group, - pubkey, - ssh_string_data(session->next_crypto->ecdh_client_pubkey), - ssh_string_len(session->next_crypto->ecdh_client_pubkey), - ctx); - } else { - rc = EC_POINT_oct2point(group, - pubkey, - ssh_string_data(session->next_crypto->ecdh_server_pubkey), - ssh_string_len(session->next_crypto->ecdh_server_pubkey), - ctx); - } - bignum_ctx_free(ctx); - if (rc <= 0) { - EC_POINT_clear_free(pubkey); - return -1; - } - - buffer = malloc(len); - if (buffer == NULL) { - EC_POINT_clear_free(pubkey); - return -1; - } - - rc = ECDH_compute_key(buffer, - len, - pubkey, - session->next_crypto->ecdh_privkey, - NULL); - EC_POINT_clear_free(pubkey); - if (rc <= 0) { - free(buffer); - return -1; - } - - bignum_bin2bn(buffer, len, session->next_crypto->k); - free(buffer); - - EC_KEY_free(session->next_crypto->ecdh_privkey); - session->next_crypto->ecdh_privkey = NULL; - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Session server cookie", - session->next_crypto->server_kex.cookie, 16); - ssh_print_hexa("Session client cookie", - session->next_crypto->client_kex.cookie, 16); - ssh_print_bignum("Shared secret key", session->next_crypto->k); -#endif - - return 0; -} - -/** @internal - * @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back - * a SSH_MSG_NEWKEYS - */ -int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet){ - ssh_string q_s_string = NULL; - ssh_string pubkey = NULL; - ssh_string signature = NULL; - int rc; - pubkey = buffer_get_ssh_string(packet); - if (pubkey == NULL){ - ssh_set_error(session,SSH_FATAL, "No public key in packet"); - goto error; - } - ecdh_import_pubkey(session, pubkey); - - q_s_string = buffer_get_ssh_string(packet); - if (q_s_string == NULL) { - ssh_set_error(session,SSH_FATAL, "No Q_S ECC point in packet"); - goto error; - } - session->next_crypto->ecdh_server_pubkey = q_s_string; - signature = buffer_get_ssh_string(packet); - if (signature == NULL) { - ssh_set_error(session, SSH_FATAL, "No signature in packet"); - goto error; - } - session->next_crypto->dh_server_signature = signature; - signature=NULL; /* ownership changed */ - /* TODO: verify signature now instead of waiting for NEWKEYS */ - if (ecdh_build_k(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot build k number"); - goto error; - } - - /* Send the MSG_NEWKEYS */ - if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { - goto error; - } - - rc=packet_send(session); - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - return rc; -error: - return SSH_ERROR; -} - -#ifdef WITH_SERVER - -/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a - * SSH_MSG_KEXDH_REPLY - */ - -int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){ - /* ECDH keys */ - ssh_string q_c_string; - ssh_string q_s_string; - EC_KEY *ecdh_key; - const EC_GROUP *group; - const EC_POINT *ecdh_pubkey; - bignum_CTX ctx; - /* SSH host keys (rsa,dsa,ecdsa) */ - ssh_key privkey; - ssh_string sig_blob = NULL; - int len; - int rc; - - /* Extract the client pubkey from the init packet */ - q_c_string = buffer_get_ssh_string(packet); - if (q_c_string == NULL) { - ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet"); - return SSH_ERROR; - } - session->next_crypto->ecdh_client_pubkey = q_c_string; - - /* Build server's keypair */ - - ctx = BN_CTX_new(); - ecdh_key = EC_KEY_new_by_curve_name(NISTP256); - if (ecdh_key == NULL) { - ssh_set_error_oom(session); - BN_CTX_free(ctx); - return SSH_ERROR; - } - - group = EC_KEY_get0_group(ecdh_key); - EC_KEY_generate_key(ecdh_key); - - ecdh_pubkey = EC_KEY_get0_public_key(ecdh_key); - len = EC_POINT_point2oct(group, - ecdh_pubkey, - POINT_CONVERSION_UNCOMPRESSED, - NULL, - 0, - ctx); - - q_s_string = ssh_string_new(len); - if (q_s_string == NULL) { - EC_KEY_free(ecdh_key); - BN_CTX_free(ctx); - return SSH_ERROR; - } - - EC_POINT_point2oct(group, - ecdh_pubkey, - POINT_CONVERSION_UNCOMPRESSED, - ssh_string_data(q_s_string), - len, - ctx); - BN_CTX_free(ctx); - - session->next_crypto->ecdh_privkey = ecdh_key; - session->next_crypto->ecdh_server_pubkey = q_s_string; - - /* build k and session_id */ - rc = ecdh_build_k(session); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot build k number"); - return SSH_ERROR; - } - - /* privkey is not allocated */ - rc = ssh_get_key_params(session, &privkey); - if (rc == SSH_ERROR) { - return SSH_ERROR; - } - - rc = make_sessionid(session); - if (rc != SSH_OK) { - ssh_set_error(session, SSH_FATAL, "Could not create a session id"); - return SSH_ERROR; - } - - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); - if (sig_blob == NULL) { - ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); - return SSH_ERROR; - } - - rc = ssh_buffer_pack(session->out_buffer, - "bSSS", - SSH2_MSG_KEXDH_REPLY, - session->next_crypto->server_pubkey, /* host's pubkey */ - q_s_string, /* ecdh public key */ - sig_blob); /* signature blob */ - - ssh_string_free(sig_blob); - - if (rc != SSH_OK) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent"); - rc = packet_send(session); - if (rc == SSH_ERROR) { - return SSH_ERROR; - } - - /* Send the MSG_NEWKEYS */ - rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); - if (rc < 0) { - return SSH_ERROR;; - } - - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - rc = packet_send(session); - SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - - return rc; -} - -#endif /* WITH_SERVER */ - -#endif /* HAVE_ECDH */ diff --git a/libssh/src/ed25519.c b/libssh/src/ed25519.c deleted file mode 100644 index 2ae0ef4e..00000000 --- a/libssh/src/ed25519.c +++ /dev/null @@ -1,222 +0,0 @@ -/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ - -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c - */ - -#include "config.h" - -#include "libssh/libcrypto.h" -#include "libssh/wrapper.h" -#include "libssh/ge25519.h" -#include "libssh/sc25519.h" -#include "libssh/ed25519.h" - -/* - * Public Domain, Author: Daniel J. Bernstein - * Copied from nacl-20110221/crypto_verify/32/ref/verify.c - */ - -static int crypto_verify_32(const unsigned char *x,const unsigned char *y) -{ - unsigned int differentbits = 0; -#define F(i) differentbits |= x[i] ^ y[i]; - F(0) - F(1) - F(2) - F(3) - F(4) - F(5) - F(6) - F(7) - F(8) - F(9) - F(10) - F(11) - F(12) - F(13) - F(14) - F(15) - F(16) - F(17) - F(18) - F(19) - F(20) - F(21) - F(22) - F(23) - F(24) - F(25) - F(26) - F(27) - F(28) - F(29) - F(30) - F(31) - - return (1 & ((differentbits - 1) >> 8)) - 1; -} - -static void get_hram(unsigned char *hram, - const unsigned char *sm, - const unsigned char *pk, - unsigned char *playground, - unsigned long long smlen) -{ - unsigned long long i; - SHA512CTX ctx; - for (i = 0;i < 32;++i) playground[i] = sm[i]; - for (i = 32;i < 64;++i) playground[i] = pk[i-32]; - for (i = 64;i < smlen;++i) playground[i] = sm[i]; - - ctx = sha512_init(); - sha512_update(ctx, playground, smlen); - sha512_final(hram, ctx); -} - - -int crypto_sign_ed25519_keypair(unsigned char *pk, - unsigned char *sk) -{ - sc25519 scsk; - ge25519 gepk; - SHA512CTX ctx; - unsigned char extsk[64]; - int i; - int rc; - - rc = ssh_get_random(sk, 32, 0); - if (rc < 0){ - return -1; - } - - ctx = sha512_init(); - sha512_update(ctx, sk, 32); - sha512_final(extsk, ctx); - extsk[0] &= 248; - extsk[31] &= 127; - extsk[31] |= 64; - - sc25519_from32bytes(&scsk,extsk); - - ge25519_scalarmult_base(&gepk, &scsk); - ge25519_pack(pk, &gepk); - for(i=0;i<32;i++) { - sk[32 + i] = pk[i]; - } - - return 0; -} - -int crypto_sign_ed25519(unsigned char *sm, - unsigned long long *smlen, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *sk) -{ - sc25519 sck, scs, scsk; - ge25519 ger; - SHA512CTX ctx; - unsigned char r[32]; - unsigned char s[32]; - unsigned char extsk[64]; - unsigned long long i; - unsigned char hmg[SHA512_DIGEST_LEN]; - unsigned char hram[SHA512_DIGEST_LEN]; - - ctx = sha512_init(); - sha512_update(ctx, sk, 32); - sha512_final(extsk, ctx); - - extsk[0] &= 248; - extsk[31] &= 127; - extsk[31] |= 64; - - *smlen = mlen + 64; - for (i = 0;i < mlen; i++) { - sm[64 + i] = m[i]; - } - for (i = 0;i < 32; i++) { - sm[32 + i] = extsk[32+i]; - } - - /* Generate k as h(extsk[32],...,extsk[63],m) */ - ctx = sha512_init(); - sha512_update(ctx, sm + 32, mlen + 32); - sha512_final(hmg, ctx); - - /* Computation of R */ - sc25519_from64bytes(&sck, hmg); - ge25519_scalarmult_base(&ger, &sck); - ge25519_pack(r, &ger); - - /* Computation of s */ - for (i = 0; i < 32; i++) { - sm[i] = r[i]; - } - - get_hram(hram, sm, sk+32, sm, mlen+64); - - sc25519_from64bytes(&scs, hram); - sc25519_from32bytes(&scsk, extsk); - sc25519_mul(&scs, &scs, &scsk); - - sc25519_add(&scs, &scs, &sck); - - sc25519_to32bytes(s,&scs); /* cat s */ - for (i = 0;i < 32; i++) { - sm[32 + i] = s[i]; - } - - return 0; -} - -int crypto_sign_ed25519_open(unsigned char *m, - unsigned long long *mlen, - const unsigned char *sm, - unsigned long long smlen, - const unsigned char *pk) -{ - unsigned int i; - int ret; - unsigned char t2[32]; - ge25519 get1, get2; - sc25519 schram, scs; - unsigned char hram[SHA512_DIGEST_LEN]; - - *mlen = (unsigned long long) -1; - if (smlen < 64) return -1; - - if (ge25519_unpackneg_vartime(&get1, pk)) { - return -1; - } - - get_hram(hram,sm,pk,m,smlen); - - sc25519_from64bytes(&schram, hram); - - sc25519_from32bytes(&scs, sm+32); - - ge25519_double_scalarmult_vartime(&get2, - &get1, - &schram, - &ge25519_base, - &scs); - ge25519_pack(t2, &get2); - - ret = crypto_verify_32(sm, t2); - if (ret != 0) { - for (i = 0; i < smlen - 64; i++) { - m[i] = sm[i + 64]; - } - *mlen = smlen-64; - } else { - for (i = 0; i < smlen - 64; i++) { - m[i] = 0; - } - } - - return ret; -} diff --git a/libssh/src/error.c b/libssh/src/error.c deleted file mode 100644 index bd755c4f..00000000 --- a/libssh/src/error.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * error.c - functions for ssh error handling - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include "libssh/priv.h" -#include "libssh/session.h" - -/** - * @defgroup libssh_error The SSH error functions. - * @ingroup libssh - * - * Functions for error handling. - * - * @{ - */ - -/** - * @internal - * - * @brief Registers an error with a description. - * - * @param error The place to store the error. - * - * @param code The class of error. - * - * @param descr The description, which can be a format string. - * - * @param ... The arguments for the format string. - */ -void _ssh_set_error(void *error, - int code, - const char *function, - const char *descr, ...) -{ - struct ssh_common_struct *err = error; - va_list va; - - va_start(va, descr); - vsnprintf(err->error.error_buffer, ERROR_BUFFERLEN, descr, va); - va_end(va); - - err->error.error_code = code; - if (ssh_get_log_level() >= SSH_LOG_WARN) { - ssh_log_function(SSH_LOG_WARN, - function, - err->error.error_buffer); - } -} - -/** - * @internal - * - * @brief Registers an out of memory error - * - * @param error The place to store the error. - * - */ -void _ssh_set_error_oom(void *error, const char *function) -{ - struct error_struct *err = error; - - snprintf(err->error_buffer, sizeof(err->error_buffer), - "%s: Out of memory", function); - err->error_code = SSH_FATAL; -} - -/** - * @internal - * - * @brief Registers an invalid argument error - * - * @param error The place to store the error. - * - * @param function The function the error happened in. - * - */ -void _ssh_set_error_invalid(void *error, const char *function) -{ - _ssh_set_error(error, SSH_FATAL, function, - "Invalid argument in %s", function); -} - -/** - * @brief Retrieve the error text message from the last error. - * - * @param error An ssh_session or ssh_bind. - * - * @return A static string describing the error. - */ -const char *ssh_get_error(void *error) { - struct error_struct *err = error; - - return err->error_buffer; -} - -/** - * @brief Retrieve the error code from the last error. - * - * @param error An ssh_session or ssh_bind. - * - * \return SSH_NO_ERROR No error occurred\n - * SSH_REQUEST_DENIED The last request was denied but situation is - * recoverable\n - * SSH_FATAL A fatal error occurred. This could be an unexpected - * disconnection\n - * - * Other error codes are internal but can be considered same than - * SSH_FATAL. - */ -int ssh_get_error_code(void *error) { - struct error_struct *err = error; - - return err->error_code; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/fe25519.c b/libssh/src/fe25519.c deleted file mode 100644 index 0cedd89d..00000000 --- a/libssh/src/fe25519.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c - */ - -#define WINDOWSIZE 1 /* Should be 1,2, or 4 */ -#define WINDOWMASK ((1<>= 31; /* 1: yes; 0: no */ - return x; -} - -static uint32_t ge(uint32_t a,uint32_t b) /* 16-bit inputs */ -{ - unsigned int x = a; - - x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */ - x >>= 31; /* 0: yes; 1: no */ - x ^= 1; /* 1: yes; 0: no */ - - return x; -} - -static uint32_t times19(uint32_t a) -{ - return (a << 4) + (a << 1) + a; -} - -static uint32_t times38(uint32_t a) -{ - return (a << 5) + (a << 2) + (a << 1); -} - -static void reduce_add_sub(fe25519 *r) -{ - uint32_t t; - int i,rep; - - for(rep = 0; rep < 4; rep++) { - t = r->v[31] >> 7; - r->v[31] &= 127; - t = times19(t); - r->v[0] += t; - for(i = 0; i < 31; i++) { - t = r->v[i] >> 8; - r->v[i+1] += t; - r->v[i] &= 255; - } - } -} - -static void reduce_mul(fe25519 *r) -{ - uint32_t t; - int i,rep; - - for(rep = 0; rep < 2; rep++) { - t = r->v[31] >> 7; - r->v[31] &= 127; - t = times19(t); - r->v[0] += t; - for(i = 0; i < 31; i++) { - t = r->v[i] >> 8; - r->v[i+1] += t; - r->v[i] &= 255; - } - } -} - -/* reduction modulo 2^255-19 */ -void fe25519_freeze(fe25519 *r) -{ - int i; - uint32_t m = equal(r->v[31],127); - - for (i = 30; i > 0; i--) { - m &= equal(r->v[i],255); - } - m &= ge(r->v[0],237); - - m = -m; - - r->v[31] -= m&127; - for (i = 30; i > 0; i--) { - r->v[i] -= m&255; - } - r->v[0] -= m&237; -} - -void fe25519_unpack(fe25519 *r, const unsigned char x[32]) -{ - int i; - - for (i = 0;i < 32; i++) { - r->v[i] = x[i]; - } - - r->v[31] &= 127; -} - -/* Assumes input x being reduced below 2^255 */ -void fe25519_pack(unsigned char r[32], const fe25519 *x) -{ - int i; - - fe25519 y = *x; - fe25519_freeze(&y); - - for (i = 0; i < 32; i++) { - r[i] = y.v[i]; - } -} - -int fe25519_iszero(const fe25519 *x) -{ - int i; - int r; - - fe25519 t = *x; - fe25519_freeze(&t); - - r = equal(t.v[0],0); - for (i = 1; i < 32; i++) { - r &= equal(t.v[i],0); - } - - return r; -} - -int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) -{ - int i; - - fe25519 t1 = *x; - fe25519 t2 = *y; - fe25519_freeze(&t1); - fe25519_freeze(&t2); - - for (i = 0; i < 32; i++) { - if(t1.v[i] != t2.v[i]) { - return 0; - } - } - - return 1; -} - -void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) -{ - int i; - uint32_t mask = b; - - mask = -mask; - - for (i = 0; i < 32; i++) { - r->v[i] ^= mask & (x->v[i] ^ r->v[i]); - } -} - -unsigned char fe25519_getparity(const fe25519 *x) -{ - fe25519 t = *x; - fe25519_freeze(&t); - - return t.v[0] & 1; -} - -void fe25519_setone(fe25519 *r) -{ - int i; - - r->v[0] = 1; - for (i = 1; i < 32; i++) { - r->v[i]=0; - } -} - -void fe25519_setzero(fe25519 *r) -{ - int i; - - for (i = 0; i < 32; i++) { - r->v[i]=0; - } -} - -void fe25519_neg(fe25519 *r, const fe25519 *x) -{ - fe25519 t; - int i; - - for (i = 0; i < 32; i++) { - t.v[i]=x->v[i]; - } - - fe25519_setzero(r); - fe25519_sub(r, r, &t); -} - -void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) -{ - int i; - - for (i = 0; i < 32; i++) { - r->v[i] = x->v[i] + y->v[i]; - } - - reduce_add_sub(r); -} - -void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) -{ - int i; - uint32_t t[32]; - - t[0] = x->v[0] + 0x1da; - t[31] = x->v[31] + 0xfe; - - for (i = 1; i < 31; i++) { - t[i] = x->v[i] + 0x1fe; - } - - for (i = 0; i < 32; i++) { - r->v[i] = t[i] - y->v[i]; - } - - reduce_add_sub(r); -} - -void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) -{ - int i,j; - uint32_t t[63]; - - for (i = 0; i < 63; i++) { - t[i] = 0; - } - - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - t[i+j] += x->v[i] * y->v[j]; - } - } - - for (i = 32; i < 63; i++) { - r->v[i-32] = t[i-32] + times38(t[i]); - } - r->v[31] = t[31]; /* result now in r[0]...r[31] */ - - reduce_mul(r); -} - -void fe25519_square(fe25519 *r, const fe25519 *x) -{ - fe25519_mul(r, x, x); -} - -void fe25519_invert(fe25519 *r, const fe25519 *x) -{ - fe25519 z2; - fe25519 z9; - fe25519 z11; - fe25519 z2_5_0; - fe25519 z2_10_0; - fe25519 z2_20_0; - fe25519 z2_50_0; - fe25519 z2_100_0; - fe25519 t0; - fe25519 t1; - int i; - - /* 2 */ fe25519_square(&z2, x); - /* 4 */ fe25519_square(&t1, &z2); - /* 8 */ fe25519_square(&t0, &t1); - /* 9 */ fe25519_mul(&z9, &t0, x); - /* 11 */ fe25519_mul(&z11, &z9, &z2); - /* 22 */ fe25519_square(&t0, &z11); - /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t0, &z9); - - /* 2^6 - 2^1 */ fe25519_square(&t0, &z2_5_0); - /* 2^7 - 2^2 */ fe25519_square(&t1, &t0); - /* 2^8 - 2^3 */ fe25519_square(&t0, &t1); - /* 2^9 - 2^4 */ fe25519_square(&t1, &t0); - /* 2^10 - 2^5 */ fe25519_square(&t0, &t1); - /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t0, &z2_5_0); - - /* 2^11 - 2^1 */ fe25519_square(&t0, &z2_10_0); - /* 2^12 - 2^2 */ fe25519_square(&t1, &t0); - /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { - fe25519_square(&t0, &t1); - fe25519_square(&t1, &t0); - } - /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t1, &z2_10_0); - - /* 2^21 - 2^1 */ fe25519_square(&t0, &z2_20_0); - /* 2^22 - 2^2 */ fe25519_square(&t1, &t0); - /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { - fe25519_square(&t0, &t1); - fe25519_square(&t1,&t0); - } - /* 2^40 - 2^0 */ fe25519_mul(&t0, &t1, &z2_20_0); - - /* 2^41 - 2^1 */ fe25519_square(&t1, &t0); - /* 2^42 - 2^2 */ fe25519_square(&t0, &t1); - /* 2^50 - 2^10 */ for (i = 2; i < 10;i += 2) { - fe25519_square(&t1, &t0); - fe25519_square(&t0, &t1); - } - /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0); - - /* 2^51 - 2^1 */ fe25519_square(&t0, &z2_50_0); - /* 2^52 - 2^2 */ fe25519_square(&t1, &t0); - /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { - fe25519_square(&t0, &t1); - fe25519_square(&t1,&t0); - } - /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t1, &z2_50_0); - - /* 2^101 - 2^1 */ fe25519_square(&t1, &z2_100_0); - /* 2^102 - 2^2 */ fe25519_square(&t0, &t1); - /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { - fe25519_square(&t1, &t0); - fe25519_square(&t0,&t1); - } - /* 2^200 - 2^0 */ fe25519_mul(&t1, &t0, &z2_100_0); - - /* 2^201 - 2^1 */ fe25519_square(&t0, &t1); - /* 2^202 - 2^2 */ fe25519_square(&t1, &t0); - /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { - fe25519_square(&t0, &t1); - fe25519_square(&t1,&t0); - } - /* 2^250 - 2^0 */ fe25519_mul(&t0, &t1, &z2_50_0); - - /* 2^251 - 2^1 */ fe25519_square(&t1, &t0); - /* 2^252 - 2^2 */ fe25519_square(&t0, &t1); - /* 2^253 - 2^3 */ fe25519_square(&t1, &t0); - /* 2^254 - 2^4 */ fe25519_square(&t0, &t1); - /* 2^255 - 2^5 */ fe25519_square(&t1, &t0); - /* 2^255 - 21 */ fe25519_mul(r, &t1, &z11); -} - -void fe25519_pow2523(fe25519 *r, const fe25519 *x) -{ - fe25519 z2; - fe25519 z9; - fe25519 z11; - fe25519 z2_5_0; - fe25519 z2_10_0; - fe25519 z2_20_0; - fe25519 z2_50_0; - fe25519 z2_100_0; - fe25519 t; - int i; - - /* 2 */ fe25519_square(&z2, x); - /* 4 */ fe25519_square(&t, &z2); - /* 8 */ fe25519_square(&t, &t); - /* 9 */ fe25519_mul(&z9, &t, x); - /* 11 */ fe25519_mul(&z11, &z9, &z2); - /* 22 */ fe25519_square(&t, &z11); - /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t, &z9); - - /* 2^6 - 2^1 */ fe25519_square(&t, &z2_5_0); - /* 2^10 - 2^5 */ for (i = 1; i < 5; i++) { - fe25519_square(&t,&t); - } - /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t, &z2_5_0); - - /* 2^11 - 2^1 */ fe25519_square(&t, &z2_10_0); - /* 2^20 - 2^10 */ for (i = 1; i < 10; i++) { - fe25519_square(&t, &t); - } - /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t, &z2_10_0); - - /* 2^21 - 2^1 */ fe25519_square(&t, &z2_20_0); - /* 2^40 - 2^20 */ for (i = 1; i < 20; i++) { - fe25519_square(&t,&t); - } - /* 2^40 - 2^0 */ fe25519_mul(&t, &t, &z2_20_0); - - /* 2^41 - 2^1 */ fe25519_square(&t, &t); - /* 2^50 - 2^10 */ for (i = 1; i < 10; i++) { - fe25519_square(&t,&t); - } - /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0, &t, &z2_10_0); - - /* 2^51 - 2^1 */ fe25519_square(&t, &z2_50_0); - /* 2^100 - 2^50 */ for (i = 1; i < 50; i++) { - fe25519_square(&t, &t); - } - /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t, &z2_50_0); - - /* 2^101 - 2^1 */ fe25519_square(&t, &z2_100_0); - /* 2^200 - 2^100 */ for (i = 1; i < 100; i++) { - fe25519_square(&t, &t); - } - /* 2^200 - 2^0 */ fe25519_mul(&t, &t, &z2_100_0); - - /* 2^201 - 2^1 */ fe25519_square(&t, &t); - /* 2^250 - 2^50 */ for (i = 1; i < 50; i++) { - fe25519_square(&t, &t); - } - /* 2^250 - 2^0 */ fe25519_mul(&t, &t, &z2_50_0); - - /* 2^251 - 2^1 */ fe25519_square(&t, &t); - /* 2^252 - 2^2 */ fe25519_square(&t, &t); - /* 2^252 - 3 */ fe25519_mul(r, &t, x); -} diff --git a/libssh/src/gcrypt_missing.c b/libssh/src/gcrypt_missing.c deleted file mode 100644 index b21e5f30..00000000 --- a/libssh/src/gcrypt_missing.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * gcrypt_missing.c - routines that are in OpenSSL but not in libgcrypt. - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2006 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include - -#include "libssh/priv.h" -#include "libssh/libgcrypt.h" - -#ifdef HAVE_LIBGCRYPT -int my_gcry_dec2bn(bignum *bn, const char *data) { - int count; - - *bn = bignum_new(); - if (*bn == NULL) { - return 0; - } - gcry_mpi_set_ui(*bn, 0); - for (count = 0; data[count]; count++) { - gcry_mpi_mul_ui(*bn, *bn, 10); - gcry_mpi_add_ui(*bn, *bn, data[count] - '0'); - } - - return count; -} - -char *my_gcry_bn2dec(bignum bn) { - bignum bndup, num, ten; - char *ret; - int count, count2; - int size, rsize; - char decnum; - - size = gcry_mpi_get_nbits(bn) * 3; - rsize = size / 10 + size / 1000 + 2; - - ret = malloc(rsize + 1); - if (ret == NULL) { - return NULL; - } - - if (!gcry_mpi_cmp_ui(bn, 0)) { - strcpy(ret, "0"); - } else { - ten = bignum_new(); - if (ten == NULL) { - SAFE_FREE(ret); - return NULL; - } - - num = bignum_new(); - if (num == NULL) { - SAFE_FREE(ret); - bignum_free(ten); - return NULL; - } - - for (bndup = gcry_mpi_copy(bn), bignum_set_word(ten, 10), count = rsize; - count; count--) { - gcry_mpi_div(bndup, num, bndup, ten, 0); - for (decnum = 0, count2 = gcry_mpi_get_nbits(num); count2; - decnum *= 2, decnum += (gcry_mpi_test_bit(num, count2 - 1) ? 1 : 0), - count2--) - ; - ret[count - 1] = decnum + '0'; - } - for (count = 0; count < rsize && ret[count] == '0'; count++) - ; - for (count2 = 0; count2 < rsize - count; ++count2) { - ret[count2] = ret[count2 + count]; - } - ret[count2] = 0; - bignum_free(num); - bignum_free(bndup); - bignum_free(ten); - } - - return ret; -} - -#endif -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/ge25519.c b/libssh/src/ge25519.c deleted file mode 100644 index 20a33d1e..00000000 --- a/libssh/src/ge25519.c +++ /dev/null @@ -1,367 +0,0 @@ -/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ - -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c - */ - -#include "libssh/fe25519.h" -#include "libssh/sc25519.h" -#include "libssh/ge25519.h" - -/* - * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 - * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555 - * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960); - */ - -/* d */ -static const fe25519 ge25519_ecd = { - {0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, - 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, - 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, - 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52} -}; - -/* 2*d */ -static const fe25519 ge25519_ec2d = { - {0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, - 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, - 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, - 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24} -}; - -/* sqrt(-1) */ -static const fe25519 ge25519_sqrtm1 = { - {0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, - 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, - 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, - 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B} -}; - -#define ge25519_p3 ge25519 - -typedef struct { - fe25519 x; - fe25519 z; - fe25519 y; - fe25519 t; -} ge25519_p1p1; - -typedef struct { - fe25519 x; - fe25519 y; - fe25519 z; -} ge25519_p2; - -typedef struct { - fe25519 x; - fe25519 y; -} ge25519_aff; - - -/* Packed coordinates of the base point */ -const ge25519 ge25519_base = { - {{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, - 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, - 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, - 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}}, - {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, - 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, - 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, - 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}} -}; - -/* Multiples of the base point in affine representation */ -static const ge25519_aff ge25519_base_multiples_affine[425] = { -#include "ge25519_base.data" -}; - -static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) -{ - fe25519_mul(&r->x, &p->x, &p->t); - fe25519_mul(&r->y, &p->y, &p->z); - fe25519_mul(&r->z, &p->z, &p->t); -} - -static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) -{ - p1p1_to_p2((ge25519_p2 *)r, p); - fe25519_mul(&r->t, &p->x, &p->y); -} - -static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q) -{ - fe25519 a,b,t1,t2,c,d,e,f,g,h,qt; - fe25519_mul(&qt, &q->x, &q->y); - fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */ - fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */ - fe25519_sub(&t1, &q->y, &q->x); - fe25519_add(&t2, &q->y, &q->x); - fe25519_mul(&a, &a, &t1); - fe25519_mul(&b, &b, &t2); - fe25519_sub(&e, &b, &a); /* E = B-A */ - fe25519_add(&h, &b, &a); /* H = B+A */ - fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */ - fe25519_mul(&c, &c, &ge25519_ec2d); - fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */ - fe25519_sub(&f, &d, &c); /* F = D-C */ - fe25519_add(&g, &d, &c); /* G = D+C */ - fe25519_mul(&r->x, &e, &f); - fe25519_mul(&r->y, &h, &g); - fe25519_mul(&r->z, &g, &f); - fe25519_mul(&r->t, &e, &h); -} - -static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q) -{ - fe25519 a, b, c, d, t; - - fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */ - fe25519_sub(&t, &q->y, &q->x); - fe25519_mul(&a, &a, &t); - fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */ - fe25519_add(&t, &q->x, &q->y); - fe25519_mul(&b, &b, &t); - fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */ - fe25519_mul(&c, &c, &ge25519_ec2d); - fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */ - fe25519_add(&d, &d, &d); - fe25519_sub(&r->x, &b, &a); /* E = B-A */ - fe25519_sub(&r->t, &d, &c); /* F = D-C */ - fe25519_add(&r->z, &d, &c); /* G = D+C */ - fe25519_add(&r->y, &b, &a); /* H = B+A */ -} - -/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */ -static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p) -{ - fe25519 a,b,c,d; - fe25519_square(&a, &p->x); - fe25519_square(&b, &p->y); - fe25519_square(&c, &p->z); - fe25519_add(&c, &c, &c); - fe25519_neg(&d, &a); - - fe25519_add(&r->x, &p->x, &p->y); - fe25519_square(&r->x, &r->x); - fe25519_sub(&r->x, &r->x, &a); - fe25519_sub(&r->x, &r->x, &b); - fe25519_add(&r->z, &d, &b); - fe25519_sub(&r->t, &r->z, &c); - fe25519_sub(&r->y, &d, &b); -} - -/* Constant-time version of: if(b) r = p */ -static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b) -{ - fe25519_cmov(&r->x, &p->x, b); - fe25519_cmov(&r->y, &p->y, b); -} - -static unsigned char equal(signed char b,signed char c) -{ - unsigned char ub = b; - unsigned char uc = c; - unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint32_t y = x; /* 0: yes; 1..255: no */ - - y -= 1; /* 4294967295: yes; 0..254: no */ - y >>= 31; /* 1: yes; 0: no */ - - return y; -} - -static unsigned char negative(signed char b) -{ - unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - - x >>= 63; /* 1: yes; 0: no */ - - return x; -} - -static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b) -{ - /* constant time */ - fe25519 v; - - *t = ge25519_base_multiples_affine[5 * pos + 0]; - - cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 1], - equal(b,1) | equal(b,-1)); - cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 2], - equal(b,2) | equal(b,-2)); - cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 3], - equal(b,3) | equal(b,-3)); - cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 4], - equal(b,-4)); - - fe25519_neg(&v, &t->x); - fe25519_cmov(&t->x, &v, negative(b)); -} - -static void setneutral(ge25519 *r) -{ - fe25519_setzero(&r->x); - fe25519_setone(&r->y); - fe25519_setone(&r->z); - fe25519_setzero(&r->t); -} - -/* ******************************************************************** - * EXPORTED FUNCTIONS - ******************************************************************** */ - -/* return 0 on success, -1 otherwise */ -int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32]) -{ - unsigned char par; - - fe25519 t, chk, num, den, den2, den4, den6; - fe25519_setone(&r->z); - par = p[31] >> 7; - fe25519_unpack(&r->y, p); - fe25519_square(&num, &r->y); /* x = y^2 */ - fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */ - fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ - fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ - - /* Computation of sqrt(num/den) */ - /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ - fe25519_square(&den2, &den); - fe25519_square(&den4, &den2); - fe25519_mul(&den6, &den4, &den2); - fe25519_mul(&t, &den6, &num); - fe25519_mul(&t, &t, &den); - - fe25519_pow2523(&t, &t); - /* 2. computation of r->x = t * num * den^3 */ - fe25519_mul(&t, &t, &num); - fe25519_mul(&t, &t, &den); - fe25519_mul(&t, &t, &den); - fe25519_mul(&r->x, &t, &den); - - /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */ - fe25519_square(&chk, &r->x); - fe25519_mul(&chk, &chk, &den); - if (!fe25519_iseq_vartime(&chk, &num)) { - fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1); - } - - /* 4. Now we have one of the two square roots, except if input was not a square */ - fe25519_square(&chk, &r->x); - fe25519_mul(&chk, &chk, &den); - if (!fe25519_iseq_vartime(&chk, &num)) { - return -1; - } - - /* 5. Choose the desired square root according to parity: */ - if(fe25519_getparity(&r->x) != (1-par)) { - fe25519_neg(&r->x, &r->x); - } - - fe25519_mul(&r->t, &r->x, &r->y); - - return 0; -} - -void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) -{ - fe25519 tx, ty, zi; - - fe25519_invert(&zi, &p->z); - fe25519_mul(&tx, &p->x, &zi); - fe25519_mul(&ty, &p->y, &zi); - fe25519_pack(r, &ty); - - r[31] ^= fe25519_getparity(&tx) << 7; -} - -int ge25519_isneutral_vartime(const ge25519_p3 *p) -{ - int ret = 1; - - if (!fe25519_iszero(&p->x)) { - ret = 0; - } - - if (!fe25519_iseq_vartime(&p->y, &p->z)) { - ret = 0; - } - - return ret; -} - -/* computes [s1]p1 + [s2]p2 */ -void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2) -{ - ge25519_p1p1 tp1p1; - ge25519_p3 pre[16]; - unsigned char b[127]; - int i; - - /* precomputation s2 s1 */ - setneutral(pre); /* 00 00 */ - pre[1] = *p1; /* 00 01 */ - dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */ - add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */ - pre[4] = *p2; /* 01 00 */ - add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */ - add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */ - add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */ - dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */ - add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */ - dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */ - add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */ - add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */ - add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */ - add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */ - add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */ - - sc25519_2interleave2(b,s1,s2); - - /* scalar multiplication */ - *r = pre[b[126]]; - - for (i = 125; i >= 0; i--) { - dbl_p1p1(&tp1p1, (ge25519_p2 *)r); - p1p1_to_p2((ge25519_p2 *) r, &tp1p1); - dbl_p1p1(&tp1p1, (ge25519_p2 *)r); - if(b[i] != 0) { - p1p1_to_p3(r, &tp1p1); - add_p1p1(&tp1p1, r, &pre[b[i]]); - } - if (i != 0) { - p1p1_to_p2((ge25519_p2 *)r, &tp1p1); - } else { - p1p1_to_p3(r, &tp1p1); - } - } -} - -void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) -{ - signed char b[85]; - int i; - ge25519_aff t; - - sc25519_window3(b,s); - - choose_t((ge25519_aff *)r, 0, b[0]); - fe25519_setone(&r->z); - fe25519_mul(&r->t, &r->x, &r->y); - for (i = 1; i < 85; i++) { - choose_t(&t, (unsigned long long) i, b[i]); - ge25519_mixadd2(r, &t); - } -} diff --git a/libssh/src/ge25519_base.data b/libssh/src/ge25519_base.data deleted file mode 100644 index 66fb1b61..00000000 --- a/libssh/src/ge25519_base.data +++ /dev/null @@ -1,858 +0,0 @@ -/* $OpenBSD: ge25519_base.data,v 1.3 2013/12/09 11:03:45 markus Exp $ */ - -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519_base.data - */ - -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} , - {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}}, -{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} , - {{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}}, -{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} , - {{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}}, -{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} , - {{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} , - {{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}}, -{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} , - {{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}}, -{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} , - {{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}}, -{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} , - {{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} , - {{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}}, -{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} , - {{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}}, -{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} , - {{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}}, -{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} , - {{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} , - {{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}}, -{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} , - {{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}}, -{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} , - {{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}}, -{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} , - {{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} , - {{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}}, -{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} , - {{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}}, -{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} , - {{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}}, -{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} , - {{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} , - {{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}}, -{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} , - {{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}}, -{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} , - {{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}}, -{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} , - {{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} , - {{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}}, -{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} , - {{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}}, -{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} , - {{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}}, -{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} , - {{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} , - {{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}}, -{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} , - {{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}}, -{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} , - {{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}}, -{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} , - {{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} , - {{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}}, -{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} , - {{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}}, -{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} , - {{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}}, -{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} , - {{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} , - {{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}}, -{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} , - {{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}}, -{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} , - {{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}}, -{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} , - {{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} , - {{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}}, -{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} , - {{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}}, -{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} , - {{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}}, -{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} , - {{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} , - {{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}}, -{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} , - {{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}}, -{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} , - {{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}}, -{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} , - {{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} , - {{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}}, -{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} , - {{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}}, -{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} , - {{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}}, -{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} , - {{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} , - {{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}}, -{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} , - {{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}}, -{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} , - {{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}}, -{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} , - {{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} , - {{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}}, -{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} , - {{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}}, -{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} , - {{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}}, -{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} , - {{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} , - {{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}}, -{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} , - {{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}}, -{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} , - {{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}}, -{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} , - {{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} , - {{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}}, -{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} , - {{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}}, -{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} , - {{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}}, -{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} , - {{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} , - {{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}}, -{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} , - {{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}}, -{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} , - {{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}}, -{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} , - {{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} , - {{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}}, -{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} , - {{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}}, -{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} , - {{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}}, -{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} , - {{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} , - {{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}}, -{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} , - {{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}}, -{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} , - {{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}}, -{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} , - {{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} , - {{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}}, -{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} , - {{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}}, -{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} , - {{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}}, -{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} , - {{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} , - {{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}}, -{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} , - {{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}}, -{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} , - {{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}}, -{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} , - {{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} , - {{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}}, -{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} , - {{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}}, -{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} , - {{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}}, -{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} , - {{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} , - {{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}}, -{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} , - {{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}}, -{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} , - {{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}}, -{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} , - {{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} , - {{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}}, -{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} , - {{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}}, -{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} , - {{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}}, -{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} , - {{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} , - {{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}}, -{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} , - {{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}}, -{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} , - {{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}}, -{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} , - {{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} , - {{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}}, -{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} , - {{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}}, -{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} , - {{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}}, -{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} , - {{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} , - {{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}}, -{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} , - {{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}}, -{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} , - {{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}}, -{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} , - {{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} , - {{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}}, -{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} , - {{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}}, -{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} , - {{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}}, -{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} , - {{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} , - {{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}}, -{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} , - {{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}}, -{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} , - {{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}}, -{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} , - {{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} , - {{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}}, -{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} , - {{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}}, -{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} , - {{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}}, -{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} , - {{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} , - {{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}}, -{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} , - {{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}}, -{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} , - {{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}}, -{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} , - {{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} , - {{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}}, -{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} , - {{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}}, -{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} , - {{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}}, -{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} , - {{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} , - {{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}}, -{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} , - {{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}}, -{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} , - {{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}}, -{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} , - {{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} , - {{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}}, -{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} , - {{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}}, -{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} , - {{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}}, -{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} , - {{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} , - {{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}}, -{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} , - {{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}}, -{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} , - {{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}}, -{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} , - {{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} , - {{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}}, -{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} , - {{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}}, -{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} , - {{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}}, -{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} , - {{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} , - {{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}}, -{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} , - {{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}}, -{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} , - {{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}}, -{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} , - {{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} , - {{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}}, -{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} , - {{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}}, -{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} , - {{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}}, -{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} , - {{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} , - {{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}}, -{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} , - {{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}}, -{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} , - {{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}}, -{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} , - {{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} , - {{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}}, -{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} , - {{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}}, -{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} , - {{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}}, -{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} , - {{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} , - {{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}}, -{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} , - {{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}}, -{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} , - {{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}}, -{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} , - {{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} , - {{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}}, -{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} , - {{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}}, -{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} , - {{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}}, -{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} , - {{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} , - {{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}}, -{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} , - {{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}}, -{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} , - {{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}}, -{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} , - {{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} , - {{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}}, -{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} , - {{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}}, -{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} , - {{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}}, -{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} , - {{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} , - {{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}}, -{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} , - {{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}}, -{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} , - {{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}}, -{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} , - {{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} , - {{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}}, -{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} , - {{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}}, -{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} , - {{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}}, -{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} , - {{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} , - {{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}}, -{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} , - {{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}}, -{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} , - {{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}}, -{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} , - {{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} , - {{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}}, -{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} , - {{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}}, -{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} , - {{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}}, -{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} , - {{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} , - {{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}}, -{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} , - {{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}}, -{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} , - {{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}}, -{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} , - {{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} , - {{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}}, -{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} , - {{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}}, -{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} , - {{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}}, -{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} , - {{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} , - {{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}}, -{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} , - {{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}}, -{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} , - {{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}}, -{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} , - {{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} , - {{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}}, -{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} , - {{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}}, -{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} , - {{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}}, -{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} , - {{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} , - {{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}}, -{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} , - {{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}}, -{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} , - {{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}}, -{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} , - {{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} , - {{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}}, -{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} , - {{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}}, -{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} , - {{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}}, -{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} , - {{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} , - {{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}}, -{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} , - {{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}}, -{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} , - {{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}}, -{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} , - {{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} , - {{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}}, -{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} , - {{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}}, -{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} , - {{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}}, -{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} , - {{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} , - {{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}}, -{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} , - {{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}}, -{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} , - {{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}}, -{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} , - {{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} , - {{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}}, -{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} , - {{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}}, -{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} , - {{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}}, -{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} , - {{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} , - {{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}}, -{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} , - {{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}}, -{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} , - {{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}}, -{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} , - {{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} , - {{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}}, -{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} , - {{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}}, -{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} , - {{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}}, -{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} , - {{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} , - {{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}}, -{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} , - {{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}}, -{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} , - {{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}}, -{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} , - {{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} , - {{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}}, -{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} , - {{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}}, -{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} , - {{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}}, -{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} , - {{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} , - {{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}}, -{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} , - {{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}}, -{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} , - {{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}}, -{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} , - {{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} , - {{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}}, -{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} , - {{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}}, -{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} , - {{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}}, -{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} , - {{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} , - {{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}}, -{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} , - {{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}}, -{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} , - {{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}}, -{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} , - {{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} , - {{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}}, -{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} , - {{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}}, -{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} , - {{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}}, -{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} , - {{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} , - {{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}}, -{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} , - {{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}}, -{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} , - {{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}}, -{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} , - {{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} , - {{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}}, -{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} , - {{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}}, -{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} , - {{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}}, -{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} , - {{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} , - {{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}}, -{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} , - {{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}}, -{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} , - {{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}}, -{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} , - {{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} , - {{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}}, -{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} , - {{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}}, -{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} , - {{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}}, -{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} , - {{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} , - {{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}}, -{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} , - {{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}}, -{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} , - {{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}}, -{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} , - {{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} , - {{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}}, -{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} , - {{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}}, -{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} , - {{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}}, -{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} , - {{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} , - {{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}}, -{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} , - {{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}}, -{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} , - {{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}}, -{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} , - {{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} , - {{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}}, -{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} , - {{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}}, -{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} , - {{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}}, -{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} , - {{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} , - {{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}}, -{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} , - {{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}}, -{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} , - {{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}}, -{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} , - {{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} , - {{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}}, -{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} , - {{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}}, -{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} , - {{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}}, -{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} , - {{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} , - {{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}}, -{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} , - {{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}}, -{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} , - {{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}}, -{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} , - {{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} , - {{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}}, -{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} , - {{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}}, -{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} , - {{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}}, -{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} , - {{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} , - {{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}}, -{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} , - {{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}}, -{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} , - {{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}}, -{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} , - {{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} , - {{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}}, -{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} , - {{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}}, -{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} , - {{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}}, -{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} , - {{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} , - {{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}}, -{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} , - {{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}}, -{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} , - {{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}}, -{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} , - {{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} , - {{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}}, -{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} , - {{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}}, -{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} , - {{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}}, -{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} , - {{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} , - {{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}}, -{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} , - {{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}}, -{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} , - {{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}}, -{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} , - {{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}}, -{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, -{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} , - {{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}}, -{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} , - {{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}}, -{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} , - {{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}}, -{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} , - {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}} diff --git a/libssh/src/getpass.c b/libssh/src/getpass.c deleted file mode 100644 index c36f263b..00000000 --- a/libssh/src/getpass.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * getpass.c - platform independent getpass function. - * - * This file is part of the SSH Library - * - * Copyright (c) 2011-2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include - -#include - -/** - * @internal - * - * @brief Get the password from the console. - * - * @param[in] prompt The prompt to display. - * - * @param[in] buf The buffer to fill. - * - * @param[in] len The length of the buffer. - * - * @param[in] verify Should the password be verified? - * - * @return 1 on success, 0 on error. - */ -static int ssh_gets(const char *prompt, char *buf, size_t len, int verify) { - char *tmp; - char *ptr = NULL; - int ok = 0; - - tmp = malloc(len); - if (tmp == NULL) { - return 0; - } - memset(tmp,'\0',len); - - /* read the password */ - while (!ok) { - if (buf[0] != '\0') { - fprintf(stdout, "%s[%s] ", prompt, buf); - } else { - fprintf(stdout, "%s", prompt); - } - fflush(stdout); - if (fgets(tmp, len, stdin) == NULL) { - free(tmp); - return 0; - } - - if ((ptr = strchr(tmp, '\n'))) { - *ptr = '\0'; - } - fprintf(stdout, "\n"); - - if (*tmp) { - strncpy(buf, tmp, len); - } - - if (verify) { - char *key_string; - - key_string = malloc(len); - if (key_string == NULL) { - break; - } - memset(key_string, '\0', len); - - fprintf(stdout, "\nVerifying, please re-enter. %s", prompt); - fflush(stdout); - if (! fgets(key_string, len, stdin)) { - memset(key_string, '\0', len); - SAFE_FREE(key_string); - clearerr(stdin); - continue; - } - if ((ptr = strchr(key_string, '\n'))) { - *ptr = '\0'; - } - fprintf(stdout, "\n"); - if (strcmp(buf, key_string)) { - printf("\n\07\07Mismatch - try again\n"); - memset(key_string, '\0', len); - SAFE_FREE(key_string); - fflush(stdout); - continue; - } - memset(key_string, '\0', len); - SAFE_FREE(key_string); - } - ok = 1; - } - memset(tmp, '\0', len); - free(tmp); - - return ok; -} - -#ifdef _WIN32 -#include - -int ssh_getpass(const char *prompt, - char *buf, - size_t len, - int echo, - int verify) { - HANDLE h; - DWORD mode = 0; - int ok; - - /* fgets needs at least len - 1 */ - if (prompt == NULL || buf == NULL || len < 2) { - return -1; - } - - /* get stdin and mode */ - h = GetStdHandle(STD_INPUT_HANDLE); - if (!GetConsoleMode(h, &mode)) { - return -1; - } - - /* disable echo */ - if (!echo) { - if (!SetConsoleMode(h, mode & ~ENABLE_ECHO_INPUT)) { - return -1; - } - } - - ok = ssh_gets(prompt, buf, len, verify); - - /* reset echo */ - SetConsoleMode(h, mode); - - if (!ok) { - memset (buf, '\0', len); - return -1; - } - - /* force termination */ - buf[len - 1] = '\0'; - - return 0; -} - -#else - -#include -#ifdef HAVE_TERMIOS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -/** - * @ingroup libssh_misc - * - * @brief Get a password from the console. - * - * You should make sure that the buffer is an empty string! - * - * You can also use this function to ask for a username. Then you can fill the - * buffer with the username and it is shows to the users. If the users just - * presses enter the buffer will be untouched. - * - * @code - * char username[128]; - * - * snprintf(username, sizeof(username), "john"); - * - * ssh_getpass("Username:", username, sizeof(username), 1, 0); - * @endcode - * - * The prompt will look like this: - * - * Username: [john] - * - * If you press enter then john is used as the username, or you can type it in - * to change it. - * - * @param[in] prompt The prompt to show to ask for the password. - * - * @param[out] buf The buffer the password should be stored. It NEEDS to be - * empty or filled out. - * - * @param[in] len The length of the buffer. - * - * @param[in] echo Should we echo what you type. - * - * @param[in] verify Should we ask for the password twice. - * - * @return 0 on success, -1 on error. - */ -int ssh_getpass(const char *prompt, - char *buf, - size_t len, - int echo, - int verify) { - struct termios attr; - struct termios old_attr; - int ok = 0; - int fd = -1; - - /* fgets needs at least len - 1 */ - if (prompt == NULL || buf == NULL || len < 2) { - return -1; - } - - if (isatty(STDIN_FILENO)) { - ZERO_STRUCT(attr); - ZERO_STRUCT(old_attr); - - /* get local terminal attributes */ - if (tcgetattr(STDIN_FILENO, &attr) < 0) { - perror("tcgetattr"); - return -1; - } - - /* save terminal attributes */ - memcpy(&old_attr, &attr, sizeof(attr)); - if((fd = fcntl(0, F_GETFL, 0)) < 0) { - perror("fcntl"); - return -1; - } - - /* disable echo */ - if (!echo) { - attr.c_lflag &= ~(ECHO); - } - - /* write attributes to terminal */ - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr) < 0) { - perror("tcsetattr"); - return -1; - } - } - - /* disable nonblocking I/O */ - if (fd & O_NDELAY) { - fcntl(0, F_SETFL, fd & ~O_NDELAY); - } - - ok = ssh_gets(prompt, buf, len, verify); - - if (isatty(STDIN_FILENO)) { - /* reset terminal */ - tcsetattr(STDIN_FILENO, TCSANOW, &old_attr); - } - - /* close fd */ - if (fd & O_NDELAY) { - fcntl(0, F_SETFL, fd); - } - - if (!ok) { - memset (buf, '\0', len); - return -1; - } - - /* force termination */ - buf[len - 1] = '\0'; - - return 0; -} - -#endif - -/* vim: set ts=4 sw=4 et cindent syntax=c.doxygen: */ diff --git a/libssh/src/gssapi.c b/libssh/src/gssapi.c deleted file mode 100644 index 099294ee..00000000 --- a/libssh/src/gssapi.c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/** current state of an GSSAPI authentication */ -enum ssh_gssapi_state_e { - SSH_GSSAPI_STATE_NONE, /* no status */ - SSH_GSSAPI_STATE_RCV_TOKEN, /* Expecting a token */ - SSH_GSSAPI_STATE_RCV_MIC, /* Expecting a MIC */ -}; - -struct ssh_gssapi_struct{ - enum ssh_gssapi_state_e state; /* current state */ - struct gss_OID_desc_struct mech; /* mechanism being elected for auth */ - gss_cred_id_t server_creds; /* credentials of server */ - gss_cred_id_t client_creds; /* creds delegated by the client */ - gss_ctx_id_t ctx; /* the authentication context */ - gss_name_t client_name; /* Identity of the client */ - char *user; /* username of client */ - char *canonic_user; /* canonic form of the client's username */ - char *service; /* name of the service */ - struct { - gss_name_t server_name; /* identity of server */ - OM_uint32 flags; /* flags used for init context */ - gss_OID oid; /* mech being used for authentication */ - gss_cred_id_t creds; /* creds used to initialize context */ - gss_cred_id_t client_deleg_creds; /* delegated creds (const, not freeable) */ - } client; -}; - - -/** @internal - * @initializes a gssapi context for authentication - */ -static int ssh_gssapi_init(ssh_session session){ - if (session->gssapi != NULL) - return SSH_OK; - session->gssapi = malloc(sizeof(struct ssh_gssapi_struct)); - if(!session->gssapi){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - ZERO_STRUCTP(session->gssapi); - session->gssapi->server_creds = GSS_C_NO_CREDENTIAL; - session->gssapi->client_creds = GSS_C_NO_CREDENTIAL; - session->gssapi->ctx = GSS_C_NO_CONTEXT; - session->gssapi->state = SSH_GSSAPI_STATE_NONE; - return SSH_OK; -} - -/** @internal - * @frees a gssapi context - */ -static void ssh_gssapi_free(ssh_session session){ - OM_uint32 min; - if (session->gssapi == NULL) - return; - SAFE_FREE(session->gssapi->user); - SAFE_FREE(session->gssapi->mech.elements); - gss_release_cred(&min,&session->gssapi->server_creds); - if (session->gssapi->client.creds != - session->gssapi->client.client_deleg_creds) { - gss_release_cred(&min, &session->gssapi->client.creds); - } - SAFE_FREE(session->gssapi); -} - -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token){ -#ifdef WITH_SERVER - if(session->server) - return ssh_packet_userauth_gssapi_token_server(session, type, packet, user); -#endif - return ssh_packet_userauth_gssapi_token_client(session, type, packet, user); -} -#ifdef WITH_SERVER - -/** @internal - * @brief sends a SSH_MSG_USERAUTH_GSSAPI_RESPONSE packet - * @param[in] oid the OID that was selected for authentication - */ -static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){ - if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) < 0 || - buffer_add_ssh_string(session->out_buffer,oid) < 0) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - - packet_send(session); - SSH_LOG(SSH_LOG_PACKET, - "Sent SSH_MSG_USERAUTH_GSSAPI_RESPONSE"); - return SSH_OK; -} - -#endif /* WITH_SERVER */ - -static void ssh_gssapi_log_error(int verb, const char *msg, int maj_stat){ - gss_buffer_desc buffer; - OM_uint32 dummy, message_context; - gss_display_status(&dummy,maj_stat,GSS_C_GSS_CODE, GSS_C_NO_OID, &message_context, &buffer); - SSH_LOG(verb, "GSSAPI(%s): %s", msg, (const char *)buffer.value); -} - -#ifdef WITH_SERVER - -/** @internal - * @brief handles an user authentication using GSSAPI - */ -int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids){ - char service_name[]="host"; - gss_buffer_desc name_buf; - gss_name_t server_name; /* local server fqdn */ - OM_uint32 maj_stat, min_stat; - unsigned int i; - char *ptr; - gss_OID_set supported; /* oids supported by server */ - gss_OID_set both_supported; /* oids supported by both client and server */ - gss_OID_set selected; /* oid selected for authentication */ - int present=0; - int oid_count=0; - struct gss_OID_desc_struct oid; - int rc; - - if (ssh_callbacks_exists(session->server_callbacks, gssapi_select_oid_function)){ - ssh_string oid_s = session->server_callbacks->gssapi_select_oid_function(session, - user, n_oid, oids, - session->server_callbacks->userdata); - if (oid_s != NULL){ - if (ssh_gssapi_init(session) == SSH_ERROR) - return SSH_ERROR; - session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN; - rc = ssh_gssapi_send_response(session, oid_s); - ssh_string_free(oid_s); - return rc; - } else { - return ssh_auth_reply_default(session,0); - } - } - gss_create_empty_oid_set(&min_stat, &both_supported); - - maj_stat = gss_indicate_mechs(&min_stat, &supported); - for (i=0; i < supported->count; ++i){ - ptr = ssh_get_hexa(supported->elements[i].elements, supported->elements[i].length); - SSH_LOG(SSH_LOG_DEBUG, "Supported mech %d: %s\n", i, ptr); - free(ptr); - } - - for (i=0 ; i< n_oid ; ++i){ - unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]); - size_t len = ssh_string_len(oids[i]); - if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){ - SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID"); - continue; - } - oid.elements = &oid_s[2]; - oid.length = len - 2; - gss_test_oid_set_member(&min_stat,&oid,supported,&present); - if(present){ - gss_add_oid_set_member(&min_stat,&oid,&both_supported); - oid_count++; - } - } - gss_release_oid_set(&min_stat, &supported); - if (oid_count == 0){ - SSH_LOG(SSH_LOG_PROTOCOL,"GSSAPI: no OID match"); - ssh_auth_reply_default(session, 0); - gss_release_oid_set(&min_stat, &both_supported); - return SSH_OK; - } - /* from now we have room for context */ - if (ssh_gssapi_init(session) == SSH_ERROR) - return SSH_ERROR; - - name_buf.value = service_name; - name_buf.length = strlen(name_buf.value) + 1; - maj_stat = gss_import_name(&min_stat, &name_buf, - (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name); - if (maj_stat != GSS_S_COMPLETE) { - SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat); - ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat); - return -1; - } - - maj_stat = gss_acquire_cred(&min_stat, server_name, 0, - both_supported, GSS_C_ACCEPT, - &session->gssapi->server_creds, &selected, NULL); - gss_release_name(&min_stat, &server_name); - gss_release_oid_set(&min_stat, &both_supported); - - if (maj_stat != GSS_S_COMPLETE) { - SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat); - ssh_gssapi_log_error(SSH_LOG_WARNING, "acquiring creds", maj_stat); - ssh_auth_reply_default(session,0); - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PROTOCOL, "acquiring credentials %d, %d", maj_stat, min_stat); - - /* finding which OID from client we selected */ - for (i=0 ; i< n_oid ; ++i){ - unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]); - size_t len = ssh_string_len(oids[i]); - if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){ - SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID"); - continue; - } - oid.elements = &oid_s[2]; - oid.length = len - 2; - gss_test_oid_set_member(&min_stat,&oid,selected,&present); - if(present){ - SSH_LOG(SSH_LOG_PACKET, "Selected oid %d", i); - break; - } - } - session->gssapi->mech.length = oid.length; - session->gssapi->mech.elements = malloc(oid.length); - if (session->gssapi->mech.elements == NULL){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - memcpy(session->gssapi->mech.elements, oid.elements, oid.length); - gss_release_oid_set(&min_stat, &selected); - session->gssapi->user = strdup(user); - session->gssapi->service = service_name; - session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN; - return ssh_gssapi_send_response(session, oids[i]); -} - -static char *ssh_gssapi_name_to_char(gss_name_t name){ - gss_buffer_desc buffer; - OM_uint32 maj_stat, min_stat; - char *ptr; - maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); - ssh_gssapi_log_error(SSH_LOG_WARNING, "converting name", maj_stat); - ptr=malloc(buffer.length + 1); - memcpy(ptr, buffer.value, buffer.length); - ptr[buffer.length] = '\0'; - gss_release_buffer(&min_stat, &buffer); - return ptr; - -} - -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){ - ssh_string token; - char *hexa; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER; - gss_name_t client_name = GSS_C_NO_NAME; - OM_uint32 ret_flags=0; - gss_channel_bindings_t input_bindings=GSS_C_NO_CHANNEL_BINDINGS; - int rc; - - (void)user; - (void)type; - - SSH_LOG(SSH_LOG_PACKET,"Received SSH_MSG_USERAUTH_GSSAPI_TOKEN"); - if (!session->gssapi || session->gssapi->state != SSH_GSSAPI_STATE_RCV_TOKEN){ - ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_USERAUTH_GSSAPI_TOKEN in invalid state"); - return SSH_PACKET_USED; - } - token = buffer_get_ssh_string(packet); - - if (token == NULL){ - ssh_set_error(session, SSH_REQUEST_DENIED, "ssh_packet_userauth_gssapi_token: invalid packet"); - return SSH_PACKET_USED; - } - - if (ssh_callbacks_exists(session->server_callbacks, gssapi_accept_sec_ctx_function)){ - ssh_string out_token=NULL; - rc = session->server_callbacks->gssapi_accept_sec_ctx_function(session, - token, &out_token, session->server_callbacks->userdata); - if (rc == SSH_ERROR){ - ssh_auth_reply_default(session, 0); - ssh_gssapi_free(session); - session->gssapi=NULL; - return SSH_PACKET_USED; - } - if (ssh_string_len(out_token) != 0){ - rc = ssh_buffer_pack(session->out_buffer, - "bS", - SSH2_MSG_USERAUTH_GSSAPI_TOKEN, - out_token); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - return SSH_PACKET_USED; - } - packet_send(session); - ssh_string_free(out_token); - } else { - session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC; - } - return SSH_PACKET_USED; - } - hexa = ssh_get_hexa(ssh_string_data(token),ssh_string_len(token)); - SSH_LOG(SSH_LOG_PACKET, "GSSAPI Token : %s",hexa); - SAFE_FREE(hexa); - input_token.length = ssh_string_len(token); - input_token.value = ssh_string_data(token); - - maj_stat = gss_accept_sec_context(&min_stat, &session->gssapi->ctx, session->gssapi->server_creds, - &input_token, input_bindings, &client_name, NULL /*mech_oid*/, &output_token, &ret_flags, - NULL /*time*/, &session->gssapi->client_creds); - ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat); - ssh_string_free(token); - if (client_name != GSS_C_NO_NAME){ - session->gssapi->client_name = client_name; - session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name); - } - if (GSS_ERROR(maj_stat)){ - ssh_gssapi_log_error(SSH_LOG_WARNING, "Gssapi error", maj_stat); - ssh_auth_reply_default(session,0); - ssh_gssapi_free(session); - session->gssapi=NULL; - return SSH_PACKET_USED; - } - - if (output_token.length != 0){ - hexa = ssh_get_hexa(output_token.value, output_token.length); - SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa); - SAFE_FREE(hexa); - ssh_buffer_pack(session->out_buffer, - "bdP", - SSH2_MSG_USERAUTH_GSSAPI_TOKEN, - output_token.length, - (size_t)output_token.length, output_token.value); - packet_send(session); - } - if(maj_stat == GSS_S_COMPLETE){ - session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC; - } - return SSH_PACKET_USED; -} - -#endif /* WITH_SERVER */ - -static ssh_buffer ssh_gssapi_build_mic(ssh_session session){ - ssh_buffer mic_buffer; - int rc; - - mic_buffer = ssh_buffer_new(); - if (mic_buffer == NULL) { - ssh_set_error_oom(session); - return NULL; - } - - rc = ssh_buffer_pack(mic_buffer, - "dPbsss", - session->current_crypto->digest_len, - (size_t)session->current_crypto->digest_len, session->current_crypto->session_id, - SSH2_MSG_USERAUTH_REQUEST, - session->gssapi->user, - "ssh-connection", - "gssapi-with-mic"); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - ssh_buffer_free(mic_buffer); - return NULL; - } - - return mic_buffer; -} - -#ifdef WITH_SERVER - -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic) -{ - ssh_string mic_token; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER; - gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER; - ssh_buffer mic_buffer = NULL; - - (void)user; - (void)type; - - SSH_LOG(SSH_LOG_PACKET,"Received SSH_MSG_USERAUTH_GSSAPI_MIC"); - mic_token = buffer_get_ssh_string(packet); - if (mic_token == NULL) { - ssh_set_error(session, SSH_FATAL, "Missing MIC in packet"); - goto error; - } - if (session->gssapi == NULL - || session->gssapi->state != SSH_GSSAPI_STATE_RCV_MIC) { - ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_USERAUTH_GSSAPI_MIC in invalid state"); - goto error; - } - - mic_buffer = ssh_gssapi_build_mic(session); - if (mic_buffer == NULL) { - ssh_set_error_oom(session); - goto error; - } - if (ssh_callbacks_exists(session->server_callbacks, gssapi_verify_mic_function)){ - int rc = session->server_callbacks->gssapi_verify_mic_function(session, mic_token, - ssh_buffer_get_begin(mic_buffer), ssh_buffer_get_len(mic_buffer), - session->server_callbacks->userdata); - if (rc != SSH_OK) { - goto error; - } - } else { - mic_buf.length = ssh_buffer_get_len(mic_buffer); - mic_buf.value = ssh_buffer_get_begin(mic_buffer); - mic_token_buf.length = ssh_string_len(mic_token); - mic_token_buf.value = ssh_string_data(mic_token); - - maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL); - ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC", maj_stat); - ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC (min stat)", min_stat); - if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat)) { - goto error; - } - } - - if (ssh_callbacks_exists(session->server_callbacks, auth_gssapi_mic_function)){ - switch(session->server_callbacks->auth_gssapi_mic_function(session, - session->gssapi->user, session->gssapi->canonic_user, - session->server_callbacks->userdata)){ - case SSH_AUTH_SUCCESS: - ssh_auth_reply_success(session, 0); - break; - case SSH_AUTH_PARTIAL: - ssh_auth_reply_success(session, 1); - break; - default: - ssh_auth_reply_default(session, 0); - break; - } - } - - goto end; - -error: - ssh_auth_reply_default(session,0); - -end: - ssh_gssapi_free(session); - if (mic_buffer != NULL) { - ssh_buffer_free(mic_buffer); - } - if (mic_token != NULL) { - ssh_string_free(mic_token); - } - - return SSH_PACKET_USED; -} - -/** @brief returns the client credentials of the connected client. - * If the client has given a forwardable token, the SSH server will - * retrieve it. - * @returns gssapi credentials handle. - * @returns NULL if no forwardable token is available. - */ -ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session){ - if (!session || !session->gssapi || session->gssapi->client_creds == GSS_C_NO_CREDENTIAL) - return NULL; - return (ssh_gssapi_creds)session->gssapi->client_creds; -} - -#endif /* SERVER */ - -/** - * @brief Set the forwadable ticket to be given to the server for authentication. - * Unlike ssh_gssapi_get_creds() this is called on the client side of an ssh - * connection. - * - * @param[in] creds gssapi credentials handle. - */ -void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds) -{ - if (session == NULL) { - return; - } - if (session->gssapi == NULL) { - ssh_gssapi_init(session); - if (session->gssapi == NULL) { - return; - } - } - - session->gssapi->client.client_deleg_creds = (gss_cred_id_t)creds; -} - -static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){ - int rc; - int i; - - rc = ssh_buffer_pack(session->out_buffer, - "bsssd", - SSH2_MSG_USERAUTH_REQUEST, - session->opts.username, - "ssh-connection", - "gssapi-with-mic", - n_oid); - - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto fail; - } - - for (i=0; iout_buffer, oid_set[i]); - if (rc < 0) { - goto fail; - } - } - - session->auth_state = SSH_AUTH_STATE_GSSAPI_REQUEST_SENT; - return packet_send(session); -fail: - ssh_buffer_reinit(session->out_buffer); - return SSH_ERROR; -} - -/** @brief returns the OIDs of the mechs that have usable credentials - */ -static int ssh_gssapi_match(ssh_session session, gss_OID_set *valid_oids) -{ - OM_uint32 maj_stat, min_stat, lifetime; - gss_OID_set actual_mechs; - gss_buffer_desc namebuf; - gss_name_t client_id = GSS_C_NO_NAME; - gss_OID oid; - unsigned int i; - char *ptr; - int ret; - - if (session->gssapi->client.client_deleg_creds == NULL) { - if (session->opts.gss_client_identity != NULL) { - namebuf.value = (void *)session->opts.gss_client_identity; - namebuf.length = strlen(session->opts.gss_client_identity); - - maj_stat = gss_import_name(&min_stat, &namebuf, - GSS_C_NT_USER_NAME, &client_id); - if (GSS_ERROR(maj_stat)) { - ret = SSH_ERROR; - goto end; - } - } - - maj_stat = gss_acquire_cred(&min_stat, client_id, GSS_C_INDEFINITE, - GSS_C_NO_OID_SET, GSS_C_INITIATE, - &session->gssapi->client.creds, - &actual_mechs, NULL); - if (GSS_ERROR(maj_stat)) { - ret = SSH_ERROR; - goto end; - } - } else { - session->gssapi->client.creds = - session->gssapi->client.client_deleg_creds; - - maj_stat = gss_inquire_cred(&min_stat, session->gssapi->client.creds, - &client_id, NULL, NULL, &actual_mechs); - if (GSS_ERROR(maj_stat)) { - ret = SSH_ERROR; - goto end; - } - } - - gss_create_empty_oid_set(&min_stat, valid_oids); - - /* double check each single cred */ - for (i = 0; i < actual_mechs->count; i++) { - /* check lifetime is not 0 or skip */ - lifetime = 0; - oid = &actual_mechs->elements[i]; - maj_stat = gss_inquire_cred_by_mech(&min_stat, - session->gssapi->client.creds, - oid, NULL, &lifetime, NULL, NULL); - if (maj_stat == GSS_S_COMPLETE && lifetime > 0) { - gss_add_oid_set_member(&min_stat, oid, valid_oids); - ptr = ssh_get_hexa(oid->elements, oid->length); - SSH_LOG(SSH_LOG_DEBUG, "GSSAPI valid oid %d : %s\n", i, ptr); - SAFE_FREE(ptr); - } - } - - ret = SSH_OK; - -end: - gss_release_name(&min_stat, &client_id); - return ret; -} - -/** - * @brief launches a gssapi-with-mic auth request - * @returns SSH_AUTH_ERROR: A serious error happened\n - * SSH_AUTH_DENIED: Authentication failed : use another method\n - * SSH_AUTH_AGAIN: In nonblocking mode, you've got to call this again - * later. - */ -int ssh_gssapi_auth_mic(ssh_session session){ - int i; - gss_OID_set selected; /* oid selected for authentication */ - ssh_string *oids; - int rc; - int n_oids = 0; - OM_uint32 maj_stat, min_stat; - char name_buf[256]; - gss_buffer_desc hostname; - const char *gss_host = session->opts.host; - - rc = ssh_gssapi_init(session); - if (rc == SSH_ERROR) { - return SSH_AUTH_ERROR; - } - - if (session->opts.gss_server_identity != NULL) { - gss_host = session->opts.gss_server_identity; - } - /* import target host name */ - snprintf(name_buf, sizeof(name_buf), "host@%s", gss_host); - - hostname.value = name_buf; - hostname.length = strlen(name_buf) + 1; - maj_stat = gss_import_name(&min_stat, &hostname, - (gss_OID)GSS_C_NT_HOSTBASED_SERVICE, - &session->gssapi->client.server_name); - if (maj_stat != GSS_S_COMPLETE) { - SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat); - ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat); - return SSH_PACKET_USED; - } - - /* copy username */ - session->gssapi->user = strdup(session->opts.username); - if (session->gssapi->user == NULL) { - ssh_set_error_oom(session); - return SSH_AUTH_ERROR; - } - - SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi to host %s with user %s", - session->opts.host, session->gssapi->user); - rc = ssh_gssapi_match(session, &selected); - if (rc == SSH_ERROR) { - return SSH_AUTH_DENIED; - } - - n_oids = selected->count; - SSH_LOG(SSH_LOG_PROTOCOL, "Sending %d oids", n_oids); - - oids = calloc(n_oids, sizeof(ssh_string)); - if (oids == NULL) { - ssh_set_error_oom(session); - return SSH_AUTH_ERROR; - } - - for (i=0; ielements[i].length + 2); - ((unsigned char *)oids[i]->data)[0] = SSH_OID_TAG; - ((unsigned char *)oids[i]->data)[1] = selected->elements[i].length; - memcpy((unsigned char *)oids[i]->data + 2, selected->elements[i].elements, - selected->elements[i].length); - } - - rc = ssh_gssapi_send_auth_mic(session, oids, n_oids); - for (i = 0; i < n_oids; i++) { - ssh_string_free(oids[i]); - } - free(oids); - if (rc != SSH_ERROR) { - return SSH_AUTH_AGAIN; - } - - return SSH_AUTH_ERROR; -} - -static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s){ - gss_OID ret = malloc(sizeof (gss_OID_desc)); - unsigned char *data = ssh_string_data(oid_s); - size_t len = ssh_string_len(oid_s); - if(len > 256 || len <= 2){ - SAFE_FREE(ret); - return NULL; - } - if(data[0] != SSH_OID_TAG || data[1] != len - 2){ - SAFE_FREE(ret); - return NULL; - } - ret->elements = malloc(len - 2); - memcpy(ret->elements, &data[2], len-2); - ret->length = len-2; - return ret; -} - -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){ - ssh_string oid_s; - gss_uint32 maj_stat, min_stat; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - char *hexa; - (void)type; - (void)user; - - SSH_LOG(SSH_LOG_PACKET, "Received SSH_USERAUTH_GSSAPI_RESPONSE"); - if (session->auth_state != SSH_AUTH_STATE_GSSAPI_REQUEST_SENT){ - ssh_set_error(session, SSH_FATAL, "Invalid state in ssh_packet_userauth_gssapi_response"); - return SSH_PACKET_USED; - } - oid_s = buffer_get_ssh_string(packet); - if (!oid_s){ - ssh_set_error(session, SSH_FATAL, "Missing OID"); - return SSH_PACKET_USED; - } - session->gssapi->client.oid = ssh_gssapi_oid_from_string(oid_s); - ssh_string_free(oid_s); - if (!session->gssapi->client.oid) { - ssh_set_error(session, SSH_FATAL, "Invalid OID"); - return SSH_PACKET_USED; - } - - session->gssapi->client.flags = GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG; - if (session->opts.gss_delegate_creds) { - session->gssapi->client.flags |= GSS_C_DELEG_FLAG; - } - - /* prepare the first TOKEN response */ - maj_stat = gss_init_sec_context(&min_stat, - session->gssapi->client.creds, - &session->gssapi->ctx, - session->gssapi->client.server_name, - session->gssapi->client.oid, - session->gssapi->client.flags, - 0, NULL, &input_token, NULL, - &output_token, NULL, NULL); - if(GSS_ERROR(maj_stat)){ - ssh_gssapi_log_error(SSH_LOG_WARNING, "Initializing gssapi context", maj_stat); - return SSH_PACKET_USED; - } - if (output_token.length != 0){ - hexa = ssh_get_hexa(output_token.value, output_token.length); - SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa); - SAFE_FREE(hexa); - ssh_buffer_pack(session->out_buffer, - "bdP", - SSH2_MSG_USERAUTH_GSSAPI_TOKEN, - output_token.length, - (size_t)output_token.length, output_token.value); - packet_send(session); - session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN; - } - return SSH_PACKET_USED; -} - -static int ssh_gssapi_send_mic(ssh_session session){ - OM_uint32 maj_stat, min_stat; - gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER; - gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER; - ssh_buffer mic_buffer; - int rc; - - SSH_LOG(SSH_LOG_PACKET,"Sending SSH_MSG_USERAUTH_GSSAPI_MIC"); - - mic_buffer = ssh_gssapi_build_mic(session); - if (mic_buffer == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - mic_buf.length = ssh_buffer_get_len(mic_buffer); - mic_buf.value = ssh_buffer_get_begin(mic_buffer); - - maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT, &mic_buf, &mic_token_buf); - if (GSS_ERROR(maj_stat)){ - ssh_buffer_free(mic_buffer); - ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "generating MIC", maj_stat); - return SSH_ERROR; - } - - rc = ssh_buffer_pack(session->out_buffer, - "bdP", - SSH2_MSG_USERAUTH_GSSAPI_MIC, - mic_token_buf.length, - (size_t)mic_token_buf.length, mic_token_buf.value); - if (rc != SSH_OK) { - ssh_buffer_free(mic_buffer); - ssh_set_error_oom(session); - return SSH_ERROR; - } - - return packet_send(session); -} - -SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){ - ssh_string token; - char *hexa; - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER; - (void)user; - (void)type; - - SSH_LOG(SSH_LOG_PACKET,"Received SSH_MSG_USERAUTH_GSSAPI_TOKEN"); - if (!session->gssapi || session->auth_state != SSH_AUTH_STATE_GSSAPI_TOKEN){ - ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_USERAUTH_GSSAPI_TOKEN in invalid state"); - return SSH_PACKET_USED; - } - token = buffer_get_ssh_string(packet); - - if (token == NULL){ - ssh_set_error(session, SSH_REQUEST_DENIED, "ssh_packet_userauth_gssapi_token: invalid packet"); - return SSH_PACKET_USED; - } - hexa = ssh_get_hexa(ssh_string_data(token),ssh_string_len(token)); - SSH_LOG(SSH_LOG_PACKET, "GSSAPI Token : %s",hexa); - SAFE_FREE(hexa); - input_token.length = ssh_string_len(token); - input_token.value = ssh_string_data(token); - maj_stat = gss_init_sec_context(&min_stat, - session->gssapi->client.creds, - &session->gssapi->ctx, - session->gssapi->client.server_name, - session->gssapi->client.oid, - session->gssapi->client.flags, - 0, NULL, &input_token, NULL, - &output_token, NULL, NULL); - - ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat); - ssh_string_free(token); - if (GSS_ERROR(maj_stat)){ - ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "Gssapi error", maj_stat); - ssh_gssapi_free(session); - session->gssapi=NULL; - return SSH_PACKET_USED; - } - - if (output_token.length != 0){ - hexa = ssh_get_hexa(output_token.value, output_token.length); - SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa); - SAFE_FREE(hexa); - ssh_buffer_pack(session->out_buffer, - "bdP", - SSH2_MSG_USERAUTH_GSSAPI_TOKEN, - output_token.length, - (size_t)output_token.length, output_token.value); - packet_send(session); - } - if(maj_stat == GSS_S_COMPLETE){ - session->auth_state = SSH_AUTH_STATE_NONE; - ssh_gssapi_send_mic(session); - } - return SSH_PACKET_USED; -} diff --git a/libssh/src/gzip.c b/libssh/src/gzip.c deleted file mode 100644 index ca190bc2..00000000 --- a/libssh/src/gzip.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * gzip.c - hooks for compression of packets - * - * This file is part of the SSH Library - * - * Copyright (c) 2003 by Aris Adamantiadis - * Copyright (c) 2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/crypto.h" -#include "libssh/session.h" - -#define BLOCKSIZE 4092 - -static z_stream *initcompress(ssh_session session, int level) { - z_stream *stream = NULL; - int status; - - stream = malloc(sizeof(z_stream)); - if (stream == NULL) { - return NULL; - } - memset(stream, 0, sizeof(z_stream)); - - status = deflateInit(stream, level); - if (status != Z_OK) { - SAFE_FREE(stream); - ssh_set_error(session, SSH_FATAL, - "status %d inititalising zlib deflate", status); - return NULL; - } - - return stream; -} - -static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int level){ - z_stream *zout = session->current_crypto->compress_out_ctx; - void *in_ptr = buffer_get_rest(source); - unsigned long in_size = buffer_get_rest_len(source); - ssh_buffer dest = NULL; - unsigned char out_buf[BLOCKSIZE] = {0}; - unsigned long len; - int status; - - if(zout == NULL) { - zout = session->current_crypto->compress_out_ctx = initcompress(session, level); - if (zout == NULL) { - return NULL; - } - } - - dest = ssh_buffer_new(); - if (dest == NULL) { - return NULL; - } - - zout->next_out = out_buf; - zout->next_in = in_ptr; - zout->avail_in = in_size; - do { - zout->avail_out = BLOCKSIZE; - status = deflate(zout, Z_PARTIAL_FLUSH); - if (status != Z_OK) { - ssh_buffer_free(dest); - ssh_set_error(session, SSH_FATAL, - "status %d deflating zlib packet", status); - return NULL; - } - len = BLOCKSIZE - zout->avail_out; - if (ssh_buffer_add_data(dest, out_buf, len) < 0) { - ssh_buffer_free(dest); - return NULL; - } - zout->next_out = out_buf; - } while (zout->avail_out == 0); - - return dest; -} - -int compress_buffer(ssh_session session, ssh_buffer buf) { - ssh_buffer dest = NULL; - - dest = gzip_compress(session, buf, session->opts.compressionlevel); - if (dest == NULL) { - return -1; - } - - if (ssh_buffer_reinit(buf) < 0) { - ssh_buffer_free(dest); - return -1; - } - - if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) { - ssh_buffer_free(dest); - return -1; - } - - ssh_buffer_free(dest); - return 0; -} - -/* decompression */ - -static z_stream *initdecompress(ssh_session session) { - z_stream *stream = NULL; - int status; - - stream = malloc(sizeof(z_stream)); - if (stream == NULL) { - return NULL; - } - memset(stream,0,sizeof(z_stream)); - - status = inflateInit(stream); - if (status != Z_OK) { - SAFE_FREE(stream); - ssh_set_error(session, SSH_FATAL, - "Status = %d initiating inflate context!", status); - return NULL; - } - - return stream; -} - -static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t maxlen) { - z_stream *zin = session->current_crypto->compress_in_ctx; - void *in_ptr = buffer_get_rest(source); - unsigned long in_size = buffer_get_rest_len(source); - unsigned char out_buf[BLOCKSIZE] = {0}; - ssh_buffer dest = NULL; - unsigned long len; - int status; - - if (zin == NULL) { - zin = session->current_crypto->compress_in_ctx = initdecompress(session); - if (zin == NULL) { - return NULL; - } - } - - dest = ssh_buffer_new(); - if (dest == NULL) { - return NULL; - } - - zin->next_out = out_buf; - zin->next_in = in_ptr; - zin->avail_in = in_size; - - do { - zin->avail_out = BLOCKSIZE; - status = inflate(zin, Z_PARTIAL_FLUSH); - if (status != Z_OK && status != Z_BUF_ERROR) { - ssh_set_error(session, SSH_FATAL, - "status %d inflating zlib packet", status); - ssh_buffer_free(dest); - return NULL; - } - - len = BLOCKSIZE - zin->avail_out; - if (ssh_buffer_add_data(dest,out_buf,len) < 0) { - ssh_buffer_free(dest); - return NULL; - } - if (buffer_get_rest_len(dest) > maxlen){ - /* Size of packet exceeded, avoid a denial of service attack */ - ssh_buffer_free(dest); - return NULL; - } - zin->next_out = out_buf; - } while (zin->avail_out == 0); - - return dest; -} - -int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen){ - ssh_buffer dest = NULL; - - dest = gzip_decompress(session,buf, maxlen); - if (dest == NULL) { - return -1; - } - - if (ssh_buffer_reinit(buf) < 0) { - ssh_buffer_free(dest); - return -1; - } - - if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) { - ssh_buffer_free(dest); - return -1; - } - - ssh_buffer_free(dest); - return 0; -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/init.c b/libssh/src/init.c deleted file mode 100644 index 241b8618..00000000 --- a/libssh/src/init.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * init.c - initialization and finalization of the library - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include "libssh/priv.h" -#include "libssh/socket.h" -#include "libssh/dh.h" -#include "libssh/poll.h" -#include "libssh/threads.h" - -#ifdef _WIN32 -#include -#endif - -/** - * @defgroup libssh The libssh API - * - * The libssh library is implementing the SSH protocols and some of its - * extensions. This group of functions is mostly used to implment a SSH client. - * Some function are needed to implement a SSH server too. - * - * @{ - */ - -/** - * @brief Initialize global cryptographic data structures. - * - * This function should only be called once, at the beginning of the program, in - * the main thread. It may be omitted if your program is not multithreaded. - * - * @returns 0 on success, -1 if an error occured. - */ -int ssh_init(void) { - if(ssh_threads_init()) - return -1; - if(ssh_crypto_init()) - return -1; - if(ssh_socket_init()) - return -1; - return 0; -} - - -/** - * @brief Finalize and cleanup all libssh and cryptographic data structures. - * - * This function should only be called once, at the end of the program! - * - * @returns 0 on succes, -1 if an error occured. - * - @returns 0 otherwise - */ -int ssh_finalize(void) { - ssh_crypto_finalize(); - ssh_socket_cleanup(); - /* It is important to finalize threading after CRYPTO because - * it still depends on it */ - ssh_threads_finalize(); - - return 0; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/kex.c b/libssh/src/kex.c deleted file mode 100644 index f1a1b566..00000000 --- a/libssh/src/kex.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * kex.c - key exchange - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/dh.h" -#include "libssh/kex.h" -#include "libssh/session.h" -#include "libssh/ssh2.h" -#include "libssh/string.h" -#include "libssh/curve25519.h" -#include "libssh/knownhosts.h" - -#ifdef HAVE_LIBGCRYPT -# define BLOWFISH "blowfish-cbc," -# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc," -# define DES "3des-cbc,des-cbc-ssh1" -#elif defined(HAVE_LIBCRYPTO) -# ifdef HAVE_OPENSSL_BLOWFISH_H -# define BLOWFISH "blowfish-cbc," -# else -# define BLOWFISH "" -# endif -# ifdef HAVE_OPENSSL_AES_H -# ifdef BROKEN_AES_CTR -# define AES "aes256-cbc,aes192-cbc,aes128-cbc," -# else -# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc," -# endif /* BROKEN_AES_CTR */ -# else -# define AES "" -# endif -# define DES "3des-cbc,des-cbc-ssh1" -#endif - -#ifdef WITH_ZLIB -#define ZLIB "none,zlib,zlib@openssh.com" -#else -#define ZLIB "none" -#endif - -#ifdef HAVE_CURVE25519 -#define CURVE25519 "curve25519-sha256@libssh.org," -#else -#define CURVE25519 "" -#endif - -#ifdef HAVE_ECDH -#define ECDH "ecdh-sha2-nistp256," -#define HOSTKEYS "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss" -#else -#define HOSTKEYS "ssh-rsa,ssh-dss" -#define ECDH "" -#endif - -#define KEY_EXCHANGE CURVE25519 ECDH "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" -#define KEX_METHODS_SIZE 10 - -/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */ -static const char *default_methods[] = { - KEY_EXCHANGE, - HOSTKEYS, - AES BLOWFISH DES, - AES BLOWFISH DES, - "hmac-sha1,hmac-sha2-256,hmac-sha2-512", - "hmac-sha1,hmac-sha2-256,hmac-sha2-512", - "none", - "none", - "", - "", - NULL -}; - -/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */ -static const char *supported_methods[] = { - KEY_EXCHANGE, - HOSTKEYS, - AES BLOWFISH DES, - AES BLOWFISH DES, - "hmac-sha1,hmac-sha2-256,hmac-sha2-512", - "hmac-sha1,hmac-sha2-256,hmac-sha2-512", - ZLIB, - ZLIB, - "", - "", - NULL -}; - -/* descriptions of the key exchange packet */ -static const char *ssh_kex_descriptions[] = { - "kex algos", - "server host key algo", - "encryption client->server", - "encryption server->client", - "mac algo client->server", - "mac algo server->client", - "compression algo client->server", - "compression algo server->client", - "languages client->server", - "languages server->client", - NULL -}; - -/* tokenize will return a token of strings delimited by ",". the first element has to be freed */ -static char **tokenize(const char *chain){ - char **tokens; - int n=1; - int i=0; - char *tmp; - char *ptr; - - tmp = strdup(chain); - if (tmp == NULL) { - return NULL; - } - ptr = tmp; - while(*ptr){ - if(*ptr==','){ - n++; - *ptr=0; - } - ptr++; - } - /* now n contains the number of tokens, the first possibly empty if the list was empty too e.g. "" */ - tokens=malloc(sizeof(char *) * (n+1) ); /* +1 for the null */ - if (tokens == NULL) { - SAFE_FREE(tmp); - return NULL; - } - ptr=tmp; - for(i=0;i= KEX_METHODS_SIZE) { - return NULL; - } - - return supported_methods[algo]; -} - -const char *ssh_kex_get_description(uint32_t algo) { - if (algo >= KEX_METHODS_SIZE) { - return NULL; - } - - return ssh_kex_descriptions[algo]; -} - -/* find_matching gets 2 parameters : a list of available objects (available_d), separated by colons,*/ -/* and a list of preferred objects (preferred_d) */ -/* it will return a strduped pointer on the first preferred object found in the available objects list */ - -char *ssh_find_matching(const char *available_d, const char *preferred_d){ - char ** tok_available, **tok_preferred; - int i_avail, i_pref; - char *ret; - - if ((available_d == NULL) || (preferred_d == NULL)) { - return NULL; /* don't deal with null args */ - } - - tok_available = tokenize(available_d); - if (tok_available == NULL) { - return NULL; - } - - tok_preferred = tokenize(preferred_d); - if (tok_preferred == NULL) { - SAFE_FREE(tok_available[0]); - SAFE_FREE(tok_available); - return NULL; - } - - for(i_pref=0; tok_preferred[i_pref] ; ++i_pref){ - for(i_avail=0; tok_available[i_avail]; ++i_avail){ - if(strcmp(tok_available[i_avail],tok_preferred[i_pref]) == 0){ - /* match */ - ret=strdup(tok_available[i_avail]); - /* free the tokens */ - SAFE_FREE(tok_available[0]); - SAFE_FREE(tok_preferred[0]); - SAFE_FREE(tok_available); - SAFE_FREE(tok_preferred); - return ret; - } - } - } - SAFE_FREE(tok_available[0]); - SAFE_FREE(tok_preferred[0]); - SAFE_FREE(tok_available); - SAFE_FREE(tok_preferred); - return NULL; -} - -/** - * @internal - * @brief returns whether the first client key exchange algorithm matches - * the first server key exchange algorithm - * @returns whether the first client key exchange algorithm matches - * the first server key exchange algorithm - */ -static int is_first_kex_packet_follows_guess_wrong(const char *client_kex, - const char *server_kex) { - int is_wrong = 1; - char **server_kex_tokens = NULL; - char **client_kex_tokens = NULL; - - if ((client_kex == NULL) || (server_kex == NULL)) { - goto out; - } - - client_kex_tokens = tokenize(client_kex); - - if (client_kex_tokens == NULL) { - goto out; - } - - if (client_kex_tokens[0] == NULL) { - goto freeout; - } - - server_kex_tokens = tokenize(server_kex); - if (server_kex_tokens == NULL) { - goto freeout; - } - - is_wrong = (strcmp(client_kex_tokens[0], server_kex_tokens[0]) != 0); - - SAFE_FREE(server_kex_tokens[0]); - SAFE_FREE(server_kex_tokens); -freeout: - SAFE_FREE(client_kex_tokens[0]); - SAFE_FREE(client_kex_tokens); -out: - return is_wrong; -} - -SSH_PACKET_CALLBACK(ssh_packet_kexinit){ - int i; - int server_kex=session->server; - ssh_string str = NULL; - char *strings[KEX_METHODS_SIZE]; - int rc = SSH_ERROR; - - uint8_t first_kex_packet_follows = 0; - uint32_t kexinit_reserved = 0; - - (void)type; - (void)user; - - memset(strings, 0, sizeof(strings)); - if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){ - SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange"); - } else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){ - ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state"); - goto error; - } - - if (server_kex) { - rc = buffer_get_data(packet,session->next_crypto->client_kex.cookie, 16); - if (rc != 16) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet"); - goto error; - } - - rc = hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed"); - goto error; - } - } else { - rc = buffer_get_data(packet,session->next_crypto->server_kex.cookie, 16); - if (rc != 16) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet"); - goto error; - } - - rc = hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed"); - goto error; - } - } - - for (i = 0; i < KEX_METHODS_SIZE; i++) { - str = buffer_get_ssh_string(packet); - if (str == NULL) { - break; - } - - rc = buffer_add_ssh_string(session->in_hashbuf, str); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer"); - goto error; - } - - strings[i] = ssh_string_to_char(str); - if (strings[i] == NULL) { - ssh_set_error_oom(session); - goto error; - } - ssh_string_free(str); - str = NULL; - } - - /* copy the server kex info into an array of strings */ - if (server_kex) { - for (i = 0; i < SSH_KEX_METHODS; i++) { - session->next_crypto->client_kex.methods[i] = strings[i]; - } - } else { /* client */ - for (i = 0; i < SSH_KEX_METHODS; i++) { - session->next_crypto->server_kex.methods[i] = strings[i]; - } - } - - /* - * Handle the two final fields for the KEXINIT message (RFC 4253 7.1): - * - * boolean first_kex_packet_follows - * uint32 0 (reserved for future extension) - * - * Notably if clients set 'first_kex_packet_follows', it is expected - * that its value is included when computing the session ID (see - * 'make_sessionid'). - */ - if (server_kex) { - rc = buffer_get_u8(packet, &first_kex_packet_follows); - if (rc != 1) { - goto error; - } - - rc = buffer_add_u8(session->in_hashbuf, first_kex_packet_follows); - if (rc < 0) { - goto error; - } - - rc = buffer_add_u32(session->in_hashbuf, kexinit_reserved); - if (rc < 0) { - goto error; - } - - /* - * Remember whether 'first_kex_packet_follows' was set and the client - * guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message - * must be ignored. - */ - if (first_kex_packet_follows) { - session->first_kex_follows_guess_wrong = - is_first_kex_packet_follows_guess_wrong(session->next_crypto->client_kex.methods[SSH_KEX], - session->next_crypto->server_kex.methods[SSH_KEX]); - } - } - - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED; - session->dh_handshake_state = DH_STATE_INIT; - session->ssh_connection_callback(session); - return SSH_PACKET_USED; - -error: - ssh_string_free(str); - for (i = 0; i < SSH_KEX_METHODS; i++) { - SAFE_FREE(strings[i]); - } - - session->session_state = SSH_SESSION_STATE_ERROR; - - return SSH_PACKET_USED; -} - -void ssh_list_kex(struct ssh_kex_struct *kex) { - int i = 0; - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("session cookie", kex->cookie, 16); -#endif - - for(i = 0; i < SSH_KEX_METHODS; i++) { - if (kex->methods[i] == NULL) { - continue; - } - SSH_LOG(SSH_LOG_FUNCTIONS, "%s: %s", - ssh_kex_descriptions[i], kex->methods[i]); - } -} - -/** - * @internal - * @brief selects the hostkey mechanisms to be chosen for the key exchange, - * as some hostkey mechanisms may be present in known_hosts file and preferred - * @returns a cstring containing a comma-separated list of hostkey methods. - * NULL if no method matches - */ -static char *ssh_client_select_hostkeys(ssh_session session){ - char methods_buffer[128]={0}; - static const char *preferred_hostkeys[]={"ecdsa-sha2-nistp521","ecdsa-sha2-nistp384", - "ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss", "ssh-rsa1", NULL}; - char **methods; - int i,j; - int needcoma=0; - - methods = ssh_knownhosts_algorithms(session); - if (methods == NULL || methods[0] == NULL){ - SAFE_FREE(methods); - return NULL; - } - - for (i=0;preferred_hostkeys[i] != NULL; ++i){ - for (j=0; methods[j] != NULL; ++j){ - if(strcmp(preferred_hostkeys[i], methods[j]) == 0){ - if (verify_existing_algo(SSH_HOSTKEYS, methods[j])){ - if(needcoma) - strncat(methods_buffer,",",sizeof(methods_buffer)-strlen(methods_buffer)-1); - strncat(methods_buffer, methods[j], sizeof(methods_buffer)-strlen(methods_buffer)-1); - needcoma = 1; - } - } - } - } - for(i=0;methods[i]!= NULL; ++i){ - SAFE_FREE(methods[i]); - } - SAFE_FREE(methods); - - if(strlen(methods_buffer) > 0){ - SSH_LOG(SSH_LOG_DEBUG, "Changing host key method to \"%s\"", methods_buffer); - return strdup(methods_buffer); - } else { - SSH_LOG(SSH_LOG_DEBUG, "No supported kex method for existing key in known_hosts file"); - return NULL; - } - -} -/** - * @brief sets the key exchange parameters to be sent to the server, - * in function of the options and available methods. - */ -int set_client_kex(ssh_session session){ - struct ssh_kex_struct *client= &session->next_crypto->client_kex; - const char *wanted; - int i; - - ssh_get_random(client->cookie, 16, 0); - - memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **)); - /* first check if we have specific host key methods */ - if(session->opts.wanted_methods[SSH_HOSTKEYS] == NULL){ - /* Only if no override */ - session->opts.wanted_methods[SSH_HOSTKEYS] = - ssh_client_select_hostkeys(session); - } - - for (i = 0; i < KEX_METHODS_SIZE; i++) { - wanted = session->opts.wanted_methods[i]; - if (wanted == NULL) - wanted = default_methods[i]; - client->methods[i] = strdup(wanted); - } - - return SSH_OK; -} - -/** @brief Select the different methods on basis of client's and - * server's kex messages, and watches out if a match is possible. - */ -int ssh_kex_select_methods (ssh_session session){ - struct ssh_kex_struct *server = &session->next_crypto->server_kex; - struct ssh_kex_struct *client = &session->next_crypto->client_kex; - int i; - - for (i = 0; i < KEX_METHODS_SIZE; i++) { - session->next_crypto->kex_methods[i]=ssh_find_matching(server->methods[i],client->methods[i]); - if(session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){ - ssh_set_error(session,SSH_FATAL,"kex error : no match for method %s: server [%s], client [%s]", - ssh_kex_descriptions[i],server->methods[i],client->methods[i]); - return SSH_ERROR; - } else if ((i >= SSH_LANG_C_S) && (session->next_crypto->kex_methods[i] == NULL)) { - /* we can safely do that for languages */ - session->next_crypto->kex_methods[i] = strdup(""); - } - } - if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){ - session->next_crypto->kex_type=SSH_KEX_DH_GROUP1_SHA1; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){ - session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){ - session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){ - session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG; - } - - return SSH_OK; -} - - -/* this function only sends the predefined set of kex methods */ -int ssh_send_kex(ssh_session session, int server_kex) { - struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex : - &session->next_crypto->client_kex); - ssh_string str = NULL; - int i; - int rc; - - rc = ssh_buffer_pack(session->out_buffer, - "bP", - SSH2_MSG_KEXINIT, - 16, - kex->cookie); /* cookie */ - if (rc != SSH_OK) - goto error; - if (hashbufout_add_cookie(session) < 0) { - goto error; - } - - ssh_list_kex(kex); - - for (i = 0; i < KEX_METHODS_SIZE; i++) { - str = ssh_string_from_char(kex->methods[i]); - if (str == NULL) { - goto error; - } - - if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) { - goto error; - } - if (buffer_add_ssh_string(session->out_buffer, str) < 0) { - goto error; - } - ssh_string_free(str); - str = NULL; - } - - rc = ssh_buffer_pack(session->out_buffer, - "bd", - 0, - 0); - if (rc != SSH_OK) { - goto error; - } - - if (packet_send(session) == SSH_ERROR) { - return -1; - } - - return 0; -error: - ssh_buffer_reinit(session->out_buffer); - ssh_buffer_reinit(session->out_hashbuf); - ssh_string_free(str); - - return -1; -} - -/* returns 1 if at least one of the name algos is in the default algorithms table */ -int verify_existing_algo(int algo, const char *name){ - char *ptr; - if(algo>9 || algo <0) - return -1; - ptr=ssh_find_matching(supported_methods[algo],name); - if(ptr){ - free(ptr); - return 1; - } - return 0; -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/kex1.c b/libssh/src/kex1.c deleted file mode 100644 index 758054f8..00000000 --- a/libssh/src/kex1.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * kex.c - key exchange - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#ifndef _WIN32 -#include -#endif - -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/crypto.h" -#include "libssh/kex.h" -#include "libssh/keys.h" -#include "libssh/session.h" -#include "libssh/ssh1.h" -#include "libssh/wrapper.h" - -/* SSHv1 functions */ - -/* makes a STRING contating 3 strings : ssh-rsa1,e and n */ -/* this is a public key in openssh's format */ -static ssh_string make_rsa1_string(ssh_string e, ssh_string n){ - ssh_buffer buffer = NULL; - ssh_string rsa = NULL; - ssh_string ret = NULL; - - buffer = ssh_buffer_new(); - rsa = ssh_string_from_char("ssh-rsa1"); - if (rsa == NULL) { - goto error; - } - - if (buffer_add_ssh_string(buffer, rsa) < 0) { - goto error; - } - if (buffer_add_ssh_string(buffer, e) < 0) { - goto error; - } - if (buffer_add_ssh_string(buffer, n) < 0) { - goto error; - } - - ret = ssh_string_new(ssh_buffer_get_len(buffer)); - if (ret == NULL) { - goto error; - } - - ssh_string_fill(ret, ssh_buffer_get_begin(buffer), ssh_buffer_get_len(buffer)); -error: - ssh_buffer_free(buffer); - ssh_string_free(rsa); - - return ret; -} - -static int build_session_id1(ssh_session session, ssh_string servern, - ssh_string hostn) { - MD5CTX md5 = NULL; - - md5 = md5_init(); - if (md5 == NULL) { - return -1; - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("host modulus",ssh_string_data(hostn),ssh_string_len(hostn)); - ssh_print_hexa("server modulus",ssh_string_data(servern),ssh_string_len(servern)); -#endif - md5_update(md5,ssh_string_data(hostn),ssh_string_len(hostn)); - md5_update(md5,ssh_string_data(servern),ssh_string_len(servern)); - md5_update(md5,session->next_crypto->server_kex.cookie,8); - if(session->next_crypto->session_id != NULL) - SAFE_FREE(session->next_crypto->session_id); - session->next_crypto->session_id = malloc(MD5_DIGEST_LEN); - if(session->next_crypto->session_id == NULL){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - md5_final(session->next_crypto->session_id,md5); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN); -#endif - - return 0; -} - -/* returns 1 if the modulus of k1 is < than the one of k2 */ -static int modulus_smaller(ssh_public_key k1, ssh_public_key k2){ - bignum n1; - bignum n2; - int res; -#ifdef HAVE_LIBGCRYPT - gcry_sexp_t sexp; - sexp=gcry_sexp_find_token(k1->rsa_pub,"n",0); - n1=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG); - gcry_sexp_release(sexp); - sexp=gcry_sexp_find_token(k2->rsa_pub,"n",0); - n2=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG); - gcry_sexp_release(sexp); -#elif defined HAVE_LIBCRYPTO - n1=k1->rsa_pub->n; - n2=k2->rsa_pub->n; -#endif - if(bignum_cmp(n1,n2)<0) - res=1; - else - res=0; -#ifdef HAVE_LIBGCRYPT - bignum_free(n1); - bignum_free(n2); -#endif - return res; - -} - -static ssh_string ssh_encrypt_rsa1(ssh_session session, - ssh_string data, - ssh_public_key key) { - ssh_string str = NULL; - size_t len = ssh_string_len(data); - size_t size = 0; -#ifdef HAVE_LIBGCRYPT - const char *tmp = NULL; - gcry_sexp_t ret_sexp; - gcry_sexp_t data_sexp; - - if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))", - len, ssh_string_data(data))) { - ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); - return NULL; - } - if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) { - gcry_sexp_release(data_sexp); - ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); - return NULL; - } - - gcry_sexp_release(data_sexp); - - data_sexp = gcry_sexp_find_token(ret_sexp, "a", 0); - if (data_sexp == NULL) { - ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); - gcry_sexp_release(ret_sexp); - return NULL; - } - tmp = gcry_sexp_nth_data(data_sexp, 1, &size); - if (*tmp == 0) { - size--; - tmp++; - } - - str = ssh_string_new(size); - if (str == NULL) { - ssh_set_error(session, SSH_FATAL, "Not enough space"); - gcry_sexp_release(data_sexp); - gcry_sexp_release(ret_sexp); - return NULL; - } - ssh_string_fill(str, tmp, size); - - gcry_sexp_release(data_sexp); - gcry_sexp_release(ret_sexp); -#elif defined HAVE_LIBCRYPTO - size = RSA_size(key->rsa_pub); - - str = ssh_string_new(size); - if (str == NULL) { - ssh_set_error(session, SSH_FATAL, "Not enough space"); - return NULL; - } - - if (RSA_public_encrypt(len, ssh_string_data(data), ssh_string_data(str), key->rsa_pub, - RSA_PKCS1_PADDING) < 0) { - ssh_string_free(str); - return NULL; - } -#endif - - return str; -} - -#define ABS(A) ( (A)<0 ? -(A):(A) ) -static ssh_string encrypt_session_key(ssh_session session, ssh_public_key srvkey, - ssh_public_key hostkey, int slen, int hlen) { - unsigned char buffer[32] = {0}; - int i; - ssh_string data1 = NULL; - ssh_string data2 = NULL; - if(session->next_crypto->encryptkey != NULL) - SAFE_FREE(session->next_crypto->encryptkey); - if(session->next_crypto->decryptkey != NULL) - SAFE_FREE(session->next_crypto->decryptkey); - if(session->next_crypto->encryptIV != NULL) - SAFE_FREE(session->next_crypto->encryptIV); - if(session->next_crypto->decryptIV != NULL) - SAFE_FREE(session->next_crypto->decryptIV); - session->next_crypto->encryptkey = malloc(32); - session->next_crypto->decryptkey = malloc(32); - session->next_crypto->encryptIV = malloc(32); - session->next_crypto->decryptIV = malloc(32); - if(session->next_crypto->encryptkey == NULL || - session->next_crypto->decryptkey == NULL || - session->next_crypto->encryptIV == NULL || - session->next_crypto->decryptIV == NULL){ - ssh_set_error_oom(session); - return NULL; - } - /* first, generate a session key */ - ssh_get_random(session->next_crypto->encryptkey, 32, 1); - memcpy(buffer, session->next_crypto->encryptkey, 32); - memcpy(session->next_crypto->decryptkey, session->next_crypto->encryptkey, 32); - memset(session->next_crypto->encryptIV, 0, 32); - memset(session->next_crypto->decryptIV, 0, 32); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("session key",buffer,32); -#endif - - /* xor session key with session_id */ - for (i = 0; i < 16; i++) { - buffer[i] ^= session->next_crypto->session_id[i]; - } - data1 = ssh_string_new(32); - if (data1 == NULL) { - return NULL; - } - ssh_string_fill(data1, buffer, 32); - if (ABS(hlen - slen) < 128){ - SSH_LOG(SSH_LOG_FUNCTIONS, - "Difference between server modulus and host modulus is only %d. " - "It's illegal and may not work", - ABS(hlen - slen)); - } - - if (modulus_smaller(srvkey, hostkey)) { - data2 = ssh_encrypt_rsa1(session, data1, srvkey); - ssh_string_free(data1); - data1 = NULL; - if (data2 == NULL) { - return NULL; - } - data1 = ssh_encrypt_rsa1(session, data2, hostkey); - ssh_string_free(data2); - if (data1 == NULL) { - return NULL; - } - } else { - data2 = ssh_encrypt_rsa1(session, data1, hostkey); - ssh_string_free(data1); - data1 = NULL; - if (data2 == NULL) { - return NULL; - } - data1 = ssh_encrypt_rsa1(session, data2, srvkey); - ssh_string_free(data2); - if (data1 == NULL) { - return NULL; - } - } - - return data1; -} - -/* 2 SSH_SMSG_PUBLIC_KEY - * - * 8 bytes anti_spoofing_cookie - * 32-bit int server_key_bits - * mp-int server_key_public_exponent - * mp-int server_key_public_modulus - * 32-bit int host_key_bits - * mp-int host_key_public_exponent - * mp-int host_key_public_modulus - * 32-bit int protocol_flags - * 32-bit int supported_ciphers_mask - * 32-bit int supported_authentications_mask - */ -/** - * @brief Wait for a SSH_SMSG_PUBLIC_KEY and does the key exchange - */ -SSH_PACKET_CALLBACK(ssh_packet_publickey1){ - ssh_string server_exp = NULL; - ssh_string server_mod = NULL; - ssh_string host_exp = NULL; - ssh_string host_mod = NULL; - ssh_string serverkey = NULL; - ssh_string hostkey = NULL; - ssh_public_key srv = NULL; - ssh_public_key host = NULL; - uint32_t server_bits; - uint32_t host_bits; - uint32_t protocol_flags; - uint32_t supported_ciphers_mask; - uint32_t supported_authentications_mask; - ssh_string enc_session = NULL; - uint16_t bits; - int ko; - uint32_t support_3DES = 0; - uint32_t support_DES = 0; - - (void)type; - (void)user; - SSH_LOG(SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY"); - if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){ - ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state"); - goto error; - } - if (buffer_get_data(packet, session->next_crypto->server_kex.cookie, 8) != 8) { - ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer"); - goto error; - } - - buffer_get_u32(packet, &server_bits); - server_exp = buffer_get_mpint(packet); - if (server_exp == NULL) { - goto error; - } - server_mod = buffer_get_mpint(packet); - if (server_mod == NULL) { - goto error; - } - buffer_get_u32(packet, &host_bits); - host_exp = buffer_get_mpint(packet); - if (host_exp == NULL) { - goto error; - } - host_mod = buffer_get_mpint(packet); - if (host_mod == NULL) { - goto error; - } - buffer_get_u32(packet, &protocol_flags); - buffer_get_u32(packet, &supported_ciphers_mask); - ko = buffer_get_u32(packet, &supported_authentications_mask); - - if ((ko != sizeof(uint32_t)) || !host_mod || !host_exp - || !server_mod || !server_exp) { - SSH_LOG(SSH_LOG_RARE, "Invalid SSH_SMSG_PUBLIC_KEY packet"); - ssh_set_error(session, SSH_FATAL, "Invalid SSH_SMSG_PUBLIC_KEY packet"); - goto error; - } - - server_bits = ntohl(server_bits); - host_bits = ntohl(host_bits); - protocol_flags = ntohl(protocol_flags); - supported_ciphers_mask = ntohl(supported_ciphers_mask); - supported_authentications_mask = ntohl(supported_authentications_mask); - SSH_LOG(SSH_LOG_PROTOCOL, - "Server bits: %d; Host bits: %d; Protocol flags: %.8lx; " - "Cipher mask: %.8lx; Auth mask: %.8lx", - server_bits, - host_bits, - (unsigned long int) protocol_flags, - (unsigned long int) supported_ciphers_mask, - (unsigned long int) supported_authentications_mask); - - serverkey = make_rsa1_string(server_exp, server_mod); - if (serverkey == NULL) { - goto error; - } - hostkey = make_rsa1_string(host_exp,host_mod); - if (hostkey == NULL) { - goto error; - } - if (build_session_id1(session, server_mod, host_mod) < 0) { - goto error; - } - - srv = publickey_from_string(session, serverkey); - if (srv == NULL) { - goto error; - } - host = publickey_from_string(session, hostkey); - if (host == NULL) { - goto error; - } - - session->next_crypto->server_pubkey = ssh_string_copy(hostkey); - if (session->next_crypto->server_pubkey == NULL) { - goto error; - } - session->next_crypto->server_pubkey_type = "ssh-rsa1"; - - /* now, we must choose an encryption algo */ - /* hardcode 3des */ - // - support_3DES = (supported_ciphers_mask & (1<out_buffer, SSH_CMSG_SESSION_KEY) < 0) { - goto error; - } - if (buffer_add_u8(session->out_buffer, support_3DES ? SSH_CIPHER_3DES : SSH_CIPHER_DES) < 0) { - goto error; - } - if (ssh_buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) { - goto error; - } - - enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits); - if (enc_session == NULL) { - goto error; - } - - bits = ssh_string_len(enc_session) * 8 - 7; - SSH_LOG(SSH_LOG_PROTOCOL, "%d bits, %" PRIdS " bytes encrypted session", - bits, ssh_string_len(enc_session)); - bits = htons(bits); - /* the encrypted mpint */ - if (ssh_buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) { - goto error; - } - if (ssh_buffer_add_data(session->out_buffer, ssh_string_data(enc_session), - ssh_string_len(enc_session)) < 0) { - goto error; - } - /* the protocol flags */ - if (buffer_add_u32(session->out_buffer, 0) < 0) { - goto error; - } - session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED; - if (packet_send(session) == SSH_ERROR) { - goto error; - } - - /* we can set encryption */ - if(crypt_set_algorithms(session, support_3DES ? SSH_3DES : SSH_DES)){ - goto error; - } - - session->current_crypto = session->next_crypto; - session->next_crypto = NULL; - goto end; -error: - session->session_state=SSH_SESSION_STATE_ERROR; -end: - - ssh_string_free(host_mod); - ssh_string_free(host_exp); - ssh_string_free(server_mod); - ssh_string_free(server_exp); - ssh_string_free(serverkey); - ssh_string_free(hostkey); - ssh_string_free(enc_session); - - publickey_free(srv); - publickey_free(host); - - return SSH_PACKET_USED; -} - -int ssh_get_kex1(ssh_session session) { - SSH_LOG(SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY"); - - /* Here the callback is called */ - while(session->session_state==SSH_SESSION_STATE_INITIAL_KEX){ - ssh_handle_packets(session, SSH_TIMEOUT_USER); - } - if (session->session_state==SSH_SESSION_STATE_ERROR) { - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS"); - /* Waiting for SSH_SMSG_SUCCESS */ - while(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){ - ssh_handle_packets(session, SSH_TIMEOUT_USER); - } - if(session->session_state==SSH_SESSION_STATE_ERROR) { - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n"); - - return SSH_OK; -} diff --git a/libssh/src/known_hosts.c b/libssh/src/known_hosts.c deleted file mode 100644 index 8c05c8de..00000000 --- a/libssh/src/known_hosts.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - * keyfiles.c - private and public key handling for authentication. - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2009 by Aris Adamantiadis - * Copyright (c) 2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/buffer.h" -#include "libssh/misc.h" -#include "libssh/pki.h" -#include "libssh/options.h" -#include "libssh/knownhosts.h" -/*todo: remove this include */ -#include "libssh/string.h" - -#ifdef HAVE_LIBGCRYPT -#include -#elif defined HAVE_LIBCRYPTO -#include -#include -#include -#include -#endif /* HAVE_LIBCRYPTO */ - -#ifndef _WIN32 -# include -# include -#endif - -/** - * @addtogroup libssh_session - * - * @{ - */ - -static int alldigits(const char *s) { - while (*s) { - if (isdigit(*s)) { - s++; - } else { - return 0; - } - } - - return 1; -} - -/** - * @internal - * - * @brief Free a token array. - */ -static void tokens_free(char **tokens) { - if (tokens == NULL) { - return; - } - - SAFE_FREE(tokens[0]); - /* It's not needed to free other pointers because tokens generated by - * space_tokenize fit all in one malloc - */ - SAFE_FREE(tokens); -} - -/** - * @internal - * - * @brief Return one line of known host file. - * - * This will return a token array containing (host|ip), keytype and key. - * - * @param[out] file A pointer to the known host file. Could be pointing to - * NULL at start. - * - * @param[in] filename The file name of the known host file. - * - * @param[out] found_type A pointer to a string to be set with the found key - * type. - * - * @returns The found_type type of key (ie "dsa","ssh-rsa1"). Don't - * free that value. NULL if no match was found or the file - * was not found. - */ -static char **ssh_get_knownhost_line(FILE **file, const char *filename, - const char **found_type) { - char buffer[4096] = {0}; - char *ptr; - char **tokens; - - if(*file == NULL){ - *file = fopen(filename,"r"); - if (*file == NULL) { - return NULL; - } - } - - while (fgets(buffer, sizeof(buffer), *file)) { - ptr = strchr(buffer, '\n'); - if (ptr) { - *ptr = '\0'; - } - - ptr = strchr(buffer,'\r'); - if (ptr) { - *ptr = '\0'; - } - - if (buffer[0] == '\0' || buffer[0] == '#') { - continue; /* skip empty lines */ - } - - tokens = space_tokenize(buffer); - if (tokens == NULL) { - fclose(*file); - *file = NULL; - - return NULL; - } - - if(!tokens[0] || !tokens[1] || !tokens[2]) { - /* it should have at least 3 tokens */ - tokens_free(tokens); - continue; - } - - *found_type = tokens[1]; - if (tokens[3]) { - /* openssh rsa1 format has 4 tokens on the line. Recognize it - by the fact that everything is all digits */ - if (tokens[4]) { - /* that's never valid */ - tokens_free(tokens); - continue; - } - if (alldigits(tokens[1]) && alldigits(tokens[2]) && alldigits(tokens[3])) { - *found_type = "ssh-rsa1"; - } else { - /* 3 tokens only, not four */ - tokens_free(tokens); - continue; - } - } - - return tokens; - } - - fclose(*file); - *file = NULL; - - /* we did not find anything, end of file*/ - return NULL; -} - -/** - * @brief Check the public key in the known host line matches the public key of - * the currently connected server. - * - * @param[in] session The SSH session to use. - * - * @param[in] tokens A list of tokens in the known_hosts line. - * - * @returns 1 if the key matches, 0 if the key doesn't match and -1 - * on error. - */ -static int check_public_key(ssh_session session, char **tokens) { - ssh_string pubkey = session->current_crypto->server_pubkey; - ssh_buffer pubkey_buffer; - char *pubkey_64; - - /* ok we found some public key in known hosts file. now un-base64it */ - if (alldigits(tokens[1])) { - /* openssh rsa1 format */ - bignum tmpbn; - ssh_string tmpstring; - unsigned int len; - int i; - - pubkey_buffer = ssh_buffer_new(); - if (pubkey_buffer == NULL) { - return -1; - } - - tmpstring = ssh_string_from_char("ssh-rsa1"); - if (tmpstring == NULL) { - ssh_buffer_free(pubkey_buffer); - return -1; - } - - if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) { - ssh_buffer_free(pubkey_buffer); - ssh_string_free(tmpstring); - return -1; - } - ssh_string_free(tmpstring); - - for (i = 2; i < 4; i++) { /* e, then n */ - tmpbn = NULL; - bignum_dec2bn(tokens[i], &tmpbn); - if (tmpbn == NULL) { - ssh_buffer_free(pubkey_buffer); - return -1; - } - /* for some reason, make_bignum_string does not work - because of the padding which it does --kv */ - /* tmpstring = make_bignum_string(tmpbn); */ - /* do it manually instead */ - len = bignum_num_bytes(tmpbn); - tmpstring = malloc(4 + len); - if (tmpstring == NULL) { - ssh_buffer_free(pubkey_buffer); - bignum_free(tmpbn); - return -1; - } - /* TODO: fix the hardcoding */ - tmpstring->size = htonl(len); -#ifdef HAVE_LIBGCRYPT - bignum_bn2bin(tmpbn, len, ssh_string_data(tmpstring)); -#elif defined HAVE_LIBCRYPTO - bignum_bn2bin(tmpbn, ssh_string_data(tmpstring)); -#endif - bignum_free(tmpbn); - if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) { - ssh_buffer_free(pubkey_buffer); - ssh_string_free(tmpstring); - bignum_free(tmpbn); - return -1; - } - ssh_string_free(tmpstring); - } - } else { - /* ssh-dss or ssh-rsa */ - pubkey_64 = tokens[2]; - pubkey_buffer = base64_to_bin(pubkey_64); - } - - if (pubkey_buffer == NULL) { - ssh_set_error(session, SSH_FATAL, - "Verifying that server is a known host: base64 error"); - return -1; - } - - if (buffer_get_rest_len(pubkey_buffer) != ssh_string_len(pubkey)) { - ssh_buffer_free(pubkey_buffer); - return 0; - } - - /* now test that they are identical */ - if (memcmp(buffer_get_rest(pubkey_buffer), ssh_string_data(pubkey), - buffer_get_rest_len(pubkey_buffer)) != 0) { - ssh_buffer_free(pubkey_buffer); - return 0; - } - - ssh_buffer_free(pubkey_buffer); - return 1; -} - -/** - * @brief Check if a hostname matches a openssh-style hashed known host. - * - * @param[in] host The host to check. - * - * @param[in] hashed The hashed value. - * - * @returns 1 if it matches, 0 otherwise. - */ -static int match_hashed_host(const char *host, const char *sourcehash) -{ - /* Openssh hash structure : - * |1|base64 encoded salt|base64 encoded hash - * hash is produced that way : - * hash := HMAC_SHA1(key=salt,data=host) - */ - unsigned char buffer[256] = {0}; - ssh_buffer salt; - ssh_buffer hash; - HMACCTX mac; - char *source; - char *b64hash; - int match; - unsigned int size; - - if (strncmp(sourcehash, "|1|", 3) != 0) { - return 0; - } - - source = strdup(sourcehash + 3); - if (source == NULL) { - return 0; - } - - b64hash = strchr(source, '|'); - if (b64hash == NULL) { - /* Invalid hash */ - SAFE_FREE(source); - - return 0; - } - - *b64hash = '\0'; - b64hash++; - - salt = base64_to_bin(source); - if (salt == NULL) { - SAFE_FREE(source); - - return 0; - } - - hash = base64_to_bin(b64hash); - SAFE_FREE(source); - if (hash == NULL) { - ssh_buffer_free(salt); - - return 0; - } - - mac = hmac_init(buffer_get_rest(salt), buffer_get_rest_len(salt), SSH_HMAC_SHA1); - if (mac == NULL) { - ssh_buffer_free(salt); - ssh_buffer_free(hash); - - return 0; - } - size = sizeof(buffer); - hmac_update(mac, host, strlen(host)); - hmac_final(mac, buffer, &size); - - if (size == buffer_get_rest_len(hash) && - memcmp(buffer, buffer_get_rest(hash), size) == 0) { - match = 1; - } else { - match = 0; - } - - ssh_buffer_free(salt); - ssh_buffer_free(hash); - - SSH_LOG(SSH_LOG_PACKET, - "Matching a hashed host: %s match=%d", host, match); - - return match; -} - -/* How it's working : - * 1- we open the known host file and bitch if it doesn't exist - * 2- we need to examine each line of the file, until going on state SSH_SERVER_KNOWN_OK: - * - there's a match. if the key is good, state is SSH_SERVER_KNOWN_OK, - * else it's SSH_SERVER_KNOWN_CHANGED (or SSH_SERVER_FOUND_OTHER) - * - there's no match : no change - */ - -/** - * @brief Check if the server is known. - * - * Checks the user's known host file for a previous connection to the - * current server. - * - * @param[in] session The SSH session to use. - * - * @returns SSH_SERVER_KNOWN_OK: The server is known and has not changed.\n - * SSH_SERVER_KNOWN_CHANGED: The server key has changed. Either you - * are under attack or the administrator - * changed the key. You HAVE to warn the - * user about a possible attack.\n - * SSH_SERVER_FOUND_OTHER: The server gave use a key of a type while - * we had an other type recorded. It is a - * possible attack.\n - * SSH_SERVER_NOT_KNOWN: The server is unknown. User should - * confirm the MD5 is correct.\n - * SSH_SERVER_FILE_NOT_FOUND: The known host file does not exist. The - * host is thus unknown. File will be - * created if host key is accepted.\n - * SSH_SERVER_ERROR: Some error happened. - * - * @see ssh_get_pubkey_hash() - * - * @bug There is no current way to remove or modify an entry into the known - * host table. - */ -int ssh_is_server_known(ssh_session session) { - FILE *file = NULL; - char **tokens; - char *host; - char *hostport; - const char *type; - int match; - int ret = SSH_SERVER_NOT_KNOWN; - - if (session->opts.knownhosts == NULL) { - if (ssh_options_apply(session) < 0) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Can't find a known_hosts file"); - - return SSH_SERVER_FILE_NOT_FOUND; - } - } - - if (session->opts.host == NULL) { - ssh_set_error(session, SSH_FATAL, - "Can't verify host in known hosts if the hostname isn't known"); - - return SSH_SERVER_ERROR; - } - - if (session->current_crypto == NULL){ - ssh_set_error(session, SSH_FATAL, - "ssh_is_host_known called without cryptographic context"); - - return SSH_SERVER_ERROR; - } - host = ssh_lowercase(session->opts.host); - hostport = ssh_hostport(host, session->opts.port); - if (host == NULL || hostport == NULL) { - ssh_set_error_oom(session); - SAFE_FREE(host); - SAFE_FREE(hostport); - - return SSH_SERVER_ERROR; - } - - do { - tokens = ssh_get_knownhost_line(&file, - session->opts.knownhosts, - &type); - - /* End of file, return the current state */ - if (tokens == NULL) { - break; - } - match = match_hashed_host(host, tokens[0]); - if (match == 0){ - match = match_hostname(hostport, tokens[0], strlen(tokens[0])); - } - if (match == 0) { - match = match_hostname(host, tokens[0], strlen(tokens[0])); - } - if (match == 0) { - match = match_hashed_host(hostport, tokens[0]); - } - if (match) { - /* We got a match. Now check the key type */ - if (strcmp(session->current_crypto->server_pubkey_type, type) != 0) { - SSH_LOG(SSH_LOG_PACKET, - "ssh_is_server_known: server type [%s] doesn't match the " - "type [%s] in known_hosts file", - session->current_crypto->server_pubkey_type, - type); - /* Different type. We don't override the known_changed error which is - * more important */ - if (ret != SSH_SERVER_KNOWN_CHANGED) - ret = SSH_SERVER_FOUND_OTHER; - tokens_free(tokens); - continue; - } - /* so we know the key type is good. We may get a good key or a bad key. */ - match = check_public_key(session, tokens); - tokens_free(tokens); - - if (match < 0) { - ret = SSH_SERVER_ERROR; - break; - } else if (match == 1) { - ret = SSH_SERVER_KNOWN_OK; - break; - } else if(match == 0) { - /* We override the status with the wrong key state */ - ret = SSH_SERVER_KNOWN_CHANGED; - } - } else { - tokens_free(tokens); - } - } while (1); - - if ((ret == SSH_SERVER_NOT_KNOWN) && - (session->opts.StrictHostKeyChecking == 0)) { - ssh_write_knownhost(session); - ret = SSH_SERVER_KNOWN_OK; - } - - SAFE_FREE(host); - SAFE_FREE(hostport); - if (file != NULL) { - fclose(file); - } - - /* Return the current state at end of file */ - return ret; -} - -/** - * @brief Write the current server as known in the known hosts file. - * - * This will create the known hosts file if it does not exist. You generaly use - * it when ssh_is_server_known() answered SSH_SERVER_NOT_KNOWN. - * - * @param[in] session The ssh session to use. - * - * @return SSH_OK on success, SSH_ERROR on error. - */ -int ssh_write_knownhost(ssh_session session) { - ssh_key key; - ssh_string pubkey_s; - char *b64_key; - char buffer[4096] = {0}; - FILE *file; - char *dir; - char *host; - char *hostport; - int rc; - - if (session->opts.host == NULL) { - ssh_set_error(session, SSH_FATAL, - "Can't write host in known hosts if the hostname isn't known"); - return SSH_ERROR; - } - - host = ssh_lowercase(session->opts.host); - /* If using a nonstandard port, save the host in the [host]:port format */ - if(session->opts.port != 22) { - hostport = ssh_hostport(host, session->opts.port); - SAFE_FREE(host); - if (hostport == NULL) { - return SSH_ERROR; - } - host = hostport; - hostport = NULL; - } - - if (session->opts.knownhosts == NULL) { - if (ssh_options_apply(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Can't find a known_hosts file"); - SAFE_FREE(host); - return SSH_ERROR; - } - } - - if (session->current_crypto==NULL) { - ssh_set_error(session, SSH_FATAL, "No current crypto context"); - SAFE_FREE(host); - return SSH_ERROR; - } - - pubkey_s = session->current_crypto->server_pubkey; - if (pubkey_s == NULL){ - ssh_set_error(session, SSH_FATAL, "No public key present"); - SAFE_FREE(host); - return SSH_ERROR; - } - - /* Check if ~/.ssh exists and create it if not */ - dir = ssh_dirname(session->opts.knownhosts); - if (dir == NULL) { - ssh_set_error(session, SSH_FATAL, "%s", strerror(errno)); - SAFE_FREE(host); - return SSH_ERROR; - } - - if (!ssh_file_readaccess_ok(dir)) { - if (ssh_mkdir(dir, 0700) < 0) { - ssh_set_error(session, SSH_FATAL, - "Cannot create %s directory.", dir); - SAFE_FREE(dir); - SAFE_FREE(host); - return SSH_ERROR; - } - } - SAFE_FREE(dir); - - file = fopen(session->opts.knownhosts, "a"); - if (file == NULL) { - ssh_set_error(session, SSH_FATAL, - "Couldn't open known_hosts file %s for appending: %s", - session->opts.knownhosts, strerror(errno)); - SAFE_FREE(host); - return SSH_ERROR; - } - - rc = ssh_pki_import_pubkey_blob(pubkey_s, &key); - if (rc < 0) { - fclose(file); - SAFE_FREE(host); - return -1; - } - - if (strcmp(session->current_crypto->server_pubkey_type, "ssh-rsa1") == 0) { - /* openssh uses a different format for ssh-rsa1 keys. - Be compatible --kv */ - rc = ssh_pki_export_pubkey_rsa1(key, host, buffer, sizeof(buffer)); - ssh_key_free(key); - SAFE_FREE(host); - if (rc < 0) { - fclose(file); - return -1; - } - } else { - rc = ssh_pki_export_pubkey_base64(key, &b64_key); - if (rc < 0) { - ssh_key_free(key); - fclose(file); - SAFE_FREE(host); - return -1; - } - - snprintf(buffer, sizeof(buffer), - "%s %s %s\n", - host, - key->type_c, - b64_key); - - ssh_key_free(key); - SAFE_FREE(host); - SAFE_FREE(b64_key); - } - - if (fwrite(buffer, strlen(buffer), 1, file) != 1 || ferror(file)) { - fclose(file); - return -1; - } - - fclose(file); - return 0; -} - -#define KNOWNHOSTS_MAXTYPES 10 - -/** - * @internal - * @brief Check which kind of host keys should be preferred for connection - * by reading the known_hosts file. - * - * @param[in] session The SSH session to use. - * - * @returns array of supported key types - * NULL on error - */ -char **ssh_knownhosts_algorithms(ssh_session session) { - FILE *file = NULL; - char **tokens; - char *host; - char *hostport; - const char *type; - int match; - char **array; - int i=0, j; - - if (session->opts.knownhosts == NULL) { - if (ssh_options_apply(session) < 0) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Can't find a known_hosts file"); - return NULL; - } - } - - if (session->opts.host == NULL) { - return NULL; - } - - host = ssh_lowercase(session->opts.host); - hostport = ssh_hostport(host, session->opts.port); - array = malloc(sizeof(char *) * KNOWNHOSTS_MAXTYPES); - - if (host == NULL || hostport == NULL || array == NULL) { - ssh_set_error_oom(session); - SAFE_FREE(host); - SAFE_FREE(hostport); - SAFE_FREE(array); - return NULL; - } - - do { - tokens = ssh_get_knownhost_line(&file, - session->opts.knownhosts, &type); - - /* End of file, return the current state */ - if (tokens == NULL) { - break; - } - match = match_hashed_host(host, tokens[0]); - if (match == 0){ - match = match_hostname(hostport, tokens[0], strlen(tokens[0])); - } - if (match == 0) { - match = match_hostname(host, tokens[0], strlen(tokens[0])); - } - if (match == 0) { - match = match_hashed_host(hostport, tokens[0]); - } - if (match) { - /* We got a match. Now check the key type */ - SSH_LOG(SSH_LOG_DEBUG, "server %s:%d has %s in known_hosts", - host, session->opts.port, type); - /* don't copy more than once */ - for(j=0;j= KNOWNHOSTS_MAXTYPES-1){ - tokens_free(tokens); - break; - } - } - } - tokens_free(tokens); - } while (1); - - array[i]=NULL; - SAFE_FREE(host); - SAFE_FREE(hostport); - if (file != NULL) { - fclose(file); - } - - /* Return the current state at end of file */ - return array; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/legacy.c b/libssh/src/legacy.c deleted file mode 100644 index 15f287a6..00000000 --- a/libssh/src/legacy.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/** functions in that file are wrappers to the newly named functions. All - * of them are depreciated, but these wrapper will avoid breaking backward - * compatibility - */ - -#include "config.h" - -#include -#include - -#include -#include -#include -#include -#include -#include "libssh/pki_priv.h" -#include -#include -#include "libssh/options.h" - -/* AUTH FUNCTIONS */ -int ssh_auth_list(ssh_session session) { - return ssh_userauth_list(session, NULL); -} - -int ssh_userauth_offer_pubkey(ssh_session session, const char *username, - int type, ssh_string publickey) -{ - ssh_key key; - int rc; - - (void) type; /* unused */ - - rc = ssh_pki_import_pubkey_blob(publickey, &key); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Failed to convert public key"); - return SSH_AUTH_ERROR; - } - - rc = ssh_userauth_try_publickey(session, username, key); - ssh_key_free(key); - - return rc; -} - -int ssh_userauth_pubkey(ssh_session session, - const char *username, - ssh_string publickey, - ssh_private_key privatekey) -{ - ssh_key key; - int rc; - - (void) publickey; /* unused */ - - key = ssh_key_new(); - if (key == NULL) { - return SSH_AUTH_ERROR; - } - - key->type = privatekey->type; - key->type_c = ssh_key_type_to_char(key->type); - key->flags = SSH_KEY_FLAG_PRIVATE|SSH_KEY_FLAG_PUBLIC; - key->dsa = privatekey->dsa_priv; - key->rsa = privatekey->rsa_priv; - - rc = ssh_userauth_publickey(session, username, key); - key->dsa = NULL; - key->rsa = NULL; - ssh_key_free(key); - - return rc; -} - -int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) { - return ssh_userauth_publickey_auto(session, NULL, passphrase); -} - -int ssh_userauth_privatekey_file(ssh_session session, - const char *username, - const char *filename, - const char *passphrase) { - char *pubkeyfile = NULL; - ssh_string pubkey = NULL; - ssh_private_key privkey = NULL; - int type = 0; - int rc = SSH_AUTH_ERROR; - size_t klen = strlen(filename) + 4 + 1; - - pubkeyfile = malloc(klen); - if (pubkeyfile == NULL) { - ssh_set_error_oom(session); - - return SSH_AUTH_ERROR; - } - snprintf(pubkeyfile, klen, "%s.pub", filename); - - pubkey = publickey_from_file(session, pubkeyfile, &type); - if (pubkey == NULL) { - SSH_LOG(SSH_LOG_RARE, "Public key file %s not found. Trying to generate it.", pubkeyfile); - /* auto-detect the key type with type=0 */ - privkey = privatekey_from_file(session, filename, 0, passphrase); - } else { - SSH_LOG(SSH_LOG_RARE, "Public key file %s loaded.", pubkeyfile); - privkey = privatekey_from_file(session, filename, type, passphrase); - } - if (privkey == NULL) { - goto error; - } - /* ssh_userauth_pubkey is responsible for taking care of null-pubkey */ - rc = ssh_userauth_pubkey(session, username, pubkey, privkey); - privatekey_free(privkey); - -error: - SAFE_FREE(pubkeyfile); - ssh_string_free(pubkey); - - return rc; -} - -/* BUFFER FUNCTIONS */ - -void buffer_free(ssh_buffer buffer){ - ssh_buffer_free(buffer); -} -void *buffer_get(ssh_buffer buffer){ - return ssh_buffer_get_begin(buffer); -} -uint32_t buffer_get_len(ssh_buffer buffer){ - return ssh_buffer_get_len(buffer); -} -ssh_buffer buffer_new(void){ - return ssh_buffer_new(); -} - -ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms){ - return ssh_channel_accept_x11(channel, timeout_ms); -} - -int channel_change_pty_size(ssh_channel channel,int cols,int rows){ - return ssh_channel_change_pty_size(channel,cols,rows); -} - -ssh_channel channel_forward_accept(ssh_session session, int timeout_ms){ - return ssh_channel_accept_forward(session, timeout_ms, NULL); -} - -int channel_close(ssh_channel channel){ - return ssh_channel_close(channel); -} - -int channel_forward_cancel(ssh_session session, const char *address, int port){ - return ssh_channel_cancel_forward(session, address, port); -} - -int channel_forward_listen(ssh_session session, const char *address, - int port, int *bound_port){ - return ssh_channel_listen_forward(session, address, port, bound_port); -} - -void channel_free(ssh_channel channel){ - ssh_channel_free(channel); -} - -int channel_get_exit_status(ssh_channel channel){ - return ssh_channel_get_exit_status(channel); -} - -ssh_session channel_get_session(ssh_channel channel){ - return ssh_channel_get_session(channel); -} - -int channel_is_closed(ssh_channel channel){ - return ssh_channel_is_closed(channel); -} - -int channel_is_eof(ssh_channel channel){ - return ssh_channel_is_eof(channel); -} - -int channel_is_open(ssh_channel channel){ - return ssh_channel_is_open(channel); -} - -ssh_channel channel_new(ssh_session session){ - return ssh_channel_new(session); -} - -int channel_open_forward(ssh_channel channel, const char *remotehost, - int remoteport, const char *sourcehost, int localport){ - return ssh_channel_open_forward(channel, remotehost, remoteport, - sourcehost,localport); -} - -int channel_open_session(ssh_channel channel){ - return ssh_channel_open_session(channel); -} - -int channel_poll(ssh_channel channel, int is_stderr){ - return ssh_channel_poll(channel, is_stderr); -} - -int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr){ - return ssh_channel_read(channel, dest, count, is_stderr); -} - -/* - * This function will completely be depreciated. The old implementation was not - * renamed. - * int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count, - * int is_stderr); - */ - -int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count, - int is_stderr){ - return ssh_channel_read_nonblocking(channel, dest, count, is_stderr); -} - -int channel_request_env(ssh_channel channel, const char *name, const char *value){ - return ssh_channel_request_env(channel, name, value); -} - -int channel_request_exec(ssh_channel channel, const char *cmd){ - return ssh_channel_request_exec(channel, cmd); -} - -int channel_request_pty(ssh_channel channel){ - return ssh_channel_request_pty(channel); -} - -int channel_request_pty_size(ssh_channel channel, const char *term, - int cols, int rows){ - return ssh_channel_request_pty_size(channel, term, cols, rows); -} - -int channel_request_shell(ssh_channel channel){ - return ssh_channel_request_shell(channel); -} - -int channel_request_send_signal(ssh_channel channel, const char *signum){ - return ssh_channel_request_send_signal(channel, signum); -} - -int channel_request_sftp(ssh_channel channel){ - return ssh_channel_request_sftp(channel); -} - -int channel_request_subsystem(ssh_channel channel, const char *subsystem){ - return ssh_channel_request_subsystem(channel, subsystem); -} - -int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol, - const char *cookie, int screen_number){ - return ssh_channel_request_x11(channel, single_connection, protocol, cookie, - screen_number); -} - -int channel_send_eof(ssh_channel channel){ - return ssh_channel_send_eof(channel); -} - -int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct - timeval * timeout){ - return ssh_channel_select(readchans, writechans, exceptchans, timeout); -} - -void channel_set_blocking(ssh_channel channel, int blocking){ - ssh_channel_set_blocking(channel, blocking); -} - -int channel_write(ssh_channel channel, const void *data, uint32_t len){ - return ssh_channel_write(channel, data, len); -} - -/* - * These functions have to be wrapped around the pki.c functions. - -void privatekey_free(ssh_private_key prv); -ssh_private_key privatekey_from_file(ssh_session session, const char *filename, - int type, const char *passphrase); -int ssh_publickey_to_file(ssh_session session, const char *file, - ssh_string pubkey, int type); -ssh_string publickey_to_string(ssh_public_key key); - * - */ - -void string_burn(ssh_string str){ - ssh_string_burn(str); -} - -ssh_string string_copy(ssh_string str){ - return ssh_string_copy(str); -} - -void *string_data(ssh_string str){ - return ssh_string_data(str); -} - -int string_fill(ssh_string str, const void *data, size_t len){ - return ssh_string_fill(str,data,len); -} - -void string_free(ssh_string str){ - ssh_string_free(str); -} - -ssh_string string_from_char(const char *what){ - return ssh_string_from_char(what); -} - -size_t string_len(ssh_string str){ - return ssh_string_len(str); -} - -ssh_string string_new(size_t size){ - return ssh_string_new(size); -} - -char *string_to_char(ssh_string str){ - return ssh_string_to_char(str); -} - -/* OLD PKI FUNCTIONS */ - -void publickey_free(ssh_public_key key) { - if (key == NULL) { - return; - } - - switch(key->type) { - case SSH_KEYTYPE_DSS: -#ifdef HAVE_LIBGCRYPT - gcry_sexp_release(key->dsa_pub); -#elif HAVE_LIBCRYPTO - DSA_free(key->dsa_pub); -#endif - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: -#ifdef HAVE_LIBGCRYPT - gcry_sexp_release(key->rsa_pub); -#elif defined HAVE_LIBCRYPTO - RSA_free(key->rsa_pub); -#endif - break; - default: - break; - } - SAFE_FREE(key); -} - -ssh_public_key publickey_from_privatekey(ssh_private_key prv) { - struct ssh_public_key_struct *p; - ssh_key privkey; - ssh_key pubkey; - int rc; - - privkey = ssh_key_new(); - if (privkey == NULL) { - return NULL; - } - - privkey->type = prv->type; - privkey->type_c = ssh_key_type_to_char(privkey->type); - privkey->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; - privkey->dsa = prv->dsa_priv; - privkey->rsa = prv->rsa_priv; - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - privkey->dsa = NULL; - privkey->rsa = NULL; - ssh_key_free(privkey); - if (rc < 0) { - return NULL; - } - - p = ssh_pki_convert_key_to_publickey(pubkey); - ssh_key_free(pubkey); - - return p; -} - -ssh_private_key privatekey_from_file(ssh_session session, - const char *filename, - int type, - const char *passphrase) { - ssh_auth_callback auth_fn = NULL; - void *auth_data = NULL; - ssh_private_key privkey; - ssh_key key; - int rc; - - (void) type; /* unused */ - - if (session->common.callbacks) { - auth_fn = session->common.callbacks->auth_function; - auth_data = session->common.callbacks->userdata; - } - - - rc = ssh_pki_import_privkey_file(filename, - passphrase, - auth_fn, - auth_data, - &key); - if (rc == SSH_ERROR) { - return NULL; - } - - privkey = malloc(sizeof(struct ssh_private_key_struct)); - if (privkey == NULL) { - ssh_key_free(key); - return NULL; - } - - privkey->type = key->type; - privkey->dsa_priv = key->dsa; - privkey->rsa_priv = key->rsa; - - key->dsa = NULL; - key->rsa = NULL; - - ssh_key_free(key); - - return privkey; -} - -enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey){ - if (privatekey==NULL) - return SSH_KEYTYPE_UNKNOWN; - return privatekey->type; -} - -void privatekey_free(ssh_private_key prv) { - if (prv == NULL) { - return; - } - -#ifdef HAVE_LIBGCRYPT - gcry_sexp_release(prv->dsa_priv); - gcry_sexp_release(prv->rsa_priv); -#elif defined HAVE_LIBCRYPTO - DSA_free(prv->dsa_priv); - RSA_free(prv->rsa_priv); -#endif - memset(prv, 0, sizeof(struct ssh_private_key_struct)); - SAFE_FREE(prv); -} - -ssh_string publickey_from_file(ssh_session session, const char *filename, - int *type) { - ssh_key key; - ssh_string key_str = NULL; - int rc; - - (void) session; /* unused */ - - rc = ssh_pki_import_pubkey_file(filename, &key); - if (rc < 0) { - return NULL; - } - - rc = ssh_pki_export_pubkey_blob(key, &key_str); - if (rc < 0) { - ssh_key_free(key); - return NULL; - } - - if (type) { - *type = key->type; - } - ssh_key_free(key); - - return key_str; -} - -const char *ssh_type_to_char(int type) { - return ssh_key_type_to_char(type); -} - -int ssh_type_from_name(const char *name) { - return ssh_key_type_from_name(name); -} - -ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) { - struct ssh_public_key_struct *pubkey; - ssh_key key; - int rc; - - (void) session; /* unused */ - - rc = ssh_pki_import_pubkey_blob(pubkey_s, &key); - if (rc < 0) { - return NULL; - } - - pubkey = malloc(sizeof(struct ssh_public_key_struct)); - if (pubkey == NULL) { - ssh_key_free(key); - return NULL; - } - - pubkey->type = key->type; - pubkey->type_c = key->type_c; - - pubkey->dsa_pub = key->dsa; - key->dsa = NULL; - pubkey->rsa_pub = key->rsa; - key->rsa = NULL; - - ssh_key_free(key); - - return pubkey; -} - -ssh_string publickey_to_string(ssh_public_key pubkey) { - ssh_key key; - ssh_string key_blob; - int rc; - - key = ssh_key_new(); - if (key == NULL) { - return NULL; - } - - key->type = pubkey->type; - key->type_c = pubkey->type_c; - - key->dsa = pubkey->dsa_pub; - key->rsa = pubkey->rsa_pub; - - rc = ssh_pki_export_pubkey_blob(key, &key_blob); - if (rc < 0) { - key_blob = NULL; - } - - key->dsa = NULL; - key->rsa = NULL; - ssh_key_free(key); - - return key_blob; -} - -int ssh_publickey_to_file(ssh_session session, - const char *file, - ssh_string pubkey, - int type) -{ - FILE *fp; - char *user; - char buffer[1024]; - char host[256]; - unsigned char *pubkey_64; - size_t len; - int rc; - if(session==NULL) - return SSH_ERROR; - if(file==NULL || pubkey==NULL){ - ssh_set_error(session, SSH_FATAL, "Invalid parameters"); - return SSH_ERROR; - } - pubkey_64 = bin_to_base64(ssh_string_data(pubkey), ssh_string_len(pubkey)); - if (pubkey_64 == NULL) { - return SSH_ERROR; - } - - user = ssh_get_local_username(); - if (user == NULL) { - SAFE_FREE(pubkey_64); - return SSH_ERROR; - } - - rc = gethostname(host, sizeof(host)); - if (rc < 0) { - SAFE_FREE(user); - SAFE_FREE(pubkey_64); - return SSH_ERROR; - } - - snprintf(buffer, sizeof(buffer), "%s %s %s@%s\n", - ssh_type_to_char(type), - pubkey_64, - user, - host); - - SAFE_FREE(pubkey_64); - SAFE_FREE(user); - - SSH_LOG(SSH_LOG_RARE, "Trying to write public key file: %s", file); - SSH_LOG(SSH_LOG_PACKET, "public key file content: %s", buffer); - - fp = fopen(file, "w+"); - if (fp == NULL) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Error opening %s: %s", file, strerror(errno)); - return SSH_ERROR; - } - - len = strlen(buffer); - if (fwrite(buffer, len, 1, fp) != 1 || ferror(fp)) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Unable to write to %s", file); - fclose(fp); - unlink(file); - return SSH_ERROR; - } - - fclose(fp); - return SSH_OK; -} - -int ssh_try_publickey_from_file(ssh_session session, - const char *keyfile, - ssh_string *publickey, - int *type) { - char *pubkey_file; - size_t len; - ssh_string pubkey_string; - int pubkey_type; - - if (session == NULL || keyfile == NULL || publickey == NULL || type == NULL) { - return -1; - } - - if (session->opts.sshdir == NULL) { - if (ssh_options_apply(session) < 0) { - return -1; - } - } - - SSH_LOG(SSH_LOG_PACKET, "Trying to open privatekey %s", keyfile); - if (!ssh_file_readaccess_ok(keyfile)) { - SSH_LOG(SSH_LOG_PACKET, "Failed to open privatekey %s", keyfile); - return -1; - } - - len = strlen(keyfile) + 5; - pubkey_file = malloc(len); - if (pubkey_file == NULL) { - return -1; - } - snprintf(pubkey_file, len, "%s.pub", keyfile); - - SSH_LOG(SSH_LOG_PACKET, "Trying to open publickey %s", - pubkey_file); - if (!ssh_file_readaccess_ok(pubkey_file)) { - SSH_LOG(SSH_LOG_PACKET, "Failed to open publickey %s", - pubkey_file); - SAFE_FREE(pubkey_file); - return 1; - } - - SSH_LOG(SSH_LOG_PACKET, "Success opening public and private key"); - - /* - * We are sure both the private and public key file is readable. We return - * the public as a string, and the private filename as an argument - */ - pubkey_string = publickey_from_file(session, pubkey_file, &pubkey_type); - if (pubkey_string == NULL) { - SSH_LOG(SSH_LOG_PACKET, - "Wasn't able to open public key file %s: %s", - pubkey_file, - ssh_get_error(session)); - SAFE_FREE(pubkey_file); - return -1; - } - - SAFE_FREE(pubkey_file); - - *publickey = pubkey_string; - *type = pubkey_type; - - return 0; -} - -ssh_string ssh_get_pubkey(ssh_session session){ - if(session==NULL || session->current_crypto ==NULL || - session->current_crypto->server_pubkey==NULL) - return NULL; - else - return ssh_string_copy(session->current_crypto->server_pubkey); -} - -/**************************************************************************** - * SERVER SUPPORT - ****************************************************************************/ - -#ifdef WITH_SERVER -int ssh_accept(ssh_session session) { - return ssh_handle_key_exchange(session); -} - -int channel_write_stderr(ssh_channel channel, const void *data, uint32_t len) { - return ssh_channel_write(channel, data, len); -} - -/** @deprecated - * @brief Interface previously exported by error. - */ -ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype){ - (void) packettype; - ssh_set_error(session, SSH_FATAL, "ssh_message_retrieve: obsolete libssh call"); - return NULL; -} - -#endif /* WITH_SERVER */ diff --git a/libssh/src/libcrypto.c b/libssh/src/libcrypto.c deleted file mode 100644 index 479c8c18..00000000 --- a/libssh/src/libcrypto.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/crypto.h" -#include "libssh/wrapper.h" -#include "libssh/libcrypto.h" - -#ifdef HAVE_LIBCRYPTO - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_OPENSSL_AES_H -#define HAS_AES -#include -#endif -#ifdef HAVE_OPENSSL_BLOWFISH_H -#define HAS_BLOWFISH -#include -#endif -#ifdef HAVE_OPENSSL_DES_H -#define HAS_DES -#include -#endif - -#if (OPENSSL_VERSION_NUMBER<0x00907000L) -#define OLD_CRYPTO -#endif - -#include "libssh/crypto.h" - -struct ssh_mac_ctx_struct { - enum ssh_mac_e mac_type; - union { - SHACTX sha1_ctx; - SHA256CTX sha256_ctx; - SHA384CTX sha384_ctx; - SHA512CTX sha512_ctx; - } ctx; -}; - -static int alloc_key(struct ssh_cipher_struct *cipher) { - cipher->key = malloc(cipher->keylen); - if (cipher->key == NULL) { - return -1; - } - - return 0; -} - -void ssh_reseed(void){ - struct timeval tv; - gettimeofday(&tv, NULL); - RAND_add(&tv, sizeof(tv), 0.0); -} - -SHACTX sha1_init(void) { - SHACTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - SHA1_Init(c); - - return c; -} - -void sha1_update(SHACTX c, const void *data, unsigned long len) { - SHA1_Update(c,data,len); -} - -void sha1_final(unsigned char *md, SHACTX c) { - SHA1_Final(md, c); - SAFE_FREE(c); -} - -void sha1(unsigned char *digest, int len, unsigned char *hash) { - SHA1(digest, len, hash); -} - -#ifdef HAVE_OPENSSL_ECC -static const EVP_MD *nid_to_evpmd(int nid) -{ - switch (nid) { - case NID_X9_62_prime256v1: - return EVP_sha256(); - case NID_secp384r1: - return EVP_sha384(); - case NID_secp521r1: - return EVP_sha512(); - default: - return NULL; - } - - return NULL; -} - -void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen) -{ - const EVP_MD *evp_md = nid_to_evpmd(nid); - EVP_MD_CTX md; - - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, digest, len); - EVP_DigestFinal(&md, hash, hlen); -} - -EVPCTX evp_init(int nid) -{ - const EVP_MD *evp_md = nid_to_evpmd(nid); - - EVPCTX ctx = malloc(sizeof(EVP_MD_CTX)); - if (ctx == NULL) { - return NULL; - } - - EVP_DigestInit(ctx, evp_md); - - return ctx; -} - -void evp_update(EVPCTX ctx, const void *data, unsigned long len) -{ - EVP_DigestUpdate(ctx, data, len); -} - -void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) -{ - EVP_DigestFinal(ctx, md, mdlen); -} -#endif - -SHA256CTX sha256_init(void){ - SHA256CTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - SHA256_Init(c); - - return c; -} - -void sha256_update(SHA256CTX c, const void *data, unsigned long len){ - SHA256_Update(c,data,len); -} - -void sha256_final(unsigned char *md, SHA256CTX c) { - SHA256_Final(md, c); - SAFE_FREE(c); -} - -void sha256(unsigned char *digest, int len, unsigned char *hash) { - SHA256(digest, len, hash); -} - -SHA384CTX sha384_init(void){ - SHA384CTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - SHA384_Init(c); - - return c; -} - -void sha384_update(SHA384CTX c, const void *data, unsigned long len){ - SHA384_Update(c,data,len); -} - -void sha384_final(unsigned char *md, SHA384CTX c) { - SHA384_Final(md, c); - SAFE_FREE(c); -} - -void sha384(unsigned char *digest, int len, unsigned char *hash) { - SHA384(digest, len, hash); -} - -SHA512CTX sha512_init(void){ - SHA512CTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - SHA512_Init(c); - - return c; -} - -void sha512_update(SHA512CTX c, const void *data, unsigned long len){ - SHA512_Update(c,data,len); -} - -void sha512_final(unsigned char *md, SHA512CTX c) { - SHA512_Final(md, c); - SAFE_FREE(c); -} - -void sha512(unsigned char *digest, int len, unsigned char *hash) { - SHA512(digest, len, hash); -} - -MD5CTX md5_init(void) { - MD5CTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - - MD5_Init(c); - - return c; -} - -void md5_update(MD5CTX c, const void *data, unsigned long len) { - MD5_Update(c, data, len); -} - -void md5_final(unsigned char *md, MD5CTX c) { - MD5_Final(md,c); - SAFE_FREE(c); -} - -ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){ - ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct)); - if (ctx == NULL) { - return NULL; - } - - ctx->mac_type=type; - switch(type){ - case SSH_MAC_SHA1: - ctx->ctx.sha1_ctx = sha1_init(); - return ctx; - case SSH_MAC_SHA256: - ctx->ctx.sha256_ctx = sha256_init(); - return ctx; - case SSH_MAC_SHA384: - ctx->ctx.sha384_ctx = sha384_init(); - return ctx; - case SSH_MAC_SHA512: - ctx->ctx.sha512_ctx = sha512_init(); - return ctx; - default: - SAFE_FREE(ctx); - return NULL; - } -} - -void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len) { - switch(ctx->mac_type){ - case SSH_MAC_SHA1: - sha1_update(ctx->ctx.sha1_ctx, data, len); - break; - case SSH_MAC_SHA256: - sha256_update(ctx->ctx.sha256_ctx, data, len); - break; - case SSH_MAC_SHA384: - sha384_update(ctx->ctx.sha384_ctx, data, len); - break; - case SSH_MAC_SHA512: - sha512_update(ctx->ctx.sha512_ctx, data, len); - break; - default: - break; - } -} - -void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) { - switch(ctx->mac_type){ - case SSH_MAC_SHA1: - sha1_final(md,ctx->ctx.sha1_ctx); - break; - case SSH_MAC_SHA256: - sha256_final(md,ctx->ctx.sha256_ctx); - break; - case SSH_MAC_SHA384: - sha384_final(md,ctx->ctx.sha384_ctx); - break; - case SSH_MAC_SHA512: - sha512_final(md,ctx->ctx.sha512_ctx); - break; - default: - break; - } - SAFE_FREE(ctx); -} - -HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) { - HMACCTX ctx = NULL; - - ctx = malloc(sizeof(*ctx)); - if (ctx == NULL) { - return NULL; - } - -#ifndef OLD_CRYPTO - HMAC_CTX_init(ctx); // openssl 0.9.7 requires it. -#endif - - switch(type) { - case SSH_HMAC_SHA1: - HMAC_Init(ctx, key, len, EVP_sha1()); - break; - case SSH_HMAC_SHA256: - HMAC_Init(ctx, key, len, EVP_sha256()); - break; - case SSH_HMAC_SHA384: - HMAC_Init(ctx, key, len, EVP_sha384()); - break; - case SSH_HMAC_SHA512: - HMAC_Init(ctx, key, len, EVP_sha512()); - break; - case SSH_HMAC_MD5: - HMAC_Init(ctx, key, len, EVP_md5()); - break; - default: - SAFE_FREE(ctx); - ctx = NULL; - } - - return ctx; -} - -void hmac_update(HMACCTX ctx, const void *data, unsigned long len) { - HMAC_Update(ctx, data, len); -} - -void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) { - HMAC_Final(ctx,hashmacbuf,len); - -#ifndef OLD_CRYPTO - HMAC_CTX_cleanup(ctx); -#else - HMAC_cleanup(ctx); -#endif - - SAFE_FREE(ctx); -} - -#ifdef HAS_BLOWFISH -/* the wrapper functions for blowfish */ -static int blowfish_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){ - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - BF_set_key(cipher->key, 16, key); - } - cipher->IV = IV; - return 0; -} - -static void blowfish_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - BF_cbc_encrypt(in, out, len, cipher->key, cipher->IV, BF_ENCRYPT); -} - -static void blowfish_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - BF_cbc_encrypt(in, out, len, cipher->key, cipher->IV, BF_DECRYPT); -} -#endif /* HAS_BLOWFISH */ - -#ifdef HAS_AES -static int aes_set_encrypt_key(struct ssh_cipher_struct *cipher, void *key, - void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (AES_set_encrypt_key(key,cipher->keysize,cipher->key) < 0) { - SAFE_FREE(cipher->key); - return -1; - } - } - cipher->IV=IV; - return 0; -} -static int aes_set_decrypt_key(struct ssh_cipher_struct *cipher, void *key, - void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (AES_set_decrypt_key(key,cipher->keysize,cipher->key) < 0) { - SAFE_FREE(cipher->key); - return -1; - } - } - cipher->IV=IV; - return 0; -} - -static void aes_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len) { - AES_cbc_encrypt(in, out, len, cipher->key, cipher->IV, AES_ENCRYPT); -} - -static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len) { - AES_cbc_encrypt(in, out, len, cipher->key, cipher->IV, AES_DECRYPT); -} - -#ifndef BROKEN_AES_CTR -/* OpenSSL until 0.9.7c has a broken AES_ctr128_encrypt implementation which - * increments the counter from 2^64 instead of 1. It's better not to use it - */ - -/** @internal - * @brief encrypts/decrypts data with stream cipher AES_ctr128. 128 bits is actually - * the size of the CTR counter and incidentally the blocksize, but not the keysize. - * @param len[in] must be a multiple of AES128 block size. - */ -static void aes_ctr128_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len) { - unsigned char tmp_buffer[128/8]; - unsigned int num=0; - /* Some things are special with ctr128 : - * In this case, tmp_buffer is not being used, because it is used to store temporary data - * when an encryption is made on lengths that are not multiple of blocksize. - * Same for num, which is being used to store the current offset in blocksize in CTR - * function. - */ - AES_ctr128_encrypt(in, out, len, cipher->key, cipher->IV, tmp_buffer, &num); -} -#endif /* BROKEN_AES_CTR */ -#endif /* HAS_AES */ - -#ifdef HAS_DES -static int des3_set_key(struct ssh_cipher_struct *cipher, void *key,void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - - DES_set_odd_parity(key); - DES_set_odd_parity((void*)((uint8_t*)key + 8)); - DES_set_odd_parity((void*)((uint8_t*)key + 16)); - DES_set_key_unchecked(key, cipher->key); - DES_set_key_unchecked((void*)((uint8_t*)key + 8), (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule))); - DES_set_key_unchecked((void*)((uint8_t*)key + 16), (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule))); - } - cipher->IV=IV; - return 0; -} - -static void des3_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - DES_ede3_cbc_encrypt(in, out, len, cipher->key, - (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - cipher->IV, 1); -} - -static void des3_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - DES_ede3_cbc_encrypt(in, out, len, cipher->key, - (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - cipher->IV, 0); -} - -static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Encrypt IV before", cipher->IV, 24); -#endif - DES_ncbc_encrypt(in, out, len, cipher->key, cipher->IV, 1); - DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->IV + 8), 0); - DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->IV + 16), 1); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Encrypt IV after", cipher->IV, 24); -#endif -} - -static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Decrypt IV before", cipher->IV, 24); -#endif - - DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - cipher->IV, 0); - DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->IV + 8), 1); - DES_ncbc_encrypt(in, out, len, cipher->key, (void*)((uint8_t*)cipher->IV + 16), 0); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Decrypt IV after", cipher->IV, 24); -#endif -} - -static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){ - if(!cipher->key){ - if (alloc_key(cipher) < 0) { - return -1; - } - DES_set_odd_parity(key); - DES_set_key_unchecked(key,cipher->key); - } - cipher->IV=IV; - return 0; -} - -static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len){ - - DES_ncbc_encrypt(in, out, len, cipher->key, cipher->IV, 1); -} - -static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len){ - - DES_ncbc_encrypt(in,out,len, cipher->key, cipher->IV, 0); -} - -#endif /* HAS_DES */ - -/* - * The table of supported ciphers - * - * WARNING: If you modify ssh_cipher_struct, you must make sure the order is - * correct! - */ -static struct ssh_cipher_struct ssh_ciphertab[] = { -#ifdef HAS_BLOWFISH - { - "blowfish-cbc", - 8, - sizeof (BF_KEY), - NULL, - NULL, - 128, - blowfish_set_key, - blowfish_set_key, - blowfish_encrypt, - blowfish_decrypt - }, -#endif /* HAS_BLOWFISH */ -#ifdef HAS_AES -#ifndef BROKEN_AES_CTR - { - "aes128-ctr", - 16, - sizeof(AES_KEY), - NULL, - NULL, - 128, - aes_set_encrypt_key, - aes_set_encrypt_key, - aes_ctr128_encrypt, - aes_ctr128_encrypt - }, - { - "aes192-ctr", - 16, - sizeof(AES_KEY), - NULL, - NULL, - 192, - aes_set_encrypt_key, - aes_set_encrypt_key, - aes_ctr128_encrypt, - aes_ctr128_encrypt - }, - { - "aes256-ctr", - 16, - sizeof(AES_KEY), - NULL, - NULL, - 256, - aes_set_encrypt_key, - aes_set_encrypt_key, - aes_ctr128_encrypt, - aes_ctr128_encrypt - }, -#endif /* BROKEN_AES_CTR */ - { - "aes128-cbc", - 16, - sizeof(AES_KEY), - NULL, - NULL, - 128, - aes_set_encrypt_key, - aes_set_decrypt_key, - aes_encrypt, - aes_decrypt - }, - { - "aes192-cbc", - 16, - sizeof(AES_KEY), - NULL, - NULL, - 192, - aes_set_encrypt_key, - aes_set_decrypt_key, - aes_encrypt, - aes_decrypt - }, - { - "aes256-cbc", - 16, - sizeof(AES_KEY), - NULL, - NULL, - 256, - aes_set_encrypt_key, - aes_set_decrypt_key, - aes_encrypt, - aes_decrypt - }, -#endif /* HAS_AES */ -#ifdef HAS_DES - { - "3des-cbc", - 8, - sizeof(DES_key_schedule) * 3, - NULL, - NULL, - 192, - des3_set_key, - des3_set_key, - des3_encrypt, - des3_decrypt - }, - { - "3des-cbc-ssh1", - 8, - sizeof(DES_key_schedule) * 3, - NULL, - NULL, - 192, - des3_set_key, - des3_set_key, - des3_1_encrypt, - des3_1_decrypt - }, - { - "des-cbc-ssh1", - 8, - sizeof(DES_key_schedule), - NULL, - NULL, - 64, - des1_set_key, - des1_set_key, - des1_1_encrypt, - des1_1_decrypt - }, -#endif /* HAS_DES */ - { - NULL, - 0, - 0, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL - } -}; - - -struct ssh_cipher_struct *ssh_get_ciphertab(void) -{ - return ssh_ciphertab; -} - -#endif /* LIBCRYPTO */ - diff --git a/libssh/src/libgcrypt.c b/libssh/src/libgcrypt.c deleted file mode 100644 index 24d4a3c5..00000000 --- a/libssh/src/libgcrypt.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/crypto.h" -#include "libssh/wrapper.h" - -#ifdef HAVE_LIBGCRYPT -#include - -struct ssh_mac_ctx_struct { - enum ssh_mac_e mac_type; - gcry_md_hd_t ctx; -}; - -static int alloc_key(struct ssh_cipher_struct *cipher) { - cipher->key = malloc(cipher->keylen); - if (cipher->key == NULL) { - return -1; - } - - return 0; -} - -void ssh_reseed(void){ - } - -SHACTX sha1_init(void) { - SHACTX ctx = NULL; - gcry_md_open(&ctx, GCRY_MD_SHA1, 0); - - return ctx; -} - -void sha1_update(SHACTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void sha1_final(unsigned char *md, SHACTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN); - gcry_md_close(c); -} - -void sha1(unsigned char *digest, int len, unsigned char *hash) { - gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len); -} - -SHA256CTX sha256_init(void) { - SHA256CTX ctx = NULL; - gcry_md_open(&ctx, GCRY_MD_SHA256, 0); - - return ctx; -} - -void sha256_update(SHACTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void sha256_final(unsigned char *md, SHACTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA256_DIGEST_LEN); - gcry_md_close(c); -} - -void sha256(unsigned char *digest, int len, unsigned char *hash){ - gcry_md_hash_buffer(GCRY_MD_SHA256, hash, digest, len); -} - -SHA384CTX sha384_init(void) { - SHA384CTX ctx = NULL; - gcry_md_open(&ctx, GCRY_MD_SHA384, 0); - - return ctx; -} - -void sha384_update(SHACTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void sha384_final(unsigned char *md, SHACTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA384_DIGEST_LEN); - gcry_md_close(c); -} - -void sha384(unsigned char *digest, int len, unsigned char *hash) { - gcry_md_hash_buffer(GCRY_MD_SHA384, hash, digest, len); -} - -SHA512CTX sha512_init(void) { - SHA512CTX ctx = NULL; - gcry_md_open(&ctx, GCRY_MD_SHA512, 0); - - return ctx; -} - -void sha512_update(SHACTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void sha512_final(unsigned char *md, SHACTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA512_DIGEST_LEN); - gcry_md_close(c); -} - -void sha512(unsigned char *digest, int len, unsigned char *hash) { - gcry_md_hash_buffer(GCRY_MD_SHA512, hash, digest, len); -} - -MD5CTX md5_init(void) { - MD5CTX c = NULL; - gcry_md_open(&c, GCRY_MD_MD5, 0); - - return c; -} - -void md5_update(MD5CTX c, const void *data, unsigned long len) { - gcry_md_write(c,data,len); -} - -void md5_final(unsigned char *md, MD5CTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN); - gcry_md_close(c); -} - -ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){ - ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct)); - if (ctx == NULL) { - return NULL; - } - - ctx->mac_type=type; - switch(type){ - case SSH_MAC_SHA1: - gcry_md_open(&ctx->ctx, GCRY_MD_SHA1, 0); - break; - case SSH_MAC_SHA256: - gcry_md_open(&ctx->ctx, GCRY_MD_SHA256, 0); - break; - case SSH_MAC_SHA384: - gcry_md_open(&ctx->ctx, GCRY_MD_SHA384, 0); - break; - case SSH_MAC_SHA512: - gcry_md_open(&ctx->ctx, GCRY_MD_SHA512, 0); - break; - default: - SAFE_FREE(ctx); - return NULL; - } - return ctx; -} - -void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len) { - gcry_md_write(ctx->ctx,data,len); -} - -void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) { - size_t len; - switch(ctx->mac_type){ - case SSH_MAC_SHA1: - len=SHA_DIGEST_LEN; - break; - case SSH_MAC_SHA256: - len=SHA256_DIGEST_LEN; - break; - case SSH_MAC_SHA384: - len=SHA384_DIGEST_LEN; - break; - case SSH_MAC_SHA512: - len=SHA512_DIGEST_LEN; - break; - } - gcry_md_final(ctx->ctx); - memcpy(md, gcry_md_read(ctx->ctx, 0), len); - gcry_md_close(ctx->ctx); - SAFE_FREE(ctx); -} - -HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) { - HMACCTX c = NULL; - - switch(type) { - case SSH_HMAC_SHA1: - gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); - break; - case SSH_HMAC_SHA256: - gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); - break; - case SSH_HMAC_SHA384: - gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC); - break; - case SSH_HMAC_SHA512: - gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC); - break; - case SSH_HMAC_MD5: - gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); - break; - default: - c = NULL; - } - - gcry_md_setkey(c, key, len); - - return c; -} - -void hmac_update(HMACCTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len) { - *len = gcry_md_get_algo_dlen(gcry_md_get_algo(c)); - memcpy(hashmacbuf, gcry_md_read(c, 0), *len); - gcry_md_close(c); -} - -/* the wrapper functions for blowfish */ -static int blowfish_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){ - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_BLOWFISH, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 16)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - -static void blowfish_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void blowfish_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) { - int mode=GCRY_CIPHER_MODE_CBC; - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if(strstr(cipher->name,"-ctr")) - mode=GCRY_CIPHER_MODE_CTR; - switch (cipher->keysize) { - case 128: - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES128, - mode, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - break; - case 192: - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES192, - mode, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - break; - case 256: - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES256, - mode, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - break; - } - if (gcry_cipher_setkey(cipher->key[0], key, cipher->keysize / 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if(mode == GCRY_CIPHER_MODE_CBC){ - if (gcry_cipher_setiv(cipher->key[0], IV, 16)) { - - SAFE_FREE(cipher->key); - return -1; - } - } else { - if(gcry_cipher_setctr(cipher->key[0],IV,16)){ - SAFE_FREE(cipher->key); - return -1; - } - } - } - - return 0; -} - -static void aes_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out, - unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){ - if(!cipher->key){ - if (alloc_key(cipher) < 0) { - return -1; - } - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - return 0; -} - -static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_3DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 24)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - - -static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static void des3_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void des3_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static int des3_1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - - if (gcry_cipher_open(&cipher->key[1], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[1], (unsigned char *)key + 8, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[1], (unsigned char *)IV + 8, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - - if (gcry_cipher_open(&cipher->key[2], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[2], (unsigned char *)key + 16, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[2], (unsigned char *)IV + 16, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - -static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); - gcry_cipher_decrypt(cipher->key[1], in, len, out, len); - gcry_cipher_encrypt(cipher->key[2], out, len, in, len); -} - -static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[2], out, len, in, len); - gcry_cipher_encrypt(cipher->key[1], in, len, out, len); - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -/* the table of supported ciphers */ -static struct ssh_cipher_struct ssh_ciphertab[] = { - { - .name = "blowfish-cbc", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 128, - .set_encrypt_key = blowfish_set_key, - .set_decrypt_key = blowfish_set_key, - .encrypt = blowfish_encrypt, - .decrypt = blowfish_decrypt - }, - { - .name = "aes128-ctr", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 128, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .encrypt = aes_encrypt, - .decrypt = aes_encrypt - }, - { - .name = "aes192-ctr", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 192, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .encrypt = aes_encrypt, - .decrypt = aes_encrypt - }, - { - .name = "aes256-ctr", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 256, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .encrypt = aes_encrypt, - .decrypt = aes_encrypt - }, - { - .name = "aes128-cbc", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 128, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .encrypt = aes_encrypt, - .decrypt = aes_decrypt - }, - { - .name = "aes192-cbc", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 192, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .encrypt = aes_encrypt, - .decrypt = aes_decrypt - }, - { - .name = "aes256-cbc", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 256, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .encrypt = aes_encrypt, - .decrypt = aes_decrypt - }, - { - .name = "3des-cbc", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 192, - .set_encrypt_key = des3_set_key, - .set_decrypt_key = des3_set_key, - .encrypt = des3_encrypt, - .decrypt = des3_decrypt - }, - { - .name = "3des-cbc-ssh1", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t) * 3, - .key = NULL, - .keysize = 192, - .set_encrypt_key = des3_1_set_key, - .set_decrypt_key = des3_1_set_key, - .encrypt = des3_1_encrypt, - .decrypt = des3_1_decrypt - }, - { - .name = "des-cbc-ssh1", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 64, - .set_encrypt_key = des1_set_key, - .set_decrypt_key = des1_set_key, - .encrypt = des1_1_encrypt, - .decrypt = des1_1_decrypt - }, - { - .name = NULL, - .blocksize = 0, - .keylen = 0, - .key = NULL, - .keysize = 0, - .set_encrypt_key = NULL, - .set_decrypt_key = NULL, - .encrypt = NULL, - .decrypt = NULL - } -}; - -struct ssh_cipher_struct *ssh_get_ciphertab(void) -{ - return ssh_ciphertab; -} - -#endif diff --git a/libssh/src/log.c b/libssh/src/log.c deleted file mode 100644 index a72dd412..00000000 --- a/libssh/src/log.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * log.c - logging and debugging functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2008-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include -#ifndef _WIN32 -#include -#else -#include -#endif -#include - -#include "libssh/priv.h" -#include "libssh/misc.h" -#include "libssh/session.h" - -LIBSSH_THREAD int ssh_log_level; -LIBSSH_THREAD ssh_logging_callback ssh_log_cb; -LIBSSH_THREAD void *ssh_log_userdata; - -/** - * @defgroup libssh_log The SSH logging functions. - * @ingroup libssh - * - * Logging functions for debugging and problem resolving. - * - * @{ - */ - -static int current_timestring(int hires, char *buf, size_t len) -{ - char tbuf[64]; - struct timeval tv; - struct tm *tm; - time_t t; - - gettimeofday(&tv, NULL); - t = (time_t) tv.tv_sec; - - tm = localtime(&t); - if (tm == NULL) { - return -1; - } - - if (hires) { - strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm); - snprintf(buf, len, "%s.%06ld", tbuf, (long)tv.tv_usec); - } else { - strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm); - snprintf(buf, len, "%s", tbuf); - } - - return 0; -} - -static void ssh_log_stderr(int verbosity, - const char *function, - const char *buffer) -{ - char date[64] = {0}; - int rc; - - rc = current_timestring(1, date, sizeof(date)); - if (rc == 0) { - fprintf(stderr, "[%s, %d] %s:", date, verbosity, function); - } else { - fprintf(stderr, "[%d] %s", verbosity, function); - } - - fprintf(stderr, " %s\n", buffer); -} - -void ssh_log_function(int verbosity, - const char *function, - const char *buffer) -{ - ssh_logging_callback log_fn = ssh_get_log_callback(); - if (log_fn) { - char buf[1024]; - - snprintf(buf, sizeof(buf), "%s: %s", function, buffer); - - log_fn(verbosity, - function, - buf, - ssh_get_log_userdata()); - return; - } - - ssh_log_stderr(verbosity, function, buffer); -} - -void _ssh_log(int verbosity, - const char *function, - const char *format, ...) -{ - char buffer[1024]; - va_list va; - - if (verbosity <= ssh_get_log_level()) { - va_start(va, format); - vsnprintf(buffer, sizeof(buffer), format, va); - va_end(va); - ssh_log_function(verbosity, function, buffer); - } -} - -/* LEGACY */ - -void ssh_log(ssh_session session, - int verbosity, - const char *format, ...) -{ - char buffer[1024]; - va_list va; - - if (verbosity <= session->common.log_verbosity) { - va_start(va, format); - vsnprintf(buffer, sizeof(buffer), format, va); - va_end(va); - ssh_log_function(verbosity, "", buffer); - } -} - -/** @internal - * @brief log a SSH event with a common pointer - * @param common The SSH/bind session. - * @param verbosity The verbosity of the event. - * @param format The format string of the log entry. - */ -void ssh_log_common(struct ssh_common_struct *common, - int verbosity, - const char *function, - const char *format, ...) -{ - char buffer[1024]; - va_list va; - - if (verbosity <= common->log_verbosity) { - va_start(va, format); - vsnprintf(buffer, sizeof(buffer), format, va); - va_end(va); - ssh_log_function(verbosity, function, buffer); - } -} - - -/* PUBLIC */ - -/** - * @brief Set the log level of the library. - * - * @param[in] level The level to set. - * - * @return SSH_OK on success, SSH_ERROR on error. - */ -int ssh_set_log_level(int level) { - if (level < 0) { - return SSH_ERROR; - } - - ssh_log_level = level; - - return SSH_OK; -} - -/** - * @brief Get the log level of the library. - * - * @return The value of the log level. - */ -int ssh_get_log_level(void) { - return ssh_log_level; -} - -int ssh_set_log_callback(ssh_logging_callback cb) { - if (cb == NULL) { - return SSH_ERROR; - } - - ssh_log_cb = cb; - - return SSH_OK; -} - -ssh_logging_callback ssh_get_log_callback(void) { - return ssh_log_cb; -} - -/** - * @brief Get the userdata of the logging function. - * - * @return The userdata if set or NULL. - */ -void *ssh_get_log_userdata(void) -{ - if (ssh_log_userdata == NULL) { - return NULL; - } - - return ssh_log_userdata; -} - -/** - * @brief Set the userdata for the logging function. - * - * @param[in] data The userdata to set. - * - * @return SSH_OK on success. - */ -int ssh_set_log_userdata(void *data) -{ - ssh_log_userdata = data; - - return 0; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/match.c b/libssh/src/match.c deleted file mode 100644 index 53620bdd..00000000 --- a/libssh/src/match.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * Simple pattern matching, with '*' and '?' as wildcards. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ - -/* - * 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. - */ - -#include -#include -#include - -#include "libssh/priv.h" - -/* - * Returns true if the given string matches the pattern (which may contain ? - * and * as wildcards), and zero if it does not match. - */ -static int match_pattern(const char *s, const char *pattern) { - if (s == NULL || pattern == NULL) { - return 0; - } - - for (;;) { - /* If at end of pattern, accept if also at end of string. */ - if (*pattern == '\0') { - return (*s == '\0'); - } - - if (*pattern == '*') { - /* Skip the asterisk. */ - pattern++; - - /* If at end of pattern, accept immediately. */ - if (!*pattern) - return 1; - - /* If next character in pattern is known, optimize. */ - if (*pattern != '?' && *pattern != '*') { - /* - * Look instances of the next character in - * pattern, and try to match starting from - * those. - */ - for (; *s; s++) - if (*s == *pattern && match_pattern(s + 1, pattern + 1)) { - return 1; - } - /* Failed. */ - return 0; - } - /* - * Move ahead one character at a time and try to - * match at each position. - */ - for (; *s; s++) { - if (match_pattern(s, pattern)) { - return 1; - } - } - /* Failed. */ - return 0; - } - /* - * There must be at least one more character in the string. - * If we are at the end, fail. - */ - if (!*s) { - return 0; - } - - /* Check if the next character of the string is acceptable. */ - if (*pattern != '?' && *pattern != *s) { - return 0; - } - - /* Move to the next character, both in string and in pattern. */ - s++; - pattern++; - } - - /* NOTREACHED */ -} - -/* - * Tries to match the string against the comma-separated sequence of subpatterns - * (each possibly preceded by ! to indicate negation). - * Returns -1 if negation matches, 1 if there is a positive match, 0 if there is - * no match at all. - */ -static int match_pattern_list(const char *string, const char *pattern, - unsigned int len, int dolower) { - char sub[1024]; - int negated; - int got_positive; - unsigned int i, subi; - - got_positive = 0; - for (i = 0; i < len;) { - /* Check if the subpattern is negated. */ - if (pattern[i] == '!') { - negated = 1; - i++; - } else { - negated = 0; - } - - /* - * Extract the subpattern up to a comma or end. Convert the - * subpattern to lowercase. - */ - for (subi = 0; - i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; - subi++, i++) { - sub[subi] = dolower && isupper(pattern[i]) ? - (char)tolower(pattern[i]) : pattern[i]; - } - - /* If subpattern too long, return failure (no match). */ - if (subi >= sizeof(sub) - 1) { - return 0; - } - - /* If the subpattern was terminated by a comma, skip the comma. */ - if (i < len && pattern[i] == ',') { - i++; - } - - /* Null-terminate the subpattern. */ - sub[subi] = '\0'; - - /* Try to match the subpattern against the string. */ - if (match_pattern(string, sub)) { - if (negated) { - return -1; /* Negative */ - } else { - got_positive = 1; /* Positive */ - } - } - } - - /* - * Return success if got a positive match. If there was a negative - * match, we have already returned -1 and never get here. - */ - return got_positive; -} - -/* - * Tries to match the host name (which must be in all lowercase) against the - * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). - * Returns -1 if negation matches, 1 if there is a positive match, 0 if there - * is no match at all. - */ -int match_hostname(const char *host, const char *pattern, unsigned int len) { - return match_pattern_list(host, pattern, len, 1); -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/messages.c b/libssh/src/messages.c deleted file mode 100644 index 5a6963e8..00000000 --- a/libssh/src/messages.c +++ /dev/null @@ -1,1379 +0,0 @@ -/* - * messages.c - message parsing for client and server - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/libssh.h" -#include "libssh/priv.h" -#include "libssh/ssh2.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/channels.h" -#include "libssh/session.h" -#include "libssh/misc.h" -#include "libssh/pki.h" -#include "libssh/dh.h" -#include "libssh/messages.h" -#ifdef WITH_SERVER -#include "libssh/server.h" -#include "libssh/gssapi.h" -#endif - -/** - * @defgroup libssh_messages The SSH message functions - * @ingroup libssh - * - * This file contains the message parsing utilities for client and server - * programs using libssh. - * - * On the server the the main loop of the program will call - * ssh_message_get(session) to get messages as they come. They are not 1-1 with - * the protocol messages. Then, the user will know what kind of a message it is - * and use the appropriate functions to handle it (or use the default handlers - * if you don't know what to do). - * - * @{ - */ - -static ssh_message ssh_message_new(ssh_session session){ - ssh_message msg = malloc(sizeof(struct ssh_message_struct)); - if (msg == NULL) { - return NULL; - } - ZERO_STRUCTP(msg); - msg->session = session; - return msg; -} - -#ifndef WITH_SERVER - -/* Reduced version of the reply default that only reply with - * SSH_MSG_UNIMPLEMENTED - */ -static int ssh_message_reply_default(ssh_message msg) { - SSH_LOG(SSH_LOG_FUNCTIONS, "Reporting unknown packet"); - - if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_UNIMPLEMENTED) < 0) - goto error; - if (buffer_add_u32(msg->session->out_buffer, - htonl(msg->session->recv_seq-1)) < 0) - goto error; - return packet_send(msg->session); - error: - return SSH_ERROR; -} - -#endif - -#ifdef WITH_SERVER - -static int ssh_execute_server_request(ssh_session session, ssh_message msg) -{ - ssh_channel channel = NULL; - int rc; - - switch(msg->type) { - case SSH_REQUEST_AUTH: - if (msg->auth_request.method == SSH_AUTH_METHOD_PASSWORD && - ssh_callbacks_exists(session->server_callbacks, auth_password_function)) { - rc = session->server_callbacks->auth_password_function(session, - msg->auth_request.username, msg->auth_request.password, - session->server_callbacks->userdata); - if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL) { - ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } else if(msg->auth_request.method == SSH_AUTH_METHOD_PUBLICKEY && - ssh_callbacks_exists(session->server_callbacks, auth_pubkey_function)) { - rc = session->server_callbacks->auth_pubkey_function(session, - msg->auth_request.username, msg->auth_request.pubkey, - msg->auth_request.signature_state, - session->server_callbacks->userdata); - if (msg->auth_request.signature_state != SSH_PUBLICKEY_STATE_NONE) { - if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL) { - ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL); - } else { - ssh_message_reply_default(msg); - } - } else { - if (rc == SSH_AUTH_SUCCESS) { - ssh_message_auth_reply_pk_ok_simple(msg); - } else { - ssh_message_reply_default(msg); - } - } - - return SSH_OK; - } else if (msg->auth_request.method == SSH_AUTH_METHOD_NONE && - ssh_callbacks_exists(session->server_callbacks, auth_none_function)) { - rc = session->server_callbacks->auth_none_function(session, - msg->auth_request.username, session->server_callbacks->userdata); - if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL){ - ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } - break; - case SSH_REQUEST_CHANNEL_OPEN: - if (msg->channel_request_open.type == SSH_CHANNEL_SESSION && - ssh_callbacks_exists(session->server_callbacks, channel_open_request_session_function)) { - channel = session->server_callbacks->channel_open_request_session_function(session, - session->server_callbacks->userdata); - if (channel != NULL) { - rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel); - return SSH_OK; - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } - break; - case SSH_REQUEST_CHANNEL: - channel = msg->channel_request.channel; - - if (msg->channel_request.type == SSH_CHANNEL_REQUEST_PTY && - ssh_callbacks_exists(channel->callbacks, channel_pty_request_function)) { - rc = channel->callbacks->channel_pty_request_function(session, channel, - msg->channel_request.TERM, - msg->channel_request.width, msg->channel_request.height, - msg->channel_request.pxwidth, msg->channel_request.pxheight, - channel->callbacks->userdata); - if (rc == 0) { - ssh_message_channel_request_reply_success(msg); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_SHELL && - ssh_callbacks_exists(channel->callbacks, channel_shell_request_function)) { - rc = channel->callbacks->channel_shell_request_function(session, - channel, - channel->callbacks->userdata); - if (rc == 0) { - ssh_message_channel_request_reply_success(msg); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_X11 && - ssh_callbacks_exists(channel->callbacks, channel_x11_req_function)) { - channel->callbacks->channel_x11_req_function(session, - channel, - msg->channel_request.x11_single_connection, - msg->channel_request.x11_auth_protocol, - msg->channel_request.x11_auth_cookie, - msg->channel_request.x11_screen_number, - channel->callbacks->userdata); - ssh_message_channel_request_reply_success(msg); - - return SSH_OK; - } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_WINDOW_CHANGE && - ssh_callbacks_exists(channel->callbacks, channel_pty_window_change_function)) { - rc = channel->callbacks->channel_pty_window_change_function(session, - channel, - msg->channel_request.width, msg->channel_request.height, - msg->channel_request.pxwidth, msg->channel_request.pxheight, - channel->callbacks->userdata); - } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_EXEC && - ssh_callbacks_exists(channel->callbacks, channel_exec_request_function)) { - rc = channel->callbacks->channel_exec_request_function(session, - channel, - msg->channel_request.command, - channel->callbacks->userdata); - if (rc == 0) { - ssh_message_channel_request_reply_success(msg); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_ENV && - ssh_callbacks_exists(channel->callbacks, channel_env_request_function)) { - rc = channel->callbacks->channel_env_request_function(session, - channel, - msg->channel_request.var_name, msg->channel_request.var_value, - channel->callbacks->userdata); - if (rc == 0) { - ssh_message_channel_request_reply_success(msg); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_SUBSYSTEM && - ssh_callbacks_exists(channel->callbacks, channel_subsystem_request_function)) { - rc = channel->callbacks->channel_subsystem_request_function(session, - channel, - msg->channel_request.subsystem, - channel->callbacks->userdata); - if (rc == 0) { - ssh_message_channel_request_reply_success(msg); - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } - break; - case SSH_REQUEST_SERVICE: - if (ssh_callbacks_exists(session->server_callbacks, service_request_function)) { - rc = session->server_callbacks->service_request_function(session, - msg->service_request.service, session->server_callbacks->userdata); - if (rc == 0) { - ssh_message_reply_default(msg); - } else { - ssh_disconnect(session); - } - - return SSH_OK; - } - - return SSH_AGAIN; - case SSH_REQUEST_GLOBAL: - break; - } - - return SSH_AGAIN; -} - -static int ssh_execute_client_request(ssh_session session, ssh_message msg) -{ - ssh_channel channel = NULL; - int rc = SSH_AGAIN; - - if (msg->type == SSH_REQUEST_CHANNEL_OPEN - && msg->channel_request_open.type == SSH_CHANNEL_X11 - && ssh_callbacks_exists(session->common.callbacks, channel_open_request_x11_function)) { - channel = session->common.callbacks->channel_open_request_x11_function (session, - msg->channel_request_open.originator, - msg->channel_request_open.originator_port, - session->common.callbacks->userdata); - if (channel != NULL) { - rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel); - - return rc; - } else { - ssh_message_reply_default(msg); - } - - return SSH_OK; - } - - return rc; -} - -/** @internal - * Executes the callbacks defined in session->server_callbacks, out of an ssh_message - * I don't like ssh_message interface but it works. - * @returns SSH_OK if the message has been handled, or SSH_AGAIN otherwise. - */ -static int ssh_execute_server_callbacks(ssh_session session, ssh_message msg){ - int rc = SSH_AGAIN; - - if (session->server_callbacks != NULL){ - rc = ssh_execute_server_request(session, msg); - } else if (session->common.callbacks != NULL) { - /* This one is in fact a client callback... */ - rc = ssh_execute_client_request(session, msg); - } - - return rc; -} - -#endif /* WITH_SERVER */ - -static int ssh_execute_message_callback(ssh_session session, ssh_message msg) { - int ret; - if(session->ssh_message_callback != NULL) { - ret = session->ssh_message_callback(session, msg, - session->ssh_message_callback_data); - if(ret == 1) { - ret = ssh_message_reply_default(msg); - ssh_message_free(msg); - if(ret != SSH_OK) { - return ret; - } - } else { - ssh_message_free(msg); - } - } else { - ret = ssh_message_reply_default(msg); - ssh_message_free(msg); - if(ret != SSH_OK) { - return ret; - } - } - return SSH_OK; -} - -/** - * @internal - * - * @brief Add a message to the current queue of messages to be parsed and/or call - * the various callback functions. - * - * @param[in] session The SSH session to add the message. - * - * @param[in] message The message to add to the queue. - */ -void ssh_message_queue(ssh_session session, ssh_message message){ - if (message != NULL) { -#ifdef WITH_SERVER - int ret; - /* probably not the best place to execute server callbacks, but still better - * than nothing. - */ - ret = ssh_execute_server_callbacks(session, message); - if (ret == SSH_OK){ - ssh_message_free(message); - return; - } -#endif /* WITH_SERVER */ - if(session->ssh_message_callback != NULL) { - ssh_execute_message_callback(session, message); - return; - } - if (session->server_callbacks != NULL){ - /* if we have server callbacks, but nothing was executed, it means we are - * in non-synchronous mode, and we just don't care about the message we - * received. Just send a default response. Do not queue it. - */ - ssh_message_reply_default(message); - ssh_message_free(message); - return; - } - if(session->ssh_message_list == NULL) { - session->ssh_message_list = ssh_list_new(); - } - if (session->ssh_message_list != NULL) { - ssh_list_append(session->ssh_message_list, message); - } - } -} - -/** - * @internal - * - * @brief Pop a message from the message list and dequeue it. - * - * @param[in] session The SSH session to pop the message. - * - * @returns The head message or NULL if it doesn't exist. - */ -ssh_message ssh_message_pop_head(ssh_session session){ - ssh_message msg=NULL; - struct ssh_iterator *i; - if(session->ssh_message_list == NULL) - return NULL; - i=ssh_list_get_iterator(session->ssh_message_list); - if(i != NULL){ - msg=ssh_iterator_value(ssh_message,i); - ssh_list_remove(session->ssh_message_list,i); - } - return msg; -} - -/* Returns 1 if there is a message available */ -static int ssh_message_termination(void *s){ - ssh_session session = s; - struct ssh_iterator *it; - if(session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - it = ssh_list_get_iterator(session->ssh_message_list); - if(!it) - return 0; - else - return 1; -} -/** - * @brief Retrieve a SSH message from a SSH session. - * - * @param[in] session The SSH session to get the message. - * - * @returns The SSH message received, NULL in case of error, or timeout - * elapsed. - * - * @warning This function blocks until a message has been received. Betterset up - * a callback if this behavior is unwanted. - */ -ssh_message ssh_message_get(ssh_session session) { - ssh_message msg = NULL; - int rc; - - msg=ssh_message_pop_head(session); - if(msg) { - return msg; - } - if(session->ssh_message_list == NULL) { - session->ssh_message_list = ssh_list_new(); - } - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_USER, - ssh_message_termination, session); - if(rc || session->session_state == SSH_SESSION_STATE_ERROR) - return NULL; - msg=ssh_list_pop_head(ssh_message, session->ssh_message_list); - - return msg; -} - -/** - * @brief Get the type of the message. - * - * @param[in] msg The message to get the type from. - * - * @return The message type or -1 on error. - */ -int ssh_message_type(ssh_message msg) { - if (msg == NULL) { - return -1; - } - - return msg->type; -} - -/** - * @brief Get the subtype of the message. - * - * @param[in] msg The message to get the subtype from. - * - * @return The message type or -1 on error. - */ -int ssh_message_subtype(ssh_message msg) { - if (msg == NULL) { - return -1; - } - - switch(msg->type) { - case SSH_REQUEST_AUTH: - return msg->auth_request.method; - case SSH_REQUEST_CHANNEL_OPEN: - return msg->channel_request_open.type; - case SSH_REQUEST_CHANNEL: - return msg->channel_request.type; - case SSH_REQUEST_GLOBAL: - return msg->global_request.type; - } - - return -1; -} - -/** - * @brief Free a SSH message. - * - * @param[in] msg The message to release the memory. - */ -void ssh_message_free(ssh_message msg){ - if (msg == NULL) { - return; - } - - switch(msg->type) { - case SSH_REQUEST_AUTH: - SAFE_FREE(msg->auth_request.username); - if (msg->auth_request.password) { - BURN_STRING(msg->auth_request.password); - SAFE_FREE(msg->auth_request.password); - } - ssh_key_free(msg->auth_request.pubkey); - break; - case SSH_REQUEST_CHANNEL_OPEN: - SAFE_FREE(msg->channel_request_open.originator); - SAFE_FREE(msg->channel_request_open.destination); - break; - case SSH_REQUEST_CHANNEL: - SAFE_FREE(msg->channel_request.TERM); - SAFE_FREE(msg->channel_request.modes); - SAFE_FREE(msg->channel_request.var_name); - SAFE_FREE(msg->channel_request.var_value); - SAFE_FREE(msg->channel_request.command); - SAFE_FREE(msg->channel_request.subsystem); - break; - case SSH_REQUEST_SERVICE: - SAFE_FREE(msg->service_request.service); - break; - case SSH_REQUEST_GLOBAL: - SAFE_FREE(msg->global_request.bind_address); - break; - } - ZERO_STRUCTP(msg); - SAFE_FREE(msg); -} - -#ifdef WITH_SERVER - -SSH_PACKET_CALLBACK(ssh_packet_service_request){ - ssh_string service = NULL; - char *service_c = NULL; - ssh_message msg=NULL; - - (void)type; - (void)user; - service = buffer_get_ssh_string(packet); - if (service == NULL) { - ssh_set_error(session, SSH_FATAL, "Invalid SSH_MSG_SERVICE_REQUEST packet"); - goto error; - } - - service_c = ssh_string_to_char(service); - if (service_c == NULL) { - goto error; - } - SSH_LOG(SSH_LOG_PACKET, - "Received a SERVICE_REQUEST for service %s", service_c); - msg=ssh_message_new(session); - if(!msg){ - SAFE_FREE(service_c); - goto error; - } - msg->type=SSH_REQUEST_SERVICE; - msg->service_request.service=service_c; -error: - ssh_string_free(service); - if(msg != NULL) - ssh_message_queue(session,msg); - - return SSH_PACKET_USED; -} - - -/* - * This function concats in a buffer the values needed to do a signature - * verification. - */ -static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session, - ssh_message msg, - const char *service) -{ - struct ssh_crypto_struct *crypto = - session->current_crypto ? session->current_crypto : - session->next_crypto; - ssh_buffer buffer; - ssh_string str=NULL; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - return NULL; - } - rc = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey, &str); - if (rc < 0) { - ssh_buffer_free(buffer); - return NULL; - } - - rc = ssh_buffer_pack(buffer, - "dPbsssbsS", - crypto->digest_len, /* session ID string */ - (size_t)crypto->digest_len, crypto->session_id, - SSH2_MSG_USERAUTH_REQUEST, /* type */ - msg->auth_request.username, - service, - "publickey", /* method */ - 1, /* has to be signed (true) */ - msg->auth_request.pubkey->type_c, /* pubkey algorithm */ - str); /* public key as a blob */ - - ssh_string_free(str); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - ssh_buffer_free(buffer); - return NULL; - } - - return buffer; -} - -/** - * @internal - * - * @brief Handle a SSH_MSG_MSG_USERAUTH_REQUEST packet and queue a - * SSH Message - */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ - ssh_message msg = NULL; - char *service = NULL; - char *method = NULL; - int rc; - - (void)user; - (void)type; - - msg = ssh_message_new(session); - if (msg == NULL) { - ssh_set_error_oom(session); - goto error; - } - msg->type = SSH_REQUEST_AUTH; - rc = ssh_buffer_unpack(packet, - "sss", - &msg->auth_request.username, - &service, - &method); - - if (rc != SSH_OK) { - goto error; - } - - SSH_LOG(SSH_LOG_PACKET, - "Auth request for service %s, method %s for user '%s'", - service, method, - msg->auth_request.username); - - - if (strcmp(method, "none") == 0) { - msg->auth_request.method = SSH_AUTH_METHOD_NONE; - goto end; - } - - if (strcmp(method, "password") == 0) { - uint8_t tmp; - - msg->auth_request.method = SSH_AUTH_METHOD_PASSWORD; - rc = ssh_buffer_unpack(packet, "bs", &tmp, &msg->auth_request.password); - if (rc != SSH_OK) { - goto error; - } - goto end; - } - - if (strcmp(method, "keyboard-interactive") == 0) { - ssh_string lang = NULL; - ssh_string submethods = NULL; - - msg->auth_request.method = SSH_AUTH_METHOD_INTERACTIVE; - lang = buffer_get_ssh_string(packet); - if (lang == NULL) { - goto error; - } - /* from the RFC 4256 - * 3.1. Initial Exchange - * "The language tag is deprecated and SHOULD be the empty string." - */ - ssh_string_free(lang); - - submethods = buffer_get_ssh_string(packet); - if (submethods == NULL) { - goto error; - } - /* from the RFC 4256 - * 3.1. Initial Exchange - * "One possible implementation strategy of the submethods field on the - * server is that, unless the user may use multiple different - * submethods, the server ignores this field." - */ - ssh_string_free(submethods); - - goto end; - } - - if (strcmp(method, "publickey") == 0) { - ssh_string algo = NULL; - ssh_string pubkey_blob = NULL; - uint8_t has_sign; - - msg->auth_request.method = SSH_AUTH_METHOD_PUBLICKEY; - SAFE_FREE(method); - rc = ssh_buffer_unpack(packet, "bSS", - &has_sign, - &algo, - &pubkey_blob - ); - - if (rc != SSH_OK) { - goto error; - } - ssh_string_free(algo); - algo = NULL; - - rc = ssh_pki_import_pubkey_blob(pubkey_blob, &msg->auth_request.pubkey); - ssh_string_free(pubkey_blob); - pubkey_blob = NULL; - if (rc < 0) { - goto error; - } - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_NONE; - // has a valid signature ? - if(has_sign) { - ssh_string sig_blob = NULL; - ssh_buffer digest = NULL; - - sig_blob = buffer_get_ssh_string(packet); - if(sig_blob == NULL) { - SSH_LOG(SSH_LOG_PACKET, "Invalid signature packet from peer"); - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR; - goto error; - } - - digest = ssh_msg_userauth_build_digest(session, msg, service); - if (digest == NULL) { - ssh_string_free(sig_blob); - SSH_LOG(SSH_LOG_PACKET, "Failed to get digest"); - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; - goto error; - } - - rc = ssh_pki_signature_verify_blob(session, - sig_blob, - msg->auth_request.pubkey, - buffer_get_rest(digest), - buffer_get_rest_len(digest)); - ssh_string_free(sig_blob); - ssh_buffer_free(digest); - if (rc < 0) { - SSH_LOG( - SSH_LOG_PACKET, - "Received an invalid signature from peer"); - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; - goto error; - } - - SSH_LOG(SSH_LOG_PACKET, "Valid signature received"); - - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_VALID; - } - goto end; - } -#ifdef WITH_GSSAPI - if (strcmp(method, "gssapi-with-mic") == 0) { - uint32_t n_oid; - ssh_string *oids; - ssh_string oid; - char *hexa; - int i; - buffer_get_u32(packet, &n_oid); - n_oid=ntohl(n_oid); - if(n_oid > 100){ - ssh_set_error(session, SSH_FATAL, "USERAUTH_REQUEST: gssapi-with-mic OID count too big (%d)",n_oid); - goto error; - } - SSH_LOG(SSH_LOG_PACKET, "gssapi: %d OIDs", n_oid); - oids = calloc(n_oid, sizeof(ssh_string)); - if (oids == NULL){ - ssh_set_error_oom(session); - goto error; - } - for (i=0;i<(int) n_oid;++i){ - oid=buffer_get_ssh_string(packet); - if(oid == NULL){ - for(i=i-1;i>=0;--i){ - SAFE_FREE(oids[i]); - } - SAFE_FREE(oids); - ssh_set_error(session, SSH_LOG_PACKET, "USERAUTH_REQUEST: gssapi-with-mic missing OID"); - goto error; - } - oids[i] = oid; - if(session->common.log_verbosity >= SSH_LOG_PACKET){ - hexa = ssh_get_hexa(ssh_string_data(oid), ssh_string_len(oid)); - SSH_LOG(SSH_LOG_PACKET,"gssapi: OID %d: %s",i, hexa); - SAFE_FREE(hexa); - } - } - ssh_gssapi_handle_userauth(session, msg->auth_request.username, n_oid, oids); - - for(i=0;i<(int)n_oid;++i){ - SAFE_FREE(oids[i]); - } - SAFE_FREE(oids); - /* bypass the message queue thing */ - SAFE_FREE(service); - SAFE_FREE(method); - ssh_message_free(msg); - - return SSH_PACKET_USED; - } -#endif - - msg->auth_request.method = SSH_AUTH_METHOD_UNKNOWN; - SAFE_FREE(method); - goto end; -error: - SAFE_FREE(service); - SAFE_FREE(method); - - ssh_message_free(msg); - - return SSH_PACKET_USED; -end: - SAFE_FREE(service); - SAFE_FREE(method); - - ssh_message_queue(session,msg); - - return SSH_PACKET_USED; -} - -#endif /* WITH_SERVER */ -/** - * @internal - * - * @brief Handle a SSH_MSG_MSG_USERAUTH_INFO_RESPONSE packet and queue a - * SSH Message - */ -#ifndef WITH_SERVER -SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){ - (void)session; - (void)type; - (void)packet; - (void)user; - return SSH_PACKET_USED; -} -#else /* WITH_SERVER */ -SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){ - uint32_t nanswers; - uint32_t i; - ssh_string tmp; - int rc; - - ssh_message msg = NULL; - - /* GSSAPI_TOKEN has same packed number. XXX fix this */ -#ifdef WITH_GSSAPI - if (session->gssapi != NULL) { - return ssh_packet_userauth_gssapi_token(session, type, packet, user); - } -#endif - (void)user; - (void)type; - - msg = ssh_message_new(session); - if (msg == NULL) { - ssh_set_error_oom(session); - goto error; - } - - /* HACK: we forge a message to be able to handle it in the - * same switch() as other auth methods */ - msg->type = SSH_REQUEST_AUTH; - msg->auth_request.method = SSH_AUTH_METHOD_INTERACTIVE; - msg->auth_request.kbdint_response = 1; -#if 0 // should we wipe the username ? - msg->auth_request.username = NULL; -#endif - - rc = ssh_buffer_unpack(packet, "d", &nanswers); - if (rc != SSH_OK) { - ssh_set_error_invalid(session); - goto error; - } - - if (session->kbdint == NULL) { - SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a keyboard-interactive " - "response but it seems we didn't send the request."); - - session->kbdint = ssh_kbdint_new(); - if (session->kbdint == NULL) { - ssh_set_error_oom(session); - - goto error; - } - } - - SSH_LOG(SSH_LOG_PACKET,"kbdint: %d answers",nanswers); - if (nanswers > KBDINT_MAX_PROMPT) { - ssh_set_error(session, SSH_FATAL, - "Too much answers received from client: %u (0x%.4x)", - nanswers, nanswers); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - goto error; - } - - if(nanswers != session->kbdint->nprompts) { - /* warn but let the application handle this case */ - SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Number of prompts and answers" - " mismatch: p=%u a=%u", session->kbdint->nprompts, nanswers); - } - session->kbdint->nanswers = nanswers; - session->kbdint->answers = malloc(nanswers * sizeof(char *)); - if (session->kbdint->answers == NULL) { - session->kbdint->nanswers = 0; - ssh_set_error_oom(session); - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - goto error; - } - memset(session->kbdint->answers, 0, nanswers * sizeof(char *)); - - for (i = 0; i < nanswers; i++) { - tmp = buffer_get_ssh_string(packet); - if (tmp == NULL) { - ssh_set_error(session, SSH_FATAL, "Short INFO_RESPONSE packet"); - session->kbdint->nanswers = i; - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - goto error; - } - session->kbdint->answers[i] = ssh_string_to_char(tmp); - ssh_string_free(tmp); - if (session->kbdint->answers[i] == NULL) { - ssh_set_error_oom(session); - session->kbdint->nanswers = i; - ssh_kbdint_free(session->kbdint); - session->kbdint = NULL; - - goto error; - } - } - - ssh_message_queue(session,msg); - - return SSH_PACKET_USED; - -error: - ssh_message_free(msg); - - return SSH_PACKET_USED; -} -#endif /* WITH_SERVER */ - -SSH_PACKET_CALLBACK(ssh_packet_channel_open){ - ssh_message msg = NULL; - char *type_c = NULL; - uint32_t originator_port, destination_port; - int rc; - - (void)type; - (void)user; - msg = ssh_message_new(session); - if (msg == NULL) { - ssh_set_error_oom(session); - goto error; - } - - msg->type = SSH_REQUEST_CHANNEL_OPEN; - rc = ssh_buffer_unpack(packet, "s", &type_c); - if (rc != SSH_OK){ - goto error; - } - - SSH_LOG(SSH_LOG_PACKET, - "Clients wants to open a %s channel", type_c); - - ssh_buffer_unpack(packet,"ddd", - &msg->channel_request_open.sender, - &msg->channel_request_open.window, - &msg->channel_request_open.packet_size); - - if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED){ - ssh_set_error(session,SSH_FATAL, "Invalid state when receiving channel open request (must be authenticated)"); - goto error; - } - - if (strcmp(type_c,"session") == 0) { - msg->channel_request_open.type = SSH_CHANNEL_SESSION; - SAFE_FREE(type_c); - goto end; - } - - if (strcmp(type_c,"direct-tcpip") == 0) { - rc = ssh_buffer_unpack(packet, - "sdsd", - &msg->channel_request_open.destination, - &destination_port, - &msg->channel_request_open.originator, - &originator_port); - if (rc != SSH_OK) { - goto error; - } - - msg->channel_request_open.destination_port = (uint16_t) destination_port; - msg->channel_request_open.originator_port = (uint16_t) originator_port; - msg->channel_request_open.type = SSH_CHANNEL_DIRECT_TCPIP; - goto end; - } - - if (strcmp(type_c,"forwarded-tcpip") == 0) { - rc = ssh_buffer_unpack(packet, "sdsd", - &msg->channel_request_open.destination, - &destination_port, - &msg->channel_request_open.originator, - &originator_port - ); - if (rc != SSH_OK){ - goto error; - } - msg->channel_request_open.destination_port = (uint16_t) destination_port; - msg->channel_request_open.originator_port = (uint16_t) originator_port; - msg->channel_request_open.type = SSH_CHANNEL_FORWARDED_TCPIP; - goto end; - } - - if (strcmp(type_c,"x11") == 0) { - rc = ssh_buffer_unpack(packet, "sd", - &msg->channel_request_open.originator, - &originator_port); - if (rc != SSH_OK){ - goto error; - } - msg->channel_request_open.originator_port = (uint16_t) originator_port; - msg->channel_request_open.type = SSH_CHANNEL_X11; - goto end; - } - - msg->channel_request_open.type = SSH_CHANNEL_UNKNOWN; - goto end; - -error: - ssh_message_free(msg); - msg=NULL; -end: - SAFE_FREE(type_c); - if(msg != NULL) - ssh_message_queue(session,msg); - - return SSH_PACKET_USED; -} - -int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan) { - ssh_session session; - int rc; - - if (msg == NULL) { - return SSH_ERROR; - } - - session = msg->session; - - chan->local_channel = ssh_channel_new_id(session); - chan->local_maxpacket = 35000; - chan->local_window = 32000; - chan->remote_channel = msg->channel_request_open.sender; - chan->remote_maxpacket = msg->channel_request_open.packet_size; - chan->remote_window = msg->channel_request_open.window; - chan->state = SSH_CHANNEL_STATE_OPEN; - - rc = ssh_buffer_pack(session->out_buffer, - "bdddd", - SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, - chan->remote_channel, - chan->local_channel, - chan->local_window, - chan->local_maxpacket); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PACKET, - "Accepting a channel request_open for chan %d", - chan->remote_channel); - - rc = packet_send(session); - - return rc; -} - - -ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) { - ssh_channel chan; - int rc; - - if (msg == NULL) { - return NULL; - } - - chan = ssh_channel_new(msg->session); - if (chan == NULL) { - return NULL; - } - rc = ssh_message_channel_request_open_reply_accept_channel(msg, chan); - if (rc < 0) { - ssh_channel_free(chan); - chan = NULL; - } - return chan; - -} - -/** - * @internal - * - * @brief This function parses the last end of a channel request packet. - * - * This is normally converted to a SSH message and placed in the queue. - * - * @param[in] session The SSH session. - * - * @param[in] channel The channel the request is made on. - * - * @param[in] packet The rest of the packet to be parsed. - * - * @param[in] request The type of request. - * - * @param[in] want_reply The want_reply field from the request. - * - * @returns SSH_OK on success, SSH_ERROR if an error occured. - */ -int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet, - const char *request, uint8_t want_reply) { - ssh_message msg = NULL; - int rc; - - msg = ssh_message_new(session); - if (msg == NULL) { - ssh_set_error_oom(session); - goto error; - } - - SSH_LOG(SSH_LOG_PACKET, - "Received a %s channel_request for channel (%d:%d) (want_reply=%hhd)", - request, channel->local_channel, channel->remote_channel, want_reply); - - msg->type = SSH_REQUEST_CHANNEL; - msg->channel_request.channel = channel; - msg->channel_request.want_reply = want_reply; - - if (strcmp(request, "pty-req") == 0) { - rc = ssh_buffer_unpack(packet, "sddddS", - &msg->channel_request.TERM, - &msg->channel_request.width, - &msg->channel_request.height, - &msg->channel_request.pxwidth, - &msg->channel_request.pxheight, - &msg->channel_request.modes - ); - - msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY; - - if (rc != SSH_OK) { - goto error; - } - goto end; - } - - if (strcmp(request, "window-change") == 0) { - msg->channel_request.type = SSH_CHANNEL_REQUEST_WINDOW_CHANGE; - rc = ssh_buffer_unpack(packet, "dddd", - &msg->channel_request.width, - &msg->channel_request.height, - &msg->channel_request.pxwidth, - &msg->channel_request.pxheight); - if (rc != SSH_OK){ - goto error; - } - goto end; - } - - if (strcmp(request, "subsystem") == 0) { - rc = ssh_buffer_unpack(packet, "s", - &msg->channel_request.subsystem); - msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM; - if (rc != SSH_OK){ - goto error; - } - goto end; - } - - if (strcmp(request, "shell") == 0) { - msg->channel_request.type = SSH_CHANNEL_REQUEST_SHELL; - goto end; - } - - if (strcmp(request, "exec") == 0) { - rc = ssh_buffer_unpack(packet, "s", - &msg->channel_request.command); - msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC; - if (rc != SSH_OK) { - goto error; - } - goto end; - } - - if (strcmp(request, "env") == 0) { - rc = ssh_buffer_unpack(packet, "ss", - &msg->channel_request.var_name, - &msg->channel_request.var_value); - msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV; - if (rc != SSH_OK) { - goto error; - } - goto end; - } - - if (strcmp(request, "x11-req") == 0) { - rc = ssh_buffer_unpack(packet, "bssd", - &msg->channel_request.x11_single_connection, - &msg->channel_request.x11_auth_protocol, - &msg->channel_request.x11_auth_cookie, - &msg->channel_request.x11_screen_number); - - msg->channel_request.type = SSH_CHANNEL_REQUEST_X11; - if (rc != SSH_OK) { - goto error; - } - - goto end; - } - - msg->channel_request.type = SSH_CHANNEL_REQUEST_UNKNOWN; -end: - ssh_message_queue(session,msg); - - return SSH_OK; -error: - ssh_message_free(msg); - - return SSH_ERROR; -} - -int ssh_message_channel_request_reply_success(ssh_message msg) { - uint32_t channel; - int rc; - - if (msg == NULL) { - return SSH_ERROR; - } - - if (msg->channel_request.want_reply) { - channel = msg->channel_request.channel->remote_channel; - - SSH_LOG(SSH_LOG_PACKET, - "Sending a channel_request success to channel %d", channel); - - rc = ssh_buffer_pack(msg->session->out_buffer, - "bd", - SSH2_MSG_CHANNEL_SUCCESS, - channel); - if (rc != SSH_OK){ - ssh_set_error_oom(msg->session); - return SSH_ERROR; - } - - return packet_send(msg->session); - } - - SSH_LOG(SSH_LOG_PACKET, - "The client doesn't want to know the request succeeded"); - - return SSH_OK; -} - -#ifdef WITH_SERVER -SSH_PACKET_CALLBACK(ssh_packet_global_request){ - ssh_message msg = NULL; - char *request=NULL; - uint8_t want_reply; - int rc = SSH_PACKET_USED; - int r; - (void)user; - (void)type; - (void)packet; - - SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet"); - r = ssh_buffer_unpack(packet, "sb", - &request, - &want_reply); - if (r != SSH_OK){ - goto error; - } - - msg = ssh_message_new(session); - if (msg == NULL) { - ssh_set_error_oom(session); - goto error; - } - msg->type = SSH_REQUEST_GLOBAL; - - if (strcmp(request, "tcpip-forward") == 0) { - r = ssh_buffer_unpack(packet, "sd", - &msg->global_request.bind_address, - &msg->global_request.bind_port - ); - if (r != SSH_OK){ - goto error; - } - msg->global_request.type = SSH_GLOBAL_REQUEST_TCPIP_FORWARD; - msg->global_request.want_reply = want_reply; - - SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, - msg->global_request.bind_address, - msg->global_request.bind_port); - - if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) { - SSH_LOG(SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, - want_reply, msg->global_request.bind_address, - msg->global_request.bind_port); - session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata); - } else { - ssh_message_reply_default(msg); - } - } else if (strcmp(request, "cancel-tcpip-forward") == 0) { - r = ssh_buffer_unpack(packet, "sd", - &msg->global_request.bind_address, - &msg->global_request.bind_port); - if (r != SSH_OK){ - goto error; - } - msg->global_request.type = SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD; - msg->global_request.want_reply = want_reply; - - SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, - msg->global_request.bind_address, - msg->global_request.bind_port); - - if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) { - session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata); - } else { - ssh_message_reply_default(msg); - } - } else { - SSH_LOG(SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s %d", request, want_reply); - rc = SSH_PACKET_NOT_USED; - } - - SAFE_FREE(msg); - SAFE_FREE(request); - return rc; -error: - SAFE_FREE(msg); - SAFE_FREE(request); - SSH_LOG(SSH_LOG_WARNING, "Invalid SSH_MSG_GLOBAL_REQUEST packet"); - return SSH_PACKET_NOT_USED; -} - -#endif /* WITH_SERVER */ - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/misc.c b/libssh/src/misc.c deleted file mode 100644 index 6daf60ab..00000000 --- a/libssh/src/misc.c +++ /dev/null @@ -1,1035 +0,0 @@ -/* - * misc.c - useful client functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2009 by Aris Adamantiadis - * Copyright (c) 2008-2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#ifndef _WIN32 -/* This is needed for a standard getpwuid_r on opensolaris */ -#define _POSIX_PTHREAD_SEMANTICS -#include -#include -#include -#include -#include - -#ifndef HAVE_CLOCK_GETTIME -#include -#endif /* HAVE_CLOCK_GETTIME */ -#endif /* _WIN32 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 - -#ifndef _WIN32_IE -# define _WIN32_IE 0x0501 // SHGetSpecialFolderPath -#endif - -#include // Must be the first to include -#include -#include -#include - -#if _MSC_VER >= 1400 -# include -#endif /* _MSC_VER */ - -#endif /* _WIN32 */ - -#include "libssh/priv.h" -#include "libssh/misc.h" -#include "libssh/session.h" - -#ifdef HAVE_LIBGCRYPT -#define GCRYPT_STRING "/gnutls" -#else -#define GCRYPT_STRING "" -#endif - -#ifdef HAVE_LIBCRYPTO -#define CRYPTO_STRING "/openssl" -#else -#define CRYPTO_STRING "" -#endif - -#ifdef WITH_ZLIB -#define ZLIB_STRING "/zlib" -#else -#define ZLIB_STRING "" -#endif - -/** - * @defgroup libssh_misc The SSH helper functions. - * @ingroup libssh - * - * Different helper functions used in the SSH Library. - * - * @{ - */ - -#ifdef _WIN32 -char *ssh_get_user_home_dir(void) { - char tmp[MAX_PATH] = {0}; - char *szPath = NULL; - - if (SHGetSpecialFolderPathA(NULL, tmp, CSIDL_PROFILE, TRUE)) { - szPath = malloc(strlen(tmp) + 1); - if (szPath == NULL) { - return NULL; - } - - strcpy(szPath, tmp); - return szPath; - } - - return NULL; -} - -/* we have read access on file */ -int ssh_file_readaccess_ok(const char *file) { - if (_access(file, 4) < 0) { - return 0; - } - - return 1; -} - -#define SSH_USEC_IN_SEC 1000000LL -#define SSH_SECONDS_SINCE_1601 11644473600LL - -int gettimeofday(struct timeval *__p, void *__t) { - union { - unsigned long long ns100; /* time since 1 Jan 1601 in 100ns units */ - FILETIME ft; - } now; - - GetSystemTimeAsFileTime (&now.ft); - __p->tv_usec = (long) ((now.ns100 / 10LL) % SSH_USEC_IN_SEC); - __p->tv_sec = (long)(((now.ns100 / 10LL ) / SSH_USEC_IN_SEC) - SSH_SECONDS_SINCE_1601); - - return (0); -} - -char *ssh_get_local_username(void) { - DWORD size = 0; - char *user; - - /* get the size */ - GetUserName(NULL, &size); - - user = (char *) malloc(size); - if (user == NULL) { - return NULL; - } - - if (GetUserName(user, &size)) { - return user; - } - - return NULL; -} - -int ssh_is_ipaddr_v4(const char *str) { - struct sockaddr_storage ss; - int sslen = sizeof(ss); - int rc = SOCKET_ERROR; - - /* WSAStringToAddressA thinks that 0.0.0 is a valid IP */ - if (strlen(str) < 7) { - return 0; - } - - rc = WSAStringToAddressA((LPSTR) str, - AF_INET, - NULL, - (struct sockaddr*)&ss, - &sslen); - if (rc == 0) { - return 1; - } - - return 0; -} - -int ssh_is_ipaddr(const char *str) { - int rc = SOCKET_ERROR; - - if (strchr(str, ':')) { - struct sockaddr_storage ss; - int sslen = sizeof(ss); - - /* TODO link-local (IP:v6:addr%ifname). */ - rc = WSAStringToAddressA((LPSTR) str, - AF_INET6, - NULL, - (struct sockaddr*)&ss, - &sslen); - if (rc == 0) { - return 1; - } - } - - return ssh_is_ipaddr_v4(str); -} -#else /* _WIN32 */ - -#ifndef NSS_BUFLEN_PASSWD -#define NSS_BUFLEN_PASSWD 4096 -#endif /* NSS_BUFLEN_PASSWD */ - -char *ssh_get_user_home_dir(void) { - char *szPath = NULL; - struct passwd pwd; - struct passwd *pwdbuf; - char buf[NSS_BUFLEN_PASSWD]; - int rc; - - rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf); - if (rc != 0) { - szPath = getenv("HOME"); - if (szPath == NULL) { - return NULL; - } - memset(buf, 0, sizeof(buf)); - snprintf(buf, sizeof(buf), "%s", szPath); - - return strdup(buf); - } - - szPath = strdup(pwd.pw_dir); - - return szPath; -} - -/* we have read access on file */ -int ssh_file_readaccess_ok(const char *file) { - if (access(file, R_OK) < 0) { - return 0; - } - - return 1; -} - -char *ssh_get_local_username(void) { - struct passwd pwd; - struct passwd *pwdbuf; - char buf[NSS_BUFLEN_PASSWD]; - char *name; - int rc; - - rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf); - if (rc != 0) { - return NULL; - } - - name = strdup(pwd.pw_name); - - if (name == NULL) { - return NULL; - } - - return name; -} - -int ssh_is_ipaddr_v4(const char *str) { - int rc = -1; - struct in_addr dest; - - rc = inet_pton(AF_INET, str, &dest); - if (rc > 0) { - return 1; - } - - return 0; -} - -int ssh_is_ipaddr(const char *str) { - int rc = -1; - - if (strchr(str, ':')) { - struct in6_addr dest6; - - /* TODO link-local (IP:v6:addr%ifname). */ - rc = inet_pton(AF_INET6, str, &dest6); - if (rc > 0) { - return 1; - } - } - - return ssh_is_ipaddr_v4(str); -} - -#endif /* _WIN32 */ - -#ifndef HAVE_NTOHLL -uint64_t ntohll(uint64_t a) { -#ifdef WORDS_BIGENDIAN - return a; -#else /* WORDS_BIGENDIAN */ - return (((uint64_t)(a) << 56) | \ - (((uint64_t)(a) << 40) & 0xff000000000000ULL) | \ - (((uint64_t)(a) << 24) & 0xff0000000000ULL) | \ - (((uint64_t)(a) << 8) & 0xff00000000ULL) | \ - (((uint64_t)(a) >> 8) & 0xff000000ULL) | \ - (((uint64_t)(a) >> 24) & 0xff0000ULL) | \ - (((uint64_t)(a) >> 40) & 0xff00ULL) | \ - ((uint64_t)(a) >> 56)); -#endif /* WORDS_BIGENDIAN */ -} -#endif /* HAVE_NTOHLL */ - -char *ssh_lowercase(const char* str) { - char *new, *p; - - if (str == NULL) { - return NULL; - } - - new = strdup(str); - if (new == NULL) { - return NULL; - } - - for (p = new; *p; p++) { - *p = tolower(*p); - } - - return new; -} - -char *ssh_hostport(const char *host, int port){ - char *dest; - size_t len; - if(host==NULL) - return NULL; - /* 3 for []:, 5 for 65536 and 1 for nul */ - len=strlen(host) + 3 + 5 + 1; - dest=malloc(len); - if(dest==NULL) - return NULL; - snprintf(dest,len,"[%s]:%d",host,port); - return dest; -} - -/** - * @brief Check if libssh is the required version or get the version - * string. - * - * @param[in] req_version The version required. - * - * @return If the version of libssh is newer than the version - * required it will return a version string. - * NULL if the version is older. - * - * Example: - * - * @code - * if (ssh_version(SSH_VERSION_INT(0,2,1)) == NULL) { - * fprintf(stderr, "libssh version is too old!\n"); - * exit(1); - * } - * - * if (debug) { - * printf("libssh %s\n", ssh_version(0)); - * } - * @endcode - */ -const char *ssh_version(int req_version) { - if (req_version <= LIBSSH_VERSION_INT) { - return SSH_STRINGIFY(LIBSSH_VERSION) GCRYPT_STRING CRYPTO_STRING - ZLIB_STRING; - } - - return NULL; -} - -struct ssh_list *ssh_list_new(void) { - struct ssh_list *ret=malloc(sizeof(struct ssh_list)); - if(!ret) - return NULL; - ret->root=ret->end=NULL; - return ret; -} - -void ssh_list_free(struct ssh_list *list){ - struct ssh_iterator *ptr,*next; - if(!list) - return; - ptr=list->root; - while(ptr){ - next=ptr->next; - SAFE_FREE(ptr); - ptr=next; - } - SAFE_FREE(list); -} - -struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list){ - if(!list) - return NULL; - return list->root; -} - -struct ssh_iterator *ssh_list_find(const struct ssh_list *list, void *value){ - struct ssh_iterator *it; - for(it = ssh_list_get_iterator(list); it != NULL ;it=it->next) - if(it->data==value) - return it; - return NULL; -} - -static struct ssh_iterator *ssh_iterator_new(const void *data){ - struct ssh_iterator *iterator=malloc(sizeof(struct ssh_iterator)); - if(!iterator) - return NULL; - iterator->next=NULL; - iterator->data=data; - return iterator; -} - -int ssh_list_append(struct ssh_list *list,const void *data){ - struct ssh_iterator *iterator=ssh_iterator_new(data); - if(!iterator) - return SSH_ERROR; - if(!list->end){ - /* list is empty */ - list->root=list->end=iterator; - } else { - /* put it on end of list */ - list->end->next=iterator; - list->end=iterator; - } - return SSH_OK; -} - -int ssh_list_prepend(struct ssh_list *list, const void *data){ - struct ssh_iterator *it = ssh_iterator_new(data); - - if (it == NULL) { - return SSH_ERROR; - } - - if (list->end == NULL) { - /* list is empty */ - list->root = list->end = it; - } else { - /* set as new root */ - it->next = list->root; - list->root = it; - } - - return SSH_OK; -} - -void ssh_list_remove(struct ssh_list *list, struct ssh_iterator *iterator){ - struct ssh_iterator *ptr,*prev; - prev=NULL; - ptr=list->root; - while(ptr && ptr != iterator){ - prev=ptr; - ptr=ptr->next; - } - if(!ptr){ - /* we did not find the element */ - return; - } - /* unlink it */ - if(prev) - prev->next=ptr->next; - /* if iterator was the head */ - if(list->root == iterator) - list->root=iterator->next; - /* if iterator was the tail */ - if(list->end == iterator) - list->end = prev; - SAFE_FREE(iterator); -} - -/** - * @internal - * - * @brief Removes the top element of the list and returns the data value - * attached to it. - * - * @param[in[ list The ssh_list to remove the element. - * - * @returns A pointer to the element being stored in head, or NULL - * if the list is empty. - */ -const void *_ssh_list_pop_head(struct ssh_list *list){ - struct ssh_iterator *iterator=list->root; - const void *data; - if(!list->root) - return NULL; - data=iterator->data; - list->root=iterator->next; - if(list->end==iterator) - list->end=NULL; - SAFE_FREE(iterator); - return data; -} - -/** - * @brief Parse directory component. - * - * dirname breaks a null-terminated pathname string into a directory component. - * In the usual case, ssh_dirname() returns the string up to, but not including, - * the final '/'. Trailing '/' characters are not counted as part of the - * pathname. The caller must free the memory. - * - * @param[in] path The path to parse. - * - * @return The dirname of path or NULL if we can't allocate memory. - * If path does not contain a slash, c_dirname() returns - * the string ".". If path is the string "/", it returns - * the string "/". If path is NULL or an empty string, - * "." is returned. - */ -char *ssh_dirname (const char *path) { - char *new = NULL; - size_t len; - - if (path == NULL || *path == '\0') { - return strdup("."); - } - - len = strlen(path); - - /* Remove trailing slashes */ - while(len > 0 && path[len - 1] == '/') --len; - - /* We have only slashes */ - if (len == 0) { - return strdup("/"); - } - - /* goto next slash */ - while(len > 0 && path[len - 1] != '/') --len; - - if (len == 0) { - return strdup("."); - } else if (len == 1) { - return strdup("/"); - } - - /* Remove slashes again */ - while(len > 0 && path[len - 1] == '/') --len; - - new = malloc(len + 1); - if (new == NULL) { - return NULL; - } - - strncpy(new, path, len); - new[len] = '\0'; - - return new; -} - -/** - * @brief basename - parse filename component. - * - * basename breaks a null-terminated pathname string into a filename component. - * ssh_basename() returns the component following the final '/'. Trailing '/' - * characters are not counted as part of the pathname. - * - * @param[in] path The path to parse. - * - * @return The filename of path or NULL if we can't allocate - * memory. If path is a the string "/", basename returns - * the string "/". If path is NULL or an empty string, - * "." is returned. - */ -char *ssh_basename (const char *path) { - char *new = NULL; - const char *s; - size_t len; - - if (path == NULL || *path == '\0') { - return strdup("."); - } - - len = strlen(path); - /* Remove trailing slashes */ - while(len > 0 && path[len - 1] == '/') --len; - - /* We have only slashes */ - if (len == 0) { - return strdup("/"); - } - - while(len > 0 && path[len - 1] != '/') --len; - - if (len > 0) { - s = path + len; - len = strlen(s); - - while(len > 0 && s[len - 1] == '/') --len; - } else { - return strdup(path); - } - - new = malloc(len + 1); - if (new == NULL) { - return NULL; - } - - strncpy(new, s, len); - new[len] = '\0'; - - return new; -} - -/** - * @brief Attempts to create a directory with the given pathname. - * - * This is the portable version of mkdir, mode is ignored on Windows systems. - * - * @param[in] pathname The path name to create the directory. - * - * @param[in] mode The permissions to use. - * - * @return 0 on success, < 0 on error with errno set. - */ -int ssh_mkdir(const char *pathname, mode_t mode) { - int r; - -#ifdef _WIN32 - r = _mkdir(pathname); -#else - r = mkdir(pathname, mode); -#endif - - return r; -} - -/** - * @brief Expand a directory starting with a tilde '~' - * - * @param[in] d The directory to expand. - * - * @return The expanded directory, NULL on error. - */ -char *ssh_path_expand_tilde(const char *d) { - char *h = NULL, *r; - const char *p; - size_t ld; - size_t lh = 0; - - if (d[0] != '~') { - return strdup(d); - } - d++; - - /* handle ~user/path */ - p = strchr(d, '/'); - if (p != NULL && p > d) { -#ifdef _WIN32 - return strdup(d); -#else - struct passwd *pw; - size_t s = p - d; - char u[128]; - - if (s >= sizeof(u)) { - return NULL; - } - memcpy(u, d, s); - u[s] = '\0'; - pw = getpwnam(u); - if (pw == NULL) { - return NULL; - } - ld = strlen(p); - h = strdup(pw->pw_dir); -#endif - } else { - ld = strlen(d); - p = (char *) d; - h = ssh_get_user_home_dir(); - } - if (h == NULL) { - return NULL; - } - lh = strlen(h); - - r = malloc(ld + lh + 1); - if (r == NULL) { - SAFE_FREE(h); - return NULL; - } - - if (lh > 0) { - memcpy(r, h, lh); - } - SAFE_FREE(h); - memcpy(r + lh, p, ld + 1); - - return r; -} - -char *ssh_path_expand_escape(ssh_session session, const char *s) { - char host[NI_MAXHOST]; - char buf[MAX_BUF_SIZE]; - char *r, *x = NULL; - const char *p; - size_t i, l; - - r = ssh_path_expand_tilde(s); - if (r == NULL) { - ssh_set_error_oom(session); - return NULL; - } - - if (strlen(r) > MAX_BUF_SIZE) { - ssh_set_error(session, SSH_FATAL, "string to expand too long"); - free(r); - return NULL; - } - - p = r; - buf[0] = '\0'; - - for (i = 0; *p != '\0'; p++) { - if (*p != '%') { - buf[i] = *p; - i++; - if (i >= MAX_BUF_SIZE) { - free(r); - return NULL; - } - buf[i] = '\0'; - continue; - } - - p++; - if (*p == '\0') { - break; - } - - switch (*p) { - case 'd': - x = strdup(session->opts.sshdir); - break; - case 'u': - x = ssh_get_local_username(); - break; - case 'l': - if (gethostname(host, sizeof(host) == 0)) { - x = strdup(host); - } - break; - case 'h': - x = strdup(session->opts.host); - break; - case 'r': - x = strdup(session->opts.username); - break; - case 'p': - if (session->opts.port < 65536) { - char tmp[6]; - - snprintf(tmp, sizeof(tmp), "%u", session->opts.port); - x = strdup(tmp); - } - break; - default: - ssh_set_error(session, SSH_FATAL, - "Wrong escape sequence detected"); - free(r); - return NULL; - } - - if (x == NULL) { - ssh_set_error_oom(session); - free(r); - return NULL; - } - - i += strlen(x); - if (i >= MAX_BUF_SIZE) { - ssh_set_error(session, SSH_FATAL, - "String too long"); - free(x); - free(r); - return NULL; - } - l = strlen(buf); - strncpy(buf + l, x, sizeof(buf) - l - 1); - buf[i] = '\0'; - SAFE_FREE(x); - } - - free(r); - return strdup(buf); -#undef MAX_BUF_SIZE -} - -/** - * @internal - * - * @brief Analyze the SSH banner to find out if we have a SSHv1 or SSHv2 - * server. - * - * @param session The session to analyze the banner from. - * @param server 0 means we are a client, 1 a server. - * @param ssh1 The variable which is set if it is a SSHv1 server. - * @param ssh2 The variable which is set if it is a SSHv2 server. - * - * @return 0 on success, < 0 on error. - * - * @see ssh_get_banner() - */ -int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) { - const char *banner; - const char *openssh; - - if (server) { - banner = session->clientbanner; - } else { - banner = session->serverbanner; - } - - if (banner == NULL) { - ssh_set_error(session, SSH_FATAL, "Invalid banner"); - return -1; - } - - /* - * Typical banners e.g. are: - * - * SSH-1.5-openSSH_5.4 - * SSH-1.99-openSSH_3.0 - * - * SSH-2.0-something - * 012345678901234567890 - */ - if (strlen(banner) < 6 || - strncmp(banner, "SSH-", 4) != 0) { - ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner); - return -1; - } - - SSH_LOG(SSH_LOG_RARE, "Analyzing banner: %s", banner); - - switch(banner[4]) { - case '1': - *ssh1 = 1; - if (strlen(banner) > 6) { - if (banner[6] == '9') { - *ssh2 = 1; - } else { - *ssh2 = 0; - } - } - break; - case '2': - *ssh1 = 0; - *ssh2 = 1; - break; - default: - ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner); - return -1; - } - - openssh = strstr(banner, "OpenSSH"); - if (openssh != NULL) { - int major, minor; - - /* - * The banner is typical: - * OpenSSH_5.4 - * 012345678901234567890 - */ - if (strlen(openssh) > 9) { - major = strtol(openssh + 8, (char **) NULL, 10); - minor = strtol(openssh + 10, (char **) NULL, 10); - session->openssh = SSH_VERSION_INT(major, minor, 0); - SSH_LOG(SSH_LOG_RARE, - "We are talking to an OpenSSH client version: %d.%d (%x)", - major, minor, session->openssh); - } - } - - - return 0; -} - -/* try the Monotonic clock if possible for perfs reasons */ -#ifdef _POSIX_MONOTONIC_CLOCK -#define CLOCK CLOCK_MONOTONIC -#else -#define CLOCK CLOCK_REALTIME -#endif - -/** - * @internal - * @brief initializes a timestamp to the current time - * @param[out] ts pointer to an allocated ssh_timestamp structure - */ -void ssh_timestamp_init(struct ssh_timestamp *ts){ -#ifdef HAVE_CLOCK_GETTIME - struct timespec tp; - clock_gettime(CLOCK, &tp); - ts->useconds = tp.tv_nsec / 1000; -#else - struct timeval tp; - gettimeofday(&tp, NULL); - ts->useconds = tp.tv_usec; -#endif - ts->seconds = tp.tv_sec; -} - -#undef CLOCK - -/** - * @internal - * @brief gets the time difference between two timestamps in ms - * @param[in] old older value - * @param[in] new newer value - * @returns difference in milliseconds - */ - -static int ssh_timestamp_difference(struct ssh_timestamp *old, - struct ssh_timestamp *new){ - long seconds, usecs, msecs; - seconds = new->seconds - old->seconds; - usecs = new->useconds - old->useconds; - if (usecs < 0){ - seconds--; - usecs += 1000000; - } - msecs = seconds * 1000 + usecs/1000; - return msecs; -} - -/** - * @internal - * @brief turn seconds and microseconds pair (as provided by user-set options) - * into millisecond value - * @param[in] sec number of seconds - * @param[in] usec number of microseconds - * @returns milliseconds, or 10000 if user supplied values are equal to zero - */ -int ssh_make_milliseconds(long sec, long usec) { - int res = usec ? (usec / 1000) : 0; - res += (sec * 1000); - if (res == 0) { - res = 10 * 1000; /* use a reasonable default value in case - * SSH_OPTIONS_TIMEOUT is not set in options. */ - } - return res; -} - -/** - * @internal - * @brief Checks if a timeout is elapsed, in function of a previous - * timestamp and an assigned timeout - * @param[in] ts pointer to an existing timestamp - * @param[in] timeout timeout in milliseconds. Negative values mean infinite - * timeout - * @returns 1 if timeout is elapsed - * 0 otherwise - */ -int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout) { - struct ssh_timestamp now; - - switch(timeout) { - case -2: /* - * -2 means user-defined timeout as available in - * session->timeout, session->timeout_usec. - */ - fprintf(stderr, "ssh_timeout_elapsed called with -2. this needs to " - "be fixed. please set a breakpoint on %s:%d and " - "fix the caller\n", __FILE__, __LINE__); - case -1: /* -1 means infinite timeout */ - return 0; - case 0: /* 0 means no timeout */ - return 1; - default: - break; - } - - ssh_timestamp_init(&now); - - return (ssh_timestamp_difference(ts,&now) >= timeout); -} - -/** - * @brief updates a timeout value so it reflects the remaining time - * @param[in] ts pointer to an existing timestamp - * @param[in] timeout timeout in milliseconds. Negative values mean infinite - * timeout - * @returns remaining time in milliseconds, 0 if elapsed, -1 if never. - */ -int ssh_timeout_update(struct ssh_timestamp *ts, int timeout){ - struct ssh_timestamp now; - int ms, ret; - if (timeout <= 0) { - return timeout; - } - ssh_timestamp_init(&now); - ms = ssh_timestamp_difference(ts,&now); - if(ms < 0) - ms = 0; - ret = timeout - ms; - return ret >= 0 ? ret: 0; -} - - -int ssh_match_group(const char *group, const char *object) -{ - const char *a; - const char *z; - - z = group; - do { - a = strchr(z, ','); - if (a == NULL) { - if (strcmp(z, object) == 0) { - return 1; - } - return 0; - } else { - if (strncmp(z, object, a - z) == 0) { - return 1; - } - } - z = a + 1; - } while(1); - - /* not reached */ - return 0; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/options.c b/libssh/src/options.c deleted file mode 100644 index f7f24553..00000000 --- a/libssh/src/options.c +++ /dev/null @@ -1,1568 +0,0 @@ -/* - * options.c - handle pre-connection options - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 by Aris Adamantiadis - * Copyright (c) 2009-2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include -#include -#include -#ifndef _WIN32 -#include -#else -#include -#endif -#include -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/misc.h" -#include "libssh/options.h" -#ifdef WITH_SERVER -#include "libssh/server.h" -#include "libssh/bind.h" -#endif - -/** - * @addtogroup libssh_session - * @{ - */ - -/** - * @brief Duplicate the options of a session structure. - * - * If you make several sessions with the same options this is useful. You - * cannot use twice the same option structure in ssh_session_connect. - * - * @param src The session to use to copy the options. - * - * @param dest A pointer to store the allocated session with duplicated - * options. You have to free the memory. - * - * @returns 0 on sucess, -1 on error with errno set. - * - * @see ssh_session_connect() - */ -int ssh_options_copy(ssh_session src, ssh_session *dest) { - ssh_session new; - int i; - - if (src == NULL || dest == NULL) { - return -1; - } - - new = ssh_new(); - if (new == NULL) { - return -1; - } - - if (src->opts.username) { - new->opts.username = strdup(src->opts.username); - if (new->opts.username == NULL) { - ssh_free(new); - return -1; - } - } - - if (src->opts.host) { - new->opts.host = strdup(src->opts.host); - if (new->opts.host == NULL) { - ssh_free(new); - return -1; - } - } - - if (src->opts.identity) { - struct ssh_iterator *it; - - new->opts.identity = ssh_list_new(); - if (new->opts.identity == NULL) { - ssh_free(new); - return -1; - } - - it = ssh_list_get_iterator(src->opts.identity); - while (it) { - char *id; - int rc; - - id = strdup((char *) it->data); - if (id == NULL) { - ssh_free(new); - return -1; - } - - rc = ssh_list_append(new->opts.identity, id); - if (rc < 0) { - free(id); - ssh_free(new); - return -1; - } - it = it->next; - } - } - - if (src->opts.sshdir) { - new->opts.sshdir = strdup(src->opts.sshdir); - if (new->opts.sshdir == NULL) { - ssh_free(new); - return -1; - } - } - - if (src->opts.knownhosts) { - new->opts.knownhosts = strdup(src->opts.knownhosts); - if (new->opts.knownhosts == NULL) { - ssh_free(new); - return -1; - } - } - - for (i = 0; i < 10; i++) { - if (src->opts.wanted_methods[i]) { - new->opts.wanted_methods[i] = strdup(src->opts.wanted_methods[i]); - if (new->opts.wanted_methods[i] == NULL) { - ssh_free(new); - return -1; - } - } - } - - if (src->opts.ProxyCommand) { - new->opts.ProxyCommand = strdup(src->opts.ProxyCommand); - if (new->opts.ProxyCommand == NULL) { - ssh_free(new); - return -1; - } - } - new->opts.fd = src->opts.fd; - new->opts.port = src->opts.port; - new->opts.timeout = src->opts.timeout; - new->opts.timeout_usec = src->opts.timeout_usec; - new->opts.ssh2 = src->opts.ssh2; - new->opts.ssh1 = src->opts.ssh1; - new->opts.compressionlevel = src->opts.compressionlevel; - new->common.log_verbosity = src->common.log_verbosity; - new->common.callbacks = src->common.callbacks; - - *dest = new; - - return 0; -} - -int ssh_options_set_algo(ssh_session session, int algo, - const char *list) { - if (!verify_existing_algo(algo, list)) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Setting method: no algorithm for method \"%s\" (%s)\n", - ssh_kex_get_description(algo), list); - return -1; - } - - SAFE_FREE(session->opts.wanted_methods[algo]); - session->opts.wanted_methods[algo] = strdup(list); - if (session->opts.wanted_methods[algo] == NULL) { - ssh_set_error_oom(session); - return -1; - } - - return 0; -} - -/** - * @brief This function can set all possible ssh options. - * - * @param session An allocated SSH session structure. - * - * @param type The option type to set. This could be one of the - * following: - * - * - SSH_OPTIONS_HOST: - * The hostname or ip address to connect to (const char *). - * - * - SSH_OPTIONS_PORT: - * The port to connect to (unsigned int). - * - * - SSH_OPTIONS_PORT_STR: - * The port to connect to (const char *). - * - * - SSH_OPTIONS_FD: - * The file descriptor to use (socket_t).\n - * \n - * If you wish to open the socket yourself for a reason - * or another, set the file descriptor. Don't forget to - * set the hostname as the hostname is used as a key in - * the known_host mechanism. - * - * - SSH_OPTIONS_BINDADDR: - * The address to bind the client to (const char *). - * - * - SSH_OPTIONS_USER: - * The username for authentication (const char *).\n - * \n - * If the value is NULL, the username is set to the - * default username. - * - * - SSH_OPTIONS_SSH_DIR: - * Set the ssh directory (const char *,format string).\n - * \n - * If the value is NULL, the directory is set to the - * default ssh directory.\n - * \n - * The ssh directory is used for files like known_hosts - * and identity (private and public key). It may include - * "%s" which will be replaced by the user home - * directory. - * - * - SSH_OPTIONS_KNOWNHOSTS: - * Set the known hosts file name (const char *,format string).\n - * \n - * If the value is NULL, the directory is set to the - * default known hosts file, normally - * ~/.ssh/known_hosts.\n - * \n - * The known hosts file is used to certify remote hosts - * are genuine. It may include "%s" which will be - * replaced by the user home directory. - * - * - SSH_OPTIONS_IDENTITY: - * Set the identity file name (const char *,format string).\n - * \n - * By default identity, id_dsa and id_rsa are checked.\n - * \n - * The identity file used authenticate with public key. - * It may include "%s" which will be replaced by the - * user home directory. - * - * - SSH_OPTIONS_TIMEOUT: - * Set a timeout for the connection in seconds (long). - * - * - SSH_OPTIONS_TIMEOUT_USEC: - * Set a timeout for the connection in micro seconds - * (long). - * - * - SSH_OPTIONS_SSH1: - * Allow or deny the connection to SSH1 servers - * (int, 0 is false). - * - * - SSH_OPTIONS_SSH2: - * Allow or deny the connection to SSH2 servers - * (int, 0 is false). - * - * - SSH_OPTIONS_LOG_VERBOSITY: - * Set the session logging verbosity (int).\n - * \n - * The verbosity of the messages. Every log smaller or - * equal to verbosity will be shown. - * - SSH_LOG_NOLOG: No logging - * - SSH_LOG_RARE: Rare conditions or warnings - * - SSH_LOG_ENTRY: API-accessible entrypoints - * - SSH_LOG_PACKET: Packet id and size - * - SSH_LOG_FUNCTIONS: Function entering and leaving - * - * - SSH_OPTIONS_LOG_VERBOSITY_STR: - * Set the session logging verbosity (const char *).\n - * \n - * The verbosity of the messages. Every log smaller or - * equal to verbosity will be shown. - * - SSH_LOG_NOLOG: No logging - * - SSH_LOG_RARE: Rare conditions or warnings - * - SSH_LOG_ENTRY: API-accessible entrypoints - * - SSH_LOG_PACKET: Packet id and size - * - SSH_LOG_FUNCTIONS: Function entering and leaving - * \n - * See the corresponding numbers in libssh.h. - * - * - SSH_OPTIONS_AUTH_CALLBACK: - * Set a callback to use your own authentication function - * (function pointer). - * - * - SSH_OPTIONS_AUTH_USERDATA: - * Set the user data passed to the authentication - * function (generic pointer). - * - * - SSH_OPTIONS_LOG_CALLBACK: - * Set a callback to use your own logging function - * (function pointer). - * - * - SSH_OPTIONS_LOG_USERDATA: - * Set the user data passed to the logging function - * (generic pointer). - * - * - SSH_OPTIONS_STATUS_CALLBACK: - * Set a callback to show connection status in realtime - * (function pointer).\n - * \n - * @code - * fn(void *arg, float status) - * @endcode - * \n - * During ssh_connect(), libssh will call the callback - * with status from 0.0 to 1.0. - * - * - SSH_OPTIONS_STATUS_ARG: - * Set the status argument which should be passed to the - * status callback (generic pointer). - * - * - SSH_OPTIONS_CIPHERS_C_S: - * Set the symmetric cipher client to server (const char *, - * comma-separated list). - * - * - SSH_OPTIONS_CIPHERS_S_C: - * Set the symmetric cipher server to client (const char *, - * comma-separated list). - * - * - SSH_OPTIONS_KEY_EXCHANGE: - * Set the key exchange method to be used (const char *, - * comma-separated list). ex: - * "ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" - * - * - SSH_OPTIONS_HOSTKEYS: - * Set the preferred server host key types (const char *, - * comma-separated list). ex: - * "ssh-rsa,ssh-dsa,ecdh-sha2-nistp256" - * - * - SSH_OPTIONS_COMPRESSION_C_S: - * Set the compression to use for client to server - * communication (const char *, "yes", "no" or a specific - * algorithm name if needed ("zlib","zlib@openssh.com","none"). - * - * - SSH_OPTIONS_COMPRESSION_S_C: - * Set the compression to use for server to client - * communication (const char *, "yes", "no" or a specific - * algorithm name if needed ("zlib","zlib@openssh.com","none"). - * - * - SSH_OPTIONS_COMPRESSION: - * Set the compression to use for both directions - * communication (const char *, "yes", "no" or a specific - * algorithm name if needed ("zlib","zlib@openssh.com","none"). - * - * - SSH_OPTIONS_COMPRESSION_LEVEL: - * Set the compression level to use for zlib functions. (int, - * value from 1 to 9, 9 being the most efficient but slower). - * - * - SSH_OPTIONS_STRICTHOSTKEYCHECK: - * Set the parameter StrictHostKeyChecking to avoid - * asking about a fingerprint (int, 0 = false). - * - * - SSH_OPTIONS_PROXYCOMMAND: - * Set the command to be executed in order to connect to - * server (const char *). - * - * - SSH_OPTIONS_GSSAPI_SERVER_IDENTITY - * Set it to specify the GSSAPI server identity that libssh - * should expect when connecting to the server (const char *). - * - * - SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY - * Set it to specify the GSSAPI client identity that libssh - * should expect when connecting to the server (const char *). - * - * - SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS - * Set it to specify that GSSAPI should delegate credentials - * to the server (int, 0 = false). - * - * @param value The value to set. This is a generic pointer and the - * datatype which is used should be set according to the - * type set. - * - * @return 0 on success, < 0 on error. - */ -int ssh_options_set(ssh_session session, enum ssh_options_e type, - const void *value) { - const char *v; - char *p, *q; - long int i; - int rc; - - if (session == NULL) { - return -1; - } - - switch (type) { - case SSH_OPTIONS_HOST: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - q = strdup(value); - if (q == NULL) { - ssh_set_error_oom(session); - return -1; - } - p = strchr(q, '@'); - - SAFE_FREE(session->opts.host); - - if (p) { - *p = '\0'; - session->opts.host = strdup(p + 1); - if (session->opts.host == NULL) { - SAFE_FREE(q); - ssh_set_error_oom(session); - return -1; - } - - SAFE_FREE(session->opts.username); - session->opts.username = strdup(q); - SAFE_FREE(q); - if (session->opts.username == NULL) { - ssh_set_error_oom(session); - return -1; - } - } else { - session->opts.host = q; - } - } - break; - case SSH_OPTIONS_PORT: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int *x = (int *) value; - if (*x <= 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->opts.port = *x & 0xffff; - } - break; - case SSH_OPTIONS_PORT_STR: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - q = strdup(v); - if (q == NULL) { - ssh_set_error_oom(session); - return -1; - } - i = strtol(q, &p, 10); - if (q == p) { - SAFE_FREE(q); - } - SAFE_FREE(q); - if (i <= 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->opts.port = i & 0xffff; - } - break; - case SSH_OPTIONS_FD: - if (value == NULL) { - session->opts.fd = SSH_INVALID_SOCKET; - ssh_set_error_invalid(session); - return -1; - } else { - socket_t *x = (socket_t *) value; - if (*x < 0) { - session->opts.fd = SSH_INVALID_SOCKET; - ssh_set_error_invalid(session); - return -1; - } - - session->opts.fd = *x & 0xffff; - } - break; - case SSH_OPTIONS_BINDADDR: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } - - q = strdup(v); - if (q == NULL) { - return -1; - } - SAFE_FREE(session->opts.bindaddr); - session->opts.bindaddr = q; - break; - case SSH_OPTIONS_USER: - v = value; - SAFE_FREE(session->opts.username); - if (v == NULL) { - q = ssh_get_local_username(); - if (q == NULL) { - ssh_set_error_oom(session); - return -1; - } - session->opts.username = q; - } else if (v[0] == '\0') { - ssh_set_error_oom(session); - return -1; - } else { /* username provided */ - session->opts.username = strdup(value); - if (session->opts.username == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - break; - case SSH_OPTIONS_SSH_DIR: - v = value; - SAFE_FREE(session->opts.sshdir); - if (v == NULL) { - session->opts.sshdir = ssh_path_expand_tilde("~/.ssh"); - if (session->opts.sshdir == NULL) { - return -1; - } - } else if (v[0] == '\0') { - ssh_set_error_oom(session); - return -1; - } else { - session->opts.sshdir = ssh_path_expand_tilde(v); - if (session->opts.sshdir == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - break; - case SSH_OPTIONS_IDENTITY: - case SSH_OPTIONS_ADD_IDENTITY: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } - q = strdup(v); - if (q == NULL) { - return -1; - } - rc = ssh_list_prepend(session->opts.identity, q); - if (rc < 0) { - free(q); - return -1; - } - break; - case SSH_OPTIONS_KNOWNHOSTS: - v = value; - SAFE_FREE(session->opts.knownhosts); - if (v == NULL) { - session->opts.knownhosts = ssh_path_expand_escape(session, - "%d/known_hosts"); - if (session->opts.knownhosts == NULL) { - ssh_set_error_oom(session); - return -1; - } - } else if (v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - session->opts.knownhosts = strdup(v); - if (session->opts.knownhosts == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - break; - case SSH_OPTIONS_TIMEOUT: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - long *x = (long *) value; - if (*x < 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->opts.timeout = *x & 0xffffffff; - } - break; - case SSH_OPTIONS_TIMEOUT_USEC: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - long *x = (long *) value; - if (*x < 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->opts.timeout_usec = *x & 0xffffffff; - } - break; - case SSH_OPTIONS_SSH1: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int *x = (int *) value; - if (*x < 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->opts.ssh1 = *x; - } - break; - case SSH_OPTIONS_SSH2: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int *x = (int *) value; - if (*x < 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->opts.ssh2 = *x & 0xffff; - } - break; - case SSH_OPTIONS_LOG_VERBOSITY: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int *x = (int *) value; - if (*x < 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->common.log_verbosity = *x & 0xffff; - ssh_set_log_level(*x & 0xffff); - } - break; - case SSH_OPTIONS_LOG_VERBOSITY_STR: - v = value; - if (v == NULL || v[0] == '\0') { - session->common.log_verbosity = 0; - ssh_set_error_invalid(session); - return -1; - } else { - q = strdup(v); - if (q == NULL) { - ssh_set_error_oom(session); - return -1; - } - i = strtol(q, &p, 10); - if (q == p) { - SAFE_FREE(q); - } - SAFE_FREE(q); - if (i < 0) { - ssh_set_error_invalid(session); - return -1; - } - - session->common.log_verbosity = i & 0xffff; - ssh_set_log_level(i & 0xffff); - } - break; - case SSH_OPTIONS_CIPHERS_C_S: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (ssh_options_set_algo(session, SSH_CRYPT_C_S, v) < 0) - return -1; - } - break; - case SSH_OPTIONS_CIPHERS_S_C: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (ssh_options_set_algo(session, SSH_CRYPT_S_C, v) < 0) - return -1; - } - break; - case SSH_OPTIONS_KEY_EXCHANGE: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (ssh_options_set_algo(session, SSH_KEX, v) < 0) - return -1; - } - break; - case SSH_OPTIONS_HOSTKEYS: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (ssh_options_set_algo(session, SSH_HOSTKEYS, v) < 0) - return -1; - } - break; - case SSH_OPTIONS_HMAC_C_S: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (ssh_options_set_algo(session, SSH_MAC_C_S, v) < 0) - return -1; - } - break; - case SSH_OPTIONS_HMAC_S_C: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (ssh_options_set_algo(session, SSH_MAC_S_C, v) < 0) - return -1; - } - break; - case SSH_OPTIONS_COMPRESSION_C_S: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (strcasecmp(value,"yes")==0){ - if(ssh_options_set_algo(session,SSH_COMP_C_S,"zlib@openssh.com,zlib") < 0) - return -1; - } else if (strcasecmp(value,"no")==0){ - if(ssh_options_set_algo(session,SSH_COMP_C_S,"none") < 0) - return -1; - } else { - if (ssh_options_set_algo(session, SSH_COMP_C_S, v) < 0) - return -1; - } - } - break; - case SSH_OPTIONS_COMPRESSION_S_C: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - if (strcasecmp(value,"yes")==0){ - if(ssh_options_set_algo(session,SSH_COMP_S_C,"zlib@openssh.com,zlib") < 0) - return -1; - } else if (strcasecmp(value,"no")==0){ - if(ssh_options_set_algo(session,SSH_COMP_S_C,"none") < 0) - return -1; - } else { - if (ssh_options_set_algo(session, SSH_COMP_S_C, v) < 0) - return -1; - } - } - break; - case SSH_OPTIONS_COMPRESSION: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } - if(ssh_options_set(session,SSH_OPTIONS_COMPRESSION_C_S, v) < 0) - return -1; - if(ssh_options_set(session,SSH_OPTIONS_COMPRESSION_S_C, v) < 0) - return -1; - break; - case SSH_OPTIONS_COMPRESSION_LEVEL: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int *x = (int *)value; - if (*x < 1 || *x > 9) { - ssh_set_error_invalid(session); - return -1; - } - session->opts.compressionlevel = *x & 0xff; - } - break; - case SSH_OPTIONS_STRICTHOSTKEYCHECK: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int *x = (int *) value; - - session->opts.StrictHostKeyChecking = (*x & 0xff) > 0 ? 1 : 0; - } - session->opts.StrictHostKeyChecking = *(int*)value; - break; - case SSH_OPTIONS_PROXYCOMMAND: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - SAFE_FREE(session->opts.ProxyCommand); - /* Setting the command to 'none' disables this option. */ - rc = strcasecmp(v, "none"); - if (rc != 0) { - q = strdup(v); - if (q == NULL) { - return -1; - } - session->opts.ProxyCommand = q; - } - } - break; - case SSH_OPTIONS_GSSAPI_SERVER_IDENTITY: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - SAFE_FREE(session->opts.gss_server_identity); - session->opts.gss_server_identity = strdup(v); - if (session->opts.gss_server_identity == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - break; - case SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY: - v = value; - if (v == NULL || v[0] == '\0') { - ssh_set_error_invalid(session); - return -1; - } else { - SAFE_FREE(session->opts.gss_client_identity); - session->opts.gss_client_identity = strdup(v); - if (session->opts.gss_client_identity == NULL) { - ssh_set_error_oom(session); - return -1; - } - } - break; - case SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS: - if (value == NULL) { - ssh_set_error_invalid(session); - return -1; - } else { - int x = *(int *)value; - - session->opts.gss_delegate_creds = (x & 0xff); - } - break; - - default: - ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type); - return -1; - break; - } - - return 0; -} - -/** - * @brief This function can get ssh the ssh port. It must only be used on - * a valid ssh session. This function is useful when the session - * options have been automatically inferred from the environment - * or configuration files and one - * - * @param session An allocated SSH session structure. - * - * @param port_target An unsigned integer into which the - * port will be set from the ssh session. - * - * @return 0 on success, < 0 on error. - * - */ -int ssh_options_get_port(ssh_session session, unsigned int* port_target) { - if (session == NULL) { - return -1; - } - if (!session->opts.port) { - ssh_set_error_invalid(session); - return -1; - } - *port_target = session->opts.port; - return 0; -} - -/** - * @brief This function can get ssh options, it does not support all options provided for - * ssh options set, but mostly those which a user-space program may care about having - * trusted the ssh driver to infer these values from underlaying configuration files. - * It operates only on those SSH_OPTIONS_* which return char*. If you wish to receive - * the port then please use ssh_options_get_port() which returns an unsigned int. - * - * @param session An allocated SSH session structure. - * - * @param type The option type to get. This could be one of the - * following: - * - * - SSH_OPTIONS_HOST: - * The hostname or ip address to connect to (const char *). - * - * - SSH_OPTIONS_USER: - * The username for authentication (const char *).\n - * \n when not explicitly set this will be inferred from the - * ~/.ssh/config file. - * - * - SSH_OPTIONS_IDENTITY: - * Set the identity file name (const char *,format string).\n - * \n - * By default identity, id_dsa and id_rsa are checked.\n - * \n - * The identity file used authenticate with public key. - * It may include "%s" which will be replaced by the - * user home directory. - * - * - SSH_OPTIONS_PROXYCOMMAND: - * Get the proxycommand necessary to log into the - * remote host. When not explicitly set, it will be read - * from the ~/.ssh/config file. - * - * @param value The value to get into. As a char**, space will be - * allocated by the function for the value, it is - * your responsibility to free the memory using - * ssh_string_free_char(). - * - * @return SSH_OK on success, SSH_ERROR on error. - */ -int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value) -{ - char* src = NULL; - - if (session == NULL) { - return SSH_ERROR; - } - - if (value == NULL) { - ssh_set_error_invalid(session); - return SSH_ERROR; - } - - switch(type) - { - case SSH_OPTIONS_HOST: { - src = session->opts.host; - break; - } - case SSH_OPTIONS_USER: { - src = session->opts.username; - break; - } - case SSH_OPTIONS_IDENTITY: { - struct ssh_iterator *it = ssh_list_get_iterator(session->opts.identity); - if (it == NULL) { - return SSH_ERROR; - } - src = ssh_iterator_value(char *, it); - break; - } - case SSH_OPTIONS_PROXYCOMMAND: { - src = session->opts.ProxyCommand; - break; - } - default: - ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type); - return SSH_ERROR; - break; - } - if (src == NULL) { - return SSH_ERROR; - } - *value = strdup(src); - if (*value == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - return SSH_OK; -} - -/** - * @brief Parse command line arguments. - * - * This is a helper for your application to generate the appropriate - * options from the command line arguments.\n - * The argv array and argc value are changed so that the parsed - * arguments wont appear anymore in them.\n - * The single arguments (without switches) are not parsed. thus, - * myssh -l user localhost\n - * The command wont set the hostname value of options to localhost. - * - * @param session The session to configure. - * - * @param argcptr The pointer to the argument count. - * - * @param argv The arguments list pointer. - * - * @returns 0 on success, < 0 on error. - * - * @see ssh_session_new() - */ -int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) { - char *user = NULL; - char *cipher = NULL; - char *identity = NULL; - char *port = NULL; - char **save = NULL; - char **tmp = NULL; - int i = 0; - int argc = *argcptr; - int debuglevel = 0; - int usersa = 0; - int usedss = 0; - int compress = 0; - int cont = 1; - int current = 0; -#ifdef WITH_SSH1 - int ssh1 = 1; -#else - int ssh1 = 0; -#endif - int ssh2 = 1; -#ifdef _MSC_VER - /* Not supported with a Microsoft compiler */ - return -1; -#else - int saveoptind = optind; /* need to save 'em */ - int saveopterr = opterr; - - opterr = 0; /* shut up getopt */ - while(cont && ((i = getopt(argc, argv, "c:i:Cl:p:vb:rd12")) != -1)) { - switch(i) { - case 'l': - user = optarg; - break; - case 'p': - port = optarg; - break; - case 'v': - debuglevel++; - break; - case 'r': - usersa++; - break; - case 'd': - usedss++; - break; - case 'c': - cipher = optarg; - break; - case 'i': - identity = optarg; - break; - case 'C': - compress++; - break; - case '2': - ssh2 = 1; - ssh1 = 0; - break; - case '1': - ssh2 = 0; - ssh1 = 1; - break; - default: - { - char opt[3]="- "; - opt[1] = optopt; - tmp = realloc(save, (current + 1) * sizeof(char*)); - if (tmp == NULL) { - SAFE_FREE(save); - ssh_set_error_oom(session); - return -1; - } - save = tmp; - save[current] = strdup(opt); - if (save[current] == NULL) { - SAFE_FREE(save); - ssh_set_error_oom(session); - return -1; - } - current++; - if (optarg) { - save[current++] = argv[optind + 1]; - } - } - } /* switch */ - } /* while */ - opterr = saveopterr; - tmp = realloc(save, (current + (argc - optind)) * sizeof(char*)); - if (tmp == NULL) { - SAFE_FREE(save); - ssh_set_error_oom(session); - return -1; - } - save = tmp; - while (optind < argc) { - tmp = realloc(save, (current + 1) * sizeof(char*)); - if (tmp == NULL) { - SAFE_FREE(save); - ssh_set_error_oom(session); - return -1; - } - save = tmp; - save[current] = argv[optind]; - current++; - optind++; - } - - if (usersa && usedss) { - ssh_set_error(session, SSH_FATAL, "Either RSA or DSS must be chosen"); - cont = 0; - } - - ssh_set_log_level(debuglevel); - - optind = saveoptind; - - if(!cont) { - SAFE_FREE(save); - return -1; - } - - /* first recopy the save vector into the original's */ - for (i = 0; i < current; i++) { - /* don't erase argv[0] */ - argv[ i + 1] = save[i]; - } - argv[current + 1] = NULL; - *argcptr = current + 1; - SAFE_FREE(save); - - /* set a new option struct */ - if (compress) { - if (ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "yes") < 0) { - cont = 0; - } - } - - if (cont && cipher) { - if (ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, cipher) < 0) { - cont = 0; - } - if (cont && ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, cipher) < 0) { - cont = 0; - } - } - - if (cont && user) { - if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) { - cont = 0; - } - } - - if (cont && identity) { - if (ssh_options_set(session, SSH_OPTIONS_IDENTITY, identity) < 0) { - cont = 0; - } - } - - ssh_options_set(session, SSH_OPTIONS_PORT_STR, port); - - ssh_options_set(session, SSH_OPTIONS_SSH1, &ssh1); - ssh_options_set(session, SSH_OPTIONS_SSH2, &ssh2); - - if (!cont) { - return SSH_ERROR; - } - - return SSH_OK; -#endif -} - -/** - * @brief Parse the ssh config file. - * - * This should be the last call of all options, it may overwrite options which - * are already set. It requires that the host name is already set with - * ssh_options_set_host(). - * - * @param session SSH session handle - * - * @param filename The options file to use, if NULL the default - * ~/.ssh/config will be used. - * - * @return 0 on success, < 0 on error. - * - * @see ssh_options_set_host() - */ -int ssh_options_parse_config(ssh_session session, const char *filename) { - char *expanded_filename; - int r; - - if (session == NULL) { - return -1; - } - if (session->opts.host == NULL) { - ssh_set_error_invalid(session); - return -1; - } - - if (session->opts.sshdir == NULL) { - r = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL); - if (r < 0) { - ssh_set_error_oom(session); - return -1; - } - } - - /* set default filename */ - if (filename == NULL) { - expanded_filename = ssh_path_expand_escape(session, "%d/config"); - } else { - expanded_filename = ssh_path_expand_escape(session, filename); - } - if (expanded_filename == NULL) { - return -1; - } - - r = ssh_config_parse_file(session, expanded_filename); - if (r < 0) { - goto out; - } - if (filename == NULL) { - r = ssh_config_parse_file(session, "/etc/ssh/ssh_config"); - } - -out: - free(expanded_filename); - return r; -} - -int ssh_options_apply(ssh_session session) { - struct ssh_iterator *it; - char *tmp; - int rc; - - if (session->opts.sshdir == NULL) { - rc = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL); - if (rc < 0) { - return -1; - } - } - - if (session->opts.username == NULL) { - rc = ssh_options_set(session, SSH_OPTIONS_USER, NULL); - if (rc < 0) { - return -1; - } - } - - if (session->opts.knownhosts == NULL) { - tmp = ssh_path_expand_escape(session, "%d/known_hosts"); - } else { - tmp = ssh_path_expand_escape(session, session->opts.knownhosts); - } - if (tmp == NULL) { - return -1; - } - free(session->opts.knownhosts); - session->opts.knownhosts = tmp; - - if (session->opts.ProxyCommand != NULL) { - tmp = ssh_path_expand_escape(session, session->opts.ProxyCommand); - if (tmp == NULL) { - return -1; - } - free(session->opts.ProxyCommand); - session->opts.ProxyCommand = tmp; - } - - for (it = ssh_list_get_iterator(session->opts.identity); - it != NULL; - it = it->next) { - char *id = (char *) it->data; - tmp = ssh_path_expand_escape(session, id); - if (tmp == NULL) { - return -1; - } - free(id); - it->data = tmp; - } - - return 0; -} - -/** @} */ - -#ifdef WITH_SERVER -/** - * @addtogroup libssh_server - * @{ - */ -static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc, - const void *value) { - if (value == NULL) { - ssh_set_error_invalid(sshbind); - return -1; - } else { - SAFE_FREE(*key_loc); - *key_loc = strdup(value); - if (*key_loc == NULL) { - ssh_set_error_oom(sshbind); - return -1; - } - } - return 0; -} - -/** - * @brief Set options for an SSH server bind. - * - * @param sshbind The ssh server bind to configure. - * - * @param type The option type to set. This should be one of the - * following: - * - * - SSH_BIND_OPTIONS_HOSTKEY: - * Set the path to an ssh host key, regardless - * of type. Only one key from per key type - * (RSA, DSA, ECDSA) is allowed in an ssh_bind - * at a time, and later calls to this function - * with this option for the same key type will - * override prior calls (const char *). - * - * - SSH_BIND_OPTIONS_BINDADDR: - * Set the IP address to bind (const char *). - * - * - SSH_BIND_OPTIONS_BINDPORT: - * Set the port to bind (unsigned int *). - * - * - SSH_BIND_OPTIONS_BINDPORT_STR: - * Set the port to bind (const char *). - * - * - SSH_BIND_OPTIONS_LOG_VERBOSITY: - * Set the session logging verbosity (int *). - * The logging verbosity should have one of the - * following values, which are listed in order - * of increasing verbosity. Every log message - * with verbosity less than or equal to the - * logging verbosity will be shown. - * - SSH_LOG_NOLOG: No logging - * - SSH_LOG_RARE: Rare conditions or warnings - * - SSH_LOG_ENTRY: API-accessible entrypoints - * - SSH_LOG_PACKET: Packet id and size - * - SSH_LOG_FUNCTIONS: Function entering and leaving - * - * - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR: - * Set the session logging verbosity via a - * string that will be converted to a numerical - * value (e.g. "3") and interpreted according - * to the values of - * SSH_BIND_OPTIONS_LOG_VERBOSITY above (const - * char *). - * - * - SSH_BIND_OPTIONS_DSAKEY: - * Set the path to the ssh host dsa key, SSHv2 - * only (const char *). - * - * - SSH_BIND_OPTIONS_RSAKEY: - * Set the path to the ssh host rsa key, SSHv2 - * only (const char *). - * - * - SSH_BIND_OPTIONS_ECDSAKEY: - * Set the path to the ssh host ecdsa key, - * SSHv2 only (const char *). - * - * - SSH_BIND_OPTIONS_BANNER: - * Set the server banner sent to clients (const char *). - * - * @param value The value to set. This is a generic pointer and the - * datatype which should be used is described at the - * corresponding value of type above. - * - * @return 0 on success, < 0 on error, invalid option, or parameter. - */ -int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, - const void *value) { - char *p, *q; - int i, rc; - - if (sshbind == NULL) { - return -1; - } - - switch (type) { - case SSH_BIND_OPTIONS_HOSTKEY: - if (value == NULL) { - ssh_set_error_invalid(sshbind); - return -1; - } else { - int key_type; - ssh_key key; - ssh_key *bind_key_loc = NULL; - char **bind_key_path_loc; - - rc = ssh_pki_import_privkey_file(value, NULL, NULL, NULL, &key); - if (rc != SSH_OK) { - return -1; - } - key_type = ssh_key_type(key); - switch (key_type) { - case SSH_KEYTYPE_DSS: - bind_key_loc = &sshbind->dsa; - bind_key_path_loc = &sshbind->dsakey; - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_ECC - bind_key_loc = &sshbind->ecdsa; - bind_key_path_loc = &sshbind->ecdsakey; -#else - ssh_set_error(sshbind, - SSH_FATAL, - "ECDSA key used and libssh compiled " - "without ECDSA support"); -#endif - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - bind_key_loc = &sshbind->rsa; - bind_key_path_loc = &sshbind->rsakey; - break; - default: - ssh_set_error(sshbind, - SSH_FATAL, - "Unsupported key type %d", key_type); - } - - if (bind_key_loc == NULL) { - ssh_key_free(key); - return -1; - } - - /* Set the location of the key on disk even though we don't - need it in case some other function wants it */ - rc = ssh_bind_set_key(sshbind, bind_key_path_loc, value); - if (rc < 0) { - ssh_key_free(key); - return -1; - } - ssh_key_free(*bind_key_loc); - *bind_key_loc = key; - } - break; - case SSH_BIND_OPTIONS_BINDADDR: - if (value == NULL) { - ssh_set_error_invalid(sshbind); - return -1; - } else { - SAFE_FREE(sshbind->bindaddr); - sshbind->bindaddr = strdup(value); - if (sshbind->bindaddr == NULL) { - ssh_set_error_oom(sshbind); - return -1; - } - } - break; - case SSH_BIND_OPTIONS_BINDPORT: - if (value == NULL) { - ssh_set_error_invalid(sshbind); - return -1; - } else { - int *x = (int *) value; - sshbind->bindport = *x & 0xffff; - } - break; - case SSH_BIND_OPTIONS_BINDPORT_STR: - if (value == NULL) { - sshbind->bindport = 22 & 0xffff; - } else { - q = strdup(value); - if (q == NULL) { - ssh_set_error_oom(sshbind); - return -1; - } - i = strtol(q, &p, 10); - if (q == p) { - SAFE_FREE(q); - } - SAFE_FREE(q); - - sshbind->bindport = i & 0xffff; - } - break; - case SSH_BIND_OPTIONS_LOG_VERBOSITY: - if (value == NULL) { - ssh_set_error_invalid(sshbind); - return -1; - } else { - int *x = (int *) value; - ssh_set_log_level(*x & 0xffff); - } - break; - case SSH_BIND_OPTIONS_LOG_VERBOSITY_STR: - if (value == NULL) { - ssh_set_log_level(0); - } else { - q = strdup(value); - if (q == NULL) { - ssh_set_error_oom(sshbind); - return -1; - } - i = strtol(q, &p, 10); - if (q == p) { - SAFE_FREE(q); - } - SAFE_FREE(q); - - ssh_set_log_level(i & 0xffff); - } - break; - case SSH_BIND_OPTIONS_DSAKEY: - rc = ssh_bind_set_key(sshbind, &sshbind->dsakey, value); - if (rc < 0) { - return -1; - } - break; - case SSH_BIND_OPTIONS_RSAKEY: - rc = ssh_bind_set_key(sshbind, &sshbind->rsakey, value); - if (rc < 0) { - return -1; - } - break; - case SSH_BIND_OPTIONS_ECDSAKEY: - rc = ssh_bind_set_key(sshbind, &sshbind->ecdsakey, value); - if (rc < 0) { - return -1; - } - break; - case SSH_BIND_OPTIONS_BANNER: - if (value == NULL) { - ssh_set_error_invalid(sshbind); - return -1; - } else { - SAFE_FREE(sshbind->banner); - sshbind->banner = strdup(value); - if (sshbind->banner == NULL) { - ssh_set_error_oom(sshbind); - return -1; - } - } - break; - default: - ssh_set_error(sshbind, SSH_REQUEST_DENIED, "Unknown ssh option %d", type); - return -1; - break; - } - - return 0; -} -#endif - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/packet.c b/libssh/src/packet.c deleted file mode 100644 index d16cd165..00000000 --- a/libssh/src/packet.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * packet.c - packet building functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/ssh2.h" -#include "libssh/crypto.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/socket.h" -#include "libssh/channels.h" -#include "libssh/misc.h" -#include "libssh/session.h" -#include "libssh/messages.h" -#include "libssh/pcap.h" -#include "libssh/kex.h" -#include "libssh/auth.h" -#include "libssh/gssapi.h" - -static ssh_packet_callback default_packet_handlers[]= { - ssh_packet_disconnect_callback, // SSH2_MSG_DISCONNECT 1 - ssh_packet_ignore_callback, // SSH2_MSG_IGNORE 2 - ssh_packet_unimplemented, // SSH2_MSG_UNIMPLEMENTED 3 - ssh_packet_ignore_callback, // SSH2_MSG_DEBUG 4 -#if WITH_SERVER - ssh_packet_service_request, // SSH2_MSG_SERVICE_REQUEST 5 -#else - NULL, -#endif - ssh_packet_service_accept, // SSH2_MSG_SERVICE_ACCEPT 6 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, // 7-19 - ssh_packet_kexinit, // SSH2_MSG_KEXINIT 20 - ssh_packet_newkeys, // SSH2_MSG_NEWKEYS 21 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, // 22-29 -#if WITH_SERVER - ssh_packet_kexdh_init, // SSH2_MSG_KEXDH_INIT 30 - // SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30 -#else - NULL, -#endif - ssh_packet_dh_reply, // SSH2_MSG_KEXDH_REPLY 31 - // SSH2_MSG_KEX_DH_GEX_GROUP 31 - NULL, // SSH2_MSG_KEX_DH_GEX_INIT 32 - NULL, // SSH2_MSG_KEX_DH_GEX_REPLY 33 - NULL, // SSH2_MSG_KEX_DH_GEX_REQUEST 34 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, // 35-49 -#if WITH_SERVER - ssh_packet_userauth_request, // SSH2_MSG_USERAUTH_REQUEST 50 -#else - NULL, -#endif - ssh_packet_userauth_failure, // SSH2_MSG_USERAUTH_FAILURE 51 - ssh_packet_userauth_success, // SSH2_MSG_USERAUTH_SUCCESS 52 - ssh_packet_userauth_banner, // SSH2_MSG_USERAUTH_BANNER 53 - NULL,NULL,NULL,NULL,NULL,NULL, // 54-59 - ssh_packet_userauth_pk_ok, // SSH2_MSG_USERAUTH_PK_OK 60 - // SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 - // SSH2_MSG_USERAUTH_INFO_REQUEST 60 - // SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 - ssh_packet_userauth_info_response, // SSH2_MSG_USERAUTH_INFO_RESPONSE 61 - // SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 - NULL, // 62 - NULL, // SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 - NULL, // SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 - NULL, // SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 -#if defined(WITH_GSSAPI) && defined(WITH_SERVER) - ssh_packet_userauth_gssapi_mic, // SSH2_MSG_USERAUTH_GSSAPI_MIC 66 -#else /* WITH_GSSAPI && WITH_SERVER */ - NULL, -#endif /* WITH_GSSAPI && WITH_SERVER */ - NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, // 67-79 -#ifdef WITH_SERVER - ssh_packet_global_request, // SSH2_MSG_GLOBAL_REQUEST 80 -#else /* WITH_SERVER */ - NULL, -#endif /* WITH_SERVER */ - ssh_request_success, // SSH2_MSG_REQUEST_SUCCESS 81 - ssh_request_denied, // SSH2_MSG_REQUEST_FAILURE 82 - NULL, NULL, NULL, NULL, NULL, NULL, NULL,// 83-89 - ssh_packet_channel_open, // SSH2_MSG_CHANNEL_OPEN 90 - ssh_packet_channel_open_conf, // SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 - ssh_packet_channel_open_fail, // SSH2_MSG_CHANNEL_OPEN_FAILURE 92 - channel_rcv_change_window, // SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 - channel_rcv_data, // SSH2_MSG_CHANNEL_DATA 94 - channel_rcv_data, // SSH2_MSG_CHANNEL_EXTENDED_DATA 95 - channel_rcv_eof, // SSH2_MSG_CHANNEL_EOF 96 - channel_rcv_close, // SSH2_MSG_CHANNEL_CLOSE 97 - channel_rcv_request, // SSH2_MSG_CHANNEL_REQUEST 98 - ssh_packet_channel_success, // SSH2_MSG_CHANNEL_SUCCESS 99 - ssh_packet_channel_failure, // SSH2_MSG_CHANNEL_FAILURE 100 -}; - -/* in nonblocking mode, socket_read will read as much as it can, and return */ -/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */ -/* in blocking mode, it will read at least len bytes and will block until it's ok. */ - -/** @internal - * @handles a data received event. It then calls the handlers for the different packet types - * or and exception handler callback. - * @param user pointer to current ssh_session - * @param data pointer to the data received - * @len length of data received. It might not be enough for a complete packet - * @returns number of bytes read and processed. - */ -int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) -{ - ssh_session session= (ssh_session) user; - unsigned int blocksize = (session->current_crypto ? - session->current_crypto->in_cipher->blocksize : 8); - unsigned char mac[DIGEST_MAX_LEN] = {0}; - char buffer[16] = {0}; - size_t current_macsize = 0; - const uint8_t *packet; - int to_be_read; - int rc; - uint32_t len, compsize, payloadsize; - uint8_t padding; - size_t processed = 0; /* number of byte processed from the callback */ - - if(session->current_crypto != NULL) { - current_macsize = hmac_digest_len(session->current_crypto->in_hmac); - } - - if (data == NULL) { - goto error; - } - - if (session->session_state == SSH_SESSION_STATE_ERROR) { - goto error; - } - - switch(session->packet_state) { - case PACKET_STATE_INIT: - if (receivedlen < blocksize) { - /* - * We didn't receive enough data to read at least one - * block size, give up - */ - return 0; - } - - memset(&session->in_packet, 0, sizeof(PACKET)); - - if (session->in_buffer) { - rc = ssh_buffer_reinit(session->in_buffer); - if (rc < 0) { - goto error; - } - } else { - session->in_buffer = ssh_buffer_new(); - if (session->in_buffer == NULL) { - goto error; - } - } - - memcpy(buffer, data, blocksize); - processed += blocksize; - len = packet_decrypt_len(session, buffer); - - rc = ssh_buffer_add_data(session->in_buffer, buffer, blocksize); - if (rc < 0) { - goto error; - } - - if (len > MAX_PACKET_LEN) { - ssh_set_error(session, - SSH_FATAL, - "read_packet(): Packet len too high(%u %.4x)", - len, len); - goto error; - } - - to_be_read = len - blocksize + sizeof(uint32_t); - if (to_be_read < 0) { - /* remote sshd sends invalid sizes? */ - ssh_set_error(session, - SSH_FATAL, - "Given numbers of bytes left to be read < 0 (%d)!", - to_be_read); - goto error; - } - - /* Saves the status of the current operations */ - session->in_packet.len = len; - session->packet_state = PACKET_STATE_SIZEREAD; - /* FALL TROUGH */ - case PACKET_STATE_SIZEREAD: - len = session->in_packet.len; - to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize; - /* if to_be_read is zero, the whole packet was blocksize bytes. */ - if (to_be_read != 0) { - if (receivedlen - processed < (unsigned int)to_be_read) { - /* give up, not enough data in buffer */ - SSH_LOG(SSH_LOG_PACKET,"packet: partial packet (read len) [len=%d]",len); - return processed; - } - - packet = ((uint8_t*)data) + processed; -#if 0 - ssh_socket_read(session->socket, - packet, - to_be_read - current_macsize); -#endif - - rc = ssh_buffer_add_data(session->in_buffer, - packet, - to_be_read - current_macsize); - if (rc < 0) { - goto error; - } - processed += to_be_read - current_macsize; - } - - if (session->current_crypto) { - /* - * Decrypt the rest of the packet (blocksize bytes already - * have been decrypted) - */ - uint32_t buffer_len = buffer_get_rest_len(session->in_buffer); - - /* The following check avoids decrypting zero bytes */ - if (buffer_len > blocksize) { - uint8_t *payload = ((uint8_t*)buffer_get_rest(session->in_buffer) + blocksize); - uint32_t plen = buffer_len - blocksize; - - rc = packet_decrypt(session, payload, plen); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Decrypt error"); - goto error; - } - } - - /* copy the last part from the incoming buffer */ - packet = ((uint8_t *)data) + processed; - memcpy(mac, packet, current_macsize); - - rc = packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "HMAC error"); - goto error; - } - processed += current_macsize; - } - - /* skip the size field which has been processed before */ - buffer_pass_bytes(session->in_buffer, sizeof(uint32_t)); - - rc = buffer_get_u8(session->in_buffer, &padding); - if (rc == 0) { - ssh_set_error(session, - SSH_FATAL, - "Packet too short to read padding"); - goto error; - } - - if (padding > buffer_get_rest_len(session->in_buffer)) { - ssh_set_error(session, - SSH_FATAL, - "Invalid padding: %d (%d left)", - padding, - buffer_get_rest_len(session->in_buffer)); - goto error; - } - buffer_pass_bytes_end(session->in_buffer, padding); - compsize = buffer_get_rest_len(session->in_buffer); - -#ifdef WITH_ZLIB - if (session->current_crypto - && session->current_crypto->do_compress_in - && buffer_get_rest_len(session->in_buffer) > 0) { - rc = decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN); - if (rc < 0) { - goto error; - } - } -#endif /* WITH_ZLIB */ - payloadsize = buffer_get_rest_len(session->in_buffer); - session->recv_seq++; - if (session->raw_counter != NULL) { - session->raw_counter->in_bytes += payloadsize; - session->raw_counter->in_packets++; - } - - /* - * We don't want to rewrite a new packet while still executing the - * packet callbacks - */ - session->packet_state = PACKET_STATE_PROCESSING; - ssh_packet_parse_type(session); - SSH_LOG(SSH_LOG_PACKET, - "packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]", - session->in_packet.type, len, padding, compsize, payloadsize); - - /* Execute callbacks */ - ssh_packet_process(session, session->in_packet.type); - session->packet_state = PACKET_STATE_INIT; - if (processed < receivedlen) { - /* Handle a potential packet left in socket buffer */ - SSH_LOG(SSH_LOG_PACKET, - "Processing %" PRIdS " bytes left in socket buffer", - receivedlen-processed); - - packet = ((uint8_t*)data) + processed; - - rc = ssh_packet_socket_callback(packet, receivedlen - processed,user); - processed += rc; - } - - return processed; - case PACKET_STATE_PROCESSING: - SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying."); - return 0; - } - - ssh_set_error(session, - SSH_FATAL, - "Invalid state into packet_read2(): %d", - session->packet_state); - -error: - session->session_state= SSH_SESSION_STATE_ERROR; - - return processed; -} - -void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s){ - session->socket_callbacks.data=ssh_packet_socket_callback; - session->socket_callbacks.connected=NULL; - session->socket_callbacks.controlflow=NULL; - session->socket_callbacks.exception=NULL; - session->socket_callbacks.userdata=session; - ssh_socket_set_callbacks(s,&session->socket_callbacks); -} - -/** @internal - * @brief sets the callbacks for the packet layer - */ -void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks){ - if(session->packet_callbacks == NULL){ - session->packet_callbacks = ssh_list_new(); - } - if (session->packet_callbacks != NULL) { - ssh_list_append(session->packet_callbacks, callbacks); - } -} - -/** @internal - * @brief sets the default packet handlers - */ -void ssh_packet_set_default_callbacks(ssh_session session){ -#ifdef WITH_SSH1 - if(session->version==1){ - ssh_packet_set_default_callbacks1(session); - return; - } -#endif - session->default_packet_callbacks.start=1; - session->default_packet_callbacks.n_callbacks=sizeof(default_packet_handlers)/sizeof(ssh_packet_callback); - session->default_packet_callbacks.user=session; - session->default_packet_callbacks.callbacks=default_packet_handlers; - ssh_packet_set_callbacks(session, &session->default_packet_callbacks); -} - -/** @internal - * @brief dispatch the call of packet handlers callbacks for a received packet - * @param type type of packet - */ -void ssh_packet_process(ssh_session session, uint8_t type){ - struct ssh_iterator *i; - int r=SSH_PACKET_NOT_USED; - ssh_packet_callbacks cb; - - SSH_LOG(SSH_LOG_PACKET, "Dispatching handler for packet type %d",type); - if(session->packet_callbacks == NULL){ - SSH_LOG(SSH_LOG_RARE,"Packet callback is not initialized !"); - - return; - } - i=ssh_list_get_iterator(session->packet_callbacks); - while(i != NULL){ - cb=ssh_iterator_value(ssh_packet_callbacks,i); - i=i->next; - if(!cb) - continue; - if(cb->start > type) - continue; - if(cb->start + cb->n_callbacks <= type) - continue; - if(cb->callbacks[type - cb->start]==NULL) - continue; - r=cb->callbacks[type - cb->start](session,type,session->in_buffer,cb->user); - if(r==SSH_PACKET_USED) - break; - } - if(r==SSH_PACKET_NOT_USED){ - SSH_LOG(SSH_LOG_RARE,"Couldn't do anything with packet type %d",type); - ssh_packet_send_unimplemented(session, session->recv_seq-1); - } -} - -/** @internal - * @brief sends a SSH_MSG_UNIMPLEMENTED answer to an unhandled packet - * @param session the SSH session - * @param seqnum the sequence number of the unknown packet - * @return SSH_ERROR on error, else SSH_OK - */ -int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum){ - int rc; - - rc = ssh_buffer_pack(session->out_buffer, - "bd", - SSH2_MSG_UNIMPLEMENTED, - seqnum); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - rc = packet_send(session); - - return rc; -} - -/** @internal - * @brief handles a SSH_MSG_UNIMPLEMENTED packet - */ -SSH_PACKET_CALLBACK(ssh_packet_unimplemented){ - uint32_t seq; - int rc; - - (void)session; /* unused */ - (void)type; - (void)user; - - rc = ssh_buffer_unpack(packet, "d", &seq); - if (rc != SSH_OK) { - SSH_LOG(SSH_LOG_WARNING, - "Could not unpack SSH_MSG_UNIMPLEMENTED packet"); - } - - SSH_LOG(SSH_LOG_RARE, - "Received SSH_MSG_UNIMPLEMENTED (sequence number %d)",seq); - - return SSH_PACKET_USED; -} - -/** @internal - * @parse the "Type" header field of a packet and updates the session - */ -int ssh_packet_parse_type(ssh_session session) { - memset(&session->in_packet, 0, sizeof(PACKET)); - if(session->in_buffer == NULL) { - return SSH_ERROR; - } - - if(buffer_get_u8(session->in_buffer, &session->in_packet.type) == 0) { - ssh_set_error(session, SSH_FATAL, "Packet too short to read type"); - return SSH_ERROR; - } - - session->in_packet.valid = 1; - - return SSH_OK; -} - -/* - * This function places the outgoing packet buffer into an outgoing - * socket buffer - */ -static int ssh_packet_write(ssh_session session) { - int rc = SSH_ERROR; - - rc=ssh_socket_write(session->socket, - buffer_get_rest(session->out_buffer), - buffer_get_rest_len(session->out_buffer)); - - return rc; -} - -static int packet_send2(ssh_session session) { - unsigned int blocksize = (session->current_crypto ? - session->current_crypto->out_cipher->blocksize : 8); - enum ssh_hmac_e hmac_type = (session->current_crypto ? - session->current_crypto->out_hmac : session->next_crypto->out_hmac); - uint32_t currentlen = buffer_get_rest_len(session->out_buffer); - unsigned char *hmac = NULL; - char padstring[32] = { 0 }; - int rc = SSH_ERROR; - uint32_t finallen,payloadsize,compsize; - uint8_t padding; - - uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 }; - - payloadsize = currentlen; -#ifdef WITH_ZLIB - if (session->current_crypto - && session->current_crypto->do_compress_out - && buffer_get_rest_len(session->out_buffer)) { - if (compress_buffer(session,session->out_buffer) < 0) { - goto error; - } - currentlen = buffer_get_rest_len(session->out_buffer); - } -#endif /* WITH_ZLIB */ - compsize = currentlen; - padding = (blocksize - ((currentlen +5) % blocksize)); - if(padding < 4) { - padding += blocksize; - } - - if (session->current_crypto) { - ssh_get_random(padstring, padding, 0); - } - - finallen = htonl(currentlen + padding + 1); - - memcpy(&header[0], &finallen, sizeof(finallen)); - header[sizeof(finallen)] = padding; - rc = buffer_prepend_data(session->out_buffer, &header, sizeof(header)); - if (rc < 0) { - goto error; - } - rc = ssh_buffer_add_data(session->out_buffer, padstring, padding); - if (rc < 0) { - goto error; - } -#ifdef WITH_PCAP - if(session->pcap_ctx){ - ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT, - buffer_get_rest(session->out_buffer),buffer_get_rest_len(session->out_buffer) - ,buffer_get_rest_len(session->out_buffer)); - } -#endif - hmac = packet_encrypt(session, buffer_get_rest(session->out_buffer), - buffer_get_rest_len(session->out_buffer)); - if (hmac) { - rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type)); - if (rc < 0) { - goto error; - } - } - - rc = ssh_packet_write(session); - session->send_seq++; - if (session->raw_counter != NULL) { - session->raw_counter->out_bytes += payloadsize; - session->raw_counter->out_packets++; - } - - SSH_LOG(SSH_LOG_PACKET, - "packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]", - ntohl(finallen), padding, compsize, payloadsize); - if (ssh_buffer_reinit(session->out_buffer) < 0) { - rc = SSH_ERROR; - } -error: - - return rc; /* SSH_OK, AGAIN or ERROR */ -} - - -int packet_send(ssh_session session) { -#ifdef WITH_SSH1 - if (session->version == 1) { - return packet_send1(session); - } -#endif - return packet_send2(session); -} diff --git a/libssh/src/packet1.c b/libssh/src/packet1.c deleted file mode 100644 index eac70084..00000000 --- a/libssh/src/packet1.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include - -#ifndef _WIN32 -#include -#endif /* _WIN32 */ - -#include "libssh/priv.h" -#include "libssh/ssh1.h" -#include "libssh/crc32.h" -#include "libssh/packet.h" -#include "libssh/session.h" -#include "libssh/buffer.h" -#include "libssh/socket.h" -#include "libssh/kex.h" -#include "libssh/crypto.h" - -#ifdef WITH_SSH1 - -static ssh_packet_callback default_packet_handlers1[]= { - NULL, //SSH_MSG_NONE 0 - ssh_packet_disconnect1, //SSH_MSG_DISCONNECT 1 - ssh_packet_publickey1, //SSH_SMSG_PUBLIC_KEY 2 - NULL, //SSH_CMSG_SESSION_KEY 3 - NULL, //SSH_CMSG_USER 4 - NULL, //SSH_CMSG_AUTH_RHOSTS 5 - NULL, //SSH_CMSG_AUTH_RSA 6 - NULL, //SSH_SMSG_AUTH_RSA_CHALLENGE 7 - NULL, //SSH_CMSG_AUTH_RSA_RESPONSE 8 - NULL, //SSH_CMSG_AUTH_PASSWORD 9 - NULL, //SSH_CMSG_REQUEST_PTY 10 - NULL, //SSH_CMSG_WINDOW_SIZE 11 - NULL, //SSH_CMSG_EXEC_SHELL 12 - NULL, //SSH_CMSG_EXEC_CMD 13 - ssh_packet_smsg_success1, //SSH_SMSG_SUCCESS 14 - ssh_packet_smsg_failure1, //SSH_SMSG_FAILURE 15 - NULL, //SSH_CMSG_STDIN_DATA 16 - ssh_packet_data1, //SSH_SMSG_STDOUT_DATA 17 - ssh_packet_data1, //SSH_SMSG_STDERR_DATA 18 - NULL, //SSH_CMSG_EOF 19 - ssh_packet_exist_status1, //SSH_SMSG_EXITSTATUS 20 - NULL, //SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 - NULL, //SSH_MSG_CHANNEL_OPEN_FAILURE 22 - NULL, //SSH_MSG_CHANNEL_DATA 23 - ssh_packet_close1, //SSH_MSG_CHANNEL_CLOSE 24 - NULL, //SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 - NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 26 - NULL, //SSH_SMSG_X11_OPEN 27 - NULL, //SSH_CMSG_PORT_FORWARD_REQUEST 28 - NULL, //SSH_MSG_PORT_OPEN 29 - NULL, //SSH_CMSG_AGENT_REQUEST_FORWARDING 30 - NULL, //SSH_SMSG_AGENT_OPEN 31 - ssh_packet_ignore_callback, //SSH_MSG_IGNORE 32 - NULL, //SSH_CMSG_EXIT_CONFIRMATION 33 - NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 34 - NULL, //SSH_CMSG_AUTH_RHOSTS_RSA 35 - ssh_packet_ignore_callback, //SSH_MSG_DEBUG 36 -}; - -/** @internal - * @brief sets the default packet handlers - */ -void ssh_packet_set_default_callbacks1(ssh_session session){ - session->default_packet_callbacks.start=0; - session->default_packet_callbacks.n_callbacks=sizeof(default_packet_handlers1)/sizeof(ssh_packet_callback); - session->default_packet_callbacks.user=session; - session->default_packet_callbacks.callbacks=default_packet_handlers1; - ssh_packet_set_callbacks(session, &session->default_packet_callbacks); -} - - -/** @internal - * @handles a data received event. It then calls the handlers for the different packet types - * or and exception handler callback. Adapted for SSH-1 packets. - * @param user pointer to current ssh_session - * @param data pointer to the data received - * @len length of data received. It might not be enough for a complete packet - * @returns number of bytes read and processed. - */ - -int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user) { - void *packet = NULL; - int to_be_read; - size_t processed=0; - uint32_t padding; - uint32_t crc; - uint32_t len, buffer_len; - ssh_session session=(ssh_session)user; - - switch (session->packet_state){ - case PACKET_STATE_INIT: - memset(&session->in_packet, 0, sizeof(PACKET)); - - if (session->in_buffer) { - if (ssh_buffer_reinit(session->in_buffer) < 0) { - goto error; - } - } else { - session->in_buffer = ssh_buffer_new(); - if (session->in_buffer == NULL) { - goto error; - } - } - /* must have at least enough bytes for size */ - if(receivedlen < sizeof(uint32_t)){ - return 0; - } - memcpy(&len,data,sizeof(uint32_t)); - processed += sizeof(uint32_t); - - /* len is not encrypted */ - len = ntohl(len); - if (len > MAX_PACKET_LEN) { - ssh_set_error(session, SSH_FATAL, - "read_packet(): Packet len too high (%u %.8x)", len, len); - goto error; - } - - SSH_LOG(SSH_LOG_PACKET, "Reading a %d bytes packet", len); - - session->in_packet.len = len; - session->packet_state = PACKET_STATE_SIZEREAD; - /* FALL THROUGH */ - case PACKET_STATE_SIZEREAD: - len = session->in_packet.len; - /* SSH-1 has a fixed padding lenght */ - padding = 8 - (len % 8); - to_be_read = len + padding; - if(to_be_read + processed > receivedlen){ - /* wait for rest of packet */ - return processed; - } - /* it is _not_ possible that to_be_read be < 8. */ - packet = (char *)data + processed; - - if (ssh_buffer_add_data(session->in_buffer,packet,to_be_read) < 0) { - goto error; - } - processed += to_be_read; -#ifdef DEBUG_CRYPTO - ssh_print_hexa("read packet:", ssh_buffer_get_begin(session->in_buffer), - ssh_buffer_get_len(session->in_buffer)); -#endif - if (session->current_crypto) { - /* - * We decrypt everything, missing the lenght part (which was - * previously read, unencrypted, and is not part of the buffer - */ - buffer_len = ssh_buffer_get_len(session->in_buffer); - if (buffer_len > 0) { - int rc; - rc = packet_decrypt(session, - ssh_buffer_get_begin(session->in_buffer), - buffer_len); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Packet decrypt error"); - goto error; - } - } - } -#ifdef DEBUG_CRYPTO - ssh_print_hexa("read packet decrypted:", ssh_buffer_get_begin(session->in_buffer), - ssh_buffer_get_len(session->in_buffer)); -#endif - SSH_LOG(SSH_LOG_PACKET, "%d bytes padding", padding); - if(((len + padding) != buffer_get_rest_len(session->in_buffer)) || - ((len + padding) < sizeof(uint32_t))) { - SSH_LOG(SSH_LOG_RARE, "no crc32 in packet"); - ssh_set_error(session, SSH_FATAL, "no crc32 in packet"); - goto error; - } - - memcpy(&crc, - (unsigned char *)buffer_get_rest(session->in_buffer) + (len+padding) - sizeof(uint32_t), - sizeof(uint32_t)); - buffer_pass_bytes_end(session->in_buffer, sizeof(uint32_t)); - crc = ntohl(crc); - if (ssh_crc32(buffer_get_rest(session->in_buffer), - (len + padding) - sizeof(uint32_t)) != crc) { -#ifdef DEBUG_CRYPTO - ssh_print_hexa("crc32 on",buffer_get_rest(session->in_buffer), - len + padding - sizeof(uint32_t)); -#endif - SSH_LOG(SSH_LOG_RARE, "Invalid crc32"); - ssh_set_error(session, SSH_FATAL, - "Invalid crc32: expected %.8x, got %.8x", - crc, - ssh_crc32(buffer_get_rest(session->in_buffer), - len + padding - sizeof(uint32_t))); - goto error; - } - /* pass the padding */ - buffer_pass_bytes(session->in_buffer, padding); - SSH_LOG(SSH_LOG_PACKET, "The packet is valid"); - -/* TODO FIXME -#ifdef WITH_ZLIB - if(session->current_crypto && session->current_crypto->do_compress_in){ - decompress_buffer(session,session->in_buffer); - } -#endif -*/ - session->recv_seq++; - /* We don't want to rewrite a new packet while still executing the packet callbacks */ - session->packet_state = PACKET_STATE_PROCESSING; - ssh_packet_parse_type(session); - /* execute callbacks */ - ssh_packet_process(session, session->in_packet.type); - session->packet_state = PACKET_STATE_INIT; - if(processed < receivedlen){ - int rc; - /* Handle a potential packet left in socket buffer */ - SSH_LOG(SSH_LOG_PACKET,"Processing %" PRIdS " bytes left in socket buffer", - receivedlen-processed); - rc = ssh_packet_socket_callback1((char *)data + processed, - receivedlen - processed,user); - processed += rc; - } - - return processed; - case PACKET_STATE_PROCESSING: - SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying."); - return 0; - } - -error: - session->session_state=SSH_SESSION_STATE_ERROR; - - return processed; -} - - -int packet_send1(ssh_session session) { - unsigned int blocksize = (session->current_crypto ? - session->current_crypto->out_cipher->blocksize : 8); - uint32_t currentlen = ssh_buffer_get_len(session->out_buffer) + sizeof(uint32_t); - char padstring[32] = {0}; - int rc = SSH_ERROR; - uint32_t finallen; - uint32_t crc; - uint8_t padding; - - SSH_LOG(SSH_LOG_PACKET,"Sending a %d bytes long packet",currentlen); - -/* TODO FIXME -#ifdef WITH_ZLIB - if (session->current_crypto && session->current_crypto->do_compress_out) { - if (compress_buffer(session, session->out_buffer) < 0) { - goto error; - } - currentlen = buffer_get_len(session->out_buffer); - } -#endif -*/ - padding = blocksize - (currentlen % blocksize); - if (session->current_crypto) { - ssh_get_random(padstring, padding, 0); - } else { - memset(padstring, 0, padding); - } - - finallen = htonl(currentlen); - SSH_LOG(SSH_LOG_PACKET, - "%d bytes after comp + %d padding bytes = %d bytes packet", - currentlen, padding, ntohl(finallen)); - - if (buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) { - goto error; - } - if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) { - goto error; - } - - crc = ssh_crc32((char *)ssh_buffer_get_begin(session->out_buffer) + sizeof(uint32_t), - ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t)); - - if (buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) { - goto error; - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Clear packet", ssh_buffer_get_begin(session->out_buffer), - ssh_buffer_get_len(session->out_buffer)); -#endif - - /* session->out_buffer should have more than sizeof(uint32_t) bytes - in it as required for packet_encrypt */ - packet_encrypt(session, (unsigned char *)ssh_buffer_get_begin(session->out_buffer) + sizeof(uint32_t), - ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t)); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("encrypted packet",ssh_buffer_get_begin(session->out_buffer), - ssh_buffer_get_len(session->out_buffer)); -#endif - rc=ssh_socket_write(session->socket, ssh_buffer_get_begin(session->out_buffer), - ssh_buffer_get_len(session->out_buffer)); - if(rc== SSH_ERROR) { - goto error; - } - - session->send_seq++; - - if (ssh_buffer_reinit(session->out_buffer) < 0) { - rc = SSH_ERROR; - } -error: - - return rc; /* SSH_OK, AGAIN or ERROR */ -} - -SSH_PACKET_CALLBACK(ssh_packet_disconnect1){ - (void)packet; - (void)user; - (void)type; - SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT"); - ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT"); - ssh_socket_close(session->socket); - session->alive = 0; - session->session_state=SSH_SESSION_STATE_DISCONNECTED; - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(ssh_packet_smsg_success1){ - if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){ - session->session_state=SSH_SESSION_STATE_AUTHENTICATING; - return SSH_PACKET_USED; - } else if(session->session_state==SSH_SESSION_STATE_AUTHENTICATING){ - ssh_auth1_handler(session,type); - return SSH_PACKET_USED; - } else { - return ssh_packet_channel_success(session,type,packet,user); - } -} - -SSH_PACKET_CALLBACK(ssh_packet_smsg_failure1){ - if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){ - session->session_state=SSH_SESSION_STATE_ERROR; - ssh_set_error(session,SSH_FATAL,"Key exchange failed: received SSH_SMSG_FAILURE"); - return SSH_PACKET_USED; - } else if(session->session_state==SSH_SESSION_STATE_AUTHENTICATING){ - ssh_auth1_handler(session,type); - return SSH_PACKET_USED; - } else { - return ssh_packet_channel_failure(session,type,packet,user); - } -} - - -#endif /* WITH_SSH1 */ - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/packet_cb.c b/libssh/src/packet_cb.c deleted file mode 100644 index a10dd1ab..00000000 --- a/libssh/src/packet_cb.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * packet.c - packet building functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2011 Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include - -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/crypto.h" -#include "libssh/dh.h" -#include "libssh/misc.h" -#include "libssh/packet.h" -#include "libssh/pki.h" -#include "libssh/session.h" -#include "libssh/socket.h" -#include "libssh/ssh2.h" -#include "libssh/curve25519.h" - -/** - * @internal - * - * @brief Handle a SSH_DISCONNECT packet. - */ -SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback){ - int rc; - uint32_t code = 0; - char *error = NULL; - ssh_string error_s; - (void)user; - (void)type; - - rc = buffer_get_u32(packet, &code); - if (rc != 0) { - code = ntohl(code); - } - - error_s = buffer_get_ssh_string(packet); - if (error_s != NULL) { - error = ssh_string_to_char(error_s); - ssh_string_free(error_s); - } - SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s", - code, error != NULL ? error : "no error"); - ssh_set_error(session, SSH_FATAL, - "Received SSH_MSG_DISCONNECT: %d:%s", - code, error != NULL ? error : "no error"); - SAFE_FREE(error); - - ssh_socket_close(session->socket); - session->alive = 0; - session->session_state = SSH_SESSION_STATE_ERROR; - /* TODO: handle a graceful disconnect */ - return SSH_PACKET_USED; -} - -/** - * @internal - * - * @brief Handle a SSH_IGNORE and SSH_DEBUG packet. - */ -SSH_PACKET_CALLBACK(ssh_packet_ignore_callback){ - (void)session; /* unused */ - (void)user; - (void)type; - (void)packet; - SSH_LOG(SSH_LOG_PROTOCOL,"Received %s packet",type==SSH2_MSG_IGNORE ? "SSH_MSG_IGNORE" : "SSH_MSG_DEBUG"); - /* TODO: handle a graceful disconnect */ - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(ssh_packet_dh_reply){ - int rc; - (void)type; - (void)user; - SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_KEXDH_REPLY"); - if(session->session_state!= SSH_SESSION_STATE_DH && - session->dh_handshake_state != DH_STATE_INIT_SENT){ - ssh_set_error(session,SSH_FATAL,"ssh_packet_dh_reply called in wrong state : %d:%d", - session->session_state,session->dh_handshake_state); - goto error; - } - switch(session->next_crypto->kex_type){ - case SSH_KEX_DH_GROUP1_SHA1: - case SSH_KEX_DH_GROUP14_SHA1: - rc=ssh_client_dh_reply(session, packet); - break; -#ifdef HAVE_ECDH - case SSH_KEX_ECDH_SHA2_NISTP256: - rc = ssh_client_ecdh_reply(session, packet); - break; -#endif -#ifdef HAVE_CURVE25519 - case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG: - rc = ssh_client_curve25519_reply(session, packet); - break; -#endif - default: - ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_dh_reply"); - goto error; - } - if(rc==SSH_OK) { - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - return SSH_PACKET_USED; - } -error: - session->session_state=SSH_SESSION_STATE_ERROR; - return SSH_PACKET_USED; -} - -SSH_PACKET_CALLBACK(ssh_packet_newkeys){ - ssh_string sig_blob = NULL; - int rc; - (void)packet; - (void)user; - (void)type; - SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_NEWKEYS"); - if(session->session_state!= SSH_SESSION_STATE_DH && - session->dh_handshake_state != DH_STATE_NEWKEYS_SENT){ - ssh_set_error(session,SSH_FATAL,"ssh_packet_newkeys called in wrong state : %d:%d", - session->session_state,session->dh_handshake_state); - goto error; - } - if(session->server){ - /* server things are done in server.c */ - session->dh_handshake_state=DH_STATE_FINISHED; - } else { - ssh_key key; - /* client */ - rc = make_sessionid(session); - if (rc != SSH_OK) { - goto error; - } - - /* - * Set the cryptographic functions for the next crypto - * (it is needed for generate_session_keys for key lengths) - */ - if (crypt_set_algorithms(session, SSH_3DES) /* knows nothing about DES*/ ) { - goto error; - } - - if (generate_session_keys(session) < 0) { - goto error; - } - - /* Verify the host's signature. FIXME do it sooner */ - sig_blob = session->next_crypto->dh_server_signature; - session->next_crypto->dh_server_signature = NULL; - - /* get the server public key */ - rc = ssh_pki_import_pubkey_blob(session->next_crypto->server_pubkey, &key); - if (rc < 0) { - return SSH_ERROR; - } - - /* check if public key from server matches user preferences */ - if (session->opts.wanted_methods[SSH_HOSTKEYS]) { - if(!ssh_match_group(session->opts.wanted_methods[SSH_HOSTKEYS], - key->type_c)) { - ssh_set_error(session, - SSH_FATAL, - "Public key from server (%s) doesn't match user " - "preference (%s)", - key->type_c, - session->opts.wanted_methods[SSH_HOSTKEYS]); - ssh_key_free(key); - return -1; - } - } - - rc = ssh_pki_signature_verify_blob(session, - sig_blob, - key, - session->next_crypto->secret_hash, - session->next_crypto->digest_len); - /* Set the server public key type for known host checking */ - session->next_crypto->server_pubkey_type = key->type_c; - - ssh_key_free(key); - ssh_string_burn(sig_blob); - ssh_string_free(sig_blob); - sig_blob = NULL; - if (rc == SSH_ERROR) { - goto error; - } - SSH_LOG(SSH_LOG_PROTOCOL,"Signature verified and valid"); - - /* - * Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and - * current_crypto - */ - if (session->current_crypto) { - crypto_free(session->current_crypto); - session->current_crypto=NULL; - } - - /* FIXME later, include a function to change keys */ - session->current_crypto = session->next_crypto; - - session->next_crypto = crypto_new(); - if (session->next_crypto == NULL) { - ssh_set_error_oom(session); - goto error; - } - session->next_crypto->session_id = malloc(session->current_crypto->digest_len); - if (session->next_crypto->session_id == NULL) { - ssh_set_error_oom(session); - goto error; - } - memcpy(session->next_crypto->session_id, session->current_crypto->session_id, - session->current_crypto->digest_len); - } - session->dh_handshake_state = DH_STATE_FINISHED; - session->ssh_connection_callback(session); - return SSH_PACKET_USED; -error: - session->session_state=SSH_SESSION_STATE_ERROR; - return SSH_PACKET_USED; -} - -/** - * @internal - * @brief handles a SSH_SERVICE_ACCEPT packet - * - */ -SSH_PACKET_CALLBACK(ssh_packet_service_accept){ - (void)packet; - (void)type; - (void)user; - - session->auth_service_state=SSH_AUTH_SERVICE_ACCEPTED; - SSH_LOG(SSH_LOG_PACKET, - "Received SSH_MSG_SERVICE_ACCEPT"); - - return SSH_PACKET_USED; -} diff --git a/libssh/src/packet_crypt.c b/libssh/src/packet_crypt.c deleted file mode 100644 index 914727e0..00000000 --- a/libssh/src/packet_crypt.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * crypt.c - blowfish-cbc code - * - * This file is part of the SSH Library - * - * Copyright (c) 2003 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#ifdef OPENSSL_CRYPTO -#include -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/wrapper.h" -#include "libssh/crypto.h" -#include "libssh/buffer.h" - -uint32_t packet_decrypt_len(ssh_session session, char *crypted){ - uint32_t decrypted; - - if (session->current_crypto) { - if (packet_decrypt(session, crypted, - session->current_crypto->in_cipher->blocksize) < 0) { - return 0; - } - } - memcpy(&decrypted,crypted,sizeof(decrypted)); - return ntohl(decrypted); -} - -int packet_decrypt(ssh_session session, void *data,uint32_t len) { - struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher; - char *out = NULL; - - assert(len); - - if(len % session->current_crypto->in_cipher->blocksize != 0){ - ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); - return SSH_ERROR; - } - out = malloc(len); - if (out == NULL) { - return -1; - } - - if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey, - session->current_crypto->decryptIV) < 0) { - SAFE_FREE(out); - return -1; - } - crypto->decrypt(crypto,data,out,len); - - memcpy(data,out,len); - BURN_BUFFER(out, len); - SAFE_FREE(out); - return 0; -} - -unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) { - struct ssh_cipher_struct *crypto = NULL; - HMACCTX ctx = NULL; - char *out = NULL; - unsigned int finallen; - uint32_t seq; - enum ssh_hmac_e type; - - assert(len); - - if (!session->current_crypto) { - return NULL; /* nothing to do here */ - } - if(len % session->current_crypto->in_cipher->blocksize != 0){ - ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); - return NULL; - } - out = malloc(len); - if (out == NULL) { - return NULL; - } - - type = session->current_crypto->out_hmac; - seq = ntohl(session->send_seq); - crypto = session->current_crypto->out_cipher; - - if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey, - session->current_crypto->encryptIV) < 0) { - SAFE_FREE(out); - return NULL; - } - - if (session->version == 2) { - ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type); - if (ctx == NULL) { - SAFE_FREE(out); - return NULL; - } - hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t)); - hmac_update(ctx,data,len); - hmac_final(ctx,session->current_crypto->hmacbuf,&finallen); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("mac: ",data,hmac_digest_len(type)); - if (finallen != hmac_digest_len(type)) { - printf("Final len is %d\n",finallen); - } - ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type)); -#endif - } - - crypto->encrypt(crypto, data, out, len); - - memcpy(data, out, len); - BURN_BUFFER(out, len); - SAFE_FREE(out); - - if (session->version == 2) { - return session->current_crypto->hmacbuf; - } - - return NULL; -} - -/** - * @internal - * - * @brief Verify the hmac of a packet - * - * @param session The session to use. - * @param buffer The buffer to verify the hmac from. - * @param mac The mac to compare with the hmac. - * - * @return 0 if hmac and mac are equal, < 0 if not or an error - * occurred. - */ -int packet_hmac_verify(ssh_session session, ssh_buffer buffer, - unsigned char *mac, enum ssh_hmac_e type) { - unsigned char hmacbuf[DIGEST_MAX_LEN] = {0}; - HMACCTX ctx; - unsigned int len; - uint32_t seq; - - ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type); - if (ctx == NULL) { - return -1; - } - - seq = htonl(session->recv_seq); - - hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t)); - hmac_update(ctx, buffer_get_rest(buffer), buffer_get_rest_len(buffer)); - hmac_final(ctx, hmacbuf, &len); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("received mac",mac,len); - ssh_print_hexa("Computed mac",hmacbuf,len); - ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t)); -#endif - if (memcmp(mac, hmacbuf, len) == 0) { - return 0; - } - - return -1; -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/pcap.c b/libssh/src/pcap.c deleted file mode 100644 index 134bdf10..00000000 --- a/libssh/src/pcap.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* pcap.c */ -#include "config.h" -#ifdef WITH_PCAP - -#include -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#endif -#include -#include - -#include "libssh/libssh.h" -#include "libssh/pcap.h" -#include "libssh/session.h" -#include "libssh/buffer.h" -#include "libssh/socket.h" - -/** - * @internal - * - * @defgroup libssh_pcap The libssh pcap functions - * @ingroup libssh - * - * The pcap file generation - * - * - * @{ - */ - -/* The header of a pcap file is the following. We are not going to make it - * very complicated. - * Just for information. - */ -struct pcap_hdr_s { - uint32_t magic_number; /* magic number */ - uint16_t version_major; /* major version number */ - uint16_t version_minor; /* minor version number */ - int32_t thiszone; /* GMT to local correction */ - uint32_t sigfigs; /* accuracy of timestamps */ - uint32_t snaplen; /* max length of captured packets, in octets */ - uint32_t network; /* data link type */ -}; - -#define PCAP_MAGIC 0xa1b2c3d4 -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 - -#define DLT_RAW 12 /* raw IP */ - -/* TCP flags */ -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 - -/* The header of a pcap packet. - * Just for information. - */ -struct pcaprec_hdr_s { - uint32_t ts_sec; /* timestamp seconds */ - uint32_t ts_usec; /* timestamp microseconds */ - uint32_t incl_len; /* number of octets of packet saved in file */ - uint32_t orig_len; /* actual length of packet */ -}; - -/** @private - * @brief a pcap context expresses the state of a pcap dump - * in a SSH session only. Multiple pcap contexts may be used into - * a single pcap file. - */ - -struct ssh_pcap_context_struct { - ssh_session session; - ssh_pcap_file file; - int connected; - /* All of these information are useful to generate - * the dummy IP and TCP packets - */ - uint32_t ipsource; - uint32_t ipdest; - uint16_t portsource; - uint16_t portdest; - uint32_t outsequence; - uint32_t insequence; -}; - -/** @private - * @brief a pcap file expresses the state of a pcap file which may - * contain several streams. - */ -struct ssh_pcap_file_struct { - FILE *output; - uint16_t ipsequence; -}; - -/** - * @brief create a new ssh_pcap_file object - */ -ssh_pcap_file ssh_pcap_file_new(void) { - struct ssh_pcap_file_struct *pcap; - - pcap = (struct ssh_pcap_file_struct *) malloc(sizeof(struct ssh_pcap_file_struct)); - if (pcap == NULL) { - return NULL; - } - ZERO_STRUCTP(pcap); - - return pcap; -} - -/** @internal - * @brief writes a packet on file - */ -static int ssh_pcap_file_write(ssh_pcap_file pcap, ssh_buffer packet){ - int err; - uint32_t len; - if(pcap == NULL || pcap->output==NULL) - return SSH_ERROR; - len=buffer_get_rest_len(packet); - err=fwrite(buffer_get_rest(packet),len,1,pcap->output); - if(err<0) - return SSH_ERROR; - else - return SSH_OK; -} - -/** @internal - * @brief prepends a packet with the pcap header and writes packet - * on file - */ -int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len){ - ssh_buffer header=ssh_buffer_new(); - struct timeval now; - int err; - if(header == NULL) - return SSH_ERROR; - gettimeofday(&now,NULL); - err = buffer_add_u32(header,htonl(now.tv_sec)); - if (err < 0) { - goto error; - } - err = buffer_add_u32(header,htonl(now.tv_usec)); - if (err < 0) { - goto error; - } - err = buffer_add_u32(header,htonl(buffer_get_rest_len(packet))); - if (err < 0) { - goto error; - } - err = buffer_add_u32(header,htonl(original_len)); - if (err < 0) { - goto error; - } - err = buffer_add_buffer(header,packet); - if (err < 0) { - goto error; - } - err=ssh_pcap_file_write(pcap,header); -error: - ssh_buffer_free(header); - return err; -} - -/** - * @brief opens a new pcap file and create header - */ -int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename){ - ssh_buffer header; - int err; - if(pcap == NULL) - return SSH_ERROR; - if(pcap->output){ - fclose(pcap->output); - pcap->output=NULL; - } - pcap->output=fopen(filename,"wb"); - if(pcap->output==NULL) - return SSH_ERROR; - header=ssh_buffer_new(); - if(header==NULL) - return SSH_ERROR; - err = buffer_add_u32(header,htonl(PCAP_MAGIC)); - if (err < 0) { - goto error; - } - err = buffer_add_u16(header,htons(PCAP_VERSION_MAJOR)); - if (err < 0) { - goto error; - } - err = buffer_add_u16(header,htons(PCAP_VERSION_MINOR)); - if (err < 0) { - goto error; - } - /* currently hardcode GMT to 0 */ - err = buffer_add_u32(header,htonl(0)); - if (err < 0) { - goto error; - } - /* accuracy */ - err = buffer_add_u32(header,htonl(0)); - if (err < 0) { - goto error; - } - /* size of the biggest packet */ - err = buffer_add_u32(header,htonl(MAX_PACKET_LEN)); - if (err < 0) { - goto error; - } - /* we will write sort-of IP */ - err = buffer_add_u32(header,htonl(DLT_RAW)); - if (err < 0) { - goto error; - } - err=ssh_pcap_file_write(pcap,header); -error: - ssh_buffer_free(header); - return err; -} - -int ssh_pcap_file_close(ssh_pcap_file pcap){ - int err; - if(pcap ==NULL || pcap->output==NULL) - return SSH_ERROR; - err=fclose(pcap->output); - pcap->output=NULL; - if(err != 0) - return SSH_ERROR; - else - return SSH_OK; -} - -void ssh_pcap_file_free(ssh_pcap_file pcap){ - ssh_pcap_file_close(pcap); - SAFE_FREE(pcap); -} - - -/** @internal - * @brief allocates a new ssh_pcap_context object - */ - -ssh_pcap_context ssh_pcap_context_new(ssh_session session){ - ssh_pcap_context ctx = (struct ssh_pcap_context_struct *) malloc(sizeof(struct ssh_pcap_context_struct)); - if(ctx==NULL){ - ssh_set_error_oom(session); - return NULL; - } - ZERO_STRUCTP(ctx); - ctx->session=session; - return ctx; -} - -void ssh_pcap_context_free(ssh_pcap_context ctx){ - SAFE_FREE(ctx); -} - -void ssh_pcap_context_set_file(ssh_pcap_context ctx, ssh_pcap_file pcap){ - ctx->file=pcap; -} - -/** @internal - * @brief sets the IP and port parameters in the connection - */ -static int ssh_pcap_context_connect(ssh_pcap_context ctx){ - ssh_session session=ctx->session; - struct sockaddr_in local, remote; - socket_t fd; - socklen_t len; - if(session==NULL) - return SSH_ERROR; - if(session->socket==NULL) - return SSH_ERROR; - fd=ssh_socket_get_fd_in(session->socket); - /* TODO: adapt for windows */ - if(fd<0) - return SSH_ERROR; - len=sizeof(local); - if(getsockname(fd,(struct sockaddr *)&local,&len)<0){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Getting local IP address: %s",strerror(errno)); - return SSH_ERROR; - } - len=sizeof(remote); - if(getpeername(fd,(struct sockaddr *)&remote,&len)<0){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Getting remote IP address: %s",strerror(errno)); - return SSH_ERROR; - } - if(local.sin_family != AF_INET){ - ssh_set_error(session,SSH_REQUEST_DENIED,"Only IPv4 supported for pcap logging"); - return SSH_ERROR; - } - memcpy(&ctx->ipsource,&local.sin_addr,sizeof(ctx->ipsource)); - memcpy(&ctx->ipdest,&remote.sin_addr,sizeof(ctx->ipdest)); - memcpy(&ctx->portsource,&local.sin_port,sizeof(ctx->portsource)); - memcpy(&ctx->portdest,&remote.sin_port,sizeof(ctx->portdest)); - - ctx->connected=1; - return SSH_OK; -} - -#define IPHDR_LEN 20 -#define TCPHDR_LEN 20 -#define TCPIPHDR_LEN (IPHDR_LEN + TCPHDR_LEN) -/** @internal - * @brief write a SSH packet as a TCP over IP in a pcap file - * @param ctx open pcap context - * @param direction SSH_PCAP_DIRECTION_IN if the packet has been received - * @param direction SSH_PCAP_DIRECTION_OUT if the packet has been emitted - * @param data pointer to the data to write - * @param len data to write in the pcap file. May be smaller than origlen. - * @param origlen number of bytes of complete data. - * @returns SSH_OK write is successful - * @returns SSH_ERROR an error happened. - */ -int ssh_pcap_context_write(ssh_pcap_context ctx,enum ssh_pcap_direction direction - , void *data, uint32_t len, uint32_t origlen){ - ssh_buffer ip; - int rc; - if(ctx==NULL || ctx->file ==NULL) - return SSH_ERROR; - if(ctx->connected==0) - if(ssh_pcap_context_connect(ctx)==SSH_ERROR) - return SSH_ERROR; - ip=ssh_buffer_new(); - if(ip==NULL){ - ssh_set_error_oom(ctx->session); - return SSH_ERROR; - } - - /* build an IP packet */ - rc = ssh_buffer_pack(ip, - "bbwwwbbw", - 4 << 4 | 5, /* V4, 20 bytes */ - 0, /* tos */ - origlen + TCPIPHDR_LEN, /* total len */ - ctx->file->ipsequence, /* IP id number */ - 0, /* fragment offset */ - 64, /* TTL */ - 6, /* protocol TCP=6 */ - 0); /* checksum */ - - ctx->file->ipsequence++; - if (rc != SSH_OK){ - goto error; - } - if(direction==SSH_PCAP_DIR_OUT){ - rc = buffer_add_u32(ip,ctx->ipsource); - if (rc < 0) { - goto error; - } - rc = buffer_add_u32(ip,ctx->ipdest); - if (rc < 0) { - goto error; - } - } else { - rc = buffer_add_u32(ip,ctx->ipdest); - if (rc < 0) { - goto error; - } - rc = buffer_add_u32(ip,ctx->ipsource); - if (rc < 0) { - goto error; - } - } - /* TCP */ - if(direction==SSH_PCAP_DIR_OUT){ - rc = buffer_add_u16(ip,ctx->portsource); - if (rc < 0) { - goto error; - } - rc = buffer_add_u16(ip,ctx->portdest); - if (rc < 0) { - goto error; - } - } else { - rc = buffer_add_u16(ip,ctx->portdest); - if (rc < 0) { - goto error; - } - rc = buffer_add_u16(ip,ctx->portsource); - if (rc < 0) { - goto error; - } - } - /* sequence number */ - if(direction==SSH_PCAP_DIR_OUT){ - rc = ssh_buffer_pack(ip, "d", ctx->outsequence); - if (rc != SSH_OK) { - goto error; - } - ctx->outsequence+=origlen; - } else { - rc = ssh_buffer_pack(ip, "d", ctx->insequence); - if (rc != SSH_OK) { - goto error; - } - ctx->insequence+=origlen; - } - /* ack number */ - if(direction==SSH_PCAP_DIR_OUT){ - rc = ssh_buffer_pack(ip, "d", ctx->insequence); - if (rc != SSH_OK) { - goto error; - } - } else { - rc = ssh_buffer_pack(ip, "d", ctx->outsequence); - if (rc != SSH_OK) { - goto error; - } - } - - rc = ssh_buffer_pack(ip, - "bbwwwP", - 5 << 4, /* header len = 20 = 5 * 32 bits, at offset 4*/ - TH_PUSH | TH_ACK, /* flags */ - 65535, /* window */ - 0, /* checksum */ - 0, /* urgent data ptr */ - (size_t)len, data); /* actual data */ - if (rc != SSH_OK) { - goto error; - } - rc=ssh_pcap_file_write_packet(ctx->file,ip,origlen + TCPIPHDR_LEN); -error: - ssh_buffer_free(ip); - return rc; -} - -/** @brief sets the pcap file used to trace the session - * @param current session - * @param pcap an handler to a pcap file. A pcap file may be used in several - * sessions. - * @returns SSH_ERROR in case of error, SSH_OK otherwise. - */ -int ssh_set_pcap_file(ssh_session session, ssh_pcap_file pcap){ - ssh_pcap_context ctx=ssh_pcap_context_new(session); - if(ctx==NULL){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - ctx->file=pcap; - if(session->pcap_ctx) - ssh_pcap_context_free(session->pcap_ctx); - session->pcap_ctx=ctx; - return SSH_OK; -} - - -#else /* WITH_PCAP */ - -/* Simple stub returning errors when no pcap compiled in */ - -#include "libssh/libssh.h" -#include "libssh/priv.h" - -int ssh_pcap_file_close(ssh_pcap_file pcap){ - (void) pcap; - return SSH_ERROR; -} - -void ssh_pcap_file_free(ssh_pcap_file pcap){ - (void) pcap; -} - -ssh_pcap_file ssh_pcap_file_new(void){ - return NULL; -} -int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename){ - (void) pcap; - (void) filename; - return SSH_ERROR; -} - -int ssh_set_pcap_file(ssh_session session, ssh_pcap_file pcapfile){ - (void) pcapfile; - ssh_set_error(session,SSH_REQUEST_DENIED,"Pcap support not compiled in"); - return SSH_ERROR; -} - -#endif - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/pki.c b/libssh/src/pki.c deleted file mode 100644 index af472ebb..00000000 --- a/libssh/src/pki.c +++ /dev/null @@ -1,1649 +0,0 @@ -/* - * known_hosts.c - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * Copyright (c) 2011-2013 Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/** - * @defgroup libssh_pki The SSH Public Key Infrastructure - * @ingroup libssh - * - * Functions for the creation, importation and manipulation of public and - * private keys in the context of the SSH protocol - * - * @{ - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -# if _MSC_VER >= 1400 -# include -# undef open -# define open _open -# undef close -# define close _close -# undef read -# define read _read -# undef unlink -# define unlink _unlink -# endif /* _MSC_VER */ -#endif - -#include "libssh/libssh.h" -#include "libssh/session.h" -#include "libssh/priv.h" -#include "libssh/pki.h" -#include "libssh/pki_priv.h" -#include "libssh/keys.h" -#include "libssh/buffer.h" -#include "libssh/misc.h" -#include "libssh/agent.h" - -void _ssh_pki_log(const char *function, const char *format, ...) -{ -#ifdef DEBUG_CRYPTO - char buffer[1024]; - va_list va; - - va_start(va, format); - vsnprintf(buffer, sizeof(buffer), format, va); - va_end(va); - - ssh_log_function(SSH_LOG_DEBUG, function, buffer); -#else - (void) function; - (void) format; -#endif - return; -} - -enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) { - if (strncmp(privkey, DSA_HEADER_BEGIN, strlen(DSA_HEADER_BEGIN)) == 0) { - return SSH_KEYTYPE_DSS; - } - - if (strncmp(privkey, RSA_HEADER_BEGIN, strlen(RSA_HEADER_BEGIN)) == 0) { - return SSH_KEYTYPE_RSA; - } - - if (strncmp(privkey, ECDSA_HEADER_BEGIN, strlen(ECDSA_HEADER_BEGIN)) == 0) { - return SSH_KEYTYPE_ECDSA; - } - - return SSH_KEYTYPE_UNKNOWN; -} - -/** - * @brief returns the ECDSA key name ("ecdsa-sha2-nistp256" for example) - * - * @param[in] key the ssh_key whose ECDSA name to get - * - * @returns the ECDSA key name ("ecdsa-sha2-nistp256" for example) - * - * @returns "unknown" if the ECDSA key name is not known - */ -const char *ssh_pki_key_ecdsa_name(const ssh_key key) -{ -#ifdef HAVE_OPENSSL_ECC /* FIXME Better ECC check needed */ - return pki_key_ecdsa_nid_to_name(key->ecdsa_nid); -#else - (void) key; /* unused */ - return NULL; -#endif -} - -/** - * @brief creates a new empty SSH key - * @returns an empty ssh_key handle, or NULL on error. - */ -ssh_key ssh_key_new (void) { - ssh_key ptr = malloc (sizeof (struct ssh_key_struct)); - if (ptr == NULL) { - return NULL; - } - ZERO_STRUCTP(ptr); - return ptr; -} - -ssh_key ssh_key_dup(const ssh_key key) -{ - if (key == NULL) { - return NULL; - } - - return pki_key_dup(key, 0); -} - -/** - * @brief clean up the key and deallocate all existing keys - * @param[in] key ssh_key to clean - */ -void ssh_key_clean (ssh_key key){ - if(key == NULL) - return; -#ifdef HAVE_LIBGCRYPT - if(key->dsa) gcry_sexp_release(key->dsa); - if(key->rsa) gcry_sexp_release(key->rsa); - if(key->ecdsa) gcry_sexp_release(key->ecdsa); -#elif defined HAVE_LIBCRYPTO - if(key->dsa) DSA_free(key->dsa); - if(key->rsa) RSA_free(key->rsa); -#ifdef HAVE_OPENSSL_ECC - if(key->ecdsa) EC_KEY_free(key->ecdsa); -#endif /* HAVE_OPENSSL_ECC */ -#endif - if (key->ed25519_privkey != NULL){ - BURN_BUFFER(key->ed25519_privkey, sizeof(ed25519_privkey)); - SAFE_FREE(key->ed25519_privkey); - } - SAFE_FREE(key->ed25519_pubkey); - key->flags=SSH_KEY_FLAG_EMPTY; - key->type=SSH_KEYTYPE_UNKNOWN; - key->ecdsa_nid = 0; - key->type_c=NULL; - key->dsa = NULL; - key->rsa = NULL; - key->ecdsa = NULL; -} - -/** - * @brief deallocate a SSH key - * @param[in] key ssh_key handle to free - */ -void ssh_key_free (ssh_key key){ - if(key){ - ssh_key_clean(key); - SAFE_FREE(key); - } -} - -/** - * @brief returns the type of a ssh key - * @param[in] key the ssh_key handle - * @returns one of SSH_KEYTYPE_RSA,SSH_KEYTYPE_DSS,SSH_KEYTYPE_RSA1 - * @returns SSH_KEYTYPE_UNKNOWN if the type is unknown - */ -enum ssh_keytypes_e ssh_key_type(const ssh_key key){ - if (key == NULL) { - return SSH_KEYTYPE_UNKNOWN; - } - return key->type; -} - -/** - * @brief Convert a key type to a string. - * - * @param[in] type The type to convert. - * - * @return A string for the keytype or NULL if unknown. - */ -const char *ssh_key_type_to_char(enum ssh_keytypes_e type) { - switch (type) { - case SSH_KEYTYPE_DSS: - return "ssh-dss"; - case SSH_KEYTYPE_RSA: - return "ssh-rsa"; - case SSH_KEYTYPE_RSA1: - return "ssh-rsa1"; - case SSH_KEYTYPE_ECDSA: - return "ssh-ecdsa"; - case SSH_KEYTYPE_ED25519: - return "ssh-ed25519"; - case SSH_KEYTYPE_UNKNOWN: - return NULL; - } - - /* We should never reach this */ - return NULL; -} - -/** - * @brief Convert a ssh key name to a ssh key type. - * - * @param[in] name The name to convert. - * - * @return The enum ssh key type. - */ -enum ssh_keytypes_e ssh_key_type_from_name(const char *name) { - if (name == NULL) { - return SSH_KEYTYPE_UNKNOWN; - } - - if (strcmp(name, "rsa1") == 0) { - return SSH_KEYTYPE_RSA1; - } else if (strcmp(name, "rsa") == 0) { - return SSH_KEYTYPE_RSA; - } else if (strcmp(name, "dsa") == 0) { - return SSH_KEYTYPE_DSS; - } else if (strcmp(name, "ssh-rsa1") == 0) { - return SSH_KEYTYPE_RSA1; - } else if (strcmp(name, "ssh-rsa") == 0) { - return SSH_KEYTYPE_RSA; - } else if (strcmp(name, "ssh-dss") == 0) { - return SSH_KEYTYPE_DSS; - } else if (strcmp(name, "ssh-ecdsa") == 0 - || strcmp(name, "ecdsa") == 0 - || strcmp(name, "ecdsa-sha2-nistp256") == 0 - || strcmp(name, "ecdsa-sha2-nistp384") == 0 - || strcmp(name, "ecdsa-sha2-nistp521") == 0) { - return SSH_KEYTYPE_ECDSA; - } else if (strcmp(name, "ssh-ed25519") == 0){ - return SSH_KEYTYPE_ED25519; - } - - return SSH_KEYTYPE_UNKNOWN; -} - -/** - * @brief Check if the key has/is a public key. - * - * @param[in] k The key to check. - * - * @return 1 if it is a public key, 0 if not. - */ -int ssh_key_is_public(const ssh_key k) { - if (k == NULL) { - return 0; - } - - return (k->flags & SSH_KEY_FLAG_PUBLIC); -} - -/** - * @brief Check if the key is a private key. - * - * @param[in] k The key to check. - * - * @return 1 if it is a private key, 0 if not. - */ -int ssh_key_is_private(const ssh_key k) { - if (k == NULL) { - return 0; - } - - return (k->flags & SSH_KEY_FLAG_PRIVATE); -} - -/** - * @brief Compare keys if they are equal. - * - * @param[in] k1 The first key to compare. - * - * @param[in] k2 The second key to compare. - * - * @param[in] what What part or type of the key do you want to compare. - * - * @return 0 if equal, 1 if not. - */ -int ssh_key_cmp(const ssh_key k1, - const ssh_key k2, - enum ssh_keycmp_e what) -{ - if (k1 == NULL || k2 == NULL) { - return 1; - } - - if (k1->type != k2->type) { - ssh_pki_log("key types don't match!"); - return 1; - } - - if (what == SSH_KEY_CMP_PRIVATE) { - if (!ssh_key_is_private(k1) || - !ssh_key_is_private(k2)) { - return 1; - } - } - - if (k1->type == SSH_KEYTYPE_ED25519) { - return pki_ed25519_key_cmp(k1, k2, what); - } - - return pki_key_compare(k1, k2, what); -} - -ssh_signature ssh_signature_new(void) -{ - struct ssh_signature_struct *sig; - - sig = malloc(sizeof(struct ssh_signature_struct)); - if (sig == NULL) { - return NULL; - } - ZERO_STRUCTP(sig); - - return sig; -} - -void ssh_signature_free(ssh_signature sig) -{ - if (sig == NULL) { - return; - } - - switch(sig->type) { - case SSH_KEYTYPE_DSS: -#ifdef HAVE_LIBGCRYPT - gcry_sexp_release(sig->dsa_sig); -#elif defined HAVE_LIBCRYPTO - DSA_SIG_free(sig->dsa_sig); -#endif - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: -#ifdef HAVE_LIBGCRYPT - gcry_sexp_release(sig->rsa_sig); -#elif defined HAVE_LIBCRYPTO - SAFE_FREE(sig->rsa_sig); -#endif - break; - case SSH_KEYTYPE_ECDSA: -#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ECC) - ECDSA_SIG_free(sig->ecdsa_sig); -#endif - break; - case SSH_KEYTYPE_ED25519: - SAFE_FREE(sig->ed25519_sig); - break; - case SSH_KEYTYPE_UNKNOWN: - break; - } - - SAFE_FREE(sig); -} - -/** - * @brief import a base64 formated key from a memory c-string - * - * @param[in] b64_key The c-string holding the base64 encoded key - * - * @param[in] passphrase The passphrase to decrypt the key, or NULL - * - * @param[in] auth_fn An auth function you may want to use or NULL. - * - * @param[in] auth_data Private data passed to the auth function. - * - * @param[out] pkey A pointer where the allocated key can be stored. You - * need to free the memory. - * - * @return SSH_ERROR in case of error, SSH_OK otherwise. - * - * @see ssh_key_free() - */ -int ssh_pki_import_privkey_base64(const char *b64_key, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data, - ssh_key *pkey) -{ - ssh_key key; - - if (b64_key == NULL || pkey == NULL) { - return SSH_ERROR; - } - - if (b64_key == NULL || !*b64_key) { - return SSH_ERROR; - } - - ssh_pki_log("Trying to decode privkey passphrase=%s", - passphrase ? "true" : "false"); - - key = pki_private_key_from_base64(b64_key, passphrase, auth_fn, auth_data); - if (key == NULL) { - return SSH_ERROR; - } - - *pkey = key; - - return SSH_OK; -} - -/** - * @brief Import a key from a file. - * - * @param[in] filename The filename of the the private key. - * - * @param[in] passphrase The passphrase to decrypt the private key. Set to NULL - * if none is needed or it is unknown. - * - * @param[in] auth_fn An auth function you may want to use or NULL. - * - * @param[in] auth_data Private data passed to the auth function. - * - * @param[out] pkey A pointer to store the allocated ssh_key. You need to - * free the key. - * - * @returns SSH_OK on success, SSH_EOF if the file doesn't exist or permission - * denied, SSH_ERROR otherwise. - * - * @see ssh_key_free() - **/ -int ssh_pki_import_privkey_file(const char *filename, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data, - ssh_key *pkey) { - struct stat sb; - char *key_buf; - ssh_key key; - FILE *file; - off_t size; - int rc; - - if (pkey == NULL || filename == NULL || *filename == '\0') { - return SSH_ERROR; - } - - file = fopen(filename, "rb"); - if (file == NULL) { - ssh_pki_log("Error opening %s: %s", - filename, strerror(errno)); - return SSH_EOF; - } - - rc = fstat(fileno(file), &sb); - if (rc < 0) { - fclose(file); - ssh_pki_log("Error getting stat of %s: %s", - filename, strerror(errno)); - switch (errno) { - case ENOENT: - case EACCES: - return SSH_EOF; - } - - return SSH_ERROR; - } - - if (sb.st_size > MAX_PRIVKEY_SIZE) { - ssh_pki_log("Private key is bigger than 4M."); - fclose(file); - return SSH_ERROR; - } - - key_buf = malloc(sb.st_size + 1); - if (key_buf == NULL) { - fclose(file); - ssh_pki_log("Out of memory!"); - return SSH_ERROR; - } - - size = fread(key_buf, 1, sb.st_size, file); - fclose(file); - - if (size != sb.st_size) { - SAFE_FREE(key_buf); - ssh_pki_log("Error reading %s: %s", - filename, strerror(errno)); - return SSH_ERROR; - } - key_buf[size] = 0; - - key = pki_private_key_from_base64(key_buf, passphrase, auth_fn, auth_data); - SAFE_FREE(key_buf); - if (key == NULL) { - return SSH_ERROR; - } - - *pkey = key; - return SSH_OK; -} - -/** - * @brief Export a private key to a pam file on disk. - * - * @param[in] privkey The private key to export. - * - * @param[in] passphrase The passphrase to use to encrypt the key with or - * NULL. An empty string means no passphrase. - * - * @param[in] auth_fn An auth function you may want to use or NULL. - * - * @param[in] auth_data Private data passed to the auth function. - * - * @param[in] filename The path where to store the pem file. - * - * @return SSH_OK on success, SSH_ERROR on error. - */ -int ssh_pki_export_privkey_file(const ssh_key privkey, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data, - const char *filename) -{ - ssh_string blob; - FILE *fp; - int rc; - - if (privkey == NULL || !ssh_key_is_private(privkey)) { - return SSH_ERROR; - } - - fp = fopen(filename, "wb"); - if (fp == NULL) { - SSH_LOG(SSH_LOG_FUNCTIONS, "Error opening %s: %s", - filename, strerror(errno)); - return SSH_EOF; - } - - - blob = pki_private_key_to_pem(privkey, - passphrase, - auth_fn, - auth_data); - if (blob == NULL) { - fclose(fp); - return -1; - } - - rc = fwrite(ssh_string_data(blob), ssh_string_len(blob), 1, fp); - ssh_string_free(blob); - if (rc != 1 || ferror(fp)) { - fclose(fp); - unlink(filename); - return SSH_ERROR; - } - fclose(fp); - - return SSH_OK; -} - -/* temporary function to migrate seemlessly to ssh_key */ -ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key) { - ssh_public_key pub; - ssh_key tmp; - - if(key == NULL) { - return NULL; - } - - tmp = ssh_key_dup(key); - if (tmp == NULL) { - return NULL; - } - - pub = malloc(sizeof(struct ssh_public_key_struct)); - if (pub == NULL) { - ssh_key_free(tmp); - return NULL; - } - ZERO_STRUCTP(pub); - - pub->type = tmp->type; - pub->type_c = tmp->type_c; - - pub->dsa_pub = tmp->dsa; - tmp->dsa = NULL; - pub->rsa_pub = tmp->rsa; - tmp->rsa = NULL; - - ssh_key_free(tmp); - - return pub; -} - -ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key) { - ssh_private_key privkey; - - privkey = malloc(sizeof(struct ssh_private_key_struct)); - if (privkey == NULL) { - ssh_key_free(key); - return NULL; - } - - privkey->type = key->type; - privkey->dsa_priv = key->dsa; - privkey->rsa_priv = key->rsa; - - return privkey; -} - -static int pki_import_pubkey_buffer(ssh_buffer buffer, - enum ssh_keytypes_e type, - ssh_key *pkey) { - ssh_key key; - int rc; - - key = ssh_key_new(); - if (key == NULL) { - return SSH_ERROR; - } - - key->type = type; - key->type_c = ssh_key_type_to_char(type); - key->flags = SSH_KEY_FLAG_PUBLIC; - - switch (type) { - case SSH_KEYTYPE_DSS: - { - ssh_string p; - ssh_string q; - ssh_string g; - ssh_string pubkey; - - p = buffer_get_ssh_string(buffer); - if (p == NULL) { - goto fail; - } - q = buffer_get_ssh_string(buffer); - if (q == NULL) { - ssh_string_burn(p); - ssh_string_free(p); - - goto fail; - } - g = buffer_get_ssh_string(buffer); - if (g == NULL) { - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(q); - ssh_string_free(q); - - goto fail; - } - pubkey = buffer_get_ssh_string(buffer); - if (pubkey == NULL) { - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(g); - ssh_string_free(g); - - goto fail; - } - - rc = pki_pubkey_build_dss(key, p, q, g, pubkey); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p)); - ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q)); - ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g)); -#endif - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(g); - ssh_string_free(g); - ssh_string_burn(pubkey); - ssh_string_free(pubkey); - if (rc == SSH_ERROR) { - goto fail; - } - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - { - ssh_string e; - ssh_string n; - - e = buffer_get_ssh_string(buffer); - if (e == NULL) { - goto fail; - } - n = buffer_get_ssh_string(buffer); - if (n == NULL) { - ssh_string_burn(e); - ssh_string_free(e); - - goto fail; - } - - rc = pki_pubkey_build_rsa(key, e, n); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e)); - ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n)); -#endif - ssh_string_burn(e); - ssh_string_free(e); - ssh_string_burn(n); - ssh_string_free(n); - if (rc == SSH_ERROR) { - goto fail; - } - } - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_ECC - { - ssh_string e; - ssh_string i; - int nid; - - i = buffer_get_ssh_string(buffer); - if (i == NULL) { - goto fail; - } - nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i)); - ssh_string_free(i); - if (nid == -1) { - goto fail; - } - - - e = buffer_get_ssh_string(buffer); - if (e == NULL) { - goto fail; - } - - rc = pki_pubkey_build_ecdsa(key, nid, e); - ssh_string_burn(e); - ssh_string_free(e); - if (rc < 0) { - goto fail; - } - - /* Update key type */ - key->type_c = ssh_pki_key_ecdsa_name(key); - } - break; -#endif - case SSH_KEYTYPE_ED25519: - { - ssh_string pubkey = buffer_get_ssh_string(buffer); - if (ssh_string_len(pubkey) != ED25519_PK_LEN) { - ssh_pki_log("Invalid public key length"); - ssh_string_burn(pubkey); - ssh_string_free(pubkey); - goto fail; - } - - key->ed25519_pubkey = malloc(ED25519_PK_LEN); - if (key->ed25519_pubkey == NULL) { - ssh_string_burn(pubkey); - ssh_string_free(pubkey); - goto fail; - } - - memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_PK_LEN); - ssh_string_burn(pubkey); - ssh_string_free(pubkey); - } - break; - case SSH_KEYTYPE_UNKNOWN: - default: - ssh_pki_log("Unknown public key protocol %d", type); - goto fail; - } - - *pkey = key; - return SSH_OK; -fail: - ssh_key_free(key); - - return SSH_ERROR; -} - -/** - * @brief Import a base64 formated public key from a memory c-string. - * - * @param[in] b64_key The base64 key to format. - * - * @param[in] type The type of the key to format. - * - * @param[out] pkey A pointer where the allocated key can be stored. You - * need to free the memory. - * - * @return SSH_OK on success, SSH_ERROR on error. - * - * @see ssh_key_free() - */ -int ssh_pki_import_pubkey_base64(const char *b64_key, - enum ssh_keytypes_e type, - ssh_key *pkey) { - ssh_buffer buffer; - ssh_string type_s; - int rc; - - if (b64_key == NULL || pkey == NULL) { - return SSH_ERROR; - } - - buffer = base64_to_bin(b64_key); - if (buffer == NULL) { - return SSH_ERROR; - } - - type_s = buffer_get_ssh_string(buffer); - if (type_s == NULL) { - ssh_buffer_free(buffer); - return SSH_ERROR; - } - ssh_string_free(type_s); - - rc = pki_import_pubkey_buffer(buffer, type, pkey); - ssh_buffer_free(buffer); - - return rc; -} - -/** - * @internal - * - * @brief Import a public key from a ssh string. - * - * @param[in] key_blob The key blob to import as specified in RFC 4253 section - * 6.6 "Public Key Algorithms". - * - * @param[out] pkey A pointer where the allocated key can be stored. You - * need to free the memory. - * - * @return SSH_OK on success, SSH_ERROR on error. - * - * @see ssh_key_free() - */ -int ssh_pki_import_pubkey_blob(const ssh_string key_blob, - ssh_key *pkey) { - ssh_buffer buffer; - ssh_string type_s = NULL; - enum ssh_keytypes_e type; - int rc; - - if (key_blob == NULL || pkey == NULL) { - return SSH_ERROR; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_pki_log("Out of memory!"); - return SSH_ERROR; - } - - rc = ssh_buffer_add_data(buffer, ssh_string_data(key_blob), - ssh_string_len(key_blob)); - if (rc < 0) { - ssh_pki_log("Out of memory!"); - goto fail; - } - - type_s = buffer_get_ssh_string(buffer); - if (type_s == NULL) { - ssh_pki_log("Out of memory!"); - goto fail; - } - - type = ssh_key_type_from_name(ssh_string_get_char(type_s)); - if (type == SSH_KEYTYPE_UNKNOWN) { - ssh_pki_log("Unknown key type found!"); - goto fail; - } - ssh_string_free(type_s); - - rc = pki_import_pubkey_buffer(buffer, type, pkey); - - ssh_buffer_free(buffer); - - return rc; -fail: - ssh_buffer_free(buffer); - ssh_string_free(type_s); - - return SSH_ERROR; -} - -/** - * @brief Import a public key from the given filename. - * - * @param[in] filename The path to the public key. - * - * @param[out] pkey A pointer to store the allocated public key. You need to - * free the memory. - * - * @returns SSH_OK on success, SSH_EOF if the file doesn't exist or permission - * denied, SSH_ERROR otherwise. - * - * @see ssh_key_free() - */ -int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey) -{ - enum ssh_keytypes_e type; - struct stat sb; - char *key_buf, *p; - const char *q; - FILE *file; - off_t size; - int rc; - - if (pkey == NULL || filename == NULL || *filename == '\0') { - return SSH_ERROR; - } - - file = fopen(filename, "r"); - if (file == NULL) { - ssh_pki_log("Error opening %s: %s", - filename, strerror(errno)); - return SSH_EOF; - } - - rc = fstat(fileno(file), &sb); - if (rc < 0) { - fclose(file); - ssh_pki_log("Error gettint stat of %s: %s", - filename, strerror(errno)); - switch (errno) { - case ENOENT: - case EACCES: - return SSH_EOF; - } - return SSH_ERROR; - } - - if (sb.st_size > MAX_PUBKEY_SIZE) { - fclose(file); - return SSH_ERROR; - } - - key_buf = malloc(sb.st_size + 1); - if (key_buf == NULL) { - fclose(file); - ssh_pki_log("Out of memory!"); - return SSH_ERROR; - } - - size = fread(key_buf, 1, sb.st_size, file); - fclose(file); - - if (size != sb.st_size) { - SAFE_FREE(key_buf); - ssh_pki_log("Error reading %s: %s", - filename, strerror(errno)); - return SSH_ERROR; - } - key_buf[size] = '\0'; - - q = p = key_buf; - while (!isspace((int)*p)) p++; - *p = '\0'; - - type = ssh_key_type_from_name(q); - if (type == SSH_KEYTYPE_UNKNOWN) { - SAFE_FREE(key_buf); - return SSH_ERROR; - } - q = ++p; - while (!isspace((int)*p)) p++; - *p = '\0'; - - rc = ssh_pki_import_pubkey_base64(q, type, pkey); - SAFE_FREE(key_buf); - - return rc; -} - -/** - * @brief Generates a keypair. - * - * @param[in] type Type of key to create - * - * @param[in] parameter Parameter to the creation of key: - * rsa : length of the key in bits (e.g. 1024, 2048, 4096) - * dsa : length of the key in bits (e.g. 1024, 2048, 3072) - * ecdsa : bits of the key (e.g. 256, 384, 512) - * @param[out] pkey A pointer to store the allocated private key. You need - * to free the memory. - * - * @return SSH_OK on success, SSH_ERROR on error. - * - * @warning Generating a key pair may take some time. - */ -int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, - ssh_key *pkey){ - int rc; - ssh_key key = ssh_key_new(); - - if (key == NULL) { - return SSH_ERROR; - } - - key->type = type; - key->type_c = ssh_key_type_to_char(type); - key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; - - switch(type){ - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - rc = pki_key_generate_rsa(key, parameter); - if(rc == SSH_ERROR) - goto error; - break; - case SSH_KEYTYPE_DSS: - rc = pki_key_generate_dss(key, parameter); - if(rc == SSH_ERROR) - goto error; - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_ECC - rc = pki_key_generate_ecdsa(key, parameter); - if (rc == SSH_ERROR) { - goto error; - } - - /* Update key type */ - key->type_c = ssh_pki_key_ecdsa_name(key); - break; -#endif - case SSH_KEYTYPE_ED25519: - rc = pki_key_generate_ed25519(key); - if (rc == SSH_ERROR) { - goto error; - } - break; - case SSH_KEYTYPE_UNKNOWN: - goto error; - } - - *pkey = key; - return SSH_OK; -error: - ssh_key_free(key); - return SSH_ERROR; -} - -/** - * @brief Create a public key from a private key. - * - * @param[in] privkey The private key to get the public key from. - * - * @param[out] pkey A pointer to store the newly allocated public key. You - * NEED to free the key. - * - * @return A public key, NULL on error. - * - * @see ssh_key_free() - */ -int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey, - ssh_key *pkey) -{ - ssh_key pubkey; - - if (privkey == NULL || !ssh_key_is_private(privkey)) { - return SSH_ERROR; - } - - pubkey = pki_key_dup(privkey, 1); - if (pubkey == NULL) { - return SSH_ERROR; - } - - *pkey = pubkey; - return SSH_OK; -} - -/** - * @internal - * - * @brief Create a key_blob from a public key. - * - * The "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key - * Algorithms" for any of the supported protocol 2 key types. - * - * @param[in] key A public or private key to create the public ssh_string - * from. - * - * @param[out] pblob A pointer to store the newly allocated key blob. You - * NEED to free it. - * - * @return SSH_OK on success, SSH_ERROR otherwise. - * - * @see ssh_string_free() - */ -int ssh_pki_export_pubkey_blob(const ssh_key key, - ssh_string *pblob) -{ - ssh_string blob; - - if (key == NULL) { - return SSH_OK; - } - - blob = pki_publickey_to_blob(key); - if (blob == NULL) { - return SSH_ERROR; - } - - *pblob = blob; - return SSH_OK; -} - -/** - * @brief Convert a public key to a base64 encoded key. - * - * @param[in] key The key to hash - * - * @param[out] b64_key A pointer to store the allocated base64 encoded key. You - * need to free the buffer. - * - * @return SSH_OK on success, SSH_ERROR on error. - * - * @see ssh_string_free_char() - */ -int ssh_pki_export_pubkey_base64(const ssh_key key, - char **b64_key) -{ - ssh_string key_blob; - unsigned char *b64; - - if (key == NULL || b64_key == NULL) { - return SSH_ERROR; - } - - key_blob = pki_publickey_to_blob(key); - if (key_blob == NULL) { - return SSH_ERROR; - } - - b64 = bin_to_base64(ssh_string_data(key_blob), ssh_string_len(key_blob)); - ssh_string_free(key_blob); - if (b64 == NULL) { - return SSH_ERROR; - } - - *b64_key = (char *)b64; - - return SSH_OK; -} - -int ssh_pki_export_pubkey_file(const ssh_key key, - const char *filename) -{ - char key_buf[4096]; - char host[256]; - char *b64_key; - char *user; - FILE *fp; - int rc; - - if (key == NULL || filename == NULL || *filename == '\0') { - return SSH_ERROR; - } - - user = ssh_get_local_username(); - if (user == NULL) { - return SSH_ERROR; - } - - rc = gethostname(host, sizeof(host)); - if (rc < 0) { - free(user); - return SSH_ERROR; - } - - rc = ssh_pki_export_pubkey_base64(key, &b64_key); - if (rc < 0) { - free(user); - return SSH_ERROR; - } - - rc = snprintf(key_buf, sizeof(key_buf), - "%s %s %s@%s\n", - key->type_c, - b64_key, - user, - host); - free(user); - free(b64_key); - if (rc < 0) { - return SSH_ERROR; - } - - fp = fopen(filename, "w+"); - if (fp == NULL) { - return SSH_ERROR; - } - rc = fwrite(key_buf, strlen(key_buf), 1, fp); - if (rc != 1 || ferror(fp)) { - fclose(fp); - unlink(filename); - return SSH_ERROR; - } - fclose(fp); - - return SSH_OK; -} - -int ssh_pki_export_pubkey_rsa1(const ssh_key key, - const char *host, - char *rsa1, - size_t rsa1_len) -{ - return pki_export_pubkey_rsa1(key, host, rsa1, rsa1_len); -} - -int ssh_pki_export_signature_blob(const ssh_signature sig, - ssh_string *sig_blob) -{ - ssh_buffer buf = NULL; - ssh_string str; - int rc; - - if (sig == NULL || sig_blob == NULL) { - return SSH_ERROR; - } - - buf = ssh_buffer_new(); - if (buf == NULL) { - return SSH_ERROR; - } - - str = ssh_string_from_char(sig->type_c); - if (str == NULL) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - rc = buffer_add_ssh_string(buf, str); - ssh_string_free(str); - if (rc < 0) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - str = pki_signature_to_blob(sig); - if (str == NULL) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - rc = buffer_add_ssh_string(buf, str); - ssh_string_free(str); - if (rc < 0) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - str = ssh_string_new(buffer_get_rest_len(buf)); - if (str == NULL) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - ssh_string_fill(str, buffer_get_rest(buf), buffer_get_rest_len(buf)); - ssh_buffer_free(buf); - - *sig_blob = str; - - return SSH_OK; -} - -int ssh_pki_import_signature_blob(const ssh_string sig_blob, - const ssh_key pubkey, - ssh_signature *psig) -{ - ssh_signature sig; - enum ssh_keytypes_e type; - ssh_string str; - ssh_buffer buf; - int rc; - - if (sig_blob == NULL || psig == NULL) { - return SSH_ERROR; - } - - buf = ssh_buffer_new(); - if (buf == NULL) { - return SSH_ERROR; - } - - rc = ssh_buffer_add_data(buf, - ssh_string_data(sig_blob), - ssh_string_len(sig_blob)); - if (rc < 0) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - str = buffer_get_ssh_string(buf); - if (str == NULL) { - ssh_buffer_free(buf); - return SSH_ERROR; - } - - type = ssh_key_type_from_name(ssh_string_get_char(str)); - ssh_string_free(str); - - str = buffer_get_ssh_string(buf); - ssh_buffer_free(buf); - if (str == NULL) { - return SSH_ERROR; - } - - sig = pki_signature_from_blob(pubkey, str, type); - ssh_string_free(str); - if (sig == NULL) { - return SSH_ERROR; - } - - *psig = sig; - return SSH_OK; -} - -int ssh_pki_signature_verify_blob(ssh_session session, - ssh_string sig_blob, - const ssh_key key, - unsigned char *digest, - size_t dlen) -{ - ssh_signature sig; - int rc; - - rc = ssh_pki_import_signature_blob(sig_blob, key, &sig); - if (rc < 0) { - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_FUNCTIONS, - "Going to verify a %s type signature", - key->type_c); - - - if (key->type == SSH_KEYTYPE_ECDSA) { -#if HAVE_ECC - unsigned char ehash[EVP_DIGEST_LEN] = {0}; - uint32_t elen; - - evp(key->ecdsa_nid, digest, dlen, ehash, &elen); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash to be verified with ecdsa", - ehash, elen); -#endif - - rc = pki_signature_verify(session, - sig, - key, - ehash, - elen); -#endif - } else if (key->type == SSH_KEYTYPE_ED25519) { - rc = pki_signature_verify(session, sig, key, digest, dlen); - } else { - unsigned char hash[SHA_DIGEST_LEN] = {0}; - - sha1(digest, dlen, hash); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash to be verified with dsa", hash, SHA_DIGEST_LEN); -#endif - - rc = pki_signature_verify(session, - sig, - key, - hash, - SHA_DIGEST_LEN); - } - - ssh_signature_free(sig); - - return rc; -} - -/* - * This function signs the session id as a string then - * the content of sigbuf */ -ssh_string ssh_pki_do_sign(ssh_session session, - ssh_buffer sigbuf, - const ssh_key privkey) { - struct ssh_crypto_struct *crypto = - session->current_crypto ? session->current_crypto : - session->next_crypto; - ssh_signature sig; - ssh_string sig_blob; - ssh_string session_id; - int rc; - - if (privkey == NULL || !ssh_key_is_private(privkey)) { - return NULL; - } - - session_id = ssh_string_new(crypto->digest_len); - if (session_id == NULL) { - return NULL; - } - ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); - - if (privkey->type == SSH_KEYTYPE_ECDSA) { -#ifdef HAVE_ECC - unsigned char ehash[EVP_DIGEST_LEN] = {0}; - uint32_t elen; - EVPCTX ctx; - - ctx = evp_init(privkey->ecdsa_nid); - if (ctx == NULL) { - ssh_string_free(session_id); - return NULL; - } - - evp_update(ctx, session_id, ssh_string_len(session_id) + 4); - evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); - evp_final(ctx, ehash, &elen); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed", ehash, elen); -#endif - - sig = pki_do_sign(privkey, ehash, elen); -#endif - } else if (privkey->type == SSH_KEYTYPE_ED25519){ - ssh_buffer buf; - - buf = ssh_buffer_new(); - if (buf == NULL) { - ssh_string_free(session_id); - return NULL; - } - - ssh_buffer_set_secure(buf); - rc = ssh_buffer_pack(buf, - "SP", - session_id, - buffer_get_rest_len(sigbuf), buffer_get_rest(sigbuf)); - if (rc != SSH_OK) { - ssh_string_free(session_id); - ssh_buffer_free(buf); - return NULL; - } - - sig = pki_do_sign(privkey, - ssh_buffer_get_begin(buf), - ssh_buffer_get_len(buf)); - ssh_buffer_free(buf); - } else { - unsigned char hash[SHA_DIGEST_LEN] = {0}; - SHACTX ctx; - - ctx = sha1_init(); - if (ctx == NULL) { - ssh_string_free(session_id); - return NULL; - } - - sha1_update(ctx, session_id, ssh_string_len(session_id) + 4); - sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); - sha1_final(hash, ctx); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); -#endif - - sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN); - } - ssh_string_free(session_id); - if (sig == NULL) { - return NULL; - } - - rc = ssh_pki_export_signature_blob(sig, &sig_blob); - ssh_signature_free(sig); - if (rc < 0) { - return NULL; - } - - return sig_blob; -} - -#ifndef _WIN32 -ssh_string ssh_pki_do_sign_agent(ssh_session session, - struct ssh_buffer_struct *buf, - const ssh_key pubkey) { - struct ssh_crypto_struct *crypto; - ssh_string session_id; - ssh_string sig_blob; - ssh_buffer sig_buf; - int rc; - - if (session->current_crypto) { - crypto = session->current_crypto; - } else { - crypto = session->next_crypto; - } - - /* prepend session identifier */ - session_id = ssh_string_new(crypto->digest_len); - if (session_id == NULL) { - return NULL; - } - ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); - - sig_buf = ssh_buffer_new(); - if (sig_buf == NULL) { - ssh_string_free(session_id); - return NULL; - } - - rc = buffer_add_ssh_string(sig_buf, session_id); - if (rc < 0) { - ssh_string_free(session_id); - ssh_buffer_free(sig_buf); - return NULL; - } - ssh_string_free(session_id); - - /* append out buffer */ - if (buffer_add_buffer(sig_buf, buf) < 0) { - ssh_buffer_free(sig_buf); - return NULL; - } - - /* create signature */ - sig_blob = ssh_agent_sign_data(session, pubkey, sig_buf); - - ssh_buffer_free(sig_buf); - - return sig_blob; -} -#endif /* _WIN32 */ - -#ifdef WITH_SERVER -ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, - const ssh_key privkey) -{ - struct ssh_crypto_struct *crypto; - ssh_signature sig; - ssh_string sig_blob; - int rc; - - if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) { - return NULL; - } - crypto = session->next_crypto ? session->next_crypto : - session->current_crypto; - - if (crypto->secret_hash == NULL){ - ssh_set_error(session,SSH_FATAL,"Missing secret_hash"); - return NULL; - } - - if (privkey->type == SSH_KEYTYPE_ECDSA) { -#ifdef HAVE_ECC - unsigned char ehash[EVP_DIGEST_LEN] = {0}; - uint32_t elen; - - evp(privkey->ecdsa_nid, crypto->secret_hash, crypto->digest_len, - ehash, &elen); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed", ehash, elen); -#endif - - sig = pki_do_sign_sessionid(privkey, ehash, elen); - if (sig == NULL) { - return NULL; - } -#endif - } else if (privkey->type == SSH_KEYTYPE_ED25519) { - sig = ssh_signature_new(); - if (sig == NULL){ - return NULL; - } - - sig->type = privkey->type; - sig->type_c = privkey->type_c; - - rc = pki_ed25519_sign(privkey, - sig, - crypto->secret_hash, - crypto->digest_len); - if (rc != SSH_OK){ - ssh_signature_free(sig); - sig = NULL; - } - } else { - unsigned char hash[SHA_DIGEST_LEN] = {0}; - SHACTX ctx; - - ctx = sha1_init(); - if (ctx == NULL) { - return NULL; - } - sha1_update(ctx, crypto->secret_hash, crypto->digest_len); - sha1_final(hash, ctx); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); -#endif - - sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN); - if (sig == NULL) { - return NULL; - } - } - - rc = ssh_pki_export_signature_blob(sig, &sig_blob); - ssh_signature_free(sig); - if (rc < 0) { - return NULL; - } - - return sig_blob; -} -#endif /* WITH_SERVER */ - -/** - * @} - */ diff --git a/libssh/src/pki_crypto.c b/libssh/src/pki_crypto.c deleted file mode 100644 index 5706fdf0..00000000 --- a/libssh/src/pki_crypto.c +++ /dev/null @@ -1,1671 +0,0 @@ -/* - * pki_crypto.c - PKI infrastructure using OpenSSL - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2009 by Aris Adamantiadis - * Copyright (c) 2009-2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef _PKI_CRYPTO_H -#define _PKI_CRYPTO_H - -#include "libssh/priv.h" - -#include -#include -#include -#include - -#ifdef HAVE_OPENSSL_EC_H -#include -#endif -#ifdef HAVE_OPENSSL_ECDSA_H -#include -#endif - -#include "libssh/libssh.h" -#include "libssh/buffer.h" -#include "libssh/session.h" -#include "libssh/pki.h" -#include "libssh/pki_priv.h" -#include "libssh/bignum.h" - -struct pem_get_password_struct { - ssh_auth_callback fn; - void *data; -}; - -static int pem_get_password(char *buf, int size, int rwflag, void *userdata) { - struct pem_get_password_struct *pgp = userdata; - - (void) rwflag; /* unused */ - - if (buf == NULL) { - return 0; - } - - memset(buf, '\0', size); - if (pgp) { - int rc; - - rc = pgp->fn("Passphrase for private key:", - buf, size, 0, 0, - pgp->data); - if (rc == 0) { - return strlen(buf); - } - } - - return 0; -} - -#ifdef HAVE_OPENSSL_ECC -static int pki_key_ecdsa_to_nid(EC_KEY *k) -{ - const EC_GROUP *g = EC_KEY_get0_group(k); - int nid; - - nid = EC_GROUP_get_curve_name(g); - if (nid) { - return nid; - } - - return -1; -} - -const char *pki_key_ecdsa_nid_to_name(int nid) -{ - switch (nid) { - case NID_X9_62_prime256v1: - return "ecdsa-sha2-nistp256"; - case NID_secp384r1: - return "ecdsa-sha2-nistp384"; - case NID_secp521r1: - return "ecdsa-sha2-nistp521"; - default: - break; - } - - return "unknown"; -} - -static const char *pki_key_ecdsa_nid_to_char(int nid) -{ - switch (nid) { - case NID_X9_62_prime256v1: - return "nistp256"; - case NID_secp384r1: - return "nistp384"; - case NID_secp521r1: - return "nistp521"; - default: - break; - } - - return "unknown"; -} - -int pki_key_ecdsa_nid_from_name(const char *name) -{ - if (strcmp(name, "nistp256") == 0) { - return NID_X9_62_prime256v1; - } else if (strcmp(name, "nistp384") == 0) { - return NID_secp384r1; - } else if (strcmp(name, "nistp521") == 0) { - return NID_secp521r1; - } - - return -1; -} - -static ssh_string make_ecpoint_string(const EC_GROUP *g, - const EC_POINT *p) -{ - ssh_string s; - size_t len; - - len = EC_POINT_point2oct(g, - p, - POINT_CONVERSION_UNCOMPRESSED, - NULL, - 0, - NULL); - if (len == 0) { - return NULL; - } - - s = ssh_string_new(len); - if (s == NULL) { - return NULL; - } - - len = EC_POINT_point2oct(g, - p, - POINT_CONVERSION_UNCOMPRESSED, - ssh_string_data(s), - ssh_string_len(s), - NULL); - if (len != ssh_string_len(s)) { - ssh_string_free(s); - return NULL; - } - - return s; -} - -int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e) -{ - EC_POINT *p; - const EC_GROUP *g; - int ok; - - key->ecdsa_nid = nid; - key->type_c = pki_key_ecdsa_nid_to_name(nid); - - key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid); - if (key->ecdsa == NULL) { - return -1; - } - - g = EC_KEY_get0_group(key->ecdsa); - - p = EC_POINT_new(g); - if (p == NULL) { - return -1; - } - - ok = EC_POINT_oct2point(g, - p, - ssh_string_data(e), - ssh_string_len(e), - NULL); - if (!ok) { - EC_POINT_free(p); - return -1; - } - - /* EC_KEY_set_public_key duplicates p */ - ok = EC_KEY_set_public_key(key->ecdsa, p); - EC_POINT_free(p); - if (!ok) { - return -1; - } - - return 0; -} -#endif - -ssh_key pki_key_dup(const ssh_key key, int demote) -{ - ssh_key new; - int rc; - - new = ssh_key_new(); - if (new == NULL) { - return NULL; - } - - new->type = key->type; - new->type_c = key->type_c; - if (demote) { - new->flags = SSH_KEY_FLAG_PUBLIC; - } else { - new->flags = key->flags; - } - - switch (key->type) { - case SSH_KEYTYPE_DSS: - new->dsa = DSA_new(); - if (new->dsa == NULL) { - goto fail; - } - - /* - * p = public prime number - * q = public 160-bit subprime, q | p-1 - * g = public generator of subgroup - * pub_key = public key y = g^x - * priv_key = private key x - */ - new->dsa->p = BN_dup(key->dsa->p); - if (new->dsa->p == NULL) { - goto fail; - } - - new->dsa->q = BN_dup(key->dsa->q); - if (new->dsa->q == NULL) { - goto fail; - } - - new->dsa->g = BN_dup(key->dsa->g); - if (new->dsa->g == NULL) { - goto fail; - } - - new->dsa->pub_key = BN_dup(key->dsa->pub_key); - if (new->dsa->pub_key == NULL) { - goto fail; - } - - if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { - new->dsa->priv_key = BN_dup(key->dsa->priv_key); - if (new->dsa->priv_key == NULL) { - goto fail; - } - } - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - new->rsa = RSA_new(); - if (new->rsa == NULL) { - goto fail; - } - - /* - * n = public modulus - * e = public exponent - * d = private exponent - * p = secret prime factor - * q = secret prime factor - * dmp1 = d mod (p-1) - * dmq1 = d mod (q-1) - * iqmp = q^-1 mod p - */ - new->rsa->n = BN_dup(key->rsa->n); - if (new->rsa->n == NULL) { - goto fail; - } - - new->rsa->e = BN_dup(key->rsa->e); - if (new->rsa->e == NULL) { - goto fail; - } - - if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { - new->rsa->d = BN_dup(key->rsa->d); - if (new->rsa->d == NULL) { - goto fail; - } - - /* p, q, dmp1, dmq1 and iqmp may be NULL in private keys, but the - * RSA operations are much faster when these values are available. - */ - if (key->rsa->p != NULL) { - new->rsa->p = BN_dup(key->rsa->p); - if (new->rsa->p == NULL) { - goto fail; - } - } - - if (key->rsa->q != NULL) { - new->rsa->q = BN_dup(key->rsa->q); - if (new->rsa->q == NULL) { - goto fail; - } - } - - if (key->rsa->dmp1 != NULL) { - new->rsa->dmp1 = BN_dup(key->rsa->dmp1); - if (new->rsa->dmp1 == NULL) { - goto fail; - } - } - - if (key->rsa->dmq1 != NULL) { - new->rsa->dmq1 = BN_dup(key->rsa->dmq1); - if (new->rsa->dmq1 == NULL) { - goto fail; - } - } - - if (key->rsa->iqmp != NULL) { - new->rsa->iqmp = BN_dup(key->rsa->iqmp); - if (new->rsa->iqmp == NULL) { - goto fail; - } - } - } - - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - new->ecdsa_nid = key->ecdsa_nid; - - /* privkey -> pubkey */ - if (demote && ssh_key_is_private(key)) { - const EC_POINT *p; - int ok; - - new->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid); - if (new->ecdsa == NULL) { - goto fail; - } - - p = EC_KEY_get0_public_key(key->ecdsa); - if (p == NULL) { - goto fail; - } - - ok = EC_KEY_set_public_key(new->ecdsa, p); - if (!ok) { - goto fail; - } - } else { - new->ecdsa = EC_KEY_dup(key->ecdsa); - } - break; -#endif - case SSH_KEYTYPE_ED25519: - rc = pki_ed25519_key_dup(new, key); - if (rc != SSH_OK) { - goto fail; - } - break; - case SSH_KEYTYPE_UNKNOWN: - default: - ssh_key_free(new); - return NULL; - } - - return new; -fail: - ssh_key_free(new); - return NULL; -} - -int pki_key_generate_rsa(ssh_key key, int parameter){ - BIGNUM *e; - int rc; - - e = BN_new(); - key->rsa = RSA_new(); - - BN_set_word(e, 65537); - rc = RSA_generate_key_ex(key->rsa, parameter, e, NULL); - - BN_free(e); - - if (rc == -1 || key->rsa == NULL) - return SSH_ERROR; - return SSH_OK; -} - -int pki_key_generate_dss(ssh_key key, int parameter){ - int rc; - key->dsa = DSA_generate_parameters(parameter, NULL, 0, NULL, NULL, - NULL, NULL); - if(key->dsa == NULL){ - return SSH_ERROR; - } - rc = DSA_generate_key(key->dsa); - if (rc != 1){ - DSA_free(key->dsa); - key->dsa=NULL; - return SSH_ERROR; - } - return SSH_OK; -} - -#ifdef HAVE_OPENSSL_ECC -int pki_key_generate_ecdsa(ssh_key key, int parameter) { - int nid; - int ok; - - switch (parameter) { - case 384: - nid = NID_secp384r1; - break; - case 512: - nid = NID_secp521r1; - break; - case 256: - default: - nid = NID_X9_62_prime256v1; - } - - key->ecdsa_nid = nid; - key->type = SSH_KEYTYPE_ECDSA; - key->type_c = pki_key_ecdsa_nid_to_name(nid); - - key->ecdsa = EC_KEY_new_by_curve_name(nid); - if (key->ecdsa == NULL) { - return SSH_ERROR; - } - - ok = EC_KEY_generate_key(key->ecdsa); - if (!ok) { - EC_KEY_free(key->ecdsa); - return SSH_ERROR; - } - - EC_KEY_set_asn1_flag(key->ecdsa, OPENSSL_EC_NAMED_CURVE); - - return SSH_OK; -} -#endif - -int pki_key_compare(const ssh_key k1, - const ssh_key k2, - enum ssh_keycmp_e what) -{ - switch (k1->type) { - case SSH_KEYTYPE_DSS: - if (DSA_size(k1->dsa) != DSA_size(k2->dsa)) { - return 1; - } - if (bignum_cmp(k1->dsa->p, k2->dsa->p) != 0) { - return 1; - } - if (bignum_cmp(k1->dsa->q, k2->dsa->q) != 0) { - return 1; - } - if (bignum_cmp(k1->dsa->g, k2->dsa->g) != 0) { - return 1; - } - if (bignum_cmp(k1->dsa->pub_key, k2->dsa->pub_key) != 0) { - return 1; - } - - if (what == SSH_KEY_CMP_PRIVATE) { - if (bignum_cmp(k1->dsa->priv_key, k2->dsa->priv_key) != 0) { - return 1; - } - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - if (RSA_size(k1->rsa) != RSA_size(k2->rsa)) { - return 1; - } - if (bignum_cmp(k1->rsa->e, k2->rsa->e) != 0) { - return 1; - } - if (bignum_cmp(k1->rsa->n, k2->rsa->n) != 0) { - return 1; - } - - if (what == SSH_KEY_CMP_PRIVATE) { - if (bignum_cmp(k1->rsa->p, k2->rsa->p) != 0) { - return 1; - } - - if (bignum_cmp(k1->rsa->q, k2->rsa->q) != 0) { - return 1; - } - } - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - { - const EC_POINT *p1 = EC_KEY_get0_public_key(k1->ecdsa); - const EC_POINT *p2 = EC_KEY_get0_public_key(k2->ecdsa); - const EC_GROUP *g1 = EC_KEY_get0_group(k1->ecdsa); - const EC_GROUP *g2 = EC_KEY_get0_group(k2->ecdsa); - - if (p1 == NULL || p2 == NULL) { - return 1; - } - - if (EC_GROUP_cmp(g1, g2, NULL) != 0) { - return 1; - } - - if (EC_POINT_cmp(g1, p1, p2, NULL) != 0) { - return 1; - } - - if (what == SSH_KEY_CMP_PRIVATE) { - if (bignum_cmp(EC_KEY_get0_private_key(k1->ecdsa), - EC_KEY_get0_private_key(k2->ecdsa))) { - return 1; - } - } - - break; - } -#endif - case SSH_KEYTYPE_ED25519: - /* ed25519 keys handled globaly */ - case SSH_KEYTYPE_UNKNOWN: - default: - return 1; - } - - return 0; -} - -ssh_string pki_private_key_to_pem(const ssh_key key, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data) -{ - ssh_string blob; - BUF_MEM *buf; - BIO *mem; - int rc; - - /* needed for openssl initialization */ - if (ssh_init() < 0) { - return NULL; - } - - mem = BIO_new(BIO_s_mem()); - if (mem == NULL) { - return NULL; - } - - switch (key->type) { - case SSH_KEYTYPE_DSS: - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rc = PEM_write_bio_DSAPrivateKey(mem, - key->dsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - pem_get_password, - &pgp); - } else { - rc = PEM_write_bio_DSAPrivateKey(mem, - key->dsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ - (void*) passphrase); - } - if (rc != 1) { - goto err; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rc = PEM_write_bio_RSAPrivateKey(mem, - key->rsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - pem_get_password, - &pgp); - } else { - rc = PEM_write_bio_RSAPrivateKey(mem, - key->rsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ - (void*) passphrase); - } - if (rc != 1) { - goto err; - } - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_ECC - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rc = PEM_write_bio_ECPrivateKey(mem, - key->ecdsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - pem_get_password, - &pgp); - } else { - rc = PEM_write_bio_ECPrivateKey(mem, - key->ecdsa, - NULL, /* cipher */ - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ - (void*) passphrase); - } - if (rc != 1) { - goto err; - } - break; -#endif - case SSH_KEYTYPE_ED25519: - case SSH_KEYTYPE_UNKNOWN: - BIO_free(mem); - ssh_pki_log("Unkown or invalid private key type %d", key->type); - return NULL; - } - - BIO_get_mem_ptr(mem, &buf); - - blob = ssh_string_new(buf->length); - if (blob == NULL) { - goto err; - } - - ssh_string_fill(blob, buf->data, buf->length); - BIO_free(mem); - - return blob; -err: - BIO_free(mem); - return NULL; -} - -ssh_key pki_private_key_from_base64(const char *b64_key, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data) { - BIO *mem = NULL; - DSA *dsa = NULL; - RSA *rsa = NULL; - ssh_key key; - enum ssh_keytypes_e type; -#ifdef HAVE_OPENSSL_ECC - EC_KEY *ecdsa = NULL; -#else - void *ecdsa = NULL; -#endif - - /* needed for openssl initialization */ - if (ssh_init() < 0) { - return NULL; - } - - type = pki_privatekey_type_from_string(b64_key); - if (type == SSH_KEYTYPE_UNKNOWN) { - ssh_pki_log("Unknown or invalid private key."); - return NULL; - } - - mem = BIO_new_mem_buf((void*)b64_key, -1); - - switch (type) { - case SSH_KEYTYPE_DSS: - if (passphrase == NULL) { - if (auth_fn) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, pem_get_password, &pgp); - } else { - /* openssl uses its own callback to get the passphrase here */ - dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL); - } - } else { - dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase); - } - - BIO_free(mem); - - if (dsa == NULL) { - ssh_pki_log("Parsing private key: %s", - ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - if (passphrase == NULL) { - if (auth_fn) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, pem_get_password, &pgp); - } else { - /* openssl uses its own callback to get the passphrase here */ - rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL); - } - } else { - rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, (void *) passphrase); - } - - BIO_free(mem); - - if (rsa == NULL) { - ssh_pki_log("Parsing private key: %s", - ERR_error_string(ERR_get_error(),NULL)); - return NULL; - } - - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - if (passphrase == NULL) { - if (auth_fn) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - - ecdsa = PEM_read_bio_ECPrivateKey(mem, NULL, pem_get_password, &pgp); - } else { - /* openssl uses its own callback to get the passphrase here */ - ecdsa = PEM_read_bio_ECPrivateKey(mem, NULL, NULL, NULL); - } - } else { - ecdsa = PEM_read_bio_ECPrivateKey(mem, NULL, NULL, (void *) passphrase); - } - - BIO_free(mem); - - if (ecdsa == NULL) { - ssh_pki_log("Parsing private key: %s", - ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - break; -#endif - case SSH_KEYTYPE_ED25519: - case SSH_KEYTYPE_UNKNOWN: - BIO_free(mem); - ssh_pki_log("Unkown or invalid private key type %d", type); - return NULL; - } - - key = ssh_key_new(); - if (key == NULL) { - goto fail; - } - - key->type = type; - key->type_c = ssh_key_type_to_char(type); - key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; - key->dsa = dsa; - key->rsa = rsa; - key->ecdsa = ecdsa; -#ifdef HAVE_OPENSSL_ECC - if (key->type == SSH_KEYTYPE_ECDSA) { - key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa); - key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid); - } -#endif - - return key; -fail: - ssh_key_free(key); - DSA_free(dsa); - RSA_free(rsa); -#ifdef HAVE_OPENSSL_ECC - EC_KEY_free(ecdsa); -#endif - - return NULL; -} - -int pki_pubkey_build_dss(ssh_key key, - ssh_string p, - ssh_string q, - ssh_string g, - ssh_string pubkey) { - key->dsa = DSA_new(); - if (key->dsa == NULL) { - return SSH_ERROR; - } - - key->dsa->p = make_string_bn(p); - key->dsa->q = make_string_bn(q); - key->dsa->g = make_string_bn(g); - key->dsa->pub_key = make_string_bn(pubkey); - if (key->dsa->p == NULL || - key->dsa->q == NULL || - key->dsa->g == NULL || - key->dsa->pub_key == NULL) { - DSA_free(key->dsa); - return SSH_ERROR; - } - - return SSH_OK; -} - -int pki_pubkey_build_rsa(ssh_key key, - ssh_string e, - ssh_string n) { - key->rsa = RSA_new(); - if (key->rsa == NULL) { - return SSH_ERROR; - } - - key->rsa->e = make_string_bn(e); - key->rsa->n = make_string_bn(n); - if (key->rsa->e == NULL || - key->rsa->n == NULL) { - RSA_free(key->rsa); - return SSH_ERROR; - } - - return SSH_OK; -} - -ssh_string pki_publickey_to_blob(const ssh_key key) -{ - ssh_buffer buffer; - ssh_string type_s; - ssh_string str = NULL; - ssh_string e = NULL; - ssh_string n = NULL; - ssh_string p = NULL; - ssh_string g = NULL; - ssh_string q = NULL; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - return NULL; - } - - type_s = ssh_string_from_char(key->type_c); - if (type_s == NULL) { - ssh_buffer_free(buffer); - return NULL; - } - - rc = buffer_add_ssh_string(buffer, type_s); - ssh_string_free(type_s); - if (rc < 0) { - ssh_buffer_free(buffer); - return NULL; - } - - switch (key->type) { - case SSH_KEYTYPE_DSS: - p = make_bignum_string(key->dsa->p); - if (p == NULL) { - goto fail; - } - - q = make_bignum_string(key->dsa->q); - if (q == NULL) { - goto fail; - } - - g = make_bignum_string(key->dsa->g); - if (g == NULL) { - goto fail; - } - - n = make_bignum_string(key->dsa->pub_key); - if (n == NULL) { - goto fail; - } - - if (buffer_add_ssh_string(buffer, p) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, q) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, g) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, n) < 0) { - goto fail; - } - - ssh_string_burn(p); - ssh_string_free(p); - p = NULL; - ssh_string_burn(g); - ssh_string_free(g); - g = NULL; - ssh_string_burn(q); - ssh_string_free(q); - q = NULL; - ssh_string_burn(n); - ssh_string_free(n); - n = NULL; - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - e = make_bignum_string(key->rsa->e); - if (e == NULL) { - goto fail; - } - - n = make_bignum_string(key->rsa->n); - if (n == NULL) { - goto fail; - } - - if (buffer_add_ssh_string(buffer, e) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, n) < 0) { - goto fail; - } - - ssh_string_burn(e); - ssh_string_free(e); - e = NULL; - ssh_string_burn(n); - ssh_string_free(n); - n = NULL; - - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - rc = ssh_buffer_reinit(buffer); - if (rc < 0) { - ssh_buffer_free(buffer); - return NULL; - } - - type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_name(key->ecdsa_nid)); - if (type_s == NULL) { - ssh_buffer_free(buffer); - return NULL; - } - - rc = buffer_add_ssh_string(buffer, type_s); - ssh_string_free(type_s); - if (rc < 0) { - ssh_buffer_free(buffer); - return NULL; - } - - type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid)); - if (type_s == NULL) { - ssh_buffer_free(buffer); - return NULL; - } - - rc = buffer_add_ssh_string(buffer, type_s); - ssh_string_free(type_s); - if (rc < 0) { - ssh_buffer_free(buffer); - return NULL; - } - - e = make_ecpoint_string(EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)); - if (e == NULL) { - ssh_buffer_free(buffer); - return NULL; - } - - rc = buffer_add_ssh_string(buffer, e); - if (rc < 0) { - goto fail; - } - - ssh_string_burn(e); - ssh_string_free(e); - e = NULL; - - break; -#endif - case SSH_KEYTYPE_ED25519: - rc = pki_ed25519_public_key_to_blob(buffer, key); - if (rc == SSH_ERROR){ - goto fail; - } - break; - case SSH_KEYTYPE_UNKNOWN: - default: - goto fail; - } - - str = ssh_string_new(buffer_get_rest_len(buffer)); - if (str == NULL) { - goto fail; - } - - rc = ssh_string_fill(str, buffer_get_rest(buffer), buffer_get_rest_len(buffer)); - if (rc < 0) { - goto fail; - } - ssh_buffer_free(buffer); - - return str; -fail: - ssh_buffer_free(buffer); - ssh_string_burn(str); - ssh_string_free(str); - ssh_string_burn(e); - ssh_string_free(e); - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(g); - ssh_string_free(g); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(n); - ssh_string_free(n); - - return NULL; -} - -int pki_export_pubkey_rsa1(const ssh_key key, - const char *host, - char *rsa1, - size_t rsa1_len) -{ - char *e; - char *n; - int rsa_size = RSA_size(key->rsa); - - e = bignum_bn2dec(key->rsa->e); - if (e == NULL) { - return SSH_ERROR; - } - - n = bignum_bn2dec(key->rsa->n); - if (n == NULL) { - OPENSSL_free(e); - return SSH_ERROR; - } - - snprintf(rsa1, rsa1_len, - "%s %d %s %s\n", - host, rsa_size << 3, e, n); - OPENSSL_free(e); - OPENSSL_free(n); - - return SSH_OK; -} - -/** - * @internal - * - * @brief Compute a digital signature. - * - * @param[in] digest The message digest. - * - * @param[in] dlen The length of the digest. - * - * @param[in] privkey The private rsa key to use for signing. - * - * @return A newly allocated rsa sig blob or NULL on error. - */ -static ssh_string _RSA_do_sign(const unsigned char *digest, - int dlen, - RSA *privkey) -{ - ssh_string sig_blob; - unsigned char *sig; - unsigned int slen; - int ok; - - sig = malloc(RSA_size(privkey)); - if (sig == NULL) { - return NULL; - } - - ok = RSA_sign(NID_sha1, digest, dlen, sig, &slen, privkey); - if (!ok) { - SAFE_FREE(sig); - return NULL; - } - - sig_blob = ssh_string_new(slen); - if (sig_blob == NULL) { - SAFE_FREE(sig); - return NULL; - } - - ssh_string_fill(sig_blob, sig, slen); - memset(sig, 'd', slen); - SAFE_FREE(sig); - - return sig_blob; -} - -static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig) -{ - char buffer[40] = { 0 }; - ssh_string sig_blob = NULL; - - ssh_string r; - int r_len, r_offset_in, r_offset_out; - - ssh_string s; - int s_len, s_offset_in, s_offset_out; - - r = make_bignum_string(sig->dsa_sig->r); - if (r == NULL) { - return NULL; - } - - s = make_bignum_string(sig->dsa_sig->s); - if (s == NULL) { - ssh_string_free(r); - return NULL; - } - - r_len = ssh_string_len(r); - r_offset_in = (r_len > 20) ? (r_len - 20) : 0; - r_offset_out = (r_len < 20) ? (20 - r_len) : 0; - - s_len = ssh_string_len(s); - s_offset_in = (s_len > 20) ? (s_len - 20) : 0; - s_offset_out = (s_len < 20) ? (20 - s_len) : 0; - - memcpy(buffer + r_offset_out, - ((char *)ssh_string_data(r)) + r_offset_in, - r_len - r_offset_in); - memcpy(buffer + 20 + s_offset_out, - ((char *)ssh_string_data(s)) + s_offset_in, - s_len - s_offset_in); - - ssh_string_free(r); - ssh_string_free(s); - - sig_blob = ssh_string_new(40); - if (sig_blob == NULL) { - return NULL; - } - - ssh_string_fill(sig_blob, buffer, 40); - - return sig_blob; -} - -ssh_string pki_signature_to_blob(const ssh_signature sig) -{ - ssh_string sig_blob = NULL; - - switch(sig->type) { - case SSH_KEYTYPE_DSS: - sig_blob = pki_dsa_signature_to_blob(sig); - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sig_blob = ssh_string_copy(sig->rsa_sig); - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - { - ssh_string r; - ssh_string s; - ssh_buffer b; - int rc; - - b = ssh_buffer_new(); - if (b == NULL) { - return NULL; - } - - r = make_bignum_string(sig->ecdsa_sig->r); - if (r == NULL) { - ssh_buffer_free(b); - return NULL; - } - rc = buffer_add_ssh_string(b, r); - ssh_string_free(r); - if (rc < 0) { - ssh_buffer_free(b); - return NULL; - } - - s = make_bignum_string(sig->ecdsa_sig->s); - if (s == NULL) { - ssh_buffer_free(b); - return NULL; - } - rc = buffer_add_ssh_string(b, s); - ssh_string_free(s); - if (rc < 0) { - ssh_buffer_free(b); - return NULL; - } - - sig_blob = ssh_string_new(buffer_get_rest_len(b)); - if (sig_blob == NULL) { - ssh_buffer_free(b); - return NULL; - } - - ssh_string_fill(sig_blob, buffer_get_rest(b), buffer_get_rest_len(b)); - ssh_buffer_free(b); - break; - } -#endif - case SSH_KEYTYPE_ED25519: - sig_blob = pki_ed25519_sig_to_blob(sig); - break; - default: - case SSH_KEYTYPE_UNKNOWN: - ssh_pki_log("Unknown signature key type: %s", sig->type_c); - return NULL; - } - - return sig_blob; -} - -static ssh_signature pki_signature_from_rsa_blob(const ssh_key pubkey, - const ssh_string sig_blob, - ssh_signature sig) -{ - uint32_t pad_len = 0; - char *blob_orig; - char *blob_padded_data; - ssh_string sig_blob_padded; - - size_t rsalen = 0; - size_t len = ssh_string_len(sig_blob); - - if (pubkey->rsa == NULL) { - ssh_pki_log("Pubkey RSA field NULL"); - goto errout; - } - - rsalen = RSA_size(pubkey->rsa); - if (len > rsalen) { - ssh_pki_log("Signature is too big: %lu > %lu", - (unsigned long)len, (unsigned long)rsalen); - goto errout; - } - -#ifdef DEBUG_CRYPTO - ssh_pki_log("RSA signature len: %lu", (unsigned long)len); - ssh_print_hexa("RSA signature", ssh_string_data(sig_blob), len); -#endif - - if (len == rsalen) { - sig->rsa_sig = ssh_string_copy(sig_blob); - } else { - /* pad the blob to the expected rsalen size */ - ssh_pki_log("RSA signature len %lu < %lu", - (unsigned long)len, (unsigned long)rsalen); - - pad_len = rsalen - len; - - sig_blob_padded = ssh_string_new(rsalen); - if (sig_blob_padded == NULL) { - goto errout; - } - - blob_padded_data = (char *) ssh_string_data(sig_blob_padded); - blob_orig = (char *) ssh_string_data(sig_blob); - - /* front-pad the buffer with zeroes */ - BURN_BUFFER(blob_padded_data, pad_len); - /* fill the rest with the actual signature blob */ - memcpy(blob_padded_data + pad_len, blob_orig, len); - - sig->rsa_sig = sig_blob_padded; - } - - return sig; - -errout: - ssh_signature_free(sig); - return NULL; -} - -ssh_signature pki_signature_from_blob(const ssh_key pubkey, - const ssh_string sig_blob, - enum ssh_keytypes_e type) -{ - ssh_signature sig; - ssh_string r; - ssh_string s; - size_t len; - int rc; - - sig = ssh_signature_new(); - if (sig == NULL) { - return NULL; - } - - sig->type = type; - sig->type_c = ssh_key_type_to_char(type); - - len = ssh_string_len(sig_blob); - - switch(type) { - case SSH_KEYTYPE_DSS: - /* 40 is the dual signature blob len. */ - if (len != 40) { - ssh_pki_log("Signature has wrong size: %lu", - (unsigned long)len); - ssh_signature_free(sig); - return NULL; - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("r", ssh_string_data(sig_blob), 20); - ssh_print_hexa("s", (unsigned char *)ssh_string_data(sig_blob) + 20, 20); -#endif - - sig->dsa_sig = DSA_SIG_new(); - if (sig->dsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - - r = ssh_string_new(20); - if (r == NULL) { - ssh_signature_free(sig); - return NULL; - } - ssh_string_fill(r, ssh_string_data(sig_blob), 20); - - sig->dsa_sig->r = make_string_bn(r); - ssh_string_free(r); - if (sig->dsa_sig->r == NULL) { - ssh_signature_free(sig); - return NULL; - } - - s = ssh_string_new(20); - if (s == NULL) { - ssh_signature_free(sig); - return NULL; - } - ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20); - - sig->dsa_sig->s = make_string_bn(s); - ssh_string_free(s); - if (sig->dsa_sig->s == NULL) { - ssh_signature_free(sig); - return NULL; - } - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig); - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - sig->ecdsa_sig = ECDSA_SIG_new(); - if (sig->ecdsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - - { /* build ecdsa siganature */ - ssh_buffer b; - uint32_t rlen; - - b = ssh_buffer_new(); - if (b == NULL) { - ssh_signature_free(sig); - return NULL; - } - - rc = ssh_buffer_add_data(b, - ssh_string_data(sig_blob), - ssh_string_len(sig_blob)); - if (rc < 0) { - ssh_buffer_free(b); - ssh_signature_free(sig); - return NULL; - } - - r = buffer_get_ssh_string(b); - if (r == NULL) { - ssh_buffer_free(b); - ssh_signature_free(sig); - return NULL; - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r)); -#endif - - sig->ecdsa_sig->r = make_string_bn(r); - ssh_string_burn(r); - ssh_string_free(r); - if (sig->ecdsa_sig->r == NULL) { - ssh_buffer_free(b); - ssh_signature_free(sig); - return NULL; - } - - s = buffer_get_ssh_string(b); - rlen = buffer_get_rest_len(b); - ssh_buffer_free(b); - if (s == NULL) { - ssh_signature_free(sig); - return NULL; - } - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s)); -#endif - - sig->ecdsa_sig->s = make_string_bn(s); - ssh_string_burn(s); - ssh_string_free(s); - if (sig->ecdsa_sig->s == NULL) { - ssh_signature_free(sig); - return NULL; - } - - if (rlen != 0) { - ssh_pki_log("Signature has remaining bytes in inner " - "sigblob: %lu", - (unsigned long)rlen); - ssh_signature_free(sig); - return NULL; - } - } - - break; -#endif - case SSH_KEYTYPE_ED25519: - rc = pki_ed25519_sig_from_blob(sig, sig_blob); - if (rc == SSH_ERROR){ - ssh_signature_free(sig); - return NULL; - } - break; - default: - case SSH_KEYTYPE_UNKNOWN: - ssh_pki_log("Unknown signature type"); - ssh_signature_free(sig); - return NULL; - } - - return sig; -} - -int pki_signature_verify(ssh_session session, - const ssh_signature sig, - const ssh_key key, - const unsigned char *hash, - size_t hlen) -{ - int rc; - - switch(key->type) { - case SSH_KEYTYPE_DSS: - rc = DSA_do_verify(hash, - hlen, - sig->dsa_sig, - key->dsa); - if (rc <= 0) { - ssh_set_error(session, - SSH_FATAL, - "DSA error: %s", - ERR_error_string(ERR_get_error(), NULL)); - return SSH_ERROR; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - rc = RSA_verify(NID_sha1, - hash, - hlen, - ssh_string_data(sig->rsa_sig), - ssh_string_len(sig->rsa_sig), - key->rsa); - if (rc <= 0) { - ssh_set_error(session, - SSH_FATAL, - "RSA error: %s", - ERR_error_string(ERR_get_error(), NULL)); - return SSH_ERROR; - } - break; - case SSH_KEYTYPE_ED25519: - rc = pki_ed25519_verify(key, sig, hash, hlen); - if (rc != SSH_OK){ - ssh_set_error(session, - SSH_FATAL, - "ed25519 signature verification error"); - return SSH_ERROR; - } - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - rc = ECDSA_do_verify(hash, - hlen, - sig->ecdsa_sig, - key->ecdsa); - if (rc <= 0) { - ssh_set_error(session, - SSH_FATAL, - "ECDSA error: %s", - ERR_error_string(ERR_get_error(), NULL)); - return SSH_ERROR; - } - break; -#endif - case SSH_KEYTYPE_UNKNOWN: - default: - ssh_set_error(session, SSH_FATAL, "Unknown public key type"); - return SSH_ERROR; - } - - return SSH_OK; -} - -ssh_signature pki_do_sign(const ssh_key privkey, - const unsigned char *hash, - size_t hlen) { - ssh_signature sig; - int rc; - - sig = ssh_signature_new(); - if (sig == NULL) { - return NULL; - } - - sig->type = privkey->type; - sig->type_c = privkey->type_c; - - switch(privkey->type) { - case SSH_KEYTYPE_DSS: - sig->dsa_sig = DSA_do_sign(hash, hlen, privkey->dsa); - if (sig->dsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - -#ifdef DEBUG_CRYPTO - ssh_print_bignum("r", sig->dsa_sig->r); - ssh_print_bignum("s", sig->dsa_sig->s); -#endif - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sig->rsa_sig = _RSA_do_sign(hash, hlen, privkey->rsa); - if (sig->rsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - sig->dsa_sig = NULL; - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - sig->ecdsa_sig = ECDSA_do_sign(hash, hlen, privkey->ecdsa); - if (sig->ecdsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - -# ifdef DEBUG_CRYPTO - ssh_print_bignum("r", sig->ecdsa_sig->r); - ssh_print_bignum("s", sig->ecdsa_sig->s); -# endif /* DEBUG_CRYPTO */ - - break; -#endif /* HAVE_OPENSSL_ECC */ - case SSH_KEYTYPE_ED25519: - rc = pki_ed25519_sign(privkey, sig, hash, hlen); - if (rc != SSH_OK){ - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_UNKNOWN: - default: - ssh_signature_free(sig); - return NULL; - } - - return sig; -} - -#ifdef WITH_SERVER -ssh_signature pki_do_sign_sessionid(const ssh_key key, - const unsigned char *hash, - size_t hlen) -{ - ssh_signature sig; - - sig = ssh_signature_new(); - if (sig == NULL) { - return NULL; - } - sig->type = key->type; - sig->type_c = key->type_c; - - switch(key->type) { - case SSH_KEYTYPE_DSS: - sig->dsa_sig = DSA_do_sign(hash, hlen, key->dsa); - if (sig->dsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sig->rsa_sig = _RSA_do_sign(hash, hlen, key->rsa); - if (sig->rsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_ECDSA: -#ifdef HAVE_OPENSSL_ECC - sig->ecdsa_sig = ECDSA_do_sign(hash, hlen, key->ecdsa); - if (sig->ecdsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } - break; -#endif - case SSH_KEYTYPE_ED25519: - /* ED25519 handled in caller */ - case SSH_KEYTYPE_UNKNOWN: - default: - ssh_signature_free(sig); - return NULL; - } - - return sig; -} -#endif /* WITH_SERVER */ - -#endif /* _PKI_CRYPTO_H */ diff --git a/libssh/src/pki_ed25519.c b/libssh/src/pki_ed25519.c deleted file mode 100644 index 7fb9827c..00000000 --- a/libssh/src/pki_ed25519.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * pki_ed25519 .c - PKI infrastructure using ed25519 - * - * This file is part of the SSH Library - * - * Copyright (c) 2014 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "libssh/pki.h" -#include "libssh/pki_priv.h" -#include "libssh/ed25519.h" -#include "libssh/buffer.h" - -int pki_key_generate_ed25519(ssh_key key) -{ - int rc; - - key->ed25519_privkey = malloc(sizeof (ed25519_privkey)); - if (key->ed25519_privkey == NULL) { - goto error; - } - - key->ed25519_pubkey = malloc(sizeof (ed25519_privkey)); - if (key->ed25519_privkey == NULL) { - goto error; - } - - rc = crypto_sign_ed25519_keypair(*key->ed25519_pubkey, - *key->ed25519_privkey); - if (rc != 0) { - goto error; - } - - return SSH_OK; -error: - SAFE_FREE(key->ed25519_privkey); - SAFE_FREE(key->ed25519_pubkey); - - return SSH_ERROR; -} - -int pki_ed25519_sign(const ssh_key privkey, - ssh_signature sig, - const unsigned char *hash, - size_t hlen) -{ - int rc; - uint8_t *buffer; - unsigned long long dlen = 0; - - buffer = malloc(hlen + ED25519_SIG_LEN); - if (buffer == NULL) { - return SSH_ERROR; - } - - rc = crypto_sign_ed25519(buffer, - &dlen, - hash, - hlen, - *privkey->ed25519_privkey); - if (rc != 0) { - goto error; - } - sig->ed25519_sig = malloc(ED25519_SIG_LEN); - if (sig->ed25519_sig == NULL) { - goto error; - } - - /* This shouldn't happen */ - if (dlen - hlen != ED25519_SIG_LEN) { - goto error; - } - memcpy(sig->ed25519_sig, buffer, dlen - hlen); - SAFE_FREE(buffer); - - return SSH_OK; -error: - SAFE_FREE(buffer); - return SSH_ERROR; -} - -int pki_ed25519_verify(const ssh_key pubkey, - ssh_signature sig, - const unsigned char *hash, - size_t hlen) -{ - unsigned long long mlen = 0; - uint8_t *buffer; - uint8_t *buffer2; - int rc; - - if (pubkey == NULL || sig == NULL || - hash == NULL || sig->ed25519_sig == NULL) { - return SSH_ERROR; - } - - buffer = malloc(hlen + ED25519_SIG_LEN); - if (buffer == NULL) { - return SSH_ERROR; - } - - buffer2 = malloc(hlen + ED25519_SIG_LEN); - if (buffer2 == NULL) { - goto error; - } - - memcpy(buffer, sig->ed25519_sig, ED25519_SIG_LEN); - memcpy(buffer + ED25519_SIG_LEN, hash, hlen); - - rc = crypto_sign_ed25519_open(buffer2, - &mlen, - buffer, - hlen + ED25519_SIG_LEN, - *pubkey->ed25519_pubkey); - - BURN_BUFFER(buffer, hlen + ED25519_SIG_LEN); - BURN_BUFFER(buffer2, hlen); - SAFE_FREE(buffer); - SAFE_FREE(buffer2); - if (rc == 0) { - return SSH_OK; - } else { - return SSH_ERROR; - } -error: - SAFE_FREE(buffer); - SAFE_FREE(buffer2); - - return SSH_ERROR; -} - -/** - * @internal - * - * @brief Compare ed25519 keys if they are equal. - * - * @param[in] k1 The first key to compare. - * - * @param[in] k2 The second key to compare. - * - * @param[in] what What part or type of the key do you want to compare. - * - * @return 0 if equal, 1 if not. - */ -int pki_ed25519_key_cmp(const ssh_key k1, - const ssh_key k2, - enum ssh_keycmp_e what) -{ - int cmp; - - switch(what) { - case SSH_KEY_CMP_PRIVATE: - if (k1->ed25519_privkey == NULL || k2->ed25519_privkey == NULL) { - return 1; - } - cmp = memcmp(k1->ed25519_privkey, k2->ed25519_privkey, ED25519_SK_LEN); - if (cmp != 0) { - return 1; - } - /* FALL THROUGH */ - case SSH_KEY_CMP_PUBLIC: - if (k1->ed25519_pubkey == NULL || k2->ed25519_pubkey == NULL) { - return 1; - } - cmp = memcmp(k1->ed25519_pubkey, k2->ed25519_pubkey, ED25519_PK_LEN); - if (cmp != 0) { - return 1; - } - } - - return 0; -} - -/** - * @internal - * - * @brief duplicate an ed25519 key - * - * @param[out\ new preinitialized output ssh_ke - * - * @param[in] key key to copy - * - * @return SSH_ERROR on error, SSH_OK on success - */ -int pki_ed25519_key_dup(ssh_key new, const ssh_key key) -{ - if (key->ed25519_privkey == NULL || key->ed25519_pubkey == NULL) { - return SSH_ERROR; - } - - new->ed25519_privkey = malloc(ED25519_SK_LEN); - if (new->ed25519_privkey == NULL) { - return SSH_ERROR; - } - - new->ed25519_pubkey = malloc(ED25519_PK_LEN); - if (new->ed25519_privkey == NULL || new->ed25519_pubkey == NULL){ - SAFE_FREE(new->ed25519_privkey); - return SSH_ERROR; - } - - memcpy(new->ed25519_privkey, key->ed25519_privkey, ED25519_SK_LEN); - memcpy(new->ed25519_pubkey, key->ed25519_pubkey, ED25519_PK_LEN); - - return SSH_OK; -} - -/** - * @internal - * - * @brief outputs an ed25519 public key in a blob buffer. - * - * @param[out] buffer output buffer - * - * @param[in] key key to output - * - * @return SSH_ERROR on error, SSH_OK on success - */ -int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key) -{ - int rc; - - if (key->ed25519_pubkey == NULL){ - return SSH_ERROR; - } - - rc = ssh_buffer_pack(buffer, - "dP", - (uint32_t)ED25519_PK_LEN, - (size_t)ED25519_PK_LEN, key->ed25519_pubkey); - - return rc; -} - -/** - * @internal - * - * @brief output a signature blob from an ed25519 signature - * - * @param[in] sig signature to convert - * - * @return Signature blob in SSH string, or NULL on error - */ -ssh_string pki_ed25519_sig_to_blob(ssh_signature sig) -{ - ssh_string sig_blob; - - if (sig->ed25519_sig == NULL) { - return NULL; - } - - sig_blob = ssh_string_new(ED25519_SIG_LEN); - if (sig_blob == NULL) { - return NULL; - } - ssh_string_fill(sig_blob, sig->ed25519_sig, ED25519_SIG_LEN); - - return sig_blob; -} - -/** - * @internal - * - * @brief Convert a signature blob in an ed25519 signature. - * - * @param[out] sig a preinitialized signature - * - * @param[in] sig_blob a signature blob - * - * @return SSH_ERROR on error, SSH_OK on success - */ -int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob) -{ - size_t len; - - len = ssh_string_len(sig_blob); - if (len != ED25519_SIG_LEN){ - ssh_pki_log("Invalid ssh-ed25519 signature len: %zu", len); - return SSH_ERROR; - } - - sig->ed25519_sig = malloc(ED25519_SIG_LEN); - if (sig->ed25519_sig == NULL){ - return SSH_ERROR; - } - - memcpy(sig->ed25519_sig, ssh_string_data(sig_blob), ED25519_SIG_LEN); - - return SSH_OK; -} diff --git a/libssh/src/pki_gcrypt.c b/libssh/src/pki_gcrypt.c deleted file mode 100644 index 2811acce..00000000 --- a/libssh/src/pki_gcrypt.c +++ /dev/null @@ -1,1713 +0,0 @@ -/* - * pki_gcrypt.c private and public key handling using gcrypt. - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2009 Aris Adamantiadis - * Copyright (c) 2009-2011 Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#ifdef HAVE_LIBGCRYPT - -#include -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/session.h" -#include "libssh/wrapper.h" -#include "libssh/misc.h" -#include "libssh/pki.h" -#include "libssh/pki_priv.h" - -#define MAXLINESIZE 80 -#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 MAX_KEY_SIZE 32 -#define MAX_PASSPHRASE_SIZE 1024 -#define ASN1_INTEGER 2 -#define ASN1_SEQUENCE 48 -#define PKCS5_SALT_LEN 8 - -static int load_iv(const char *header, unsigned char *iv, int iv_len) { - int i; - int j; - int k; - - memset(iv, 0, iv_len); - for (i = 0; i < iv_len; i++) { - if ((header[2*i] >= '0') && (header[2*i] <= '9')) - j = header[2*i] - '0'; - else if ((header[2*i] >= 'A') && (header[2*i] <= 'F')) - j = header[2*i] - 'A' + 10; - else if ((header[2*i] >= 'a') && (header[2*i] <= 'f')) - j = header[2*i] - 'a' + 10; - else - return -1; - if ((header[2*i+1] >= '0') && (header[2*i+1] <= '9')) - k = header[2*i+1] - '0'; - else if ((header[2*i+1] >= 'A') && (header[2*i+1] <= 'F')) - k = header[2*i+1] - 'A' + 10; - else if ((header[2*i+1] >= 'a') && (header[2*i+1] <= 'f')) - k = header[2*i+1] - 'a' + 10; - else - return -1; - iv[i] = (j << 4) + k; - } - return 0; -} - -static uint32_t char_to_u32(unsigned char *data, uint32_t size) { - uint32_t ret; - uint32_t i; - - for (i = 0, ret = 0; i < size; ret = ret << 8, ret += data[i++]) - ; - return ret; -} - -static uint32_t asn1_get_len(ssh_buffer buffer) { - uint32_t len; - unsigned char tmp[4]; - - if (buffer_get_data(buffer,tmp,1) == 0) { - return 0; - } - - if (tmp[0] > 127) { - len = tmp[0] & 127; - if (len > 4) { - return 0; /* Length doesn't fit in u32. Can this really happen? */ - } - if (buffer_get_data(buffer,tmp,len) == 0) { - return 0; - } - len = char_to_u32(tmp, len); - } else { - len = char_to_u32(tmp, 1); - } - - return len; -} - -static ssh_string asn1_get_int(ssh_buffer buffer) { - ssh_string str; - unsigned char type; - uint32_t size; - - if (buffer_get_data(buffer, &type, 1) == 0 || type != ASN1_INTEGER) { - return NULL; - } - size = asn1_get_len(buffer); - if (size == 0) { - return NULL; - } - - str = ssh_string_new(size); - if (str == NULL) { - return NULL; - } - - if (buffer_get_data(buffer, ssh_string_data(str), size) == 0) { - ssh_string_free(str); - return NULL; - } - - return str; -} - -static int asn1_check_sequence(ssh_buffer buffer) { - unsigned char *j = NULL; - unsigned char tmp; - int i; - uint32_t size; - uint32_t padding; - - if (buffer_get_data(buffer, &tmp, 1) == 0 || tmp != ASN1_SEQUENCE) { - return 0; - } - - size = asn1_get_len(buffer); - if ((padding = ssh_buffer_get_len(buffer) - buffer->pos - size) > 0) { - for (i = ssh_buffer_get_len(buffer) - buffer->pos - size, - j = (unsigned char*)ssh_buffer_get_begin(buffer) + size + buffer->pos; - i; - i--, j++) - { - if (*j != padding) { /* padding is allowed */ - return 0; /* but nothing else */ - } - } - } - - return 1; -} - -static int passphrase_to_key(char *data, unsigned int datalen, - unsigned char *salt, unsigned char *key, unsigned int keylen) { - MD5CTX md; - unsigned char digest[MD5_DIGEST_LEN] = {0}; - unsigned int i; - unsigned int j; - unsigned int md_not_empty; - - for (j = 0, md_not_empty = 0; j < keylen; ) { - md = md5_init(); - if (md == NULL) { - return -1; - } - - if (md_not_empty) { - md5_update(md, digest, MD5_DIGEST_LEN); - } else { - md_not_empty = 1; - } - - md5_update(md, data, datalen); - if (salt) { - md5_update(md, salt, PKCS5_SALT_LEN); - } - md5_final(digest, md); - - for (i = 0; j < keylen && i < MD5_DIGEST_LEN; j++, i++) { - if (key) { - key[j] = digest[i]; - } - } - } - - return 0; -} - -static int privatekey_decrypt(int algo, int mode, unsigned int key_len, - unsigned char *iv, unsigned int iv_len, - ssh_buffer data, ssh_auth_callback cb, - void *userdata, - const char *desc) -{ - char passphrase[MAX_PASSPHRASE_SIZE] = {0}; - unsigned char key[MAX_KEY_SIZE] = {0}; - unsigned char *tmp = NULL; - gcry_cipher_hd_t cipher; - int rc = -1; - - if (!algo) { - return -1; - } - - if (cb) { - rc = (*cb)(desc, passphrase, MAX_PASSPHRASE_SIZE, 0, 0, userdata); - if (rc < 0) { - return -1; - } - } else if (cb == NULL && userdata != NULL) { - snprintf(passphrase, MAX_PASSPHRASE_SIZE, "%s", (char *) userdata); - } - - if (passphrase_to_key(passphrase, strlen(passphrase), iv, key, key_len) < 0) { - return -1; - } - - if (gcry_cipher_open(&cipher, algo, mode, 0) - || gcry_cipher_setkey(cipher, key, key_len) - || gcry_cipher_setiv(cipher, iv, iv_len) - || (tmp = malloc(ssh_buffer_get_len(data) * sizeof (char))) == NULL - || gcry_cipher_decrypt(cipher, tmp, ssh_buffer_get_len(data), - ssh_buffer_get_begin(data), ssh_buffer_get_len(data))) { - gcry_cipher_close(cipher); - return -1; - } - - memcpy(ssh_buffer_get_begin(data), tmp, ssh_buffer_get_len(data)); - - SAFE_FREE(tmp); - gcry_cipher_close(cipher); - - return 0; -} - -static int privatekey_dek_header(const char *header, unsigned int header_len, - int *algo, int *mode, unsigned int *key_len, unsigned char **iv, - unsigned int *iv_len) { - unsigned int iv_pos; - - if (header_len > 13 && !strncmp("DES-EDE3-CBC", header, 12)) - { - *algo = GCRY_CIPHER_3DES; - iv_pos = 13; - *mode = GCRY_CIPHER_MODE_CBC; - *key_len = 24; - *iv_len = 8; - } - else if (header_len > 8 && !strncmp("DES-CBC", header, 7)) - { - *algo = GCRY_CIPHER_DES; - iv_pos = 8; - *mode = GCRY_CIPHER_MODE_CBC; - *key_len = 8; - *iv_len = 8; - } - else if (header_len > 12 && !strncmp("AES-128-CBC", header, 11)) - { - *algo = GCRY_CIPHER_AES128; - iv_pos = 12; - *mode = GCRY_CIPHER_MODE_CBC; - *key_len = 16; - *iv_len = 16; - } - else if (header_len > 12 && !strncmp("AES-192-CBC", header, 11)) - { - *algo = GCRY_CIPHER_AES192; - iv_pos = 12; - *mode = GCRY_CIPHER_MODE_CBC; - *key_len = 24; - *iv_len = 16; - } - else if (header_len > 12 && !strncmp("AES-256-CBC", header, 11)) - { - *algo = GCRY_CIPHER_AES256; - iv_pos = 12; - *mode = GCRY_CIPHER_MODE_CBC; - *key_len = 32; - *iv_len = 16; - } else { - return -1; - } - - *iv = malloc(*iv_len); - if (*iv == NULL) { - return -1; - } - - return load_iv(header + iv_pos, *iv, *iv_len); -} - -#define get_next_line(p, len) { \ - while(p[len] == '\n' || p[len] == '\r') /* skip empty lines */ \ - len++; \ - if(p[len] == '\0') /* EOL */ \ - len = -1; \ - else /* calculate length */ \ - for(p += len, len = 0; p[len] && p[len] != '\n' \ - && p[len] != '\r'; len++); \ - } - -static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type, - ssh_auth_callback cb, void *userdata, const char *desc) { - ssh_buffer buffer = NULL; - ssh_buffer out = NULL; - const char *p; - unsigned char *iv = NULL; - const char *header_begin; - const char *header_end; - unsigned int header_begin_size; - unsigned int header_end_size; - unsigned int key_len = 0; - unsigned int iv_len = 0; - int algo = 0; - int mode = 0; - int len; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - return NULL; - } - - switch(type) { - case SSH_KEYTYPE_DSS: - header_begin = DSA_HEADER_BEGIN; - header_end = DSA_HEADER_END; - break; - case SSH_KEYTYPE_RSA: - header_begin = RSA_HEADER_BEGIN; - header_end = RSA_HEADER_END; - break; - default: - ssh_buffer_free(buffer); - return NULL; - } - - header_begin_size = strlen(header_begin); - header_end_size = strlen(header_end); - - p = pkey; - len = 0; - get_next_line(p, len); - - while(len > 0 && strncmp(p, header_begin, header_begin_size)) { - /* skip line */ - get_next_line(p, len); - } - if(len < 0) { - /* no header found */ - return NULL; - } - /* skip header line */ - get_next_line(p, len); - - if (len > 11 && strncmp("Proc-Type: 4,ENCRYPTED", p, 11) == 0) { - /* skip line */ - get_next_line(p, len); - - if (len > 10 && strncmp("DEK-Info: ", p, 10) == 0) { - p += 10; - len = 0; - get_next_line(p, len); - if (privatekey_dek_header(p, len, &algo, &mode, &key_len, - &iv, &iv_len) < 0) { - ssh_buffer_free(buffer); - SAFE_FREE(iv); - return NULL; - } - } else { - ssh_buffer_free(buffer); - SAFE_FREE(iv); - return NULL; - } - } else { - if(len > 0) { - if (ssh_buffer_add_data(buffer, p, len) < 0) { - ssh_buffer_free(buffer); - SAFE_FREE(iv); - return NULL; - } - } - } - - get_next_line(p, len); - while(len > 0 && strncmp(p, header_end, header_end_size) != 0) { - if (ssh_buffer_add_data(buffer, p, len) < 0) { - ssh_buffer_free(buffer); - SAFE_FREE(iv); - return NULL; - } - get_next_line(p, len); - } - - if (len == -1 || strncmp(p, header_end, header_end_size) != 0) { - ssh_buffer_free(buffer); - SAFE_FREE(iv); - return NULL; - } - - if (ssh_buffer_add_data(buffer, "\0", 1) < 0) { - ssh_buffer_free(buffer); - SAFE_FREE(iv); - return NULL; - } - - out = base64_to_bin(ssh_buffer_get_begin(buffer)); - ssh_buffer_free(buffer); - if (out == NULL) { - SAFE_FREE(iv); - return NULL; - } - - if (algo) { - if (privatekey_decrypt(algo, mode, key_len, iv, iv_len, out, - cb, userdata, desc) < 0) { - ssh_buffer_free(out); - SAFE_FREE(iv); - return NULL; - } - } - SAFE_FREE(iv); - - return out; -} - -static int b64decode_rsa_privatekey(const char *pkey, gcry_sexp_t *r, - ssh_auth_callback cb, void *userdata, const char *desc) { - const unsigned char *data; - ssh_string n = NULL; - ssh_string e = NULL; - ssh_string d = NULL; - ssh_string p = NULL; - ssh_string q = NULL; - ssh_string unused1 = NULL; - ssh_string unused2 = NULL; - ssh_string u = NULL; - ssh_string v = NULL; - ssh_buffer buffer = NULL; - int rc = 1; - - buffer = privatekey_string_to_buffer(pkey, SSH_KEYTYPE_RSA, cb, userdata, desc); - if (buffer == NULL) { - return 0; - } - - if (!asn1_check_sequence(buffer)) { - ssh_buffer_free(buffer); - return 0; - } - - v = asn1_get_int(buffer); - if (v == NULL) { - ssh_buffer_free(buffer); - return 0; - } - - data = ssh_string_data(v); - if (ssh_string_len(v) != 1 || data[0] != 0) { - ssh_buffer_free(buffer); - return 0; - } - - n = asn1_get_int(buffer); - e = asn1_get_int(buffer); - d = asn1_get_int(buffer); - q = asn1_get_int(buffer); - p = asn1_get_int(buffer); - unused1 = asn1_get_int(buffer); - unused2 = asn1_get_int(buffer); - u = asn1_get_int(buffer); - - ssh_buffer_free(buffer); - - if (n == NULL || e == NULL || d == NULL || p == NULL || q == NULL || - unused1 == NULL || unused2 == NULL|| u == NULL) { - rc = 0; - goto error; - } - - if (gcry_sexp_build(r, NULL, - "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))", - ssh_string_len(n), ssh_string_data(n), - ssh_string_len(e), ssh_string_data(e), - ssh_string_len(d), ssh_string_data(d), - ssh_string_len(p), ssh_string_data(p), - ssh_string_len(q), ssh_string_data(q), - ssh_string_len(u), ssh_string_data(u))) { - rc = 0; - } - -error: - ssh_string_free(n); - ssh_string_free(e); - ssh_string_free(d); - ssh_string_free(p); - ssh_string_free(q); - ssh_string_free(unused1); - ssh_string_free(unused2); - ssh_string_free(u); - ssh_string_free(v); - - return rc; -} - -static int b64decode_dsa_privatekey(const char *pkey, gcry_sexp_t *r, ssh_auth_callback cb, - void *userdata, const char *desc) { - const unsigned char *data; - ssh_buffer buffer = NULL; - ssh_string p = NULL; - ssh_string q = NULL; - ssh_string g = NULL; - ssh_string y = NULL; - ssh_string x = NULL; - ssh_string v = NULL; - int rc = 1; - - buffer = privatekey_string_to_buffer(pkey, SSH_KEYTYPE_DSS, cb, userdata, desc); - if (buffer == NULL) { - return 0; - } - - if (!asn1_check_sequence(buffer)) { - ssh_buffer_free(buffer); - return 0; - } - - v = asn1_get_int(buffer); - if (v == NULL) { - ssh_buffer_free(buffer); - return 0; - } - - data = ssh_string_data(v); - if (ssh_string_len(v) != 1 || data[0] != 0) { - ssh_buffer_free(buffer); - return 0; - } - - p = asn1_get_int(buffer); - q = asn1_get_int(buffer); - g = asn1_get_int(buffer); - y = asn1_get_int(buffer); - x = asn1_get_int(buffer); - ssh_buffer_free(buffer); - - if (p == NULL || q == NULL || g == NULL || y == NULL || x == NULL) { - rc = 0; - goto error; - } - - if (gcry_sexp_build(r, NULL, - "(private-key(dsa(p %b)(q %b)(g %b)(y %b)(x %b)))", - ssh_string_len(p), ssh_string_data(p), - ssh_string_len(q), ssh_string_data(q), - ssh_string_len(g), ssh_string_data(g), - ssh_string_len(y), ssh_string_data(y), - ssh_string_len(x), ssh_string_data(x))) { - rc = 0; - } - -error: - ssh_string_free(p); - ssh_string_free(q); - ssh_string_free(g); - ssh_string_free(y); - ssh_string_free(x); - ssh_string_free(v); - - return rc; -} - -#ifdef HAVE_GCRYPT_ECC -int pki_key_ecdsa_nid_from_name(const char *name) -{ - return -1; -} -#endif - -ssh_string pki_private_key_to_pem(const ssh_key key, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data) -{ - (void) key; - (void) passphrase; - (void) auth_fn; - (void) auth_data; - - return NULL; -} - -ssh_key pki_private_key_from_base64(const char *b64_key, - const char *passphrase, - ssh_auth_callback auth_fn, - void *auth_data) -{ - gcry_sexp_t dsa = NULL; - gcry_sexp_t rsa = NULL; - ssh_key key = NULL; - enum ssh_keytypes_e type; - int valid; - - /* needed for gcrypt initialization */ - if (ssh_init() < 0) { - return NULL; - } - - type = pki_privatekey_type_from_string(b64_key); - if (type == SSH_KEYTYPE_UNKNOWN) { - ssh_pki_log("Unknown or invalid private key."); - return NULL; - } - - switch (type) { - case SSH_KEYTYPE_DSS: - if (passphrase == NULL) { - if (auth_fn) { - valid = b64decode_dsa_privatekey(b64_key, &dsa, auth_fn, - auth_data, "Passphrase for private key:"); - } else { - valid = b64decode_dsa_privatekey(b64_key, &dsa, NULL, NULL, - NULL); - } - } else { - valid = b64decode_dsa_privatekey(b64_key, &dsa, NULL, (void *) - passphrase, NULL); - } - - if (!valid) { - ssh_pki_log("Parsing private key"); - goto fail; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - if (passphrase == NULL) { - if (auth_fn) { - valid = b64decode_rsa_privatekey(b64_key, &rsa, auth_fn, - auth_data, "Passphrase for private key:"); - } else { - valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL, NULL, - NULL); - } - } else { - valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL, - (void *)passphrase, NULL); - } - - if (!valid) { - ssh_pki_log("Parsing private key"); - goto fail; - } - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - ssh_pki_log("Unkown or invalid private key type %d", type); - return NULL; - } - - key = ssh_key_new(); - if (key == NULL) { - goto fail; - } - - key->type = type; - key->type_c = ssh_key_type_to_char(type); - key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; - key->dsa = dsa; - key->rsa = rsa; - - return key; -fail: - ssh_key_free(key); - gcry_sexp_release(dsa); - gcry_sexp_release(rsa); - - return NULL; -} - -int pki_pubkey_build_dss(ssh_key key, - ssh_string p, - ssh_string q, - ssh_string g, - ssh_string pubkey) { - gcry_sexp_build(&key->dsa, NULL, - "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))", - ssh_string_len(p), ssh_string_data(p), - ssh_string_len(q), ssh_string_data(q), - ssh_string_len(g), ssh_string_data(g), - ssh_string_len(pubkey), ssh_string_data(pubkey)); - if (key->dsa == NULL) { - return SSH_ERROR; - } - - return SSH_OK; -} - -int pki_pubkey_build_rsa(ssh_key key, - ssh_string e, - ssh_string n) { - gcry_sexp_build(&key->rsa, NULL, - "(public-key(rsa(n %b)(e %b)))", - ssh_string_len(n), ssh_string_data(n), - ssh_string_len(e),ssh_string_data(e)); - if (key->rsa == NULL) { - return SSH_ERROR; - } - - return SSH_OK; -} - -#ifdef HAVE_GCRYPT_ECC -int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e) -{ - return -1; -} -#endif - -ssh_key pki_key_dup(const ssh_key key, int demote) -{ - ssh_key new; - gcry_sexp_t sexp; - gcry_error_t err; - const char *tmp = NULL; - size_t size; - - ssh_string p = NULL; - ssh_string q = NULL; - ssh_string g = NULL; - ssh_string y = NULL; - ssh_string x = NULL; - - ssh_string e = NULL; - ssh_string n = NULL; - ssh_string d = NULL; - ssh_string u = NULL; - - new = ssh_key_new(); - if (new == NULL) { - return NULL; - } - new->type = key->type; - new->type_c = key->type_c; - if (demote) { - new->flags = SSH_KEY_FLAG_PUBLIC; - } else { - new->flags = key->flags; - } - - switch(key->type) { - case SSH_KEYTYPE_DSS: - sexp = gcry_sexp_find_token(key->dsa, "p", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - p = ssh_string_new(size); - if (p == NULL) { - goto fail; - } - ssh_string_fill(p, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->dsa, "q", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - q = ssh_string_new(size); - if (q == NULL) { - goto fail; - } - ssh_string_fill(q, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->dsa, "g", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - g = ssh_string_new(size); - if (g == NULL) { - goto fail; - } - ssh_string_fill(g, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->dsa, "y", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - y = ssh_string_new(size); - if (y == NULL) { - goto fail; - } - ssh_string_fill(y, (char *)tmp, size); - gcry_sexp_release(sexp); - - if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { - sexp = gcry_sexp_find_token(key->dsa, "x", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - x = ssh_string_new(size); - if (x == NULL) { - goto fail; - } - ssh_string_fill(x, (char *)tmp, size); - gcry_sexp_release(sexp); - - err = gcry_sexp_build(&new->dsa, NULL, - "(private-key(dsa(p %b)(q %b)(g %b)(y %b)(x %b)))", - ssh_string_len(p), ssh_string_data(p), - ssh_string_len(q), ssh_string_data(q), - ssh_string_len(g), ssh_string_data(g), - ssh_string_len(y), ssh_string_data(y), - ssh_string_len(x), ssh_string_data(x)); - } else { - err = gcry_sexp_build(&new->dsa, NULL, - "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))", - ssh_string_len(p), ssh_string_data(p), - ssh_string_len(q), ssh_string_data(q), - ssh_string_len(g), ssh_string_data(g), - ssh_string_len(y), ssh_string_data(y)); - } - if (err) { - goto fail; - } - - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(g); - ssh_string_free(g); - ssh_string_burn(y); - ssh_string_free(y); - ssh_string_burn(x); - ssh_string_free(x); - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sexp = gcry_sexp_find_token(key->rsa, "e", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - e = ssh_string_new(size); - if (e == NULL) { - goto fail; - } - ssh_string_fill(e, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->rsa, "n", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - n = ssh_string_new(size); - if (n == NULL) { - goto fail; - } - ssh_string_fill(n, (char *)tmp, size); - gcry_sexp_release(sexp); - - if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { - sexp = gcry_sexp_find_token(key->rsa, "d", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - d = ssh_string_new(size); - if (e == NULL) { - goto fail; - } - ssh_string_fill(d, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->rsa, "p", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - p = ssh_string_new(size); - if (p == NULL) { - goto fail; - } - ssh_string_fill(p, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->rsa, "q", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - q = ssh_string_new(size); - if (q == NULL) { - goto fail; - } - ssh_string_fill(q, (char *)tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->rsa, "u", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - u = ssh_string_new(size); - if (u == NULL) { - goto fail; - } - ssh_string_fill(u, (char *)tmp, size); - gcry_sexp_release(sexp); - - err = gcry_sexp_build(&new->rsa, NULL, - "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))", - ssh_string_len(n), ssh_string_data(n), - ssh_string_len(e), ssh_string_data(e), - ssh_string_len(d), ssh_string_data(d), - ssh_string_len(p), ssh_string_data(p), - ssh_string_len(q), ssh_string_data(q), - ssh_string_len(u), ssh_string_data(u)); - } else { - err = gcry_sexp_build(&new->rsa, NULL, - "(public-key(rsa(n %b)(e %b)))", - ssh_string_len(n), ssh_string_data(n), - ssh_string_len(e), ssh_string_data(e)); - } - - if (err) { - goto fail; - } - - ssh_string_burn(e); - ssh_string_free(e); - ssh_string_burn(n); - ssh_string_free(n); - ssh_string_burn(d); - ssh_string_free(d); - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(u); - ssh_string_free(u); - - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - ssh_key_free(new); - return NULL; - } - - return new; -fail: - gcry_sexp_release(sexp); - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(g); - ssh_string_free(g); - ssh_string_burn(y); - ssh_string_free(y); - ssh_string_burn(x); - ssh_string_free(x); - - ssh_string_burn(e); - ssh_string_free(e); - ssh_string_burn(n); - ssh_string_free(n); - ssh_string_burn(u); - ssh_string_free(u); - - ssh_key_free(new); - - return NULL; -} - -static int pki_key_generate(ssh_key key, int parameter, const char *type_s, int type){ - gcry_sexp_t parms; - int rc; - rc = gcry_sexp_build(&parms, - NULL, - "(genkey(%s(nbits %d)(transient-key)))", - type_s, - parameter); - if (rc != 0) - return SSH_ERROR; - if(type == SSH_KEYTYPE_RSA) - rc = gcry_pk_genkey(&key->rsa, parms); - else - rc = gcry_pk_genkey(&key->dsa, parms); - gcry_sexp_release(parms); - if (rc != 0) - return SSH_ERROR; - return SSH_OK; -} - -int pki_key_generate_rsa(ssh_key key, int parameter){ - return pki_key_generate(key, parameter, "rsa", SSH_KEYTYPE_RSA); -} -int pki_key_generate_dss(ssh_key key, int parameter){ - return pki_key_generate(key, parameter, "dsa", SSH_KEYTYPE_DSS); -} - -#ifdef HAVE_GCRYPT_ECC -int pki_key_generate_ecdsa(ssh_key key, int parameter) { - return -1; -} -#endif - -static int _bignum_cmp(const gcry_sexp_t s1, - const gcry_sexp_t s2, - const char *what) -{ - gcry_sexp_t sexp; - bignum b1; - bignum b2; - - sexp = gcry_sexp_find_token(s1, what, 0); - if (sexp == NULL) { - return 1; - } - b1 = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(sexp); - if (b1 == NULL) { - return 1; - } - - sexp = gcry_sexp_find_token(s2, what, 0); - if (sexp == NULL) { - return 1; - } - b2 = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(sexp); - if (b2 == NULL) { - return 1; - } - - if (bignum_cmp(b1, b2) != 0) { - return 1; - } - - return 0; -} - -int pki_key_compare(const ssh_key k1, - const ssh_key k2, - enum ssh_keycmp_e what) -{ - switch (k1->type) { - case SSH_KEYTYPE_DSS: - if (_bignum_cmp(k1->dsa, k2->dsa, "p") != 0) { - return 1; - } - - if (_bignum_cmp(k1->dsa, k2->dsa, "q") != 0) { - return 1; - } - - if (_bignum_cmp(k1->dsa, k2->dsa, "g") != 0) { - return 1; - } - - if (_bignum_cmp(k1->dsa, k2->dsa, "y") != 0) { - return 1; - } - - if (what == SSH_KEY_CMP_PRIVATE) { - if (_bignum_cmp(k1->dsa, k2->dsa, "x") != 0) { - return 1; - } - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - if (_bignum_cmp(k1->rsa, k2->rsa, "e") != 0) { - return 1; - } - - if (_bignum_cmp(k1->rsa, k2->rsa, "n") != 0) { - return 1; - } - - if (what == SSH_KEY_CMP_PRIVATE) { - if (_bignum_cmp(k1->rsa, k2->rsa, "d") != 0) { - return 1; - } - - if (_bignum_cmp(k1->rsa, k2->rsa, "p") != 0) { - return 1; - } - - if (_bignum_cmp(k1->rsa, k2->rsa, "q") != 0) { - return 1; - } - - if (_bignum_cmp(k1->rsa, k2->rsa, "u") != 0) { - return 1; - } - } - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - return 1; - } - - return 0; -} - -ssh_string pki_publickey_to_blob(const ssh_key key) -{ - ssh_buffer buffer; - ssh_string type_s; - ssh_string str = NULL; - ssh_string e = NULL; - ssh_string n = NULL; - ssh_string p = NULL; - ssh_string g = NULL; - ssh_string q = NULL; - const char *tmp = NULL; - size_t size; - gcry_sexp_t sexp; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - return NULL; - } - - type_s = ssh_string_from_char(key->type_c); - if (type_s == NULL) { - ssh_buffer_free(buffer); - return NULL; - } - - rc = buffer_add_ssh_string(buffer, type_s); - ssh_string_free(type_s); - if (rc < 0) { - ssh_buffer_free(buffer); - return NULL; - } - - switch (key->type) { - case SSH_KEYTYPE_DSS: - sexp = gcry_sexp_find_token(key->dsa, "p", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - p = ssh_string_new(size); - if (p == NULL) { - goto fail; - } - ssh_string_fill(p, (char *) tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->dsa, "q", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - q = ssh_string_new(size); - if (q == NULL) { - goto fail; - } - ssh_string_fill(q, (char *) tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->dsa, "g", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - g = ssh_string_new(size); - if (g == NULL) { - goto fail; - } - ssh_string_fill(g, (char *) tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->dsa, "y", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - n = ssh_string_new(size); - if (n == NULL) { - goto fail; - } - ssh_string_fill(n, (char *) tmp, size); - - if (buffer_add_ssh_string(buffer, p) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, q) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, g) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, n) < 0) { - goto fail; - } - - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(g); - ssh_string_free(g); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(n); - ssh_string_free(n); - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sexp = gcry_sexp_find_token(key->rsa, "e", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - e = ssh_string_new(size); - if (e == NULL) { - goto fail; - } - ssh_string_fill(e, (char *) tmp, size); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(key->rsa, "n", 0); - if (sexp == NULL) { - goto fail; - } - tmp = gcry_sexp_nth_data(sexp, 1, &size); - n = ssh_string_new(size); - if (n == NULL) { - goto fail; - } - ssh_string_fill(n, (char *) tmp, size); - gcry_sexp_release(sexp); - - if (buffer_add_ssh_string(buffer, e) < 0) { - goto fail; - } - if (buffer_add_ssh_string(buffer, n) < 0) { - goto fail; - } - - ssh_string_burn(e); - ssh_string_free(e); - ssh_string_burn(n); - ssh_string_free(n); - - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - goto fail; - } - - str = ssh_string_new(buffer_get_rest_len(buffer)); - if (str == NULL) { - goto fail; - } - - rc = ssh_string_fill(str, buffer_get_rest(buffer), buffer_get_rest_len(buffer)); - if (rc < 0) { - goto fail; - } - ssh_buffer_free(buffer); - - return str; -fail: - ssh_buffer_free(buffer); - ssh_string_burn(str); - ssh_string_free(str); - ssh_string_burn(e); - ssh_string_free(e); - ssh_string_burn(p); - ssh_string_free(p); - ssh_string_burn(g); - ssh_string_free(g); - ssh_string_burn(q); - ssh_string_free(q); - ssh_string_burn(n); - ssh_string_free(n); - - return NULL; -} - -int pki_export_pubkey_rsa1(const ssh_key key, - const char *host, - char *rsa1, - size_t rsa1_len) -{ - gcry_sexp_t sexp; - int rsa_size; - bignum b; - char *e, *n; - - sexp = gcry_sexp_find_token(key->rsa, "e", 0); - if (sexp == NULL) { - return SSH_ERROR; - } - b = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(sexp); - if (b == NULL) { - return SSH_ERROR; - } - e = bignum_bn2dec(b); - - sexp = gcry_sexp_find_token(key->rsa, "n", 0); - if (sexp == NULL) { - SAFE_FREE(e); - return SSH_ERROR; - } - b = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(sexp); - if (b == NULL) { - SAFE_FREE(e); - return SSH_ERROR; - } - n = bignum_bn2dec(b); - - rsa_size = (gcry_pk_get_nbits(key->rsa) + 7) / 8; - - snprintf(rsa1, rsa1_len, - "%s %d %s %s\n", - host, rsa_size << 3, e, n); - SAFE_FREE(e); - SAFE_FREE(n); - - return SSH_OK; -} - -ssh_string pki_signature_to_blob(const ssh_signature sig) -{ - char buffer[40] = {0}; - const char *r = NULL; - const char *s = NULL; - gcry_sexp_t sexp; - size_t size = 0; - ssh_string sig_blob = NULL; - - switch(sig->type) { - case SSH_KEYTYPE_DSS: - sexp = gcry_sexp_find_token(sig->dsa_sig, "r", 0); - if (sexp == NULL) { - return NULL; - } - r = gcry_sexp_nth_data(sexp, 1, &size); - /* libgcrypt put 0 when first bit is set */ - if (*r == 0) { - size--; - r++; - } - memcpy(buffer, r + size - 20, 20); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(sig->dsa_sig, "s", 0); - if (sexp == NULL) { - return NULL; - } - s = gcry_sexp_nth_data(sexp,1,&size); - if (*s == 0) { - size--; - s++; - } - memcpy(buffer+ 20, s + size - 20, 20); - gcry_sexp_release(sexp); - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - sexp = gcry_sexp_find_token(sig->rsa_sig, "s", 0); - if (sexp == NULL) { - return NULL; - } - s = gcry_sexp_nth_data(sexp, 1, &size); - if (*s == 0) { - size--; - s++; - } - - sig_blob = ssh_string_new(size); - if (sig_blob == NULL) { - return NULL; - } - ssh_string_fill(sig_blob, discard_const_p(char, s), size); - - gcry_sexp_release(sexp); - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - ssh_pki_log("Unknown signature key type: %d", sig->type); - return NULL; - break; - } - - return sig_blob; -} - -ssh_signature pki_signature_from_blob(const ssh_key pubkey, - const ssh_string sig_blob, - enum ssh_keytypes_e type) -{ - ssh_signature sig; - gcry_error_t err; - size_t len; - size_t rsalen; - - sig = ssh_signature_new(); - if (sig == NULL) { - return NULL; - } - - sig->type = type; - - len = ssh_string_len(sig_blob); - - switch(type) { - case SSH_KEYTYPE_DSS: - /* 40 is the dual signature blob len. */ - if (len != 40) { - ssh_pki_log("Signature has wrong size: %lu", - (unsigned long)len); - ssh_signature_free(sig); - return NULL; - } - -#ifdef DEBUG_CRYPTO - ssh_pki_log("DSA signature len: %lu", (unsigned long)len); - ssh_print_hexa("DSA signature", ssh_string_data(sig_blob), len); -#endif - - err = gcry_sexp_build(&sig->dsa_sig, - NULL, - "(sig-val(dsa(r %b)(s %b)))", - 20, - ssh_string_data(sig_blob), - 20, - (unsigned char *)ssh_string_data(sig_blob) + 20); - if (err) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - rsalen = (gcry_pk_get_nbits(pubkey->rsa) + 7) / 8; - - if (len > rsalen) { - ssh_pki_log("Signature is to big size: %lu", - (unsigned long)len); - ssh_signature_free(sig); - return NULL; - } - - if (len < rsalen) { - ssh_pki_log("RSA signature len %lu < %lu", - (unsigned long)len, (unsigned long)rsalen); - } - -#ifdef DEBUG_CRYPTO - ssh_pki_log("RSA signature len: %lu", (unsigned long)len); - ssh_print_hexa("RSA signature", ssh_string_data(sig_blob), len); -#endif - - err = gcry_sexp_build(&sig->rsa_sig, - NULL, - "(sig-val(rsa(s %b)))", - ssh_string_len(sig_blob), - ssh_string_data(sig_blob)); - if (err) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - ssh_pki_log("Unknown signature type"); - return NULL; - } - - return sig; -} - -int pki_signature_verify(ssh_session session, - const ssh_signature sig, - const ssh_key key, - const unsigned char *hash, - size_t hlen) -{ - unsigned char ghash[hlen + 1]; - gcry_sexp_t sexp; - gcry_error_t err; - - switch(key->type) { - case SSH_KEYTYPE_DSS: - /* That is to mark the number as positive */ - if(hash[0] >= 0x80) { - memcpy(ghash + 1, hash, hlen); - ghash[0] = 0; - hash = ghash; - hlen += 1; - } - - err = gcry_sexp_build(&sexp, NULL, "%b", hlen, hash); - if (err) { - ssh_set_error(session, - SSH_FATAL, - "DSA hash error: %s", gcry_strerror(err)); - return SSH_ERROR; - } - err = gcry_pk_verify(sig->dsa_sig, sexp, key->dsa); - gcry_sexp_release(sexp); - if (err) { - ssh_set_error(session, SSH_FATAL, "Invalid DSA signature"); - if (gcry_err_code(err) != GPG_ERR_BAD_SIGNATURE) { - ssh_set_error(session, - SSH_FATAL, - "DSA verify error: %s", - gcry_strerror(err)); - } - return SSH_ERROR; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - err = gcry_sexp_build(&sexp, - NULL, - "(data(flags pkcs1)(hash sha1 %b))", - hlen, hash); - if (err) { - ssh_set_error(session, - SSH_FATAL, - "RSA hash error: %s", - gcry_strerror(err)); - return SSH_ERROR; - } - err = gcry_pk_verify(sig->rsa_sig, sexp, key->rsa); - gcry_sexp_release(sexp); - if (err) { - ssh_set_error(session, SSH_FATAL, "Invalid RSA signature"); - if (gcry_err_code(err) != GPG_ERR_BAD_SIGNATURE) { - ssh_set_error(session, - SSH_FATAL, - "RSA verify error: %s", - gcry_strerror(err)); - } - return SSH_ERROR; - } - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - ssh_set_error(session, SSH_FATAL, "Unknown public key type"); - return SSH_ERROR; - } - - return SSH_OK; -} - -ssh_signature pki_do_sign(const ssh_key privkey, - const unsigned char *hash, - size_t hlen) { - unsigned char ghash[hlen + 1]; - ssh_signature sig; - gcry_sexp_t sexp; - gcry_error_t err; - - sig = ssh_signature_new(); - if (sig == NULL) { - return NULL; - } - sig->type = privkey->type; - sig->type_c = privkey->type_c; - switch (privkey->type) { - case SSH_KEYTYPE_DSS: - /* That is to mark the number as positive */ - if(hash[0] >= 0x80) { - memcpy(ghash + 1, hash, hlen); - ghash[0] = 0; - hash = ghash; - hlen += 1; - } - - err = gcry_sexp_build(&sexp, NULL, "%b", hlen, hash); - if (err) { - ssh_signature_free(sig); - return NULL; - } - - err = gcry_pk_sign(&sig->dsa_sig, sexp, privkey->dsa); - gcry_sexp_release(sexp); - if (err) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - err = gcry_sexp_build(&sexp, - NULL, - "(data(flags pkcs1)(hash sha1 %b))", - hlen, - hash); - if (err) { - ssh_signature_free(sig); - return NULL; - } - - err = gcry_pk_sign(&sig->rsa_sig, sexp, privkey->rsa); - gcry_sexp_release(sexp); - if (err) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - ssh_signature_free(sig); - return NULL; - } - - return sig; -} - -#ifdef WITH_SERVER -ssh_signature pki_do_sign_sessionid(const ssh_key key, - const unsigned char *hash, - size_t hlen) -{ - unsigned char ghash[hlen + 1]; - ssh_signature sig; - gcry_sexp_t sexp; - gcry_error_t err; - - sig = ssh_signature_new(); - if (sig == NULL) { - return NULL; - } - sig->type = key->type; - sig->type_c = key->type_c; - - switch(key->type) { - case SSH_KEYTYPE_DSS: - /* That is to mark the number as positive */ - if(hash[0] >= 0x80) { - memcpy(ghash + 1, hash, hlen); - ghash[0] = 0; - hash = ghash; - hlen += 1; - } - - err = gcry_sexp_build(&sexp, NULL, "%b", hlen, hash); - if (err) { - ssh_signature_free(sig); - return NULL; - } - err = gcry_pk_sign(&sig->dsa_sig, sexp, key->dsa); - gcry_sexp_release(sexp); - if (err) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - err = gcry_sexp_build(&sexp, - NULL, - "(data(flags pkcs1)(hash sha1 %b))", - hlen, - hash); - if (err) { - ssh_signature_free(sig); - return NULL; - } - err = gcry_pk_sign(&sig->rsa_sig, sexp, key->rsa); - gcry_sexp_release(sexp); - if (err) { - ssh_signature_free(sig); - return NULL; - } - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_UNKNOWN: - return NULL; - } - - return sig; -} -#endif /* WITH_SERVER */ - -#endif /* HAVE_LIBGCRYPT */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/poll.c b/libssh/src/poll.c deleted file mode 100644 index 4e9f19f0..00000000 --- a/libssh/src/poll.c +++ /dev/null @@ -1,970 +0,0 @@ -/* - * poll.c - poll wrapper - * - * This file is part of the SSH Library - * - * Copyright (c) 2009-2013 by Andreas Schneider - * Copyright (c) 2003-2013 by Aris Adamantiadis - * Copyright (c) 2009 Aleksandar Kanchev - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - * - * vim: ts=2 sw=2 et cindent - */ - -#include "config.h" - -#include -#include - -#include "libssh/priv.h" -#include "libssh/libssh.h" -#include "libssh/poll.h" -#include "libssh/socket.h" -#include "libssh/session.h" -#ifdef WITH_SERVER -#include "libssh/server.h" -#include "libssh/misc.h" -#endif - - -#ifndef SSH_POLL_CTX_CHUNK -#define SSH_POLL_CTX_CHUNK 5 -#endif - -/** - * @defgroup libssh_poll The SSH poll functions. - * @ingroup libssh - * - * Add a generic way to handle sockets asynchronously. - * - * It's based on poll objects, each of which store a socket, its events and a - * callback, which gets called whenever an event is set. The poll objects are - * attached to a poll context, which should be allocated on per thread basis. - * - * Polling the poll context will poll all the attached poll objects and call - * their callbacks (handlers) if any of the socket events are set. This should - * be done within the main loop of an application. - * - * @{ - */ - -struct ssh_poll_handle_struct { - ssh_poll_ctx ctx; - ssh_session session; - union { - socket_t fd; - size_t idx; - } x; - short events; - int lock; - ssh_poll_callback cb; - void *cb_data; -}; - -struct ssh_poll_ctx_struct { - ssh_poll_handle *pollptrs; - ssh_pollfd_t *pollfds; - size_t polls_allocated; - size_t polls_used; - size_t chunk_size; -}; - -#ifdef HAVE_POLL -#include - -void ssh_poll_init(void) { - return; -} - -void ssh_poll_cleanup(void) { - return; -} - -int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) { - return poll((struct pollfd *) fds, nfds, timeout); -} - -#else /* HAVE_POLL */ - -typedef int (*poll_fn)(ssh_pollfd_t *, nfds_t, int); -static poll_fn ssh_poll_emu; - -#include - -#ifdef _WIN32 -#ifndef STRICT -#define STRICT -#endif /* STRICT */ - -#include -#include -#include -#else /* _WIN32 */ -#include -#include -#include -#endif /* _WIN32 */ - -#ifdef HAVE_UNISTD_H -#include -#endif - - -/* - * This is a poll(2)-emulation using select for systems not providing a native - * poll implementation. - * - * Keep in mind that select is terribly inefficient. The interface is simply not - * meant to be used with maximum descriptor value greater, say, 32 or so. With - * a value as high as 1024 on Linux you'll pay dearly in every single call. - * poll() will be orders of magnitude faster. - */ -static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) { - fd_set readfds, writefds, exceptfds; - struct timeval tv, *ptv; - socket_t max_fd; - int rc; - nfds_t i; - - if (fds == NULL) { - errno = EFAULT; - return -1; - } - - FD_ZERO (&readfds); - FD_ZERO (&writefds); - FD_ZERO (&exceptfds); - - /* compute fd_sets and find largest descriptor */ - for (rc = -1, max_fd = 0, i = 0; i < nfds; i++) { - if (fds[i].fd == SSH_INVALID_SOCKET) { - continue; - } -#ifndef _WIN32 - if (fds[i].fd >= FD_SETSIZE) { - rc = -1; - break; - } -#endif - - if (fds[i].events & (POLLIN | POLLRDNORM)) { - FD_SET (fds[i].fd, &readfds); - } - if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { - FD_SET (fds[i].fd, &writefds); - } - if (fds[i].events & (POLLPRI | POLLRDBAND)) { - FD_SET (fds[i].fd, &exceptfds); - } - if (fds[i].fd > max_fd && - (fds[i].events & (POLLIN | POLLOUT | POLLPRI | - POLLRDNORM | POLLRDBAND | - POLLWRNORM | POLLWRBAND))) { - max_fd = fds[i].fd; - rc = 0; - } - } - - if (max_fd == SSH_INVALID_SOCKET || rc == -1) { - errno = EINVAL; - return -1; - } - - if (timeout < 0) { - ptv = NULL; - } else { - ptv = &tv; - if (timeout == 0) { - tv.tv_sec = 0; - tv.tv_usec = 0; - } else { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - } - } - - rc = select (max_fd + 1, &readfds, &writefds, &exceptfds, ptv); - if (rc < 0) { - return -1; - } - - for (rc = 0, i = 0; i < nfds; i++) - if (fds[i].fd >= 0) { - fds[i].revents = 0; - - if (FD_ISSET(fds[i].fd, &readfds)) { - int save_errno = errno; - char data[64] = {0}; - int ret; - - /* support for POLLHUP */ - ret = recv(fds[i].fd, data, 64, MSG_PEEK); -#ifdef _WIN32 - if ((ret == -1) && - (errno == WSAESHUTDOWN || errno == WSAECONNRESET || - errno == WSAECONNABORTED || errno == WSAENETRESET)) { -#else - if ((ret == -1) && - (errno == ESHUTDOWN || errno == ECONNRESET || - errno == ECONNABORTED || errno == ENETRESET)) { -#endif - fds[i].revents |= POLLHUP; - } else { - fds[i].revents |= fds[i].events & (POLLIN | POLLRDNORM); - } - - errno = save_errno; - } - if (FD_ISSET(fds[i].fd, &writefds)) { - fds[i].revents |= fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND); - } - - if (FD_ISSET(fds[i].fd, &exceptfds)) { - fds[i].revents |= fds[i].events & (POLLPRI | POLLRDBAND); - } - - if (fds[i].revents & ~POLLHUP) { - rc++; - } - } else { - fds[i].revents = POLLNVAL; - } - - return rc; -} - -void ssh_poll_init(void) { - ssh_poll_emu = bsd_poll; -} - -void ssh_poll_cleanup(void) { - ssh_poll_emu = bsd_poll; -} - -int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) { - return (ssh_poll_emu)(fds, nfds, timeout); -} - -#endif /* HAVE_POLL */ - -/** - * @brief Allocate a new poll object, which could be used within a poll context. - * - * @param fd Socket that will be polled. - * @param events Poll events that will be monitored for the socket. i.e. - * POLLIN, POLLPRI, POLLOUT - * @param cb Function to be called if any of the events are set. - * The prototype of cb is: - * int (*ssh_poll_callback)(ssh_poll_handle p, socket_t fd, - * int revents, void *userdata); - * @param userdata Userdata to be passed to the callback function. NULL if - * not needed. - * - * @return A new poll object, NULL on error - */ - -ssh_poll_handle ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, - void *userdata) { - ssh_poll_handle p; - - p = malloc(sizeof(struct ssh_poll_handle_struct)); - if (p == NULL) { - return NULL; - } - ZERO_STRUCTP(p); - - p->x.fd = fd; - p->events = events; - p->cb = cb; - p->cb_data = userdata; - - return p; -} - - -/** - * @brief Free a poll object. - * - * @param p Pointer to an already allocated poll object. - */ - -void ssh_poll_free(ssh_poll_handle p) { - if(p->ctx != NULL){ - ssh_poll_ctx_remove(p->ctx,p); - p->ctx=NULL; - } - SAFE_FREE(p); -} - -/** - * @brief Get the poll context of a poll object. - * - * @param p Pointer to an already allocated poll object. - * - * @return Poll context or NULL if the poll object isn't attached. - */ -ssh_poll_ctx ssh_poll_get_ctx(ssh_poll_handle p) { - return p->ctx; -} - -/** - * @brief Get the events of a poll object. - * - * @param p Pointer to an already allocated poll object. - * - * @return Poll events. - */ -short ssh_poll_get_events(ssh_poll_handle p) { - return p->events; -} - -/** - * @brief Set the events of a poll object. The events will also be propagated - * to an associated poll context. - * - * @param p Pointer to an already allocated poll object. - * @param events Poll events. - */ -void ssh_poll_set_events(ssh_poll_handle p, short events) { - p->events = events; - if (p->ctx != NULL && !p->lock) { - p->ctx->pollfds[p->x.idx].events = events; - } -} - -/** - * @brief Set the file descriptor of a poll object. The FD will also be propagated - * to an associated poll context. - * - * @param p Pointer to an already allocated poll object. - * @param fd New file descriptor. - */ -void ssh_poll_set_fd(ssh_poll_handle p, socket_t fd) { - if (p->ctx != NULL) { - p->ctx->pollfds[p->x.idx].fd = fd; - } else { - p->x.fd = fd; - } -} - -/** - * @brief Add extra events to a poll object. Duplicates are ignored. - * The events will also be propagated to an associated poll context. - * - * @param p Pointer to an already allocated poll object. - * @param events Poll events. - */ -void ssh_poll_add_events(ssh_poll_handle p, short events) { - ssh_poll_set_events(p, ssh_poll_get_events(p) | events); -} - -/** - * @brief Remove events from a poll object. Non-existent are ignored. - * The events will also be propagated to an associated poll context. - * - * @param p Pointer to an already allocated poll object. - * @param events Poll events. - */ -void ssh_poll_remove_events(ssh_poll_handle p, short events) { - ssh_poll_set_events(p, ssh_poll_get_events(p) & ~events); -} - -/** - * @brief Get the raw socket of a poll object. - * - * @param p Pointer to an already allocated poll object. - * - * @return Raw socket. - */ - -socket_t ssh_poll_get_fd(ssh_poll_handle p) { - if (p->ctx != NULL) { - return p->ctx->pollfds[p->x.idx].fd; - } - - return p->x.fd; -} -/** - * @brief Set the callback of a poll object. - * - * @param p Pointer to an already allocated poll object. - * @param cb Function to be called if any of the events are set. - * @param userdata Userdata to be passed to the callback function. NULL if - * not needed. - */ -void ssh_poll_set_callback(ssh_poll_handle p, ssh_poll_callback cb, void *userdata) { - if (cb != NULL) { - p->cb = cb; - p->cb_data = userdata; - } -} - -/** - * @brief Create a new poll context. It could be associated with many poll object - * which are going to be polled at the same time as the poll context. You - * would need a single poll context per thread. - * - * @param chunk_size The size of the memory chunk that will be allocated, when - * more memory is needed. This is for efficiency reasons, - * i.e. don't allocate memory for each new poll object, but - * for the next 5. Set it to 0 if you want to use the - * library's default value. - */ -ssh_poll_ctx ssh_poll_ctx_new(size_t chunk_size) { - ssh_poll_ctx ctx; - - ctx = malloc(sizeof(struct ssh_poll_ctx_struct)); - if (ctx == NULL) { - return NULL; - } - ZERO_STRUCTP(ctx); - - if (chunk_size == 0) { - chunk_size = SSH_POLL_CTX_CHUNK; - } - - ctx->chunk_size = chunk_size; - - return ctx; -} - -/** - * @brief Free a poll context. - * - * @param ctx Pointer to an already allocated poll context. - */ -void ssh_poll_ctx_free(ssh_poll_ctx ctx) { - if (ctx->polls_allocated > 0) { - while (ctx->polls_used > 0){ - ssh_poll_handle p = ctx->pollptrs[0]; - /* - * The free function calls ssh_poll_ctx_remove() and decrements - * ctx->polls_used - */ - ssh_poll_free(p); - } - - SAFE_FREE(ctx->pollptrs); - SAFE_FREE(ctx->pollfds); - } - - SAFE_FREE(ctx); -} - -static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size) { - ssh_poll_handle *pollptrs; - ssh_pollfd_t *pollfds; - - pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * new_size); - if (pollptrs == NULL) { - return -1; - } - ctx->pollptrs = pollptrs; - - pollfds = realloc(ctx->pollfds, sizeof(ssh_pollfd_t) * new_size); - if (pollfds == NULL) { - pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * ctx->polls_allocated); - if (pollptrs == NULL) { - return -1; - } - ctx->pollptrs = pollptrs; - return -1; - } - - ctx->pollfds = pollfds; - ctx->polls_allocated = new_size; - - return 0; -} - -/** - * @brief Add a poll object to a poll context. - * - * @param ctx Pointer to an already allocated poll context. - * @param p Pointer to an already allocated poll object. - * - * @return 0 on success, < 0 on error - */ -int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p) { - socket_t fd; - - if (p->ctx != NULL) { - /* already attached to a context */ - return -1; - } - - if (ctx->polls_used == ctx->polls_allocated && - ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) { - return -1; - } - - fd = p->x.fd; - p->x.idx = ctx->polls_used++; - ctx->pollptrs[p->x.idx] = p; - ctx->pollfds[p->x.idx].fd = fd; - ctx->pollfds[p->x.idx].events = p->events; - ctx->pollfds[p->x.idx].revents = 0; - p->ctx = ctx; - - return 0; -} - -/** - * @brief Add a socket object to a poll context. - * - * @param ctx Pointer to an already allocated poll context. - * @param s A SSH socket handle - * - * @return 0 on success, < 0 on error - */ -int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s) { - ssh_poll_handle p_in, p_out; - int ret; - p_in=ssh_socket_get_poll_handle_in(s); - if(p_in==NULL) - return -1; - ret = ssh_poll_ctx_add(ctx,p_in); - if(ret != 0) - return ret; - p_out=ssh_socket_get_poll_handle_out(s); - if(p_in != p_out) - ret = ssh_poll_ctx_add(ctx,p_out); - return ret; -} - - -/** - * @brief Remove a poll object from a poll context. - * - * @param ctx Pointer to an already allocated poll context. - * @param p Pointer to an already allocated poll object. - */ -void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p) { - size_t i; - - i = p->x.idx; - p->x.fd = ctx->pollfds[i].fd; - p->ctx = NULL; - - ctx->polls_used--; - - /* fill the empty poll slot with the last one */ - if (ctx->polls_used > 0 && ctx->polls_used != i) { - ctx->pollfds[i] = ctx->pollfds[ctx->polls_used]; - ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used]; - ctx->pollptrs[i]->x.idx = i; - } - - /* this will always leave at least chunk_size polls allocated */ - if (ctx->polls_allocated - ctx->polls_used > ctx->chunk_size) { - ssh_poll_ctx_resize(ctx, ctx->polls_allocated - ctx->chunk_size); - } -} - -/** - * @brief Poll all the sockets associated through a poll object with a - * poll context. If any of the events are set after the poll, the - * call back function of the socket will be called. - * This function should be called once within the programs main loop. - * - * @param ctx Pointer to an already allocated poll context. - * @param timeout An upper limit on the time for which ssh_poll_ctx() will - * block, in milliseconds. Specifying a negative value - * means an infinite timeout. This parameter is passed to - * the poll() function. - * @returns SSH_OK No error. - * SSH_ERROR Error happened during the poll. - * SSH_AGAIN Timeout occured - */ - -int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) { - int rc; - int i, used; - ssh_poll_handle p; - socket_t fd; - int revents; - - if (!ctx->polls_used) - return SSH_ERROR; - - rc = ssh_poll(ctx->pollfds, ctx->polls_used, timeout); - if(rc < 0) - return SSH_ERROR; - if (rc == 0) - return SSH_AGAIN; - used = ctx->polls_used; - for (i = 0; i < used && rc > 0; ) { - if (!ctx->pollfds[i].revents || ctx->pollptrs[i]->lock) { - i++; - } else { - int ret; - - p = ctx->pollptrs[i]; - fd = ctx->pollfds[i].fd; - revents = ctx->pollfds[i].revents; - /* avoid having any event caught during callback */ - ctx->pollfds[i].events = 0; - p->lock = 1; - if (p->cb && (ret = p->cb(p, fd, revents, p->cb_data)) < 0) { - if (ret == -2) { - return -1; - } - /* the poll was removed, reload the used counter and start again */ - used = ctx->polls_used; - i=0; - } else { - ctx->pollfds[i].revents = 0; - ctx->pollfds[i].events = p->events; - p->lock = 0; - i++; - } - - rc--; - } - } - - return rc; -} - -/** - * @internal - * @brief gets the default poll structure for the current session, - * when used in blocking mode. - * @param session SSH session - * @returns the default ssh_poll_ctx - */ -ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session){ - if(session->default_poll_ctx != NULL) - return session->default_poll_ctx; - /* 2 is enough for the default one */ - session->default_poll_ctx = ssh_poll_ctx_new(2); - return session->default_poll_ctx; -} - -/* public event API */ - -struct ssh_event_fd_wrapper { - ssh_event_callback cb; - void * userdata; -}; - -struct ssh_event_struct { - ssh_poll_ctx ctx; -#ifdef WITH_SERVER - struct ssh_list *sessions; -#endif -}; - -/** - * @brief Create a new event context. It could be associated with many - * ssh_session objects and socket fd which are going to be polled at the - * same time as the event context. You would need a single event context - * per thread. - * - * @return The ssh_event object on success, NULL on failure. - */ -ssh_event ssh_event_new(void) { - ssh_event event; - - event = malloc(sizeof(struct ssh_event_struct)); - if (event == NULL) { - return NULL; - } - ZERO_STRUCTP(event); - - event->ctx = ssh_poll_ctx_new(2); - if(event->ctx == NULL) { - free(event); - return NULL; - } - -#ifdef WITH_SERVER - event->sessions = ssh_list_new(); - if(event->sessions == NULL) { - ssh_poll_ctx_free(event->ctx); - free(event); - return NULL; - } -#endif - - return event; -} - -static int ssh_event_fd_wrapper_callback(ssh_poll_handle p, socket_t fd, int revents, - void *userdata) { - struct ssh_event_fd_wrapper *pw = (struct ssh_event_fd_wrapper *)userdata; - - (void)p; - if(pw->cb != NULL) { - return pw->cb(fd, revents, pw->userdata); - } - return 0; -} - -/** - * @brief Add a fd to the event and assign it a callback, - * when used in blocking mode. - * @param event The ssh_event - * @param fd Socket that will be polled. - * @param events Poll events that will be monitored for the socket. i.e. - * POLLIN, POLLPRI, POLLOUT - * @param cb Function to be called if any of the events are set. - * The prototype of cb is: - * int (*ssh_event_callback)(socket_t fd, int revents, - * void *userdata); - * @param userdata Userdata to be passed to the callback function. NULL if - * not needed. - * - * @returns SSH_OK on success - * SSH_ERROR on failure - */ -int ssh_event_add_fd(ssh_event event, socket_t fd, short events, - ssh_event_callback cb, void *userdata) { - ssh_poll_handle p; - struct ssh_event_fd_wrapper *pw; - - if(event == NULL || event->ctx == NULL || cb == NULL - || fd == SSH_INVALID_SOCKET) { - return SSH_ERROR; - } - pw = malloc(sizeof(struct ssh_event_fd_wrapper)); - if(pw == NULL) { - return SSH_ERROR; - } - - pw->cb = cb; - pw->userdata = userdata; - - /* pw is freed by ssh_event_remove_fd */ - p = ssh_poll_new(fd, events, ssh_event_fd_wrapper_callback, pw); - if(p == NULL) { - free(pw); - return SSH_ERROR; - } - - if(ssh_poll_ctx_add(event->ctx, p) < 0) { - free(pw); - ssh_poll_free(p); - return SSH_ERROR; - } - return SSH_OK; -} - -/** - * @brief remove the poll handle from session and assign them to a event, - * when used in blocking mode. - * - * @param event The ssh_event object - * @param session The session to add to the event. - * - * @returns SSH_OK on success - * SSH_ERROR on failure - */ -int ssh_event_add_session(ssh_event event, ssh_session session) { - unsigned int i; - ssh_poll_handle p; -#ifdef WITH_SERVER - struct ssh_iterator *iterator; -#endif - - if(event == NULL || event->ctx == NULL || session == NULL) { - return SSH_ERROR; - } - if(session->default_poll_ctx == NULL) { - return SSH_ERROR; - } - for(i = 0; i < session->default_poll_ctx->polls_used; i++) { - p = session->default_poll_ctx->pollptrs[i]; - ssh_poll_ctx_remove(session->default_poll_ctx, p); - ssh_poll_ctx_add(event->ctx, p); - /* associate the pollhandler with a session so we can put it back - * at ssh_event_free() - */ - p->session = session; - } -#ifdef WITH_SERVER - iterator = ssh_list_get_iterator(event->sessions); - while(iterator != NULL) { - if((ssh_session)iterator->data == session) { - /* allow only one instance of this session */ - return SSH_OK; - } - iterator = iterator->next; - } - if(ssh_list_append(event->sessions, session) == SSH_ERROR) { - return SSH_ERROR; - } -#endif - return SSH_OK; -} - -/** - * @brief Poll all the sockets and sessions associated through an event object. - * If any of the events are set after the poll, the - * call back functions of the sessions or sockets will be called. - * This function should be called once within the programs main loop. - * - * @param event The ssh_event object to poll. - * @param timeout An upper limit on the time for which the poll will - * block, in milliseconds. Specifying a negative value - * means an infinite timeout. This parameter is passed to - * the poll() function. - * @returns SSH_OK No error. - * SSH_ERROR Error happened during the poll. - */ -int ssh_event_dopoll(ssh_event event, int timeout) { - int rc; - - if(event == NULL || event->ctx == NULL) { - return SSH_ERROR; - } - rc = ssh_poll_ctx_dopoll(event->ctx, timeout); - return rc; -} - -/** - * @brief Remove a socket fd from an event context. - * - * @param event The ssh_event object. - * @param fd The fd to remove. - * - * @returns SSH_OK on success - * SSH_ERROR on failure - */ -int ssh_event_remove_fd(ssh_event event, socket_t fd) { - register size_t i, used; - int rc = SSH_ERROR; - - if(event == NULL || event->ctx == NULL) { - return SSH_ERROR; - } - - used = event->ctx->polls_used; - for (i = 0; i < used; i++) { - if(fd == event->ctx->pollfds[i].fd) { - ssh_poll_handle p = event->ctx->pollptrs[i]; - if (p->session != NULL){ - /* we cannot free that handle, it's owned by its session */ - continue; - } - if (p->cb == ssh_event_fd_wrapper_callback) { - struct ssh_event_fd_wrapper *pw = p->cb_data; - SAFE_FREE(pw); - } - - /* - * The free function calls ssh_poll_ctx_remove() and decrements - * event->ctx->polls_used. - */ - ssh_poll_free(p); - rc = SSH_OK; - - /* restart the loop */ - used = event->ctx->polls_used; - i = 0; - } - } - - return rc; -} - -/** - * @brief Remove a session object from an event context. - * - * @param event The ssh_event object. - * @param session The session to remove. - * - * @returns SSH_OK on success - * SSH_ERROR on failure - */ -int ssh_event_remove_session(ssh_event event, ssh_session session) { - ssh_poll_handle p; - register size_t i, used; - int rc = SSH_ERROR; -#ifdef WITH_SERVER - struct ssh_iterator *iterator; -#endif - - if(event == NULL || event->ctx == NULL || session == NULL) { - return SSH_ERROR; - } - - used = event->ctx->polls_used; - for(i = 0; i < used; i++) { - p = event->ctx->pollptrs[i]; - if(p->session == session){ - ssh_poll_ctx_remove(event->ctx, p); - p->session = NULL; - ssh_poll_ctx_add(session->default_poll_ctx, p); - rc = SSH_OK; - used = 0; - } - } -#ifdef WITH_SERVER - iterator = ssh_list_get_iterator(event->sessions); - while(iterator != NULL) { - if((ssh_session)iterator->data == session) { - ssh_list_remove(event->sessions, iterator); - /* there should be only one instance of this session */ - break; - } - iterator = iterator->next; - } -#endif - - return rc; -} - -/** - * @brief Free an event context. - * - * @param event The ssh_event object to free. - * Note: you have to manually remove sessions and socket - * fds before freeing the event object. - * - */ -void ssh_event_free(ssh_event event) { - int used, i; - ssh_poll_handle p; - if(event == NULL) { - return; - } - if(event->ctx != NULL) { - used = event->ctx->polls_used; - for(i = 0; i < used; i++) { - p = event->ctx->pollptrs[i]; - if(p->session != NULL){ - ssh_poll_ctx_remove(event->ctx, p); - ssh_poll_ctx_add(p->session->default_poll_ctx, p); - p->session = NULL; - used = 0; - } - } - - ssh_poll_ctx_free(event->ctx); - } -#ifdef WITH_SERVER - if(event->sessions != NULL) { - ssh_list_free(event->sessions); - } -#endif - free(event); -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/sc25519.c b/libssh/src/sc25519.c deleted file mode 100644 index 9576d416..00000000 --- a/libssh/src/sc25519.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, - * Peter Schwabe, Bo-Yin Yang. - * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c - */ - -#include "libssh/priv.h" -#include "libssh/sc25519.h" - -/*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */ - -static const uint32_t m[32] = { - 0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, - 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 -}; - -static const uint32_t mu[33] = { - 0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, - 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, - 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F -}; - -static uint32_t lt(uint32_t a,uint32_t b) /* 16-bit inputs */ -{ - unsigned int x = a; - - x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ - x >>= 31; /* 0: no; 1: yes */ - - return x; -} - -/* Reduce coefficients of r before calling reduce_add_sub */ -static void reduce_add_sub(sc25519 *r) -{ - uint32_t pb = 0; - uint32_t b; - uint32_t mask; - int i; - unsigned char t[32]; - - for (i = 0; i < 32; i++) { - pb += m[i]; - b = lt(r->v[i],pb); - t[i] = r->v[i]-pb+(b<<8); - pb = b; - } - mask = b - 1; - for (i = 0; i < 32; i++) { - r->v[i] ^= mask & (r->v[i] ^ t[i]); - } -} - -/* Reduce coefficients of x before calling barrett_reduce */ -static void barrett_reduce(sc25519 *r, const uint32_t x[64]) -{ - /* See HAC, Alg. 14.42 */ - int i,j; - uint32_t q2[66]; - uint32_t *q3 = q2 + 33; - uint32_t r1[33]; - uint32_t r2[33]; - uint32_t carry; - uint32_t pb = 0; - uint32_t b; - - for (i = 0; i < 66; i++) { - q2[i] = 0; - } - for (i = 0; i < 33; i++) { - r2[i] = 0; - } - - for (i = 0; i < 33; i++) { - for (j = 0; j < 33; j++) { - if (i + j >= 31) { - q2[i+j] += mu[i]*x[j+31]; - } - } - } - - carry = q2[31] >> 8; - q2[32] += carry; - carry = q2[32] >> 8; - q2[33] += carry; - - for (i = 0; i < 33; i++) { - r1[i] = x[i]; - } - - for (i = 0; i < 32; i++) { - for (j = 0; j < 33; j++) { - if (i + j < 33) { - r2[i+j] += m[i]*q3[j]; - } - } - } - - for (i = 0; i < 32; i++) { - carry = r2[i] >> 8; - r2[i+1] += carry; - r2[i] &= 0xff; - } - - for (i = 0; i < 32; i++) { - pb += r2[i]; - b = lt(r1[i],pb); - r->v[i] = r1[i]-pb+(b<<8); - pb = b; - } - - /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 - * If so: Handle it here! - */ - - reduce_add_sub(r); - reduce_add_sub(r); -} - -void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) -{ - int i; - uint32_t t[64]; - - for (i = 0; i < 32; i++) { - t[i] = x[i]; - } - for (i = 32; i < 64; i++) { - t[i] = 0; - } - - barrett_reduce(r, t); -} - -void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]) -{ - int i; - - for (i = 0; i < 16; i++) { - r->v[i] = x[i]; - } -} - -void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) -{ - int i; - uint32_t t[64]; - - for (i = 0; i < 64; i++) { - t[i] = x[i]; - } - - barrett_reduce(r, t); -} - -void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x) -{ - int i; - - for (i = 0; i < 16; i++) { - r->v[i] = x->v[i]; - } - for (i = 0; i < 16; i++) { - r->v[16+i] = 0; - } -} - -void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) -{ - int i; - - for (i = 0; i < 32; i++) { - r[i] = x->v[i]; - } -} - -int sc25519_iszero_vartime(const sc25519 *x) -{ - int i; - - for (i = 0; i < 32; i++) { - if(x->v[i] != 0) { - return 0; - } - } - - return 1; -} - -int sc25519_isshort_vartime(const sc25519 *x) -{ - int i; - - for (i = 31; i > 15; i--) { - if (x->v[i] != 0) { - return 0; - } - } - - return 1; -} - -int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y) -{ - int i; - - for (i = 31; i >= 0; i--) { - if (x->v[i] < y->v[i]) { - return 1; - } - if (x->v[i] > y->v[i]) { - return 0; - } - } - - return 0; -} - -void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y) -{ - int i, carry; - - for (i = 0; i < 32; i++) { - r->v[i] = x->v[i] + y->v[i]; - } - - for (i = 0;i < 31; i++) { - carry = r->v[i] >> 8; - r->v[i+1] += carry; - r->v[i] &= 0xff; - } - - reduce_add_sub(r); -} - -void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y) -{ - uint32_t b = 0; - uint32_t t; - int i; - - for (i = 0; i < 32; i++) { - t = x->v[i] - y->v[i] - b; - r->v[i] = t & 255; - b = (t >> 8) & 1; - } -} - -void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y) -{ - int i,j,carry; - uint32_t t[64]; - - for (i = 0; i < 64; i++) { - t[i] = 0; - } - - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - t[i+j] += x->v[i] * y->v[j]; - } - } - - /* Reduce coefficients */ - for (i = 0; i < 63; i++) { - carry = t[i] >> 8; - t[i+1] += carry; - t[i] &= 0xff; - } - - barrett_reduce(r, t); -} - -void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y) -{ - sc25519 t; - sc25519_from_shortsc(&t, y); - sc25519_mul(r, x, &t); -} - -void sc25519_window3(signed char r[85], const sc25519 *s) -{ - char carry; - int i; - - for (i = 0; i < 10; i++) { - r[8*i+0] = s->v[3*i+0] & 7; - r[8*i+1] = (s->v[3*i+0] >> 3) & 7; - r[8*i+2] = (s->v[3*i+0] >> 6) & 7; - r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; - r[8*i+3] = (s->v[3*i+1] >> 1) & 7; - r[8*i+4] = (s->v[3*i+1] >> 4) & 7; - r[8*i+5] = (s->v[3*i+1] >> 7) & 7; - r[8*i+5] ^= (s->v[3*i+2] << 1) & 7; - r[8*i+6] = (s->v[3*i+2] >> 2) & 7; - r[8*i+7] = (s->v[3*i+2] >> 5) & 7; - } - r[8*i+0] = s->v[3*i+0] & 7; - r[8*i+1] = (s->v[3*i+0] >> 3) & 7; - r[8*i+2] = (s->v[3*i+0] >> 6) & 7; - r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; - r[8*i+3] = (s->v[3*i+1] >> 1) & 7; - r[8*i+4] = (s->v[3*i+1] >> 4) & 7; - - /* Making it signed */ - carry = 0; - for (i = 0; i < 84; i++) { - r[i] += carry; - r[i+1] += r[i] >> 3; - r[i] &= 7; - carry = r[i] >> 2; - r[i] -= carry<<3; - } - - r[84] += carry; -} - -void sc25519_window5(signed char r[51], const sc25519 *s) -{ - char carry; - int i; - - for (i = 0; i < 6; i++) { - r[8*i+0] = s->v[5*i+0] & 31; - r[8*i+1] = (s->v[5*i+0] >> 5) & 31; - r[8*i+1] ^= (s->v[5*i+1] << 3) & 31; - r[8*i+2] = (s->v[5*i+1] >> 2) & 31; - r[8*i+3] = (s->v[5*i+1] >> 7) & 31; - r[8*i+3] ^= (s->v[5*i+2] << 1) & 31; - r[8*i+4] = (s->v[5*i+2] >> 4) & 31; - r[8*i+4] ^= (s->v[5*i+3] << 4) & 31; - r[8*i+5] = (s->v[5*i+3] >> 1) & 31; - r[8*i+6] = (s->v[5*i+3] >> 6) & 31; - r[8*i+6] ^= (s->v[5*i+4] << 2) & 31; - r[8*i+7] = (s->v[5*i+4] >> 3) & 31; - } - r[8*i+0] = s->v[5*i+0] & 31; - r[8*i+1] = (s->v[5*i+0] >> 5) & 31; - r[8*i+1] ^= (s->v[5*i+1] << 3) & 31; - r[8*i+2] = (s->v[5*i+1] >> 2) & 31; - - /* Making it signed */ - carry = 0; - for (i = 0; i < 50; i++) { - r[i] += carry; - r[i+1] += r[i] >> 5; - r[i] &= 31; - carry = r[i] >> 4; - r[i] -= carry<<5; - } - - r[50] += carry; -} - -void sc25519_2interleave2(unsigned char r[127], - const sc25519 *s1, - const sc25519 *s2) -{ - int i; - - for (i = 0; i < 31; i++) { - r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2); - r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2); - r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2); - r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2); - } - r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2); - r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2); - r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2); -} diff --git a/libssh/src/scp.c b/libssh/src/scp.c deleted file mode 100644 index 0208ddc5..00000000 --- a/libssh/src/scp.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * scp - SSH scp wrapper functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/scp.h" - -/** - * @defgroup libssh_scp The SSH scp functions - * @ingroup libssh - * - * SCP protocol over SSH functions - * - * @{ - */ - -/** - * @brief Create a new scp session. - * - * @param[in] session The SSH session to use. - * - * @param[in] mode One of SSH_SCP_WRITE or SSH_SCP_READ, depending if you - * need to drop files remotely or read them. - * It is not possible to combine read and write. - * SSH_SCP_RECURSIVE Flag can be or'ed to this to indicate - * that you're going to use recursion. Browsing through - * directories is not possible without this. - * - * @param[in] location The directory in which write or read will be done. Any - * push or pull will be relative to this place. - * This can also be a pattern of files to download (read). - * - * @returns A ssh_scp handle, NULL if the creation was impossible. - */ -ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location){ - ssh_scp scp=malloc(sizeof(struct ssh_scp_struct)); - if(scp == NULL){ - ssh_set_error(session,SSH_FATAL,"Error allocating memory for ssh_scp"); - return NULL; - } - ZERO_STRUCTP(scp); - if((mode&~SSH_SCP_RECURSIVE) != SSH_SCP_WRITE && (mode &~SSH_SCP_RECURSIVE) != SSH_SCP_READ){ - ssh_set_error(session,SSH_FATAL,"Invalid mode %d for ssh_scp_new()",mode); - ssh_scp_free(scp); - return NULL; - } - scp->location=strdup(location); - if (scp->location == NULL) { - ssh_set_error(session,SSH_FATAL,"Error allocating memory for ssh_scp"); - ssh_scp_free(scp); - return NULL; - } - scp->session=session; - scp->mode=mode & ~SSH_SCP_RECURSIVE; - scp->recursive = (mode & SSH_SCP_RECURSIVE) != 0; - scp->channel=NULL; - scp->state=SSH_SCP_NEW; - return scp; -} - -/** - * @brief Initialize the scp channel. - * - * @param[in] scp The scp context to initialize. - * - * @return SSH_OK on success or an SSH error code. - * - * @see ssh_scp_new() - */ -int ssh_scp_init(ssh_scp scp) -{ - int r; - char execbuffer[1024]; - uint8_t code; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_NEW){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state"); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'", - scp->mode==SSH_SCP_WRITE?"write":"read", - scp->recursive?"recursive ":"", - scp->location); - scp->channel=ssh_channel_new(scp->session); - if(scp->channel == NULL){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - r= ssh_channel_open_session(scp->channel); - if(r==SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - if(scp->mode == SSH_SCP_WRITE) - snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s", - scp->recursive ? "-r":"", scp->location); - else - snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s", - scp->recursive ? "-r":"", scp->location); - if(ssh_channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - if(scp->mode == SSH_SCP_WRITE){ - r=ssh_channel_read(scp->channel,&code,1,0); - if(r<=0){ - ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - if(code != 0){ - ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - } else { - ssh_channel_write(scp->channel,"",1); - } - if(scp->mode == SSH_SCP_WRITE) - scp->state=SSH_SCP_WRITE_INITED; - else - scp->state=SSH_SCP_READ_INITED; - return SSH_OK; -} - -/** - * @brief Close the scp channel. - * - * @param[in] scp The scp context to close. - * - * @return SSH_OK on success or an SSH error code. - * - * @see ssh_scp_init() - */ -int ssh_scp_close(ssh_scp scp) -{ - char buffer[128]; - int err; - if(scp==NULL) - return SSH_ERROR; - if(scp->channel != NULL){ - if(ssh_channel_send_eof(scp->channel) == SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - /* avoid situations where data are buffered and - * not yet stored on disk. This can happen if the close is sent - * before we got the EOF back - */ - while(!ssh_channel_is_eof(scp->channel)){ - err=ssh_channel_read(scp->channel,buffer,sizeof(buffer),0); - if(err==SSH_ERROR || err==0) - break; - } - if(ssh_channel_close(scp->channel) == SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - ssh_channel_free(scp->channel); - scp->channel=NULL; - } - scp->state=SSH_SCP_NEW; - return SSH_OK; -} - -/** - * @brief Free a scp context. - * - * @param[in] scp The context to free. - * - * @see ssh_scp_new() - */ -void ssh_scp_free(ssh_scp scp) -{ - if(scp==NULL) - return; - if(scp->state != SSH_SCP_NEW) - ssh_scp_close(scp); - if(scp->channel) - ssh_channel_free(scp->channel); - SAFE_FREE(scp->location); - SAFE_FREE(scp->request_name); - SAFE_FREE(scp->warning); - SAFE_FREE(scp); -} - -/** - * @brief Create a directory in a scp in sink mode. - * - * @param[in] scp The scp handle. - * - * @param[in] dirname The name of the directory being created. - * - * @param[in] mode The UNIX permissions for the new directory, e.g. 0755. - * - * @returns SSH_OK if the directory has been created, SSH_ERROR if - * an error occured. - * - * @see ssh_scp_leave_directory() - */ -int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){ - char buffer[1024]; - int r; - uint8_t code; - char *dir; - char *perms; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_WRITE_INITED){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_directory called under invalid state"); - return SSH_ERROR; - } - dir=ssh_basename(dirname); - perms=ssh_scp_string_mode(mode); - snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir); - SAFE_FREE(dir); - SAFE_FREE(perms); - r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); - if(r==SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - r=ssh_channel_read(scp->channel,&code,1,0); - if(r<=0){ - ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - if(code != 0){ - ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - return SSH_OK; -} - -/** - * @brief Leave a directory. - * - * @returns SSH_OK if the directory has been left,SSH_ERROR if an - * error occured. - * - * @see ssh_scp_push_directory() - */ - int ssh_scp_leave_directory(ssh_scp scp){ - char buffer[]="E\n"; - int r; - uint8_t code; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_WRITE_INITED){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_leave_directory called under invalid state"); - return SSH_ERROR; - } - r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); - if(r==SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - r=ssh_channel_read(scp->channel,&code,1,0); - if(r<=0){ - ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - if(code != 0){ - ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - return SSH_OK; -} - -/** - * @brief Initialize the sending of a file to a scp in sink mode, using a 64-bit size. - * - * @param[in] scp The scp handle. - * - * @param[in] filename The name of the file being sent. It should not contain - * any path indicator - * - * @param[in] size Exact size in bytes of the file being sent. - * - * @param[in] mode The UNIX permissions for the new file, e.g. 0644. - * - * @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an - * error occured. - * - * @see ssh_scp_push_file() - */ -int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int mode){ - char buffer[1024]; - int r; - uint8_t code; - char *file; - char *perms; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_WRITE_INITED){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state"); - return SSH_ERROR; - } - file=ssh_basename(filename); - perms=ssh_scp_string_mode(mode); - SSH_LOG(SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIu64 " with permissions '%s'",file,size,perms); - snprintf(buffer, sizeof(buffer), "C%s %" PRIu64 " %s\n", perms, size, file); - SAFE_FREE(file); - SAFE_FREE(perms); - r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); - if(r==SSH_ERROR){ - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - r=ssh_channel_read(scp->channel,&code,1,0); - if(r<=0){ - ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - if(code != 0){ - ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - scp->filelen = size; - scp->processed = 0; - scp->state=SSH_SCP_WRITE_WRITING; - return SSH_OK; -} - -/** - * @brief Initialize the sending of a file to a scp in sink mode. - * - * @param[in] scp The scp handle. - * - * @param[in] filename The name of the file being sent. It should not contain - * any path indicator - * - * @param[in] size Exact size in bytes of the file being sent. - * - * @param[in] mode The UNIX permissions for the new file, e.g. 0644. - * - * @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an - * error occured. - */ -int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){ - return ssh_scp_push_file64(scp, filename, (uint64_t) size, mode); -} - -/** - * @internal - * - * @brief Wait for a response of the scp server. - * - * @param[in] scp The scp handle. - * - * @param[out] response A pointer where the response message must be copied if - * any. This pointer must then be free'd. - * - * @returns The return code, SSH_ERROR a error occured. - */ -int ssh_scp_response(ssh_scp scp, char **response){ - unsigned char code; - int r; - char msg[128]; - if(scp==NULL) - return SSH_ERROR; - r=ssh_channel_read(scp->channel,&code,1,0); - if(r == SSH_ERROR) - return SSH_ERROR; - if(code == 0) - return 0; - if(code > 2){ - ssh_set_error(scp->session,SSH_FATAL, "SCP: invalid status code %ud received", code); - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - r=ssh_scp_read_string(scp,msg,sizeof(msg)); - if(r==SSH_ERROR) - return r; - /* Warning */ - if(code == 1){ - ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Warning: status code 1 received: %s", msg); - SSH_LOG(SSH_LOG_RARE,"SCP: Warning: status code 1 received: %s", msg); - if(response) - *response=strdup(msg); - return 1; - } - if(code == 2){ - ssh_set_error(scp->session,SSH_FATAL, "SCP: Error: status code 2 received: %s", msg); - if(response) - *response=strdup(msg); - return 2; - } - /* Not reached */ - return SSH_ERROR; -} - -/** - * @brief Write into a remote scp file. - * - * @param[in] scp The scp handle. - * - * @param[in] buffer The buffer to write. - * - * @param[in] len The number of bytes to write. - * - * @returns SSH_OK if the write was successful, SSH_ERROR an error - * occured while writing. - */ -int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ - int w; - int r; - uint8_t code; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_WRITE_WRITING){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state"); - return SSH_ERROR; - } - if(scp->processed + len > scp->filelen) - len = (size_t) (scp->filelen - scp->processed); - /* hack to avoid waiting for window change */ - r = ssh_channel_poll(scp->channel, 0); - if (r == SSH_ERROR) { - scp->state = SSH_SCP_ERROR; - return SSH_ERROR; - } - w=ssh_channel_write(scp->channel,buffer,len); - if(w != SSH_ERROR) - scp->processed += w; - else { - scp->state=SSH_SCP_ERROR; - //return=channel_get_exit_status(scp->channel); - return SSH_ERROR; - } - /* Far end sometimes send a status message, which we need to read - * and handle */ - r = ssh_channel_poll(scp->channel,0); - if(r > 0){ - r = ssh_channel_read(scp->channel, &code, 1, 0); - if(r == SSH_ERROR){ - return SSH_ERROR; - } - if(code == 1 || code == 2){ - ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Error: status code %i received", code); - return SSH_ERROR; - } - } - /* Check if we arrived at end of file */ - if(scp->processed == scp->filelen) { - code = 0; - w = ssh_channel_write(scp->channel, &code, 1); - if(w == SSH_ERROR){ - scp->state = SSH_SCP_ERROR; - return SSH_ERROR; - } - scp->processed=scp->filelen=0; - scp->state=SSH_SCP_WRITE_INITED; - } - return SSH_OK; -} - -/** - * @brief Read a string on a channel, terminated by '\n' - * - * @param[in] scp The scp handle. - * - * @param[out] buffer A pointer to a buffer to place the string. - * - * @param[in] len The size of the buffer in bytes. If the string is bigger - * than len-1, only len-1 bytes are read and the string is - * null-terminated. - * - * @returns SSH_OK if the string was read, SSH_ERROR if an error - * occured while reading. - */ -int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len){ - size_t r=0; - int err=SSH_OK; - if(scp==NULL) - return SSH_ERROR; - while(rchannel,&buffer[r],1,0); - if(err==SSH_ERROR){ - break; - } - if(err==0){ - ssh_set_error(scp->session,SSH_FATAL,"End of file while reading string"); - err=SSH_ERROR; - break; - } - r++; - if(buffer[r-1] == '\n') - break; - } - buffer[r]=0; - return err; -} - -/** - * @brief Wait for a scp request (file, directory). - * - * @returns SSH_SCP_REQUEST_NEWFILE: The other side is sending - * a file - * SSH_SCP_REQUEST_NEWDIR: The other side is sending - * a directory - * SSH_SCP_REQUEST_ENDDIR: The other side has - * finished with the current - * directory - * SSH_SCP_REQUEST_WARNING: The other side sent us a warning - * SSH_SCP_REQUEST_EOF: The other side finished sending us - * files and data. - * SSH_ERROR: Some error happened - * - * @see ssh_scp_read() - * @see ssh_scp_deny_request() - * @see ssh_scp_accept_request() - * @see ssh_scp_request_get_warning() - */ -int ssh_scp_pull_request(ssh_scp scp){ - char buffer[MAX_BUF_SIZE] = {0}; - char *mode=NULL; - char *p,*tmp; - uint64_t size; - char *name=NULL; - int err; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_READ_INITED){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state"); - return SSH_ERROR; - } - err=ssh_scp_read_string(scp,buffer,sizeof(buffer)); - if(err==SSH_ERROR){ - if(ssh_channel_is_eof(scp->channel)){ - scp->state=SSH_SCP_TERMINATED; - return SSH_SCP_REQUEST_EOF; - } - return err; - } - p=strchr(buffer,'\n'); - if(p!=NULL) - *p='\0'; - SSH_LOG(SSH_LOG_PROTOCOL,"Received SCP request: '%s'",buffer); - switch(buffer[0]){ - case 'C': - /* File */ - case 'D': - /* Directory */ - p=strchr(buffer,' '); - if(p==NULL) - goto error; - *p='\0'; - p++; - //mode=strdup(&buffer[1]); - scp->request_mode=ssh_scp_integer_mode(&buffer[1]); - tmp=p; - p=strchr(p,' '); - if(p==NULL) - goto error; - *p=0; - size = strtoull(tmp,NULL,10); - p++; - name=strdup(p); - SAFE_FREE(scp->request_name); - scp->request_name=name; - if(buffer[0]=='C'){ - scp->filelen=size; - scp->request_type=SSH_SCP_REQUEST_NEWFILE; - } else { - scp->filelen='0'; - scp->request_type=SSH_SCP_REQUEST_NEWDIR; - } - scp->state=SSH_SCP_READ_REQUESTED; - scp->processed = 0; - return scp->request_type; - break; - case 'E': - scp->request_type=SSH_SCP_REQUEST_ENDDIR; - ssh_channel_write(scp->channel,"",1); - return scp->request_type; - case 0x1: - ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]); - scp->request_type=SSH_SCP_REQUEST_WARNING; - SAFE_FREE(scp->warning); - scp->warning=strdup(&buffer[1]); - return scp->request_type; - case 0x2: - ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]); - return SSH_ERROR; - case 'T': - /* Timestamp */ - default: - ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer); - return SSH_ERROR; - } - - /* a parsing error occured */ - error: - SAFE_FREE(name); - SAFE_FREE(mode); - ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer); - return SSH_ERROR; -} - -/** - * @brief Deny the transfer of a file or creation of a directory coming from the - * remote party. - * - * @param[in] scp The scp handle. - * @param[in] reason A nul-terminated string with a human-readable - * explanation of the deny. - * - * @returns SSH_OK if the message was sent, SSH_ERROR if the sending - * the message failed, or sending it in a bad state. - */ -int ssh_scp_deny_request(ssh_scp scp, const char *reason){ - char buffer[MAX_BUF_SIZE]; - int err; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_READ_REQUESTED){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state"); - return SSH_ERROR; - } - snprintf(buffer,sizeof(buffer),"%c%s\n",2,reason); - err=ssh_channel_write(scp->channel,buffer,strlen(buffer)); - if(err==SSH_ERROR) { - return SSH_ERROR; - } - else { - scp->state=SSH_SCP_READ_INITED; - return SSH_OK; - } -} - -/** - * @brief Accepts transfer of a file or creation of a directory coming from the - * remote party. - * - * @param[in] scp The scp handle. - * - * @returns SSH_OK if the message was sent, SSH_ERROR if sending the - * message failed, or sending it in a bad state. - */ -int ssh_scp_accept_request(ssh_scp scp){ - char buffer[]={0x00}; - int err; - if(scp==NULL) - return SSH_ERROR; - if(scp->state != SSH_SCP_READ_REQUESTED){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state"); - return SSH_ERROR; - } - err=ssh_channel_write(scp->channel,buffer,1); - if(err==SSH_ERROR) { - return SSH_ERROR; - } - if(scp->request_type==SSH_SCP_REQUEST_NEWFILE) - scp->state=SSH_SCP_READ_READING; - else - scp->state=SSH_SCP_READ_INITED; - return SSH_OK; -} - -/** @brief Read from a remote scp file - * @param[in] scp The scp handle. - * - * @param[in] buffer The destination buffer. - * - * @param[in] size The size of the buffer. - * - * @returns The nNumber of bytes read, SSH_ERROR if an error occured - * while reading. - */ -int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){ - int r; - int code; - if(scp==NULL) - return SSH_ERROR; - if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){ - r=ssh_scp_accept_request(scp); - if(r==SSH_ERROR) - return r; - } - if(scp->state != SSH_SCP_READ_READING){ - ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_read called under invalid state"); - return SSH_ERROR; - } - if(scp->processed + size > scp->filelen) - size = (size_t) (scp->filelen - scp->processed); - if(size > 65536) - size=65536; /* avoid too large reads */ - r=ssh_channel_read(scp->channel,buffer,size,0); - if(r != SSH_ERROR) - scp->processed += r; - else { - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - /* Check if we arrived at end of file */ - if(scp->processed == scp->filelen) { - scp->processed=scp->filelen=0; - ssh_channel_write(scp->channel,"",1); - code=ssh_scp_response(scp,NULL); - if(code == 0){ - scp->state=SSH_SCP_READ_INITED; - return r; - } - if(code==1){ - scp->state=SSH_SCP_READ_INITED; - return SSH_ERROR; - } - scp->state=SSH_SCP_ERROR; - return SSH_ERROR; - } - return r; -} - -/** - * @brief Get the name of the directory or file being pushed from the other - * party. - * - * @returns The file name, NULL on error. The string should not be - * freed. - */ -const char *ssh_scp_request_get_filename(ssh_scp scp){ - if(scp==NULL) - return NULL; - return scp->request_name; -} - -/** - * @brief Get the permissions of the directory or file being pushed from the - * other party. - * - * @returns The UNIX permission, e.g 0644, -1 on error. - */ -int ssh_scp_request_get_permissions(ssh_scp scp){ - if(scp==NULL) - return -1; - return scp->request_mode; -} - -/** @brief Get the size of the file being pushed from the other party. - * - * @returns The numeric size of the file being read. - * @warning The real size may not fit in a 32 bits field and may - * be truncated. - * @see ssh_scp_request_get_size64() - */ -size_t ssh_scp_request_get_size(ssh_scp scp){ - if(scp==NULL) - return 0; - return (size_t)scp->filelen; -} - -/** @brief Get the size of the file being pushed from the other party. - * - * @returns The numeric size of the file being read. - */ -uint64_t ssh_scp_request_get_size64(ssh_scp scp){ - if(scp==NULL) - return 0; - return scp->filelen; -} - -/** - * @brief Convert a scp text mode to an integer. - * - * @param[in] mode The mode to convert, e.g. "0644". - * - * @returns An integer value, e.g. 420 for "0644". - */ -int ssh_scp_integer_mode(const char *mode){ - int value=strtoul(mode,NULL,8) & 0xffff; - return value; -} - -/** - * @brief Convert a unix mode into a scp string. - * - * @param[in] mode The mode to convert, e.g. 420 or 0644. - * - * @returns A pointer to a malloc'ed string containing the scp mode, - * e.g. "0644". - */ -char *ssh_scp_string_mode(int mode){ - char buffer[16]; - snprintf(buffer,sizeof(buffer),"%.4o",mode); - return strdup(buffer); -} - -/** - * @brief Get the warning string from a scp handle. - * - * @param[in] scp The scp handle. - * - * @returns A warning string, or NULL on error. The string should - * not be freed. - */ -const char *ssh_scp_request_get_warning(ssh_scp scp){ - if(scp==NULL) - return NULL; - return scp->warning; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/server.c b/libssh/src/server.c deleted file mode 100644 index 3a38fc7b..00000000 --- a/libssh/src/server.c +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * server.c - functions for creating a SSH server - * - * This file is part of the SSH Library - * - * Copyright (c) 2004-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -# include -# include - - /* - * is necessary for getaddrinfo before Windows XP, but it isn't - * available on some platforms like MinGW. - */ -# ifdef HAVE_WSPIAPI_H -# include -# endif -#else -# include -#endif - -#include "libssh/priv.h" -#include "libssh/libssh.h" -#include "libssh/server.h" -#include "libssh/ssh2.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/socket.h" -#include "libssh/session.h" -#include "libssh/kex.h" -#include "libssh/misc.h" -#include "libssh/pki.h" -#include "libssh/dh.h" -#include "libssh/messages.h" -#include "libssh/options.h" -#include "libssh/curve25519.h" - -#define set_status(session, status) do {\ - if (session->common.callbacks && session->common.callbacks->connect_status_function) \ - session->common.callbacks->connect_status_function(session->common.callbacks->userdata, status); \ - } while (0) - -static int dh_handshake_server(ssh_session session); - - -/** - * @addtogroup libssh_server - * - * @{ - */ - -/** @internal - * This functions sets the Key Exchange protocols to be accepted - * by the server. They depend on - * -What the user asked (via options) - * -What is available (keys) - * It should then accept the intersection of what the user asked - * and what is available, and return an error if nothing matches - */ - -static int server_set_kex(ssh_session session) { - struct ssh_kex_struct *server = &session->next_crypto->server_kex; - int i, j, rc; - const char *wanted; - char hostkeys[64] = {0}; - enum ssh_keytypes_e keytype; - size_t len; - - ZERO_STRUCTP(server); - ssh_get_random(server->cookie, 16, 0); - -#ifdef HAVE_ECC - if (session->srv.ecdsa_key != NULL) { - snprintf(hostkeys, sizeof(hostkeys), - "%s", session->srv.ecdsa_key->type_c); - } -#endif - if (session->srv.dsa_key != NULL) { - len = strlen(hostkeys); - keytype = ssh_key_type(session->srv.dsa_key); - - snprintf(hostkeys + len, sizeof(hostkeys) - len, - ",%s", ssh_key_type_to_char(keytype)); - } - if (session->srv.rsa_key != NULL) { - len = strlen(hostkeys); - keytype = ssh_key_type(session->srv.rsa_key); - - snprintf(hostkeys + len, sizeof(hostkeys) - len, - ",%s", ssh_key_type_to_char(keytype)); - } - - if (strlen(hostkeys) == 0) { - return -1; - } - - rc = ssh_options_set_algo(session, - SSH_HOSTKEYS, - hostkeys[0] == ',' ? hostkeys + 1 : hostkeys); - if (rc < 0) { - return -1; - } - - for (i = 0; i < 10; i++) { - if ((wanted = session->opts.wanted_methods[i]) == NULL) { - wanted = ssh_kex_get_supported_method(i); - } - server->methods[i] = strdup(wanted); - if (server->methods[i] == NULL) { - for (j = 0; j < i; j++) { - SAFE_FREE(server->methods[j]); - } - return -1; - } - } - - return 0; -} - -/** @internal - * @brief parse an incoming SSH_MSG_KEXDH_INIT packet and complete - * key exchange - **/ -static int ssh_server_kexdh_init(ssh_session session, ssh_buffer packet){ - ssh_string e; - e = buffer_get_ssh_string(packet); - if (e == NULL) { - ssh_set_error(session, SSH_FATAL, "No e number in client request"); - return -1; - } - if (dh_import_e(session, e) < 0) { - ssh_set_error(session, SSH_FATAL, "Cannot import e number"); - session->session_state=SSH_SESSION_STATE_ERROR; - } else { - session->dh_handshake_state=DH_STATE_INIT_SENT; - dh_handshake_server(session); - } - ssh_string_free(e); - return SSH_OK; -} - -SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){ - int rc; - (void)type; - (void)user; - - SSH_LOG(SSH_LOG_PACKET,"Received SSH_MSG_KEXDH_INIT"); - if(session->dh_handshake_state != DH_STATE_INIT){ - SSH_LOG(SSH_LOG_RARE,"Invalid state for SSH_MSG_KEXDH_INIT"); - goto error; - } - - /* If first_kex_packet_follows guess was wrong, ignore this message. */ - if (session->first_kex_follows_guess_wrong != 0) { - SSH_LOG(SSH_LOG_RARE, "first_kex_packet_follows guess was wrong, " - "ignoring first SSH_MSG_KEXDH_INIT message"); - session->first_kex_follows_guess_wrong = 0; - goto error; - } - - switch(session->next_crypto->kex_type){ - case SSH_KEX_DH_GROUP1_SHA1: - case SSH_KEX_DH_GROUP14_SHA1: - rc=ssh_server_kexdh_init(session, packet); - break; - #ifdef HAVE_ECDH - case SSH_KEX_ECDH_SHA2_NISTP256: - rc = ssh_server_ecdh_init(session, packet); - break; - #endif - #ifdef HAVE_CURVE25519 - case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG: - rc = ssh_server_curve25519_init(session, packet); - break; - #endif - default: - ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_kexdh_init"); - rc = SSH_ERROR; - } - if (rc == SSH_ERROR) - session->session_state = SSH_SESSION_STATE_ERROR; - error: - - return SSH_PACKET_USED; -} - -int ssh_get_key_params(ssh_session session, ssh_key *privkey){ - ssh_key pubkey; - ssh_string pubkey_blob; - int rc; - - switch(session->srv.hostkey) { - case SSH_KEYTYPE_DSS: - *privkey = session->srv.dsa_key; - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - *privkey = session->srv.rsa_key; - break; - case SSH_KEYTYPE_ECDSA: - *privkey = session->srv.ecdsa_key; - break; - case SSH_KEYTYPE_UNKNOWN: - default: - *privkey = NULL; - } - - rc = ssh_pki_export_privkey_to_pubkey(*privkey, &pubkey); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, - "Could not get the public key from the private key"); - - return -1; - } - - rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob); - ssh_key_free(pubkey); - if (rc < 0) { - ssh_set_error_oom(session); - return -1; - } - - dh_import_pubkey(session, pubkey_blob); - return SSH_OK; -} - -static int dh_handshake_server(ssh_session session) { - ssh_key privkey; - ssh_string sig_blob; - ssh_string f; - int rc; - - if (dh_generate_y(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Could not create y number"); - return -1; - } - if (dh_generate_f(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Could not create f number"); - return -1; - } - - f = dh_get_f(session); - if (f == NULL) { - ssh_set_error(session, SSH_FATAL, "Could not get the f number"); - return -1; - } - - if (ssh_get_key_params(session,&privkey) != SSH_OK){ - ssh_string_free(f); - return -1; - } - - if (dh_build_k(session) < 0) { - ssh_set_error(session, SSH_FATAL, "Could not import the public key"); - ssh_string_free(f); - return -1; - } - - if (make_sessionid(session) != SSH_OK) { - ssh_set_error(session, SSH_FATAL, "Could not create a session id"); - ssh_string_free(f); - return -1; - } - - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); - if (sig_blob == NULL) { - ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); - ssh_string_free(f); - return -1; - } - - rc = ssh_buffer_pack(session->out_buffer, - "bSSS", - SSH2_MSG_KEXDH_REPLY, - session->next_crypto->server_pubkey, - f, - sig_blob); - ssh_string_free(f); - ssh_string_free(sig_blob); - if(rc != SSH_OK){ - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - return -1; - } - - if (packet_send(session) == SSH_ERROR) { - return -1; - } - - if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { - ssh_buffer_reinit(session->out_buffer); - return -1; - } - - if (packet_send(session) == SSH_ERROR) { - return -1; - } - SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent"); - session->dh_handshake_state=DH_STATE_NEWKEYS_SENT; - - return 0; -} - -/** - * @internal - * - * @brief A function to be called each time a step has been done in the - * connection. - */ -static void ssh_server_connection_callback(ssh_session session){ - int ssh1,ssh2; - - switch(session->session_state){ - case SSH_SESSION_STATE_NONE: - case SSH_SESSION_STATE_CONNECTING: - case SSH_SESSION_STATE_SOCKET_CONNECTED: - break; - case SSH_SESSION_STATE_BANNER_RECEIVED: - if (session->clientbanner == NULL) { - goto error; - } - set_status(session, 0.4f); - SSH_LOG(SSH_LOG_RARE, - "SSH client banner: %s", session->clientbanner); - - /* Here we analyze the different protocols the server allows. */ - if (ssh_analyze_banner(session, 1, &ssh1, &ssh2) < 0) { - goto error; - } - /* Here we decide which version of the protocol to use. */ - if (ssh2 && session->opts.ssh2) { - session->version = 2; - } else if (ssh1 && session->opts.ssh1) { - session->version = 1; - } else if (ssh1 && !session->opts.ssh1) { -#ifdef WITH_SSH1 - ssh_set_error(session, SSH_FATAL, - "SSH-1 protocol not available (configure session to allow SSH-1)"); - goto error; -#else - ssh_set_error(session, SSH_FATAL, - "SSH-1 protocol not available (libssh compiled without SSH-1 support)"); - goto error; -#endif - } else { - ssh_set_error(session, SSH_FATAL, - "No version of SSH protocol usable (banner: %s)", - session->clientbanner); - goto error; - } - /* from now, the packet layer is handling incoming packets */ - if(session->version==2) - session->socket_callbacks.data=ssh_packet_socket_callback; -#ifdef WITH_SSH1 - else - session->socket_callbacks.data=ssh_packet_socket_callback1; -#endif - ssh_packet_set_default_callbacks(session); - set_status(session, 0.5f); - session->session_state=SSH_SESSION_STATE_INITIAL_KEX; - if (ssh_send_kex(session, 1) < 0) { - goto error; - } - break; - case SSH_SESSION_STATE_INITIAL_KEX: - /* TODO: This state should disappear in favor of get_key handle */ -#ifdef WITH_SSH1 - if(session->version==1){ - if (ssh_get_kex1(session) < 0) - goto error; - set_status(session,0.6f); - session->connected = 1; - break; - } -#endif - break; - case SSH_SESSION_STATE_KEXINIT_RECEIVED: - set_status(session,0.6f); - if(session->next_crypto->server_kex.methods[0]==NULL){ - if(server_set_kex(session) == SSH_ERROR) - goto error; - /* We are in a rekeying, so we need to send the server kex */ - if(ssh_send_kex(session, 1) < 0) - goto error; - } - ssh_list_kex(&session->next_crypto->client_kex); // log client kex - if (ssh_kex_select_methods(session) < 0) { - goto error; - } - if (crypt_set_algorithms_server(session) == SSH_ERROR) - goto error; - set_status(session,0.8f); - session->session_state=SSH_SESSION_STATE_DH; - break; - case SSH_SESSION_STATE_DH: - if(session->dh_handshake_state==DH_STATE_FINISHED){ - if (generate_session_keys(session) < 0) { - goto error; - } - - /* - * Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and - * current_crypto - */ - if (session->current_crypto) { - crypto_free(session->current_crypto); - } - - /* FIXME TODO later, include a function to change keys */ - session->current_crypto = session->next_crypto; - session->next_crypto = crypto_new(); - if (session->next_crypto == NULL) { - goto error; - } - session->next_crypto->session_id = malloc(session->current_crypto->digest_len); - if (session->next_crypto->session_id == NULL) { - ssh_set_error_oom(session); - goto error; - } - memcpy(session->next_crypto->session_id, session->current_crypto->session_id, - session->current_crypto->digest_len); - - set_status(session,1.0f); - session->connected = 1; - session->session_state=SSH_SESSION_STATE_AUTHENTICATING; - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) - session->session_state = SSH_SESSION_STATE_AUTHENTICATED; - } - break; - case SSH_SESSION_STATE_AUTHENTICATING: - break; - case SSH_SESSION_STATE_ERROR: - goto error; - default: - ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state); - } - - return; -error: - ssh_socket_close(session->socket); - session->alive = 0; - session->session_state=SSH_SESSION_STATE_ERROR; -} - -/** - * @internal - * - * @brief Gets the banner from socket and saves it in session. - * Updates the session state - * - * @param data pointer to the beginning of header - * @param len size of the banner - * @param user is a pointer to session - * @returns Number of bytes processed, or zero if the banner is not complete. - */ -static int callback_receive_banner(const void *data, size_t len, void *user) { - char *buffer = (char *) data; - ssh_session session = (ssh_session) user; - char *str = NULL; - size_t i; - int ret=0; - - for (i = 0; i < len; i++) { -#ifdef WITH_PCAP - if(session->pcap_ctx && buffer[i] == '\n') { - ssh_pcap_context_write(session->pcap_ctx, - SSH_PCAP_DIR_IN, - buffer, - i + 1, - i + 1); - } -#endif - if (buffer[i] == '\r') { - buffer[i]='\0'; - } - - if (buffer[i] == '\n') { - buffer[i]='\0'; - - str = strdup(buffer); - /* number of bytes read */ - ret = i + 1; - session->clientbanner = str; - session->session_state = SSH_SESSION_STATE_BANNER_RECEIVED; - SSH_LOG(SSH_LOG_PACKET, "Received banner: %s", str); - session->ssh_connection_callback(session); - - return ret; - } - - if(i > 127) { - /* Too big banner */ - session->session_state = SSH_SESSION_STATE_ERROR; - ssh_set_error(session, SSH_FATAL, "Receiving banner: too large banner"); - - return 0; - } - } - - return ret; -} - -/* returns 0 until the key exchange is not finished */ -static int ssh_server_kex_termination(void *s){ - ssh_session session = s; - if (session->session_state != SSH_SESSION_STATE_ERROR && - session->session_state != SSH_SESSION_STATE_AUTHENTICATING && - session->session_state != SSH_SESSION_STATE_DISCONNECTED) - return 0; - else - return 1; -} - -/** Set the acceptable authentication methods to be sent to - * client. - * @param[in] session the SSH server session - * @param[in] auth_methods Bitfield of authentication methods - * to be accepted, e.g. SSH_AUTH_METHOD_PUBLICKEY - */ -void ssh_set_auth_methods(ssh_session session, int auth_methods){ - /* accept only methods in range */ - session->auth_methods = auth_methods & 0x3f; -} - -/* Do the banner and key exchange */ -int ssh_handle_key_exchange(ssh_session session) { - int rc; - if (session->session_state != SSH_SESSION_STATE_NONE) - goto pending; - rc = ssh_send_banner(session, 1); - if (rc < 0) { - return SSH_ERROR; - } - - session->alive = 1; - - session->ssh_connection_callback = ssh_server_connection_callback; - session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED; - ssh_socket_set_callbacks(session->socket,&session->socket_callbacks); - session->socket_callbacks.data=callback_receive_banner; - session->socket_callbacks.exception=ssh_socket_exception_callback; - session->socket_callbacks.userdata=session; - - rc = server_set_kex(session); - if (rc < 0) { - return SSH_ERROR; - } - pending: - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_USER, - ssh_server_kex_termination,session); - SSH_LOG(SSH_LOG_PACKET, "ssh_handle_key_exchange: current state : %d", - session->session_state); - if (rc != SSH_OK) - return rc; - if (session->session_state == SSH_SESSION_STATE_ERROR || - session->session_state == SSH_SESSION_STATE_DISCONNECTED) { - return SSH_ERROR; - } - - return SSH_OK; -} - -/* messages */ - -/** @internal - * replies to an SSH_AUTH packet with a default (denied) response. - */ -int ssh_auth_reply_default(ssh_session session,int partial) { - char methods_c[128] = {0}; - int rc = SSH_ERROR; - - - if (session->auth_methods == 0) { - session->auth_methods = SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD; - } - if (session->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { - strncat(methods_c, "publickey,", - sizeof(methods_c) - strlen(methods_c) - 1); - } - if (session->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC){ - strncat(methods_c,"gssapi-with-mic,", - sizeof(methods_c) - strlen(methods_c) - 1); - } - if (session->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { - strncat(methods_c, "keyboard-interactive,", - sizeof(methods_c) - strlen(methods_c) - 1); - } - if (session->auth_methods & SSH_AUTH_METHOD_PASSWORD) { - strncat(methods_c, "password,", - sizeof(methods_c) - strlen(methods_c) - 1); - } - if (session->auth_methods & SSH_AUTH_METHOD_HOSTBASED) { - strncat(methods_c, "hostbased,", - sizeof(methods_c) - strlen(methods_c) - 1); - } - - if (methods_c[0] == '\0' || methods_c[strlen(methods_c)-1] != ',') { - return SSH_ERROR; - } - - /* Strip the comma. */ - methods_c[strlen(methods_c) - 1] = '\0'; // strip the comma. We are sure there is at - - SSH_LOG(SSH_LOG_PACKET, - "Sending a auth failure. methods that can continue: %s", methods_c); - - rc = ssh_buffer_pack(session->out_buffer, - "bsb", - SSH2_MSG_USERAUTH_FAILURE, - methods_c, - partial ? 1 : 0); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - rc = packet_send(session); - return rc; -} - -static int ssh_message_channel_request_open_reply_default(ssh_message msg) { - int rc; - - SSH_LOG(SSH_LOG_FUNCTIONS, "Refusing a channel"); - - rc = ssh_buffer_pack(msg->session->out_buffer, - "bdddd", - SSH2_MSG_CHANNEL_OPEN_FAILURE, - msg->channel_request_open.sender, - SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, - 0, /* reason is empty string */ - 0); /* language string */ - if (rc != SSH_OK){ - ssh_set_error_oom(msg->session); - return SSH_ERROR; - } - - rc = packet_send(msg->session); - return rc; -} - -static int ssh_message_channel_request_reply_default(ssh_message msg) { - uint32_t channel; - int rc; - - if (msg->channel_request.want_reply) { - channel = msg->channel_request.channel->remote_channel; - - SSH_LOG(SSH_LOG_PACKET, - "Sending a default channel_request denied to channel %d", channel); - - rc = ssh_buffer_pack(msg->session->out_buffer, - "bd", - SSH2_MSG_CHANNEL_FAILURE, - channel); - if (rc != SSH_OK){ - ssh_set_error_oom(msg->session); - return SSH_ERROR; - } - return packet_send(msg->session); - } - - SSH_LOG(SSH_LOG_PACKET, - "The client doesn't want to know the request failed!"); - - return SSH_OK; -} - -static int ssh_message_service_request_reply_default(ssh_message msg) { - /* The only return code accepted by specifications are success or disconnect */ - return ssh_message_service_reply_success(msg); -} - -int ssh_message_service_reply_success(ssh_message msg) { - ssh_session session; - int rc; - - if (msg == NULL) { - return SSH_ERROR; - } - session = msg->session; - - SSH_LOG(SSH_LOG_PACKET, - "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service); - - rc = ssh_buffer_pack(session->out_buffer, - "bs", - SSH2_MSG_SERVICE_ACCEPT, - msg->service_request.service); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - return SSH_ERROR; - } - rc = packet_send(msg->session); - return rc; -} - -int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_port) { - int rc; - - SSH_LOG(SSH_LOG_FUNCTIONS, "Accepting a global request"); - - if (msg->global_request.want_reply) { - if (buffer_add_u8(msg->session->out_buffer - , SSH2_MSG_REQUEST_SUCCESS) < 0) { - goto error; - } - - if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD - && msg->global_request.bind_port == 0) { - rc = ssh_buffer_pack(msg->session->out_buffer, "d", bound_port); - if (rc != SSH_ERROR) { - ssh_set_error_oom(msg->session); - goto error; - } - } - - return packet_send(msg->session); - } - - if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD - && msg->global_request.bind_port == 0) { - SSH_LOG(SSH_LOG_PACKET, - "The client doesn't want to know the remote port!"); - } - - return SSH_OK; -error: - return SSH_ERROR; -} - -static int ssh_message_global_request_reply_default(ssh_message msg) { - SSH_LOG(SSH_LOG_FUNCTIONS, "Refusing a global request"); - - if (msg->global_request.want_reply) { - if (buffer_add_u8(msg->session->out_buffer - , SSH2_MSG_REQUEST_FAILURE) < 0) { - goto error; - } - return packet_send(msg->session); - } - SSH_LOG(SSH_LOG_PACKET, - "The client doesn't want to know the request failed!"); - - return SSH_OK; -error: - return SSH_ERROR; -} - -int ssh_message_reply_default(ssh_message msg) { - if (msg == NULL) { - return -1; - } - - switch(msg->type) { - case SSH_REQUEST_AUTH: - return ssh_auth_reply_default(msg->session, 0); - case SSH_REQUEST_CHANNEL_OPEN: - return ssh_message_channel_request_open_reply_default(msg); - case SSH_REQUEST_CHANNEL: - return ssh_message_channel_request_reply_default(msg); - case SSH_REQUEST_SERVICE: - return ssh_message_service_request_reply_default(msg); - case SSH_REQUEST_GLOBAL: - return ssh_message_global_request_reply_default(msg); - default: - SSH_LOG(SSH_LOG_PACKET, - "Don't know what to default reply to %d type", - msg->type); - break; - } - - return -1; -} - -const char *ssh_message_service_service(ssh_message msg){ - if (msg == NULL) { - return NULL; - } - return msg->service_request.service; -} - -const char *ssh_message_auth_user(ssh_message msg) { - if (msg == NULL) { - return NULL; - } - - return msg->auth_request.username; -} - -const char *ssh_message_auth_password(ssh_message msg){ - if (msg == NULL) { - return NULL; - } - - return msg->auth_request.password; -} - -ssh_key ssh_message_auth_pubkey(ssh_message msg) { - if (msg == NULL) { - return NULL; - } - - return msg->auth_request.pubkey; -} - -/* Get the publickey of an auth request */ -ssh_public_key ssh_message_auth_publickey(ssh_message msg){ - if (msg == NULL) { - return NULL; - } - - return ssh_pki_convert_key_to_publickey(msg->auth_request.pubkey); -} - -enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg){ - if (msg == NULL) { - return -1; - } - return msg->auth_request.signature_state; -} - -int ssh_message_auth_kbdint_is_response(ssh_message msg) { - if (msg == NULL) { - return -1; - } - - return msg->auth_request.kbdint_response != 0; -} - -int ssh_message_auth_set_methods(ssh_message msg, int methods) { - if (msg == NULL || msg->session == NULL) { - return -1; - } - - msg->session->auth_methods = methods; - - return 0; -} - -int ssh_message_auth_interactive_request(ssh_message msg, const char *name, - const char *instruction, unsigned int num_prompts, - const char **prompts, char *echo) { - int rc; - unsigned int i = 0; - - if(name == NULL || instruction == NULL) { - return SSH_ERROR; - } - if(num_prompts > 0 && (prompts == NULL || echo == NULL)) { - return SSH_ERROR; - } - - rc = ssh_buffer_pack(msg->session->out_buffer, - "bsssd", - SSH2_MSG_USERAUTH_INFO_REQUEST, - name, - instruction, - "", /* language tag */ - num_prompts); - if (rc != SSH_OK){ - ssh_set_error_oom(msg->session); - return SSH_ERROR; - } - - for(i = 0; i < num_prompts; i++) { - rc = ssh_buffer_pack(msg->session->out_buffer, - "sb", - prompts[i], - echo[1] ? 1 : 0); - if (rc != SSH_OK){ - ssh_set_error_oom(msg->session); - return SSH_ERROR; - } - } - - rc = packet_send(msg->session); - - /* fill in the kbdint structure */ - if (msg->session->kbdint == NULL) { - SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a " - "keyboard-interactive response but it " - "seems we didn't send the request."); - - msg->session->kbdint = ssh_kbdint_new(); - if (msg->session->kbdint == NULL) { - ssh_set_error_oom(msg->session); - - return SSH_ERROR; - } - } else { - ssh_kbdint_clean(msg->session->kbdint); - } - - msg->session->kbdint->name = strdup(name); - if(msg->session->kbdint->name == NULL) { - ssh_set_error_oom(msg->session); - ssh_kbdint_free(msg->session->kbdint); - msg->session->kbdint = NULL; - return SSH_PACKET_USED; - } - msg->session->kbdint->instruction = strdup(instruction); - if(msg->session->kbdint->instruction == NULL) { - ssh_set_error_oom(msg->session); - ssh_kbdint_free(msg->session->kbdint); - msg->session->kbdint = NULL; - return SSH_PACKET_USED; - } - - msg->session->kbdint->nprompts = num_prompts; - if(num_prompts > 0) { - msg->session->kbdint->prompts = malloc(num_prompts * sizeof(char *)); - if (msg->session->kbdint->prompts == NULL) { - msg->session->kbdint->nprompts = 0; - ssh_set_error_oom(msg->session); - ssh_kbdint_free(msg->session->kbdint); - msg->session->kbdint = NULL; - return SSH_ERROR; - } - msg->session->kbdint->echo = malloc(num_prompts * sizeof(unsigned char)); - if (msg->session->kbdint->echo == NULL) { - ssh_set_error_oom(msg->session); - ssh_kbdint_free(msg->session->kbdint); - msg->session->kbdint = NULL; - return SSH_ERROR; - } - for (i = 0; i < num_prompts; i++) { - msg->session->kbdint->echo[i] = echo[i]; - msg->session->kbdint->prompts[i] = strdup(prompts[i]); - if (msg->session->kbdint->prompts[i] == NULL) { - ssh_set_error_oom(msg->session); - msg->session->kbdint->nprompts = i; - ssh_kbdint_free(msg->session->kbdint); - msg->session->kbdint = NULL; - return SSH_PACKET_USED; - } - } - } else { - msg->session->kbdint->prompts = NULL; - msg->session->kbdint->echo = NULL; - } - - return rc; -} - -int ssh_auth_reply_success(ssh_session session, int partial) { - int r; - - if (session == NULL) { - return SSH_ERROR; - } - - if (partial) { - return ssh_auth_reply_default(session, partial); - } - - session->session_state = SSH_SESSION_STATE_AUTHENTICATED; - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED; - - if (buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_SUCCESS) < 0) { - return SSH_ERROR; - } - - r = packet_send(session); - if(session->current_crypto && session->current_crypto->delayed_compress_out){ - SSH_LOG(SSH_LOG_PROTOCOL,"Enabling delayed compression OUT"); - session->current_crypto->do_compress_out=1; - } - if(session->current_crypto && session->current_crypto->delayed_compress_in){ - SSH_LOG(SSH_LOG_PROTOCOL,"Enabling delayed compression IN"); - session->current_crypto->do_compress_in=1; - } - return r; -} - -int ssh_message_auth_reply_success(ssh_message msg, int partial) { - if(msg == NULL) - return SSH_ERROR; - return ssh_auth_reply_success(msg->session, partial); -} - -/* Answer OK to a pubkey auth request */ -int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey) { - int rc; - if (msg == NULL) { - return SSH_ERROR; - } - - rc = ssh_buffer_pack(msg->session->out_buffer, - "bSS", - SSH2_MSG_USERAUTH_PK_OK, - algo, - pubkey); - if(rc != SSH_OK){ - ssh_set_error_oom(msg->session); - return SSH_ERROR; - } - - rc = packet_send(msg->session); - return rc; -} - -int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) { - ssh_string algo; - ssh_string pubkey_blob = NULL; - int ret; - - algo = ssh_string_from_char(msg->auth_request.pubkey->type_c); - if (algo == NULL) { - return SSH_ERROR; - } - - ret = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey, &pubkey_blob); - if (ret < 0) { - ssh_string_free(algo); - return SSH_ERROR; - } - - ret = ssh_message_auth_reply_pk_ok(msg, algo, pubkey_blob); - - ssh_string_free(algo); - ssh_string_free(pubkey_blob); - - return ret; -} - - -const char *ssh_message_channel_request_open_originator(ssh_message msg){ - return msg->channel_request_open.originator; -} - -int ssh_message_channel_request_open_originator_port(ssh_message msg){ - return msg->channel_request_open.originator_port; -} - -const char *ssh_message_channel_request_open_destination(ssh_message msg){ - return msg->channel_request_open.destination; -} - -int ssh_message_channel_request_open_destination_port(ssh_message msg){ - return msg->channel_request_open.destination_port; -} - -ssh_channel ssh_message_channel_request_channel(ssh_message msg){ - return msg->channel_request.channel; -} - -const char *ssh_message_channel_request_pty_term(ssh_message msg){ - return msg->channel_request.TERM; -} - -int ssh_message_channel_request_pty_width(ssh_message msg){ - return msg->channel_request.width; -} - -int ssh_message_channel_request_pty_height(ssh_message msg){ - return msg->channel_request.height; -} - -int ssh_message_channel_request_pty_pxwidth(ssh_message msg){ - return msg->channel_request.pxwidth; -} - -int ssh_message_channel_request_pty_pxheight(ssh_message msg){ - return msg->channel_request.pxheight; -} - -const char *ssh_message_channel_request_env_name(ssh_message msg){ - return msg->channel_request.var_name; -} - -const char *ssh_message_channel_request_env_value(ssh_message msg){ - return msg->channel_request.var_value; -} - -const char *ssh_message_channel_request_command(ssh_message msg){ - return msg->channel_request.command; -} - -const char *ssh_message_channel_request_subsystem(ssh_message msg){ - return msg->channel_request.subsystem; -} - -int ssh_message_channel_request_x11_single_connection(ssh_message msg){ - return msg->channel_request.x11_single_connection ? 1 : 0; -} - -const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg){ - return msg->channel_request.x11_auth_protocol; -} - -const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg){ - return msg->channel_request.x11_auth_cookie; -} - -int ssh_message_channel_request_x11_screen_number(ssh_message msg){ - return msg->channel_request.x11_screen_number; -} - -const char *ssh_message_global_request_address(ssh_message msg){ - return msg->global_request.bind_address; -} - -int ssh_message_global_request_port(ssh_message msg){ - return msg->global_request.bind_port; -} - -/** @brief defines the ssh_message callback - * @param session the current ssh session - * @param[in] ssh_bind_message_callback a function pointer to a callback taking the - * current ssh session and received message as parameters. the function returns - * 0 if the message has been parsed and treated successfully, 1 otherwise (libssh - * must take care of the response). - * @param[in] data void pointer to be passed to callback functions - */ -void ssh_set_message_callback(ssh_session session, - int(*ssh_bind_message_callback)(ssh_session session, ssh_message msg, void *data), - void *data) { - session->ssh_message_callback = ssh_bind_message_callback; - session->ssh_message_callback_data = data; -} - -int ssh_execute_message_callbacks(ssh_session session){ - ssh_message msg=NULL; - int ret; - ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING); - if(!session->ssh_message_list) - return SSH_OK; - if(session->ssh_message_callback){ - while((msg=ssh_message_pop_head(session)) != NULL) { - ret=session->ssh_message_callback(session,msg, - session->ssh_message_callback_data); - if(ret==1){ - ret = ssh_message_reply_default(msg); - ssh_message_free(msg); - if(ret != SSH_OK) - return ret; - } else { - ssh_message_free(msg); - } - } - } else { - while((msg=ssh_message_pop_head(session)) != NULL) { - ret = ssh_message_reply_default(msg); - ssh_message_free(msg); - if(ret != SSH_OK) - return ret; - } - } - return SSH_OK; -} - -int ssh_send_keepalive(ssh_session session) -{ - int rc; - - rc = ssh_buffer_pack(session->out_buffer, - "bsb", - SSH2_MSG_GLOBAL_REQUEST, - "keepalive@openssh.com", - 1); - if (rc != SSH_OK) { - goto err; - } - - if (packet_send(session) == SSH_ERROR) { - goto err; - } - - ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING); - - SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive"); - return SSH_OK; - -err: - ssh_set_error_oom(session); - ssh_buffer_reinit(session->out_buffer); - return SSH_ERROR; -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/session.c b/libssh/src/session.c deleted file mode 100644 index a3b19ede..00000000 --- a/libssh/src/session.c +++ /dev/null @@ -1,888 +0,0 @@ -/* - * session.c - non-networking functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2005-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include - -#include "libssh/priv.h" -#include "libssh/libssh.h" -#include "libssh/crypto.h" -#include "libssh/server.h" -#include "libssh/socket.h" -#include "libssh/ssh2.h" -#include "libssh/agent.h" -#include "libssh/packet.h" -#include "libssh/session.h" -#include "libssh/misc.h" -#include "libssh/buffer.h" -#include "libssh/poll.h" - -#define FIRST_CHANNEL 42 // why not ? it helps to find bugs. - -/** - * @defgroup libssh_session The SSH session functions. - * @ingroup libssh - * - * Functions that manage a session. - * - * @{ - */ - -/** - * @brief Create a new ssh session. - * - * @returns A new ssh_session pointer, NULL on error. - */ -ssh_session ssh_new(void) { - ssh_session session; - char *id = NULL; - int rc; - - session = malloc(sizeof (struct ssh_session_struct)); - if (session == NULL) { - return NULL; - } - ZERO_STRUCTP(session); - - session->next_crypto = crypto_new(); - if (session->next_crypto == NULL) { - goto err; - } - - session->socket = ssh_socket_new(session); - if (session->socket == NULL) { - goto err; - } - - session->out_buffer = ssh_buffer_new(); - if (session->out_buffer == NULL) { - goto err; - } - - session->in_buffer=ssh_buffer_new(); - if (session->in_buffer == NULL) { - goto err; - } - - session->alive = 0; - session->auth_methods = 0; - ssh_set_blocking(session, 1); - session->maxchannel = FIRST_CHANNEL; - -#ifndef _WIN32 - session->agent = agent_new(session); - if (session->agent == NULL) { - goto err; - } -#endif /* _WIN32 */ - - /* OPTIONS */ - session->opts.StrictHostKeyChecking = 1; - session->opts.port = 22; - session->opts.fd = -1; - session->opts.ssh2 = 1; - session->opts.compressionlevel=7; -#ifdef WITH_SSH1 - session->opts.ssh1 = 1; -#else - session->opts.ssh1 = 0; -#endif - - session->opts.identity = ssh_list_new(); - if (session->opts.identity == NULL) { - goto err; - } - -#ifdef HAVE_ECC - id = strdup("%d/id_ecdsa"); - if (id == NULL) { - goto err; - } - rc = ssh_list_append(session->opts.identity, id); - if (rc == SSH_ERROR) { - goto err; - } -#endif - - id = strdup("%d/id_rsa"); - if (id == NULL) { - goto err; - } - rc = ssh_list_append(session->opts.identity, id); - if (rc == SSH_ERROR) { - goto err; - } - - id = strdup("%d/id_dsa"); - if (id == NULL) { - goto err; - } - rc = ssh_list_append(session->opts.identity, id); - if (rc == SSH_ERROR) { - goto err; - } - - id = strdup("%d/identity"); - if (id == NULL) { - goto err; - } - rc = ssh_list_append(session->opts.identity, id); - if (rc == SSH_ERROR) { - goto err; - } - - return session; - -err: - free(id); - ssh_free(session); - return NULL; -} - -/** - * @brief Deallocate a SSH session handle. - * - * @param[in] session The SSH session to free. - * - * @see ssh_disconnect() - * @see ssh_new() - */ -void ssh_free(ssh_session session) { - int i; - struct ssh_iterator *it; - - if (session == NULL) { - return; - } - - /* - * Delete all channels - * - * This needs the first thing we clean up cause if there is still an open - * channel we call ssh_channel_close() first. So we need a working socket - * and poll context for it. - */ - for (it = ssh_list_get_iterator(session->channels); - it != NULL; - it = ssh_list_get_iterator(session->channels)) { - ssh_channel_do_free(ssh_iterator_value(ssh_channel,it)); - ssh_list_remove(session->channels, it); - } - ssh_list_free(session->channels); - session->channels = NULL; - -#ifdef WITH_PCAP - if (session->pcap_ctx) { - ssh_pcap_context_free(session->pcap_ctx); - session->pcap_ctx = NULL; - } -#endif - - ssh_socket_free(session->socket); - session->socket = NULL; - - if (session->default_poll_ctx) { - ssh_poll_ctx_free(session->default_poll_ctx); - } - - ssh_buffer_free(session->in_buffer); - ssh_buffer_free(session->out_buffer); - session->in_buffer = session->out_buffer = NULL; - - if (session->in_hashbuf != NULL) { - ssh_buffer_free(session->in_hashbuf); - } - if (session->out_hashbuf != NULL) { - ssh_buffer_free(session->out_hashbuf); - } - - crypto_free(session->current_crypto); - crypto_free(session->next_crypto); - -#ifndef _WIN32 - agent_free(session->agent); -#endif /* _WIN32 */ - - ssh_key_free(session->srv.dsa_key); - session->srv.dsa_key = NULL; - ssh_key_free(session->srv.rsa_key); - session->srv.rsa_key = NULL; - ssh_key_free(session->srv.ecdsa_key); - session->srv.ecdsa_key = NULL; - - if (session->ssh_message_list) { - ssh_message msg; - - for (msg = ssh_list_pop_head(ssh_message, session->ssh_message_list); - msg != NULL; - msg = ssh_list_pop_head(ssh_message, session->ssh_message_list)) { - ssh_message_free(msg); - } - ssh_list_free(session->ssh_message_list); - } - - if (session->packet_callbacks) { - ssh_list_free(session->packet_callbacks); - } - - /* options */ - if (session->opts.identity) { - char *id; - - for (id = ssh_list_pop_head(char *, session->opts.identity); - id != NULL; - id = ssh_list_pop_head(char *, session->opts.identity)) { - SAFE_FREE(id); - } - ssh_list_free(session->opts.identity); - } - - SAFE_FREE(session->auth_auto_state); - SAFE_FREE(session->serverbanner); - SAFE_FREE(session->clientbanner); - SAFE_FREE(session->banner); - - SAFE_FREE(session->opts.bindaddr); - SAFE_FREE(session->opts.custombanner); - SAFE_FREE(session->opts.username); - SAFE_FREE(session->opts.host); - SAFE_FREE(session->opts.sshdir); - SAFE_FREE(session->opts.knownhosts); - SAFE_FREE(session->opts.ProxyCommand); - SAFE_FREE(session->opts.gss_server_identity); - SAFE_FREE(session->opts.gss_client_identity); - - for (i = 0; i < 10; i++) { - if (session->opts.wanted_methods[i]) { - SAFE_FREE(session->opts.wanted_methods[i]); - } - } - - /* burn connection, it could contain sensitive data */ - BURN_BUFFER(session, sizeof(struct ssh_session_struct)); - SAFE_FREE(session); -} - -/** - * @brief get the client banner - * - * @param[in] session The SSH session - * - * @return Returns the client banner string or NULL. - */ -const char* ssh_get_clientbanner(ssh_session session) { - if (session == NULL) { - return NULL; - } - - return session->clientbanner; -} - -/** - * @brief get the server banner - * - * @param[in] session The SSH session - * - * @return Returns the server banner string or NULL. - */ -const char* ssh_get_serverbanner(ssh_session session) { - if(!session) { - return NULL; - } - return session->serverbanner; -} - -/** - * @brief get the name of the input cipher for the given session. - * - * @param[in] session The SSH session. - * - * @return Returns cipher name or NULL. - */ -const char* ssh_get_cipher_in(ssh_session session) { - if ((session != NULL) && - (session->current_crypto != NULL) && - (session->current_crypto->in_cipher != NULL)) { - return session->current_crypto->in_cipher->name; - } - return NULL; -} - -/** - * @brief get the name of the output cipher for the given session. - * - * @param[in] session The SSH session. - * - * @return Returns cipher name or NULL. - */ -const char* ssh_get_cipher_out(ssh_session session) { - if ((session != NULL) && - (session->current_crypto != NULL) && - (session->current_crypto->out_cipher != NULL)) { - return session->current_crypto->out_cipher->name; - } - return NULL; -} - -/** - * @brief get the name of the input HMAC algorithm for the given session. - * - * @param[in] session The SSH session. - * - * @return Returns HMAC algorithm name or NULL if unknown. - */ -const char* ssh_get_hmac_in(ssh_session session) { - if ((session != NULL) && - (session->current_crypto != NULL)) { - return ssh_hmac_type_to_string(session->current_crypto->in_hmac); - } - return NULL; -} - -/** - * @brief get the name of the output HMAC algorithm for the given session. - * - * @param[in] session The SSH session. - * - * @return Returns HMAC algorithm name or NULL if unknown. - */ -const char* ssh_get_hmac_out(ssh_session session) { - if ((session != NULL) && - (session->current_crypto != NULL)) { - return ssh_hmac_type_to_string(session->current_crypto->out_hmac); - } - return NULL; -} - -/** - * @brief Disconnect impolitely from a remote host by closing the socket. - * - * Suitable if you forked and want to destroy this session. - * - * @param[in] session The SSH session to disconnect. - */ -void ssh_silent_disconnect(ssh_session session) { - if (session == NULL) { - return; - } - - ssh_socket_close(session->socket); - session->alive = 0; - ssh_disconnect(session); -} - -/** - * @brief Set the session in blocking/nonblocking mode. - * - * @param[in] session The ssh session to change. - * - * @param[in] blocking Zero for nonblocking mode. - */ -void ssh_set_blocking(ssh_session session, int blocking) { - if (session == NULL) { - return; - } - session->flags &= ~SSH_SESSION_FLAG_BLOCKING; - session->flags |= blocking ? SSH_SESSION_FLAG_BLOCKING : 0; -} - -/** - * @brief Return the blocking mode of libssh - * @param[in] session The SSH session - * @returns 0 if the session is nonblocking, - * @returns 1 if the functions may block. - */ -int ssh_is_blocking(ssh_session session){ - return (session->flags&SSH_SESSION_FLAG_BLOCKING) ? 1 : 0; -} - -/* Waits until the output socket is empty */ -static int ssh_flush_termination(void *c){ - ssh_session session = c; - if (ssh_socket_buffered_write_bytes(session->socket) == 0 || - session->session_state == SSH_SESSION_STATE_ERROR) - return 1; - else - return 0; -} - -/** - * @brief Blocking flush of the outgoing buffer - * @param[in] session The SSH session - * @param[in] timeout Set an upper limit on the time for which this function - * will block, in milliseconds. Specifying -1 - * means an infinite timeout. This parameter is passed to - * the poll() function. - * @returns SSH_OK on success, SSH_AGAIN if timeout occurred, - * SSH_ERROR otherwise. - */ - -int ssh_blocking_flush(ssh_session session, int timeout){ - int rc; - if (session == NULL) { - return SSH_ERROR; - } - - rc = ssh_handle_packets_termination(session, timeout, - ssh_flush_termination, session); - if (rc == SSH_ERROR) { - return rc; - } - if (!ssh_flush_termination(session)) { - rc = SSH_AGAIN; - } - - return rc; -} - -/** - * @brief Check if we are connected. - * - * @param[in] session The session to check if it is connected. - * - * @return 1 if we are connected, 0 if not. - */ -int ssh_is_connected(ssh_session session) { - if (session == NULL) { - return 0; - } - - return session->alive; -} - -/** - * @brief Get the fd of a connection. - * - * In case you'd need the file descriptor of the connection to the server/client. - * - * @param[in] session The ssh session to use. - * - * @return The file descriptor of the connection, or -1 if it is - * not connected - */ -socket_t ssh_get_fd(ssh_session session) { - if (session == NULL) { - return -1; - } - - return ssh_socket_get_fd_in(session->socket); -} - -/** - * @brief Tell the session it has data to read on the file descriptor without - * blocking. - * - * @param[in] session The ssh session to use. - */ -void ssh_set_fd_toread(ssh_session session) { - if (session == NULL) { - return; - } - - ssh_socket_set_read_wontblock(session->socket); -} - -/** - * @brief Tell the session it may write to the file descriptor without blocking. - * - * @param[in] session The ssh session to use. - */ -void ssh_set_fd_towrite(ssh_session session) { - if (session == NULL) { - return; - } - - ssh_socket_set_write_wontblock(session->socket); -} - -/** - * @brief Tell the session it has an exception to catch on the file descriptor. - * - * \param[in] session The ssh session to use. - */ -void ssh_set_fd_except(ssh_session session) { - if (session == NULL) { - return; - } - - ssh_socket_set_except(session->socket); -} - -/** - * @internal - * - * @brief Poll the current session for an event and call the appropriate - * callbacks. This function will not loop until the timeout is expired. - * - * This will block until one event happens. - * - * @param[in] session The session handle to use. - * - * @param[in] timeout Set an upper limit on the time for which this function - * will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE - * (-1) means an infinite timeout. - * Specifying SSH_TIMEOUT_USER means to use the timeout - * specified in options. 0 means poll will return immediately. - * This parameter is passed to the poll() function. - * - * @return SSH_OK on success, SSH_ERROR otherwise. - */ -int ssh_handle_packets(ssh_session session, int timeout) { - ssh_poll_handle spoll_in,spoll_out; - ssh_poll_ctx ctx; - int tm = timeout; - int rc; - - if (session == NULL || session->socket == NULL) { - return SSH_ERROR; - } - - spoll_in = ssh_socket_get_poll_handle_in(session->socket); - spoll_out = ssh_socket_get_poll_handle_out(session->socket); - ssh_poll_add_events(spoll_in, POLLIN); - ctx = ssh_poll_get_ctx(spoll_in); - - if (!ctx) { - ctx = ssh_poll_get_default_ctx(session); - ssh_poll_ctx_add(ctx, spoll_in); - if (spoll_in != spoll_out) { - ssh_poll_ctx_add(ctx, spoll_out); - } - } - - if (timeout == SSH_TIMEOUT_USER) { - if (ssh_is_blocking(session)) - tm = ssh_make_milliseconds(session->opts.timeout, - session->opts.timeout_usec); - else - tm = 0; - } - rc = ssh_poll_ctx_dopoll(ctx, tm); - if (rc == SSH_ERROR) { - session->session_state = SSH_SESSION_STATE_ERROR; - } - - return rc; -} - -/** - * @internal - * - * @brief Poll the current session for an event and call the appropriate - * callbacks. - * - * This will block until termination function returns true, or timeout expired. - * - * @param[in] session The session handle to use. - * - * @param[in] timeout Set an upper limit on the time for which this function - * will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE - * (-1) means an infinite timeout. - * Specifying SSH_TIMEOUT_USER means to use the timeout - * specified in options. 0 means poll will return immediately. - * SSH_TIMEOUT_DEFAULT uses blocking parameters of the session. - * This parameter is passed to the poll() function. - * - * @param[in] fct Termination function to be used to determine if it is - * possible to stop polling. - * @param[in] user User parameter to be passed to fct termination function. - * @return SSH_OK on success, SSH_ERROR otherwise. - */ -int ssh_handle_packets_termination(ssh_session session, - int timeout, - ssh_termination_function fct, - void *user) -{ - struct ssh_timestamp ts; - int ret = SSH_OK; - int tm; - - if (timeout == SSH_TIMEOUT_USER) { - if (ssh_is_blocking(session)) { - timeout = ssh_make_milliseconds(session->opts.timeout, - session->opts.timeout_usec); - } else { - timeout = SSH_TIMEOUT_NONBLOCKING; - } - } else if (timeout == SSH_TIMEOUT_DEFAULT) { - if (ssh_is_blocking(session)) { - timeout = SSH_TIMEOUT_INFINITE; - } else { - timeout = SSH_TIMEOUT_NONBLOCKING; - } - } - - /* avoid unnecessary syscall for the SSH_TIMEOUT_NONBLOCKING case */ - if (timeout != SSH_TIMEOUT_NONBLOCKING) { - ssh_timestamp_init(&ts); - } - - tm = timeout; - while(!fct(user)) { - ret = ssh_handle_packets(session, tm); - if (ret == SSH_ERROR) { - break; - } - if (ssh_timeout_elapsed(&ts,timeout)) { - ret = fct(user) ? SSH_OK : SSH_AGAIN; - break; - } - - tm = ssh_timeout_update(&ts, timeout); - } - - return ret; -} - -/** - * @brief Get session status - * - * @param session The ssh session to use. - * - * @returns A bitmask including SSH_CLOSED, SSH_READ_PENDING, SSH_WRITE_PENDING - * or SSH_CLOSED_ERROR which respectively means the session is closed, - * has data to read on the connection socket and session was closed - * due to an error. - */ -int ssh_get_status(ssh_session session) { - int socketstate; - int r = 0; - - if (session == NULL) { - return 0; - } - - socketstate = ssh_socket_get_status(session->socket); - - if (session->session_state == SSH_SESSION_STATE_DISCONNECTED) { - r |= SSH_CLOSED; - } - if (socketstate & SSH_READ_PENDING) { - r |= SSH_READ_PENDING; - } - if (socketstate & SSH_WRITE_PENDING) { - r |= SSH_WRITE_PENDING; - } - if ((session->session_state == SSH_SESSION_STATE_DISCONNECTED && - (socketstate & SSH_CLOSED_ERROR)) || - session->session_state == SSH_SESSION_STATE_ERROR) { - r |= SSH_CLOSED_ERROR; - } - - return r; -} - -/** - * @brief Get poll flags for an external mainloop - * - * @param session The ssh session to use. - * - * @returns A bitmask including SSH_READ_PENDING or SSH_WRITE_PENDING. - * For SSH_READ_PENDING, your invocation of poll() should include - * POLLIN. For SSH_WRITE_PENDING, your invocation of poll() should - * include POLLOUT. - */ -int ssh_get_poll_flags(ssh_session session) -{ - if (session == NULL) { - return 0; - } - - return ssh_socket_get_poll_flags (session->socket); -} - -/** - * @brief Get the disconnect message from the server. - * - * @param[in] session The ssh session to use. - * - * @return The message sent by the server along with the - * disconnect, or NULL in which case the reason of the - * disconnect may be found with ssh_get_error. - * - * @see ssh_get_error() - */ -const char *ssh_get_disconnect_message(ssh_session session) { - if (session == NULL) { - return NULL; - } - - if (session->session_state != SSH_SESSION_STATE_DISCONNECTED) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Connection not closed yet"); - } else if(!session->discon_msg) { - ssh_set_error(session, SSH_FATAL, - "Connection correctly closed but no disconnect message"); - } else { - return session->discon_msg; - } - - return NULL; -} - -/** - * @brief Get the protocol version of the session. - * - * @param session The ssh session to use. - * - * @return 1 or 2, for ssh1 or ssh2, < 0 on error. - */ -int ssh_get_version(ssh_session session) { - if (session == NULL) { - return -1; - } - - return session->version; -} - -/** - * @internal - * @brief Callback to be called when the socket received an exception code. - * @param user is a pointer to session - */ -void ssh_socket_exception_callback(int code, int errno_code, void *user){ - ssh_session session=(ssh_session)user; - - SSH_LOG(SSH_LOG_RARE,"Socket exception callback: %d (%d)",code, errno_code); - session->session_state = SSH_SESSION_STATE_ERROR; - if (errno_code == 0 && code == SSH_SOCKET_EXCEPTION_EOF) { - ssh_set_error(session, SSH_FATAL, "Socket error: disconnected"); - } else { - ssh_set_error(session, SSH_FATAL, "Socket error: %s", strerror(errno_code)); - } - - session->ssh_connection_callback(session); -} - -/** - * @brief Send a message that should be ignored - * - * @param[in] session The SSH session - * @param[in] data Data to be sent - * - * @return SSH_OK on success, SSH_ERROR otherwise. - */ -int ssh_send_ignore (ssh_session session, const char *data) { - int rc; - - if (ssh_socket_is_open(session->socket)) { - - rc = ssh_buffer_pack(session->out_buffer, - "bs", - SSH2_MSG_IGNORE, - data); - if (rc != SSH_OK){ - ssh_set_error_oom(session); - goto error; - } - packet_send(session); - ssh_handle_packets(session, 0); - } - - return SSH_OK; - -error: - ssh_buffer_reinit(session->out_buffer); - return SSH_ERROR; -} - -/** - * @brief Send a debug message - * - * @param[in] session The SSH session - * @param[in] message Data to be sent - * @param[in] always_display Message SHOULD be displayed by the server. It - * SHOULD NOT be displayed unless debugging - * information has been explicitly requested. - * - * @return SSH_OK on success, SSH_ERROR otherwise. - */ -int ssh_send_debug (ssh_session session, const char *message, int always_display) { - int rc; - - if (ssh_socket_is_open(session->socket)) { - rc = ssh_buffer_pack(session->out_buffer, - "bbsd", - SSH2_MSG_DEBUG, - always_display != 0 ? 1 : 0, - message, - 0); /* empty language tag */ - if (rc != SSH_OK) { - ssh_set_error_oom(session); - goto error; - } - packet_send(session); - ssh_handle_packets(session, 0); - } - - return SSH_OK; - -error: - ssh_buffer_reinit(session->out_buffer); - return SSH_ERROR; -} - - /** - * @brief Set the session data counters. - * - * This functions sets the counter structures to be used to calculate data - * which comes in and goes out through the session at different levels. - * - * @code - * struct ssh_counter_struct scounter = { - * .in_bytes = 0, - * .out_bytes = 0, - * .in_packets = 0, - * .out_packets = 0 - * }; - * - * struct ssh_counter_struct rcounter = { - * .in_bytes = 0, - * .out_bytes = 0, - * .in_packets = 0, - * .out_packets = 0 - * }; - * - * ssh_set_counters(session, &scounter, &rcounter); - * @endcode - * - * @param[in] session The SSH session. - * - * @param[in] scounter Counter for byte data handled by the session sockets. - * - * @param[in] rcounter Counter for byte and packet data handled by the session, - * prior compression and SSH overhead. - */ -void ssh_set_counters(ssh_session session, ssh_counter scounter, - ssh_counter rcounter) { - if (session != NULL) { - session->socket_counter = scounter; - session->raw_counter = rcounter; - } -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/sftp.c b/libssh/src/sftp.c deleted file mode 100644 index b57da645..00000000 --- a/libssh/src/sftp.c +++ /dev/null @@ -1,3081 +0,0 @@ -/* - * sftp.c - Secure FTP functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2005-2008 by Aris Adamantiadis - * Copyright (c) 2008-2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* This file contains code written by Nick Zitzmann */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#else -#define S_IFSOCK 0140000 -#define S_IFLNK 0120000 - -#ifdef _MSC_VER -#define S_IFBLK 0060000 -#define S_IFIFO 0010000 -#endif -#endif - -#include "libssh/priv.h" -#include "libssh/ssh2.h" -#include "libssh/sftp.h" -#include "libssh/buffer.h" -#include "libssh/channels.h" -#include "libssh/session.h" -#include "libssh/misc.h" - -#ifdef WITH_SFTP - -struct sftp_ext_struct { - unsigned int count; - char **name; - char **data; -}; - -/* functions */ -static int sftp_enqueue(sftp_session session, sftp_message msg); -static void sftp_message_free(sftp_message msg); -static void sftp_set_error(sftp_session sftp, int errnum); -static void status_msg_free(sftp_status_message status); - -static sftp_ext sftp_ext_new(void) { - sftp_ext ext; - - ext = malloc(sizeof(struct sftp_ext_struct)); - if (ext == NULL) { - return NULL; - } - ZERO_STRUCTP(ext); - - return ext; -} - -static void sftp_ext_free(sftp_ext ext) { - unsigned int i; - - if (ext == NULL) { - return; - } - - if (ext->count) { - for (i = 0; i < ext->count; i++) { - SAFE_FREE(ext->name[i]); - SAFE_FREE(ext->data[i]); - } - SAFE_FREE(ext->name); - SAFE_FREE(ext->data); - } - - SAFE_FREE(ext); -} - -sftp_session sftp_new(ssh_session session){ - sftp_session sftp; - - if (session == NULL) { - return NULL; - } - - sftp = malloc(sizeof(struct sftp_session_struct)); - if (sftp == NULL) { - ssh_set_error_oom(session); - - return NULL; - } - ZERO_STRUCTP(sftp); - - sftp->ext = sftp_ext_new(); - if (sftp->ext == NULL) { - ssh_set_error_oom(session); - SAFE_FREE(sftp); - - return NULL; - } - - sftp->session = session; - sftp->channel = ssh_channel_new(session); - if (sftp->channel == NULL) { - SAFE_FREE(sftp); - - return NULL; - } - - if (ssh_channel_open_session(sftp->channel)) { - ssh_channel_free(sftp->channel); - SAFE_FREE(sftp); - - return NULL; - } - - if (ssh_channel_request_sftp(sftp->channel)) { - sftp_free(sftp); - - return NULL; - } - - return sftp; -} - -sftp_session sftp_new_channel(ssh_session session, ssh_channel channel){ - sftp_session sftp; - - if (session == NULL) { - return NULL; - } - - sftp = malloc(sizeof(struct sftp_session_struct)); - if (sftp == NULL) { - ssh_set_error_oom(session); - - return NULL; - } - ZERO_STRUCTP(sftp); - - sftp->ext = sftp_ext_new(); - if (sftp->ext == NULL) { - ssh_set_error_oom(session); - SAFE_FREE(sftp); - - return NULL; - } - - sftp->session = session; - sftp->channel = channel; - - return sftp; -} - -#ifdef WITH_SERVER -sftp_session sftp_server_new(ssh_session session, ssh_channel chan){ - sftp_session sftp = NULL; - - sftp = malloc(sizeof(struct sftp_session_struct)); - if (sftp == NULL) { - ssh_set_error_oom(session); - return NULL; - } - ZERO_STRUCTP(sftp); - - sftp->session = session; - sftp->channel = chan; - - return sftp; -} - -int sftp_server_init(sftp_session sftp){ - ssh_session session = sftp->session; - sftp_packet packet = NULL; - ssh_buffer reply = NULL; - uint32_t version; - - packet = sftp_packet_read(sftp); - if (packet == NULL) { - return -1; - } - - if (packet->type != SSH_FXP_INIT) { - ssh_set_error(session, SSH_FATAL, - "Packet read of type %d instead of SSH_FXP_INIT", - packet->type); - - sftp_packet_free(packet); - return -1; - } - - SSH_LOG(SSH_LOG_PACKET, "Received SSH_FXP_INIT"); - - buffer_get_u32(packet->payload, &version); - version = ntohl(version); - SSH_LOG(SSH_LOG_PACKET, "Client version: %d", version); - sftp->client_version = version; - - sftp_packet_free(packet); - - reply = ssh_buffer_new(); - if (reply == NULL) { - ssh_set_error_oom(session); - return -1; - } - - if (buffer_add_u32(reply, ntohl(LIBSFTP_VERSION)) < 0) { - ssh_set_error_oom(session); - ssh_buffer_free(reply); - return -1; - } - - if (sftp_packet_write(sftp, SSH_FXP_VERSION, reply) < 0) { - ssh_buffer_free(reply); - return -1; - } - ssh_buffer_free(reply); - - SSH_LOG(SSH_LOG_RARE, "Server version sent"); - - if (version > LIBSFTP_VERSION) { - sftp->version = LIBSFTP_VERSION; - } else { - sftp->version=version; - } - - return 0; -} -#endif /* WITH_SERVER */ - -void sftp_free(sftp_session sftp){ - sftp_request_queue ptr; - - if (sftp == NULL) { - return; - } - - ssh_channel_send_eof(sftp->channel); - ptr = sftp->queue; - while(ptr) { - sftp_request_queue old; - sftp_message_free(ptr->message); - old = ptr->next; - SAFE_FREE(ptr); - ptr = old; - } - - ssh_channel_free(sftp->channel); - - SAFE_FREE(sftp->handles); - - sftp_ext_free(sftp->ext); - ZERO_STRUCTP(sftp); - - SAFE_FREE(sftp); -} - -int sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload){ - int size; - - if (buffer_prepend_data(payload, &type, sizeof(uint8_t)) < 0) { - ssh_set_error_oom(sftp->session); - return -1; - } - - size = htonl(buffer_get_rest_len(payload)); - if (buffer_prepend_data(payload, &size, sizeof(uint32_t)) < 0) { - ssh_set_error_oom(sftp->session); - return -1; - } - - size = ssh_channel_write(sftp->channel, buffer_get_rest(payload), - buffer_get_rest_len(payload)); - if (size < 0) { - return -1; - } else if((uint32_t) size != buffer_get_rest_len(payload)) { - SSH_LOG(SSH_LOG_PACKET, - "Had to write %d bytes, wrote only %d", - buffer_get_rest_len(payload), - size); - } - - return size; -} - -sftp_packet sftp_packet_read(sftp_session sftp) { - unsigned char buffer[MAX_BUF_SIZE]; - sftp_packet packet = NULL; - uint32_t size; - int r; - - packet = malloc(sizeof(struct sftp_packet_struct)); - if (packet == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - packet->sftp = sftp; - packet->payload = ssh_buffer_new(); - if (packet->payload == NULL) { - ssh_set_error_oom(sftp->session); - SAFE_FREE(packet); - return NULL; - } - - r=ssh_channel_read(sftp->channel, buffer, 4, 0); - if (r < 0) { - ssh_buffer_free(packet->payload); - SAFE_FREE(packet); - return NULL; - } - ssh_buffer_add_data(packet->payload, buffer, r); - if (buffer_get_u32(packet->payload, &size) != sizeof(uint32_t)) { - ssh_set_error(sftp->session, SSH_FATAL, "Short sftp packet!"); - ssh_buffer_free(packet->payload); - SAFE_FREE(packet); - return NULL; - } - - size = ntohl(size); - r=ssh_channel_read(sftp->channel, buffer, 1, 0); - if (r <= 0) { - /* TODO: check if there are cases where an error needs to be set here */ - ssh_buffer_free(packet->payload); - SAFE_FREE(packet); - return NULL; - } - ssh_buffer_add_data(packet->payload, buffer, r); - buffer_get_u8(packet->payload, &packet->type); - size=size-1; - while (size>0){ - r=ssh_channel_read(sftp->channel,buffer, - sizeof(buffer)>size ? size:sizeof(buffer),0); - - if(r <= 0) { - /* TODO: check if there are cases where an error needs to be set here */ - ssh_buffer_free(packet->payload); - SAFE_FREE(packet); - return NULL; - } - if (ssh_buffer_add_data(packet->payload, buffer, r) == SSH_ERROR) { - ssh_buffer_free(packet->payload); - SAFE_FREE(packet); - ssh_set_error_oom(sftp->session); - return NULL; - } - size -= r; - } - - return packet; -} - -static void sftp_set_error(sftp_session sftp, int errnum) { - if (sftp != NULL) { - sftp->errnum = errnum; - } -} - -/* Get the last sftp error */ -int sftp_get_error(sftp_session sftp) { - if (sftp == NULL) { - return -1; - } - - return sftp->errnum; -} - -static sftp_message sftp_message_new(sftp_session sftp){ - sftp_message msg = NULL; - - msg = malloc(sizeof(struct sftp_message_struct)); - if (msg == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - ZERO_STRUCTP(msg); - - msg->payload = ssh_buffer_new(); - if (msg->payload == NULL) { - ssh_set_error_oom(sftp->session); - SAFE_FREE(msg); - return NULL; - } - msg->sftp = sftp; - - return msg; -} - -static void sftp_message_free(sftp_message msg) { - if (msg == NULL) { - return; - } - - ssh_buffer_free(msg->payload); - SAFE_FREE(msg); -} - -static sftp_message sftp_get_message(sftp_packet packet) { - sftp_session sftp = packet->sftp; - sftp_message msg = NULL; - int rc; - - msg = sftp_message_new(sftp); - if (msg == NULL) { - return NULL; - } - - msg->sftp = packet->sftp; - msg->packet_type = packet->type; - - if ((packet->type != SSH_FXP_STATUS) && (packet->type!=SSH_FXP_HANDLE) && - (packet->type != SSH_FXP_DATA) && (packet->type != SSH_FXP_ATTRS) && - (packet->type != SSH_FXP_NAME) && (packet->type != SSH_FXP_EXTENDED_REPLY)) { - ssh_set_error(packet->sftp->session, SSH_FATAL, - "Unknown packet type %d", packet->type); - sftp_message_free(msg); - return NULL; - } - - rc = ssh_buffer_unpack(packet->payload, "d", &msg->id); - if (rc != SSH_OK) { - ssh_set_error(packet->sftp->session, SSH_FATAL, - "Invalid packet %d: no ID", packet->type); - sftp_message_free(msg); - return NULL; - } - - SSH_LOG(SSH_LOG_PACKET, - "Packet with id %d type %d", - msg->id, - msg->packet_type); - - if (ssh_buffer_add_data(msg->payload, buffer_get_rest(packet->payload), - buffer_get_rest_len(packet->payload)) < 0) { - ssh_set_error_oom(sftp->session); - sftp_message_free(msg); - return NULL; - } - - return msg; -} - -static int sftp_read_and_dispatch(sftp_session sftp) { - sftp_packet packet = NULL; - sftp_message msg = NULL; - - packet = sftp_packet_read(sftp); - if (packet == NULL) { - return -1; /* something nasty happened reading the packet */ - } - - msg = sftp_get_message(packet); - sftp_packet_free(packet); - if (msg == NULL) { - return -1; - } - - if (sftp_enqueue(sftp, msg) < 0) { - sftp_message_free(msg); - return -1; - } - - return 0; -} - -void sftp_packet_free(sftp_packet packet) { - if (packet == NULL) { - return; - } - - ssh_buffer_free(packet->payload); - free(packet); -} - -/* Initialize the sftp session with the server. */ -int sftp_init(sftp_session sftp) { - sftp_packet packet = NULL; - ssh_buffer buffer = NULL; - char *ext_name = NULL; - char *ext_data = NULL; - uint32_t version; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - rc = ssh_buffer_pack(buffer, "d", LIBSFTP_VERSION); - if (rc != SSH_OK) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - if (sftp_packet_write(sftp, SSH_FXP_INIT, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - packet = sftp_packet_read(sftp); - if (packet == NULL) { - return -1; - } - - if (packet->type != SSH_FXP_VERSION) { - ssh_set_error(sftp->session, SSH_FATAL, - "Received a %d messages instead of SSH_FXP_VERSION", packet->type); - sftp_packet_free(packet); - return -1; - } - - /* TODO: are we sure there are 4 bytes ready? */ - rc = ssh_buffer_unpack(packet->payload, "d", &version); - if (rc != SSH_OK){ - return -1; - } - SSH_LOG(SSH_LOG_RARE, - "SFTP server version %d", - version); - rc = ssh_buffer_unpack(packet->payload, "s", &ext_name); - while (rc == SSH_OK) { - int count = sftp->ext->count; - - rc = ssh_buffer_unpack(packet->payload, "s", &ext_data); - if (rc == SSH_ERROR) { - break; - } - - SSH_LOG(SSH_LOG_RARE, - "SFTP server extension: %s, version: %s", - ext_name, ext_data); - - count++; - sftp->ext->name = realloc(sftp->ext->name, count * sizeof(char *)); - if (sftp->ext->name == NULL) { - ssh_set_error_oom(sftp->session); - SAFE_FREE(ext_name); - SAFE_FREE(ext_data); - return -1; - } - sftp->ext->name[count - 1] = ext_name; - - sftp->ext->data = realloc(sftp->ext->data, count * sizeof(char *)); - if (sftp->ext->data == NULL) { - ssh_set_error_oom(sftp->session); - SAFE_FREE(ext_name); - SAFE_FREE(ext_data); - return -1; - } - sftp->ext->data[count - 1] = ext_data; - - sftp->ext->count = count; - - rc = ssh_buffer_unpack(packet->payload, "s", &ext_name); - } - - sftp_packet_free(packet); - - sftp->version = sftp->server_version = version; - - - return 0; -} - -unsigned int sftp_extensions_get_count(sftp_session sftp) { - if (sftp == NULL || sftp->ext == NULL) { - return 0; - } - - return sftp->ext->count; -} - -const char *sftp_extensions_get_name(sftp_session sftp, unsigned int idx) { - if (sftp == NULL) - return NULL; - if (sftp->ext == NULL || sftp->ext->name == NULL) { - ssh_set_error_invalid(sftp->session); - return NULL; - } - - if (idx > sftp->ext->count) { - ssh_set_error_invalid(sftp->session); - return NULL; - } - - return sftp->ext->name[idx]; -} - -const char *sftp_extensions_get_data(sftp_session sftp, unsigned int idx) { - if (sftp == NULL) - return NULL; - if (sftp->ext == NULL || sftp->ext->name == NULL) { - ssh_set_error_invalid(sftp->session); - return NULL; - } - - if (idx > sftp->ext->count) { - ssh_set_error_invalid(sftp->session); - return NULL; - } - - return sftp->ext->data[idx]; -} - -int sftp_extension_supported(sftp_session sftp, const char *name, - const char *data) { - int i, n; - - if (sftp == NULL || name == NULL || data == NULL) { - return 0; - } - - n = sftp_extensions_get_count(sftp); - for (i = 0; i < n; i++) { - const char *ext_name = sftp_extensions_get_name(sftp, i); - const char *ext_data = sftp_extensions_get_data(sftp, i); - - if (ext_name != NULL && ext_data != NULL && - strcmp(ext_name, name) == 0 && - strcmp(ext_data, data) == 0) { - return 1; - } - } - - return 0; -} - -static sftp_request_queue request_queue_new(sftp_message msg) { - sftp_request_queue queue = NULL; - - queue = malloc(sizeof(struct sftp_request_queue_struct)); - if (queue == NULL) { - ssh_set_error_oom(msg->sftp->session); - return NULL; - } - ZERO_STRUCTP(queue); - - queue->message = msg; - - return queue; -} - -static void request_queue_free(sftp_request_queue queue) { - if (queue == NULL) { - return; - } - - ZERO_STRUCTP(queue); - SAFE_FREE(queue); -} - -static int sftp_enqueue(sftp_session sftp, sftp_message msg) { - sftp_request_queue queue = NULL; - sftp_request_queue ptr; - - queue = request_queue_new(msg); - if (queue == NULL) { - return -1; - } - - SSH_LOG(SSH_LOG_PACKET, - "Queued msg type %d id %d", - msg->id, msg->packet_type); - - if(sftp->queue == NULL) { - sftp->queue = queue; - } else { - ptr = sftp->queue; - while(ptr->next) { - ptr=ptr->next; /* find end of linked list */ - } - ptr->next = queue; /* add it on bottom */ - } - - return 0; -} - -/* - * Pulls of a message from the queue based on the ID. - * Returns NULL if no message has been found. - */ -static sftp_message sftp_dequeue(sftp_session sftp, uint32_t id){ - sftp_request_queue prev = NULL; - sftp_request_queue queue; - sftp_message msg; - - if(sftp->queue == NULL) { - return NULL; - } - - queue = sftp->queue; - while (queue) { - if(queue->message->id == id) { - /* remove from queue */ - if (prev == NULL) { - sftp->queue = queue->next; - } else { - prev->next = queue->next; - } - msg = queue->message; - request_queue_free(queue); - SSH_LOG(SSH_LOG_PACKET, - "Dequeued msg id %d type %d", - msg->id, - msg->packet_type); - return msg; - } - prev = queue; - queue = queue->next; - } - - return NULL; -} - -/* - * Assigns a new SFTP ID for new requests and assures there is no collision - * between them. - * Returns a new ID ready to use in a request - */ -static inline uint32_t sftp_get_new_id(sftp_session session) { - return ++session->id_counter; -} - -static sftp_status_message parse_status_msg(sftp_message msg){ - sftp_status_message status; - int rc; - - if (msg->packet_type != SSH_FXP_STATUS) { - ssh_set_error(msg->sftp->session, SSH_FATAL, - "Not a ssh_fxp_status message passed in!"); - return NULL; - } - - status = malloc(sizeof(struct sftp_status_message_struct)); - if (status == NULL) { - ssh_set_error_oom(msg->sftp->session); - return NULL; - } - ZERO_STRUCTP(status); - - status->id = msg->id; - rc = ssh_buffer_unpack(msg->payload, "d", - &status->status); - if (rc != SSH_OK){ - SAFE_FREE(status); - ssh_set_error(msg->sftp->session, SSH_FATAL, - "Invalid SSH_FXP_STATUS message"); - return NULL; - } - rc = ssh_buffer_unpack(msg->payload, "ss", - &status->errormsg, - &status->langmsg); - - if(rc != SSH_OK && msg->sftp->version >=3){ - /* These are mandatory from version 3 */ - SAFE_FREE(status); - ssh_set_error(msg->sftp->session, SSH_FATAL, - "Invalid SSH_FXP_STATUS message"); - return NULL; - } - if (status->errormsg == NULL) - status->errormsg = strdup("No error message in packet"); - if (status->langmsg == NULL) - status->langmsg = strdup(""); - if (status->errormsg == NULL || status->langmsg == NULL) { - ssh_set_error_oom(msg->sftp->session); - status_msg_free(status); - return NULL; - } - - return status; -} - -static void status_msg_free(sftp_status_message status){ - if (status == NULL) { - return; - } - - SAFE_FREE(status->errormsg); - SAFE_FREE(status->langmsg); - SAFE_FREE(status); -} - -static sftp_file parse_handle_msg(sftp_message msg){ - sftp_file file; - - if(msg->packet_type != SSH_FXP_HANDLE) { - ssh_set_error(msg->sftp->session, SSH_FATAL, - "Not a ssh_fxp_handle message passed in!"); - return NULL; - } - - file = malloc(sizeof(struct sftp_file_struct)); - if (file == NULL) { - ssh_set_error_oom(msg->sftp->session); - return NULL; - } - ZERO_STRUCTP(file); - - file->handle = buffer_get_ssh_string(msg->payload); - if (file->handle == NULL) { - ssh_set_error(msg->sftp->session, SSH_FATAL, - "Invalid SSH_FXP_HANDLE message"); - SAFE_FREE(file); - return NULL; - } - - file->sftp = msg->sftp; - file->offset = 0; - file->eof = 0; - - return file; -} - -/* Open a directory */ -sftp_dir sftp_opendir(sftp_session sftp, const char *path){ - sftp_message msg = NULL; - sftp_file file = NULL; - sftp_dir dir = NULL; - sftp_status_message status; - ssh_string path_s; - ssh_buffer payload; - uint32_t id; - - payload = ssh_buffer_new(); - if (payload == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - path_s = ssh_string_from_char(path); - if (path_s == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(payload); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(payload, htonl(id)) < 0 || - buffer_add_ssh_string(payload, path_s) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(payload); - ssh_string_free(path_s); - return NULL; - } - ssh_string_free(path_s); - - if (sftp_packet_write(sftp, SSH_FXP_OPENDIR, payload) < 0) { - ssh_buffer_free(payload); - return NULL; - } - ssh_buffer_free(payload); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - /* something nasty has happened */ - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - switch (msg->packet_type) { - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - sftp_set_error(sftp, status->status); - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return NULL; - case SSH_FXP_HANDLE: - file = parse_handle_msg(msg); - sftp_message_free(msg); - if (file != NULL) { - dir = malloc(sizeof(struct sftp_dir_struct)); - if (dir == NULL) { - ssh_set_error_oom(sftp->session); - free(file); - return NULL; - } - ZERO_STRUCTP(dir); - - dir->sftp = sftp; - dir->name = strdup(path); - if (dir->name == NULL) { - SAFE_FREE(dir); - SAFE_FREE(file); - return NULL; - } - dir->handle = file->handle; - SAFE_FREE(file); - } - return dir; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d during opendir!", msg->packet_type); - sftp_message_free(msg); - } - - return NULL; -} - -/* - * Parse the attributes from a payload from some messages. It is coded on - * baselines from the protocol version 4. - * This code is more or less dead but maybe we need it in future. - */ -static sftp_attributes sftp_parse_attr_4(sftp_session sftp, ssh_buffer buf, - int expectnames) { - sftp_attributes attr; - ssh_string owner = NULL; - ssh_string group = NULL; - uint32_t flags = 0; - int ok = 0; - - /* unused member variable */ - (void) expectnames; - - attr = malloc(sizeof(struct sftp_attributes_struct)); - if (attr == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - ZERO_STRUCTP(attr); - - /* This isn't really a loop, but it is like a try..catch.. */ - do { - if (buffer_get_u32(buf, &flags) != 4) { - break; - } - - flags = ntohl(flags); - attr->flags = flags; - - if (flags & SSH_FILEXFER_ATTR_SIZE) { - if (buffer_get_u64(buf, &attr->size) != 8) { - break; - } - attr->size = ntohll(attr->size); - } - - if (flags & SSH_FILEXFER_ATTR_OWNERGROUP) { - owner = buffer_get_ssh_string(buf); - if (owner == NULL) { - break; - } - attr->owner = ssh_string_to_char(owner); - ssh_string_free(owner); - if (attr->owner == NULL) { - break; - } - - group = buffer_get_ssh_string(buf); - if (group == NULL) { - break; - } - attr->group = ssh_string_to_char(group); - ssh_string_free(group); - if (attr->group == NULL) { - break; - } - } - - if (flags & SSH_FILEXFER_ATTR_PERMISSIONS) { - if (buffer_get_u32(buf, &attr->permissions) != 4) { - break; - } - attr->permissions = ntohl(attr->permissions); - - /* FIXME on windows! */ - switch (attr->permissions & S_IFMT) { - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - attr->type = SSH_FILEXFER_TYPE_SPECIAL; - break; - case S_IFLNK: - attr->type = SSH_FILEXFER_TYPE_SYMLINK; - break; - case S_IFREG: - attr->type = SSH_FILEXFER_TYPE_REGULAR; - break; - case S_IFDIR: - attr->type = SSH_FILEXFER_TYPE_DIRECTORY; - break; - default: - attr->type = SSH_FILEXFER_TYPE_UNKNOWN; - break; - } - } - - if (flags & SSH_FILEXFER_ATTR_ACCESSTIME) { - if (buffer_get_u64(buf, &attr->atime64) != 8) { - break; - } - attr->atime64 = ntohll(attr->atime64); - } - - if (flags & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) { - if (buffer_get_u32(buf, &attr->atime_nseconds) != 4) { - break; - } - attr->atime_nseconds = ntohl(attr->atime_nseconds); - } - - if (flags & SSH_FILEXFER_ATTR_CREATETIME) { - if (buffer_get_u64(buf, &attr->createtime) != 8) { - break; - } - attr->createtime = ntohll(attr->createtime); - } - - if (flags & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) { - if (buffer_get_u32(buf, &attr->createtime_nseconds) != 4) { - break; - } - attr->createtime_nseconds = ntohl(attr->createtime_nseconds); - } - - if (flags & SSH_FILEXFER_ATTR_MODIFYTIME) { - if (buffer_get_u64(buf, &attr->mtime64) != 8) { - break; - } - attr->mtime64 = ntohll(attr->mtime64); - } - - if (flags & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) { - if (buffer_get_u32(buf, &attr->mtime_nseconds) != 4) { - break; - } - attr->mtime_nseconds = ntohl(attr->mtime_nseconds); - } - - if (flags & SSH_FILEXFER_ATTR_ACL) { - if ((attr->acl = buffer_get_ssh_string(buf)) == NULL) { - break; - } - } - - if (flags & SSH_FILEXFER_ATTR_EXTENDED) { - if (buffer_get_u32(buf,&attr->extended_count) != 4) { - break; - } - attr->extended_count = ntohl(attr->extended_count); - - while(attr->extended_count && - (attr->extended_type = buffer_get_ssh_string(buf)) && - (attr->extended_data = buffer_get_ssh_string(buf))){ - attr->extended_count--; - } - - if (attr->extended_count) { - break; - } - } - ok = 1; - } while (0); - - if (ok == 0) { - /* break issued somewhere */ - ssh_string_free(attr->acl); - ssh_string_free(attr->extended_type); - ssh_string_free(attr->extended_data); - SAFE_FREE(attr->owner); - SAFE_FREE(attr->group); - SAFE_FREE(attr); - - ssh_set_error(sftp->session, SSH_FATAL, "Invalid ATTR structure"); - - return NULL; - } - - return attr; -} - -enum sftp_longname_field_e { - SFTP_LONGNAME_PERM = 0, - SFTP_LONGNAME_FIXME, - SFTP_LONGNAME_OWNER, - SFTP_LONGNAME_GROUP, - SFTP_LONGNAME_SIZE, - SFTP_LONGNAME_DATE, - SFTP_LONGNAME_TIME, - SFTP_LONGNAME_NAME, -}; - -static char *sftp_parse_longname(const char *longname, - enum sftp_longname_field_e longname_field) { - const char *p, *q; - size_t len, field = 0; - char *x; - - p = longname; - /* Find the beginning of the field which is specified by sftp_longanme_field_e. */ - while(field != longname_field) { - if(isspace(*p)) { - field++; - p++; - while(*p && isspace(*p)) { - p++; - } - } else { - p++; - } - } - - q = p; - while (! isspace(*q)) { - q++; - } - - /* There is no strndup on windows */ - len = q - p + 1; - x = malloc(len); - if (x == NULL) { - return NULL; - } - - snprintf(x, len, "%s", p); - - return x; -} - -/* sftp version 0-3 code. It is different from the v4 */ -/* maybe a paste of the draft is better than the code */ -/* - uint32 flags - uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE - uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID - uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID - uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS - uint32 atime present only if flag SSH_FILEXFER_ACMODTIME - uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME - uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED - string extended_type - string extended_data - ... more extended data (extended_type - extended_data pairs), - so that number of pairs equals extended_count */ -static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf, - int expectname) { - sftp_attributes attr; - int rc; - - attr = malloc(sizeof(struct sftp_attributes_struct)); - if (attr == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - ZERO_STRUCTP(attr); - - if (expectname) { - rc = ssh_buffer_unpack(buf, "ss", - &attr->name, - &attr->longname); - if (rc != SSH_OK){ - goto error; - } - SSH_LOG(SSH_LOG_RARE, "Name: %s", attr->name); - - /* Set owner and group if we talk to openssh and have the longname */ - if (ssh_get_openssh_version(sftp->session)) { - attr->owner = sftp_parse_longname(attr->longname, SFTP_LONGNAME_OWNER); - if (attr->owner == NULL) { - goto error; - } - - attr->group = sftp_parse_longname(attr->longname, SFTP_LONGNAME_GROUP); - if (attr->group == NULL) { - goto error; - } - } - } - - rc = ssh_buffer_unpack(buf, "d", &attr->flags); - if (rc != SSH_OK){ - goto error; - } - SSH_LOG(SSH_LOG_RARE, - "Flags: %.8lx\n", (long unsigned int) attr->flags); - - if (attr->flags & SSH_FILEXFER_ATTR_SIZE) { - rc = ssh_buffer_unpack(buf, "q", &attr->size); - if(rc != SSH_OK) { - goto error; - } - SSH_LOG(SSH_LOG_RARE, - "Size: %llu\n", - (long long unsigned int) attr->size); - } - - if (attr->flags & SSH_FILEXFER_ATTR_UIDGID) { - rc = ssh_buffer_unpack(buf, "dd", - &attr->uid, - &attr->gid); - if (rc != SSH_OK){ - goto error; - } - } - - if (attr->flags & SSH_FILEXFER_ATTR_PERMISSIONS) { - rc = ssh_buffer_unpack(buf, "d", &attr->permissions); - if (rc != SSH_OK){ - goto error; - } - - switch (attr->permissions & S_IFMT) { - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - attr->type = SSH_FILEXFER_TYPE_SPECIAL; - break; - case S_IFLNK: - attr->type = SSH_FILEXFER_TYPE_SYMLINK; - break; - case S_IFREG: - attr->type = SSH_FILEXFER_TYPE_REGULAR; - break; - case S_IFDIR: - attr->type = SSH_FILEXFER_TYPE_DIRECTORY; - break; - default: - attr->type = SSH_FILEXFER_TYPE_UNKNOWN; - break; - } - } - - if (attr->flags & SSH_FILEXFER_ATTR_ACMODTIME) { - rc = ssh_buffer_unpack(buf, "dd", - &attr->atime, - &attr->mtime); - if (rc != SSH_OK){ - goto error; - } - } - - if (attr->flags & SSH_FILEXFER_ATTR_EXTENDED) { - rc = ssh_buffer_unpack(buf, "d", &attr->extended_count); - if (rc != SSH_OK){ - goto error; - } - - if (attr->extended_count > 0){ - rc = ssh_buffer_unpack(buf, "ss", - &attr->extended_type, - &attr->extended_data); - if (rc != SSH_OK){ - goto error; - } - attr->extended_count--; - } - /* just ignore the remaining extensions */ - - while (attr->extended_count > 0){ - ssh_string tmp1,tmp2; - rc = ssh_buffer_unpack(buf, "SS", &tmp1, &tmp2); - if (rc != SSH_OK){ - goto error; - } - SAFE_FREE(tmp1); - SAFE_FREE(tmp2); - attr->extended_count--; - } - } - - return attr; - - error: - ssh_string_free(attr->extended_type); - ssh_string_free(attr->extended_data); - SAFE_FREE(attr->name); - SAFE_FREE(attr->longname); - SAFE_FREE(attr->owner); - SAFE_FREE(attr->group); - SAFE_FREE(attr); - ssh_set_error(sftp->session, SSH_FATAL, "Invalid ATTR structure"); - - return NULL; -} - -/* FIXME is this really needed as a public function? */ -int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr) { - uint32_t flags = (attr ? attr->flags : 0); - int rc; - - flags &= (SSH_FILEXFER_ATTR_SIZE | SSH_FILEXFER_ATTR_UIDGID | - SSH_FILEXFER_ATTR_PERMISSIONS | SSH_FILEXFER_ATTR_ACMODTIME); - - rc = ssh_buffer_pack(buffer, "d", flags); - if (rc != SSH_OK) { - return -1; - } - - if (attr != NULL) { - if (flags & SSH_FILEXFER_ATTR_SIZE) { - rc = ssh_buffer_pack(buffer, "q", attr->size); - if (rc != SSH_OK) { - return -1; - } - } - - if (flags & SSH_FILEXFER_ATTR_UIDGID) { - rc = ssh_buffer_pack(buffer, "dd", attr->uid, attr->gid); - if (rc != SSH_OK) { - return -1; - } - } - - if (flags & SSH_FILEXFER_ATTR_PERMISSIONS) { - rc = ssh_buffer_pack(buffer, "d", attr->permissions); - if (rc != SSH_OK) { - return -1; - } - } - - if (flags & SSH_FILEXFER_ATTR_ACMODTIME) { - rc = ssh_buffer_pack(buffer, "dd", attr->atime, attr->mtime); - if (rc != SSH_OK) { - return -1; - } - } - } - return 0; -} - - -sftp_attributes sftp_parse_attr(sftp_session session, ssh_buffer buf, - int expectname) { - switch(session->version) { - case 4: - return sftp_parse_attr_4(session, buf, expectname); - case 3: - case 2: - case 1: - case 0: - return sftp_parse_attr_3(session, buf, expectname); - default: - ssh_set_error(session->session, SSH_FATAL, - "Version %d unsupported by client", session->server_version); - return NULL; - } - - return NULL; -} - -/* Get the version of the SFTP protocol supported by the server */ -int sftp_server_version(sftp_session sftp) { - return sftp->server_version; -} - -/* Get a single file attributes structure of a directory. */ -sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir) { - sftp_message msg = NULL; - sftp_status_message status; - sftp_attributes attr; - ssh_buffer payload; - uint32_t id; - - if (dir->buffer == NULL) { - payload = ssh_buffer_new(); - if (payload == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(payload, htonl(id)) < 0 || - buffer_add_ssh_string(payload, dir->handle) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(payload); - return NULL; - } - - if (sftp_packet_write(sftp, SSH_FXP_READDIR, payload) < 0) { - ssh_buffer_free(payload); - return NULL; - } - ssh_buffer_free(payload); - - SSH_LOG(SSH_LOG_PACKET, - "Sent a ssh_fxp_readdir with id %d", id); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - /* something nasty has happened */ - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - switch (msg->packet_type){ - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_EOF: - dir->eof = 1; - status_msg_free(status); - return NULL; - default: - break; - } - - ssh_set_error(sftp->session, SSH_FATAL, - "Unknown error status: %d", status->status); - status_msg_free(status); - - return NULL; - case SSH_FXP_NAME: - buffer_get_u32(msg->payload, &dir->count); - dir->count = ntohl(dir->count); - dir->buffer = msg->payload; - msg->payload = NULL; - sftp_message_free(msg); - break; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Unsupported message back %d", msg->packet_type); - sftp_message_free(msg); - - return NULL; - } - } - - /* now dir->buffer contains a buffer and dir->count != 0 */ - if (dir->count == 0) { - ssh_set_error(sftp->session, SSH_FATAL, - "Count of files sent by the server is zero, which is invalid, or " - "libsftp bug"); - return NULL; - } - - SSH_LOG(SSH_LOG_RARE, "Count is %d", dir->count); - - attr = sftp_parse_attr(sftp, dir->buffer, 1); - if (attr == NULL) { - ssh_set_error(sftp->session, SSH_FATAL, - "Couldn't parse the SFTP attributes"); - return NULL; - } - - dir->count--; - if (dir->count == 0) { - ssh_buffer_free(dir->buffer); - dir->buffer = NULL; - } - - return attr; -} - -/* Tell if the directory has reached EOF (End Of File). */ -int sftp_dir_eof(sftp_dir dir) { - return dir->eof; -} - -/* Free a SFTP_ATTRIBUTE handle */ -void sftp_attributes_free(sftp_attributes file){ - if (file == NULL) { - return; - } - - ssh_string_free(file->acl); - ssh_string_free(file->extended_data); - ssh_string_free(file->extended_type); - - SAFE_FREE(file->name); - SAFE_FREE(file->longname); - SAFE_FREE(file->group); - SAFE_FREE(file->owner); - - SAFE_FREE(file); -} - -static int sftp_handle_close(sftp_session sftp, ssh_string handle) { - sftp_status_message status; - sftp_message msg = NULL; - ssh_buffer buffer = NULL; - uint32_t id; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, handle) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - if (sftp_packet_write(sftp, SSH_FXP_CLOSE ,buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - /* something nasty has happened */ - return -1; - } - msg = sftp_dequeue(sftp,id); - } - - switch (msg->packet_type) { - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if(status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - status_msg_free(status); - return 0; - break; - default: - break; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d during sftp_handle_close!", msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -/* Close an open file handle. */ -int sftp_close(sftp_file file){ - int err = SSH_NO_ERROR; - - SAFE_FREE(file->name); - if (file->handle){ - err = sftp_handle_close(file->sftp,file->handle); - ssh_string_free(file->handle); - } - /* FIXME: check server response and implement errno */ - SAFE_FREE(file); - - return err; -} - -/* Close an open directory. */ -int sftp_closedir(sftp_dir dir){ - int err = SSH_NO_ERROR; - - SAFE_FREE(dir->name); - if (dir->handle) { - err = sftp_handle_close(dir->sftp, dir->handle); - ssh_string_free(dir->handle); - } - /* FIXME: check server response and implement errno */ - ssh_buffer_free(dir->buffer); - SAFE_FREE(dir); - - return err; -} - -/* Open a file on the server. */ -sftp_file sftp_open(sftp_session sftp, const char *file, int flags, - mode_t mode) { - sftp_message msg = NULL; - sftp_status_message status; - struct sftp_attributes_struct attr; - sftp_file handle; - ssh_string filename; - ssh_buffer buffer; - uint32_t sftp_flags = 0; - uint32_t id; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - filename = ssh_string_from_char(file); - if (filename == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - - ZERO_STRUCT(attr); - attr.permissions = mode; - attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS; - - if (flags == O_RDONLY) - sftp_flags |= SSH_FXF_READ; /* if any of the other flag is set, - READ should not be set initialy */ - if (flags & O_WRONLY) - sftp_flags |= SSH_FXF_WRITE; - if (flags & O_RDWR) - sftp_flags |= (SSH_FXF_WRITE | SSH_FXF_READ); - if (flags & O_CREAT) - sftp_flags |= SSH_FXF_CREAT; - if (flags & O_TRUNC) - sftp_flags |= SSH_FXF_TRUNC; - if (flags & O_EXCL) - sftp_flags |= SSH_FXF_EXCL; - SSH_LOG(SSH_LOG_PACKET,"Opening file %s with sftp flags %x",file,sftp_flags); - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, filename) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(filename); - return NULL; - } - ssh_string_free(filename); - - if (buffer_add_u32(buffer, htonl(sftp_flags)) < 0 || - buffer_add_attributes(buffer, &attr) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - if (sftp_packet_write(sftp, SSH_FXP_OPEN, buffer) < 0) { - ssh_buffer_free(buffer); - return NULL; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - /* something nasty has happened */ - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - switch (msg->packet_type) { - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - sftp_set_error(sftp, status->status); - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - - return NULL; - case SSH_FXP_HANDLE: - handle = parse_handle_msg(msg); - sftp_message_free(msg); - return handle; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d during open!", msg->packet_type); - sftp_message_free(msg); - } - - return NULL; -} - -void sftp_file_set_nonblocking(sftp_file handle){ - handle->nonblocking=1; -} -void sftp_file_set_blocking(sftp_file handle){ - handle->nonblocking=0; -} - -/* Read from a file using an opened sftp file handle. */ -ssize_t sftp_read(sftp_file handle, void *buf, size_t count) { - sftp_session sftp = handle->sftp; - sftp_message msg = NULL; - sftp_status_message status; - ssh_string datastring; - ssh_buffer buffer; - int id; - int rc; - - if (handle->eof) { - return 0; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(handle->sftp); - - rc = ssh_buffer_pack(buffer, - "dSqd", - id, - handle->handle, - handle->offset, - count); - if (rc != SSH_OK){ - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - if (sftp_packet_write(handle->sftp, SSH_FXP_READ, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (handle->nonblocking) { - if (ssh_channel_poll(handle->sftp->channel, 0) == 0) { - /* we cannot block */ - return 0; - } - } - if (sftp_read_and_dispatch(handle->sftp) < 0) { - /* something nasty has happened */ - return -1; - } - msg = sftp_dequeue(handle->sftp, id); - } - - switch (msg->packet_type) { - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_EOF: - handle->eof = 1; - status_msg_free(status); - return 0; - default: - break; - } - ssh_set_error(sftp->session,SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - case SSH_FXP_DATA: - datastring = buffer_get_ssh_string(msg->payload); - sftp_message_free(msg); - if (datastring == NULL) { - ssh_set_error(sftp->session, SSH_FATAL, - "Received invalid DATA packet from sftp server"); - return -1; - } - - if (ssh_string_len(datastring) > count) { - ssh_set_error(sftp->session, SSH_FATAL, - "Received a too big DATA packet from sftp server: " - "%" PRIdS " and asked for %" PRIdS, - ssh_string_len(datastring), count); - ssh_string_free(datastring); - return -1; - } - count = ssh_string_len(datastring); - handle->offset += count; - memcpy(buf, ssh_string_data(datastring), count); - ssh_string_free(datastring); - return count; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d during read!", msg->packet_type); - sftp_message_free(msg); - return -1; - } - - return -1; /* not reached */ -} - -/* Start an asynchronous read from a file using an opened sftp file handle. */ -int sftp_async_read_begin(sftp_file file, uint32_t len){ - sftp_session sftp = file->sftp; - ssh_buffer buffer; - uint32_t id; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(sftp); - - rc = ssh_buffer_pack(buffer, - "dSqd", - id, - file->handle, - file->offset, - len); - if (rc != SSH_OK) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - if (sftp_packet_write(sftp, SSH_FXP_READ, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - file->offset += len; /* assume we'll read len bytes */ - - return id; -} - -/* Wait for an asynchronous read to complete and save the data. */ -int sftp_async_read(sftp_file file, void *data, uint32_t size, uint32_t id){ - sftp_session sftp; - sftp_message msg = NULL; - sftp_status_message status; - ssh_string datastring; - int err = SSH_OK; - uint32_t len; - - if (file == NULL) { - return SSH_ERROR; - } - sftp = file->sftp; - - if (file->eof) { - return 0; - } - - /* handle an existing request */ - while (msg == NULL) { - if (file->nonblocking){ - if (ssh_channel_poll(sftp->channel, 0) == 0) { - /* we cannot block */ - return SSH_AGAIN; - } - } - - if (sftp_read_and_dispatch(sftp) < 0) { - /* something nasty has happened */ - return SSH_ERROR; - } - - msg = sftp_dequeue(sftp,id); - } - - switch (msg->packet_type) { - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - if (status->status != SSH_FX_EOF) { - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server : %s", status->errormsg); - err = SSH_ERROR; - } else { - file->eof = 1; - } - status_msg_free(status); - return err; - case SSH_FXP_DATA: - datastring = buffer_get_ssh_string(msg->payload); - sftp_message_free(msg); - if (datastring == NULL) { - ssh_set_error(sftp->session, SSH_FATAL, - "Received invalid DATA packet from sftp server"); - return SSH_ERROR; - } - if (ssh_string_len(datastring) > size) { - ssh_set_error(sftp->session, SSH_FATAL, - "Received a too big DATA packet from sftp server: " - "%" PRIdS " and asked for %u", - ssh_string_len(datastring), size); - ssh_string_free(datastring); - return SSH_ERROR; - } - len = ssh_string_len(datastring); - /* Update the offset with the correct value */ - file->offset = file->offset - (size - len); - memcpy(data, ssh_string_data(datastring), len); - ssh_string_free(datastring); - return len; - default: - ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during read!",msg->packet_type); - sftp_message_free(msg); - return SSH_ERROR; - } - - return SSH_ERROR; -} - -ssize_t sftp_write(sftp_file file, const void *buf, size_t count) { - sftp_session sftp = file->sftp; - sftp_message msg = NULL; - sftp_status_message status; - ssh_buffer buffer; - uint32_t id; - int len; - int packetlen; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(file->sftp); - - rc = ssh_buffer_pack(buffer, - "dSqdP", - id, - file->handle, - file->offset, - count, /* len of datastring */ - (size_t)count, buf); - if (rc != SSH_OK){ - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - packetlen=buffer_get_rest_len(buffer); - len = sftp_packet_write(file->sftp, SSH_FXP_WRITE, buffer); - ssh_buffer_free(buffer); - if (len < 0) { - return -1; - } else if (len != packetlen) { - SSH_LOG(SSH_LOG_PACKET, - "Could not write as much data as expected"); - } - - while (msg == NULL) { - if (sftp_read_and_dispatch(file->sftp) < 0) { - /* something nasty has happened */ - return -1; - } - msg = sftp_dequeue(file->sftp, id); - } - - switch (msg->packet_type) { - case SSH_FXP_STATUS: - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - file->offset += count; - status_msg_free(status); - return count; - default: - break; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - file->offset += count; - status_msg_free(status); - return -1; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d during write!", msg->packet_type); - sftp_message_free(msg); - return -1; - } - - return -1; /* not reached */ -} - -/* Seek to a specific location in a file. */ -int sftp_seek(sftp_file file, uint32_t new_offset) { - if (file == NULL) { - return -1; - } - - file->offset = new_offset; - file->eof = 0; - - return 0; -} - -int sftp_seek64(sftp_file file, uint64_t new_offset) { - if (file == NULL) { - return -1; - } - - file->offset = new_offset; - file->eof = 0; - - return 0; -} - -/* Report current byte position in file. */ -unsigned long sftp_tell(sftp_file file) { - return (unsigned long)file->offset; -} -/* Report current byte position in file. */ -uint64_t sftp_tell64(sftp_file file) { - return (uint64_t) file->offset; -} - -/* Rewinds the position of the file pointer to the beginning of the file.*/ -void sftp_rewind(sftp_file file) { - file->offset = 0; - file->eof = 0; -} - -/* code written by Nick */ -int sftp_unlink(sftp_session sftp, const char *file) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_buffer buffer; - uint32_t id; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(sftp); - - rc = ssh_buffer_pack(buffer, - "ds", - id, - file); - if (rc != SSH_OK) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - - if (sftp_packet_write(sftp, SSH_FXP_REMOVE, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp)) { - return -1; - } - msg = sftp_dequeue(sftp, id); - } - - if (msg->packet_type == SSH_FXP_STATUS) { - /* by specification, this command's only supposed to return SSH_FXP_STATUS */ - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - status_msg_free(status); - return 0; - default: - break; - } - - /* - * The status should be SSH_FX_OK if the command was successful, if it - * didn't, then there was an error - */ - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - } else { - ssh_set_error(sftp->session,SSH_FATAL, - "Received message %d when attempting to remove file", msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -/* code written by Nick */ -int sftp_rmdir(sftp_session sftp, const char *directory) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_buffer buffer; - uint32_t id; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(sftp); - - rc = ssh_buffer_pack(buffer, - "ds", - id, - directory); - if (rc != SSH_OK) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - if (sftp_packet_write(sftp, SSH_FXP_RMDIR, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return -1; - } - msg = sftp_dequeue(sftp, id); - } - - /* By specification, this command returns SSH_FXP_STATUS */ - if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - status_msg_free(status); - return 0; - break; - default: - break; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - } else { - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to remove directory", - msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -/* Code written by Nick */ -int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - sftp_attributes errno_attr = NULL; - struct sftp_attributes_struct attr; - ssh_buffer buffer; - ssh_string path; - uint32_t id; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - path = ssh_string_from_char(directory); - if (path == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - - ZERO_STRUCT(attr); - attr.permissions = mode; - attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS; - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, path) < 0 || - buffer_add_attributes(buffer, &attr) < 0 || - sftp_packet_write(sftp, SSH_FXP_MKDIR, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(path); - return -1; - } - ssh_buffer_free(buffer); - ssh_string_free(path); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return -1; - } - msg = sftp_dequeue(sftp, id); - } - - /* By specification, this command only returns SSH_FXP_STATUS */ - if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_FAILURE: - /* - * mkdir always returns a failure, even if the path already exists. - * To be POSIX conform and to be able to map it to EEXIST a stat - * call is needed here. - */ - errno_attr = sftp_lstat(sftp, directory); - if (errno_attr != NULL) { - SAFE_FREE(errno_attr); - sftp_set_error(sftp, SSH_FX_FILE_ALREADY_EXISTS); - } - break; - case SSH_FX_OK: - status_msg_free(status); - return 0; - break; - default: - break; - } - /* - * The status should be SSH_FX_OK if the command was successful, if it - * didn't, then there was an error - */ - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - } else { - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to make directory", - msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -/* code written by nick */ -int sftp_rename(sftp_session sftp, const char *original, const char *newname) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_buffer buffer; - uint32_t id; - int rc; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(sftp); - - rc = ssh_buffer_pack(buffer, - "dss", - id, - original, - newname); - if (rc != SSH_OK) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - - if (sftp->version >= 4){ - /* POSIX rename atomically replaces newpath, we should do the same - * only available on >=v4 */ - buffer_add_u32(buffer, SSH_FXF_RENAME_OVERWRITE); - } - - if (sftp_packet_write(sftp, SSH_FXP_RENAME, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return -1; - } - msg = sftp_dequeue(sftp, id); - } - - /* By specification, this command only returns SSH_FXP_STATUS */ - if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - status_msg_free(status); - return 0; - default: - break; - } - /* - * Status should be SSH_FX_OK if the command was successful, if it didn't, - * then there was an error - */ - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - } else { - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to rename", - msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -/* Code written by Nick */ -/* Set file attributes on a file, directory or symbolic link. */ -int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr) { - uint32_t id; - ssh_buffer buffer; - ssh_string path; - sftp_message msg = NULL; - sftp_status_message status = NULL; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - path = ssh_string_from_char(file); - if (path == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, path) < 0 || - buffer_add_attributes(buffer, attr) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(path); - return -1; - } - if (sftp_packet_write(sftp, SSH_FXP_SETSTAT, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(path); - return -1; - } - ssh_buffer_free(buffer); - ssh_string_free(path); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return -1; - } - msg = sftp_dequeue(sftp, id); - } - - /* By specification, this command only returns SSH_FXP_STATUS */ - if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - status_msg_free(status); - return 0; - default: - break; - } - /* - * The status should be SSH_FX_OK if the command was successful, if it - * didn't, then there was an error - */ - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - } else { - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to set stats", msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -/* Change the file owner and group */ -int sftp_chown(sftp_session sftp, const char *file, uid_t owner, gid_t group) { - struct sftp_attributes_struct attr; - ZERO_STRUCT(attr); - - attr.uid = owner; - attr.gid = group; - - attr.flags = SSH_FILEXFER_ATTR_UIDGID; - - return sftp_setstat(sftp, file, &attr); -} - -/* Change permissions of a file */ -int sftp_chmod(sftp_session sftp, const char *file, mode_t mode) { - struct sftp_attributes_struct attr; - ZERO_STRUCT(attr); - attr.permissions = mode; - attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS; - - return sftp_setstat(sftp, file, &attr); -} - -/* Change the last modification and access time of a file. */ -int sftp_utimes(sftp_session sftp, const char *file, - const struct timeval *times) { - struct sftp_attributes_struct attr; - ZERO_STRUCT(attr); - - attr.atime = times[0].tv_sec; - attr.atime_nseconds = times[0].tv_usec; - - attr.mtime = times[1].tv_sec; - attr.mtime_nseconds = times[1].tv_usec; - - attr.flags |= SSH_FILEXFER_ATTR_ACCESSTIME | SSH_FILEXFER_ATTR_MODIFYTIME | - SSH_FILEXFER_ATTR_SUBSECOND_TIMES; - - return sftp_setstat(sftp, file, &attr); -} - -int sftp_symlink(sftp_session sftp, const char *target, const char *dest) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_buffer buffer; - uint32_t id; - int rc; - - if (sftp == NULL) - return -1; - if (target == NULL || dest == NULL) { - ssh_set_error_invalid(sftp->session); - return -1; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return -1; - } - - id = sftp_get_new_id(sftp); - - /* TODO check for version number if they ever fix it. */ - if (ssh_get_openssh_version(sftp->session)) { - rc = ssh_buffer_pack(buffer, - "dss", - id, - target, - dest); - } else { - rc = ssh_buffer_pack(buffer, - "dss", - id, - dest, - target); - } - if (rc != SSH_OK){ - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return -1; - } - - if (sftp_packet_write(sftp, SSH_FXP_SYMLINK, buffer) < 0) { - ssh_buffer_free(buffer); - return -1; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return -1; - } - msg = sftp_dequeue(sftp, id); - } - - /* By specification, this command only returns SSH_FXP_STATUS */ - if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return -1; - } - sftp_set_error(sftp, status->status); - switch (status->status) { - case SSH_FX_OK: - status_msg_free(status); - return 0; - default: - break; - } - /* - * The status should be SSH_FX_OK if the command was successful, if it - * didn't, then there was an error - */ - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return -1; - } else { - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to set stats", msg->packet_type); - sftp_message_free(msg); - } - - return -1; -} - -char *sftp_readlink(sftp_session sftp, const char *path) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_string path_s = NULL; - ssh_string link_s = NULL; - ssh_buffer buffer; - char *lnk; - uint32_t ignored; - uint32_t id; - - if (sftp == NULL) - return NULL; - if (path == NULL) { - ssh_set_error_invalid(sftp); - return NULL; - } - if (sftp->version < 3){ - ssh_set_error(sftp,SSH_REQUEST_DENIED,"sftp version %d does not support sftp_readlink",sftp->version); - return NULL; - } - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - path_s = ssh_string_from_char(path); - if (path_s == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, path_s) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(path_s); - return NULL; - } - if (sftp_packet_write(sftp, SSH_FXP_READLINK, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(path_s); - return NULL; - } - ssh_buffer_free(buffer); - ssh_string_free(path_s); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - if (msg->packet_type == SSH_FXP_NAME) { - /* we don't care about "count" */ - buffer_get_u32(msg->payload, &ignored); - /* we only care about the file name string */ - link_s = buffer_get_ssh_string(msg->payload); - sftp_message_free(msg); - if (link_s == NULL) { - /* TODO: what error to set here? */ - return NULL; - } - lnk = ssh_string_to_char(link_s); - ssh_string_free(link_s); - - return lnk; - } else if (msg->packet_type == SSH_FXP_STATUS) { /* bad response (error) */ - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - } else { /* this shouldn't happen */ - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to set stats", msg->packet_type); - sftp_message_free(msg); - } - - return NULL; -} - -static sftp_statvfs_t sftp_parse_statvfs(sftp_session sftp, ssh_buffer buf) { - sftp_statvfs_t statvfs; - int rc; - - statvfs = malloc(sizeof(struct sftp_statvfs_struct)); - if (statvfs == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - ZERO_STRUCTP(statvfs); - - rc = ssh_buffer_unpack(buf, "qqqqqqqqqqq", - &statvfs->f_bsize, /* file system block size */ - &statvfs->f_frsize, /* fundamental fs block size */ - &statvfs->f_blocks, /* number of blocks (unit f_frsize) */ - &statvfs->f_bfree, /* free blocks in file system */ - &statvfs->f_bavail, /* free blocks for non-root */ - &statvfs->f_files, /* total file inodes */ - &statvfs->f_ffree, /* free file inodes */ - &statvfs->f_favail, /* free file inodes for to non-root */ - &statvfs->f_fsid, /* file system id */ - &statvfs->f_flag, /* bit mask of f_flag values */ - &statvfs->f_namemax/* maximum filename length */ - ); - if (rc != SSH_OK) { - SAFE_FREE(statvfs); - ssh_set_error(sftp->session, SSH_FATAL, "Invalid statvfs structure"); - return NULL; - } - - return statvfs; -} - -sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_string pathstr; - ssh_string ext; - ssh_buffer buffer; - uint32_t id; - - if (sftp == NULL) - return NULL; - if (path == NULL) { - ssh_set_error_invalid(sftp->session); - return NULL; - } - if (sftp->version < 3){ - ssh_set_error(sftp,SSH_REQUEST_DENIED,"sftp version %d does not support sftp_statvfs",sftp->version); - return NULL; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - ext = ssh_string_from_char("statvfs@openssh.com"); - if (ext == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - - pathstr = ssh_string_from_char(path); - if (pathstr == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(ext); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, ext) < 0 || - buffer_add_ssh_string(buffer, pathstr) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(ext); - ssh_string_free(pathstr); - return NULL; - } - if (sftp_packet_write(sftp, SSH_FXP_EXTENDED, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(ext); - ssh_string_free(pathstr); - return NULL; - } - ssh_buffer_free(buffer); - ssh_string_free(ext); - ssh_string_free(pathstr); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - if (msg->packet_type == SSH_FXP_EXTENDED_REPLY) { - sftp_statvfs_t buf = sftp_parse_statvfs(sftp, msg->payload); - sftp_message_free(msg); - if (buf == NULL) { - return NULL; - } - - return buf; - } else if (msg->packet_type == SSH_FXP_STATUS) { /* bad response (error) */ - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - } else { /* this shouldn't happen */ - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to get statvfs", msg->packet_type); - sftp_message_free(msg); - } - - return NULL; -} - -sftp_statvfs_t sftp_fstatvfs(sftp_file file) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - sftp_session sftp; - ssh_string ext; - ssh_buffer buffer; - uint32_t id; - - if (file == NULL) { - return NULL; - } - sftp = file->sftp; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - ext = ssh_string_from_char("fstatvfs@openssh.com"); - if (ext == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, ext) < 0 || - buffer_add_ssh_string(buffer, file->handle) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(ext); - return NULL; - } - if (sftp_packet_write(sftp, SSH_FXP_EXTENDED, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(ext); - return NULL; - } - ssh_buffer_free(buffer); - ssh_string_free(ext); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - if (msg->packet_type == SSH_FXP_EXTENDED_REPLY) { - sftp_statvfs_t buf = sftp_parse_statvfs(sftp, msg->payload); - sftp_message_free(msg); - if (buf == NULL) { - return NULL; - } - - return buf; - } else if (msg->packet_type == SSH_FXP_STATUS) { /* bad response (error) */ - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - } else { /* this shouldn't happen */ - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to set stats", msg->packet_type); - sftp_message_free(msg); - } - - return NULL; -} - -void sftp_statvfs_free(sftp_statvfs_t statvfs) { - if (statvfs == NULL) { - return; - } - - SAFE_FREE(statvfs); -} - -/* another code written by Nick */ -char *sftp_canonicalize_path(sftp_session sftp, const char *path) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_string name = NULL; - ssh_string pathstr; - ssh_buffer buffer; - char *cname; - uint32_t ignored; - uint32_t id; - - if (sftp == NULL) - return NULL; - if (path == NULL) { - ssh_set_error_invalid(sftp->session); - return NULL; - } - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - pathstr = ssh_string_from_char(path); - if (pathstr == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, pathstr) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(pathstr); - return NULL; - } - if (sftp_packet_write(sftp, SSH_FXP_REALPATH, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(pathstr); - return NULL; - } - ssh_buffer_free(buffer); - ssh_string_free(pathstr); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - if (msg->packet_type == SSH_FXP_NAME) { - /* we don't care about "count" */ - buffer_get_u32(msg->payload, &ignored); - /* we only care about the file name string */ - name = buffer_get_ssh_string(msg->payload); - sftp_message_free(msg); - if (name == NULL) { - /* TODO: error message? */ - return NULL; - } - cname = ssh_string_to_char(name); - ssh_string_free(name); - if (cname == NULL) { - ssh_set_error_oom(sftp->session); - } - return cname; - } else if (msg->packet_type == SSH_FXP_STATUS) { /* bad response (error) */ - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - } else { /* this shouldn't happen */ - ssh_set_error(sftp->session, SSH_FATAL, - "Received message %d when attempting to set stats", msg->packet_type); - sftp_message_free(msg); - } - - return NULL; -} - -static sftp_attributes sftp_xstat(sftp_session sftp, const char *path, - int param) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_string pathstr; - ssh_buffer buffer; - uint32_t id; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(sftp->session); - return NULL; - } - - pathstr = ssh_string_from_char(path); - if (pathstr == NULL) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - - id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, pathstr) < 0) { - ssh_set_error_oom(sftp->session); - ssh_buffer_free(buffer); - ssh_string_free(pathstr); - return NULL; - } - if (sftp_packet_write(sftp, param, buffer) < 0) { - ssh_buffer_free(buffer); - ssh_string_free(pathstr); - return NULL; - } - ssh_buffer_free(buffer); - ssh_string_free(pathstr); - - while (msg == NULL) { - if (sftp_read_and_dispatch(sftp) < 0) { - return NULL; - } - msg = sftp_dequeue(sftp, id); - } - - if (msg->packet_type == SSH_FXP_ATTRS) { - sftp_attributes attr = sftp_parse_attr(sftp, msg->payload, 0); - sftp_message_free(msg); - - return attr; - } else if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - sftp_set_error(sftp, status->status); - ssh_set_error(sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - return NULL; - } - ssh_set_error(sftp->session, SSH_FATAL, - "Received mesg %d during stat()", msg->packet_type); - sftp_message_free(msg); - - return NULL; -} - -sftp_attributes sftp_stat(sftp_session session, const char *path) { - return sftp_xstat(session, path, SSH_FXP_STAT); -} - -sftp_attributes sftp_lstat(sftp_session session, const char *path) { - return sftp_xstat(session, path, SSH_FXP_LSTAT); -} - -sftp_attributes sftp_fstat(sftp_file file) { - sftp_status_message status = NULL; - sftp_message msg = NULL; - ssh_buffer buffer; - uint32_t id; - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - ssh_set_error_oom(file->sftp->session); - return NULL; - } - - id = sftp_get_new_id(file->sftp); - if (buffer_add_u32(buffer, htonl(id)) < 0 || - buffer_add_ssh_string(buffer, file->handle) < 0) { - ssh_set_error_oom(file->sftp->session); - ssh_buffer_free(buffer); - return NULL; - } - if (sftp_packet_write(file->sftp, SSH_FXP_FSTAT, buffer) < 0) { - ssh_buffer_free(buffer); - return NULL; - } - ssh_buffer_free(buffer); - - while (msg == NULL) { - if (sftp_read_and_dispatch(file->sftp) < 0) { - return NULL; - } - msg = sftp_dequeue(file->sftp, id); - } - - if (msg->packet_type == SSH_FXP_ATTRS){ - return sftp_parse_attr(file->sftp, msg->payload, 0); - } else if (msg->packet_type == SSH_FXP_STATUS) { - status = parse_status_msg(msg); - sftp_message_free(msg); - if (status == NULL) { - return NULL; - } - ssh_set_error(file->sftp->session, SSH_REQUEST_DENIED, - "SFTP server: %s", status->errormsg); - status_msg_free(status); - - return NULL; - } - ssh_set_error(file->sftp->session, SSH_FATAL, - "Received msg %d during fstat()", msg->packet_type); - sftp_message_free(msg); - - return NULL; -} - -#endif /* WITH_SFTP */ -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/sftpserver.c b/libssh/src/sftpserver.c deleted file mode 100644 index 60498794..00000000 --- a/libssh/src/sftpserver.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * sftpserver.c - server based function for the sftp protocol - * - * This file is part of the SSH Library - * - * Copyright (c) 2005 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/libssh.h" -#include "libssh/sftp.h" -#include "libssh/ssh2.h" -#include "libssh/priv.h" -#include "libssh/buffer.h" -#include "libssh/misc.h" - -sftp_client_message sftp_get_client_message(sftp_session sftp) { - ssh_session session = sftp->session; - sftp_packet packet; - sftp_client_message msg; - ssh_buffer payload; - int rc; - - msg = malloc(sizeof (struct sftp_client_message_struct)); - if (msg == NULL) { - ssh_set_error_oom(session); - return NULL; - } - ZERO_STRUCTP(msg); - - packet = sftp_packet_read(sftp); - if (packet == NULL) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - - payload = packet->payload; - msg->type = packet->type; - msg->sftp = sftp; - - /* take a copy of the whole packet */ - msg->complete_message = ssh_buffer_new(); - ssh_buffer_add_data(msg->complete_message, - buffer_get_rest(payload), - buffer_get_rest_len(payload)); - - buffer_get_u32(payload, &msg->id); - - switch(msg->type) { - case SSH_FXP_CLOSE: - case SSH_FXP_READDIR: - msg->handle = buffer_get_ssh_string(payload); - if (msg->handle == NULL) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_READ: - rc = ssh_buffer_unpack(payload, - "Sqd", - &msg->handle, - &msg->offset, - &msg->len); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_WRITE: - rc = ssh_buffer_unpack(payload, - "SqS", - &msg->handle, - &msg->offset, - &msg->data); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_REMOVE: - case SSH_FXP_RMDIR: - case SSH_FXP_OPENDIR: - case SSH_FXP_READLINK: - case SSH_FXP_REALPATH: - rc = ssh_buffer_unpack(payload, - "s", - &msg->filename); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_RENAME: - case SSH_FXP_SYMLINK: - rc = ssh_buffer_unpack(payload, - "sS", - &msg->filename, - &msg->data); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_MKDIR: - case SSH_FXP_SETSTAT: - rc = ssh_buffer_unpack(payload, - "s", - &msg->filename); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - msg->attr = sftp_parse_attr(sftp, payload, 0); - if (msg->attr == NULL) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_FSETSTAT: - msg->handle = buffer_get_ssh_string(payload); - if (msg->handle == NULL) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - msg->attr = sftp_parse_attr(sftp, payload, 0); - if (msg->attr == NULL) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_LSTAT: - case SSH_FXP_STAT: - rc = ssh_buffer_unpack(payload, - "s", - &msg->filename); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - if(sftp->version > 3) { - ssh_buffer_unpack(payload, "d", &msg->flags); - } - break; - case SSH_FXP_OPEN: - rc = ssh_buffer_unpack(payload, - "sd", - &msg->filename, - &msg->flags); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - msg->attr = sftp_parse_attr(sftp, payload, 0); - if (msg->attr == NULL) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - case SSH_FXP_FSTAT: - rc = ssh_buffer_unpack(payload, - "Sd", - &msg->handle, - &msg->flags); - if (rc != SSH_OK) { - ssh_set_error_oom(session); - sftp_client_message_free(msg); - return NULL; - } - break; - default: - ssh_set_error(sftp->session, SSH_FATAL, - "Received unhandled sftp message %d\n", msg->type); - sftp_client_message_free(msg); - return NULL; - } - - sftp_packet_free(packet); - - return msg; -} - -/* Send an sftp client message. Can be used in cas of proxying */ -int sftp_send_client_message(sftp_session sftp, sftp_client_message msg){ - return sftp_packet_write(sftp, msg->type, msg->complete_message); -} - -uint8_t sftp_client_message_get_type(sftp_client_message msg){ - return msg->type; -} - -const char *sftp_client_message_get_filename(sftp_client_message msg){ - return msg->filename; -} - -void sftp_client_message_set_filename(sftp_client_message msg, const char *newname){ - free(msg->filename); - msg->filename = strdup(newname); -} - -const char *sftp_client_message_get_data(sftp_client_message msg){ - if (msg->str_data == NULL) - msg->str_data = ssh_string_to_char(msg->data); - return msg->str_data; -} - -uint32_t sftp_client_message_get_flags(sftp_client_message msg){ - return msg->flags; -} - -void sftp_client_message_free(sftp_client_message msg) { - if (msg == NULL) { - return; - } - - SAFE_FREE(msg->filename); - ssh_string_free(msg->data); - ssh_string_free(msg->handle); - sftp_attributes_free(msg->attr); - ssh_buffer_free(msg->complete_message); - SAFE_FREE(msg->str_data); - ZERO_STRUCTP(msg); - SAFE_FREE(msg); -} - -int sftp_reply_name(sftp_client_message msg, const char *name, - sftp_attributes attr) { - ssh_buffer out; - ssh_string file; - - out = ssh_buffer_new(); - if (out == NULL) { - return -1; - } - - file = ssh_string_from_char(name); - if (file == NULL) { - ssh_buffer_free(out); - return -1; - } - - if (buffer_add_u32(out, msg->id) < 0 || - buffer_add_u32(out, htonl(1)) < 0 || - buffer_add_ssh_string(out, file) < 0 || - buffer_add_ssh_string(out, file) < 0 || /* The protocol is broken here between 3 & 4 */ - buffer_add_attributes(out, attr) < 0 || - sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) { - ssh_buffer_free(out); - ssh_string_free(file); - return -1; - } - ssh_buffer_free(out); - ssh_string_free(file); - - return 0; -} - -int sftp_reply_handle(sftp_client_message msg, ssh_string handle){ - ssh_buffer out; - - out = ssh_buffer_new(); - if (out == NULL) { - return -1; - } - - if (buffer_add_u32(out, msg->id) < 0 || - buffer_add_ssh_string(out, handle) < 0 || - sftp_packet_write(msg->sftp, SSH_FXP_HANDLE, out) < 0) { - ssh_buffer_free(out); - return -1; - } - ssh_buffer_free(out); - - return 0; -} - -int sftp_reply_attr(sftp_client_message msg, sftp_attributes attr) { - ssh_buffer out; - - out = ssh_buffer_new(); - if (out == NULL) { - return -1; - } - - if (buffer_add_u32(out, msg->id) < 0 || - buffer_add_attributes(out, attr) < 0 || - sftp_packet_write(msg->sftp, SSH_FXP_ATTRS, out) < 0) { - ssh_buffer_free(out); - return -1; - } - ssh_buffer_free(out); - - return 0; -} - -int sftp_reply_names_add(sftp_client_message msg, const char *file, - const char *longname, sftp_attributes attr) { - ssh_string name; - - name = ssh_string_from_char(file); - if (name == NULL) { - return -1; - } - - if (msg->attrbuf == NULL) { - msg->attrbuf = ssh_buffer_new(); - if (msg->attrbuf == NULL) { - ssh_string_free(name); - return -1; - } - } - - if (buffer_add_ssh_string(msg->attrbuf, name) < 0) { - ssh_string_free(name); - return -1; - } - - ssh_string_free(name); - name = ssh_string_from_char(longname); - if (name == NULL) { - return -1; - } - if (buffer_add_ssh_string(msg->attrbuf,name) < 0 || - buffer_add_attributes(msg->attrbuf,attr) < 0) { - ssh_string_free(name); - return -1; - } - ssh_string_free(name); - msg->attr_num++; - - return 0; -} - -int sftp_reply_names(sftp_client_message msg) { - ssh_buffer out; - - out = ssh_buffer_new(); - if (out == NULL) { - ssh_buffer_free(msg->attrbuf); - return -1; - } - - if (buffer_add_u32(out, msg->id) < 0 || - buffer_add_u32(out, htonl(msg->attr_num)) < 0 || - ssh_buffer_add_data(out, buffer_get_rest(msg->attrbuf), - buffer_get_rest_len(msg->attrbuf)) < 0 || - sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) { - ssh_buffer_free(out); - ssh_buffer_free(msg->attrbuf); - return -1; - } - - ssh_buffer_free(out); - ssh_buffer_free(msg->attrbuf); - - msg->attr_num = 0; - msg->attrbuf = NULL; - - return 0; -} - -int sftp_reply_status(sftp_client_message msg, uint32_t status, - const char *message) { - ssh_buffer out; - ssh_string s; - - out = ssh_buffer_new(); - if (out == NULL) { - return -1; - } - - s = ssh_string_from_char(message ? message : ""); - if (s == NULL) { - ssh_buffer_free(out); - return -1; - } - - if (buffer_add_u32(out, msg->id) < 0 || - buffer_add_u32(out, htonl(status)) < 0 || - buffer_add_ssh_string(out, s) < 0 || - buffer_add_u32(out, 0) < 0 || /* language string */ - sftp_packet_write(msg->sftp, SSH_FXP_STATUS, out) < 0) { - ssh_buffer_free(out); - ssh_string_free(s); - return -1; - } - - ssh_buffer_free(out); - ssh_string_free(s); - - return 0; -} - -int sftp_reply_data(sftp_client_message msg, const void *data, int len) { - ssh_buffer out; - - out = ssh_buffer_new(); - if (out == NULL) { - return -1; - } - - if (buffer_add_u32(out, msg->id) < 0 || - buffer_add_u32(out, ntohl(len)) < 0 || - ssh_buffer_add_data(out, data, len) < 0 || - sftp_packet_write(msg->sftp, SSH_FXP_DATA, out) < 0) { - ssh_buffer_free(out); - return -1; - } - ssh_buffer_free(out); - - return 0; -} - -/* - * This function will return you a new handle to give the client. - * the function accepts an info that can be retrieved later with - * the handle. Care is given that a corrupted handle won't give a - * valid info (or worse). - */ -ssh_string sftp_handle_alloc(sftp_session sftp, void *info) { - ssh_string ret; - uint32_t val; - int i; - - if (sftp->handles == NULL) { - sftp->handles = malloc(sizeof(void *) * SFTP_HANDLES); - if (sftp->handles == NULL) { - return NULL; - } - memset(sftp->handles, 0, sizeof(void *) * SFTP_HANDLES); - } - - for (i = 0; i < SFTP_HANDLES; i++) { - if (sftp->handles[i] == NULL) { - break; - } - } - - if (i == SFTP_HANDLES) { - return NULL; /* no handle available */ - } - - val = i; - ret = ssh_string_new(4); - if (ret == NULL) { - return NULL; - } - - memcpy(ssh_string_data(ret), &val, sizeof(uint32_t)); - sftp->handles[i] = info; - - return ret; -} - -void *sftp_handle(sftp_session sftp, ssh_string handle){ - uint32_t val; - - if (sftp->handles == NULL) { - return NULL; - } - - if (ssh_string_len(handle) != sizeof(uint32_t)) { - return NULL; - } - - memcpy(&val, ssh_string_data(handle), sizeof(uint32_t)); - - if (val > SFTP_HANDLES) { - return NULL; - } - - return sftp->handles[val]; -} - -void sftp_handle_remove(sftp_session sftp, void *handle) { - int i; - - for (i = 0; i < SFTP_HANDLES; i++) { - if (sftp->handles[i] == handle) { - sftp->handles[i] = NULL; - break; - } - } -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/src/socket.c b/libssh/src/socket.c deleted file mode 100644 index 498da77e..00000000 --- a/libssh/src/socket.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * socket.c - socket functions for the library - * - * This file is part of the SSH Library - * - * Copyright (c) 2008-2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#ifdef _WIN32 -#include -#include -#if _MSC_VER >= 1400 -#include -#undef open -#define open _open -#undef close -#define close _close -#undef read -#define read _read -#undef write -#define write _write -#endif /* _MSC_VER */ -#else /* _WIN32 */ -#include -#include -#include -#include -#endif /* _WIN32 */ - -#include "libssh/priv.h" -#include "libssh/callbacks.h" -#include "libssh/socket.h" -#include "libssh/buffer.h" -#include "libssh/poll.h" -#include "libssh/session.h" - -/** - * @internal - * - * @defgroup libssh_socket The SSH socket functions. - * @ingroup libssh - * - * Functions for handling sockets. - * - * @{ - */ - -enum ssh_socket_states_e { - SSH_SOCKET_NONE, - SSH_SOCKET_CONNECTING, - SSH_SOCKET_CONNECTED, - SSH_SOCKET_EOF, - SSH_SOCKET_ERROR, - SSH_SOCKET_CLOSED -}; - -struct ssh_socket_struct { - socket_t fd_in; - socket_t fd_out; - int fd_is_socket; - int last_errno; - int read_wontblock; /* reading now on socket will - not block */ - int write_wontblock; - int data_except; - enum ssh_socket_states_e state; - ssh_buffer out_buffer; - ssh_buffer in_buffer; - ssh_session session; - ssh_socket_callbacks callbacks; - ssh_poll_handle poll_in; - ssh_poll_handle poll_out; -}; - -static int sockets_initialized = 0; - -static int ssh_socket_unbuffered_read(ssh_socket s, void *buffer, uint32_t len); -static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer, - uint32_t len); - -/** - * \internal - * \brief inits the socket system (windows specific) - */ -int ssh_socket_init(void) { - if (sockets_initialized == 0) { -#ifdef _WIN32 - struct WSAData wsaData; - - /* Initiates use of the Winsock DLL by a process. */ - if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { - return -1; - } - -#endif - ssh_poll_init(); - - sockets_initialized = 1; - } - - return 0; -} - -/** - * @brief Cleanup the socket system. - */ -void ssh_socket_cleanup(void) { - if (sockets_initialized == 1) { - ssh_poll_cleanup(); -#ifdef _WIN32 - WSACleanup(); -#endif - sockets_initialized = 0; - } -} - - -/** - * \internal - * \brief creates a new Socket object - */ -ssh_socket ssh_socket_new(ssh_session session) { - ssh_socket s; - - s = malloc(sizeof(struct ssh_socket_struct)); - if (s == NULL) { - ssh_set_error_oom(session); - return NULL; - } - s->fd_in = SSH_INVALID_SOCKET; - s->fd_out= SSH_INVALID_SOCKET; - s->last_errno = -1; - s->fd_is_socket = 1; - s->session = session; - s->in_buffer = ssh_buffer_new(); - if (s->in_buffer == NULL) { - ssh_set_error_oom(session); - SAFE_FREE(s); - return NULL; - } - s->out_buffer=ssh_buffer_new(); - if (s->out_buffer == NULL) { - ssh_set_error_oom(session); - ssh_buffer_free(s->in_buffer); - SAFE_FREE(s); - return NULL; - } - s->read_wontblock = 0; - s->write_wontblock = 0; - s->data_except = 0; - s->poll_in=s->poll_out=NULL; - s->state=SSH_SOCKET_NONE; - return s; -} - -/** - * @internal - * @brief Reset the state of a socket so it looks brand-new - * @param[in] s socket to rest - */ -void ssh_socket_reset(ssh_socket s){ - s->fd_in = SSH_INVALID_SOCKET; - s->fd_out= SSH_INVALID_SOCKET; - s->last_errno = -1; - s->fd_is_socket = 1; - ssh_buffer_reinit(s->in_buffer); - ssh_buffer_reinit(s->out_buffer); - s->read_wontblock = 0; - s->write_wontblock = 0; - s->data_except = 0; - s->poll_in=s->poll_out=NULL; - s->state=SSH_SOCKET_NONE; -} - -/** - * @internal - * @brief the socket callbacks, i.e. callbacks to be called - * upon a socket event. - * @param s socket to set callbacks on. - * @param callbacks a ssh_socket_callback object reference. - */ - -void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks){ - s->callbacks=callbacks; -} - -/** - * @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, - * in this case the socket object. - * - * @return 0 on success, < 0 when the poll object has been removed - * from its poll context. - */ -int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, - int revents, void *v_s) { - ssh_socket s = (ssh_socket)v_s; - char buffer[MAX_BUF_SIZE]; - int r; - int err = 0; - socklen_t errlen = sizeof(err); - /* Do not do anything if this socket was already closed */ - if (!ssh_socket_is_open(s)) { - return -1; - } - if (revents & POLLERR || revents & POLLHUP) { - /* Check if we are in a connecting state */ - if (s->state == SSH_SOCKET_CONNECTING) { - s->state = SSH_SOCKET_ERROR; - r = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen); - if (r < 0) { - err = errno; - } - s->last_errno = err; - ssh_socket_close(s); - if (s->callbacks && s->callbacks->connected) { - s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR, err, - s->callbacks->userdata); - } - return -1; - } - /* Then we are in a more standard kind of error */ - /* force a read to get an explanation */ - revents |= POLLIN; - } - if ((revents & POLLIN) && s->state == SSH_SOCKET_CONNECTED) { - s->read_wontblock = 1; - r = ssh_socket_unbuffered_read(s, buffer, sizeof(buffer)); - if (r < 0) { - if (p != NULL) { - ssh_poll_remove_events(p, POLLIN); - } - if (s->callbacks && s->callbacks->exception) { - s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR, - s->last_errno, s->callbacks->userdata); - /* p may have been freed, so don't use it - * anymore in this function */ - p = NULL; - return -2; - } - } - if (r == 0) { - if (p != NULL) { - ssh_poll_remove_events(p, POLLIN); - } - if (p != NULL) { - ssh_poll_remove_events(p, POLLIN); - } - if (s->callbacks && s->callbacks->exception) { - s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF, - 0, s->callbacks->userdata); - /* p may have been freed, so don't use it - * anymore in this function */ - p = NULL; - return -2; - } - } - if (r > 0) { - if (s->session->socket_counter != NULL) { - s->session->socket_counter->in_bytes += r; - } - /* Bufferize the data and then call the callback */ - r = ssh_buffer_add_data(s->in_buffer, buffer, r); - if (r < 0) { - return -1; - } - if (s->callbacks && s->callbacks->data) { - do { - r = s->callbacks->data(buffer_get_rest(s->in_buffer), - buffer_get_rest_len(s->in_buffer), - s->callbacks->userdata); - buffer_pass_bytes(s->in_buffer, r); - } while ((r > 0) && (s->state == SSH_SOCKET_CONNECTED)); - /* p may have been freed, so don't use it - * anymore in this function */ - p = NULL; - } - } - } -#ifdef _WIN32 - if (revents & POLLOUT || revents & POLLWRNORM) { -#else - if (revents & POLLOUT) { -#endif - /* First, POLLOUT is a sign we may be connected */ - if (s->state == SSH_SOCKET_CONNECTING) { - SSH_LOG(SSH_LOG_PACKET, "Received POLLOUT in connecting state"); - s->state = SSH_SOCKET_CONNECTED; - if (p != NULL) { - ssh_poll_set_events(p, POLLOUT | POLLIN); - } - r = ssh_socket_set_blocking(ssh_socket_get_fd_in(s)); - if (r < 0) { - return -1; - } - if (s->callbacks && s->callbacks->connected) { - s->callbacks->connected(SSH_SOCKET_CONNECTED_OK, 0, - s->callbacks->userdata); - } - return 0; - } - /* So, we can write data */ - s->write_wontblock=1; - if (p != NULL) { - ssh_poll_remove_events(p, POLLOUT); - } - - /* If buffered data is pending, write it */ - if (buffer_get_rest_len(s->out_buffer) > 0) { - ssh_socket_nonblocking_flush(s); - } else if (s->callbacks && s->callbacks->controlflow) { - /* Otherwise advertise the upper level that write can be done */ - s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK, - s->callbacks->userdata); - } - /* TODO: Find a way to put back POLLOUT when buffering occurs */ - } - /* Return -1 if one of the poll handlers disappeared */ - return (s->poll_in == NULL || s->poll_out == NULL) ? -1 : 0; -} - -/** @internal - * @brief returns the input poll handle corresponding to the socket, - * creates it if it does not exist. - * @returns allocated and initialized ssh_poll_handle object - */ -ssh_poll_handle ssh_socket_get_poll_handle_in(ssh_socket s){ - if(s->poll_in) - return s->poll_in; - s->poll_in=ssh_poll_new(s->fd_in,0,ssh_socket_pollcallback,s); - if(s->fd_in == s->fd_out && s->poll_out == NULL) - s->poll_out=s->poll_in; - return s->poll_in; -} - -/** @internal - * @brief returns the output poll handle corresponding to the socket, - * creates it if it does not exist. - * @returns allocated and initialized ssh_poll_handle object - */ -ssh_poll_handle ssh_socket_get_poll_handle_out(ssh_socket s){ - if(s->poll_out) - return s->poll_out; - s->poll_out=ssh_poll_new(s->fd_out,0,ssh_socket_pollcallback,s); - if(s->fd_in == s->fd_out && s->poll_in == NULL) - s->poll_in=s->poll_out; - return s->poll_out; -} - -/** \internal - * \brief Deletes a socket object - */ -void ssh_socket_free(ssh_socket s){ - if (s == NULL) { - return; - } - ssh_socket_close(s); - ssh_buffer_free(s->in_buffer); - ssh_buffer_free(s->out_buffer); - SAFE_FREE(s); -} - -#ifndef _WIN32 -int ssh_socket_unix(ssh_socket s, const char *path) { - struct sockaddr_un sunaddr; - socket_t fd; - sunaddr.sun_family = AF_UNIX; - snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", path); - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == SSH_INVALID_SOCKET) { - ssh_set_error(s->session, SSH_FATAL, - "Error from socket(AF_UNIX, SOCK_STREAM, 0): %s", - strerror(errno)); - return -1; - } - - if (fcntl(fd, F_SETFD, 1) == -1) { - ssh_set_error(s->session, SSH_FATAL, - "Error from fcntl(fd, F_SETFD, 1): %s", - strerror(errno)); - close(fd); - return -1; - } - - if (connect(fd, (struct sockaddr *) &sunaddr, - sizeof(sunaddr)) < 0) { - ssh_set_error(s->session, SSH_FATAL, "Error from connect(): %s", - strerror(errno)); - close(fd); - return -1; - } - ssh_socket_set_fd(s,fd); - return 0; -} -#endif - -/** \internal - * \brief closes a socket - */ -void ssh_socket_close(ssh_socket s){ - if (ssh_socket_is_open(s)) { -#ifdef _WIN32 - closesocket(s->fd_in); - /* fd_in = fd_out under win32 */ - s->last_errno = WSAGetLastError(); -#else - close(s->fd_in); - if(s->fd_out != s->fd_in && s->fd_out != -1) - close(s->fd_out); - s->last_errno = errno; -#endif - s->fd_in = s->fd_out = SSH_INVALID_SOCKET; - } - if(s->poll_in != NULL){ - if(s->poll_out == s->poll_in) - s->poll_out = NULL; - ssh_poll_free(s->poll_in); - s->poll_in=NULL; - } - if(s->poll_out != NULL){ - ssh_poll_free(s->poll_out); - s->poll_out=NULL; - } - - s->state = SSH_SOCKET_CLOSED; -} - -/** - * @internal - * @brief sets the file descriptor of the socket. - * @param[out] s ssh_socket to update - * @param[in] fd file descriptor to set - * @warning this function updates boths the input and output - * file descriptors - */ -void ssh_socket_set_fd(ssh_socket s, socket_t fd) { - s->fd_in = s->fd_out = fd; - - if (s->poll_in) { - ssh_poll_set_fd(s->poll_in,fd); - } else { - s->state = SSH_SOCKET_CONNECTING; - - /* POLLOUT is the event to wait for in a nonblocking connect */ - ssh_poll_set_events(ssh_socket_get_poll_handle_in(s), POLLOUT); -#ifdef _WIN32 - ssh_poll_add_events(ssh_socket_get_poll_handle_in(s), POLLWRNORM); -#endif - } -} - -/** - * @internal - * @brief sets the input file descriptor of the socket. - * @param[out] s ssh_socket to update - * @param[in] fd file descriptor to set - */ -void ssh_socket_set_fd_in(ssh_socket s, socket_t fd) { - s->fd_in = fd; - if(s->poll_in) - ssh_poll_set_fd(s->poll_in,fd); -} - -/** - * @internal - * @brief sets the output file descriptor of the socket. - * @param[out] s ssh_socket to update - * @param[in] fd file descriptor to set - */ -void ssh_socket_set_fd_out(ssh_socket s, socket_t fd) { - s->fd_out = fd; - if(s->poll_out) - ssh_poll_set_fd(s->poll_out,fd); -} - - - -/** \internal - * \brief returns the input file descriptor of the socket - */ -socket_t ssh_socket_get_fd_in(ssh_socket s) { - return s->fd_in; -} - -/** \internal - * \brief returns nonzero if the socket is open - */ -int ssh_socket_is_open(ssh_socket s) { - return s->fd_in != SSH_INVALID_SOCKET; -} - -/** \internal - * \brief read len bytes from socket into buffer - */ -static int ssh_socket_unbuffered_read(ssh_socket s, void *buffer, uint32_t len) { - int rc = -1; - - if (s->data_except) { - return -1; - } - if(s->fd_is_socket) - rc = recv(s->fd_in,buffer, len, 0); - else - rc = read(s->fd_in,buffer, len); -#ifdef _WIN32 - s->last_errno = WSAGetLastError(); -#else - s->last_errno = errno; -#endif - s->read_wontblock = 0; - - if (rc < 0) { - s->data_except = 1; - } - - return rc; -} - -/** \internal - * \brief writes len bytes from buffer to socket - */ -static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer, - uint32_t len) { - int w = -1; - - if (s->data_except) { - return -1; - } - if (s->fd_is_socket) - w = send(s->fd_out,buffer, len, 0); - else - w = write(s->fd_out, buffer, len); -#ifdef _WIN32 - s->last_errno = WSAGetLastError(); -#else - s->last_errno = errno; -#endif - s->write_wontblock = 0; - /* Reactive the POLLOUT detector in the poll multiplexer system */ - if(s->poll_out){ - SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket"); - ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT); - } - if (w < 0) { - s->data_except = 1; - } - - return w; -} - -/** \internal - * \brief returns nonzero if the current socket is in the fd_set - */ -int ssh_socket_fd_isset(ssh_socket s, fd_set *set) { - if(s->fd_in == SSH_INVALID_SOCKET) { - return 0; - } - return FD_ISSET(s->fd_in,set) || FD_ISSET(s->fd_out,set); -} - -/** \internal - * \brief sets the current fd in a fd_set and updates the max_fd - */ - -void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd) { - if (s->fd_in == SSH_INVALID_SOCKET) { - return; - } - - FD_SET(s->fd_in,set); - FD_SET(s->fd_out,set); - - if (s->fd_in >= 0 && - s->fd_in >= *max_fd && - s->fd_in != SSH_INVALID_SOCKET) { - *max_fd = s->fd_in + 1; - } - if (s->fd_out >= 0 && - s->fd_out >= *max_fd && - s->fd_out != SSH_INVALID_SOCKET) { - *max_fd = s->fd_out + 1; - } -} - -/** \internal - * \brief buffered write of data - * \returns SSH_OK, or SSH_ERROR - * \warning has no effect on socket before a flush - */ -int ssh_socket_write(ssh_socket s, const void *buffer, int len) { - if(len > 0) { - if (ssh_buffer_add_data(s->out_buffer, buffer, len) < 0) { - ssh_set_error_oom(s->session); - return SSH_ERROR; - } - ssh_socket_nonblocking_flush(s); - } - - return SSH_OK; -} - - -/** \internal - * \brief starts a nonblocking flush of the output buffer - * - */ -int ssh_socket_nonblocking_flush(ssh_socket s) { - ssh_session session = s->session; - uint32_t len; - int w; - - if (!ssh_socket_is_open(s)) { - session->alive = 0; - /* FIXME use ssh_socket_get_errno */ - ssh_set_error(session, SSH_FATAL, - "Writing packet: error on socket (or connection closed): %s", - strerror(s->last_errno)); - - return SSH_ERROR; - } - - len = buffer_get_rest_len(s->out_buffer); - if (!s->write_wontblock && s->poll_out && len > 0) { - /* force the poll system to catch pollout events */ - ssh_poll_add_events(s->poll_out, POLLOUT); - - return SSH_AGAIN; - } - if (s->write_wontblock && len > 0) { - w = ssh_socket_unbuffered_write(s, buffer_get_rest(s->out_buffer), len); - if (w < 0) { - session->alive = 0; - ssh_socket_close(s); - /* FIXME use ssh_socket_get_errno() */ - /* FIXME use callback for errors */ - ssh_set_error(session, SSH_FATAL, - "Writing packet: error on socket (or connection closed): %s", - strerror(s->last_errno)); - - return SSH_ERROR; - } - buffer_pass_bytes(s->out_buffer, w); - if (s->session->socket_counter != NULL) { - s->session->socket_counter->out_bytes += w; - } - } - - /* Is there some data pending? */ - len = buffer_get_rest_len(s->out_buffer); - if (s->poll_out && len > 0) { - /* force the poll system to catch pollout events */ - ssh_poll_add_events(s->poll_out, POLLOUT); - - return SSH_AGAIN; - } - - /* all data written */ - return SSH_OK; -} - -void ssh_socket_set_write_wontblock(ssh_socket s) { - s->write_wontblock = 1; -} - -void ssh_socket_set_read_wontblock(ssh_socket s) { - s->read_wontblock = 1; -} - -void ssh_socket_set_except(ssh_socket s) { - s->data_except = 1; -} - -int ssh_socket_data_available(ssh_socket s) { - return s->read_wontblock; -} - -int ssh_socket_data_writable(ssh_socket s) { - return s->write_wontblock; -} - -/** @internal - * @brief returns the number of outgoing bytes currently buffered - * @param s the socket - * @returns numbers of bytes buffered, or 0 if the socket isn't connected - */ -int ssh_socket_buffered_write_bytes(ssh_socket s){ - if(s==NULL || s->out_buffer == NULL) - return 0; - return buffer_get_rest_len(s->out_buffer); -} - - -int ssh_socket_get_status(ssh_socket s) { - int r = 0; - - if (ssh_buffer_get_len(s->in_buffer) > 0) { - r |= SSH_READ_PENDING; - } - - if (ssh_buffer_get_len(s->out_buffer) > 0) { - r |= SSH_WRITE_PENDING; - } - - if (s->data_except) { - r |= SSH_CLOSED_ERROR; - } - - return r; -} - -int ssh_socket_get_poll_flags(ssh_socket s) { - int r = 0; - if (s->poll_in != NULL && (ssh_poll_get_events (s->poll_in) & POLLIN) > 0) { - r |= SSH_READ_PENDING; - } - if (s->poll_out != NULL && (ssh_poll_get_events (s->poll_out) & POLLOUT) > 0) { - r |= SSH_WRITE_PENDING; - } - return r; -} - -#ifdef _WIN32 -int ssh_socket_set_nonblocking(socket_t fd) { - u_long nonblocking = 1; - return ioctlsocket(fd, FIONBIO, &nonblocking); -} - -int ssh_socket_set_blocking(socket_t fd) { - u_long nonblocking = 0; - return ioctlsocket(fd, FIONBIO, &nonblocking); -} - -#else /* _WIN32 */ -int ssh_socket_set_nonblocking(socket_t fd) { - return fcntl(fd, F_SETFL, O_NONBLOCK); -} - -int ssh_socket_set_blocking(socket_t fd) { - return fcntl(fd, F_SETFL, 0); -} -#endif /* _WIN32 */ - -/** - * @internal - * @brief Launches a socket connection - * If a the socket connected callback has been defined and - * a poll object exists, this call will be non blocking. - * @param s socket to connect. - * @param host hostname or ip address to connect to. - * @param port port number to connect to. - * @param bind_addr address to bind to, or NULL for default. - * @returns SSH_OK socket is being connected. - * @returns SSH_ERROR error while connecting to remote host. - * @bug It only tries connecting to one of the available AI's - * which is problematic for hosts having DNS fail-over. - */ - -int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr){ - socket_t fd; - - if(s->state != SSH_SOCKET_NONE) { - ssh_set_error(s->session, SSH_FATAL, - "ssh_socket_connect called on socket not unconnected"); - return SSH_ERROR; - } - fd=ssh_connect_host_nonblocking(s->session,host,bind_addr,port); - SSH_LOG(SSH_LOG_PROTOCOL,"Nonblocking connection socket: %d",fd); - if(fd == SSH_INVALID_SOCKET) - return SSH_ERROR; - ssh_socket_set_fd(s,fd); - - return SSH_OK; -} - -#ifndef _WIN32 -/** - * @internal - * @brief executes a command and redirect input and outputs - * @param command command to execute - * @param in input file descriptor - * @param out output file descriptor - */ -void ssh_execute_command(const char *command, socket_t in, socket_t out){ - const char *args[]={"/bin/sh","-c",command,NULL}; - /* redirect in and out to stdin, stdout and stderr */ - dup2(in, 0); - dup2(out,1); - dup2(out,2); - close(in); - close(out); - execv(args[0],(char * const *)args); - exit(1); -} - -/** - * @internal - * @brief Open a socket on a ProxyCommand - * This call will always be nonblocking. - * @param s socket to connect. - * @param command Command to execute. - * @returns SSH_OK socket is being connected. - * @returns SSH_ERROR error while executing the command. - */ - -int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){ - socket_t in_pipe[2]; - socket_t out_pipe[2]; - int pid; - int rc; - - if(s->state != SSH_SOCKET_NONE) - return SSH_ERROR; - - rc = pipe(in_pipe); - if (rc < 0) { - return SSH_ERROR; - } - rc = pipe(out_pipe); - if (rc < 0) { - return SSH_ERROR; - } - - SSH_LOG(SSH_LOG_PROTOCOL,"Executing proxycommand '%s'",command); - pid = fork(); - if(pid == 0){ - ssh_execute_command(command,out_pipe[0],in_pipe[1]); - } - close(in_pipe[1]); - close(out_pipe[0]); - SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",in_pipe[0],out_pipe[1]); - ssh_socket_set_fd_in(s,in_pipe[0]); - ssh_socket_set_fd_out(s,out_pipe[1]); - s->state=SSH_SOCKET_CONNECTED; - s->fd_is_socket=0; - /* POLLOUT is the event to wait for in a nonblocking connect */ - ssh_poll_set_events(ssh_socket_get_poll_handle_in(s),POLLIN); - ssh_poll_set_events(ssh_socket_get_poll_handle_out(s),POLLOUT); - if(s->callbacks && s->callbacks->connected) - s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata); - - return SSH_OK; -} - -#endif /* _WIN32 */ -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/string.c b/libssh/src/string.c deleted file mode 100644 index 9002478f..00000000 --- a/libssh/src/string.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * string.c - ssh string functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2008 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/string.h" - -/** - * @defgroup libssh_string The SSH string functions - * @ingroup libssh - * - * @brief String manipulations used in libssh. - * - * @{ - */ - -/** - * @brief Create a new SSH String object. - * - * @param[in] size The size of the string. - * - * @return The newly allocated string, NULL on error. - */ -struct ssh_string_struct *ssh_string_new(size_t size) { - struct ssh_string_struct *str = NULL; - - if (size > UINT_MAX - sizeof(struct ssh_string_struct)) { - return NULL; - } - - str = malloc(sizeof(struct ssh_string_struct) + size); - if (str == NULL) { - return NULL; - } - - str->size = htonl(size); - str->data[0] = 0; - - return str; -} - -/** - * @brief Fill a string with given data. The string should be big enough. - * - * @param s An allocated string to fill with data. - * - * @param data The data to fill the string with. - * - * @param len Size of data. - * - * @return 0 on success, < 0 on error. - */ -int ssh_string_fill(struct ssh_string_struct *s, const void *data, size_t len) { - if ((s == NULL) || (data == NULL) || - (len == 0) || (len > ssh_string_len(s))) { - return -1; - } - - memcpy(s->data, data, len); - - return 0; -} - -/** - * @brief Create a ssh string using a C string - * - * @param[in] what The source 0-terminated C string. - * - * @return The newly allocated string, NULL on error with errno - * set. - * - * @note The nul byte is not copied nor counted in the ouput string. - */ -struct ssh_string_struct *ssh_string_from_char(const char *what) { - struct ssh_string_struct *ptr; - size_t len; - - if(what == NULL) { - errno = EINVAL; - return NULL; - } - - len = strlen(what); - - ptr = ssh_string_new(len); - if (ptr == NULL) { - return NULL; - } - - memcpy(ptr->data, what, len); - - return ptr; -} - -/** - * @brief Return the size of a SSH string. - * - * @param[in] s The the input SSH string. - * - * @return The size of the content of the string, 0 on error. - */ -size_t ssh_string_len(struct ssh_string_struct *s) { - if (s == NULL) { - return ntohl(0); - } - - return ntohl(s->size); -} - -/** - * @brief Get the the string as a C nul-terminated string. - * - * This is only available as long as the SSH string exists. - * - * @param[in] s The SSH string to get the C string from. - * - * @return The char pointer, NULL on error. - */ -const char *ssh_string_get_char(struct ssh_string_struct *s) -{ - if (s == NULL) { - return NULL; - } - s->data[ssh_string_len(s)] = '\0'; - - return (const char *) s->data; -} - -/** - * @brief Convert a SSH string to a C nul-terminated string. - * - * @param[in] s The SSH input string. - * - * @return An allocated string pointer, NULL on error with errno - * set. - * - * @note If the input SSH string contains zeroes, some parts of the output - * string may not be readable with regular libc functions. - */ -char *ssh_string_to_char(struct ssh_string_struct *s) { - size_t len; - char *new; - - if (s == NULL) { - return NULL; - } - - len = ssh_string_len(s); - if (len + 1 < len) { - return NULL; - } - - new = malloc(len + 1); - if (new == NULL) { - return NULL; - } - memcpy(new, s->data, len); - new[len] = '\0'; - - return new; -} - -/** - * @brief Deallocate a char string object. - * - * @param[in] s The string to delete. - */ -void ssh_string_free_char(char *s) { - SAFE_FREE(s); -} - -/** - * @brief Copy a string, return a newly allocated string. The caller has to - * free the string. - * - * @param[in] s String to copy. - * - * @return Newly allocated copy of the string, NULL on error. - */ -struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) { - struct ssh_string_struct *new; - size_t len; - - if (s == NULL) { - return NULL; - } - - len = ssh_string_len(s); - if (len == 0) { - return NULL; - } - - new = ssh_string_new(len); - if (new == NULL) { - return NULL; - } - - memcpy(new->data, s->data, len); - - return new; -} - -/** - * @brief Destroy the data in a string so it couldn't appear in a core dump. - * - * @param[in] s The string to burn. - */ -void ssh_string_burn(struct ssh_string_struct *s) { - if (s == NULL || s->size == 0) { - return; - } - - BURN_BUFFER(s->data, ssh_string_len(s)); -} - -/** - * @brief Get the payload of the string. - * - * @param s The string to get the data from. - * - * @return Return the data of the string or NULL on error. - */ -void *ssh_string_data(struct ssh_string_struct *s) { - if (s == NULL) { - return NULL; - } - - return s->data; -} - -/** - * @brief Deallocate a SSH string object. - * - * \param[in] s The SSH string to delete. - */ -void ssh_string_free(struct ssh_string_struct *s) { - SAFE_FREE(s); -} - -/** @} */ - -/* vim: set ts=4 sw=4 et cindent: */ diff --git a/libssh/src/threads.c b/libssh/src/threads.c deleted file mode 100644 index 7f3a304e..00000000 --- a/libssh/src/threads.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/** - * @defgroup libssh_threads The SSH threading functions. - * @ingroup libssh - * - * Threading with libssh - * @{ - */ - -#include "config.h" - -#include "libssh/priv.h" -#include "libssh/crypto.h" -#include "libssh/threads.h" - -static int threads_noop (void **lock){ - (void)lock; - return 0; -} - -static unsigned long threads_id_noop (void){ - return 1; -} - -static struct ssh_threads_callbacks_struct ssh_threads_noop = -{ - "threads_noop", - threads_noop, - threads_noop, - threads_noop, - threads_noop, - threads_id_noop -}; - -struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void) { - return &ssh_threads_noop; -} - -static struct ssh_threads_callbacks_struct *user_callbacks =&ssh_threads_noop; - -#ifdef HAVE_LIBGCRYPT -#if (GCRYPT_VERSION_NUMBER >= 0x010600) -/* libgcrypt >= 1.6 does not support custom callbacks */ -GCRY_THREAD_OPTION_PTHREAD_IMPL; - -static int libgcrypt_thread_init(void){ - if(user_callbacks == NULL) - return SSH_ERROR; - if(user_callbacks == &ssh_threads_noop) - return SSH_OK; - if (strcmp(user_callbacks->type, "threads_pthread") == 0){ - gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); - return SSH_OK; - } else { - /* not supported */ - SSH_LOG(SSH_LOG_WARN, "Custom thread handlers not supported with libgcrypt >=1.6, using pthreads"); - gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); - return SSH_OK; - } -} - -#else -/* Libgcrypt < 1.6 specific way of handling thread callbacks */ - -static struct gcry_thread_cbs gcrypt_threads_callbacks; - -static int libgcrypt_thread_init(void){ - if(user_callbacks == NULL) - return SSH_ERROR; - if(user_callbacks == &ssh_threads_noop){ - gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_DEFAULT; - } else { - gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_USER; - } - gcrypt_threads_callbacks.mutex_init=user_callbacks->mutex_init; - gcrypt_threads_callbacks.mutex_destroy=user_callbacks->mutex_destroy; - gcrypt_threads_callbacks.mutex_lock=user_callbacks->mutex_lock; - gcrypt_threads_callbacks.mutex_unlock=user_callbacks->mutex_unlock; - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks); - return SSH_OK; -} -#endif /* GCRYPT_VERSION_NUMBER */ -#else /* HAVE_LIBGCRYPT */ - -/* Libcrypto specific stuff */ - -static void **libcrypto_mutexes; - -static void libcrypto_lock_callback(int mode, int i, const char *file, int line){ - (void)file; - (void)line; - if(mode & CRYPTO_LOCK){ - user_callbacks->mutex_lock(&libcrypto_mutexes[i]); - } else { - user_callbacks->mutex_unlock(&libcrypto_mutexes[i]); - } -} - -static int libcrypto_thread_init(void){ - int n=CRYPTO_num_locks(); - int i; - if(user_callbacks == &ssh_threads_noop) - return SSH_OK; - libcrypto_mutexes=malloc(sizeof(void *) * n); - if (libcrypto_mutexes == NULL) - return SSH_ERROR; - for (i=0;imutex_init(&libcrypto_mutexes[i]); - } - CRYPTO_set_id_callback(user_callbacks->thread_id); - CRYPTO_set_locking_callback(libcrypto_lock_callback); - - return SSH_OK; -} - -static void libcrypto_thread_finalize(void){ - int n=CRYPTO_num_locks(); - int i; - if (libcrypto_mutexes==NULL) - return; - for (i=0;imutex_destroy(&libcrypto_mutexes[i]); - } - SAFE_FREE(libcrypto_mutexes); - -} - -#endif - -/** @internal - * @brief inits the threading with the backend cryptographic libraries - */ - -int ssh_threads_init(void){ - static int threads_initialized=0; - int ret; - if(threads_initialized) - return SSH_OK; - /* first initialize the user_callbacks with our default handlers if not - * already the case - */ - if(user_callbacks == NULL){ - user_callbacks=&ssh_threads_noop; - } - - /* Then initialize the crypto libraries threading callbacks */ -#ifdef HAVE_LIBGCRYPT - ret = libgcrypt_thread_init(); -#else /* Libcrypto */ - ret = libcrypto_thread_init(); -#endif - if(ret == SSH_OK) - threads_initialized=1; - return ret; -} - -void ssh_threads_finalize(void){ -#ifdef HAVE_LIBGCRYPT -#else - libcrypto_thread_finalize(); -#endif -} - -int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct *cb){ - user_callbacks=cb; - return SSH_OK; -} - -const char *ssh_threads_get_type(void) { - if(user_callbacks != NULL) - return user_callbacks->type; - return NULL; -} - -/** - * @} - */ diff --git a/libssh/src/threads/CMakeLists.txt b/libssh/src/threads/CMakeLists.txt deleted file mode 100644 index a32d601e..00000000 --- a/libssh/src/threads/CMakeLists.txt +++ /dev/null @@ -1,127 +0,0 @@ -project(libssh-threads C) - -set(LIBSSH_THREADS_PUBLIC_INCLUDE_DIRS - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR} - CACHE INTERNAL "libssh public include directories" -) - -set(LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS - ${CMAKE_BINARY_DIR} -) - -set(LIBSSH_THREADS_SHARED_LIBRARY - ssh_threads_shared - CACHE INTERNAL "libssh threads shared library" -) - -if (WITH_STATIC_LIB) - set(LIBSSH_THREADS_STATIC_LIBRARY - ssh_threads_static - CACHE INTERNAL "libssh threads static library" - ) -endif (WITH_STATIC_LIB) - -set(LIBSSH_THREADS_LINK_LIBRARIES - ${LIBSSH_SHARED_LIBRARY} -) - -set(libssh_threads_SRCS -) - -# build and link pthread -if (CMAKE_USE_PTHREADS_INIT) - set(libssh_threads_SRCS - ${libssh_threads_SRCS} - pthread.c - ) - - set(LIBSSH_THREADS_LINK_LIBRARIES - ${LIBSSH_THREADS_LINK_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ) -endif (CMAKE_USE_PTHREADS_INIT) - -set(LIBSSH_THREADS_LINK_LIBRARIES - ${LIBSSH_THREADS_LINK_LIBRARIES} - CACHE INTERNAL "libssh threads link libraries" -) - -include_directories( - ${LIBSSH_THREADS_PUBLIC_INCLUDE_DIRS} - ${LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS} -) - -if (libssh_threads_SRCS) - add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${libssh_threads_SRCS}) - - target_link_libraries(${LIBSSH_THREADS_SHARED_LIBRARY} ${LIBSSH_THREADS_LINK_LIBRARIES}) - - set_target_properties( - ${LIBSSH_THREADS_SHARED_LIBRARY} - PROPERTIES - VERSION - ${LIBRARY_VERSION} - SOVERSION - ${LIBRARY_SOVERSION} - OUTPUT_NAME - ssh_threads - DEFINE_SYMBOL - LIBSSH_EXPORTS - ) - - if (WITH_VISIBILITY_HIDDEN) - set_target_properties(${LIBSSH_THREADS_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") - endif (WITH_VISIBILITY_HIDDEN) - - install( - TARGETS - ${LIBSSH_THREADS_SHARED_LIBRARY} - RUNTIME DESTINATION ${BIN_INSTALL_DIR} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} - COMPONENT libraries - ) - - if (WITH_STATIC_LIB) - add_library(${LIBSSH_THREADS_STATIC_LIBRARY} STATIC ${libssh_threads_SRCS}) - - if (MSVC) - set(OUTPUT_SUFFIX static) - else (MSVC) - set(OUTPUT_SUFFIX ) - endif (MSVC) - - set_target_properties( - ${LIBSSH_THREADS_STATIC_LIBRARY} - PROPERTIES - VERSION - ${LIBRARY_VERSION} - SOVERSION - ${LIBRARY_SOVERSION} - OUTPUT_NAME - ssh_threads - ARCHIVE_OUTPUT_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX} - ) - - if (WIN32) - set_target_properties( - ${LIBSSH_THREADS_STATIC_LIBRARY} - PROPERTIES - COMPILE_FLAGS - "-DLIBSSH_STATIC" - ) - endif (WIN32) - - install( - TARGETS - ${LIBSSH_THREADS_STATIC_LIBRARY} - DESTINATION - ${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX} - COMPONENT - libraries - ) - endif (WITH_STATIC_LIB) -endif (libssh_threads_SRCS) diff --git a/libssh/src/threads/pthread.c b/libssh/src/threads/pthread.c deleted file mode 100644 index 829fa5c6..00000000 --- a/libssh/src/threads/pthread.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include - -#ifdef HAVE_PTHREAD - -#include -#include -#include - -/** @brief Defines the needed callbacks for pthread. Use this if your - * OS supports libpthread and want to use it for threading. - * @code - * #include - * #include - * #include - * SSH_THREADS_PTHREAD(ssh_pthread_callbacks); - * int main(){ - * ssh_init_set_threads_callbacks(&ssh_pthread_callbacks); - * ssh_init(); - * ... - * } - * @endcode - * @param name name of the structure to be declared, containing the - * callbacks for threading - * - */ - -static int ssh_pthread_mutex_init (void **priv){ - int err = 0; - *priv = malloc (sizeof (pthread_mutex_t)); - if (*priv==NULL) - return ENOMEM; - err = pthread_mutex_init (*priv, NULL); - if (err != 0){ - free (*priv); - *priv=NULL; - } - return err; -} - -static int ssh_pthread_mutex_destroy (void **lock) { - int err = pthread_mutex_destroy (*lock); - free (*lock); - *lock=NULL; - return err; -} - -static int ssh_pthread_mutex_lock (void **lock) { - return pthread_mutex_lock (*lock); -} - -static int ssh_pthread_mutex_unlock (void **lock){ - return pthread_mutex_unlock (*lock); -} - -static unsigned long ssh_pthread_thread_id (void){ -#if _WIN32 - return (unsigned long) pthread_self().p; -#else - return (unsigned long) pthread_self(); -#endif -} - -static struct ssh_threads_callbacks_struct ssh_threads_pthread = -{ - .type="threads_pthread", - .mutex_init=ssh_pthread_mutex_init, - .mutex_destroy=ssh_pthread_mutex_destroy, - .mutex_lock=ssh_pthread_mutex_lock, - .mutex_unlock=ssh_pthread_mutex_unlock, - .thread_id=ssh_pthread_thread_id -}; - -struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void) { - return &ssh_threads_pthread; -} - -#endif /* HAVE_PTHREAD */ diff --git a/libssh/src/wrapper.c b/libssh/src/wrapper.c deleted file mode 100644 index bcd941b3..00000000 --- a/libssh/src/wrapper.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * wrapper.c - wrapper for crytpo functions - * - * This file is part of the SSH Library - * - * Copyright (c) 2003-2013 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* - * Why a wrapper? - * - * Let's say you want to port libssh from libcrypto of openssl to libfoo - * you are going to spend hours to remove every references to SHA1_Update() - * to libfoo_sha1_update after the work is finished, you're going to have - * only this file to modify it's not needed to say that your modifications - * are welcome. - */ - -#include "config.h" - - -#include -#include -#include - -#ifdef WITH_ZLIB -#include -#endif - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/crypto.h" -#include "libssh/wrapper.h" -#include "libssh/pki.h" - -static struct ssh_hmac_struct ssh_hmac_tab[] = { - { "hmac-sha1", SSH_HMAC_SHA1 }, - { "hmac-sha2-256", SSH_HMAC_SHA256 }, - { "hmac-sha2-384", SSH_HMAC_SHA384 }, - { "hmac-sha2-512", SSH_HMAC_SHA512 }, - { "hmac-md5", SSH_HMAC_MD5 }, - { NULL, 0} -}; - -struct ssh_hmac_struct *ssh_get_hmactab(void) { - return ssh_hmac_tab; -} - -size_t hmac_digest_len(enum ssh_hmac_e type) { - switch(type) { - case SSH_HMAC_SHA1: - return SHA_DIGEST_LEN; - case SSH_HMAC_SHA256: - return SHA256_DIGEST_LEN; - case SSH_HMAC_SHA384: - return SHA384_DIGEST_LEN; - case SSH_HMAC_SHA512: - return SHA512_DIGEST_LEN; - case SSH_HMAC_MD5: - return MD5_DIGEST_LEN; - default: - return 0; - } -} - -const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type) -{ - int i = 0; - struct ssh_hmac_struct *ssh_hmactab = ssh_get_hmactab(); - while (ssh_hmactab[i].name && (ssh_hmactab[i].hmac_type != hmac_type)) { - i++; - } - return ssh_hmactab[i].name; -} - -/* it allocates a new cipher structure based on its offset into the global table */ -static struct ssh_cipher_struct *cipher_new(int offset) { - struct ssh_cipher_struct *cipher = NULL; - - cipher = malloc(sizeof(struct ssh_cipher_struct)); - if (cipher == NULL) { - return NULL; - } - - /* note the memcpy will copy the pointers : so, you shouldn't free them */ - memcpy(cipher, &ssh_get_ciphertab()[offset], sizeof(*cipher)); - - return cipher; -} - -static void cipher_free(struct ssh_cipher_struct *cipher) { -#ifdef HAVE_LIBGCRYPT - unsigned int i; -#endif - - if (cipher == NULL) { - return; - } - - if(cipher->key) { -#ifdef HAVE_LIBGCRYPT - for (i = 0; i < (cipher->keylen / sizeof(gcry_cipher_hd_t)); i++) { - gcry_cipher_close(cipher->key[i]); - } -#elif defined HAVE_LIBCRYPTO - /* destroy the key */ - memset(cipher->key, 0, cipher->keylen); -#endif - SAFE_FREE(cipher->key); - } - SAFE_FREE(cipher); -} - -struct ssh_crypto_struct *crypto_new(void) { - struct ssh_crypto_struct *crypto; - - crypto = malloc(sizeof(struct ssh_crypto_struct)); - if (crypto == NULL) { - return NULL; - } - ZERO_STRUCTP(crypto); - return crypto; -} - -void crypto_free(struct ssh_crypto_struct *crypto){ - int i; - if (crypto == NULL) { - return; - } - - SAFE_FREE(crypto->server_pubkey); - - cipher_free(crypto->in_cipher); - cipher_free(crypto->out_cipher); - - bignum_free(crypto->e); - bignum_free(crypto->f); - bignum_free(crypto->x); - bignum_free(crypto->y); - bignum_free(crypto->k); -#ifdef HAVE_ECDH - SAFE_FREE(crypto->ecdh_client_pubkey); - SAFE_FREE(crypto->ecdh_server_pubkey); -#endif - if(crypto->session_id != NULL){ - memset(crypto->session_id, '\0', crypto->digest_len); - SAFE_FREE(crypto->session_id); - } - if(crypto->secret_hash != NULL){ - memset(crypto->secret_hash, '\0', crypto->digest_len); - SAFE_FREE(crypto->secret_hash); - } -#ifdef WITH_ZLIB - if (crypto->compress_out_ctx && - (deflateEnd(crypto->compress_out_ctx) != 0)) { - inflateEnd(crypto->compress_out_ctx); - } - SAFE_FREE(crypto->compress_out_ctx); - - if (crypto->compress_in_ctx && - (deflateEnd(crypto->compress_in_ctx) != 0)) { - inflateEnd(crypto->compress_in_ctx); - } - SAFE_FREE(crypto->compress_in_ctx); -#endif /* WITH_ZLIB */ - if(crypto->encryptIV) - SAFE_FREE(crypto->encryptIV); - if(crypto->decryptIV) - SAFE_FREE(crypto->decryptIV); - if(crypto->encryptMAC) - SAFE_FREE(crypto->encryptMAC); - if(crypto->decryptMAC) - SAFE_FREE(crypto->decryptMAC); - if(crypto->encryptkey){ - memset(crypto->encryptkey, 0, crypto->digest_len); - SAFE_FREE(crypto->encryptkey); - } - if(crypto->decryptkey){ - memset(crypto->decryptkey, 0, crypto->digest_len); - SAFE_FREE(crypto->decryptkey); - } - - for (i = 0; i < SSH_KEX_METHODS; i++) { - SAFE_FREE(crypto->client_kex.methods[i]); - SAFE_FREE(crypto->server_kex.methods[i]); - SAFE_FREE(crypto->kex_methods[i]); - } - - BURN_BUFFER(crypto, sizeof(struct ssh_crypto_struct)); - - SAFE_FREE(crypto); -} - -static int crypt_set_algorithms2(ssh_session session){ - const char *wanted; - int i = 0; - struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab(); - struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab(); - - /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */ - /* out */ - wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S]; - while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) { - i++; - } - - if (ssh_ciphertab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, - "crypt_set_algorithms2: no crypto algorithm function found for %s", - wanted); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET, "Set output algorithm to %s", wanted); - - session->next_crypto->out_cipher = cipher_new(i); - if (session->next_crypto->out_cipher == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - i = 0; - - /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */ - /* out */ - wanted = session->next_crypto->kex_methods[SSH_MAC_C_S]; - while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) { - i++; - } - - if (ssh_hmactab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, - "crypt_set_algorithms2: no hmac algorithm function found for %s", - wanted); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted); - - session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type; - i = 0; - - /* in */ - wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C]; - while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) { - i++; - } - - if (ssh_ciphertab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, - "Crypt_set_algorithms: no crypto algorithm function found for %s", - wanted); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET, "Set input algorithm to %s", wanted); - - session->next_crypto->in_cipher = cipher_new(i); - if (session->next_crypto->in_cipher == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - i = 0; - - /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */ - wanted = session->next_crypto->kex_methods[SSH_MAC_S_C]; - while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) { - i++; - } - - if (ssh_hmactab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, - "crypt_set_algorithms2: no hmac algorithm function found for %s", - wanted); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted); - - session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type; - i = 0; - - /* compression */ - if (strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib") == 0) { - session->next_crypto->do_compress_out = 1; - } - if (strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib") == 0) { - session->next_crypto->do_compress_in = 1; - } - if (strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib@openssh.com") == 0) { - session->next_crypto->delayed_compress_out = 1; - } - if (strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib@openssh.com") == 0) { - session->next_crypto->delayed_compress_in = 1; - } - - return SSH_OK; -} - -static int crypt_set_algorithms1(ssh_session session, enum ssh_des_e des_type) { - int i = 0; - struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab(); - - /* right now, we force 3des-cbc to be taken */ - while (ssh_ciphertab[i].name && strcmp(ssh_ciphertab[i].name, - des_type == SSH_DES ? "des-cbc-ssh1" : "3des-cbc-ssh1")) { - i++; - } - - if (ssh_ciphertab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, "cipher 3des-cbc-ssh1 or des-cbc-ssh1 not found!"); - return SSH_ERROR; - } - - session->next_crypto->out_cipher = cipher_new(i); - if (session->next_crypto->out_cipher == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - - session->next_crypto->in_cipher = cipher_new(i); - if (session->next_crypto->in_cipher == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - - return SSH_OK; -} - -int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type) { - return (session->version == 1) ? crypt_set_algorithms1(session, des_type) : - crypt_set_algorithms2(session); -} - -#ifdef WITH_SERVER -int crypt_set_algorithms_server(ssh_session session){ - char *method = NULL; - int i = 0; - struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab(); - struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab(); - - if (session == NULL) { - return SSH_ERROR; - } - - /* - * We must scan the kex entries to find crypto algorithms and set their - * appropriate structure - */ - /* out */ - method = session->next_crypto->kex_methods[SSH_CRYPT_S_C]; - while(ssh_ciphertab[i].name && strcmp(method,ssh_ciphertab[i].name)) - i++; - if(!ssh_ciphertab[i].name){ - ssh_set_error(session,SSH_FATAL,"crypt_set_algorithms_server : " - "no crypto algorithm function found for %s",method); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET,"Set output algorithm %s",method); - - session->next_crypto->out_cipher = cipher_new(i); - if (session->next_crypto->out_cipher == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - i=0; - /* in */ - method = session->next_crypto->kex_methods[SSH_CRYPT_C_S]; - while(ssh_ciphertab[i].name && strcmp(method,ssh_ciphertab[i].name)) - i++; - if(!ssh_ciphertab[i].name){ - ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server :" - "no crypto algorithm function found for %s",method); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET,"Set input algorithm %s",method); - - session->next_crypto->in_cipher = cipher_new(i); - if (session->next_crypto->in_cipher == NULL) { - ssh_set_error_oom(session); - return SSH_ERROR; - } - i=0; - - /* HMAC algorithm selection */ - method = session->next_crypto->kex_methods[SSH_MAC_S_C]; - while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) { - i++; - } - - if (ssh_hmactab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, - "crypt_set_algorithms_server: no hmac algorithm function found for %s", - method); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", method); - - session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type; - i=0; - - method = session->next_crypto->kex_methods[SSH_MAC_C_S]; - while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) { - i++; - } - - if (ssh_hmactab[i].name == NULL) { - ssh_set_error(session, SSH_FATAL, - "crypt_set_algorithms_server: no hmac algorithm function found for %s", - method); - return SSH_ERROR; - } - SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", method); - - session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type; - i=0; - - /* compression */ - method = session->next_crypto->kex_methods[SSH_COMP_C_S]; - if(strcmp(method,"zlib") == 0){ - SSH_LOG(SSH_LOG_PACKET,"enabling C->S compression"); - session->next_crypto->do_compress_in=1; - } - if(strcmp(method,"zlib@openssh.com") == 0){ - SSH_LOG(SSH_LOG_PACKET,"enabling C->S delayed compression"); - - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) { - session->next_crypto->do_compress_in = 1; - } else { - session->next_crypto->delayed_compress_in = 1; - } - } - - method = session->next_crypto->kex_methods[SSH_COMP_S_C]; - if(strcmp(method,"zlib") == 0){ - SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression\n"); - session->next_crypto->do_compress_out=1; - } - if(strcmp(method,"zlib@openssh.com") == 0){ - SSH_LOG(SSH_LOG_PACKET,"enabling S->C delayed compression\n"); - - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) { - session->next_crypto->do_compress_out = 1; - } else { - session->next_crypto->delayed_compress_out = 1; - } - } - - method = session->next_crypto->kex_methods[SSH_HOSTKEYS]; - session->srv.hostkey = ssh_key_type_from_name(method); - - return SSH_OK; -} - -#endif /* WITH_SERVER */ -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/libssh/tests/CMakeLists.txt b/libssh/tests/CMakeLists.txt deleted file mode 100644 index 7cdb2c48..00000000 --- a/libssh/tests/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -project(tests C) - -if (BSD OR SOLARIS OR OSX) - find_package(Argp) -endif (BSD OR SOLARIS OR OSX) - -set(TORTURE_LIBRARY torture) - -include_directories( - ${LIBSSH_PUBLIC_INCLUDE_DIRS} - ${CMOCKA_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIRS} - ${GCRYPT_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_CURRENT_SOURCE_DIR} -) - -# create test library -add_library(${TORTURE_LIBRARY} STATIC cmdline.c torture.c) -target_link_libraries(${TORTURE_LIBRARY} - ${CMOCKA_LIBRARY} - ${LIBSSH_STATIC_LIBRARY} - ${LIBSSH_LINK_LIBRARIES} - ${LIBSSH_THREADS_STATIC_LIBRARY} - ${LIBSSH_THREADS_LINK_LIBRARIES} - ${ARGP_LIBRARIES} -) - -set(TEST_TARGET_LIBRARIES - ${TORTURE_LIBRARY} - ${CMOCKA_LIBRARY} - ${LIBSSH_STATIC_LIBRARY} - ${LIBSSH_LINK_LIBRARIES} - ${LIBSSH_THREADS_STATIC_LIBRARY} - ${LIBSSH_THREADS_LINK_LIBRARIES} -) - -add_subdirectory(unittests) - -if (WITH_CLIENT_TESTING) - add_subdirectory(client) -endif (WITH_CLIENT_TESTING) - -if (WITH_BENCHMARKS) - add_subdirectory(benchmarks) -endif (WITH_BENCHMARKS) - -if (WITH_SERVER) - add_subdirectory(pkd) -endif (WITH_SERVER) diff --git a/libssh/tests/authentication.c b/libssh/tests/authentication.c deleted file mode 100644 index 248b646f..00000000 --- a/libssh/tests/authentication.c +++ /dev/null @@ -1,74 +0,0 @@ -/* -This file is distributed in public domain. You can do whatever you want -with its content. -*/ - - -#include -#include -#include -#include - -#include - -#include "tests.h" -static int auth_kbdint(SSH_SESSION *session){ - int err=ssh_userauth_kbdint(session,NULL,NULL); - char *name,*instruction,*prompt,*ptr; - char buffer[128]; - int i,n; - char echo; - while (err==SSH_AUTH_INFO){ - name=ssh_userauth_kbdint_getname(session); - instruction=ssh_userauth_kbdint_getinstruction(session); - n=ssh_userauth_kbdint_getnprompts(session); - if(strlen(name)>0) - printf("%s\n",name); - if(strlen(instruction)>0) - printf("%s\n",instruction); - for(i=0;i&1`" -echo "Ping latency to $DEST": -ping -q -c 1 -n $DEST -echo "Destination $DEST SSHD vesion : `echo | nc $DEST 22 | head -n1`" -echo "ssh login latency :`(time -f user:%U ssh $DEST 'id > /dev/null') 2>&1`" -./generate.py | dd bs=4096 count=100000 | time ssh -c $CIPHER $DEST "dd bs=4096 of=/dev/null" 2>&1 - diff --git a/libssh/tests/benchmarks/bench2.sh b/libssh/tests/benchmarks/bench2.sh deleted file mode 100755 index 01d67777..00000000 --- a/libssh/tests/benchmarks/bench2.sh +++ /dev/null @@ -1,13 +0,0 @@ -export CIPHER=aes128-cbc -export DEST=localhost - -echo "Upload raw SSH statistics" -echo "local machine: `uname -a`" -echo "Cipher : $CIPHER ; Destination : $DEST (`ssh $DEST uname -a`)" -echo "Local ssh version: `samplessh -V 2>&1`" -echo "Ping latency to $DEST": -ping -q -c 1 -n $DEST -echo "Destination $DEST SSHD vesion : `echo | nc $DEST 22 | head -n1`" -echo "ssh login latency :`(time -f user:%U samplessh $DEST 'id > /dev/null') 2>&1`" -./generate.py | dd bs=4096 count=100000 | strace samplessh -c $CIPHER $DEST "dd bs=4096 of=/dev/null" 2>&1 - diff --git a/libssh/tests/benchmarks/bench_raw.c b/libssh/tests/benchmarks/bench_raw.c deleted file mode 100644 index db1a057c..00000000 --- a/libssh/tests/benchmarks/bench_raw.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "benchmarks.h" -#include -#include -#include - -#define PYTHON_PATH "/usr/bin/python" - -const char python_eater[]= -"#!/usr/bin/python\n" -"import sys\n" -"print 'go'\n" -"sys.stdout.flush()\n" -"toread=XXXXXXXXXX\n" -"read=0\n" -"while(read < toread):\n" -" buffersize=toread-read\n" -" if(buffersize > 4096):\n" -" buffersize=4096\n" -" r=len(sys.stdin.read(buffersize))\n" -" read+=r\n" -" if(r<=0):\n" -" print 'error'\n" -" exit()\n" -"print 'done'\n"; - -static char *get_python_eater(unsigned long bytes){ - char *eater=malloc(sizeof(python_eater)); - char *ptr; - char buf[12]; - - memcpy(eater,python_eater,sizeof(python_eater)); - ptr=strstr(eater,"XXXXXXXXXX"); - if(!ptr){ - free(eater); - return NULL; - } - sprintf(buf,"0x%.8lx",bytes); - memcpy(ptr,buf,10); - return eater; -} - -/** @internal - * @brief uploads a script (python or other) at a specific path on the - * remote host - * @param[in] session an active SSH session - * @param[in] path to copy the file - * @param[in] content of the file to copy - * @return 0 on success, -1 on error - */ -static int upload_script(ssh_session session, const char *path, - const char *script){ - ssh_channel channel; - char cmd[128]; - int err; - - channel=ssh_channel_new(session); - if(!channel) - goto error; - if(ssh_channel_open_session(channel) == SSH_ERROR) - goto error; - snprintf(cmd,sizeof(cmd),"cat > %s",path); - if(ssh_channel_request_exec(channel,cmd) == SSH_ERROR) - goto error; - err=ssh_channel_write(channel,script,strlen(script)); - if(err == SSH_ERROR) - goto error; - if(ssh_channel_send_eof(channel) == SSH_ERROR) - goto error; - if(ssh_channel_close(channel) == SSH_ERROR) - goto error; - ssh_channel_free(channel); - return 0; -error: - fprintf(stderr,"Error while copying script : %s\n",ssh_get_error(session)); - return -1; -} - -/** @internal - * @brief benchmarks a raw upload (simple upload in a SSH channel) using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_raw_up (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - char *script; - char cmd[128]; - int err; - ssh_channel channel; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - - bytes = args->datasize * 1024 * 1024; - script =get_python_eater(bytes); - err=upload_script(session,"/tmp/eater.py",script); - free(script); - if(err<0) - return err; - channel=ssh_channel_new(session); - if(channel == NULL) - goto error; - if(ssh_channel_open_session(channel)==SSH_ERROR) - goto error; - snprintf(cmd,sizeof(cmd),"%s /tmp/eater.py", PYTHON_PATH); - if(ssh_channel_request_exec(channel,cmd)==SSH_ERROR) - goto error; - if((err=ssh_channel_read(channel,buffer,sizeof(buffer)-1,0))==SSH_ERROR) - goto error; - buffer[err]=0; - if(!strstr(buffer,"go")){ - fprintf(stderr,"parse error : %s\n",buffer); - ssh_channel_close(channel); - ssh_channel_free(channel); - return -1; - } - if(args->verbose>0) - fprintf(stdout,"Starting upload of %lu bytes now\n",bytes); - timestamp_init(&ts); - while(total < bytes){ - unsigned long towrite = bytes - total; - int w; - if(towrite > args->chunksize) - towrite = args->chunksize; - w=ssh_channel_write(channel,buffer,towrite); - if(w == SSH_ERROR) - goto error; - total += w; - } - - if(args->verbose>0) - fprintf(stdout,"Finished upload, now waiting the ack\n"); - - if((err=ssh_channel_read(channel,buffer,5,0))==SSH_ERROR) - goto error; - buffer[err]=0; - if(!strstr(buffer,"done")){ - fprintf(stderr,"parse error : %s\n",buffer); - ssh_channel_close(channel); - ssh_channel_free(channel); - return -1; - } - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"Upload took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - ssh_channel_close(channel); - ssh_channel_free(channel); - return 0; -error: - fprintf(stderr,"Error during raw upload : %s\n",ssh_get_error(session)); - if(channel){ - ssh_channel_close(channel); - ssh_channel_free(channel); - } - return -1; -} - -const char python_giver[] = -"#!/usr/bin/python\n" -"import sys\n" -"r=sys.stdin.read(2)\n" -"towrite=XXXXXXXXXX\n" -"wrote=0\n" -"mtu = 32786\n" -"buf = 'A'*mtu\n" -"while(wrote < towrite):\n" -" buffersize=towrite-wrote\n" -" if(buffersize > mtu):\n" -" buffersize=mtu\n" -" if(buffersize == mtu):\n" -" sys.stdout.write(buf)\n" -" else:\n" -" sys.stdout.write('A'*buffersize)\n" -" wrote+=buffersize\n" -"sys.stdout.flush()\n"; - -static char *get_python_giver(unsigned long bytes){ - char *giver=malloc(sizeof(python_giver)); - char *ptr; - char buf[12]; - - memcpy(giver,python_giver,sizeof(python_giver)); - ptr=strstr(giver,"XXXXXXXXXX"); - if(!ptr){ - free(giver); - return NULL; - } - sprintf(buf,"0x%.8lx",bytes); - memcpy(ptr,buf,10); - return giver; -} - -/** @internal - * @brief benchmarks a raw download (simple upload in a SSH channel) using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_raw_down (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - char *script; - char cmd[128]; - int err; - ssh_channel channel; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - - bytes = args->datasize * 1024 * 1024; - script =get_python_giver(bytes); - err=upload_script(session,"/tmp/giver.py",script); - free(script); - if(err<0) - return err; - channel=ssh_channel_new(session); - if(channel == NULL) - goto error; - if(ssh_channel_open_session(channel)==SSH_ERROR) - goto error; - snprintf(cmd,sizeof(cmd),"%s /tmp/giver.py", PYTHON_PATH); - if(ssh_channel_request_exec(channel,cmd)==SSH_ERROR) - goto error; - if((err=ssh_channel_write(channel,"go",2))==SSH_ERROR) - goto error; - if(args->verbose>0) - fprintf(stdout,"Starting download of %lu bytes now\n",bytes); - timestamp_init(&ts); - while(total < bytes){ - unsigned long toread = bytes - total; - int r; - if(toread > args->chunksize) - toread = args->chunksize; - r=ssh_channel_read(channel,buffer,toread,0); - if(r == SSH_ERROR) - goto error; - total += r; - } - - if(args->verbose>0) - fprintf(stdout,"Finished download\n"); - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"Download took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - ssh_channel_close(channel); - ssh_channel_free(channel); - return 0; -error: - fprintf(stderr,"Error during raw upload : %s\n",ssh_get_error(session)); - if(channel){ - ssh_channel_close(channel); - ssh_channel_free(channel); - } - return -1; -} diff --git a/libssh/tests/benchmarks/bench_scp.c b/libssh/tests/benchmarks/bench_scp.c deleted file mode 100644 index 340637ba..00000000 --- a/libssh/tests/benchmarks/bench_scp.c +++ /dev/null @@ -1,150 +0,0 @@ -/* bench_scp.c - * - * This file is part of the SSH Library - * - * Copyright (c) 2011 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "benchmarks.h" -#include -#include - -#define SCPDIR "/tmp/" -#define SCPFILE "scpbenchmark" - -/** @internal - * @brief benchmarks a scp upload using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_scp_up (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - ssh_scp scp; - - bytes = args->datasize * 1024 * 1024; - scp = ssh_scp_new(session,SSH_SCP_WRITE,SCPDIR); - if(scp == NULL) - goto error; - if(ssh_scp_init(scp)==SSH_ERROR) - goto error; - if(ssh_scp_push_file(scp,SCPFILE,bytes,0777) != SSH_OK) - goto error; - if(args->verbose>0) - fprintf(stdout,"Starting upload of %lu bytes now\n",bytes); - timestamp_init(&ts); - while(total < bytes){ - unsigned long towrite = bytes - total; - int w; - if(towrite > args->chunksize) - towrite = args->chunksize; - w=ssh_scp_write(scp,buffer,towrite); - if(w == SSH_ERROR) - goto error; - total += towrite; - } - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"Upload took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - ssh_scp_close(scp); - ssh_scp_free(scp); - return 0; -error: - fprintf(stderr,"Error during scp upload : %s\n",ssh_get_error(session)); - if(scp){ - ssh_scp_close(scp); - ssh_scp_free(scp); - } - return -1; -} - -/** @internal - * @brief benchmarks a scp download using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_scp_down (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - ssh_scp scp; - int r; - size_t size; - - bytes = args->datasize * 1024 * 1024; - scp = ssh_scp_new(session,SSH_SCP_READ,SCPDIR SCPFILE); - if(scp == NULL) - goto error; - if(ssh_scp_init(scp)==SSH_ERROR) - goto error; - r=ssh_scp_pull_request(scp); - if(r == SSH_SCP_REQUEST_NEWFILE){ - size=ssh_scp_request_get_size(scp); - if(bytes > size){ - printf("Only %d bytes available (on %lu requested).\n",size,bytes); - bytes = size; - } - if(size > bytes){ - printf("File is %d bytes (on %lu requested). Will cut the end\n",size,bytes); - } - if(args->verbose>0) - fprintf(stdout,"Starting download of %lu bytes now\n",bytes); - timestamp_init(&ts); - ssh_scp_accept_request(scp); - while(total < bytes){ - unsigned long toread = bytes - total; - if(toread > args->chunksize) - toread = args->chunksize; - r=ssh_scp_read(scp,buffer,toread); - if(r == SSH_ERROR || r == 0) - goto error; - total += r; - } - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"download took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - } else { - fprintf(stderr,"Expected SSH_SCP_REQUEST_NEWFILE, got %d\n",r); - goto error; - } - ssh_scp_close(scp); - ssh_scp_free(scp); - return 0; -error: - fprintf(stderr,"Error during scp download : %s\n",ssh_get_error(session)); - if(scp){ - ssh_scp_close(scp); - ssh_scp_free(scp); - } - return -1; -} diff --git a/libssh/tests/benchmarks/bench_sftp.c b/libssh/tests/benchmarks/bench_sftp.c deleted file mode 100644 index 9e4ab34d..00000000 --- a/libssh/tests/benchmarks/bench_sftp.c +++ /dev/null @@ -1,239 +0,0 @@ -/* bench_sftp.c - * - * This file is part of the SSH Library - * - * Copyright (c) 2011 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "benchmarks.h" -#include -#include -#include -#include -#include - -#define SFTPDIR "/tmp/" -#define SFTPFILE "scpbenchmark" - -/** @internal - * @brief benchmarks a synchronous sftp upload using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_sync_sftp_up (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - sftp_session sftp; - sftp_file file; - - bytes = args->datasize * 1024 * 1024; - sftp = sftp_new(session); - if(sftp == NULL) - goto error; - if(sftp_init(sftp)==SSH_ERROR) - goto error; - file = sftp_open(sftp,SFTPDIR SFTPFILE,O_RDWR | O_CREAT | O_TRUNC, 0777); - if(!file) - goto error; - if(args->verbose>0) - fprintf(stdout,"Starting upload of %lu bytes now\n",bytes); - timestamp_init(&ts); - while(total < bytes){ - unsigned long towrite = bytes - total; - int w; - if(towrite > args->chunksize) - towrite = args->chunksize; - w=sftp_write(file,buffer,towrite); - if(w == SSH_ERROR) - goto error; - total += w; - } - sftp_close(file); - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"Upload took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - sftp_free(sftp); - return 0; -error: - fprintf(stderr,"Error during scp upload : %s\n",ssh_get_error(session)); - if(file) - sftp_close(file); - if(sftp) - sftp_free(sftp); - return -1; -} - -/** @internal - * @brief benchmarks a synchronous sftp download using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_sync_sftp_down (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - sftp_session sftp; - sftp_file file; - int r; - - bytes = args->datasize * 1024 * 1024; - sftp = sftp_new(session); - if(sftp == NULL) - goto error; - if(sftp_init(sftp)==SSH_ERROR) - goto error; - file = sftp_open(sftp,SFTPDIR SFTPFILE,O_RDONLY,0); - if(!file) - goto error; - if(args->verbose>0) - fprintf(stdout,"Starting download of %lu bytes now\n",bytes); - timestamp_init(&ts); - while(total < bytes){ - unsigned long toread = bytes - total; - if(toread > args->chunksize) - toread = args->chunksize; - r=sftp_read(file,buffer,toread); - if(r == SSH_ERROR) - goto error; - total += r; - /* we had a smaller file */ - if(r==0){ - fprintf(stdout,"File smaller than expected : %lu (expected %lu).\n",total,bytes); - bytes = total; - break; - } - } - sftp_close(file); - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"download took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - sftp_free(sftp); - return 0; -error: - fprintf(stderr,"Error during sftp download : %s\n",ssh_get_error(session)); - if(file) - sftp_close(file); - if(sftp) - sftp_free(sftp); - return -1; -} - -/** @internal - * @brief benchmarks an asynchronous sftp download using an - * existing SSH session. - * @param[in] session Open SSH session - * @param[in] args Parsed command line arguments - * @param[out] bps The calculated bytes per second obtained via benchmark. - * @return 0 on success, -1 on error. - */ -int benchmarks_async_sftp_down (ssh_session session, struct argument_s *args, - float *bps){ - unsigned long bytes; - struct timestamp_struct ts; - float ms=0.0; - unsigned long total=0; - sftp_session sftp; - sftp_file file; - int r,i; - int warned = 0; - unsigned long toread; - int *ids=NULL; - int concurrent_downloads = args->concurrent_requests; - - bytes = args->datasize * 1024 * 1024; - sftp = sftp_new(session); - if(sftp == NULL) - goto error; - if(sftp_init(sftp)==SSH_ERROR) - goto error; - file = sftp_open(sftp,SFTPDIR SFTPFILE,O_RDONLY,0); - if(!file) - goto error; - ids = malloc(concurrent_downloads * sizeof(int)); - if(args->verbose>0) - fprintf(stdout,"Starting download of %lu bytes now, using %d concurrent downloads\n",bytes, - concurrent_downloads); - timestamp_init(&ts); - for (i=0;ichunksize); - if(ids[i]==SSH_ERROR) - goto error; - } - i=0; - while(total < bytes){ - r = sftp_async_read(file, buffer, args->chunksize, ids[i]); - if(r == SSH_ERROR) - goto error; - total += r; - if(r != (int)args->chunksize && total != bytes && !warned){ - fprintf(stderr,"async_sftp_download : receiving short reads (%d, requested %d) " - "the received file will be corrupted and shorted. Adapt chunksize to %d\n", - r, args->chunksize,r); - warned = 1; - } - /* we had a smaller file */ - if(r==0){ - fprintf(stdout,"File smaller than expected : %lu (expected %lu).\n",total,bytes); - bytes = total; - break; - } - toread = bytes - total; - if(toread < args->chunksize * concurrent_downloads){ - /* we've got enough launched downloads */ - ids[i]=-1; - } - if(toread > args->chunksize) - toread = args->chunksize; - ids[i]=sftp_async_read_begin(file,toread); - if(ids[i] == SSH_ERROR) - goto error; - i = (i+1) % concurrent_downloads; - } - sftp_close(file); - ms=elapsed_time(&ts); - *bps=8000 * (float)bytes / ms; - if(args->verbose > 0) - fprintf(stdout,"download took %f ms for %lu bytes, at %f bps\n",ms, - bytes,*bps); - sftp_free(sftp); - free(ids); - return 0; -error: - fprintf(stderr,"Error during sftp download : %s\n",ssh_get_error(session)); - if(file) - sftp_close(file); - if(sftp) - sftp_free(sftp); - free(ids); - return -1; -} diff --git a/libssh/tests/benchmarks/benchmarks.c b/libssh/tests/benchmarks/benchmarks.c deleted file mode 100644 index 5e33dd4b..00000000 --- a/libssh/tests/benchmarks/benchmarks.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include "benchmarks.h" -#include - -#include -#include -#include - -struct benchmark benchmarks[]= { - { - .name="benchmark_raw_upload", - .fct=benchmarks_raw_up, - .enabled=0 - }, - { - .name="benchmark_raw_download", - .fct=benchmarks_raw_down, - .enabled=0 - }, - { - .name="benchmark_scp_upload", - .fct=benchmarks_scp_up, - .enabled=0 - }, - { - .name="benchmark_scp_download", - .fct=benchmarks_scp_down, - .enabled=0 - }, - { - .name="benchmark_sync_sftp_upload", - .fct=benchmarks_sync_sftp_up, - .enabled=0 - }, - { - .name="benchmark_sync_sftp_download", - .fct=benchmarks_sync_sftp_down, - .enabled=0 - }, - { - .name="benchmark_async_sftp_download", - .fct=benchmarks_async_sftp_down, - .enabled=0 - } -}; - -#ifdef HAVE_ARGP_H -#include - -const char *argp_program_version = "libssh benchmarks 2011-08-28"; -const char *argp_program_bug_address = "Aris Adamantiadis "; - -static char **cmdline; - -/* Program documentation. */ -static char doc[] = "libssh benchmarks"; - - -/* The options we understand. */ -static struct argp_option options[] = { - { - .name = "verbose", - .key = 'v', - .arg = NULL, - .flags = 0, - .doc = "Make libssh benchmark more verbose", - .group = 0 - }, - { - .name = "raw-upload", - .key = '1', - .arg = NULL, - .flags = 0, - .doc = "Upload raw data using channel", - .group = 0 - }, - { - .name = "raw-download", - .key = '2', - .arg = NULL, - .flags = 0, - .doc = "Download raw data using channel", - .group = 0 - }, - { - .name = "scp-upload", - .key = '3', - .arg = NULL, - .flags = 0, - .doc = "Upload data using SCP", - .group = 0 - }, - { - .name = "scp-download", - .key = '4', - .arg = NULL, - .flags = 0, - .doc = "Download data using SCP", - .group = 0 - }, - { - .name = "sync-sftp-upload", - .key = '5', - .arg = NULL, - .flags = 0, - .doc = "Upload data using synchronous SFTP", - .group = 0 - - }, - { - .name = "sync-sftp-download", - .key = '6', - .arg = NULL, - .flags = 0, - .doc = "Download data using synchronous SFTP (slow)", - .group = 0 - - }, - { - .name = "async-sftp-download", - .key = '7', - .arg = NULL, - .flags = 0, - .doc = "Download data using asynchronous SFTP (fast)", - .group = 0 - - }, - { - .name = "host", - .key = 'h', - .arg = "HOST", - .flags = 0, - .doc = "Add a host to connect for benchmark (format user@hostname)", - .group = 0 - }, - { - .name = "size", - .key = 's', - .arg = "MBYTES", - .flags = 0, - .doc = "MBytes of data to send/receive per test", - .group = 0 - }, - { - .name = "chunk", - .key = 'c', - .arg = "bytes", - .flags = 0, - .doc = "size of data chunks to send/receive", - .group = 0 - }, - { - .name = "prequests", - .key = 'p', - .arg = "number [20]", - .flags = 0, - .doc = "[async SFTP] number of concurrent requests", - .group = 0 - }, - { - .name = "cipher", - .key = 'C', - .arg = "cipher", - .flags = 0, - .doc = "Cryptographic cipher to be used", - .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. - */ - struct argument_s *arguments = state->input; - - /* arg is currently not used */ - (void) arg; - - switch (key) { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - benchmarks[key - '1'].enabled = 1; - arguments->ntests ++; - break; - case 'v': - arguments->verbose++; - break; - case 's': - arguments->datasize = atoi(arg); - break; - case 'p': - arguments->concurrent_requests = atoi(arg); - break; - case 'c': - arguments->chunksize = atoi(arg); - break; - case 'C': - arguments->cipher = arg; - break; - case 'h': - if(arguments->nhosts >= MAX_HOSTS_CONNECT){ - fprintf(stderr, "Too much hosts\n"); - return ARGP_ERR_UNKNOWN; - } - arguments->hosts[arguments->nhosts]=arg; - arguments->nhosts++; - break; - case ARGP_KEY_ARG: - /* End processing here. */ - cmdline = &state->argv [state->next - 1]; - state->next = state->argc; - break; - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -/* Our argp parser. */ -static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL}; - -#endif /* HAVE_ARGP_H */ - -static void cmdline_parse(int argc, char **argv, struct argument_s *arguments) { - /* - * Parse our arguments; every option seen by parse_opt will - * be reflected in arguments. - */ -#ifdef HAVE_ARGP_H - argp_parse(&argp, argc, argv, 0, 0, arguments); -#else /* HAVE_ARGP_H */ - (void) argc; - (void) argv; - arguments->hosts[0]="localhost"; - arguments->nhosts=1; -#endif /* HAVE_ARGP_H */ -} - -static void arguments_init(struct argument_s *arguments){ - memset(arguments,0,sizeof(*arguments)); - arguments->chunksize=32758; - arguments->concurrent_requests=20; - arguments->datasize = 10; -} - -static ssh_session connect_host(const char *host, int verbose, char *cipher){ - ssh_session session=ssh_new(); - if(session==NULL) - goto error; - if(ssh_options_set(session,SSH_OPTIONS_HOST, host)<0) - goto error; - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbose); - if(cipher != NULL){ - if (ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, cipher) || - ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, cipher)){ - goto error; - } - } - ssh_options_parse_config(session, NULL); - if(ssh_connect(session)==SSH_ERROR) - goto error; - if(ssh_userauth_autopubkey(session,NULL) != SSH_AUTH_SUCCESS) - goto error; - return session; -error: - fprintf(stderr,"Error connecting to \"%s\": %s\n",host,ssh_get_error(session)); - ssh_free(session); - return NULL; -} - -static char *network_speed(float bps){ - static char buf[128]; - if(bps > 1000*1000*1000){ - /* Gbps */ - snprintf(buf,sizeof(buf),"%f Gbps",bps/(1000*1000*1000)); - } else if(bps > 1000*1000){ - /* Mbps */ - snprintf(buf,sizeof(buf),"%f Mbps",bps/(1000*1000)); - } else if(bps > 1000){ - snprintf(buf,sizeof(buf),"%f Kbps",bps/1000); - } else { - snprintf(buf,sizeof(buf),"%f bps",bps); - } - return buf; -} - -static void do_benchmarks(ssh_session session, struct argument_s *arguments, - const char *hostname){ - float ping_rtt=0.0; - float ssh_rtt=0.0; - float bps=0.0; - int i; - int err; - struct benchmark *b; - - if(arguments->verbose>0) - fprintf(stdout,"Testing ICMP RTT\n"); - err=benchmarks_ping_latency(hostname, &ping_rtt); - if(err == 0){ - fprintf(stdout,"ping RTT : %f ms\n",ping_rtt); - } - err=benchmarks_ssh_latency(session, &ssh_rtt); - if(err==0){ - fprintf(stdout, "SSH RTT : %f ms. Theoretical max BW (win=128K) : %s\n",ssh_rtt,network_speed(128000.0/(ssh_rtt / 1000.0))); - } - for (i=0 ; ienabled){ - err=b->fct(session,arguments,&bps); - if(err==0){ - fprintf(stdout, "%s : %s : %s\n",hostname, b->name, network_speed(bps)); - } - } - } -} - -char *buffer; - -int main(int argc, char **argv){ - struct argument_s arguments; - ssh_session session; - int i; - - arguments_init(&arguments); - cmdline_parse(argc, argv, &arguments); - if (arguments.nhosts==0){ - fprintf(stderr,"At least one host (-h) must be specified\n"); - return EXIT_FAILURE; - } - if (arguments.ntests==0){ - for(i=0; i < BENCHMARK_NUMBER ; ++i){ - benchmarks[i].enabled=1; - } - arguments.ntests=BENCHMARK_NUMBER; - } - buffer=malloc(arguments.chunksize > 1024 ? arguments.chunksize : 1024); - if(buffer == NULL){ - fprintf(stderr,"Allocation of chunk buffer failed\n"); - return EXIT_FAILURE; - } - if (arguments.verbose > 0){ - fprintf(stdout, "Will try hosts "); - for(i=0;i 0) - fprintf(stdout,"Connecting to \"%s\"...\n",arguments.hosts[i]); - session=connect_host(arguments.hosts[i], arguments.verbose, arguments.cipher); - if(session != NULL && arguments.verbose > 0) - fprintf(stdout,"Success\n"); - if(session == NULL){ - fprintf(stderr,"Errors occurred, stopping\n"); - return EXIT_FAILURE; - } - do_benchmarks(session, &arguments, arguments.hosts[i]); - ssh_disconnect(session); - ssh_free(session); - } - return EXIT_SUCCESS; -} - diff --git a/libssh/tests/benchmarks/benchmarks.h b/libssh/tests/benchmarks/benchmarks.h deleted file mode 100644 index 26da09bb..00000000 --- a/libssh/tests/benchmarks/benchmarks.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef BENCHMARKS_H_ -#define BENCHMARKS_H_ - -#include - -/* benchmarks.c */ - -/* maximum number of parallel hosts that may be checked */ -#define MAX_HOSTS_CONNECT 20 - -enum libssh_benchmarks { - BENCHMARK_RAW_UPLOAD=0, - BENCHMARK_RAW_DOWNLOAD, - BENCHMARK_SCP_UPLOAD, - BENCHMARK_SCP_DOWNLOAD, - BENCHMARK_SYNC_SFTP_UPLOAD, - BENCHMARK_SYNC_SFTP_DOWNLOAD, - BENCHMARK_ASYNC_SFTP_DOWNLOAD, - BENCHMARK_NUMBER -}; - -struct argument_s { - const char *hosts[MAX_HOSTS_CONNECT]; - int verbose; - int nhosts; - int ntests; - unsigned int datasize; - unsigned int chunksize; - int concurrent_requests; - char *cipher; -}; - -extern char *buffer; - -typedef int (*bench_fct)(ssh_session session, struct argument_s *args, - float *bps); - -struct benchmark { - const char *name; - bench_fct fct; - int enabled; -}; - -/* latency.c */ - -struct timestamp_struct { - struct timeval timestamp; -}; - -int benchmarks_ping_latency (const char *host, float *average); -int benchmarks_ssh_latency (ssh_session session, float *average); - -void timestamp_init(struct timestamp_struct *ts); -float elapsed_time(struct timestamp_struct *ts); - -/* bench_raw.c */ - -int benchmarks_raw_up (ssh_session session, struct argument_s *args, - float *bps); -int benchmarks_raw_down (ssh_session session, struct argument_s *args, - float *bps); - -/* bench_scp.c */ - -int benchmarks_scp_up (ssh_session session, struct argument_s *args, - float *bps); -int benchmarks_scp_down (ssh_session session, struct argument_s *args, - float *bps); - -/* bench_sftp.c */ - -int benchmarks_sync_sftp_up (ssh_session session, struct argument_s *args, - float *bps); -int benchmarks_sync_sftp_down (ssh_session session, struct argument_s *args, - float *bps); -int benchmarks_async_sftp_down (ssh_session session, struct argument_s *args, - float *bps); -#endif /* BENCHMARKS_H_ */ diff --git a/libssh/tests/benchmarks/latency.c b/libssh/tests/benchmarks/latency.c deleted file mode 100644 index 09c50a04..00000000 --- a/libssh/tests/benchmarks/latency.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "benchmarks.h" -#include - -#include -#include -#include -#include -#include - -#define PING_PROGRAM "/bin/ping" - -/** @internal - * @brief Calculates the RTT of the host with ICMP ping, and returns the - * average of the calculated RTT. - * @param[in] host hostname to ping. - * @param[out] average average RTT in milliseconds. - * @returns 0 on success, -1 if there is an error. - * @warning relies on an external ping program which may not exist on - * certain OS. - */ -int benchmarks_ping_latency (const char *host, float *average){ - const char *ptr; - char cmd[256]; - char line[1024]; - FILE *fd; - int found=0; - - /* strip out the hostname */ - ptr=strchr(host,'@'); - if(ptr) - ptr++; - else - ptr=host; - - snprintf(cmd,sizeof(cmd),"%s -n -q -c3 %s",PING_PROGRAM, ptr); - fd=popen(cmd,"r"); - if(fd==NULL){ - fprintf(stderr,"Error executing command : %s\n", strerror(errno)); - return -1; - } - - while(!found && fgets(line,sizeof(line),fd)!=NULL){ - if(strstr(line,"rtt")){ - ptr=strchr(line,'='); - if(ptr==NULL) - goto parseerror; - ptr=strchr(ptr,'/'); - if(ptr==NULL) - goto parseerror; - *average=strtof(ptr+1,NULL); - found=1; - break; - } - } - if(!found) - goto parseerror; - pclose(fd); - return 0; - -parseerror: - fprintf(stderr,"Parse error : couldn't locate average in %s",line); - pclose(fd); - return -1; -} - -/** @internal - * @brief initialize a timestamp to the current time. - * @param[out] ts A timestamp_struct pointer. - */ -void timestamp_init(struct timestamp_struct *ts){ - gettimeofday(&ts->timestamp,NULL); -} - -/** @internal - * @brief return the elapsed time since now and the moment ts was initialized. - * @param[in] ts An initialized timestamp_struct pointer. - * @return Elapsed time in milliseconds. - */ -float elapsed_time(struct timestamp_struct *ts){ - struct timeval now; - time_t secdiff; - long usecdiff; /* may be negative */ - - gettimeofday(&now,NULL); - secdiff=now.tv_sec - ts->timestamp.tv_sec; - usecdiff=now.tv_usec - ts->timestamp.tv_usec; - //printf("%d sec diff, %d usec diff\n",secdiff, usecdiff); - return (float) (secdiff*1000) + ((float)usecdiff)/1000; -} - -/** @internal - * @brief Calculates the RTT of the host with SSH channel operations, and - * returns the average of the calculated RTT. - * @param[in] session active SSH session to test. - * @param[out] average average RTT in milliseconds. - * @returns 0 on success, -1 if there is an error. - */ -int benchmarks_ssh_latency(ssh_session session, float *average){ - float times[3]; - struct timestamp_struct ts; - int i; - ssh_channel channel; - channel=ssh_channel_new(session); - if(channel==NULL) - goto error; - if(ssh_channel_open_session(channel)==SSH_ERROR) - goto error; - - for(i=0;i<3;++i){ - timestamp_init(&ts); - if(ssh_channel_request_env(channel,"TEST","test")==SSH_ERROR && - ssh_get_error_code(session)==SSH_FATAL) - goto error; - times[i]=elapsed_time(&ts); - } - ssh_channel_close(channel); - ssh_channel_free(channel); - channel=NULL; - printf("SSH request times : %f ms ; %f ms ; %f ms\n", times[0], times[1], times[2]); - *average=(times[0]+times[1]+times[2])/3; - return 0; -error: - fprintf(stderr,"Error calculating SSH latency : %s\n",ssh_get_error(session)); - if(channel) - ssh_channel_free(channel); - return -1; -} diff --git a/libssh/tests/chmodtest.c b/libssh/tests/chmodtest.c deleted file mode 100644 index 1e6f5112..00000000 --- a/libssh/tests/chmodtest.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#include -#include "examples_common.h" -#include - -int main(void) { - ssh_session session; - sftp_session sftp; - char buffer[1024*1024]; - int rc; - - session = connect_ssh("localhost", NULL, 0); - if (session == NULL) { - return 1; - } - - sftp=sftp_new(session); - sftp_init(sftp); - rc=sftp_rename(sftp,"/tmp/test","/tmp/test"); - rc=sftp_rename(sftp,"/tmp/test","/tmp/test"); - rc=sftp_chmod(sftp,"/tmp/test",0644); - if (rc < 0) { - printf("error : %s\n",ssh_get_error(sftp)); - - ssh_disconnect(session); - return 1; - } - - ssh_disconnect(session); - - return 0; -} diff --git a/libssh/tests/client/CMakeLists.txt b/libssh/tests/client/CMakeLists.txt deleted file mode 100644 index 616060c3..00000000 --- a/libssh/tests/client/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -project(clienttests C) - -add_cmocka_test(torture_algorithms torture_algorithms.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_auth torture_auth.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_connect torture_connect.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_knownhosts torture_knownhosts.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_proxycommand torture_proxycommand.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_session torture_session.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_forward torture_forward.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_request_env torture_request_env.c ${TORTURE_LIBRARY}) -if (WITH_SFTP) - add_cmocka_test(torture_sftp_static torture_sftp_static.c ${TORTURE_LIBRARY}) - add_cmocka_test(torture_sftp_dir torture_sftp_dir.c ${TORTURE_LIBRARY}) - add_cmocka_test(torture_sftp_read torture_sftp_read.c ${TORTURE_LIBRARY}) -endif (WITH_SFTP) diff --git a/libssh/tests/client/torture_algorithms.c b/libssh/tests/client/torture_algorithms.c deleted file mode 100644 index 8a466380..00000000 --- a/libssh/tests/client/torture_algorithms.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include "libssh/libssh.h" -#include "libssh/priv.h" - - -static void setup(void **state) { - int verbosity=torture_libssh_verbosity(); - ssh_session session = ssh_new(); - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); - *state = session; -} - -static void teardown(void **state) { - ssh_free(*state); -} - -static void test_algorithm(ssh_session session, const char *algo, const char *hmac) { - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, algo); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, algo); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_HMAC_C_S, hmac); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, hmac); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session, NULL); - if (rc != SSH_OK) { - rc = ssh_get_error_code(session); - assert_true(rc == SSH_REQUEST_DENIED); - } - - ssh_disconnect(session); -} - -static void torture_algorithms_aes128_cbc_hmac_sha1(void **state) { - test_algorithm(*state, "aes128-cbc", "hmac-sha1"); -} - -static void torture_algorithms_aes128_cbc_hmac_sha2_256(void **state) { - test_algorithm(*state, "aes128-cbc", "hmac-sha2-256"); -} - -static void torture_algorithms_aes128_cbc_hmac_sha2_512(void **state) { - test_algorithm(*state, "aes128-cbc", "hmac-sha2-512"); -} - -static void torture_algorithms_aes192_cbc_hmac_sha1(void **state) { - test_algorithm(*state, "aes192-cbc", "hmac-sha1"); -} - -static void torture_algorithms_aes192_cbc_hmac_sha2_256(void **state) { - test_algorithm(*state, "aes192-cbc", "hmac-sha2-256"); -} - -static void torture_algorithms_aes192_cbc_hmac_sha2_512(void **state) { - test_algorithm(*state, "aes192-cbc", "hmac-sha2-512"); -} - -static void torture_algorithms_aes256_cbc_hmac_sha1(void **state) { - test_algorithm(*state, "aes256-cbc", "hmac-sha1"); -} - -static void torture_algorithms_aes256_cbc_hmac_sha2_256(void **state) { - test_algorithm(*state, "aes256-cbc", "hmac-sha2-256"); -} - -static void torture_algorithms_aes256_cbc_hmac_sha2_512(void **state) { - test_algorithm(*state, "aes256-cbc", "hmac-sha2-512"); -} - -static void torture_algorithms_aes128_ctr_hmac_sha1(void **state) { - test_algorithm(*state, "aes128-ctr", "hmac-sha1"); -} - -static void torture_algorithms_aes128_ctr_hmac_sha2_256(void **state) { - test_algorithm(*state, "aes128-ctr", "hmac-sha2-256"); -} - -static void torture_algorithms_aes128_ctr_hmac_sha2_512(void **state) { - test_algorithm(*state, "aes128-ctr", "hmac-sha2-512"); -} - -static void torture_algorithms_aes192_ctr_hmac_sha1(void **state) { - test_algorithm(*state, "aes192-ctr", "hmac-sha1"); -} - -static void torture_algorithms_aes192_ctr_hmac_sha2_256(void **state) { - test_algorithm(*state, "aes192-ctr", "hmac-sha2-256"); -} - -static void torture_algorithms_aes192_ctr_hmac_sha2_512(void **state) { - test_algorithm(*state, "aes192-ctr", "hmac-sha2-512"); -} - -static void torture_algorithms_aes256_ctr_hmac_sha1(void **state) { - test_algorithm(*state, "aes256-ctr", "hmac-sha1"); -} - -static void torture_algorithms_aes256_ctr_hmac_sha2_256(void **state) { - test_algorithm(*state, "aes256-ctr", "hmac-sha2-256"); -} - -static void torture_algorithms_aes256_ctr_hmac_sha2_512(void **state) { - test_algorithm(*state, "aes256-ctr", "hmac-sha2-512"); -} - -static void torture_algorithms_3des_cbc_hmac_sha1(void **state) { - test_algorithm(*state, "3des-cbc", "hmac-sha1"); -} - -static void torture_algorithms_3des_cbc_hmac_sha2_256(void **state) { - test_algorithm(*state, "3des-cbc", "hmac-sha2-256"); -} - -static void torture_algorithms_3des_cbc_hmac_sha2_512(void **state) { - test_algorithm(*state, "3des-cbc", "hmac-sha2-512"); -} - -static void torture_algorithms_blowfish_cbc_hmac_sha1(void **state) { - test_algorithm(*state, "blowfish-cbc", "hmac-sha1"); -} - -static void torture_algorithms_blowfish_cbc_hmac_sha2_256(void **state) { - test_algorithm(*state, "blowfish-cbc", "hmac-sha2-256"); -} - -static void torture_algorithms_blowfish_cbc_hmac_sha2_512(void **state) { - test_algorithm(*state, "blowfish-cbc", "hmac-sha2-512"); -} - -static void torture_algorithms_zlib(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session,SSH_OPTIONS_HOST,"localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "zlib"); -#ifdef WITH_ZLIB - assert_true(rc == SSH_OK); -#else - assert_true(rc == SSH_ERROR); -#endif - - rc = ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "zlib"); -#ifdef WITH_ZLIB - assert_true(rc == SSH_OK); -#else - assert_true(rc == SSH_ERROR); -#endif - - rc = ssh_connect(session); -#ifdef WITH_ZLIB - if (ssh_get_openssh_version(session)) { - assert_false(rc == SSH_OK); - ssh_disconnect(session); - return; - } -#endif - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session, NULL); - if (rc != SSH_OK) { - rc = ssh_get_error_code(session); - assert_true(rc == SSH_REQUEST_DENIED); - } - - ssh_disconnect(session); -} - -static void torture_algorithms_zlib_openssh(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session,SSH_OPTIONS_HOST,"localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "zlib@openssh.com"); -#ifdef WITH_ZLIB - assert_true(rc == SSH_OK); -#else - assert_true(rc == SSH_ERROR); -#endif - - rc = ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "zlib@openssh.com"); -#ifdef WITH_ZLIB - assert_true(rc == SSH_OK); -#else - assert_true(rc == SSH_ERROR); -#endif - - rc = ssh_connect(session); -#ifdef WITH_ZLIB - if (ssh_get_openssh_version(session)) { - assert_true(rc==SSH_OK); - rc = ssh_userauth_none(session, NULL); - if (rc != SSH_OK) { - rc = ssh_get_error_code(session); - assert_true(rc == SSH_REQUEST_DENIED); - } - ssh_disconnect(session); - return; - } - assert_false(rc == SSH_OK); -#else - assert_true(rc == SSH_OK); -#endif - - ssh_disconnect(session); -} - -#if defined(HAVE_LIBCRYPTO) && defined(HAVE_ECC) -static void torture_algorithms_ecdh_sha2_nistp256(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session,SSH_OPTIONS_HOST,"localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "ecdh-sha2-nistp256"); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - rc = ssh_userauth_none(session, NULL); - if (rc != SSH_OK) { - rc = ssh_get_error_code(session); - assert_true(rc == SSH_REQUEST_DENIED); - } - - ssh_disconnect(session); -} -#endif - -static void torture_algorithms_dh_group1(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session,SSH_OPTIONS_HOST,"localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group1-sha1"); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - rc = ssh_userauth_none(session, NULL); - if (rc != SSH_OK) { - rc = ssh_get_error_code(session); - assert_true(rc == SSH_REQUEST_DENIED); - } - - ssh_disconnect(session); -} -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_algorithms_aes128_cbc_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes128_cbc_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes128_cbc_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes192_cbc_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes192_cbc_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes192_cbc_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes256_cbc_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes256_cbc_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes256_cbc_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes128_ctr_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes128_ctr_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes128_ctr_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes192_ctr_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes192_ctr_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes192_ctr_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes256_ctr_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes256_ctr_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_aes256_ctr_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_3des_cbc_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_3des_cbc_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_3des_cbc_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_blowfish_cbc_hmac_sha1, setup, teardown), - unit_test_setup_teardown(torture_algorithms_blowfish_cbc_hmac_sha2_256, setup, teardown), - unit_test_setup_teardown(torture_algorithms_blowfish_cbc_hmac_sha2_512, setup, teardown), - unit_test_setup_teardown(torture_algorithms_zlib, setup, teardown), - unit_test_setup_teardown(torture_algorithms_zlib_openssh, setup, teardown), - unit_test_setup_teardown(torture_algorithms_dh_group1,setup,teardown), -#if defined(HAVE_LIBCRYPTO) && defined(HAVE_ECC) - unit_test_setup_teardown(torture_algorithms_ecdh_sha2_nistp256,setup,teardown) -#endif - }; - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/client/torture_auth.c b/libssh/tests/client/torture_auth.c deleted file mode 100644 index af36b79f..00000000 --- a/libssh/tests/client/torture_auth.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include "libssh/libssh.h" -#include "libssh/priv.h" -#include "libssh/session.h" -#include "agent.c" - -static void setup(void **state) { - int verbosity = torture_libssh_verbosity(); - ssh_session session = ssh_new(); - - ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); - - *state = session; -} - -static void teardown(void **state) { - ssh_disconnect(*state); - ssh_free(*state); -} - -static void torture_auth_autopubkey(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session,NULL); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); - - rc = ssh_userauth_publickey_auto(session, NULL, NULL); - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_autopubkey_nonblocking(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - ssh_set_blocking(session,0); - do { - rc = ssh_userauth_none(session, NULL); - } while (rc == SSH_AUTH_AGAIN); - - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); - - do { - rc = ssh_userauth_publickey_auto(session, NULL, NULL); - } while (rc == SSH_AUTH_AGAIN); - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_kbdint(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - char *password = getenv("TORTURE_PASSWORD"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - if (password == NULL) { - print_message("*** Please set the environment variable " - "TORTURE_PASSWORD to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session,NULL); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE); - - rc = ssh_userauth_kbdint(session, NULL, NULL); - assert_true(rc == SSH_AUTH_INFO); - assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1); - - rc = ssh_userauth_kbdint_setanswer(session, 0, password); - assert_false(rc < 0); - - rc = ssh_userauth_kbdint(session, NULL, NULL); - /* Sometimes, SSH server send an empty query at the end of exchange */ - if(rc == SSH_AUTH_INFO) { - assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0); - rc = ssh_userauth_kbdint(session, NULL, NULL); - } - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_kbdint_nonblocking(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - char *password = getenv("TORTURE_PASSWORD"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - if (password == NULL) { - print_message("*** Please set the environment variable " - "TORTURE_PASSWORD to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - ssh_set_blocking(session,0); - do { - rc = ssh_userauth_none(session, NULL); - } while (rc == SSH_AUTH_AGAIN); - - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE); - - do { - rc = ssh_userauth_kbdint(session, NULL, NULL); - } while (rc == SSH_AUTH_AGAIN); - assert_true(rc == SSH_AUTH_INFO); - assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1); - do { - rc = ssh_userauth_kbdint_setanswer(session, 0, password); - } while (rc == SSH_AUTH_AGAIN); - assert_false(rc < 0); - - do { - rc = ssh_userauth_kbdint(session, NULL, NULL); - } while (rc == SSH_AUTH_AGAIN); - /* Sometimes, SSH server send an empty query at the end of exchange */ - if(rc == SSH_AUTH_INFO) { - assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0); - do { - rc = ssh_userauth_kbdint(session, NULL, NULL); - } while (rc == SSH_AUTH_AGAIN); - } - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_password(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - char *password = getenv("TORTURE_PASSWORD"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - if (password == NULL) { - print_message("*** Please set the environment variable " - "TORTURE_PASSWORD to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session, NULL); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_AUTH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PASSWORD); - - rc = ssh_userauth_password(session, NULL, password); - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_password_nonblocking(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - char *password = getenv("TORTURE_PASSWORD"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - if (password == NULL) { - print_message("*** Please set the environment variable " - "TORTURE_PASSWORD to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - ssh_set_blocking(session,0); - do { - rc = ssh_userauth_none(session, NULL); - } while (rc == SSH_AUTH_AGAIN); - - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_AUTH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PASSWORD); - - do { - rc = ssh_userauth_password(session, NULL, password); - } while(rc==SSH_AUTH_AGAIN); - - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_agent(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - if (!agent_is_running(session)){ - print_message("*** Agent not running. Test ignored\n"); - return; - } - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session,NULL); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); - - rc = ssh_userauth_agent(session, NULL); - assert_true(rc == SSH_AUTH_SUCCESS); -} - -static void torture_auth_agent_nonblocking(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - if (!agent_is_running(session)){ - print_message("*** Agent not running. Test ignored\n"); - return; - } - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session,NULL); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); - - ssh_set_blocking(session,0); - - do { - rc = ssh_userauth_agent(session, NULL); - } while (rc == SSH_AUTH_AGAIN); - assert_true(rc == SSH_AUTH_SUCCESS); -} - - -static void torture_auth_none(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session,NULL); - - assert_true(rc == SSH_AUTH_DENIED); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } -} - -static void torture_auth_none_nonblocking(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - int rc; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - - ssh_set_blocking(session,0); - - do { - rc = ssh_userauth_none(session,NULL); - } while (rc == SSH_AUTH_AGAIN); - assert_true(rc == SSH_AUTH_DENIED); - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_auth_kbdint, setup, teardown), - unit_test_setup_teardown(torture_auth_kbdint_nonblocking, setup, teardown), - unit_test_setup_teardown(torture_auth_password, setup, teardown), - unit_test_setup_teardown(torture_auth_password_nonblocking, setup, teardown), - unit_test_setup_teardown(torture_auth_autopubkey, setup, teardown), - unit_test_setup_teardown(torture_auth_autopubkey_nonblocking, setup, teardown), - unit_test_setup_teardown(torture_auth_agent, setup, teardown), - unit_test_setup_teardown(torture_auth_agent_nonblocking, setup, teardown), - unit_test_setup_teardown(torture_auth_none, setup, teardown), - unit_test_setup_teardown(torture_auth_none_nonblocking, setup, teardown), - }; - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/client/torture_connect.c b/libssh/tests/client/torture_connect.c deleted file mode 100644 index 31573ea3..00000000 --- a/libssh/tests/client/torture_connect.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include -#include -#include - -#define HOST "localhost" -/* Should work until Apnic decides to assign it :) */ -#define BLACKHOLE "1.1.1.1" - -static void setup(void **state) { - int verbosity=torture_libssh_verbosity(); - ssh_session session = ssh_new(); - - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); - - *state = session; -} - -static void teardown(void **state) { - ssh_session session = *state; - ssh_disconnect(session); - ssh_free(session); -} - -static void torture_connect_nonblocking(void **state) { - ssh_session session = *state; - - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, HOST); - assert_true(rc == SSH_OK); - ssh_set_blocking(session,0); - - do { - rc = ssh_connect(session); - assert_true(rc != SSH_ERROR); - } while(rc == SSH_AGAIN); - - assert_true(rc == SSH_OK); -} - -static void torture_connect_timeout(void **state) { - ssh_session session = *state; - struct timeval before, after; - int rc; - long timeout = 2; - time_t sec; - suseconds_t usec; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, BLACKHOLE); - assert_true(rc == SSH_OK); - rc = ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &timeout); - assert_true(rc == SSH_OK); - - rc = gettimeofday(&before, NULL); - assert_true(rc == 0); - rc = ssh_connect(session); - assert_true(rc == SSH_ERROR); - rc = gettimeofday(&after, NULL); - assert_true(rc == 0); - sec = after.tv_sec - before.tv_sec; - usec = after.tv_usec - before.tv_usec; - /* Borrow a second for the missing usecs, but don't bother calculating */ - if (usec < 0) - sec--; - assert_in_range(sec, 1, 3); -} - -static void torture_connect_double(void **state) { - ssh_session session = *state; - - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, HOST); - assert_true(rc == SSH_OK); - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - ssh_disconnect(session); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); -} - -static void torture_connect_failure(void **state) { - /* - * The intent of this test is to check that a fresh - * ssh_new/ssh_disconnect/ssh_free sequence doesn't crash/leak - * and the behavior of a double ssh_disconnect - */ - ssh_session session = *state; - ssh_disconnect(session); -} - -static void torture_connect_socket(void **state) { - ssh_session session = *state; - - int rc; - int sock_fd = 0; - struct sockaddr_in server_addr; - - sock_fd = socket(AF_INET, SOCK_STREAM, 0); - assert_true(sock_fd > 0); - - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(22); - server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - - rc = connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); - assert_true(rc == 0); - - ssh_options_set(session, SSH_OPTIONS_FD, &sock_fd); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_connect_nonblocking, setup, teardown), - unit_test_setup_teardown(torture_connect_double, setup, teardown), - unit_test_setup_teardown(torture_connect_failure, setup, teardown), - unit_test_setup_teardown(torture_connect_timeout, setup, teardown), - unit_test_setup_teardown(torture_connect_socket, setup, teardown), - }; - - ssh_init(); - - rc = run_tests(tests); - - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/client/torture_forward.c b/libssh/tests/client/torture_forward.c deleted file mode 100644 index 5754386f..00000000 --- a/libssh/tests/client/torture_forward.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include - -static void setup(void **state) -{ - ssh_session session; - const char *host; - const char *user; - const char *password; - - host = getenv("TORTURE_HOST"); - if (host == NULL) { - host = "localhost"; - } - - user = getenv("TORTURE_USER"); - password = getenv("TORTURE_PASSWORD"); - - session = torture_ssh_session(host, user, password); - - assert_non_null(session); - *state = session; -} - -static void teardown(void **state) -{ - ssh_session session = (ssh_session) *state; - - assert_non_null(session); - - if (ssh_is_connected(session)) { - ssh_disconnect(session); - } - ssh_free(session); -} - -static void torture_ssh_forward(void **state) -{ - ssh_session session = (ssh_session) *state; -#if 0 - ssh_channel c; -#endif - int bound_port; - int rc; - - rc = ssh_channel_listen_forward(session, "127.0.0.1", 8080, &bound_port); - assert_int_equal(rc, SSH_OK); - -#if 0 - c = ssh_forward_accept(session, 60000); - assert_non_null(c); - - ssh_channel_send_eof(c); - ssh_channel_close(c); -#endif -} - -int torture_run_tests(void) { - int rc; - - const UnitTest tests[] = { - unit_test_setup_teardown(torture_ssh_forward, setup, teardown), - }; - - ssh_init(); - - rc = run_tests(tests); - - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/client/torture_knownhosts.c b/libssh/tests/client/torture_knownhosts.c deleted file mode 100644 index df99ae90..00000000 --- a/libssh/tests/client/torture_knownhosts.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include "session.c" -#include "known_hosts.c" - -#define KNOWNHOSTFILES "libssh_torture_knownhosts" -#define BADRSA "AAAAB3NzaC1yc2EAAAADAQABAAABAQChm5" \ - "a6Av65O8cKtx5YXOnui3wJnYE6A6J/I4kZSAibbn14Jcl+34VJQwv96f25AxNmo" \ - "NwoiZV93IzdypQmiuieh6s6wB9WhYjU9K/6CkIpNhpCxswA90b3ePjS7LnR9B9J" \ - "slPSbG1H0KC1c5lb7G3utXteXtM+4YvCvpN5VdC4CpghT+p0cwN2Na8Md5vRItz" \ - "YgIytryNn7LLiwYfoSxvWigFrTTZsrVtCOYyNgklmffpGdzuC43wdANvTewfI9G" \ - "o71r8EXmEc228CrYPmb8Scv3mpXFK/BosohSGkPlEHu9lf3YjnknBicDaVtJOYp" \ - "wnXJPjZo2EhG79HxDRpjJHH" -#define BADDSA "AAAAB3NzaC1kc3MAAACBAITDKqGQ5aC5wHySG6ZdL1+BVBY2nLP5vzw3i3pvZfP" \ - "yNUS0UCwrt5pajsMvDRGXXebTJhWVonDnv8tpSgiuIBXMZrma8CU1KCFGRzwb/n8" \ - "cc5tJmIphlOUTrObjBmsRz7u1eZmoaddXC9ask6BNnt0DmhzYi2esL3mbardy8IN" \ - "zAAAAFQDlPFCm410pgQQPb3X5FWjyVEIl+QAAAIAp0vqfir8K8p+zP4dzFG7ppnt" \ - "DjaXf3ge6URF7f5xPDo6CClGo2JQ2REF8NxM7K9cLgR9Ifx2ahO48UMgrXEl/BOp" \ - "IQHpeBqUz26a49O5J0WEW16YSUHxWwMxWVe/SRmyKdTUZJ6fcepH88JNqm3XudNn" \ - "s78grM+yx9mcXnK2AsAAAAIBxpF8ZQIlGrSgwCmCfwjP156bC3Ya6LYf9ZpLJ0dX" \ - "EcxqLVllrNEvd2EGD9p16BYO2yaalYon8im59PtOcul2ay5XQ6rVDQ2T0pgNUpsI" \ - "h0dSi8VJXI1wes5HTyLsv9VBmU1uCXUUvufoQKfF/OcSH0ufcCpnd62g1/adZcy2" \ - "WJg==" - -static void setup(void **state) { - int verbosity=torture_libssh_verbosity(); - ssh_session session = ssh_new(); - - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); - - *state = session; -} - -static void teardown(void **state) { - ssh_session session = *state; - - ssh_disconnect(session); - ssh_free(session); - - unlink(KNOWNHOSTFILES); -} - -static void torture_knownhosts_port(void **state) { - ssh_session session = *state; - char buffer[200]; - char *p; - FILE *file; - int rc; - - /* Connect to localhost:22, force the port to 1234 and then write - * the known hosts file. Then check that the entry written is - * [localhost]:1234 - */ - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc==SSH_OK); - - session->opts.port = 1234; - rc = ssh_write_knownhost(session); - assert_true(rc == SSH_OK); - - file = fopen(KNOWNHOSTFILES, "r"); - assert_true(file != NULL); - p = fgets(buffer, sizeof(buffer), file); - assert_false(p == NULL); - fclose(file); - buffer[sizeof(buffer) - 1] = '\0'; - assert_true(strstr(buffer,"[localhost]:1234 ") != NULL); - - ssh_disconnect(session); - ssh_free(session); - - /* Now, connect back to the ssh server and verify the known host line */ - *state = session = ssh_new(); - - ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - session->opts.port = 1234; - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_KNOWN_OK); -} - -static void torture_knownhosts_fail(void **state) { - ssh_session session = *state; - FILE *file; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa"); - assert_true(rc == SSH_OK); - - file = fopen(KNOWNHOSTFILES, "w"); - assert_true(file != NULL); - fprintf(file, "localhost ssh-rsa %s\n", BADRSA); - fclose(file); - - rc = ssh_connect(session); - assert_true(rc==SSH_OK); - - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_KNOWN_CHANGED); -} - -static void torture_knownhosts_other(void **state) { - ssh_session session = *state; - FILE *file; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-dss"); - assert_true(rc == SSH_OK); - - file = fopen(KNOWNHOSTFILES, "w"); - assert_true(file != NULL); - fprintf(file, "localhost ssh-rsa %s\n", BADRSA); - fclose(file); - - rc = ssh_connect(session); - assert_true(rc==SSH_OK); - - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_FOUND_OTHER); -} - -static void torture_knownhosts_other_auto(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-dss"); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc==SSH_OK); - - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_NOT_KNOWN); - - rc = ssh_write_knownhost(session); - assert_true(rc == SSH_OK); - - ssh_disconnect(session); - ssh_free(session); - - /* connect again and check host key */ - *state = session = ssh_new(); - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc==SSH_OK); - - /* ssh-rsa is the default but libssh should try ssh-dss instead */ - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_KNOWN_OK); -} - -static void torture_knownhosts_conflict(void **state) { - ssh_session session = *state; - FILE *file; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa"); - assert_true(rc == SSH_OK); - - file = fopen(KNOWNHOSTFILES, "w"); - assert_true(file != NULL); - fprintf(file, "localhost ssh-rsa %s\n", BADRSA); - fprintf(file, "localhost ssh-dss %s\n", BADDSA); - fclose(file); - - rc = ssh_connect(session); - assert_true(rc==SSH_OK); - - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_KNOWN_CHANGED); - - rc = ssh_write_knownhost(session); - assert_true(rc==SSH_OK); - - ssh_disconnect(session); - ssh_free(session); - - /* connect again and check host key */ - *state = session = ssh_new(); - - ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa"); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_is_server_known(session); - assert_true(rc == SSH_SERVER_KNOWN_OK); -} - -static void torture_knownhosts_precheck(void **state) { - ssh_session session = *state; - FILE *file; - int rc; - char **kex; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == SSH_OK); - - rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, KNOWNHOSTFILES); - assert_true(rc == SSH_OK); - - file = fopen(KNOWNHOSTFILES, "w"); - assert_true(file != NULL); - fprintf(file, "localhost ssh-rsa %s\n", BADRSA); - fprintf(file, "localhost ssh-dss %s\n", BADDSA); - fclose(file); - - kex = ssh_knownhosts_algorithms(session); - assert_true(kex != NULL); - assert_string_equal(kex[0],"ssh-rsa"); - assert_string_equal(kex[1],"ssh-dss"); - assert_true(kex[2]==NULL); - free(kex[1]); - free(kex[0]); - free(kex); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_knownhosts_port, setup, teardown), - unit_test_setup_teardown(torture_knownhosts_fail, setup, teardown), - unit_test_setup_teardown(torture_knownhosts_other, setup, teardown), - unit_test_setup_teardown(torture_knownhosts_other_auto, setup, teardown), - unit_test_setup_teardown(torture_knownhosts_conflict, setup, teardown), - unit_test_setup_teardown(torture_knownhosts_precheck, setup, teardown) - }; - - ssh_init(); - - rc = run_tests(tests); - - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/client/torture_proxycommand.c b/libssh/tests/client/torture_proxycommand.c deleted file mode 100644 index 8cf68685..00000000 --- a/libssh/tests/client/torture_proxycommand.c +++ /dev/null @@ -1,57 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include -#include "libssh/priv.h" - -static void setup(void **state) { - ssh_session session = ssh_new(); - - *state = session; -} - -static void teardown(void **state) { - ssh_free(*state); -} - -static void torture_options_set_proxycommand(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == 0); - - rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "nc localhost 22"); - assert_true(rc == 0); - rc = ssh_connect(session); - assert_true(rc == SSH_OK); -} - -static void torture_options_set_proxycommand_notexist(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == 0); - - rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "this_command_does_not_exist"); - assert_true(rc == SSH_OK); - rc = ssh_connect(session); - assert_true(rc == SSH_ERROR); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_options_set_proxycommand, setup, teardown), - unit_test_setup_teardown(torture_options_set_proxycommand_notexist, setup, teardown), - }; - - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/client/torture_request_env.c b/libssh/tests/client/torture_request_env.c deleted file mode 100644 index 7c7338ed..00000000 --- a/libssh/tests/client/torture_request_env.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2013 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include - -static void setup(void **state) -{ - ssh_session session; - const char *host; - const char *user; - const char *password; - - host = getenv("TORTURE_HOST"); - if (host == NULL) { - host = "localhost"; - } - - user = getenv("TORTURE_USER"); - password = getenv("TORTURE_PASSWORD"); - - session = torture_ssh_session(host, user, password); - - assert_false(session == NULL); - *state = session; -} - -static void teardown(void **state) -{ - ssh_session session = *state; - - assert_false(session == NULL); - - if (ssh_is_connected(session)) { - ssh_disconnect(session); - } - ssh_free(session); -} - -static void torture_request_env(void **state) -{ - ssh_session session = *state; - ssh_channel c; - char buffer[4096] = {0}; - int nbytes; - int rc; - int lang_found = 0; - - c = ssh_channel_new(session); - assert_non_null(c); - - rc = ssh_channel_open_session(c); - assert_int_equal(rc, SSH_OK); - - rc = ssh_channel_request_env(c, "LC_LIBSSH", "LIBSSH"); - assert_int_equal(rc, SSH_OK); - - rc = ssh_channel_request_exec(c, "bash -c export"); - assert_int_equal(rc, SSH_OK); - - nbytes = ssh_channel_read(c, buffer, sizeof(buffer) - 1, 0); - while (nbytes > 0) { -#if 0 - rc = fwrite(buffer, 1, nbytes, stdout); - assert_int_equal(rc, nbytes); -#endif - buffer[nbytes]='\0'; - if (strstr(buffer, "LC_LIBSSH=\"LIBSSH\"")) { - lang_found = 1; - break; - } - - nbytes = ssh_channel_read(c, buffer, sizeof(buffer), 0); - } - assert_int_equal(lang_found, 1); - - ssh_channel_close(c); -} - -int torture_run_tests(void) { - int rc; - - const UnitTest tests[] = { - unit_test_setup_teardown(torture_request_env, setup, teardown), - }; - - ssh_init(); - - rc = run_tests(tests); - - ssh_finalize(); - return rc; -} - diff --git a/libssh/tests/client/torture_session.c b/libssh/tests/client/torture_session.c deleted file mode 100644 index ef9ef653..00000000 --- a/libssh/tests/client/torture_session.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2012 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#define LIBSSH_STATIC - -#include "torture.h" -#include "libssh/libssh.h" -#include "libssh/priv.h" -#include "libssh/session.h" - -#define BUFLEN 4096 -static char buffer[BUFLEN]; - -static void setup(void **state) { - int verbosity = torture_libssh_verbosity(); - ssh_session session = ssh_new(); - - ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); - - *state = session; -} - -static void teardown(void **state) { - ssh_disconnect(*state); - ssh_free(*state); -} - -static void torture_channel_read_error(void **state) { - ssh_session session = *state; - char *user = getenv("TORTURE_USER"); - ssh_channel channel; - int rc; - int i; - - if (user == NULL) { - print_message("*** Please set the environment variable TORTURE_USER" - " to enable this test!!\n"); - return; - } - - rc = ssh_options_set(session, SSH_OPTIONS_USER, user); - assert_true(rc == SSH_OK); - - rc = ssh_connect(session); - assert_true(rc == SSH_OK); - - rc = ssh_userauth_none(session,NULL); - /* This request should return a SSH_REQUEST_DENIED error */ - if (rc == SSH_ERROR) { - assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); - } - rc = ssh_userauth_list(session, NULL); - assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); - - rc = ssh_userauth_publickey_auto(session, NULL, NULL); - assert_true(rc == SSH_AUTH_SUCCESS); - - channel = ssh_channel_new(session); - assert_true(channel != NULL); - - rc = ssh_channel_open_session(channel); - assert_true(rc == SSH_OK); - - rc = ssh_channel_request_exec(channel, "hexdump -C /dev/urandom"); - assert_true(rc == SSH_OK); - - /* send crap and for server to send us a disconnect */ - rc = write(ssh_get_fd(session),"AAAA", 4); - assert_int_equal(rc, 4); - - for (i=0;i<20;++i){ - rc = ssh_channel_read(channel,buffer,sizeof(buffer),0); - if (rc == SSH_ERROR) - break; - } - assert_true(rc == SSH_ERROR); - - ssh_channel_free(channel); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_channel_read_error, setup, teardown), - }; - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/client/torture_sftp_dir.c b/libssh/tests/client/torture_sftp_dir.c deleted file mode 100644 index 8d2bcda8..00000000 --- a/libssh/tests/client/torture_sftp_dir.c +++ /dev/null @@ -1,74 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "sftp.c" - -static void setup(void **state) { - ssh_session session; - struct torture_sftp *t; - const char *host; - const char *user; - const char *password; - - host = getenv("TORTURE_HOST"); - if (host == NULL) { - host = "localhost"; - } - - user = getenv("TORTURE_USER"); - password = getenv("TORTURE_PASSWORD"); - - session = torture_ssh_session(host, user, password); - assert_false(session == NULL); - t = torture_sftp_session(session); - assert_false(t == NULL); - - *state = t; -} - -static void teardown(void **state) { - struct torture_sftp *t = *state; - - assert_false(t == NULL); - - torture_rmdirs(t->testdir); - torture_sftp_close(t); -} - -static void torture_sftp_mkdir(void **state) { - struct torture_sftp *t = *state; - char tmpdir[128] = {0}; - int rc; - - assert_false(t == NULL); - - snprintf(tmpdir, sizeof(tmpdir) - 1, "%s/mkdir_test", t->testdir); - - rc = sftp_mkdir(t->sftp, tmpdir, 0755); - if(rc != SSH_OK) - fprintf(stderr,"error:%s\n",ssh_get_error(t->sftp->session)); - assert_true(rc == 0); - - /* check if it really has been created */ - assert_true(torture_isdir(tmpdir)); - - rc = sftp_rmdir(t->sftp, tmpdir); - assert_true(rc == 0); - - /* check if it has been deleted */ - assert_false(torture_isdir(tmpdir)); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_sftp_mkdir, setup, teardown) - }; - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/client/torture_sftp_read.c b/libssh/tests/client/torture_sftp_read.c deleted file mode 100644 index 1e40e2cf..00000000 --- a/libssh/tests/client/torture_sftp_read.c +++ /dev/null @@ -1,83 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "sftp.c" - -#define MAX_XFER_BUF_SIZE 16384 - -static void setup(void **state) { - ssh_session session; - struct torture_sftp *t; - const char *host; - const char *user; - const char *password; - - host = getenv("TORTURE_HOST"); - if (host == NULL) { - host = "localhost"; - } - - user = getenv("TORTURE_USER"); - password = getenv("TORTURE_PASSWORD"); - - session = torture_ssh_session(host, user, password); - assert_false(session == NULL); - t = torture_sftp_session(session); - assert_false(t == NULL); - - *state = t; -} - -static void teardown(void **state) { - struct torture_sftp *t = (struct torture_sftp*) *state; - - assert_false(t == NULL); - - torture_rmdirs(t->testdir); - torture_sftp_close(t); -} - -static void torture_sftp_read_blocking(void **state) { - struct torture_sftp *t = (struct torture_sftp*) *state; - char libssh_tmp_file[] = "/tmp/libssh_sftp_test_XXXXXX"; - char buf[MAX_XFER_BUF_SIZE]; - ssize_t bytesread; - ssize_t byteswritten; - int fd; - sftp_file file; - - - file = sftp_open(t->sftp, "/usr/bin/ssh", O_RDONLY, 0); - assert_non_null(file); - - fd = mkstemp(libssh_tmp_file); - unlink(libssh_tmp_file); - - for (;;) { - bytesread = sftp_read(file, buf, MAX_XFER_BUF_SIZE); - if (bytesread == 0) { - break; /* EOF */ - } - assert_false(bytesread < 0); - - byteswritten = write(fd, buf, bytesread); - assert_int_equal(byteswritten, bytesread); - } - - close(fd); - sftp_close(file); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_sftp_read_blocking, setup, teardown) - }; - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/client/torture_sftp_static.c b/libssh/tests/client/torture_sftp_static.c deleted file mode 100644 index 7631def0..00000000 --- a/libssh/tests/client/torture_sftp_static.c +++ /dev/null @@ -1,32 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "sftp.c" - -static void torture_sftp_ext_new(void **state) { - sftp_ext x; - - (void) state; - - x = sftp_ext_new(); - assert_false(x == NULL); - assert_int_equal(x->count, 0); - assert_true(x->name == NULL); - assert_true(x->data == NULL); - - sftp_ext_free(x); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test(torture_sftp_ext_new), - }; - - ssh_init(); - - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/cmdline.c b/libssh/tests/cmdline.c deleted file mode 100644 index 4e2a7d02..00000000 --- a/libssh/tests/cmdline.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "config.h" -#include "torture.h" - -#ifdef HAVE_ARGP_H -#include - -const char *argp_program_version = "libssh test 0.2"; -const char *argp_program_bug_address = ""; - -static char **cmdline; - -/* Program documentation. */ -static char doc[] = "libssh test test"; - -/* The options we understand. */ -static struct argp_option options[] = { - { - .name = "verbose", - .key = 'v', - .arg = NULL, - .flags = 0, - .doc = "Make libssh test more verbose", - .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. - */ - struct argument_s *arguments = state->input; - - /* arg is currently not used */ - (void) arg; - - switch (key) { - case 'v': - arguments->verbose++; - break; - case ARGP_KEY_ARG: - /* End processing here. */ - cmdline = &state->argv [state->next - 1]; - state->next = state->argc; - break; - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -/* Our argp parser. */ -/* static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL}; */ -static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL}; -#endif /* HAVE_ARGP_H */ - -void torture_cmdline_parse(int argc, char **argv, struct argument_s *arguments) { - /* - * Parse our arguments; every option seen by parse_opt will - * be reflected in arguments. - */ -#ifdef HAVE_ARGP_H - argp_parse(&argp, argc, argv, 0, 0, arguments); -#else - (void) argc; - (void) argv; - (void) arguments; -#endif /* HAVE_ARGP_H */ -} diff --git a/libssh/tests/connection.c b/libssh/tests/connection.c deleted file mode 100644 index 889c5117..00000000 --- a/libssh/tests/connection.c +++ /dev/null @@ -1,31 +0,0 @@ -/* -This file is distributed in public domain. You can do whatever you want -with its content. -*/ - -#include -#include -#include "tests.h" -SSH_OPTIONS *set_opts(int argc, char **argv){ - SSH_OPTIONS *options=ssh_options_new(); - char *host=NULL; - if(ssh_options_getopt(options,&argc, argv)){ - fprintf(stderr,"error parsing command line :%s\n",ssh_get_error(options)); - return NULL; - } - int i; - while((i=getopt(argc,argv,""))!=-1){ - switch(i){ - default: - fprintf(stderr,"unknown option %c\n",optopt); - } - } - if(optind < argc) - host=argv[optind++]; - if(host==NULL){ - fprintf(stderr,"must provide an host name\n"); - return NULL; - } - ssh_options_set_host(options,host); - return options; -} diff --git a/libssh/tests/ctest-default.cmake b/libssh/tests/ctest-default.cmake deleted file mode 100644 index a8a3e211..00000000 --- a/libssh/tests/ctest-default.cmake +++ /dev/null @@ -1,71 +0,0 @@ -## The directory to run ctest in. -set(CTEST_DIRECTORY "$ENV{HOME}/workspace/tmp/dashboards/libssh") - -## The hostname of the machine -set(CTEST_SITE "host.libssh.org") -## The buildname -set(CTEST_BUILD_NAME "Linux_2.6-GCC_4.5-x86_64-default") - -## The Makefile generator to use -set(CTEST_CMAKE_GENERATOR "Unix Makefiles") - -## The Build configuration to use. -set(CTEST_BUILD_CONFIGURATION "Debug") - -## The build options for the project -set(CTEST_BUILD_OPTIONS "-DWITH_TESTING=ON -DWITH_SSH1=ON -WITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON -DDEBUG_CRYPTO=ON -DWITH_GCRYPT=OFF") - -#set(CTEST_CUSTOM_MEMCHECK_IGNORE torture_rand) - -## The Model to set: Nightly, Continous, Experimental -set(CTEST_MODEL "Experimental") - -## The branch -#set(CTEST_GIT_BRANCH "--branch v0-5") - -## Wether to enable memory checking. -set(WITH_MEMCHECK FALSE) - -## Wether to enable code coverage. -set(WITH_COVERAGE FALSE) - -####################################################################### - -if (WITH_COVERAGE AND NOT WIN32) - set(CTEST_BUILD_CONFIGURATION "Profiling") -endif (WITH_COVERAGE AND NOT WIN32) - -set(CTEST_SOURCE_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/source") -set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build") - -set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp) - -find_program(CTEST_GIT_COMMAND NAMES git) -find_program(CTEST_COVERAGE_COMMAND NAMES gcov) -find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) - -if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") - set(CTEST_CHECKOUT_COMMAND "${CTEST_GIT_COMMAND} clone ${CTEST_GIT_BRANCH} git://git.libssh.org/projects/libssh.git ${CTEST_SOURCE_DIRECTORY}") -endif() - -set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") - -set(CTEST_CONFIGURE_COMMAND "${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}") -set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} -DWITH_TESTING:BOOL=ON ${CTEST_BUILD_OPTIONS}") -set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"-G${CTEST_CMAKE_GENERATOR}\"") -set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"${CTEST_SOURCE_DIRECTORY}\"") - -ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) - -ctest_start(${CTEST_MODEL} TRACK ${CTEST_MODEL}) -ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY}) -ctest_configure(BUILD ${CTEST_BINARY_DIRECTORY}) -ctest_build(BUILD ${CTEST_BINARY_DIRECTORY}) -ctest_test(BUILD ${CTEST_BINARY_DIRECTORY}) -if (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) - ctest_coverage(BUILD ${CTEST_BINARY_DIRECTORY}) -endif (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) -if (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) - ctest_memcheck(BUILD ${CTEST_BINARY_DIRECTORY}) -endif (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) -ctest_submit() diff --git a/libssh/tests/generate.py b/libssh/tests/generate.py deleted file mode 100755 index 08c2d5b1..00000000 --- a/libssh/tests/generate.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/python -import os -a="" -for i in xrange(4096): - a+=chr(i % 256); -while True: - try: - os.write(1,a) - except: - exit(0) diff --git a/libssh/tests/pkd/CMakeLists.txt b/libssh/tests/pkd/CMakeLists.txt deleted file mode 100644 index 515dae10..00000000 --- a/libssh/tests/pkd/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -project(pkd C) - -if (WITH_SERVER AND UNIX AND NOT WIN32) - -include_directories( - ${LIBSSH_PUBLIC_INCLUDE_DIRS} - ${CMOCKA_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIRS} - ${GCRYPT_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src - ${CMAKE_CURRENT_SOURCE_DIR} -) - -set(pkd_hello_src - pkd_daemon.c - pkd_hello.c - pkd_keyutil.c - pkd_util.c -) - -set(pkd_libs - ${CMOCKA_LIBRARY} - ${LIBSSH_STATIC_LIBRARY} - ${LIBSSH_LINK_LIBRARIES} - ${LIBSSH_THREADS_STATIC_LIBRARY} - ${LIBSSH_THREADS_LINK_LIBRARIES} - ${ARGP_LIBRARIES} -) - -add_executable(pkd_hello ${pkd_hello_src}) -target_link_libraries(pkd_hello ${pkd_libs}) - -endif (WITH_SERVER AND UNIX AND NOT WIN32) diff --git a/libssh/tests/pkd/pkd_client.h b/libssh/tests/pkd/pkd_client.h deleted file mode 100644 index c4a8a601..00000000 --- a/libssh/tests/pkd/pkd_client.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * pkd_client.h -- macros for generating client-specific command - * invocations for use with pkd testing - * - * (c) 2014 Jon Simons - */ - -#ifndef __PKD_CLIENT_H__ -#define __PKD_CLIENT_H__ - -/* OpenSSH */ - -#define OPENSSH_BINARY "ssh" -#define OPENSSH_KEYGEN "ssh-keygen" - -#define OPENSSH_CMD_START \ - OPENSSH_BINARY " " \ - "-o UserKnownHostsFile=/dev/null " \ - "-o StrictHostKeyChecking=no " \ - "-i " CLIENT_ID_FILE " " \ - "1> %s.out " \ - "2> %s.err " \ - "-vvv " - -#define OPENSSH_CMD_END "-p 1234 localhost ls" - -#define OPENSSH_CMD \ - OPENSSH_CMD_START OPENSSH_CMD_END - -#define OPENSSH_KEX_CMD(kexalgo) \ - OPENSSH_CMD_START "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END - -#define OPENSSH_CIPHER_CMD(ciphers) \ - OPENSSH_CMD_START "-c " ciphers " " OPENSSH_CMD_END - -#define OPENSSH_MAC_CMD(macs) \ - OPENSSH_CMD_START "-o MACs=" macs " " OPENSSH_CMD_END - - -/* Dropbear */ - -#define DROPBEAR_BINARY "dbclient" -#define DROPBEAR_KEYGEN "dropbearkey" - -#define DROPBEAR_CMD_START \ - DROPBEAR_BINARY " " \ - "-y -y " \ - "-i " CLIENT_ID_FILE " " \ - "-v " \ - "1> %s.out " \ - "2> %s.err " - -#define DROPBEAR_CMD_END "-p 1234 localhost ls" - -#define DROPBEAR_CMD \ - DROPBEAR_CMD_START DROPBEAR_CMD_END - -#if 0 /* dbclient does not expose control over kex algo */ -#define DROPBEAR_KEX_CMD(kexalgo) \ - DROPBEAR_CMD -#endif - -#define DROPBEAR_CIPHER_CMD(ciphers) \ - DROPBEAR_CMD_START "-c " ciphers " " DROPBEAR_CMD_END - -#define DROPBEAR_MAC_CMD(macs) \ - DROPBEAR_CMD_START "-m " macs " " DROPBEAR_CMD_END - -#endif /* __PKD_CLIENT_H__ */ diff --git a/libssh/tests/pkd/pkd_daemon.c b/libssh/tests/pkd/pkd_daemon.c deleted file mode 100644 index 07736fa6..00000000 --- a/libssh/tests/pkd/pkd_daemon.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * pkd_daemon.c -- a sample public-key testing daemon using libssh - * - * Uses public key authentication to establish an exec channel and - * echo back payloads to the user. - * - * (c) 2014 Jon Simons - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "pkd_daemon.h" - -#include // for cmocka -#include - -static int pkdout_enabled; -static int pkderr_enabled; - -static void pkdout(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); -static void pkderr(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); - -static void pkdout(const char *fmt, ...) { - va_list vargs; - if (pkdout_enabled) { - va_start(vargs, fmt); - vfprintf(stdout, fmt, vargs); - va_end(vargs); - } -} - -static void pkderr(const char *fmt, ...) { - va_list vargs; - if (pkderr_enabled) { - va_start(vargs, fmt); - vfprintf(stderr, fmt, vargs); - va_end(vargs); - } -} - -/* - * pkd state: only one thread can run pkd at a time --------------------- - */ - -static struct { - int rc; - pthread_t tid; - int keep_going; - int pkd_ready; -} ctx; - -static struct { - int server_fd; - int req_exec_received; - int close_received; - int eof_received; -} pkd_state; - -static void pkd_sighandler(int signum) { - (void) signum; -} - -static int pkd_init_libssh() { - int rc = ssh_threads_set_callbacks(ssh_threads_get_pthread()); - return (rc == SSH_OK) ? 0 : 1; -} - -static int pkd_init_server_fd(short port) { - int rc = 0; - int yes = 1; - struct sockaddr_in addr; - - int server_fd = socket(PF_INET, SOCK_STREAM, 0); - if (server_fd < 0) { - rc = -1; - goto out; - } - - rc = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - if (rc != 0) { - goto outclose; - } - - memset(&addr, 0x0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = INADDR_ANY; - rc = bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)); - if (rc != 0) { - goto outclose; - } - - rc = listen(server_fd, 128); - if (rc == 0) { - goto out; - } - -outclose: - close(server_fd); - server_fd = -1; -out: - pkd_state.server_fd = server_fd; - return rc; -} - -static int pkd_accept_fd() { - int fd = -1; - struct sockaddr_in addr; - socklen_t len = sizeof(addr); - - do { - fd = accept(pkd_state.server_fd, (struct sockaddr *) &addr, &len); - } while ((ctx.keep_going != 0) && (fd < 0) && (errno == EINTR)); - - return fd; -} - -static void pkd_eof(ssh_session session, - ssh_channel channel, - void *userdata) { - (void) session; - (void) channel; - (void) userdata; - pkdout("pkd_eof\n"); - pkd_state.eof_received = 1; -} - -static void pkd_chan_close(ssh_session session, - ssh_channel channel, - void *userdata) { - (void) session; - (void) channel; - (void) userdata; - pkdout("pkd_chan_close\n"); - pkd_state.close_received = 1; -} - -static int pkd_req_exec(ssh_session s, - ssh_channel c, - const char *cmd, - void *userdata) { - (void) s; - (void) c; - (void) cmd; - (void) userdata; - /* assumes pubkey authentication has already succeeded */ - pkdout("pkd_req_exec\n"); - pkd_state.req_exec_received = 1; - return 0; -} - -/* assumes there is only ever a single channel */ -static struct ssh_channel_callbacks_struct pkd_channel_cb = { - .channel_eof_function = pkd_eof, - .channel_close_function = pkd_chan_close, - .channel_exec_request_function = pkd_req_exec, -}; - -static int pkd_auth_pubkey_cb(ssh_session s, - const char *user, - ssh_key key, - char state, - void *userdata) { - (void) s; - (void) user; - (void) key; - (void) state; - (void) userdata; - pkdout("pkd_auth_pubkey_cb keytype %s, state: %d\n", - ssh_key_type_to_char(ssh_key_type(key)), state); - if ((state == SSH_PUBLICKEY_STATE_NONE) || - (state == SSH_PUBLICKEY_STATE_VALID)) { - return SSH_AUTH_SUCCESS; - } - return SSH_AUTH_DENIED; -} - -static int pkd_service_request_cb(ssh_session session, - const char *service, - void *userdata) { - (void) session; - (void) userdata; - pkdout("pkd_service_request_cb: %s\n", service); - return (0 == (strcmp(service, "ssh-userauth"))) ? 0 : -1; -} - -static ssh_channel pkd_channel_openreq_cb(ssh_session s, - void *userdata) { - ssh_channel c = NULL; - ssh_channel *out = (ssh_channel *) userdata; - - /* assumes pubkey authentication has already succeeded */ - pkdout("pkd_channel_openreq_cb\n"); - - c = ssh_channel_new(s); - if (c == NULL) { - pkderr("ssh_channel_new: %s\n", ssh_get_error(s)); - return NULL; - } - - ssh_callbacks_init(&pkd_channel_cb); - pkd_channel_cb.userdata = userdata; - if (ssh_set_channel_callbacks(c, &pkd_channel_cb) != SSH_OK) { - pkderr("ssh_set_channel_callbacks: %s\n", ssh_get_error(s)); - ssh_channel_free(c); - c = NULL; - } - - *out = c; - - return c; -} - -static struct ssh_server_callbacks_struct pkd_server_cb = { - .auth_pubkey_function = pkd_auth_pubkey_cb, - .service_request_function = pkd_service_request_cb, - .channel_open_request_session_function = pkd_channel_openreq_cb, -}; - -static int pkd_exec_hello(int fd, struct pkd_daemon_args *args) { - int rc = -1; - ssh_bind b = NULL; - ssh_session s = NULL; - ssh_event e = NULL; - ssh_channel c = NULL; - enum ssh_bind_options_e opts = -1; - - int level = args->opts.libssh_log_level; - enum pkd_hostkey_type_e type = args->type; - const char *hostkeypath = args->hostkeypath; - - pkd_state.eof_received = 0; - pkd_state.close_received = 0; - pkd_state.req_exec_received = 0; - - b = ssh_bind_new(); - if (b == NULL) { - pkderr("ssh_bind_new\n"); - goto outclose; - } - - if (type == PKD_RSA) { - opts = SSH_BIND_OPTIONS_RSAKEY; - } else if (type == PKD_DSA) { - opts = SSH_BIND_OPTIONS_DSAKEY; - } else if (type == PKD_ECDSA) { - opts = SSH_BIND_OPTIONS_ECDSAKEY; - } else { - pkderr("unknown kex algorithm: %d\n", type); - rc = -1; - goto outclose; - } - - rc = ssh_bind_options_set(b, opts, hostkeypath); - if (rc != 0) { - pkderr("ssh_bind_options_set: %s\n", ssh_get_error(b)); - goto outclose; - } - - rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY, &level); - if (rc != 0) { - pkderr("ssh_bind_options_set log verbosity: %s\n", ssh_get_error(b)); - goto outclose; - } - - s = ssh_new(); - if (s == NULL) { - pkderr("ssh_new\n"); - goto outclose; - } - - /* - * ssh_bind_accept loads host key as side-effect. If this - * succeeds, the given 'fd' will be closed upon 'ssh_free(s)'. - */ - rc = ssh_bind_accept_fd(b, s, fd); - if (rc != SSH_OK) { - pkderr("ssh_bind_accept_fd: %s\n", ssh_get_error(b)); - goto outclose; - } - - /* accept only publickey-based auth */ - ssh_set_auth_methods(s, SSH_AUTH_METHOD_PUBLICKEY); - - /* initialize callbacks */ - ssh_callbacks_init(&pkd_server_cb); - pkd_server_cb.userdata = &c; - rc = ssh_set_server_callbacks(s, &pkd_server_cb); - if (rc != SSH_OK) { - pkderr("ssh_set_server_callbacks: %s\n", ssh_get_error(s)); - goto out; - } - - /* first do key exchange */ - rc = ssh_handle_key_exchange(s); - if (rc != SSH_OK) { - pkderr("ssh_handle_key_exchange: %s\n", ssh_get_error(s)); - goto out; - } - - /* setup and pump event to carry out exec channel */ - e = ssh_event_new(); - if (e == NULL) { - pkderr("ssh_event_new\n"); - goto out; - } - - rc = ssh_event_add_session(e, s); - if (rc != SSH_OK) { - pkderr("ssh_event_add_session\n"); - goto out; - } - - /* poll until exec channel established */ - while ((ctx.keep_going != 0) && - (rc != SSH_ERROR) && (pkd_state.req_exec_received == 0)) { - rc = ssh_event_dopoll(e, -1 /* infinite timeout */); - } - - if (rc == SSH_ERROR) { - pkderr("ssh_event_dopoll\n"); - goto out; - } else if (c == NULL) { - pkderr("poll loop exited but exec channel not ready\n"); - rc = -1; - goto out; - } - - rc = ssh_channel_write(c, "hello\n", 6); /* XXX: customizable payloads */ - if (rc != 6) { - pkderr("ssh_channel_write partial (%d)\n", rc); - } - - rc = ssh_channel_request_send_exit_status(c, 0); - if (rc != SSH_OK) { - pkderr("ssh_channel_request_send_exit_status: %s\n", - ssh_get_error(s)); - goto out; - } - - rc = ssh_channel_send_eof(c); - if (rc != SSH_OK) { - pkderr("ssh_channel_send_eof: %s\n", ssh_get_error(s)); - goto out; - } - - rc = ssh_channel_close(c); - if (rc != SSH_OK) { - pkderr("ssh_channel_close: %s\n", ssh_get_error(s)); - goto out; - } - - while ((ctx.keep_going != 0) && - (pkd_state.eof_received == 0) && - (pkd_state.close_received == 0) && - (ssh_channel_is_closed(c) == 0)) { - rc = ssh_event_dopoll(e, 1000 /* milliseconds */); - if (rc == SSH_ERROR) { - pkderr("ssh_event_dopoll for eof + close: %s\n", ssh_get_error(s)); - break; - } else { - rc = 0; - } - } - goto out; - -outclose: - close(fd); -out: - if (c != NULL) { - ssh_channel_free(c); - } - if (e != NULL) { - ssh_event_remove_session(e, s); - ssh_event_free(e); - } - if (s != NULL) { - ssh_disconnect(s); - ssh_free(s); - } - if (b != NULL) { - ssh_bind_free(b); - } - return rc; -} - -/* - * main loop ------------------------------------------------------------ - */ - -static void *pkd_main(void *args) { - int rc = -1; - struct pkd_daemon_args *a = (struct pkd_daemon_args *) args; - - struct sigaction act = { .sa_handler = pkd_sighandler, }; - - pkd_state.server_fd = -1; - pkd_state.req_exec_received = 0; - pkd_state.close_received = 0; - pkd_state.eof_received = 0; - - /* SIGUSR1 is used to interrupt 'pkd_accept_fd'. */ - rc = sigaction(SIGUSR1, &act, NULL); - if (rc != 0) { - pkderr("sigaction: %d\n", rc); - goto out; - } - - rc = pkd_init_libssh(); - if (rc != 0) { - pkderr("pkd_init_libssh: %d\n", rc); - goto out; - } - - rc = pkd_init_server_fd(1234); - if (rc != 0) { - pkderr("pkd_init_server_fd: %d\n", rc); - goto out; - } - - ctx.pkd_ready = 1; - - while (ctx.keep_going != 0) { - int fd = pkd_accept_fd(); - if (fd < 0) { - if (ctx.keep_going != 0) { - pkderr("pkd_accept_fd"); - rc = -1; - } else { - rc = 0; - } - break; - } - - rc = pkd_exec_hello(fd, a); - if (rc != 0) { - pkderr("pkd_exec_hello: %d\n", rc); - break; - } - } - - close(pkd_state.server_fd); - pkd_state.server_fd = -1; -out: - ctx.rc = rc; - - return NULL; -} - -/* - * pkd start and stop used by setup/teardown test scaffolding ----------- - */ - -int pkd_start(struct pkd_daemon_args *args) { - int rc = 0; - - pkdout_enabled = args->opts.log_stdout; - pkderr_enabled = args->opts.log_stderr; - - /* Initialize the pkd context. */ - ctx.rc = -1; - ctx.keep_going = 1; - ctx.pkd_ready = 0; - rc = pthread_create(&ctx.tid, NULL, &pkd_main, args); - assert_int_equal(rc, 0); - - /* Busy-spin until pkd thread is ready. */ - while (ctx.pkd_ready == 0); - - return rc; -} - -void pkd_stop(struct pkd_result *out) { - int rc = 0; - - ctx.keep_going = 0; - - rc = pthread_kill(ctx.tid, SIGUSR1); - assert_int_equal(rc, 0); - - rc = pthread_join(ctx.tid, NULL); - assert_int_equal(rc, 0); - - assert_non_null(out); - out->ok = (ctx.rc == 0); - - return; -} diff --git a/libssh/tests/pkd/pkd_daemon.h b/libssh/tests/pkd/pkd_daemon.h deleted file mode 100644 index c42573c1..00000000 --- a/libssh/tests/pkd/pkd_daemon.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * pkd_daemon.h -- tests use this interface to start, stop pkd - * instances and get results - * - * (c) 2014 Jon Simons - */ - -#ifndef __PKD_DAEMON_H__ -#define __PKD_DAEMON_H__ - -enum pkd_hostkey_type_e { - PKD_RSA, - PKD_DSA, - PKD_ECDSA -}; - -struct pkd_daemon_args { - enum pkd_hostkey_type_e type; - const char *hostkeypath; - - struct { - int list; - - int log_stdout; - int log_stderr; - int libssh_log_level; - - const char *testname; - unsigned int iterations; - } opts; -}; - -struct pkd_result { - int ok; -}; - -int pkd_start(struct pkd_daemon_args *args); -void pkd_stop(struct pkd_result *out); - -#endif /* __PKD_DAEMON_H__ */ diff --git a/libssh/tests/pkd/pkd_hello.c b/libssh/tests/pkd/pkd_hello.c deleted file mode 100644 index 2183f897..00000000 --- a/libssh/tests/pkd/pkd_hello.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * pkd_hello.c -- - * - * (c) 2014 Jon Simons - */ - -#include // for cmocka -#include // for cmocka -#include -#include -#include // for cmocka -#include - -#include "libssh/priv.h" - -#include "pkd_client.h" -#include "pkd_daemon.h" -#include "pkd_keyutil.h" -#include "pkd_util.h" - -#define DEFAULT_ITERATIONS 10 -static struct pkd_daemon_args pkd_dargs; - -#ifdef HAVE_ARGP_H -#include -#define PROGNAME "pkd_hello" -#define ARGP_PROGNAME "libssh " PROGNAME -const char *argp_program_version = ARGP_PROGNAME " 2014-04-12"; -const char *argp_program_bug_address = "Jon Simons "; -//static char **cmdline; -static char doc[] = \ - "\nExample usage:\n\n" - " " PROGNAME "\n" - " Run all tests with default number of iterations.\n" - " " PROGNAME " --list\n" - " List available individual test names.\n" - " " PROGNAME " -i 1000 -t torture_pkd_rsa_ecdh_sha2_nistp256\n" - " Run only the torture_pkd_rsa_ecdh_sha2_nistp256 testcase 1000 times.\n" - " " PROGNAME " -v -v -v -v -e -o\n" - " Run all tests with maximum libssh and pkd logging.\n" -; - -static struct argp_option options[] = { - { "stderr", 'e', NULL, 0, - "Emit pkd stderr messages", 0 }, - { "list", 'l', NULL, 0, - "List available individual test names", 0 }, - { "iterations", 'i', "number", 0, - "Run each test for the given number of iterations (default is 10)", 0 }, - { "stdout", 'o', NULL, 0, - "Emit pkd stdout messages", 0 }, - { "test", 't', "testname", 0, - "Run tests matching the given testname", 0 }, - { "verbose", 'v', NULL, 0, - "Increase libssh verbosity (can be used multiple times)", 0 }, - { NULL, 0, NULL, 0, - NULL, 0 }, -}; - -static error_t parse_opt(int key, char *arg, struct argp_state *state) { - (void) arg; - (void) state; - - switch(key) { - case 'e': - pkd_dargs.opts.log_stderr = 1; - break; - case 'l': - pkd_dargs.opts.list = 1; - break; - case 'i': - pkd_dargs.opts.iterations = atoi(arg); - break; - case 'o': - pkd_dargs.opts.log_stdout = 1; - break; - case 't': - pkd_dargs.opts.testname = arg; - break; - case 'v': - pkd_dargs.opts.libssh_log_level += 1; - break; - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -static struct argp parser = { - options, - parse_opt, - NULL, - doc, - NULL, - NULL, - NULL -}; -#endif /* HAVE_ARGP_H */ - -static struct pkd_state *torture_pkd_setup(enum pkd_hostkey_type_e type, - const char *hostkeypath) { - int rc = 0; - - pkd_dargs.type = type; - pkd_dargs.hostkeypath = hostkeypath; - - rc = pkd_start(&pkd_dargs); - assert_int_equal(rc, 0); - - return NULL; -} - -static void torture_pkd_teardown(void **state) { - struct pkd_result result = { .ok = 0 }; - - (void) state; - - pkd_stop(&result); - assert_int_equal(result.ok, 1); -} - -/* - * one setup for each server keytype ------------------------------------ - */ - -static void torture_pkd_setup_noop(void **state) { - *state = (void *) torture_pkd_setup(PKD_RSA, NULL /*path*/); -} - -static void torture_pkd_setup_rsa(void **state) { - setup_rsa_key(); - *state = (void *) torture_pkd_setup(PKD_RSA, LIBSSH_RSA_TESTKEY); -} - -static void torture_pkd_setup_dsa(void **state) { - setup_dsa_key(); - *state = (void *) torture_pkd_setup(PKD_DSA, LIBSSH_DSA_TESTKEY); -} - -static void torture_pkd_setup_ecdsa_256(void **state) { - setup_ecdsa_keys(); - *state = (void *) torture_pkd_setup(PKD_ECDSA, LIBSSH_ECDSA_256_TESTKEY); -} - -static void torture_pkd_setup_ecdsa_384(void **state) { - setup_ecdsa_keys(); - *state = (void *) torture_pkd_setup(PKD_ECDSA, LIBSSH_ECDSA_384_TESTKEY); -} - -static void torture_pkd_setup_ecdsa_521(void **state) { - setup_ecdsa_keys(); - *state = (void *) torture_pkd_setup(PKD_ECDSA, LIBSSH_ECDSA_521_TESTKEY); -} - -/* - * Test matrices: f(clientname, testname, ssh-command, setup-function, teardown-function). - */ - -#define PKDTESTS_DEFAULT(f, client, cmd) \ - /* Default passes by server key type. */ \ - f(client, rsa_default, cmd, setup_rsa, teardown) \ - f(client, dsa_default, cmd, setup_dsa, teardown) \ - f(client, ecdsa_256_default, cmd, setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_default, cmd, setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_default, cmd, setup_ecdsa_521, teardown) - -#define PKDTESTS_KEX(f, client, kexcmd) \ - /* Kex algorithms. */ \ - f(client, rsa_curve25519_sha256, kexcmd("curve25519-sha256@libssh.org"), setup_rsa, teardown) \ - f(client, rsa_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256 "), setup_rsa, teardown) \ - f(client, rsa_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_rsa, teardown) \ - f(client, rsa_diffie_hellman_group1_sha1, kexcmd("diffie-hellman-group1-sha1"), setup_rsa, teardown) \ - f(client, dsa_curve25519_sha256, kexcmd("curve25519-sha256@libssh.org"), setup_dsa, teardown) \ - f(client, dsa_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256 "), setup_dsa, teardown) \ - f(client, dsa_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_dsa, teardown) \ - f(client, dsa_diffie_hellman_group1_sha1, kexcmd("diffie-hellman-group1-sha1"), setup_dsa, teardown) \ - f(client, ecdsa_256_curve25519_sha256, kexcmd("curve25519-sha256@libssh.org"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256 "), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_diffie_hellman_group1_sha1, kexcmd("diffie-hellman-group1-sha1"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_curve25519_sha256, kexcmd("curve25519-sha256@libssh.org"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256 "), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_diffie_hellman_group1_sha1, kexcmd("diffie-hellman-group1-sha1"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_curve25519_sha256, kexcmd("curve25519-sha256@libssh.org"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_ecdh_sha2_nistp256, kexcmd("ecdh-sha2-nistp256 "), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_diffie_hellman_group14_sha1, kexcmd("diffie-hellman-group14-sha1"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_diffie_hellman_group1_sha1, kexcmd("diffie-hellman-group1-sha1"), setup_ecdsa_521, teardown) - -#define PKDTESTS_CIPHER(f, client, ciphercmd) \ - /* Ciphers. */ \ - f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \ - f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \ - f(client, rsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_rsa, teardown) \ - f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \ - f(client, rsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_rsa, teardown) \ - f(client, rsa_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_rsa, teardown) \ - f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \ - f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \ - f(client, dsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_dsa, teardown) \ - f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \ - f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown) \ - f(client, dsa_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_dsa, teardown) \ - f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_521, teardown) - -#define PKDTESTS_CIPHER_AES192(f, client, ciphercmd) \ - /* Ciphers. */ \ - f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \ - f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \ - f(client, dsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_dsa, teardown) \ - f(client, dsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_dsa, teardown) \ - f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \ - f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) - -#define PKDTESTS_MAC(f, client, maccmd) \ - /* MACs. */ \ - f(client, rsa_hmac_sha1, maccmd("hmac-sha1"), setup_rsa, teardown) \ - f(client, dsa_hmac_sha1, maccmd("hmac-sha1"), setup_dsa, teardown) \ - f(client, ecdsa_256_hmac_sha1, maccmd("hmac-sha1"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_hmac_sha1, maccmd("hmac-sha1"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_hmac_sha1, maccmd("hmac-sha1"), setup_ecdsa_521, teardown) \ - f(client, rsa_hmac_sha2_256, maccmd("hmac-sha2-256"), setup_rsa, teardown) \ - f(client, dsa_hmac_sha2_256, maccmd("hmac-sha2-256"), setup_dsa, teardown) \ - f(client, ecdsa_256_hmac_sha2_256, maccmd("hmac-sha2-256"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_hmac_sha2_256, maccmd("hmac-sha2-256"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_hmac_sha2_256, maccmd("hmac-sha2-256"), setup_ecdsa_521, teardown) \ - f(client, rsa_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_rsa, teardown) \ - f(client, dsa_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_dsa, teardown) \ - f(client, ecdsa_256_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_ecdsa_256, teardown) \ - f(client, ecdsa_384_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_ecdsa_384, teardown) \ - f(client, ecdsa_521_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_ecdsa_521, teardown) - -static void torture_pkd_client_noop(void **state) { - struct pkd_state *pstate = (struct pkd_state *) (*state); - (void) pstate; - return; -} - -static void torture_pkd_runtest(const char *testname, - const char *testcmd) -{ - int i, rc; - char logfile[1024] = { 0 }; - int iterations = - (pkd_dargs.opts.iterations != 0) ? pkd_dargs.opts.iterations - : DEFAULT_ITERATIONS; - - for (i = 0; i < iterations; i++) { - rc = system_checked(testcmd); - assert_int_equal(rc, 0); - } - - /* Asserts did not trip: cleanup logs. */ - snprintf(&logfile[0], sizeof(logfile), "%s.out", testname); - unlink(logfile); - snprintf(&logfile[0], sizeof(logfile), "%s.err", testname); - unlink(logfile); -} - -/* - * Though each keytest function body is the same, separate functions are - * defined here to result in distinct output when running the tests. - */ - -#define emit_keytest(client, testname, sshcmd, setup, teardown) \ - static void torture_pkd_## client ## _ ## testname(void **state) { \ - const char *tname = "torture_pkd_" #client "_" #testname; \ - char testcmd[1024] = { 0 }; \ - (void) state; \ - snprintf(&testcmd[0], sizeof(testcmd), sshcmd, tname, tname); \ - torture_pkd_runtest(tname, testcmd); \ - } - -/* - * Actual test functions are emitted here. - */ - -#define CLIENT_ID_FILE OPENSSH_DSA_TESTKEY -PKDTESTS_DEFAULT(emit_keytest, openssh_dsa, OPENSSH_CMD) -PKDTESTS_KEX(emit_keytest, openssh_dsa, OPENSSH_KEX_CMD) -PKDTESTS_CIPHER(emit_keytest, openssh_dsa, OPENSSH_CIPHER_CMD) -PKDTESTS_CIPHER_AES192(emit_keytest, openssh_dsa, OPENSSH_CIPHER_CMD) -PKDTESTS_MAC(emit_keytest, openssh_dsa, OPENSSH_MAC_CMD) -#undef CLIENT_ID_FILE - -#define CLIENT_ID_FILE OPENSSH_RSA_TESTKEY -PKDTESTS_DEFAULT(emit_keytest, openssh_rsa, OPENSSH_CMD) -PKDTESTS_KEX(emit_keytest, openssh_rsa, OPENSSH_KEX_CMD) -PKDTESTS_CIPHER(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD) -PKDTESTS_CIPHER_AES192(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD) -PKDTESTS_MAC(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD) -#undef CLIENT_ID_FILE - -#define CLIENT_ID_FILE OPENSSH_ECDSA256_TESTKEY -PKDTESTS_DEFAULT(emit_keytest, openssh_e256, OPENSSH_CMD) -PKDTESTS_KEX(emit_keytest, openssh_e256, OPENSSH_KEX_CMD) -PKDTESTS_CIPHER(emit_keytest, openssh_e256, OPENSSH_CIPHER_CMD) -PKDTESTS_CIPHER_AES192(emit_keytest, openssh_e256, OPENSSH_CIPHER_CMD) -PKDTESTS_MAC(emit_keytest, openssh_e256, OPENSSH_MAC_CMD) -#undef CLIENT_ID_FILE - -/* Could add these passes, too: */ -//#define CLIENT_ID_FILE OPENSSH_ECDSA384_TESTKEY -//#define CLIENT_ID_FILE OPENSSH_ECDSA521_TESTKEY - -#define CLIENT_ID_FILE OPENSSH_ED25519_TESTKEY -PKDTESTS_DEFAULT(emit_keytest, openssh_ed, OPENSSH_CMD) -PKDTESTS_KEX(emit_keytest, openssh_ed, OPENSSH_KEX_CMD) -PKDTESTS_CIPHER(emit_keytest, openssh_ed, OPENSSH_CIPHER_CMD) -PKDTESTS_CIPHER_AES192(emit_keytest, openssh_ed, OPENSSH_CIPHER_CMD) -PKDTESTS_MAC(emit_keytest, openssh_ed, OPENSSH_MAC_CMD) -#undef CLIENT_ID_FILE - -#define CLIENT_ID_FILE DROPBEAR_RSA_TESTKEY -PKDTESTS_DEFAULT(emit_keytest, dropbear, DROPBEAR_CMD) -PKDTESTS_CIPHER(emit_keytest, dropbear, DROPBEAR_CIPHER_CMD) -PKDTESTS_MAC(emit_keytest, dropbear, DROPBEAR_MAC_CMD) -#undef CLIENT_ID_FILE - -/* - * Define an array of testname strings mapped to their associated - * test function. Enables running tests individually by name from - * the command line. - */ - -#define emit_testmap(client, testname, sshcmd, setup, teardown) \ - { "torture_pkd_" #client "_" #testname, \ - { emit_unit_test(client, testname, sshcmd, setup, teardown) } }, - -#define emit_unit_test(client, testname, sshcmd, setup, teardown) \ - unit_test_setup_teardown(torture_pkd_ ## client ## _ ## testname, \ - torture_pkd_ ## setup, \ - torture_pkd_ ## teardown) - -#define emit_unit_test_comma(client, testname, sshcmd, setup, teardown) \ - emit_unit_test(client, testname, sshcmd, setup, teardown), - -struct { - const char *testname; - const UnitTest test[3]; /* requires setup + test + teardown */ -} testmap[] = { - /* OpenSSH */ - PKDTESTS_DEFAULT(emit_testmap, openssh_dsa, OPENSSH_CMD) - PKDTESTS_KEX(emit_testmap, openssh_dsa, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_testmap, openssh_dsa, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_testmap, openssh_dsa, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_testmap, openssh_dsa, OPENSSH_MAC_CMD) - - PKDTESTS_DEFAULT(emit_testmap, openssh_rsa, OPENSSH_CMD) - PKDTESTS_KEX(emit_testmap, openssh_rsa, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_testmap, openssh_rsa, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_testmap, openssh_rsa, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD) - - PKDTESTS_DEFAULT(emit_testmap, openssh_e256, OPENSSH_CMD) - PKDTESTS_KEX(emit_testmap, openssh_e256, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_testmap, openssh_e256, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_testmap, openssh_e256, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_testmap, openssh_e256, OPENSSH_MAC_CMD) - - PKDTESTS_DEFAULT(emit_testmap, openssh_ed, OPENSSH_CMD) - PKDTESTS_KEX(emit_testmap, openssh_ed, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_testmap, openssh_ed, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_testmap, openssh_ed, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_testmap, openssh_ed, OPENSSH_MAC_CMD) - - /* Dropbear */ - PKDTESTS_DEFAULT(emit_testmap, dropbear, DROPBEAR_CMD) - PKDTESTS_CIPHER(emit_testmap, dropbear, DROPBEAR_CIPHER_CMD) - PKDTESTS_MAC(emit_testmap, dropbear, DROPBEAR_MAC_CMD) - - /* Noop */ - emit_testmap(client, noop, "", setup_noop, teardown) - - /* NULL tail entry */ - { NULL, { { NULL, NULL, 0 }, { NULL, NULL, 0 }, { NULL, NULL, 0 } } } -}; - -static int pkd_run_tests(void) { - int rc = -1; - int tindex = 0; - - const UnitTest openssh_tests[] = { - PKDTESTS_DEFAULT(emit_unit_test_comma, openssh_dsa, OPENSSH_CMD) - PKDTESTS_KEX(emit_unit_test_comma, openssh_dsa, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_unit_test_comma, openssh_dsa, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_unit_test_comma, openssh_dsa, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_unit_test_comma, openssh_dsa, OPENSSH_MAC_CMD) - - PKDTESTS_DEFAULT(emit_unit_test_comma, openssh_rsa, OPENSSH_CMD) - PKDTESTS_KEX(emit_unit_test_comma, openssh_rsa, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_unit_test_comma, openssh_rsa, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_unit_test_comma, openssh_rsa, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_unit_test_comma, openssh_rsa, OPENSSH_MAC_CMD) - - PKDTESTS_DEFAULT(emit_unit_test_comma, openssh_e256, OPENSSH_CMD) - PKDTESTS_KEX(emit_unit_test_comma, openssh_e256, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_unit_test_comma, openssh_e256, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_unit_test_comma, openssh_e256, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_unit_test_comma, openssh_e256, OPENSSH_MAC_CMD) - - PKDTESTS_DEFAULT(emit_unit_test_comma, openssh_ed, OPENSSH_CMD) - PKDTESTS_KEX(emit_unit_test_comma, openssh_ed, OPENSSH_KEX_CMD) - PKDTESTS_CIPHER(emit_unit_test_comma, openssh_ed, OPENSSH_CIPHER_CMD) - PKDTESTS_CIPHER_AES192(emit_unit_test_comma, openssh_ed, OPENSSH_CIPHER_CMD) - PKDTESTS_MAC(emit_unit_test_comma, openssh_ed, OPENSSH_MAC_CMD) - }; - - const UnitTest dropbear_tests[] = { - PKDTESTS_DEFAULT(emit_unit_test_comma, dropbear, DROPBEAR_CMD) - PKDTESTS_CIPHER(emit_unit_test_comma, dropbear, DROPBEAR_CIPHER_CMD) - PKDTESTS_MAC(emit_unit_test_comma, dropbear, DROPBEAR_MAC_CMD) - }; - - const UnitTest noop_tests[] = { - emit_unit_test(client, noop, "", setup_noop, teardown) - }; - - /* Test list is populated depending on which clients are enabled. */ - UnitTest all_tests[(sizeof(openssh_tests) / sizeof(openssh_tests[0])) + - (sizeof(dropbear_tests) / sizeof(dropbear_tests[0])) + - (sizeof(noop_tests) / sizeof(noop_tests[0]))]; - memset(&all_tests[0], 0x0, sizeof(all_tests)); - - /* Generate client keys and populate test list for each enabled client. */ - if (is_openssh_client_enabled()) { - setup_openssh_client_keys(); - memcpy(&all_tests[tindex], &openssh_tests[0], sizeof(openssh_tests)); - tindex += (sizeof(openssh_tests) / sizeof(openssh_tests[0])); - } - - if (is_dropbear_client_enabled()) { - setup_dropbear_client_rsa_key(); - memcpy(&all_tests[tindex], &dropbear_tests[0], sizeof(dropbear_tests)); - tindex += (sizeof(dropbear_tests) / sizeof(dropbear_tests[0])); - } - - memcpy(&all_tests[tindex], &noop_tests[0], sizeof(noop_tests)); - tindex += (sizeof(noop_tests) / sizeof(noop_tests[0])); - - if (pkd_dargs.opts.testname == NULL) { - rc = _run_tests(all_tests, tindex); - } else { - int i = 0; - const UnitTest *found = NULL; - const char *testname = pkd_dargs.opts.testname; - - while (testmap[i].testname != NULL) { - if (strcmp(testmap[i].testname, testname) == 0) { - found = &testmap[i].test[0]; - break; - } - i += 1; - } - - if (found != NULL) { - rc = _run_tests(found, 3); - } else { - fprintf(stderr, "Did not find test '%s'\n", testname); - } - } - - /* Clean up client keys for each enabled client. */ - if (is_dropbear_client_enabled()) { - cleanup_dropbear_client_rsa_key(); - } - - if (is_openssh_client_enabled()) { - cleanup_openssh_client_keys(); - } - - /* Clean up any server keys that were generated. */ - cleanup_rsa_key(); - cleanup_dsa_key(); - cleanup_ecdsa_keys(); - - return rc; -} - -int main(int argc, char **argv) { - int i = 0; - int rc = 0; - - unsetenv("SSH_AUTH_SOCK"); - - rc = ssh_init(); - if (rc != 0) { - rc = SSH_ERROR; - goto out; - } - -#ifdef HAVE_ARGP_H - argp_parse(&parser, argc, argv, 0, 0, NULL); -#else /* HAVE_ARGP_H */ - (void) argc; (void) argv; -#endif /* HAVE_ARGP_H */ - - if (pkd_dargs.opts.list != 0) { - while (testmap[i].testname != NULL) { - printf("%s\n", testmap[i++].testname); - } - } else { - rc = pkd_run_tests(); - } - - rc = ssh_finalize(); - if (rc != 0) { - fprintf(stderr, "ssh_finalize: %d\n", rc); - } -out: - return rc; -} diff --git a/libssh/tests/pkd/pkd_keyutil.c b/libssh/tests/pkd/pkd_keyutil.c deleted file mode 100644 index e1e1ecb8..00000000 --- a/libssh/tests/pkd/pkd_keyutil.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * pkd_keyutil.c -- pkd test key utilities - * - * (c) 2014 Jon Simons - */ - -#include // for cmocka -#include // for cmocka -#include // for cmocka -#include - -#include -#include -#include -#include - -#include "pkd_client.h" -#include "pkd_keyutil.h" -#include "pkd_util.h" - -void setup_rsa_key() { - int rc = 0; - if (access(LIBSSH_RSA_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t rsa -q -N \"\" -f " - LIBSSH_RSA_TESTKEY); - } - assert_int_equal(rc, 0); -} - -void setup_dsa_key() { - int rc = 0; - if (access(LIBSSH_DSA_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t dsa -q -N \"\" -f " - LIBSSH_DSA_TESTKEY); - } - assert_int_equal(rc, 0); -} - -void setup_ecdsa_keys() { - int rc = 0; - - if (access(LIBSSH_ECDSA_256_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ecdsa -b 256 -q -N \"\" -f " - LIBSSH_ECDSA_256_TESTKEY); - assert_int_equal(rc, 0); - } - if (access(LIBSSH_ECDSA_384_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ecdsa -b 384 -q -N \"\" -f " - LIBSSH_ECDSA_384_TESTKEY); - assert_int_equal(rc, 0); - } - if (access(LIBSSH_ECDSA_521_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ecdsa -b 521 -q -N \"\" -f " - LIBSSH_ECDSA_521_TESTKEY); - assert_int_equal(rc, 0); - } -} - -static void cleanup_key(const char *privkey, const char *pubkey) { - unlink(privkey); - unlink(pubkey); -} - -void cleanup_rsa_key() { - cleanup_key(LIBSSH_RSA_TESTKEY, LIBSSH_RSA_TESTKEY ".pub"); -} - -void cleanup_dsa_key() { - cleanup_key(LIBSSH_DSA_TESTKEY, LIBSSH_DSA_TESTKEY ".pub"); -} - -void cleanup_ecdsa_keys() { - cleanup_key(LIBSSH_ECDSA_256_TESTKEY, LIBSSH_ECDSA_256_TESTKEY ".pub"); - cleanup_key(LIBSSH_ECDSA_384_TESTKEY, LIBSSH_ECDSA_384_TESTKEY ".pub"); - cleanup_key(LIBSSH_ECDSA_521_TESTKEY, LIBSSH_ECDSA_521_TESTKEY ".pub"); -} - -void setup_openssh_client_keys() { - int rc = 0; - - if (access(OPENSSH_DSA_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t dsa -q -N \"\" -f " - OPENSSH_DSA_TESTKEY); - } - assert_int_equal(rc, 0); - - if (access(OPENSSH_RSA_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t rsa -q -N \"\" -f " - OPENSSH_RSA_TESTKEY); - } - assert_int_equal(rc, 0); - - if (access(OPENSSH_ECDSA256_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ecdsa -b 256 -q -N \"\" -f " - OPENSSH_ECDSA256_TESTKEY); - } - assert_int_equal(rc, 0); - - if (access(OPENSSH_ECDSA384_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ecdsa -b 384 -q -N \"\" -f " - OPENSSH_ECDSA384_TESTKEY); - } - assert_int_equal(rc, 0); - - if (access(OPENSSH_ECDSA521_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ecdsa -b 521 -q -N \"\" -f " - OPENSSH_ECDSA521_TESTKEY); - } - assert_int_equal(rc, 0); - - if (access(OPENSSH_ED25519_TESTKEY, F_OK) != 0) { - rc = system_checked(OPENSSH_KEYGEN " -t ed25519 -q -N \"\" -f " - OPENSSH_ED25519_TESTKEY); - } - assert_int_equal(rc, 0); -} - -void cleanup_openssh_client_keys() { - cleanup_key(OPENSSH_DSA_TESTKEY, OPENSSH_DSA_TESTKEY ".pub"); - cleanup_key(OPENSSH_RSA_TESTKEY, OPENSSH_RSA_TESTKEY ".pub"); - cleanup_key(OPENSSH_ECDSA256_TESTKEY, OPENSSH_ECDSA256_TESTKEY ".pub"); - cleanup_key(OPENSSH_ECDSA384_TESTKEY, OPENSSH_ECDSA384_TESTKEY ".pub"); - cleanup_key(OPENSSH_ECDSA521_TESTKEY, OPENSSH_ECDSA521_TESTKEY ".pub"); - cleanup_key(OPENSSH_ED25519_TESTKEY, OPENSSH_ED25519_TESTKEY ".pub"); -} - -void setup_dropbear_client_rsa_key() { - int rc = 0; - if (access(DROPBEAR_RSA_TESTKEY, F_OK) != 0) { - rc = system_checked(DROPBEAR_KEYGEN " -t rsa -f " - DROPBEAR_RSA_TESTKEY " 1>/dev/null 2>/dev/null"); - } - assert_int_equal(rc, 0); -} - -void cleanup_dropbear_client_rsa_key() { - unlink(DROPBEAR_RSA_TESTKEY); -} diff --git a/libssh/tests/pkd/pkd_keyutil.h b/libssh/tests/pkd/pkd_keyutil.h deleted file mode 100644 index 8e9de009..00000000 --- a/libssh/tests/pkd/pkd_keyutil.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * pkd_keyutil.h -- - * - * (c) 2014 Jon Simons - */ - -#ifndef __PKD_KEYUTIL_H__ -#define __PKD_KEYUTIL_H__ - -/* Server keys. */ -#define LIBSSH_DSA_TESTKEY "libssh_testkey.id_dsa" -#define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa" -#define LIBSSH_ECDSA_256_TESTKEY "libssh_testkey.id_ecdsa256" -#define LIBSSH_ECDSA_384_TESTKEY "libssh_testkey.id_ecdsa384" -#define LIBSSH_ECDSA_521_TESTKEY "libssh_testkey.id_ecdsa521" - -void setup_dsa_key(void); -void setup_rsa_key(void); -void setup_ecdsa_keys(void); -void cleanup_dsa_key(void); -void cleanup_rsa_key(void); -void cleanup_ecdsa_keys(void); - -/* Client keys. */ -#define OPENSSH_DSA_TESTKEY "openssh_testkey.id_dsa" -#define OPENSSH_RSA_TESTKEY "openssh_testkey.id_rsa" -#define OPENSSH_ECDSA256_TESTKEY "openssh_testkey.id_ecdsa256" -#define OPENSSH_ECDSA384_TESTKEY "openssh_testkey.id_ecdsa384" -#define OPENSSH_ECDSA521_TESTKEY "openssh_testkey.id_ecdsa521" -#define OPENSSH_ED25519_TESTKEY "openssh_testkey.id_ed25519" - -#define DROPBEAR_RSA_TESTKEY "dropbear_testkey.id_rsa" - -void setup_openssh_client_keys(void); -void cleanup_openssh_client_keys(void); - -void setup_dropbear_client_rsa_key(void); -void cleanup_dropbear_client_rsa_key(void); - -#endif /* __PKD_KEYUTIL_H__ */ diff --git a/libssh/tests/pkd/pkd_util.c b/libssh/tests/pkd/pkd_util.c deleted file mode 100644 index 963b58d6..00000000 --- a/libssh/tests/pkd/pkd_util.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * pkd_util.c -- pkd utilities - * - * (c) 2014 Jon Simons - */ - -#include -#include -#include -#include - -#include "pkd_client.h" -#include "pkd_util.h" - -/** - * @brief runs system(3); exits if that is interrupted with SIGINT/QUIT - * @returns 0 upon success, non-zero otherwise - */ -int system_checked(const char *cmd) { - int rc = system(cmd); - - if (WIFSIGNALED(rc) && - ((WTERMSIG(rc) == SIGINT) || (WTERMSIG(rc) == SIGQUIT))) { - exit(1); - } - - if (rc == -1) { - return -1; - } - - return WEXITSTATUS(rc); -} - -static int bin_exists(const char *binary) { - char bin[1024] = { 0 }; - snprintf(&bin[0], sizeof(bin), "type %s 1>/dev/null 2>/dev/null", binary); - return (system_checked(bin) == 0); -} - -int is_openssh_client_enabled(void) { - return (bin_exists(OPENSSH_BINARY) && bin_exists(OPENSSH_KEYGEN)); -} - -int is_dropbear_client_enabled(void) { - return (bin_exists(DROPBEAR_BINARY) && bin_exists(DROPBEAR_KEYGEN)); -} diff --git a/libssh/tests/pkd/pkd_util.h b/libssh/tests/pkd/pkd_util.h deleted file mode 100644 index aedbbe9f..00000000 --- a/libssh/tests/pkd/pkd_util.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * pkd_keyutil.h -- - * - * (c) 2014 Jon Simons - */ - -#ifndef __PKD_UTIL_H__ -#define __PKD_UTIL_H__ - -int system_checked(const char *cmd); - -/* Is client 'X' enabled? */ -int is_openssh_client_enabled(void); -int is_dropbear_client_enabled(void); - -#endif /* __PKD_UTIL_H__ */ diff --git a/libssh/tests/sftp_stress/main.c b/libssh/tests/sftp_stress/main.c deleted file mode 100644 index c9b0ad9f..00000000 --- a/libssh/tests/sftp_stress/main.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * main.c - * - * Created on: 22 juin 2009 - * Author: aris - */ -#include -#include -#include -#include -#include -#include -#include -#include -#define TEST_READ 1 -#define TEST_WRITE 2 -#define NTHREADS 3 -#define FILESIZE 100000 -unsigned char samplefile[FILESIZE]; -volatile int stop=0; - -const char* hosts[]={"localhost","barebone"}; -void signal_stop(){ - stop=1; - printf("Stopping...\n"); -} - -SSH_SESSION *connect_host(const char *hostname); -int sftp_test(SSH_SESSION *session, int test); - -int docycle(const char *host, int test){ - SSH_SESSION *session=connect_host(host); - int ret=SSH_ERROR; - if(!session){ - printf("connect failed\n"); - } else { - printf("Connected\n"); - ret=sftp_test(session,test); - if(ret != SSH_OK){ - printf("Error in sftp\n"); - } - ssh_disconnect(session); - } - return ret; -} - -int thread(){ - while(docycle(hosts[rand()%2],TEST_WRITE) == SSH_OK) - if(stop) - break; - return 0; -} - -int main(int argc, char **argv){ - int i; - pthread_t threads[NTHREADS]; - ssh_init(); - srand(time(NULL)); - for(i=0;i -#include -#include -#include "tests.h" - -void do_connect(SSH_SESSION *session) { - char buf[4096] = {0}; - CHANNEL *channel; - - int error = ssh_connect(session); - if (error != SSH_OK) { - fprintf(stderr,"Error at connection: %s\n", ssh_get_error(session)); - return; - } - printf("Connected\n"); - - ssh_is_server_known(session); - - error = authenticate(session); - if(error != SSH_AUTH_SUCCESS) { - fprintf(stderr,"Error at authentication: %s\n", ssh_get_error(session)); - return; - } - printf("Authenticated\n"); - channel = ssh_channel_new(session); - ssh_channel_open_session(channel); - printf("Execute 'ls' on the channel\n"); - error = ssh_channel_request_exec(channel, "ls"); - if(error != SSH_OK){ - fprintf(stderr, "Error executing command: %s\n", ssh_get_error(session)); - return; - } - printf("--------------------output----------------------\n"); - while (ssh_channel_read(channel, buf, sizeof(buf), 0)) { - printf("%s", buf); - } - printf("\n"); - printf("---------------------end------------------------\n"); - ssh_channel_send_eof(channel); - fprintf(stderr, "Exit status: %d\n", ssh_channel_get_exit_status(channel)); - - printf("\nChannel test finished\n"); - ssh_channel_close(channel); - ssh_channel_free(channel); -} - -int main(int argc, char **argv){ - SSH_OPTIONS *options=set_opts(argc, argv); - SSH_SESSION *session=ssh_new(); - if(options==NULL){ - return 1; - } - ssh_set_options(session,options); - do_connect(session); - ssh_disconnect(session); - ssh_finalize(); - return 0; -} diff --git a/libssh/tests/test_pcap.c b/libssh/tests/test_pcap.c deleted file mode 100644 index 01aa714a..00000000 --- a/libssh/tests/test_pcap.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* Simple test for the pcap functions */ - -#include -#include -#include - -#include -#include -#include - -int main(int argc, char **argv){ - ssh_pcap_file pcap; - ssh_pcap_context ctx; - ssh_buffer buffer=ssh_buffer_new(); - char *str="Hello, this is a test string to test the capabilities of the" - "pcap file writer."; - printf("Simple pcap tester\n"); - pcap=ssh_pcap_file_new(); - if(ssh_pcap_file_open(pcap,"test.cap") != SSH_OK){ - printf("error happened\n"); - return EXIT_FAILURE; - } - buffer_add_data(buffer,str,strlen(str)); - ctx=ssh_pcap_context_new(NULL); - ssh_pcap_context_set_file(ctx,pcap); - ssh_pcap_context_write(ctx,SSH_PCAP_DIR_OUT,str,strlen(str),strlen(str)); - - return EXIT_SUCCESS; -} diff --git a/libssh/tests/test_socket.c b/libssh/tests/test_socket.c deleted file mode 100644 index 84f7b35e..00000000 --- a/libssh/tests/test_socket.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2009 by Aris Adamantiadis - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* Simple test for the socket callbacks */ - -#include -#include -#include -#include - -#include -#include -#include - -int stop=0; -ssh_socket s; - -static int data_rcv(const void *data, size_t len, void *user){ - printf("Received data: '"); - fwrite(data,1,len,stdout); - printf("'\n"); - ssh_socket_write(s,"Hello you !\n",12); - ssh_socket_nonblocking_flush(s); - return len; -} - -static void controlflow(int code,void *user){ - printf("Control flow: %x\n",code); -} - -static void exception(int code, int errno_code,void *user){ - printf("Exception: %d (%d)\n",code,errno_code); - stop=1; -} - -static void connected(int code, int errno_code,void *user){ - if(code == SSH_SOCKET_CONNECTED_OK) - printf("Connected: %d (%d)\n",code, errno_code); - else { - printf("Error while connecting:(%d, %d:%s)\n",code,errno_code,strerror(errno_code)); - stop=1; - } -} - -struct ssh_socket_callbacks_struct callbacks={ - data_rcv, - controlflow, - exception, - connected, - NULL -}; -int main(int argc, char **argv){ - ssh_session session; - ssh_poll_ctx ctx; - int verbosity=SSH_LOG_FUNCTIONS; - if(argc < 3){ - printf("Usage : %s host port\n", argv[0]); - return EXIT_FAILURE; - } - session=ssh_new(); - ssh_options_set(session,SSH_OPTIONS_LOG_VERBOSITY,&verbosity); - ssh_init(); - s=ssh_socket_new(session); - ctx=ssh_poll_ctx_new(2); - ssh_socket_set_callbacks(s, &callbacks); - ssh_poll_ctx_add_socket(ctx,s); - if(ssh_socket_connect(s,argv[1],atoi(argv[2]),NULL) != SSH_OK){ - printf("ssh_socket_connect: %s\n",ssh_get_error(session)); - return EXIT_FAILURE; - } - while(!stop) - ssh_poll_ctx_dopoll(ctx,-1); - printf("finished\n"); - return EXIT_SUCCESS; -} diff --git a/libssh/tests/test_ssh_bind_accept_fd.c b/libssh/tests/test_ssh_bind_accept_fd.c deleted file mode 100644 index 7611cf4c..00000000 --- a/libssh/tests/test_ssh_bind_accept_fd.c +++ /dev/null @@ -1,139 +0,0 @@ -/* Test the ability to use ssh_bind_accept_fd. - * - * Expected behavior: Prints "SUCCESS!" - * - * Faulty behavior observed before change: Connection timeout - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct options { - const char *server_keyfile; -} options; - -const char HOST[] = "127.0.0.1"; -const int PORT = 3333; - -int get_connection() { - int rc, server_socket, client_conn = -1; - struct sockaddr_in server_socket_addr; - struct sockaddr_storage client_conn_addr; - socklen_t client_conn_addr_size = sizeof(client_conn_addr); - - server_socket = socket(PF_INET, SOCK_STREAM, 0); - if (server_socket < 0) { - goto out; - } - - server_socket_addr.sin_family = AF_INET; - server_socket_addr.sin_port = htons(PORT); - if (inet_pton(AF_INET, HOST, &server_socket_addr.sin_addr) != 1) { - goto out; - } - - rc = bind(server_socket, (struct sockaddr *)&server_socket_addr, - sizeof(server_socket_addr)); - if (rc < 0) { - goto out; - } - - if (listen(server_socket, 0) < 0) { - goto out; - } - - client_conn = accept(server_socket, - (struct sockaddr *)&client_conn_addr, - &client_conn_addr_size); - - out: - return client_conn; -} - -void ssh_server() { - ssh_bind bind; - ssh_session session; - - int client_conn = get_connection(); - if (client_conn < 0) { - err(1, "get_connection"); - } - - bind = ssh_bind_new(); - if (!bind) { - errx(1, "ssh_bind_new"); - } - - if (ssh_bind_options_set(bind, SSH_BIND_OPTIONS_DSAKEY, - options.server_keyfile) != SSH_OK) { - errx(1, "ssh_bind_options_set(SSH_BIND_OPTIONS_DSAKEY"); - } - - session = ssh_new(); - if (!session) { - errx(1, "ssh_new"); - } - - if (ssh_bind_accept_fd(bind, session, client_conn) != SSH_OK) { - errx(1, "ssh_bind_accept: %s", ssh_get_error(bind)); - } - - if (ssh_handle_key_exchange(session) != SSH_OK) { - errx(1, "ssh_handle_key_exchange: %s", ssh_get_error(session)); - } - - printf("SUCCESS!\n"); -} - -void ssh_client() { - ssh_session session; - - session = ssh_new(); - if (!session) { - errx(1, "ssh_new"); - } - - if (ssh_options_set(session, SSH_OPTIONS_HOST, HOST) < 0) { - errx(1, "ssh_options_set(SSH_OPTIONS_HOST)"); - } - if (ssh_options_set(session, SSH_OPTIONS_PORT, &PORT) < 0) { - errx(1, "ssh_options_set(SSH_OPTIONS_PORT)"); - } - - if (ssh_connect(session) != SSH_OK) { - errx(1, "ssh_connect: %s", ssh_get_error(session)); - } -} - -int main(int argc, const char *argv[]) { - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - exit(1); - } - - options.server_keyfile = argv[1]; - - pid_t pid = fork(); - if (pid < 0) { - errx(1, "fork"); - } - if (pid == 0) { - /* Allow the server to get set up */ - sleep(3); - - ssh_client(); - } else { - ssh_server(); - } - - return 0; -} diff --git a/libssh/tests/test_tunnel.c b/libssh/tests/test_tunnel.c deleted file mode 100644 index 27f667b7..00000000 --- a/libssh/tests/test_tunnel.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -This file is distributed in public domain. You can do whatever you want -with its content. -*/ -#include -#include -#include -#include "tests.h" -#define ECHO_PORT 7 -void do_connect(SSH_SESSION *session){ - int error=ssh_connect(session); - if(error != SSH_OK){ - fprintf(stderr,"Error at connection :%s\n",ssh_get_error(session)); - return; - } - printf("Connected\n"); - ssh_is_server_known(session); - // we don't care what happens here - error=authenticate(session); - if(error != SSH_AUTH_SUCCESS){ - fprintf(stderr,"Error at authentication :%s\n",ssh_get_error(session)); - return; - } - printf("Authenticated\n"); - CHANNEL *channel=ssh_channel_new(session); - error=ssh_channel_open_forward(channel,"localhost",ECHO_PORT,"localhost",42); - if(error!=SSH_OK){ - fprintf(stderr,"Error when opening forward:%s\n",ssh_get_error(session)); - return; - } - printf("Forward opened\n"); - int i=0; - char string[20]; - char buffer[20]; - for(i=0;i<2000;++i){ - sprintf(string,"%d\n",i); - ssh_channel_write(channel,string,strlen(string)); - do { - error=ssh_channel_poll(channel,0); - //if(error < strlen(string)) - //usleep(10); - } while(error < strlen(string) && error >= 0); - if(error>0){ - error=ssh_channel_read_nonblocking(channel,buffer,strlen(string),0); - if(error>=0){ - if(memcmp(buffer,string,strlen(string))!=0){ - fprintf(stderr,"Problem with answer: wanted %s got %s\n",string,buffer); - } else { - printf("."); - fflush(stdout); - } - } - - } - if(error==-1){ - fprintf(stderr,"Channel reading error : %s\n",ssh_get_error(session)); - break; - } - } - printf("\nChannel test finished\n"); - ssh_channel_close(channel); - ssh_channel_free(channel); -} - -int main(int argc, char **argv){ - SSH_OPTIONS *options=set_opts(argc, argv); - SSH_SESSION *session=ssh_new(); - if(options==NULL){ - return 1; - } - ssh_set_options(session,options); - do_connect(session); - ssh_disconnect(session); - ssh_finalize(); - return 0; -} diff --git a/libssh/tests/tests.h b/libssh/tests/tests.h deleted file mode 100644 index dd001f1f..00000000 --- a/libssh/tests/tests.h +++ /dev/null @@ -1,8 +0,0 @@ -/* -This file is distributed in public domain. You can do whatever you want -with its content. -*/ -#include -int authenticate (SSH_SESSION *session); -SSH_OPTIONS *set_opts(int argc, char **argv); - diff --git a/libssh/tests/torture.c b/libssh/tests/torture.c deleted file mode 100644 index 0b8eb3da..00000000 --- a/libssh/tests/torture.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * torture.c - torture library for testing libssh - * - * This file is part of the SSH Library - * - * Copyright (c) 2008-2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# include -# include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "torture.h" - -#define TORTURE_TESTKEY_PASSWORD "libssh-rocks" - -static const char torture_rsa_testkey[] = - "-----BEGIN RSA PRIVATE KEY-----\n" - "MIIEowIBAAKCAQEArAOREUWlBXJAKZ5hABYyxnRayDZP1bJeLbPVK+npxemrhHyZ\n" - "gjdbY3ADot+JRyWjvll2w2GI+3blt0j+x/ZWwjMKu/QYcycYp5HL01goxOxuusZb\n" - "i+KiHRGB6z0EMdXM7U82U7lA/j//HyZppyDjUDniWabXQJge8ksGXGTiFeAJ/687\n" - "uV+JJcjGPxAGFQxzyjitf/FrL9S0WGKZbyqeGDzyeBZ1NLIuaiOORyLGSW4duHLD\n" - "N78EmsJnwqg2gJQmRSaD4BNZMjtbfiFcSL9Uw4XQFTsWugUDEY1AU4c5g11nhzHz\n" - "Bi9qMOt5DzrZQpD4j0gA2LOHpHhoOdg1ZuHrGQIDAQABAoIBAFJTaqy/jllq8vZ4\n" - "TKiD900wBvrns5HtSlHJTe80hqQoT+Sa1cWSxPR0eekL32Hjy9igbMzZ83uWzh7I\n" - "mtgNODy9vRdznfgO8CfTCaBfAzQsjFpr8QikMT6EUI/LpiRL1UaGsNOlSEvnSS0Z\n" - "b1uDzAdrjL+nsEHEDJud+K9jwSkCRifVMy7fLfaum+YKpdeEz7K2Mgm5pJ/Vg+9s\n" - "vI2V1q7HAOI4eUVTgJNHXy5ediRJlajQHf/lNUzHKqn7iH+JRl01gt62X8roG62b\n" - "TbFylbheqMm9awuSF2ucOcx+guuwhkPir8BEMb08j3hiK+TfwPdY0F6QH4OhiKK7\n" - "MTqTVgECgYEA0vmmu5GOBtwRmq6gVNCHhdLDQWaxAZqQRmRbzxVhFpbv0GjbQEF7\n" - "tttq3fjDrzDf6CE9RtZWw2BUSXVq+IXB/bXb1kgWU2xWywm+OFDk9OXQs8ui+MY7\n" - "FiP3yuq3YJob2g5CCsVQWl2CHvWGmTLhE1ODll39t7Y1uwdcDobJN+ECgYEA0LlR\n" - "hfMjydWmwqooU9TDjXNBmwufyYlNFTH351amYgFUDpNf35SMCP4hDosUw/zCTDpc\n" - "+1w04BJJfkH1SNvXSOilpdaYRTYuryDvGmWC66K2KX1nLErhlhs17CwzV997nYgD\n" - "H3OOU4HfqIKmdGbjvWlkmY+mLHyG10bbpOTbujkCgYAc68xHejSWDCT9p2KjPdLW\n" - "LYZGuOUa6y1L+QX85Vlh118Ymsczj8Z90qZbt3Zb1b9b+vKDe255agMj7syzNOLa\n" - "/MseHNOyq+9Z9gP1hGFekQKDIy88GzCOYG/fiT2KKJYY1kuHXnUdbiQgSlghODBS\n" - "jehD/K6DOJ80/FVKSH/dAQKBgQDJ+apTzpZhJ2f5k6L2jDq3VEK2ACedZEm9Kt9T\n" - "c1wKFnL6r83kkuB3i0L9ycRMavixvwBfFDjuY4POs5Dh8ip/mPFCa0hqISZHvbzi\n" - "dDyePJO9zmXaTJPDJ42kfpkofVAnfohXFQEy+cguTk848J+MmMIKfyE0h0QMabr9\n" - "86BUsQKBgEVgoi4RXwmtGovtMew01ORPV9MOX3v+VnsCgD4/56URKOAngiS70xEP\n" - "ONwNbTCWuuv43HGzJoVFiAMGnQP1BAJ7gkHkjSegOGKkiw12EPUWhFcMg+GkgPhc\n" - "pOqNt/VMBPjJ/ysHJqmLfQK9A35JV6Cmdphe+OIl28bcKhAOz8Dw\n" - "-----END RSA PRIVATE KEY-----\n"; - -static const char torture_rsa_testkey_pub[] = - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsA5ERRaUFckApnmEAFjLGdFrIN" - "k/Vsl4ts9Ur6enF6auEfJmCN1tjcAOi34lHJaO+WXbDYYj7duW3SP7H9lbCMwq79B" - "hzJxinkcvTWCjE7G66xluL4qIdEYHrPQQx1cztTzZTuUD+P/8fJmmnIONQOeJZptd" - "AmB7ySwZcZOIV4An/rzu5X4klyMY/EAYVDHPKOK1/8Wsv1LRYYplvKp4YPPJ4FnU0" - "si5qI45HIsZJbh24csM3vwSawmfCqDaAlCZFJoPgE1kyO1t+IVxIv1TDhdAVOxa6B" - "QMRjUBThzmDXWeHMfMGL2ow63kPOtlCkPiPSADYs4ekeGg52DVm4esZ " - "aris@aris-air\n"; - -static const char torture_dsa_testkey[] = - "-----BEGIN DSA PRIVATE KEY-----\n" - "MIIBuwIBAAKBgQCUyvVPEkn3UnZDjzCzSzSHpTltzr0Ec+1mz/JACjHMBJ9C/W/P\n" - "wvH3yjkfoFhhREvoY7IPnwAu5bcxw8TkISq7YROQ409PqwwPvy0N3GUp/+kKS268\n" - "BIJ+VKN513XRf7eL1e4aHUJ+al9x1JxTmc6T0GBq1lyu+CTUUyh25aNDFwIVAK84\n" - "j20GmU+zewjQwsIXuVb6C/PHAoGAXhuIVsJxUQJ5nWQRLf7o3XEGQ+EcVmHOzMB1\n" - "xCsHjYnpEhhco+r/HDZSD31kzDeAZUycz31WqGL8yXr+OZRLqEsGC7dwEAzPiXDu\n" - "l0zHcl0yiKPrRrLgNJHeKcT6JflBngK7jQRIVUg3F3104fbVa2rwaniLl4GSBZPX\n" - "MpUdng8CgYB4roDQBfgf8AoSAJAb7y8OVvxt5cT7iqaRMQX2XgtW09Nu9RbUIVS7\n" - "n2mw3iqZG0xnG3iv1oL9gwNXMLlf+gLmsqU3788jaEZ9IhZ8VdgHAoHm6UWM7b2u\n" - "ADmhirI6dRZUVO+/iMGUvDxa66OI4hDV055pbwQhtxupUatThyDzIgIVAI1Hd8/i\n" - "Pzsg7bTzoNvjQL+Noyiy\n" - "-----END DSA PRIVATE KEY-----\n"; - -static const char torture_dsa_testkey_pub[] = - "ssh-dss AAAAB3NzaC1kc3MAAACBAJTK9U8SSfdSdkOPMLNLNIelOW3OvQRz7WbP8k" - "AKMcwEn0L9b8/C8ffKOR+gWGFES+hjsg+fAC7ltzHDxOQhKrthE5DjT0+rDA+/LQ3c" - "ZSn/6QpLbrwEgn5Uo3nXddF/t4vV7hodQn5qX3HUnFOZzpPQYGrWXK74JNRTKHblo0" - "MXAAAAFQCvOI9tBplPs3sI0MLCF7lW+gvzxwAAAIBeG4hWwnFRAnmdZBEt/ujdcQZD" - "4RxWYc7MwHXEKweNiekSGFyj6v8cNlIPfWTMN4BlTJzPfVaoYvzJev45lEuoSwYLt3" - "AQDM+JcO6XTMdyXTKIo+tGsuA0kd4pxPol+UGeAruNBEhVSDcXfXTh9tVravBqeIuX" - "gZIFk9cylR2eDwAAAIB4roDQBfgf8AoSAJAb7y8OVvxt5cT7iqaRMQX2XgtW09Nu9R" - "bUIVS7n2mw3iqZG0xnG3iv1oL9gwNXMLlf+gLmsqU3788jaEZ9IhZ8VdgHAoHm6UWM" - "7b2uADmhirI6dRZUVO+/iMGUvDxa66OI4hDV055pbwQhtxupUatThyDzIg== " - "aris@aris-air\n"; - -static const char torture_rsa_testkey_pp[] = - "-----BEGIN RSA PRIVATE KEY-----\n" - "Proc-Type: 4,ENCRYPTED\n" - "DEK-Info: AES-128-CBC,5375534F40903DD66B3851A0DA03F6FA\n" - "\n" - "m5YYTNOMd1xCKfifwCX4R1iLJoAc4cn1aFiL7f2kBbfE2jF1LTQBJV1h1CqYZfAB\n" - "WtM/7FkQPnKXqsMndP+v+1Xc+PYigE3AezJj/0g7xn/zIBwGjkLAp435AdL5i6Fg\n" - "OhOL8LyolRrcGn17jE4S4iGbzw8PVyfzNzdj0Emwql5F6M7pgLbInRNKM/TF4z2h\n" - "b6Pi9Bw43dwaJ7wiiy/vo/v4MyXsJBoeKbc4VCmxiYFvAYCvVFlDkyIw/QnR3MKQ\n" - "g/Zsk7Pw3aOioxk6LJpZ5x0tO23nXDG1aOZHWykI0BpJV+LIpD2oSYOHJyVO83XT\n" - "RQUMSTXc2K2+ejs0XQoLt/GxDDHe+8W8fWQK3C7Lyvl9oKjmb5sTWi3mdSv0C+zR\n" - "n5KSVbUKNXrjix7qPKkv5rWqb84CKVnCMb7tWaPLR19nQqKVYBIs6v0OTTvS6Le7\n" - "lz4lxBkcUy6vi0tWH9MvLuT+ugdHLJZ4UXBthCgV58pM1o+L+WMIl+SZXckiCAO3\n" - "7ercA57695IA6iHskmr3eazJsYFEVFdR/cm+IDy2FPkKmJMjXeIWuh3yASBk7LBR\n" - "EQq3CC7AioO+Vj8m/fEIiNZJSQ6p0NmgnPoO3rTYT/IobmE99/Ht6oNLmFX4Pr7e\n" - "F4CGWKzwxWpCnw2vVolCFByASmZycbJvrIonZBKY1toU28lRm4tCM6eCNISVLMeE\n" - "VtQ+1PH9/2KZspZl+SX/kjV3egggy0TFKRU8EcYPJFC3Vpy+shEai35KBVo44Z18\n" - "apza7exm3igNEqOqe07hLs3Bjhvk1oS+WhMbAG9ARTOKuyBOJh/ZV9tFMNZ6v+q5\n" - "TofgNcIhNYNascymU1io18xTW9c3RRcmRKqIWnj4EH8o7Aojv/l+zvdV7/GVlR4W\n" - "pR9cuJEiyiEjS46axoc6dSOtdnvag+BpFQb+lGY97F9nNGyBdtLD5ASVh5OVG4fu\n" - "Pf0O7Bdj1kIuBhV8axE/slf6UHANiodeqkR9B24+0Cy+miPiHazzUkbdSJ4r03g5\n" - "J1Y5S8qbl9++sqhQMLMUkeK4pDWh1aocA9bDA2RcBNuXGiZeRFUiqxcBS+iO418n\n" - "DFyWz4UfI/m1IRSjoo/PEpgu5GmosUzs3Dl4nAcf/REBEX6M/kKKxHTLjE8DxDsz\n" - "fn/vfsXV3s0tbN7YyJdP8aU+ApZntw1OF2TS2qS8CPWHTcCGGTab5WEGC3xFXKp0\n" - "uyonCxV7vNLOiIiHdQX+1bLu7ps7GBH92xGkPg7FrNNcMc07soP7jjjB578n9Gpl\n" - "cIDBdgovTRFHiWu3yRspVt0zPfMJB/hqn+IAp98wfvjl8OZM1ZZkejnwXnQil5ZU\n" - "wjEBEtx+nX56vdxipzKoHh5yDXmPbNajBYkg3rXJrLFh3Tsf0CzHcLdHNz/qJ9LO\n" - "wH16grjR1Q0CzCW3FAv0Q0euqkXac+TfuIg3HiTPrBPnJQW1uivrx1F5tpO/uboG\n" - "h28LwqJLYh+1T0V//uiy3SMATpYKvzg2byGct9VUib8QVop8LvVF/n42RaxtTCfw\n" - "JSvUyxoaZUjQkT7iF94HsF+FVVJdI55UjgnMiZ0d5vKffWyTHYcYHkFYaSloAMWN\n" - "-----END RSA PRIVATE KEY-----\n"; - -static const char torture_dsa_testkey_pp[] = - "-----BEGIN DSA PRIVATE KEY-----\n" - "Proc-Type: 4,ENCRYPTED\n" - "DEK-Info: AES-128-CBC,266023B64B1B814BCD0D0E477257F06D\n" - "\n" - "QJQErZrvYsfeMNMnU+6yVHH5Zze/zUFdPip7Bon4T1wCGlVasn4x/GQcMm1+mgmb\n" - "PCK/qJ5qw9nCepLYJq2xh8gohbwF/XKxeaNGcRA2+ancTooDUjeRTlk1WRtS1+bq\n" - "LBkwhxLXW26lIuQUHzfi93rRqQI2LC4McngY7L7WVJer7sH7hk5//4Gf6zHtPEl+\n" - "Tr2ub1zNrVbh6e1Bitw7DaGZNX6XEWpyTTsAd42sQWh6o23MC6GyfS1YFsPGHzGe\n" - "WYQbWn2AZ1mK32z2mLZfVg41qu9RKG20iCyaczZ2YmuYyOkoLHijOAHC8vZbHwYC\n" - "+lN9Yc8/BoMuMMwDTMDaJD0TsBX02hi9YI7Gu88PMCJO+SRe5400MonUMXTwCa91\n" - "Tt3RhYpBzx2XGOq5199+oLdTJAaXHJcuB6viKNdSLBuhx6RAEJXZnVexchaHs4Q6\n" - "HweIv6Et8MjVoqwkaQDmcIGA73qZ0lbUJFZAu2YDJ6TpHc1lHZes763HoMYfuvkX\n" - "HTSuHZ7edjoWqwnl/vkc3+nG//IEj8LqAacx0i4krDcQpGuQ6BnPfwPFco2NQQpw\n" - "wHBOL6HrOnD+gGs6DUFwzA==\n" - "-----END DSA PRIVATE KEY-----\n"; - -static const char torture_ecdsa256_testkey[] = - "-----BEGIN EC PRIVATE KEY-----\n" - "MHcCAQEEIBCDeeYYAtX3EnsP0ratwVpNTaA/4K1N6VvHMiUZlVdhoAoGCCqGSM49\n" - "AwEHoUQDQgAEx+9ud88Q5GWtLd+yMtYaapC85g+2ZLp7VtFHA0EbNHqBUQxoh+Ik\n" - "89Mlr7AUxcFPd+kCo+NE6yq/mNQcL7E6iQ==\n" - "-----END EC PRIVATE KEY-----\n"; - -static const char torture_ecdsa256_testkey_pub[] = - "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNT" - "YAAABBBMfvbnfPEORlrS3fsjLWGmqQvOYPtmS6e1bRRwNBGzR6gVEMaIfiJPPTJa+w" - "FMXBT3fpAqPjROsqv5jUHC+xOok= aris@kalix86\n"; - -static const char torture_ecdsa384_testkey[] = - "-----BEGIN EC PRIVATE KEY-----\n" - "MIGkAgEBBDBY8jEa5DtRy4AVeTWhPJ/TK257behiC3uafEi6YA2oHORibqX55EDN\n" - "wz29MT40mQSgBwYFK4EEACKhZANiAARXc4BN6BrVo1QMi3+i/B85Lu7SMuzBi+1P\n" - "bJti8xz+Szgq64gaBGOK9o+WOdLAd/w7p7DJLdztJ0bYoyT4V3B3ZqR9RyGq6mYC\n" - "jkXlc5YbYHjueBbp0oeNXqsXHNAWQZo=\n" - "-----END EC PRIVATE KEY-----\n"; - -static const char torture_ecdsa384_testkey_pub[] = - "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD" - "QAAABhBFdzgE3oGtWjVAyLf6L8Hzku7tIy7MGL7U9sm2LzHP5LOCrriBoEY4r2j5Y5" - "0sB3/DunsMkt3O0nRtijJPhXcHdmpH1HIarqZgKOReVzlhtgeO54FunSh41eqxcc0B" - "ZBmg== aris@kalix86"; - -static const char torture_ecdsa521_testkey[] = - "-----BEGIN EC PRIVATE KEY-----\n" - "MIHbAgEBBEG83nSJ2SLoiBvEku1JteQKWx/Xt6THksgC7rrIaTUmNzk+60f0sCCm\n" - "Gll0dgrZLmeIw+TtnG1E20VZflCKq+IdkaAHBgUrgQQAI6GBiQOBhgAEAc6D728d\n" - "baQkHnSPtztaRwJw63CBl15cykB4SXXuwWdNOtPzBijUULMTTvBXbra8gL4ATd9d\n" - "Qnuwn8KQUh2T/z+BARjWPKhcHcGx57XpXCEkawzMYaHUUnRdeFEmNRsbXypsf0mJ\n" - "KATU3h8gzTMkbrx8DJTFHEIjXBShs44HsSYVl3Xy\n" - "-----END EC PRIVATE KEY-----\n"; - -static const char torture_ecdsa521_testkey_pub[] = - "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj" - "EAAACFBAHOg+9vHW2kJB50j7c7WkcCcOtwgZdeXMpAeEl17sFnTTrT8wYo1FCzE07w" - "V262vIC+AE3fXUJ7sJ/CkFIdk/8/gQEY1jyoXB3Bsee16VwhJGsMzGGh1FJ0XXhRJj" - "UbG18qbH9JiSgE1N4fIM0zJG68fAyUxRxCI1wUobOOB7EmFZd18g== aris@kalix86"; - -static int verbosity = 0; - -#ifndef _WIN32 -static int _torture_auth_kbdint(ssh_session session, - const char *password) { - const char *prompt; - char echo; - int err; - - if (session == NULL || password == NULL) { - return SSH_AUTH_ERROR; - } - - err = ssh_userauth_kbdint(session, NULL, NULL); - if (err == SSH_AUTH_ERROR) { - return err; - } - - if (ssh_userauth_kbdint_getnprompts(session) != 1) { - return SSH_AUTH_ERROR; - } - - prompt = ssh_userauth_kbdint_getprompt(session, 0, &echo); - if (prompt == NULL) { - return SSH_AUTH_ERROR; - } - - if (ssh_userauth_kbdint_setanswer(session, 0, password) < 0) { - return SSH_AUTH_ERROR; - } - err = ssh_userauth_kbdint(session, NULL, NULL); - if (err == SSH_AUTH_INFO) { - if (ssh_userauth_kbdint_getnprompts(session) != 0) { - return SSH_AUTH_ERROR; - } - err = ssh_userauth_kbdint(session, NULL, NULL); - } - - return err; -} - -int torture_rmdirs(const char *path) { - DIR *d; - struct dirent *dp; - struct stat sb; - char *fname; - - if ((d = opendir(path)) != NULL) { - while(stat(path, &sb) == 0) { - /* if we can remove the directory we're done */ - if (rmdir(path) == 0) { - break; - } - switch (errno) { - case ENOTEMPTY: - case EEXIST: - case EBADF: - break; /* continue */ - default: - closedir(d); - return 0; - } - - while ((dp = readdir(d)) != NULL) { - size_t len; - /* skip '.' and '..' */ - if (dp->d_name[0] == '.' && - (dp->d_name[1] == '\0' || - (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) { - continue; - } - - len = strlen(path) + strlen(dp->d_name) + 2; - fname = malloc(len); - if (fname == NULL) { - closedir(d); - return -1; - } - snprintf(fname, len, "%s/%s", path, dp->d_name); - - /* stat the file */ - if (lstat(fname, &sb) != -1) { - if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) { - if (rmdir(fname) < 0) { /* can't be deleted */ - if (errno == EACCES) { - closedir(d); - SAFE_FREE(fname); - return -1; - } - torture_rmdirs(fname); - } - } else { - unlink(fname); - } - } /* lstat */ - SAFE_FREE(fname); - } /* readdir */ - - rewinddir(d); - } - } else { - return -1; - } - - closedir(d); - return 0; -} - -int torture_isdir(const char *path) { - struct stat sb; - - if (lstat (path, &sb) == 0 && S_ISDIR(sb.st_mode)) { - return 1; - } - - return 0; -} - -ssh_session torture_ssh_session(const char *host, - const char *user, - const char *password) { - ssh_session session; - int method; - int rc; - - if (host == NULL) { - return NULL; - } - - session = ssh_new(); - if (session == NULL) { - return NULL; - } - - if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) { - goto failed; - } - - if (user != NULL) { - if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) { - goto failed; - } - } - - if (ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity) < 0) { - goto failed; - } - - if (ssh_connect(session)) { - goto failed; - } - - /* We are in testing mode, so consinder the hostkey as verified ;) */ - - /* This request should return a SSH_REQUEST_DENIED error */ - rc = ssh_userauth_none(session, NULL); - if (rc == SSH_ERROR) { - goto failed; - } - method = ssh_userauth_list(session, NULL); - if (method == 0) { - goto failed; - } - - if (password != NULL) { - if (method & SSH_AUTH_METHOD_INTERACTIVE) { - rc = _torture_auth_kbdint(session, password); - } else if (method & SSH_AUTH_METHOD_PASSWORD) { - rc = ssh_userauth_password(session, NULL, password); - } - } else { - rc = ssh_userauth_publickey_auto(session, NULL, NULL); - if (rc == SSH_AUTH_ERROR) { - goto failed; - } - } - if (rc != SSH_AUTH_SUCCESS) { - goto failed; - } - - return session; -failed: - if (ssh_is_connected(session)) { - ssh_disconnect(session); - } - ssh_free(session); - - return NULL; -} - -#ifdef WITH_SFTP - -struct torture_sftp *torture_sftp_session(ssh_session session) { - struct torture_sftp *t; - char template[] = "/tmp/ssh_torture_XXXXXX"; - char *p; - int rc; - - if (session == NULL) { - return NULL; - } - - t = malloc(sizeof(struct torture_sftp)); - if (t == NULL) { - return NULL; - } - - t->ssh = session; - t->sftp = sftp_new(session); - if (t->sftp == NULL) { - goto failed; - } - - rc = sftp_init(t->sftp); - if (rc < 0) { - goto failed; - } - - p = mkdtemp(template); - if (p == NULL) { - goto failed; - } - /* useful if TESTUSER is not the local user */ - chmod(template,0777); - t->testdir = strdup(p); - if (t->testdir == NULL) { - goto failed; - } - - return t; -failed: - if (t->sftp != NULL) { - sftp_free(t->sftp); - } - ssh_disconnect(t->ssh); - ssh_free(t->ssh); - free(t); - - return NULL; -} - -void torture_sftp_close(struct torture_sftp *t) { - if (t == NULL) { - return; - } - - if (t->sftp != NULL) { - sftp_free(t->sftp); - } - - if (t->ssh != NULL) { - if (ssh_is_connected(t->ssh)) { - ssh_disconnect(t->ssh); - } - ssh_free(t->ssh); - } - - free(t->testdir); - free(t); -} -#endif /* WITH_SFTP */ - -#endif /* _WIN32 */ - -void torture_write_file(const char *filename, const char *data){ - int fd; - int rc; - - assert_non_null(filename); - assert_true(filename[0] != '\0'); - assert_non_null(data); - - fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0755); - assert_true(fd >= 0); - - rc = write(fd, data, strlen(data)); - assert_int_equal(rc, strlen(data)); - - close(fd); -} - -static const char *torture_get_testkey_internal(enum ssh_keytypes_e type, - int bits, - int with_passphrase, - int pubkey) -{ - switch (type) { - case SSH_KEYTYPE_DSS: - if (pubkey) { - return torture_dsa_testkey_pub; - } else if (with_passphrase) { - return torture_dsa_testkey_pp; - } - return torture_dsa_testkey; - case SSH_KEYTYPE_RSA: - if (pubkey) { - return torture_rsa_testkey_pub; - } else if (with_passphrase) { - return torture_rsa_testkey_pp; - } - return torture_rsa_testkey; - case SSH_KEYTYPE_ECDSA: - if (bits == 521) { - if (pubkey) { - return torture_ecdsa521_testkey_pub; - } - return torture_ecdsa521_testkey; - } else if (bits == 384) { - if (pubkey) { - return torture_ecdsa384_testkey_pub; - } - return torture_ecdsa384_testkey; - } - - if (pubkey) { - return torture_ecdsa256_testkey_pub; - } - return torture_ecdsa256_testkey; - case SSH_KEYTYPE_RSA1: - case SSH_KEYTYPE_UNKNOWN: - return NULL; - } - - return NULL; -} - -const char *torture_get_testkey(enum ssh_keytypes_e type, - int ecda_bits, - int with_passphrase) -{ - return torture_get_testkey_internal(type, ecda_bits, with_passphrase, 0); -} - -const char *torture_get_testkey_pub(enum ssh_keytypes_e type, int ecda_bits) -{ - return torture_get_testkey_internal(type, ecda_bits, 0, 1); -} - -const char *torture_get_testkey_passphrase(void) -{ - return TORTURE_TESTKEY_PASSWORD; -} - -int torture_libssh_verbosity(void){ - return verbosity; -} - -int main(int argc, char **argv) { - struct argument_s arguments; - - arguments.verbose=0; - torture_cmdline_parse(argc, argv, &arguments); - verbosity=arguments.verbose; - - return torture_run_tests(); -} - -/* vim: set ts=4 sw=4 et cindent syntax=c.doxygen: */ diff --git a/libssh/tests/torture.h b/libssh/tests/torture.h deleted file mode 100644 index ffcea8bb..00000000 --- a/libssh/tests/torture.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * torture.c - torture library for testing libssh - * - * This file is part of the SSH Library - * - * Copyright (c) 2008-2009 by Andreas Schneider - * - * The SSH 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. - * - * The SSH 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 the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef _TORTURE_H -#define _TORTURE_H - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include - -#include "libssh/priv.h" -#include "libssh/sftp.h" - -#include - -/* Used by main to communicate with parse_opt. */ -struct argument_s { - char *args[2]; - int verbose; -}; - -struct torture_sftp { - ssh_session ssh; - sftp_session sftp; - char *testdir; -}; - -void torture_cmdline_parse(int argc, char **argv, struct argument_s *arguments); - -int torture_rmdirs(const char *path); -int torture_isdir(const char *path); - -/* - * Returns the verbosity level asked by user - */ -int torture_libssh_verbosity(void); - -ssh_session torture_ssh_session(const char *host, - const char *user, - const char *password); - -struct torture_sftp *torture_sftp_session(ssh_session session); -void torture_sftp_close(struct torture_sftp *t); - -const char *torture_get_testkey(enum ssh_keytypes_e type, - int ecdsa_bits, - int with_passphrase); -const char *torture_get_testkey_pub(enum ssh_keytypes_e type, int ecdsa_bits); -const char *torture_get_testkey_passphrase(void); - -void torture_write_file(const char *filename, const char *data); - -/* - * This function must be defined in every unit test file. - */ -int torture_run_tests(void); - -#endif /* _TORTURE_H */ diff --git a/libssh/tests/unittests/CMakeLists.txt b/libssh/tests/unittests/CMakeLists.txt deleted file mode 100644 index 38203991..00000000 --- a/libssh/tests/unittests/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -project(unittests C) - -add_cmocka_test(torture_buffer torture_buffer.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_callbacks torture_callbacks.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_init torture_init.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_list torture_list.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_misc torture_misc.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_options torture_options.c ${TORTURE_LIBRARY}) -add_cmocka_test(torture_isipaddr torture_isipaddr.c ${TORTURE_LIBRARY}) -if (UNIX AND NOT WIN32) - # requires ssh-keygen - add_cmocka_test(torture_keyfiles torture_keyfiles.c ${TORTURE_LIBRARY}) - add_cmocka_test(torture_pki torture_pki.c ${TORTURE_LIBRARY}) - # requires pthread - add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY}) - # requires /dev/null - add_cmocka_test(torture_channel torture_channel.c ${TORTURE_LIBRARY}) -endif (UNIX AND NOT WIN32) diff --git a/libssh/tests/unittests/torture_buffer.c b/libssh/tests/unittests/torture_buffer.c deleted file mode 100644 index ec87259d..00000000 --- a/libssh/tests/unittests/torture_buffer.c +++ /dev/null @@ -1,268 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#define DEBUG_BUFFER -#include "buffer.c" - -#define LIMIT (8*1024*1024) - -static void setup(void **state) { - ssh_buffer buffer; - buffer = ssh_buffer_new(); - ssh_buffer_set_secure(buffer); - *state = (void *) buffer; -} - -static void teardown(void **state) { - ssh_buffer_free(*state); -} - -/* - * Test if the continuously growing buffer size never exceeds 2 time its - * real capacity - */ -static void torture_growing_buffer(void **state) { - ssh_buffer buffer = *state; - int i; - - for(i=0;iused >= 128){ - if(buffer_get_rest_len(buffer) * 2 < buffer->allocated){ - assert_true(buffer_get_rest_len(buffer) * 2 >= buffer->allocated); - } - } - } -} - -/* - * Test if the continuously growing buffer size never exceeds 2 time its - * real capacity, when we remove 1 byte after each call (sliding window) - */ -static void torture_growing_buffer_shifting(void **state) { - ssh_buffer buffer = *state; - int i; - unsigned char c; - for(i=0; i<1024;++i){ - ssh_buffer_add_data(buffer,"S",1); - } - for(i=0;iused >= 128){ - if(buffer_get_rest_len(buffer) * 4 < buffer->allocated){ - assert_true(buffer_get_rest_len(buffer) * 4 >= buffer->allocated); - return; - } - } - } -} - -/* - * Test the behavior of buffer_prepend_data - */ -static void torture_buffer_prepend(void **state) { - ssh_buffer buffer = *state; - uint32_t v; - ssh_buffer_add_data(buffer,"abcdef",6); - buffer_prepend_data(buffer,"xyz",3); - assert_int_equal(buffer_get_rest_len(buffer),9); - assert_memory_equal(buffer_get_rest(buffer), "xyzabcdef", 9); - - /* Now remove 4 bytes and see if we can replace them */ - buffer_get_u32(buffer,&v); - assert_int_equal(buffer_get_rest_len(buffer),5); - assert_memory_equal(buffer_get_rest(buffer), "bcdef", 5); - - buffer_prepend_data(buffer,"aris",4); - assert_int_equal(buffer_get_rest_len(buffer),9); - assert_memory_equal(buffer_get_rest(buffer), "arisbcdef", 9); - - /* same thing but we add 5 bytes now */ - buffer_get_u32(buffer,&v); - assert_int_equal(buffer_get_rest_len(buffer),5); - assert_memory_equal(buffer_get_rest(buffer), "bcdef", 5); - - buffer_prepend_data(buffer,"12345",5); - assert_int_equal(buffer_get_rest_len(buffer),10); - assert_memory_equal(buffer_get_rest(buffer), "12345bcdef", 10); -} - -/* - * Test the behavior of buffer_get_ssh_string with invalid data - */ -static void torture_buffer_get_ssh_string(void **state) { - ssh_buffer buffer; - int i,j,k,l, rc; - /* some values that can go wrong */ - uint32_t values[] = {0xffffffff, 0xfffffffe, 0xfffffffc, 0xffffff00, - 0x80000000, 0x80000004, 0x7fffffff}; - char data[128]; - (void)state; - memset(data,'X',sizeof(data)); - for(i=0; i < (int)(sizeof(values)/sizeof(values[0]));++i){ - for(j=0; j< (int)sizeof(data);++j){ - for(k=1;k<5;++k){ - buffer = ssh_buffer_new(); - assert_non_null(buffer); - - for(l=0;l -#include - -static int myauthcallback (const char *prompt, char *buf, size_t len, - int echo, int verify, void *userdata) { - (void) prompt; - (void) buf; - (void) len; - (void) echo; - (void) verify; - (void) userdata; - return 0; -} - -static void setup(void **state) { - struct ssh_callbacks_struct *cb; - - cb = malloc(sizeof(struct ssh_callbacks_struct)); - assert_false(cb == NULL); - ZERO_STRUCTP(cb); - - cb->userdata = (void *) 0x0badc0de; - cb->auth_function = myauthcallback; - - ssh_callbacks_init(cb); - *state = cb; -} - -static void teardown(void **state) { - free(*state); -} - -static void torture_callbacks_size(void **state) { - struct ssh_callbacks_struct *cb = *state;; - - assert_int_not_equal(cb->size, 0); -} - -static void torture_callbacks_exists(void **state) { - struct ssh_callbacks_struct *cb = *state; - - assert_int_not_equal(ssh_callbacks_exists(cb, auth_function), 0); - assert_int_equal(ssh_callbacks_exists(cb, log_function), 0); - - /* - * We redefine size so auth_function is outside the range of - * callbacks->size. - */ - cb->size = (unsigned char *) &cb->auth_function - (unsigned char *) cb; - assert_int_equal(ssh_callbacks_exists(cb, auth_function), 0); - - /* Now make it one pointer bigger so we spill over the auth_function slot */ - cb->size += sizeof(void *); - assert_int_not_equal(ssh_callbacks_exists(cb, auth_function), 0); -} - -struct test_mock_state { - int executed; -}; - -static void test_mock_ssh_logging_callback(int priority, - const char *function, - const char *buffer, - void *userdata) -{ - struct test_mock_state *t = (struct test_mock_state *)userdata; - - check_expected(priority); - check_expected(function); - check_expected(buffer); - - t->executed++; -} - -static void torture_log_callback(void **state) -{ - struct test_mock_state t = { - .executed = 0, - }; - - (void)state; /* unused */ - - ssh_set_log_callback(test_mock_ssh_logging_callback); - ssh_set_log_userdata(&t); - ssh_set_log_level(1); - - expect_value(test_mock_ssh_logging_callback, priority, 1); - expect_string(test_mock_ssh_logging_callback, function, "torture_log_callback"); - expect_string(test_mock_ssh_logging_callback, buffer, "torture_log_callback: test"); - - SSH_LOG(SSH_LOG_WARN, "test"); - - assert_int_equal(t.executed, 1); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_callbacks_size, setup, teardown), - unit_test_setup_teardown(torture_callbacks_exists, setup, teardown), - unit_test(torture_log_callback), - }; - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_channel.c b/libssh/tests/unittests/torture_channel.c deleted file mode 100644 index 1d928b84..00000000 --- a/libssh/tests/unittests/torture_channel.c +++ /dev/null @@ -1,49 +0,0 @@ -#define LIBSSH_STATIC -#include - -#include -#include -#include - -#include "torture.h" -#include "channels.c" - -static void torture_channel_select(void **state) -{ - fd_set readfds; - int fd; - int rc; - int i; - - (void)state; /* unused */ - - fd = open("/dev/null", 0); - assert_true(fd > 2); - - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - - for (i = 0; i < 10; i++) { - ssh_channel cin[1] = { NULL, }; - ssh_channel cout[1] = { NULL, }; - struct timeval tv = { .tv_sec = 0, .tv_usec = 1000 }; - - rc = ssh_select(cin, cout, fd + 1, &readfds, &tv); - assert_int_equal(rc, SSH_OK); - } - - close(fd); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test(torture_channel_select), - }; - - ssh_init(); - rc = run_tests(tests); - ssh_finalize(); - - return rc; -} diff --git a/libssh/tests/unittests/torture_init.c b/libssh/tests/unittests/torture_init.c deleted file mode 100644 index 85bd95e1..00000000 --- a/libssh/tests/unittests/torture_init.c +++ /dev/null @@ -1,23 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "libssh/libssh.h" - -static void torture_ssh_init(void **state) { - int rc; - - (void) state; - - rc = ssh_init(); - assert_int_equal(rc, SSH_OK); - rc = ssh_finalize(); - assert_int_equal(rc, SSH_OK); -} - -int torture_run_tests(void) { - const UnitTest tests[] = { - unit_test(torture_ssh_init), - }; - - return run_tests(tests); -} diff --git a/libssh/tests/unittests/torture_isipaddr.c b/libssh/tests/unittests/torture_isipaddr.c deleted file mode 100644 index c2a1e079..00000000 --- a/libssh/tests/unittests/torture_isipaddr.c +++ /dev/null @@ -1,56 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" - -#include "misc.c" -#include "error.c" - -/* - * Test the behavior of ssh_is_ipaddr() - */ -static void torture_ssh_is_ipaddr(void **state) { - (void)state; - - assert_int_equal(ssh_is_ipaddr("127.0.0.1"),1); - assert_int_equal(ssh_is_ipaddr("0.0.0.0"),1); - assert_int_equal(ssh_is_ipaddr("1.1.1.1"),1); - assert_int_equal(ssh_is_ipaddr("255.255.255.255"),1); - assert_int_equal(ssh_is_ipaddr("128.128.128.128"),1); - assert_int_equal(ssh_is_ipaddr("1.10.100.1"),1); - assert_int_equal(ssh_is_ipaddr("0.1.10.100"),1); - - assert_int_equal(ssh_is_ipaddr("2001:0db8:85a3:0000:0000:8a2e:0370:7334"),1); - assert_int_equal(ssh_is_ipaddr("fe80:0000:0000:0000:0202:b3ff:fe1e:8329"),1); - assert_int_equal(ssh_is_ipaddr("fe80:0:0:0:202:b3ff:fe1e:8329"),1); - assert_int_equal(ssh_is_ipaddr("fe80::202:b3ff:fe1e:8329"),1); - assert_int_equal(ssh_is_ipaddr("::1"),1); - - assert_int_equal(ssh_is_ipaddr("::ffff:192.0.2.128"),1); - - assert_int_equal(ssh_is_ipaddr("0.0.0.0.0"),0); - assert_int_equal(ssh_is_ipaddr("0.0.0.0.a"),0); - assert_int_equal(ssh_is_ipaddr("a.0.0.0"),0); - assert_int_equal(ssh_is_ipaddr("0a.0.0.0.0"),0); - assert_int_equal(ssh_is_ipaddr(""),0); - assert_int_equal(ssh_is_ipaddr("0.0.0."),0); - assert_int_equal(ssh_is_ipaddr("0.0"),0); - assert_int_equal(ssh_is_ipaddr("0"),0); - assert_int_equal(ssh_is_ipaddr("255.255.255"),0); - - assert_int_equal(ssh_is_ipaddr("2001:0db8:85a3:0000:0000:8a2e:0370:7334:1002"), 0); - assert_int_equal(ssh_is_ipaddr("fe80:x:202:b3ff:fe1e:8329"), 0); - assert_int_equal(ssh_is_ipaddr("fe80:x:202:b3ff:fe1e:8329"), 0); - assert_int_equal(ssh_is_ipaddr(":1"), 0); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test(torture_ssh_is_ipaddr) - }; - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_keyfiles.c b/libssh/tests/unittests/torture_keyfiles.c deleted file mode 100644 index 9446bc6d..00000000 --- a/libssh/tests/unittests/torture_keyfiles.c +++ /dev/null @@ -1,261 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "legacy.c" - -#define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa" -#define LIBSSH_DSA_TESTKEY "libssh_testkey.id_dsa" -#define LIBSSH_PASSPHRASE "libssh-rocks" - -static void setup_rsa_key(void **state) { - ssh_session session; - int rc; - - unlink(LIBSSH_RSA_TESTKEY); - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - rc = system("ssh-keygen -t rsa -q -N \"\" -f " LIBSSH_RSA_TESTKEY); - assert_true(rc == 0); - - session = ssh_new(); - *state = session; -} - -static void setup_dsa_key(void **state) { - ssh_session session; - int rc; - - unlink(LIBSSH_DSA_TESTKEY); - unlink(LIBSSH_DSA_TESTKEY ".pub"); - - rc = system("ssh-keygen -t dsa -q -N \"\" -f " LIBSSH_DSA_TESTKEY); - assert_true(rc == 0); - - session = ssh_new(); - *state = session; -} - -static void setup_both_keys(void **state) { - setup_rsa_key(state); - ssh_free(*state); - setup_dsa_key(state); -} - -static void setup_both_keys_passphrase(void **state) { - ssh_session session; - int rc; - - rc = system("ssh-keygen -t rsa -N " LIBSSH_PASSPHRASE " -f " LIBSSH_RSA_TESTKEY); - assert_true(rc == 0); - - rc = system("ssh-keygen -t dsa -N " LIBSSH_PASSPHRASE " -f " LIBSSH_DSA_TESTKEY); - assert_true(rc == 0); - - session = ssh_new(); - *state = session; -} -static void teardown(void **state) { - unlink(LIBSSH_DSA_TESTKEY); - unlink(LIBSSH_DSA_TESTKEY ".pub"); - - unlink(LIBSSH_RSA_TESTKEY); - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - ssh_free(*state); -} - -static void torture_pubkey_from_file(void **state) { - ssh_session session = *state; - ssh_string pubkey; - int type, rc; - - rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); - - assert_true(rc == 0); - - ssh_string_free(pubkey); - - /* test if it returns 1 if pubkey doesn't exist */ - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); - assert_true(rc == 1); - - /* test if it returns -1 if privkey doesn't exist */ - unlink(LIBSSH_RSA_TESTKEY); - - rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); - assert_true(rc == -1); -} - -static int torture_read_one_line(const char *filename, char *buffer, size_t len) { - FILE *fp; - size_t rc; - - fp = fopen(filename, "r"); - if (fp == NULL) { - return -1; - } - - rc = fread(buffer, len, 1, fp); - if (rc != 0 || ferror(fp)) { - fclose(fp); - return -1; - } - - fclose(fp); - - return 0; -} - -static void torture_pubkey_generate_from_privkey(void **state) { - ssh_session session = *state; - ssh_private_key privkey = NULL; - ssh_public_key pubkey = NULL; - ssh_string pubkey_orig = NULL; - ssh_string pubkey_new = NULL; - char pubkey_line_orig[512] = {0}; - char pubkey_line_new[512] = {0}; - int type_orig = 0; - int type_new = 0; - int rc; - - /* read the publickey */ - rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey_orig, - &type_orig); - assert_true(rc == 0); - assert_true(pubkey_orig != NULL); - - rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_orig, - sizeof(pubkey_line_orig)); - assert_true(rc == 0); - - /* remove the public key, generate it from the private key and write it. */ - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - privkey = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, NULL); - assert_true(privkey != NULL); - - pubkey = publickey_from_privatekey(privkey); - assert_true(pubkey != NULL); - type_new = privkey->type; - privatekey_free(privkey); - - pubkey_new = publickey_to_string(pubkey); - publickey_free(pubkey); - - assert_true(pubkey_new != NULL); - - assert_true(ssh_string_len(pubkey_orig) == ssh_string_len(pubkey_new)); - assert_memory_equal(ssh_string_data(pubkey_orig), - ssh_string_data(pubkey_new), - ssh_string_len(pubkey_orig)); - - rc = ssh_publickey_to_file(session, LIBSSH_RSA_TESTKEY ".pub", pubkey_new, type_new); - assert_true(rc == 0); - - rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_new, - sizeof(pubkey_line_new)); - assert_true(rc == 0); - - assert_string_equal(pubkey_line_orig, pubkey_line_new); - - ssh_string_free(pubkey_orig); - ssh_string_free(pubkey_new); -} - -/** - * @brief tests the privatekey_from_file function without passphrase - */ -static void torture_privatekey_from_file(void **state) { - ssh_session session = *state; - ssh_private_key key = NULL; - - key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, SSH_KEYTYPE_RSA, NULL); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } - - key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, SSH_KEYTYPE_DSS, NULL); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } - - /* Test the automatic type discovery */ - key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, NULL); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } - - key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, 0, NULL); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } -} - -/** - * @brief tests the privatekey_from_file function with passphrase - */ -static void torture_privatekey_from_file_passphrase(void **state) { - ssh_session session = *state; - ssh_private_key key = NULL; - - key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, SSH_KEYTYPE_RSA, LIBSSH_PASSPHRASE); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } - - key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, SSH_KEYTYPE_DSS, LIBSSH_PASSPHRASE); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } - - /* Test the automatic type discovery */ - key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, LIBSSH_PASSPHRASE); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } - - key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, 0, LIBSSH_PASSPHRASE); - assert_true(key != NULL); - if (key != NULL) { - privatekey_free(key); - key = NULL; - } -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_pubkey_from_file, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pubkey_generate_from_privkey, - setup_rsa_key, teardown), - unit_test_setup_teardown(torture_privatekey_from_file, - setup_both_keys, - teardown), - unit_test_setup_teardown(torture_privatekey_from_file_passphrase, - setup_both_keys_passphrase, teardown), - }; - - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_list.c b/libssh/tests/unittests/torture_list.c deleted file mode 100644 index 75f41825..00000000 --- a/libssh/tests/unittests/torture_list.c +++ /dev/null @@ -1,91 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "error.c" -#include "misc.c" - -static void torture_ssh_list_new(void **state) { - struct ssh_list *xlist; - - (void) state; - - xlist = ssh_list_new(); - - assert_true(xlist != NULL); - assert_true(xlist->root == NULL); - assert_true(xlist->end == NULL); - - ssh_list_free(xlist); -} - -static void torture_ssh_list_append(void **state) { - struct ssh_list *xlist; - int rc; - - (void) state; - - xlist = ssh_list_new(); - assert_true(xlist != NULL); - - rc = ssh_list_append(xlist, "item1"); - assert_true(rc == 0); - assert_string_equal((const char *) xlist->root->data, "item1"); - assert_string_equal((const char *) xlist->end->data, "item1"); - - rc = ssh_list_append(xlist, "item2"); - assert_true(rc == 0); - assert_string_equal((const char *) xlist->root->data, "item1"); - assert_string_equal((const char *) xlist->end->data, "item2"); - - rc = ssh_list_append(xlist, "item3"); - assert_true(rc == 0); - assert_string_equal((const char *) xlist->root->data, "item1"); - assert_string_equal((const char *) xlist->root->next->data, "item2"); - assert_string_equal((const char *) xlist->root->next->next->data, "item3"); - assert_string_equal((const char *) xlist->end->data, "item3"); - - ssh_list_free(xlist); -} - -static void torture_ssh_list_prepend(void **state) { - struct ssh_list *xlist; - int rc; - - (void) state; - - xlist = ssh_list_new(); - assert_true(xlist != NULL); - - rc = ssh_list_prepend(xlist, "item1"); - assert_true(rc == 0); - assert_string_equal((const char *) xlist->root->data, "item1"); - assert_string_equal((const char *) xlist->end->data, "item1"); - - rc = ssh_list_append(xlist, "item2"); - assert_true(rc == 0); - assert_string_equal((const char *) xlist->root->data, "item1"); - assert_string_equal((const char *) xlist->end->data, "item2"); - - rc = ssh_list_prepend(xlist, "item3"); - assert_true(rc == 0); - assert_string_equal((const char *) xlist->root->data, "item3"); - assert_string_equal((const char *) xlist->root->next->data, "item1"); - assert_string_equal((const char *) xlist->root->next->next->data, "item2"); - assert_string_equal((const char *) xlist->end->data, "item2"); - - ssh_list_free(xlist); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test(torture_ssh_list_new), - unit_test(torture_ssh_list_append), - unit_test(torture_ssh_list_prepend), - }; - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_misc.c b/libssh/tests/unittests/torture_misc.c deleted file mode 100644 index 26770324..00000000 --- a/libssh/tests/unittests/torture_misc.c +++ /dev/null @@ -1,210 +0,0 @@ - -#include -#ifndef _WIN32 - -#define _POSIX_PTHREAD_SEMANTICS -#include -#endif - -#define LIBSSH_STATIC -#include - -#include "torture.h" -#include "misc.c" -#include "error.c" - -#define TORTURE_TEST_DIR "/usr/local/bin/truc/much/.." - - -static void setup(void **state) { - ssh_session session = ssh_new(); - *state = session; -} - -static void teardown(void **state) { - ssh_free(*state); -} - -static void torture_get_user_home_dir(void **state) { -#ifndef _WIN32 - struct passwd *pwd = getpwuid(getuid()); -#endif /* _WIN32 */ - char *user; - - (void) state; - - user = ssh_get_user_home_dir(); - assert_false(user == NULL); -#ifndef _WIN32 - assert_string_equal(user, pwd->pw_dir); -#endif /* _WIN32 */ - - SAFE_FREE(user); -} - -static void torture_basename(void **state) { - char *path; - - (void) state; - - path=ssh_basename(TORTURE_TEST_DIR "/test"); - assert_true(path != NULL); - assert_string_equal(path, "test"); - SAFE_FREE(path); - path=ssh_basename(TORTURE_TEST_DIR "/test/"); - assert_true(path != NULL); - assert_string_equal(path, "test"); - SAFE_FREE(path); -} - -static void torture_dirname(void **state) { - char *path; - - (void) state; - - path=ssh_dirname(TORTURE_TEST_DIR "/test"); - assert_true(path != NULL); - assert_string_equal(path, TORTURE_TEST_DIR ); - SAFE_FREE(path); - path=ssh_dirname(TORTURE_TEST_DIR "/test/"); - assert_true(path != NULL); - assert_string_equal(path, TORTURE_TEST_DIR); - SAFE_FREE(path); -} - -static void torture_ntohll(void **state) { - uint64_t value = 0x0123456789abcdef; - uint32_t sample = 1; - unsigned char *ptr = (unsigned char *) &sample; - uint64_t check; - - (void) state; - - if (ptr[0] == 1){ - /* we're in little endian */ - check = 0xefcdab8967452301; - } else { - /* big endian */ - check = value; - } - value = ntohll(value); - assert_true(value == check); -} - -#ifdef _WIN32 - -static void torture_path_expand_tilde_win(void **state) { - char *d; - - (void) state; - - d = ssh_path_expand_tilde("~\\.ssh"); - assert_false(d == NULL); - print_message("Expanded path: %s\n", d); - free(d); - - d = ssh_path_expand_tilde("/guru/meditation"); - assert_string_equal(d, "/guru/meditation"); - free(d); -} - -#else /* _WIN32 */ - -static void torture_path_expand_tilde_unix(void **state) { - char h[256]; - char *d; - - (void) state; - - snprintf(h, 256 - 1, "%s/.ssh", getenv("HOME")); - - d = ssh_path_expand_tilde("~/.ssh"); - assert_string_equal(d, h); - free(d); - - d = ssh_path_expand_tilde("/guru/meditation"); - assert_string_equal(d, "/guru/meditation"); - free(d); - - snprintf(h, 256 - 1, "~%s/.ssh", getenv("USER")); - d = ssh_path_expand_tilde(h); - - snprintf(h, 256 - 1, "%s/.ssh", getenv("HOME")); - assert_string_equal(d, h); - free(d); -} - -#endif /* _WIN32 */ - -static void torture_path_expand_escape(void **state) { - ssh_session session = *state; - const char *s = "%d/%h/by/%r"; - char *e; - - session->opts.sshdir = strdup("guru"); - session->opts.host = strdup("meditation"); - session->opts.username = strdup("root"); - - e = ssh_path_expand_escape(session, s); - assert_string_equal(e, "guru/meditation/by/root"); - free(e); -} - -static void torture_path_expand_known_hosts(void **state) { - ssh_session session = *state; - char *tmp; - - session->opts.sshdir = strdup("/home/guru/.ssh"); - - tmp = ssh_path_expand_escape(session, "%d/known_hosts"); - assert_string_equal(tmp, "/home/guru/.ssh/known_hosts"); - free(tmp); -} - -static void torture_timeout_elapsed(void **state){ - struct ssh_timestamp ts; - (void) state; - ssh_timestamp_init(&ts); - usleep(50000); - assert_true(ssh_timeout_elapsed(&ts,25)); - assert_false(ssh_timeout_elapsed(&ts,30000)); - assert_false(ssh_timeout_elapsed(&ts,75)); - assert_true(ssh_timeout_elapsed(&ts,0)); - assert_false(ssh_timeout_elapsed(&ts,-1)); -} - -static void torture_timeout_update(void **state){ - struct ssh_timestamp ts; - (void) state; - ssh_timestamp_init(&ts); - usleep(50000); - assert_int_equal(ssh_timeout_update(&ts,25), 0); - assert_in_range(ssh_timeout_update(&ts,30000),29000,29960); - assert_in_range(ssh_timeout_update(&ts,75),1,40); - assert_int_equal(ssh_timeout_update(&ts,0),0); - assert_int_equal(ssh_timeout_update(&ts,-1),-1); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test(torture_get_user_home_dir), - unit_test(torture_basename), - unit_test(torture_dirname), - unit_test(torture_ntohll), -#ifdef _WIN32 - unit_test(torture_path_expand_tilde_win), -#else - unit_test(torture_path_expand_tilde_unix), -#endif - unit_test_setup_teardown(torture_path_expand_escape, setup, teardown), - unit_test_setup_teardown(torture_path_expand_known_hosts, setup, teardown), - unit_test(torture_timeout_elapsed), - unit_test(torture_timeout_update), - }; - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_options.c b/libssh/tests/unittests/torture_options.c deleted file mode 100644 index 6f5df1bb..00000000 --- a/libssh/tests/unittests/torture_options.c +++ /dev/null @@ -1,215 +0,0 @@ -#define LIBSSH_STATIC - -#ifndef _WIN32 -#define _POSIX_PTHREAD_SEMANTICS -# include -#endif - -#include "torture.h" -#include -#include - -static void setup(void **state) { - ssh_session session = ssh_new(); - *state = session; -} - -static void teardown(void **state) { - ssh_free(*state); -} - -static void torture_options_set_host(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == 0); - assert_string_equal(session->opts.host, "localhost"); - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "guru@meditation"); - assert_true(rc == 0); - assert_string_equal(session->opts.host, "meditation"); - assert_string_equal(session->opts.username, "guru"); -} - -static void torture_options_get_host(void **state) { - ssh_session session = *state; - int rc; - char* host = NULL; - - rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); - assert_true(rc == 0); - assert_string_equal(session->opts.host, "localhost"); - - assert_false(ssh_options_get(session, SSH_OPTIONS_HOST, &host)); - - assert_string_equal(host, "localhost"); - free(host); -} - -static void torture_options_set_port(void **state) { - ssh_session session = *state; - int rc; - unsigned int port = 42; - - rc = ssh_options_set(session, SSH_OPTIONS_PORT, &port); - assert_true(rc == 0); - assert_true(session->opts.port == port); - - rc = ssh_options_set(session, SSH_OPTIONS_PORT_STR, "23"); - assert_true(rc == 0); - assert_true(session->opts.port == 23); - - rc = ssh_options_set(session, SSH_OPTIONS_PORT_STR, "five"); - assert_true(rc == -1); - - rc = ssh_options_set(session, SSH_OPTIONS_PORT, NULL); - assert_true(rc == -1); -} - -static void torture_options_get_port(void **state) { - ssh_session session = *state; - unsigned int given_port = 1234; - unsigned int port_container; - int rc; - rc = ssh_options_set(session, SSH_OPTIONS_PORT, &given_port); - assert_true(rc == 0); - rc = ssh_options_get_port(session, &port_container); - assert_true(rc == 0); - assert_int_equal(port_container, 1234); -} - -static void torture_options_get_user(void **state) { - ssh_session session = *state; - char* user = NULL; - int rc; - rc = ssh_options_set(session, SSH_OPTIONS_USER, "magicaltrevor"); - assert_true(rc == SSH_OK); - rc = ssh_options_get(session, SSH_OPTIONS_USER, &user); - assert_string_equal(user, "magicaltrevor"); - free(user); -} - -static void torture_options_set_fd(void **state) { - ssh_session session = *state; - socket_t fd = 42; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_FD, &fd); - assert_true(rc == 0); - assert_true(session->opts.fd == fd); - - rc = ssh_options_set(session, SSH_OPTIONS_FD, NULL); - assert_true(rc == SSH_ERROR); - assert_true(session->opts.fd == SSH_INVALID_SOCKET); -} - -static void torture_options_set_user(void **state) { - ssh_session session = *state; - int rc; -#ifndef _WIN32 -# ifndef NSS_BUFLEN_PASSWD -# define NSS_BUFLEN_PASSWD 4096 -# endif /* NSS_BUFLEN_PASSWD */ - struct passwd pwd; - struct passwd *pwdbuf; - char buf[NSS_BUFLEN_PASSWD]; - - /* get local username */ - rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf); - assert_true(rc == 0); -#endif /* _WIN32 */ - - rc = ssh_options_set(session, SSH_OPTIONS_USER, "guru"); - assert_true(rc == 0); - assert_string_equal(session->opts.username, "guru"); - - - rc = ssh_options_set(session, SSH_OPTIONS_USER, NULL); - assert_true(rc == 0); - -#ifndef _WIN32 - assert_string_equal(session->opts.username, pwd.pw_name); -#endif -} - -/* TODO */ -#if 0 -static voidtorture_options_set_sshdir) -{ -} -END_TEST -#endif - -static void torture_options_set_identity(void **state) { - ssh_session session = *state; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_ADD_IDENTITY, "identity1"); - assert_true(rc == 0); - assert_string_equal(session->opts.identity->root->data, "identity1"); - - rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "identity2"); - assert_true(rc == 0); - assert_string_equal(session->opts.identity->root->data, "identity2"); - assert_string_equal(session->opts.identity->root->next->data, "identity1"); -} - -static void torture_options_get_identity(void **state) { - ssh_session session = *state; - char *identity = NULL; - int rc; - - rc = ssh_options_set(session, SSH_OPTIONS_ADD_IDENTITY, "identity1"); - assert_true(rc == 0); - rc = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &identity); - assert_true(rc == SSH_OK); - assert_string_equal(identity, "identity1"); - SAFE_FREE(identity); - - rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "identity2"); - assert_true(rc == 0); - assert_string_equal(session->opts.identity->root->data, "identity2"); - rc = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &identity); - assert_true(rc == SSH_OK); - assert_string_equal(identity, "identity2"); - free(identity); -} - -static void torture_options_proxycommand(void **state) { - ssh_session session = *state; - int rc; - - /* Enable ProxyCommand */ - rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "ssh -q -A -X -W %h:%p JUMPHOST"); - assert_int_equal(rc, 0); - - assert_string_equal(session->opts.ProxyCommand, "ssh -q -A -X -W %h:%p JUMPHOST"); - - /* Disable ProxyCommand */ - rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "none"); - assert_int_equal(rc, 0); - - assert_null(session->opts.ProxyCommand); -} - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test_setup_teardown(torture_options_set_host, setup, teardown), - unit_test_setup_teardown(torture_options_get_host, setup, teardown), - unit_test_setup_teardown(torture_options_set_port, setup, teardown), - unit_test_setup_teardown(torture_options_get_port, setup, teardown), - unit_test_setup_teardown(torture_options_set_fd, setup, teardown), - unit_test_setup_teardown(torture_options_set_user, setup, teardown), - unit_test_setup_teardown(torture_options_get_user, setup, teardown), - unit_test_setup_teardown(torture_options_set_identity, setup, teardown), - unit_test_setup_teardown(torture_options_get_identity, setup, teardown), - unit_test_setup_teardown(torture_options_proxycommand, setup, teardown), - }; - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_pki.c b/libssh/tests/unittests/torture_pki.c deleted file mode 100644 index efcbb01b..00000000 --- a/libssh/tests/unittests/torture_pki.c +++ /dev/null @@ -1,1338 +0,0 @@ -#define LIBSSH_STATIC - -#include "torture.h" -#include "pki.c" -#include -#include - -#define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa" -#define LIBSSH_DSA_TESTKEY "libssh_testkey.id_dsa" -#define LIBSSH_ECDSA_TESTKEY "libssh_testkey.id_ecdsa" - -const unsigned char HASH[] = "12345678901234567890"; - -static void setup_rsa_key(void **state) { - (void) state; /* unused */ - - unlink(LIBSSH_RSA_TESTKEY); - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - torture_write_file(LIBSSH_RSA_TESTKEY, - torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0)); - torture_write_file(LIBSSH_RSA_TESTKEY ".pub", - torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0)); -} - -static void setup_dsa_key(void **state) { - (void) state; /* unused */ - - unlink(LIBSSH_DSA_TESTKEY); - unlink(LIBSSH_DSA_TESTKEY ".pub"); - - torture_write_file(LIBSSH_DSA_TESTKEY, - torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0)); - torture_write_file(LIBSSH_DSA_TESTKEY ".pub", - torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0)); -} - -#ifdef HAVE_OPENSSL_ECC -static void setup_ecdsa_key(void **state, int ecdsa_bits) { - - (void) state; /* unused */ - - unlink(LIBSSH_ECDSA_TESTKEY); - unlink(LIBSSH_ECDSA_TESTKEY ".pub"); - - torture_write_file(LIBSSH_ECDSA_TESTKEY, - torture_get_testkey(SSH_KEYTYPE_ECDSA, ecdsa_bits, 0)); - torture_write_file(LIBSSH_ECDSA_TESTKEY ".pub", - torture_get_testkey_pub(SSH_KEYTYPE_ECDSA, ecdsa_bits)); -} - -static void setup_ecdsa_key_521(void **state) { - setup_ecdsa_key(state, 521); -} - -static void setup_ecdsa_key_384(void **state) { - setup_ecdsa_key(state, 384); -} - -static void setup_ecdsa_key_256(void **state) { - setup_ecdsa_key(state, 256); -} -#endif - -static void setup_both_keys(void **state) { - (void) state; /* unused */ - - setup_rsa_key(state); - setup_dsa_key(state); -} - -static void teardown(void **state) { - (void) state; /* unused */ - - unlink(LIBSSH_DSA_TESTKEY); - unlink(LIBSSH_DSA_TESTKEY ".pub"); - - unlink(LIBSSH_RSA_TESTKEY); - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - unlink(LIBSSH_ECDSA_TESTKEY); - unlink(LIBSSH_ECDSA_TESTKEY ".pub"); -} - -static char *read_file(const char *filename) { - char *key; - int fd; - int size; - int rc; - struct stat sb; - - assert_true(filename != NULL); - assert_true(*filename != '\0'); - - fd = open(filename, O_RDONLY); - assert_true(fd >= 0); - - rc = fstat(fd, &sb); - assert_int_equal(rc, 0); - - key = malloc(sb.st_size + 1); - assert_true(key != NULL); - - size = read(fd, key, sb.st_size); - assert_true(size == sb.st_size); - - close(fd); - - key[size] = '\0'; - return key; -} - -static int torture_read_one_line(const char *filename, char *buffer, size_t len) { - FILE *fp; - size_t nmemb; - - fp = fopen(filename, "r"); - if (fp == NULL) { - return -1; - } - - nmemb = fread(buffer, len - 2, 1, fp); - if (nmemb != 0 || ferror(fp)) { - fclose(fp); - return -1; - } - buffer[len - 1] = '\0'; - - fclose(fp); - - return 0; -} - -/** @internal - * returns the character len of a public key string, omitting the comment part - */ -static int torture_pubkey_len(const char *pubkey){ - const char *ptr; - ptr=strchr(pubkey, ' '); - if (ptr != NULL){ - ptr = strchr(ptr + 1, ' '); - if (ptr != NULL){ - return ptr - pubkey; - } - } - return 0; -} - -static void torture_pki_keytype(void **state) { - enum ssh_keytypes_e type; - const char *type_c; - - (void) state; /* unused */ - - type = ssh_key_type(NULL); - assert_true(type == SSH_KEYTYPE_UNKNOWN); - - type = ssh_key_type_from_name(NULL); - assert_true(type == SSH_KEYTYPE_UNKNOWN); - - type = ssh_key_type_from_name("42"); - assert_true(type == SSH_KEYTYPE_UNKNOWN); - - type_c = ssh_key_type_to_char(SSH_KEYTYPE_UNKNOWN); - assert_true(type_c == NULL); - - type_c = ssh_key_type_to_char(42); - assert_true(type_c == NULL); -} - -static void torture_pki_signature(void **state) -{ - ssh_signature sig; - - (void) state; /* unused */ - - sig = ssh_signature_new(); - assert_true(sig != NULL); - - ssh_signature_free(sig); -} - -static void torture_pki_import_privkey_base64_RSA(void **state) { - int rc; - char *key_str; - ssh_key key; - const char *passphrase = torture_get_testkey_passphrase(); - enum ssh_keytypes_e type; - - (void) state; /* unused */ - - key_str = read_file(LIBSSH_RSA_TESTKEY); - assert_true(key_str != NULL); - - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); - assert_true(rc == 0); - - type = ssh_key_type(key); - assert_true(type == SSH_KEYTYPE_RSA); - - rc = ssh_key_is_public(key); - assert_true(rc == 1); - - free(key_str); - ssh_key_free(key); -} - -static void torture_pki_import_privkey_base64_NULL_key(void **state) { - int rc; - const char *passphrase = torture_get_testkey_passphrase(); - - (void) state; /* unused */ - - /* test if it returns -1 if key is NULL */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0), - passphrase, - NULL, - NULL, - NULL); - assert_true(rc == -1); - -} - -static void torture_pki_import_privkey_base64_NULL_str(void **state) { - int rc; - ssh_key key = NULL; - const char *passphrase = torture_get_testkey_passphrase(); - - (void) state; /* unused */ - - /* test if it returns -1 if key_str is NULL */ - rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key); - assert_true(rc == -1); - - ssh_key_free(key); -} - -static void torture_pki_import_privkey_base64_DSA(void **state) { - int rc; - ssh_key key; - const char *passphrase = torture_get_testkey_passphrase(); - - (void) state; /* unused */ - - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0), - passphrase, - NULL, - NULL, - &key); - assert_true(rc == 0); - - ssh_key_free(key); -} - -#ifdef HAVE_ECC -static void torture_pki_import_privkey_base64_ECDSA(void **state) { - int rc; - char *key_str; - ssh_key key; - const char *passphrase = torture_get_testkey_passphrase(); - - (void) state; /* unused */ - - key_str = read_file(LIBSSH_ECDSA_TESTKEY); - assert_true(key_str != NULL); - - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); - assert_true(rc == 0); - - free(key_str); - ssh_key_free(key); -} -#endif - -static void torture_pki_import_privkey_base64_passphrase(void **state) { - int rc; - ssh_key key = NULL; - const char *passphrase = torture_get_testkey_passphrase(); - - (void) state; /* unused */ - - - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), - passphrase, - NULL, - NULL, - &key); - assert_true(rc == 0); - ssh_key_free(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), - "wrong passphrase !!", - NULL, - NULL, - &key); - assert_true(rc == -1); - -#ifndef HAVE_LIBCRYPTO - /* test if it returns -1 if passphrase is NULL */ - /* libcrypto asks for a passphrase, so skip this test */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), - NULL, - NULL, - NULL, - &key); - assert_true(rc == -1); -#endif - - /* same for DSA */ - - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), - passphrase, - NULL, - NULL, - &key); - assert_true(rc == 0); - ssh_key_free(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), - "wrong passphrase !!", - NULL, - NULL, - &key); - assert_true(rc == -1); - -#ifndef HAVE_LIBCRYPTO - /* test if it returns -1 if passphrase is NULL */ - /* libcrypto asks for a passphrase, so skip this test */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), - NULL, - NULL, - NULL, - &key); - assert_true(rc == -1); -#endif - -} - -static void torture_pki_pki_publickey_from_privatekey_RSA(void **state) { - int rc; - ssh_key key; - ssh_key pubkey; - const char *passphrase = NULL; - - (void) state; /* unused */ - - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0), - passphrase, - NULL, - NULL, - &key); - assert_true(rc == 0); - - rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); - assert_true(rc == SSH_OK); - - ssh_key_free(key); - ssh_key_free(pubkey); -} - -static void torture_pki_pki_publickey_from_privatekey_DSA(void **state) { - int rc; - ssh_key key; - ssh_key pubkey; - const char *passphrase = NULL; - - (void) state; /* unused */ - - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0), - passphrase, - NULL, - NULL, - &key); - assert_true(rc == 0); - - rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); - assert_true(rc == SSH_OK); - - ssh_key_free(key); - ssh_key_free(pubkey); -} - -#ifdef HAVE_ECC -static void torture_pki_publickey_from_privatekey_ECDSA(void **state) { - int rc; - char *key_str; - ssh_key key; - ssh_key pubkey; - const char *passphrase = NULL; - - (void) state; /* unused */ - - key_str = read_file(LIBSSH_ECDSA_TESTKEY); - assert_true(key_str != NULL); - - rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); - assert_true(rc == 0); - - rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); - assert_true(rc == SSH_OK); - - free(key_str); - ssh_key_free(key); - ssh_key_free(pubkey); -} -#endif - -static void torture_pki_publickey_dsa_base64(void **state) -{ - enum ssh_keytypes_e type; - char *b64_key, *key_buf, *p; - const char *q; - ssh_key key; - int rc; - - (void) state; /* unused */ - - key_buf = strdup(torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0)); - assert_true(key_buf != NULL); - - q = p = key_buf; - while (*p != ' ') p++; - *p = '\0'; - - type = ssh_key_type_from_name(q); - assert_true(type == SSH_KEYTYPE_DSS); - - q = ++p; - while (*p != ' ') p++; - *p = '\0'; - - rc = ssh_pki_import_pubkey_base64(q, type, &key); - assert_true(rc == 0); - - rc = ssh_pki_export_pubkey_base64(key, &b64_key); - assert_true(rc == 0); - - assert_string_equal(q, b64_key); - - free(b64_key); - free(key_buf); - ssh_key_free(key); -} - -#ifdef HAVE_ECC -static void torture_pki_publickey_ecdsa_base64(void **state) -{ - enum ssh_keytypes_e type; - char *b64_key, *key_buf, *p; - const char *q; - ssh_key key; - int rc; - - (void) state; /* unused */ - - key_buf = read_file(LIBSSH_ECDSA_TESTKEY ".pub"); - assert_true(key_buf != NULL); - - q = p = key_buf; - while (*p != ' ') p++; - *p = '\0'; - - type = ssh_key_type_from_name(q); - assert_true(type == SSH_KEYTYPE_ECDSA); - - q = ++p; - while (*p != ' ') p++; - *p = '\0'; - - rc = ssh_pki_import_pubkey_base64(q, type, &key); - assert_true(rc == 0); - - rc = ssh_pki_export_pubkey_base64(key, &b64_key); - assert_true(rc == 0); - - assert_string_equal(q, b64_key); - - free(b64_key); - free(key_buf); - ssh_key_free(key); -} -#endif - -static void torture_pki_publickey_rsa_base64(void **state) -{ - enum ssh_keytypes_e type; - char *b64_key, *key_buf, *p; - const char *q; - ssh_key key; - int rc; - - (void) state; /* unused */ - - key_buf = strdup(torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0)); - assert_true(key_buf != NULL); - - q = p = key_buf; - while (*p != ' ') p++; - *p = '\0'; - - type = ssh_key_type_from_name(q); - assert_true(((type == SSH_KEYTYPE_RSA) || - (type == SSH_KEYTYPE_RSA1))); - - q = ++p; - while (*p != ' ') p++; - *p = '\0'; - - rc = ssh_pki_import_pubkey_base64(q, type, &key); - assert_true(rc == 0); - - rc = ssh_pki_export_pubkey_base64(key, &b64_key); - assert_true(rc == 0); - - assert_string_equal(q, b64_key); - - free(b64_key); - free(key_buf); - ssh_key_free(key); -} - -static void torture_generate_pubkey_from_privkey_rsa(void **state) { - char pubkey_generated[4096] = {0}; - ssh_key privkey; - ssh_key pubkey; - int rc; - int len; - - (void) state; /* unused */ - - /* remove the public key, generate it from the private key and write it. */ - unlink(LIBSSH_RSA_TESTKEY ".pub"); - - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - assert_true(rc == SSH_OK); - - rc = ssh_pki_export_pubkey_file(pubkey, LIBSSH_RSA_TESTKEY ".pub"); - assert_true(rc == 0); - - rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", - pubkey_generated, - sizeof(pubkey_generated)); - assert_true(rc == 0); - - len = torture_pubkey_len(torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0)); - assert_memory_equal(torture_get_testkey_pub(SSH_KEYTYPE_RSA, 0), - pubkey_generated, - len); - - ssh_key_free(privkey); - ssh_key_free(pubkey); -} - -static void torture_generate_pubkey_from_privkey_dsa(void **state) { - char pubkey_generated[4096] = {0}; - ssh_key privkey; - ssh_key pubkey; - int len; - int rc; - - (void) state; /* unused */ - - /* remove the public key, generate it from the private key and write it. */ - unlink(LIBSSH_DSA_TESTKEY ".pub"); - - rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - assert_true(rc == SSH_OK); - - rc = ssh_pki_export_pubkey_file(pubkey, LIBSSH_DSA_TESTKEY ".pub"); - assert_true(rc == 0); - - rc = torture_read_one_line(LIBSSH_DSA_TESTKEY ".pub", - pubkey_generated, - sizeof(pubkey_generated)); - assert_true(rc == 0); - - len = torture_pubkey_len(torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0)); - assert_memory_equal(torture_get_testkey_pub(SSH_KEYTYPE_DSS, 0), - pubkey_generated, - len); - - ssh_key_free(privkey); - ssh_key_free(pubkey); -} - -#ifdef HAVE_ECC -static void torture_generate_pubkey_from_privkey_ecdsa(void **state) { - char pubkey_original[4096] = {0}; - char pubkey_generated[4096] = {0}; - ssh_key privkey; - ssh_key pubkey; - int rc; - int len; - - (void) state; /* unused */ - - rc = torture_read_one_line(LIBSSH_ECDSA_TESTKEY ".pub", - pubkey_original, - sizeof(pubkey_original)); - assert_true(rc == 0); - - /* remove the public key, generate it from the private key and write it. */ - unlink(LIBSSH_ECDSA_TESTKEY ".pub"); - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - assert_true(rc == SSH_OK); - - rc = ssh_pki_export_pubkey_file(pubkey, LIBSSH_ECDSA_TESTKEY ".pub"); - assert_true(rc == 0); - - rc = torture_read_one_line(LIBSSH_ECDSA_TESTKEY ".pub", - pubkey_generated, - sizeof(pubkey_generated)); - assert_true(rc == 0); - len = torture_pubkey_len(pubkey_original); - assert_int_equal(strncmp(pubkey_original, pubkey_generated, len), 0); - - ssh_key_free(privkey); - ssh_key_free(pubkey); -} -#endif - -static void torture_pki_duplicate_key_rsa(void **state) -{ - int rc; - char *b64_key; - char *b64_key_gen; - ssh_key pubkey; - ssh_key privkey; - ssh_key privkey_dup; - - (void) state; - - rc = ssh_pki_import_pubkey_file(LIBSSH_RSA_TESTKEY ".pub", &pubkey); - assert_true(rc == 0); - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); - ssh_key_free(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - privkey_dup = ssh_key_dup(privkey); - assert_true(privkey_dup != NULL); - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - assert_true(rc == SSH_OK); - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen); - assert_true(rc == 0); - - assert_string_equal(b64_key, b64_key_gen); - - rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - - ssh_key_free(pubkey); - ssh_key_free(privkey); - ssh_key_free(privkey_dup); - ssh_string_free_char(b64_key); - ssh_string_free_char(b64_key_gen); -} - -static void torture_pki_duplicate_key_dsa(void **state) -{ - int rc; - char *b64_key; - char *b64_key_gen; - ssh_key pubkey; - ssh_key privkey; - ssh_key privkey_dup; - - (void) state; - - rc = ssh_pki_import_pubkey_file(LIBSSH_DSA_TESTKEY ".pub", &pubkey); - assert_true(rc == 0); - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); - ssh_key_free(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - privkey_dup = ssh_key_dup(privkey); - assert_true(privkey_dup != NULL); - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - assert_true(rc == SSH_OK); - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen); - assert_true(rc == 0); - - assert_string_equal(b64_key, b64_key_gen); - - rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - - ssh_key_free(pubkey); - ssh_key_free(privkey); - ssh_key_free(privkey_dup); - ssh_string_free_char(b64_key); - ssh_string_free_char(b64_key_gen); -} - -#ifdef HAVE_ECC -static void torture_pki_duplicate_key_ecdsa(void **state) -{ - int rc; - char *b64_key; - char *b64_key_gen; - ssh_key pubkey; - ssh_key privkey; - ssh_key privkey_dup; - - (void) state; - - rc = ssh_pki_import_pubkey_file(LIBSSH_ECDSA_TESTKEY ".pub", &pubkey); - assert_true(rc == 0); - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); - ssh_key_free(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - privkey_dup = ssh_key_dup(privkey); - assert_true(privkey_dup != NULL); - - rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); - assert_true(rc == SSH_OK); - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen); - assert_true(rc == 0); - - assert_string_equal(b64_key, b64_key_gen); - - rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - - ssh_key_free(pubkey); - ssh_key_free(privkey); - ssh_key_free(privkey_dup); - ssh_string_free_char(b64_key); - ssh_string_free_char(b64_key_gen); -} - -/* Test case for bug #147: Private ECDSA key duplication did not carry - * over parts of the key that then caused subsequent key demotion to - * fail. - */ -static void torture_pki_ecdsa_duplicate_then_demote(void **state) -{ - ssh_key pubkey; - ssh_key privkey; - ssh_key privkey_dup; - int rc; - - (void) state; - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - privkey_dup = ssh_key_dup(privkey); - assert_true(privkey_dup != NULL); - assert_int_equal(privkey->ecdsa_nid, privkey_dup->ecdsa_nid); - - rc = ssh_pki_export_privkey_to_pubkey(privkey_dup, &pubkey); - assert_true(rc == 0); - assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid); - - ssh_key_free(pubkey); - ssh_key_free(privkey); - ssh_key_free(privkey_dup); -} -#endif - -static void torture_pki_generate_key_rsa(void **state) -{ - int rc; - ssh_key key; - ssh_signature sign; - ssh_session session=ssh_new(); - (void) state; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 1024, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - ssh_free(session); -} - -static void torture_pki_generate_key_rsa1(void **state) -{ - int rc; - ssh_key key; - ssh_signature sign; - ssh_session session=ssh_new(); - (void) state; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 1024, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 2048, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 4096, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - ssh_free(session); -} - -static void torture_pki_generate_key_dsa(void **state) -{ - int rc; - ssh_key key; - ssh_signature sign; - ssh_session session=ssh_new(); - (void) state; - - rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 1024, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 2048, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 3072, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - ssh_free(session); -} - -#ifdef HAVE_ECC -static void torture_pki_generate_key_ecdsa(void **state) -{ - int rc; - ssh_key key; - ssh_signature sign; - enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN; - const char *type_char = NULL; - const char *etype_char = NULL; - ssh_session session=ssh_new(); - (void) state; - - rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 256, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - type = ssh_key_type(key); - assert_true(type == SSH_KEYTYPE_ECDSA); - type_char = ssh_key_type_to_char(type); - assert_true(strcmp(type_char, "ssh-ecdsa") == 0); - etype_char = ssh_pki_key_ecdsa_name(key); - assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0); - - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 384, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - type = ssh_key_type(key); - assert_true(type == SSH_KEYTYPE_ECDSA); - type_char = ssh_key_type_to_char(type); - assert_true(strcmp(type_char, "ssh-ecdsa") == 0); - etype_char =ssh_pki_key_ecdsa_name(key); - assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0); - - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key); - assert_true(rc == SSH_OK); - assert_true(key != NULL); - sign = pki_do_sign(key, HASH, 20); - assert_true(sign != NULL); - rc = pki_signature_verify(session,sign,key,HASH,20); - assert_true(rc == SSH_OK); - type = ssh_key_type(key); - assert_true(type == SSH_KEYTYPE_ECDSA); - type_char = ssh_key_type_to_char(type); - assert_true(strcmp(type_char, "ssh-ecdsa") == 0); - etype_char =ssh_pki_key_ecdsa_name(key); - assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0); - - ssh_signature_free(sign); - ssh_key_free(key); - key=NULL; - - ssh_free(session); -} -#endif - -#ifdef HAVE_LIBCRYPTO -static void torture_pki_write_privkey_rsa(void **state) -{ - ssh_key origkey; - ssh_key privkey; - int rc; - - (void) state; /* unused */ - - ssh_set_log_level(5); - - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, - NULL, - NULL, - NULL, - &origkey); - assert_true(rc == 0); - - unlink(LIBSSH_RSA_TESTKEY); - - rc = ssh_pki_export_privkey_file(origkey, - "", - NULL, - NULL, - LIBSSH_RSA_TESTKEY); - assert_true(rc == 0); - - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - - ssh_key_free(origkey); - ssh_key_free(privkey); -} - -static void torture_pki_write_privkey_dsa(void **state) -{ - ssh_key origkey; - ssh_key privkey; - int rc; - - (void) state; /* unused */ - - ssh_set_log_level(5); - - rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, - NULL, - NULL, - NULL, - &origkey); - assert_true(rc == 0); - - unlink(LIBSSH_DSA_TESTKEY); - - rc = ssh_pki_export_privkey_file(origkey, - "", - NULL, - NULL, - LIBSSH_DSA_TESTKEY); - assert_true(rc == 0); - - rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - - ssh_key_free(origkey); - ssh_key_free(privkey); -} - -#ifdef HAVE_ECC -static void torture_pki_write_privkey_ecdsa(void **state) -{ - ssh_key origkey; - ssh_key privkey; - int rc; - - (void) state; /* unused */ - - ssh_set_log_level(5); - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, - NULL, - NULL, - NULL, - &origkey); - assert_true(rc == 0); - - unlink(LIBSSH_ECDSA_TESTKEY); - - rc = ssh_pki_export_privkey_file(origkey, - "", - NULL, - NULL, - LIBSSH_ECDSA_TESTKEY); - assert_true(rc == 0); - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, - NULL, - NULL, - NULL, - &privkey); - assert_true(rc == 0); - - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - - ssh_key_free(origkey); - ssh_key_free(privkey); -} -#endif -#endif /* HAVE_LIBCRYPTO */ - -#ifdef HAVE_ECC -static void torture_pki_ecdsa_name(void **state, const char *expected_name) -{ - int rc; - ssh_key key; - const char *etype_char = NULL; - - (void) state; /* unused */ - - ssh_set_log_level(5); - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, NULL, NULL, NULL, &key); - assert_true(rc == 0); - - etype_char =ssh_pki_key_ecdsa_name(key); - assert_true(strcmp(etype_char, expected_name) == 0); - - ssh_key_free(key); -} - -static void torture_pki_ecdsa_name256(void **state) -{ - torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp256"); -} - -static void torture_pki_ecdsa_name384(void **state) -{ - torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp384"); -} - -static void torture_pki_ecdsa_name521(void **state) -{ - torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp521"); -} -#endif - -int torture_run_tests(void) { - int rc; - const UnitTest tests[] = { - unit_test(torture_pki_keytype), - - unit_test(torture_pki_signature), - - /* ssh_pki_import_privkey_base64 */ - unit_test_setup_teardown(torture_pki_import_privkey_base64_NULL_key, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pki_import_privkey_base64_NULL_str, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pki_import_privkey_base64_RSA, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pki_import_privkey_base64_DSA, - setup_dsa_key, - teardown), -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, - setup_ecdsa_key_521, - teardown), -#endif - unit_test(torture_pki_import_privkey_base64_passphrase), - /* ssh_pki_export_privkey_to_pubkey */ - unit_test_setup_teardown(torture_pki_pki_publickey_from_privatekey_RSA, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pki_pki_publickey_from_privatekey_DSA, - setup_dsa_key, - teardown), -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA, - setup_ecdsa_key_521, - teardown), - unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote, - setup_ecdsa_key_521, - teardown), -#endif - /* public key */ - unit_test_setup_teardown(torture_pki_publickey_dsa_base64, - setup_dsa_key, - teardown), - unit_test_setup_teardown(torture_pki_publickey_rsa_base64, - setup_rsa_key, - teardown), -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64, - setup_ecdsa_key_521, - teardown), -#endif - - unit_test_setup_teardown(torture_generate_pubkey_from_privkey_dsa, - setup_dsa_key, - teardown), - unit_test_setup_teardown(torture_generate_pubkey_from_privkey_rsa, - setup_rsa_key, - teardown), -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa, - setup_ecdsa_key_521, - teardown), -#endif - - unit_test_setup_teardown(torture_pki_duplicate_key_rsa, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pki_duplicate_key_dsa, - setup_dsa_key, - teardown), -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa, - setup_ecdsa_key_521, - teardown), -#endif - unit_test(torture_pki_generate_key_rsa), - unit_test(torture_pki_generate_key_rsa1), - unit_test(torture_pki_generate_key_dsa), -#ifdef HAVE_ECC - unit_test(torture_pki_generate_key_ecdsa), -#endif -#ifdef HAVE_LIBCRYPTO - unit_test_setup_teardown(torture_pki_write_privkey_rsa, - setup_rsa_key, - teardown), - unit_test_setup_teardown(torture_pki_write_privkey_dsa, - setup_dsa_key, - teardown), -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_pki_write_privkey_ecdsa, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_write_privkey_ecdsa, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_write_privkey_ecdsa, - setup_ecdsa_key_521, - teardown), -#endif -#endif /* HAVE_LIBCRYPTO */ -#ifdef HAVE_ECC - unit_test_setup_teardown(torture_pki_ecdsa_name256, - setup_ecdsa_key_256, - teardown), - unit_test_setup_teardown(torture_pki_ecdsa_name384, - setup_ecdsa_key_384, - teardown), - unit_test_setup_teardown(torture_pki_ecdsa_name521, - setup_ecdsa_key_521, - teardown), -#endif - }; - - (void)setup_both_keys; - - ssh_init(); - rc=run_tests(tests); - ssh_finalize(); - return rc; -} diff --git a/libssh/tests/unittests/torture_rand.c b/libssh/tests/unittests/torture_rand.c deleted file mode 100644 index 829989b0..00000000 --- a/libssh/tests/unittests/torture_rand.c +++ /dev/null @@ -1,68 +0,0 @@ -#define LIBSSH_STATIC -#include -#include -#include -#include -#include "torture.h" - -#ifdef HAVE_LIBGCRYPT -#define NUM_LOOPS 1000 -#else -/* openssl is much faster */ -#define NUM_LOOPS 20000 -#endif -#define NUM_THREADS 100 - -static void setup(void **state) { - (void) state; - - ssh_threads_set_callbacks(ssh_threads_get_pthread()); - ssh_init(); -} - -static void teardown(void **state) { - (void) state; - - ssh_finalize(); -} - -static void *torture_rand_thread(void *threadid) { - char buffer[12]; - int i; - int r; - - (void) threadid; - - buffer[0] = buffer[1] = buffer[10] = buffer[11] = 'X'; - for(i = 0; i < NUM_LOOPS; ++i) { - r = ssh_get_random(&buffer[2], i % 8 + 1, 0); - assert_true(r == 1); - } - - pthread_exit(NULL); -} - -static void torture_rand_threading(void **state) { - pthread_t threads[NUM_THREADS]; - int i; - int err; - - (void) state; - - for(i = 0; i < NUM_THREADS; ++i) { - err = pthread_create(&threads[i], NULL, torture_rand_thread, NULL); - assert_int_equal(err, 0); - } - for(i = 0; i < NUM_THREADS; ++i) { - err=pthread_join(threads[i], NULL); - assert_int_equal(err, 0); - } -} - -int torture_run_tests(void) { - const UnitTest tests[] = { - unit_test_setup_teardown(torture_rand_threading, setup, teardown), - }; - - return run_tests(tests); -} diff --git a/libssh/tests/valgrind.supp b/libssh/tests/valgrind.supp deleted file mode 100644 index a4276c3b..00000000 --- a/libssh/tests/valgrind.supp +++ /dev/null @@ -1,117 +0,0 @@ -### GLIBC -{ - glibc_regcomp - Memcheck:Leak - fun:*alloc - ... - fun:regcomp -} -{ - glibc_getaddrinfo_leak - Memcheck:Leak - fun:malloc - fun:make_request - fun:__check_pf - fun:getaddrinfo - fun:getai - fun:ssh_connect_host_nonblocking -} - -{ - glibc_dlopen_getdelim_selinux - Memcheck:Leak - fun:malloc - fun:getdelim - obj:/lib64/libselinux.so.1 - fun:call_init - fun:_dl_init - obj:/lib64/ld-2.15.so -} - -### OPENSSL -{ - openssl_crypto_value8 - Memcheck:Value8 - fun:* - obj:/lib*/libcrypto.so* -} - -{ - openssl_crypto_value4 - Memcheck:Value4 - fun:* - obj:/lib*/libcrypto.so* -} - -{ - openssl_crypto_cond - Memcheck:Cond - fun:* - obj:/lib*/libcrypto.so* -} - -{ - openssl_BN_cond - Memcheck:Cond - fun:BN_* -} - -{ - openssl_bn_value8 - Memcheck:Value8 - fun:bn_* -} - -{ - openssl_bn_value4 - Memcheck:Value4 - fun:bn_* -} - -{ - openssl_AES_cond - Memcheck:Cond - fun:AES_* -} - -{ - openssl_DES_cond - Memcheck:Cond - fun:DES_* -} - -{ - openssl_DES_value8 - Memcheck:Value8 - fun:DES_* -} - -{ - openssl_DES_value4 - Memcheck:Value4 - fun:DES_* -} - -{ - openssl_BF_cond - Memcheck:Cond - fun:BF_* -} - -{ - openssl_SHA1_cond - Memcheck:Cond - fun:SHA1_* -} - -{ - openssl_CRYPTO_leak - Memcheck:Leak - fun:*alloc - fun:CRYPTO_* -} -{ - openssl_CRYPTO_leak - Memcheck:Cond - fun:OPENSSL_cleanse -} diff --git a/msgpack/.gitignore b/msgpack/.gitignore deleted file mode 100644 index ca7355a4..00000000 --- a/msgpack/.gitignore +++ /dev/null @@ -1,58 +0,0 @@ -# Files generated by the bootstrap script. -/INSTALL -/NEWS -/README -/ac/ -/aclocal.m4 -/autom4te.cache/ -/config.h.in -/configure -/msgpack_vc2008.sln -/msgpack_vc2008.vcproj -/src/msgpack/pack_define.h -/src/msgpack/pack_template.h -/src/msgpack/sysdep.h -/src/msgpack/type/define.hpp -/src/msgpack/type/tuple.hpp -/src/msgpack/unpack_define.h -/src/msgpack/unpack_template.h -/src/msgpack/zone.hpp -/test/cases.mpac -/test/cases_compact.mpac -Makefile.in - -# Files generated by the configure script. - -/config.h -/config.log -/config.status -/libtool -/msgpack.pc -/src/msgpack/version.h -/stamp-h1 -Makefile -.deps -.libs - -# Files generated by make. -*.o -*.so -*.lo -*.la - -# Files generated by make check. -# TODO: Replace these with something like /test/*_test -/test/buffer -/test/cases -/test/convert -/test/fixint -/test/fixint_c -/test/msgpack_test -/test/msgpackc_test -/test/object -/test/pack_unpack -/test/pack_unpack_c -/test/streaming -/test/streaming_c -/test/version -/test/zone diff --git a/msgpack/AUTHORS b/msgpack/AUTHORS deleted file mode 100644 index ababacb0..00000000 --- a/msgpack/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -FURUHASHI Sadayuki diff --git a/msgpack/COPYING b/msgpack/COPYING deleted file mode 100644 index 4388e8fa..00000000 --- a/msgpack/COPYING +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (C) 2008-2010 FURUHASHI Sadayuki - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/msgpack/ChangeLog b/msgpack/ChangeLog deleted file mode 100644 index a983051a..00000000 --- a/msgpack/ChangeLog +++ /dev/null @@ -1,51 +0,0 @@ - -2011-08-08 version 0.5.7: - - * fixes compile error problem with llvm-gcc and Mac OS X Lion - -2011-04-24 version 0.5.6: - - * #42 fixes double-free problem on msgpack_unpacker_release_zone - -2011-02-24 version 0.5.5: - - * eliminates dependency of winsock2.h header - * fixes msgpack_vc.postbuild.bat file - * fixes some implicit cast warnings - -2010-08-29 version 0.5.4: - - * includes msgpack_vc2008.vcproj file in source package - * fixes type::fix_int types - -2010-08-27 version 0.5.3: - - * adds type::fix_{u,}int{8,16,32,64} types - * adds msgpack_pack_fix_{u,}int{8,16,32,64} functions - * adds packer::pack_fix_{u,}int{8,16,32,64} functions - * fixes include paths - -2010-07-14 version 0.5.2: - - * type::raw::str(), operator==, operator!=, operator< and operator> are now const - * generates version.h using AC_OUTPUT macro in ./configure - -2010-07-06 version 0.5.1: - - * Add msgpack_vrefbuffer_new and msgpack_vrefbuffer_free - * Add msgpack_sbuffer_new and msgpack_sbuffer_free - * Add msgpack_unpacker_next and msgpack_unpack_next - * msgpack::unpack returns void - * Add MSGPACK_VERSION{,_MAJOR,_MINOR} macros to check header version - * Add msgpack_version{,_major,_minor} functions to check library version - * ./configure supports --disable-cxx option not to build C++ API - -2010-04-29 version 0.5.0: - - * msgpack_object_type is changed. MSGPACK_OBJECT_NIL is now 0x00. - * New safe streaming deserializer API. - * Add object::object(const T&) and object::operator=(const T&) - * Add operator==(object, const T&) - * MSGPACK_DEFINE macro defines msgpack_object(object* obj, zone* z) - * C++ programs doesn't need to link "msgpackc" library. - diff --git a/msgpack/Doxyfile b/msgpack/Doxyfile deleted file mode 100644 index ca772301..00000000 --- a/msgpack/Doxyfile +++ /dev/null @@ -1,1552 +0,0 @@ -# Doxyfile 1.6.2 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "MessagePack" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = *.hpp *.h - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -#RECURSIVE = NO -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = NO - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/msgpack/LICENSE b/msgpack/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/msgpack/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/msgpack/Makefile.am b/msgpack/Makefile.am deleted file mode 100644 index bcc24a42..00000000 --- a/msgpack/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -SUBDIRS = src test - -DOC_FILES = \ - README.md \ - LICENSE \ - NOTICE \ - msgpack_vc8.vcproj \ - msgpack_vc8.sln \ - msgpack_vc2008.vcproj \ - msgpack_vc2008.sln \ - msgpack_vc.postbuild.bat - -EXTRA_DIST = \ - $(DOC_FILES) - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = msgpack.pc - -doxygen: - ./preprocess clean - cd src && $(MAKE) doxygen - ./preprocess - diff --git a/msgpack/NOTICE b/msgpack/NOTICE deleted file mode 100644 index e706f2ab..00000000 --- a/msgpack/NOTICE +++ /dev/null @@ -1,4 +0,0 @@ -MessagePack is developed by FURUHASHI Sadayuki, licensed under Apache License, -Version 2.0. The original software and related information is available at -http://msgpack.sourceforge.jp/. - diff --git a/msgpack/README.md b/msgpack/README.md deleted file mode 100644 index eac77935..00000000 --- a/msgpack/README.md +++ /dev/null @@ -1,73 +0,0 @@ -MessagePack for C/C++ -===================== -Binary-based efficient object serialization library. - - -## Installation - -Download latest package from [releases of MessagePack](http://sourceforge.net/projects/msgpack/files/) and extract it. - -On UNIX-like platform, run ./configure && make && sudo make install: - - $ ./configure - $ make - $ sudo make install - -On Windows, open msgpack_vc8.vcproj or msgpack_vc2008 file and build it using batch build. DLLs are built on lib folder, -and the headers are built on include folder. - -To use the library in your program, include msgpack.hpp header and link "msgpack" library. - - -## Example - - #include - #include - - int main(void) { - // This is target object. - std::vector target; - target.push_back("Hello,"); - target.push_back("World!"); - - // Serialize it. - msgpack::sbuffer buffer; // simple buffer - msgpack::pack(&buffer, target); - - // Deserialize the serialized data. - msgpack::unpacked msg; // includes memory pool and deserialized object - msgpack::unpack(&msg, sbuf.data(), sbuf.size()); - msgpack::object obj = msg.get(); - - // Print the deserialized object to stdout. - std::cout << obj << std::endl; // ["Hello," "World!"] - - // Convert the deserialized object to staticaly typed object. - std::vector result; - obj.convert(&result); - - // If the type is mismatched, it throws msgpack::type_error. - obj.as(); // type is mismatched, msgpack::type_error is thrown - } - -API documents and other example codes are available at the [wiki.](http://redmine.msgpack.org/projects/msgpack/wiki) - - -## License - - Copyright (C) 2008-2010 FURUHASHI Sadayuki - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -See also NOTICE file. - diff --git a/msgpack/README_crosslang.md b/msgpack/README_crosslang.md deleted file mode 100644 index 80270022..00000000 --- a/msgpack/README_crosslang.md +++ /dev/null @@ -1,38 +0,0 @@ -MessagePack cross-language test cases -===================================== - -## cases - -Valid serialized data are stored in "cases.mpac" and "cases_compact.mpac". -These files describe same objects. And "cases.json" describes an array of the described objects. - -Thus you can verify your implementations as comparing the objects. - - -## crosslang - -The *crosslang* tool reads serialized data from stdin and writes re-serialize data to stdout. - -There are C++ and Ruby implementation of crosslang tool. You can verify your implementation -as comparing that implementations. - -### C++ version - - $ cd ../cpp && ./configure && make && make install - or - $ port install msgpack # MacPorts - - $ g++ -Wall -lmsgpack crosslang.cc -o crosslang - - $ ./crosslang - Usage: ./crosslang [in-file] [out-file] - -### Ruby version - - $ gem install msgpack - or - $ port install rb_msgpack # MacPorts - - $ ruby crosslang.rb - Usage: crosslang.rb [in-file] [out-file] - diff --git a/msgpack/bootstrap b/msgpack/bootstrap deleted file mode 100755 index 1ff6b76e..00000000 --- a/msgpack/bootstrap +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/sh -# vim:ts=4:sw=4 -# Calls autotools to build configure script and Makefile.in. -# Generated automatically using bootstrapper 0.2.1 -# http://bootstrapper.sourceforge.net/ -# -# Copyright (C) 2002 Anthony Ventimiglia -# -# This bootstrap script is free software; you can redistribute -# it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# -# Calls proper programs to create configure script and Makefile.in files. -# if run with the --clean option, bootstrap removes files it generates. To -# clean all autogenerated files (eg: for cvs imports) first run -# make distclean, then bootstrap --clean -# see bootstrapper(1) for more infor - - -if test x"$1" = x"--help"; then - echo "$0: automatic bootstrapping utility for GNU Autotools" - echo " cleans up old autogenerated files and runs autoconf," - echo " automake and aclocal on local directory" - echo - echo " --clean clean up auto-generated files without" - echo " creating new scripts" - echo - exit 0 -fi - - -mkdir -p ac -test -f AUTHORS || touch AUTHORS -test -f COPYING || touch COPYING -test -f ChangeLog || touch ChangeLog -test -f NEWS || touch NEWS -test -f README || cp -f README.md README - -./preprocess -if [ $? -ne 0 ]; then - exit 1 -fi - - - -ACLOCAL="aclocal" -ACLOCAL_FILES="aclocal.m4" -ALWAYS_CLEAN="config.status config.log config.cache libtool" -AUTOCONF="autoconf" -AUTOCONF_FILES="configure" -AUTOHEADER="autoheader" -AUTOHEADER_FILES="" -AUTOMAKE="automake --add-missing --copy" -AUTOMAKE_FILES="config.sub stamp-h.in ltmain.sh missing mkinstalldirs install-sh config.guess" -CONFIG_AUX_DIR="." -CONFIG_FILES="stamp-h ltconfig" -CONFIG_HEADER="" -if [ x`uname` = x"Darwin" ]; then - LIBTOOLIZE="glibtoolize --force --copy" -else - LIBTOOLIZE="libtoolize --force --copy" -fi -LIBTOOLIZE_FILES="config.sub ltmain.sh config.guess" -RM="rm" -SUBDIRS="[]" - - -# These are files created by configure, so we'll always clean them -for i in $ALWAYS_CLEAN; do - test -f $i && \ - $RM $i -done - -if test x"$1" = x"--clean"; then - # - #Clean Files left by previous bootstrap run - # - if test -n "$CONFIG_AUX_DIR"; - then CONFIG_AUX_DIR="$CONFIG_AUX_DIR/" - fi - # Clean Libtoolize generated files - for cf in $LIBTOOLIZE_FILES; do - cf="$CONFIG_AUX_DIR$cf" - test -f $cf && \ - $RM $cf - done - #aclocal.m4 created by aclocal - test -f $ACLOCAL_FILES && $RM $ACLOCAL_FILES - #Clean Autoheader Generated files - for cf in $AUTOHEADER_FILES; do - cf=$CONFIG_AUX_DIR$cf - test -f $cf && \ - $RM $cf - done - # remove config header (Usaually config.h) - test -n "$CONFIG_HEADER" && test -f $CONFIG_HEADER && $RM $CONFIG_HEADER - #Clean Automake generated files - for cf in $AUTOMAKE_FILES; do - cf=$CONFIG_AUX_DIR$cf - test -f $cf && \ - $RM $cf - done - for i in $SUBDIRS; do - test -f $i/Makefile.in && \ - $RM $i/Makefile.in - done - #Autoconf generated files - for cf in $AUTOCONF_FILES; do - test -f $cf && \ - $RM $cf - done - for cf in $CONFIG_FILES; do - cf="$CONFIG_AUX_DIR$cf" - test -f $cf && \ - $RM $cf - done -else - $LIBTOOLIZE - $ACLOCAL - $AUTOHEADER - $AUTOMAKE - $AUTOCONF -fi - - diff --git a/msgpack/cases.json b/msgpack/cases.json deleted file mode 100644 index fd390d48..00000000 --- a/msgpack/cases.json +++ /dev/null @@ -1 +0,0 @@ -[false,true,null,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,127,127,255,65535,4294967295,-32,-32,-128,-32768,-2147483648,0.0,-0.0,1.0,-1.0,"a","a","a","","","",[0],[0],[0],[],[],[],{},{},{},{"a":97},{"a":97},{"a":97},[[]],[["a"]]] \ No newline at end of file diff --git a/msgpack/cases.mpac b/msgpack/cases.mpac deleted file mode 100644 index 5ec08c6a..00000000 Binary files a/msgpack/cases.mpac and /dev/null differ diff --git a/msgpack/cases_compact.mpac b/msgpack/cases_compact.mpac deleted file mode 100644 index 8812442d..00000000 Binary files a/msgpack/cases_compact.mpac and /dev/null differ diff --git a/msgpack/cases_gen.rb b/msgpack/cases_gen.rb deleted file mode 100644 index 95662fbb..00000000 --- a/msgpack/cases_gen.rb +++ /dev/null @@ -1,99 +0,0 @@ -# -# MessagePack format test case -# -begin -require 'rubygems' -rescue LoadError -end -require 'msgpack' -require 'json' - -source = <97} FixMap -de 00 01 a1 61 61 # {"a"=>97} map 16 -df 00 00 00 01 a1 61 61 # {"a"=>97} map 32 -91 90 # [[]] -91 91 a1 61 # [["a"]] -EOF - -source.gsub!(/\#.+$/,'') -bytes = source.strip.split(/\s+/).map {|x| x.to_i(16) }.pack('C*') - -objs = [] -compact_bytes = "" - -pac = MessagePack::Unpacker.new -pac.feed(bytes) -pac.each {|obj| - p obj - objs << obj - compact_bytes << obj.to_msgpack -} - -json = objs.to_json - -# self check -cpac = MessagePack::Unpacker.new -cpac.feed(compact_bytes) -cpac.each {|cobj| - obj = objs.shift - if obj != cobj - puts "** SELF CHECK FAILED **" - puts "expected: #{obj.inspect}" - puts "actual: #{cobj.inspect}" - exit 1 - end -} - -File.open("cases.mpac","w") {|f| f.write(bytes) } -File.open("cases_compact.mpac","w") {|f| f.write(compact_bytes) } -File.open("cases.json","w") {|f| f.write(json) } - diff --git a/msgpack/configure.in b/msgpack/configure.in deleted file mode 100644 index e7540187..00000000 --- a/msgpack/configure.in +++ /dev/null @@ -1,100 +0,0 @@ -AC_INIT(src/object.cpp) -AC_CONFIG_AUX_DIR(ac) -AM_INIT_AUTOMAKE(msgpack, 0.5.7) -AC_CONFIG_HEADER(config.h) - -AC_SUBST(CFLAGS) -CFLAGS="-O3 -Wall $CFLAGS" - -AC_SUBST(CXXFLAGS) -CXXFLAGS="-O3 -Wall $CXXFLAGS" - - -AC_PROG_CC - - -AC_MSG_CHECKING([if C++ API is enabled]) -AC_ARG_ENABLE(cxx, - AS_HELP_STRING([--disable-cxx], - [don't build C++ API]) ) #' -AC_MSG_RESULT([$enable_cxx]) -if test "$enable_cxx" != "no"; then - AC_PROG_CXX - AM_PROG_CC_C_O -fi -AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no") - - -AC_PROG_LIBTOOL -AM_PROG_AS - - -AC_MSG_CHECKING([if debug option is enabled]) -AC_ARG_ENABLE(debug, - AS_HELP_STRING([--disable-debug], - [disable assert macros and omit -g option]) ) -AC_MSG_RESULT([$enable_debug]) -if test "$enable_debug" != "no"; then - CXXFLAGS="$CXXFLAGS -g" - CFLAGS="$CFLAGS -g" -else - CXXFLAGS="$CXXFLAGS -DNDEBUG" - CFLAGS="$CFLAGS -DNDEBUG" -fi - - -AC_CACHE_CHECK([for __sync_* atomic operations], msgpack_cv_atomic_ops, [ - AC_TRY_LINK([ - int atomic_sub(int i) { return __sync_sub_and_fetch(&i, 1); } - int atomic_add(int i) { return __sync_add_and_fetch(&i, 1); } - ], [atomic_sub(1); atomic_add(1);], msgpack_cv_atomic_ops="yes") - ]) -if test "$msgpack_cv_atomic_ops" != "yes"; then - if test "$enable_cxx" = "no"; then - AC_MSG_ERROR([__sync_* atomic operations are not found. Try to enable C++ support. -If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to -add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows: - - $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686" - ]) - fi - - AC_LANG_PUSH([C++]) - AC_CACHE_CHECK([for __gnu_cxx::__exchange_and_add], msgpack_cv_gcc_cxx_atomic_ops, [ - AC_TRY_LINK([ - #include - int atomic_sub(int i) { return __gnu_cxx::__exchange_and_add(&i, -1) - 1; } - int atomic_add(int i) { return __gnu_cxx::__exchange_and_add(&i, 1) + 1; } - ], [atomic_sub(1); atomic_add(1);], msgpack_cv_gcc_cxx_atomic_ops="yes") - ]) - AC_LANG_POP([C++]) - - if test "$msgpack_cv_gcc_cxx_atomic_ops" != "yes"; then - AC_MSG_ERROR([__sync_* atomic operations nor __gnu_cxx::__exchange_and_add are not found. - -If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to -add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows: - - $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686" -]) - - else - enable_gcc_cxx_atomic=yes - fi -fi - -AM_CONDITIONAL(ENABLE_GCC_CXX_ATOMIC, test "$enable_gcc_cxx_atomic" = "yes") - - -major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` -minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` -AC_SUBST(VERSION_MAJOR, $major) -AC_SUBST(VERSION_MINOR, $minor) - - -AC_OUTPUT([Makefile - msgpack.pc - src/Makefile - src/msgpack/version.h - test/Makefile]) - diff --git a/msgpack/crosslang.cc b/msgpack/crosslang.cc deleted file mode 100644 index be521b36..00000000 --- a/msgpack/crosslang.cc +++ /dev/null @@ -1,133 +0,0 @@ -// -// MessagePack cross-language test tool -// -// $ cd ../cpp && ./configure && make && make install -// or -// $ port install msgpack # MacPorts -// -// $ g++ -Wall -lmsgpack crosslang.cc -// -#include -#include -#include -#include -#include -#include -#include - -static int run(int infd, int outfd) -try { - msgpack::unpacker pac; - - while(true) { - pac.reserve_buffer(32*1024); - - ssize_t count = - read(infd, pac.buffer(), pac.buffer_capacity()); - - if(count <= 0) { - if(count == 0) { - return 0; - } - if(errno == EAGAIN || errno == EINTR) { - continue; - } - return 1; - } - - pac.buffer_consumed(count); - - msgpack::unpacked result; - while(pac.next(&result)) { - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, result.get()); - - const char* p = sbuf.data(); - const char* const pend = p + sbuf.size(); - while(p < pend) { - ssize_t bytes = write(outfd, p, pend-p); - - if(bytes <= 0) { - if(count == 0) { - return 0; - } - if(errno == EAGAIN || errno == EINTR) { - continue; - } - return 1; - } - - p += bytes; - } - - } - } - - return 0; - -} catch (std::exception& e) { - std::cerr << e.what() << std::endl; - return 1; -} - -static void usage(const char* prog) -{ - printf( - "Usage: %s [in-file] [out-file]\n" - "\n" - "This tool is for testing of MessagePack implementation.\n" - "This does following behavior:\n" - "\n" - " 1. Reads objects serialized by MessagePack from (default: stdin)\n" - " 2. Re-serializes the objects using C++ implementation of MessagePack (Note that C++ implementation is considered valid)\n" - " 3. Writes the re-serialized objects into (default: stdout)\n" - "\n" - , prog); - exit(1); -} - -int main(int argc, char* argv[]) -{ - int infd = 0; - int outfd = 1; - - if(argc < 1 || argc > 3) { - usage(argv[0]); - } - - for(int i=1; i < argc; ++i) { - if(strlen(argv[i]) > 1 && argv[i][0] == '-') { - usage(argv[0]); - } - } - - if(argc >= 2) { - const char* fname = argv[1]; - if(strcmp(fname, "-") != 0) { - infd = open(fname, O_RDONLY); - if(infd < 0) { - perror("can't open input file"); - exit(1); - } - } - } - - if(argc >= 3) { - const char* fname = argv[2]; - if(strcmp(fname, "-") != 0) { - outfd = open(fname, O_WRONLY | O_CREAT| O_TRUNC, 0666); - if(outfd < 0) { - perror("can't open output file"); - exit(1); - } - } - } - - int code = run(infd, outfd); - - close(infd); - close(outfd); - - return code; -} - diff --git a/msgpack/crosslang.rb b/msgpack/crosslang.rb deleted file mode 100644 index 7aa44820..00000000 --- a/msgpack/crosslang.rb +++ /dev/null @@ -1,88 +0,0 @@ -# -# MessagePack cross-language test tool -# -# $ gem install msgpack -# or -# $ port install rb_msgpack # MacPorts -# -begin -require 'rubygems' -rescue LoadError -end -require 'msgpack' - -def run(inio, outio) - pac = MessagePack::Unpacker.new(inio) - - begin - pac.each {|obj| - outio.write MessagePack.pack(obj) - outio.flush - } - rescue EOFError - return 0 - rescue - $stderr.puts $! - return 1 - end - - return 0 -end - -def usage - puts < (default: stdin) - 2. Re-serializes the objects using Ruby implementation of MessagePack (Note that Ruby implementation is considered valid) - 3. Writes the re-serialized objects into (default: stdout) - -EOF - exit 1 -end - -inio = $stdin -outio = $stdout - -if ARGV.length > 2 - usage -end - -ARGV.each {|str| - if str.size > 1 && str[0] == ?- - usage - end -} - -if fname = ARGV[0] - unless fname == "-" - begin - inio = File.open(fname) - rescue - puts "can't open output file: #{$!}" - exit 1 - end - end -end - -if fname = ARGV[1] - unless fname == "-" - begin - outio = File.open(fname, "w") - rescue - puts "can't open output file: #{$!}" - exit 1 - end - end -end - -code = run(inio, outio) - -inio.close -outio.close - -exit code - diff --git a/msgpack/example/custom.cc b/msgpack/example/custom.cc deleted file mode 100644 index 835ebed9..00000000 --- a/msgpack/example/custom.cc +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include - -class old_class { -public: - old_class() : value("default") { } - - std::string value; - - MSGPACK_DEFINE(value); -}; - -class new_class { -public: - new_class() : value("default"), flag(-1) { } - - std::string value; - int flag; - - MSGPACK_DEFINE(value, flag); -}; - -int main(void) -{ - { - old_class oc; - new_class nc; - - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, oc); - - msgpack::zone zone; - msgpack::object obj; - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj); - - obj.convert(&nc); - - std::cout << obj << " value=" << nc.value << " flag=" << nc.flag << std::endl; - } - - { - new_class nc; - old_class oc; - - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, nc); - - msgpack::zone zone; - msgpack::object obj; - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj); - - obj.convert(&oc); - - std::cout << obj << " value=" << oc.value << std::endl; - } -} - diff --git a/msgpack/example/protocol.cc b/msgpack/example/protocol.cc deleted file mode 100644 index e7f2a387..00000000 --- a/msgpack/example/protocol.cc +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include -#include - -namespace myprotocol { - using namespace msgpack::type; - using msgpack::define; - - struct Get : define< tuple > { - Get() { } - Get(uint32_t f, const std::string& k) : - define_type(msgpack_type(f, k)) { } - uint32_t& flags() { return get<0>(); } - std::string& key() { return get<1>(); } - }; - - struct Put : define< tuple > { - Put() { } - Put(uint32_t f, const std::string& k, const char* valref, size_t vallen) : - define_type(msgpack_type( f, k, raw_ref(valref,vallen) )) { } - uint32_t& flags() { return get<0>(); } - std::string& key() { return get<1>(); } - raw_ref& value() { return get<2>(); } - }; - - struct MultiGet : define< std::vector > { - }; -} - - -int main(void) -{ - // send Get request - std::stringstream stream; - { - myprotocol::Get req; - req.flags() = 0; - req.key() = "key0"; - msgpack::pack(stream, req); - } - - stream.seekg(0); - - // receive Get request - { - std::string buffer(stream.str()); - - msgpack::zone mempool; - msgpack::object o = - msgpack::unpack(buffer.data(), buffer.size(), mempool); - - myprotocol::Get req; - msgpack::convert(req, o); - std::cout << "received: " << o << std::endl; - } - - - stream.str(""); - - - // send MultiGet request - { - myprotocol::MultiGet req; - req.push_back( myprotocol::Get(1, "key1") ); - req.push_back( myprotocol::Get(2, "key2") ); - req.push_back( myprotocol::Get(3, "key3") ); - msgpack::pack(stream, req); - } - - stream.seekg(0); - - // receive MultiGet request - { - std::string buffer(stream.str()); - - msgpack::zone mempool; - msgpack::object o = - msgpack::unpack(buffer.data(), buffer.size(), mempool); - - myprotocol::MultiGet req; - msgpack::convert(req, o); - std::cout << "received: " << o << std::endl; - } -} - diff --git a/msgpack/example/simple.c b/msgpack/example/simple.c deleted file mode 100644 index 41d8bb70..00000000 --- a/msgpack/example/simple.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -int main(void) -{ - /* msgpack::sbuffer is a simple buffer implementation. */ - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - - /* serialize values into the buffer using msgpack_sbuffer_write callback function. */ - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - - msgpack_pack_array(&pk, 3); - msgpack_pack_int(&pk, 1); - msgpack_pack_true(&pk); - msgpack_pack_raw(&pk, 7); - msgpack_pack_raw_body(&pk, "example", 7); - - /* deserialize the buffer into msgpack_object instance. */ - /* deserialized object is valid during the msgpack_zone instance alive. */ - msgpack_zone mempool; - msgpack_zone_init(&mempool, 2048); - - msgpack_object deserialized; - msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized); - - /* print the deserialized object. */ - msgpack_object_print(stdout, deserialized); - puts(""); - - msgpack_zone_destroy(&mempool); - msgpack_sbuffer_destroy(&sbuf); - - return 0; -} - diff --git a/msgpack/example/simple.cc b/msgpack/example/simple.cc deleted file mode 100644 index 55ecdf92..00000000 --- a/msgpack/example/simple.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include - -int main(void) -{ - msgpack::type::tuple src(1, true, "example"); - - // serialize the object into the buffer. - // any classes that implements write(const char*,size_t) can be a buffer. - std::stringstream buffer; - msgpack::pack(buffer, src); - - // send the buffer ... - buffer.seekg(0); - - // deserialize the buffer into msgpack::object instance. - std::string str(buffer.str()); - - // deserialized object is valid during the msgpack::zone instance alive. - msgpack::zone mempool; - - msgpack::object deserialized; - msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized); - - // msgpack::object supports ostream. - std::cout << deserialized << std::endl; - - // convert msgpack::object instance into the original type. - // if the type is mismatched, it throws msgpack::type_error exception. - msgpack::type::tuple dst; - deserialized.convert(&dst); - - return 0; -} - diff --git a/msgpack/example/stream.cc b/msgpack/example/stream.cc deleted file mode 100644 index 2241935c..00000000 --- a/msgpack/example/stream.cc +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -class Server { -public: - Server(int sock) : m_sock(sock) { } - - ~Server() { } - - typedef std::auto_ptr auto_zone; - - void socket_readable() - { - m_pac.reserve_buffer(1024); - - ssize_t count = - read(m_sock, m_pac.buffer(), m_pac.buffer_capacity()); - - if(count <= 0) { - if(count == 0) { - throw std::runtime_error("connection closed"); - } - if(errno == EAGAIN || errno == EINTR) { - return; - } - throw std::runtime_error(strerror(errno)); - } - - m_pac.buffer_consumed(count); - - while(m_pac.execute()) { - msgpack::object msg = m_pac.data(); - - auto_zone life( m_pac.release_zone() ); - - m_pac.reset(); - - process_message(msg, life); - } - - if(m_pac.message_size() > 10*1024*1024) { - throw std::runtime_error("message is too large"); - } - } - -private: - void process_message(msgpack::object msg, auto_zone& life) - { - std::cout << "message reached: " << msg << std::endl; - } - -private: - int m_sock; - msgpack::unpacker m_pac; -}; - - -static void* run_server(void* arg) -try { - Server* srv = reinterpret_cast(arg); - - while(true) { - srv->socket_readable(); - } - return NULL; - -} catch (std::exception& e) { - std::cerr << "error while processing client packet: " - << e.what() << std::endl; - return NULL; - -} catch (...) { - std::cerr << "error while processing client packet: " - << "unknown error" << std::endl; - return NULL; -} - - -struct fwriter { - fwriter(int fd) : m_fp( fdopen(fd, "w") ) { } - - void write(const char* buf, size_t buflen) - { - size_t count = fwrite(buf, buflen, 1, m_fp); - if(count < 1) { - std::cout << buflen << std::endl; - std::cout << count << std::endl; - throw std::runtime_error(strerror(errno)); - } - } - - void flush() { fflush(m_fp); } - - void close() { fclose(m_fp); } - -private: - FILE* m_fp; -}; - - -int main(void) -{ - int pair[2]; - pipe(pair); - - // run server thread - Server srv(pair[0]); - pthread_t thread; - pthread_create(&thread, NULL, - run_server, reinterpret_cast(&srv)); - - // client thread: - fwriter writer(pair[1]); - msgpack::packer pk(writer); - - typedef msgpack::type::tuple put_t; - typedef msgpack::type::tuple get_t; - - put_t req1("put", "apple", "red"); - put_t req2("put", "lemon", "yellow"); - get_t req3("get", "apple"); - pk.pack(req1); - pk.pack(req2); - pk.pack(req3); - writer.flush(); - writer.close(); - - pthread_join(thread, NULL); -} - diff --git a/msgpack/msgpack.pc.in b/msgpack/msgpack.pc.in deleted file mode 100644 index 8c34bef9..00000000 --- a/msgpack/msgpack.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: MessagePack -Description: Binary-based efficient object serialization library -Version: @VERSION@ -Libs: -L${libdir} -lmsgpack -Cflags: -I${includedir} diff --git a/msgpack/msgpack_vc.postbuild.bat b/msgpack/msgpack_vc.postbuild.bat deleted file mode 100644 index c7791e6a..00000000 --- a/msgpack/msgpack_vc.postbuild.bat +++ /dev/null @@ -1,45 +0,0 @@ -IF NOT EXIST include MKDIR include -IF NOT EXIST include\msgpack MKDIR include\msgpack -IF NOT EXIST include\msgpack\type MKDIR include\msgpack\type -IF NOT EXIST include\msgpack\type\tr1 MKDIR include\msgpack\type\tr1 -copy src\msgpack\pack_define.h include\msgpack\ -copy src\msgpack\pack_template.h include\msgpack\ -copy src\msgpack\unpack_define.h include\msgpack\ -copy src\msgpack\unpack_template.h include\msgpack\ -copy src\msgpack\sysdep.h include\msgpack\ -copy src\msgpack.h include\ -copy src\msgpack\sbuffer.h include\msgpack\ -copy src\msgpack\version.h include\msgpack\ -copy src\msgpack\vrefbuffer.h include\msgpack\ -copy src\msgpack\zbuffer.h include\msgpack\ -copy src\msgpack\pack.h include\msgpack\ -copy src\msgpack\unpack.h include\msgpack\ -copy src\msgpack\object.h include\msgpack\ -copy src\msgpack\zone.h include\msgpack\ -copy src\msgpack.hpp include\ -copy src\msgpack\sbuffer.hpp include\msgpack\ -copy src\msgpack\vrefbuffer.hpp include\msgpack\ -copy src\msgpack\zbuffer.hpp include\msgpack\ -copy src\msgpack\pack.hpp include\msgpack\ -copy src\msgpack\unpack.hpp include\msgpack\ -copy src\msgpack\object.hpp include\msgpack\ -copy src\msgpack\zone.hpp include\msgpack\ -copy src\msgpack\type.hpp include\msgpack\ -copy src\msgpack\type\bool.hpp include\msgpack\type\ -copy src\msgpack\type\deque.hpp include\msgpack\type\ -copy src\msgpack\type\fixint.hpp include\msgpack\type\ -copy src\msgpack\type\float.hpp include\msgpack\type\ -copy src\msgpack\type\int.hpp include\msgpack\type\ -copy src\msgpack\type\list.hpp include\msgpack\type\ -copy src\msgpack\type\map.hpp include\msgpack\type\ -copy src\msgpack\type\nil.hpp include\msgpack\type\ -copy src\msgpack\type\pair.hpp include\msgpack\type\ -copy src\msgpack\type\raw.hpp include\msgpack\type\ -copy src\msgpack\type\set.hpp include\msgpack\type\ -copy src\msgpack\type\string.hpp include\msgpack\type\ -copy src\msgpack\type\vector.hpp include\msgpack\type\ -copy src\msgpack\type\tuple.hpp include\msgpack\type\ -copy src\msgpack\type\define.hpp include\msgpack\type\ -copy src\msgpack\type\tr1\unordered_map.hpp include\msgpack\type\tr1\ -copy src\msgpack\type\tr1\unordered_set.hpp include\msgpack\type\tr1\ - diff --git a/msgpack/msgpack_vc8.sln b/msgpack/msgpack_vc8.sln deleted file mode 100644 index 84718afa..00000000 --- a/msgpack/msgpack_vc8.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "msgpack_vc8.vcproj", "{122A2EA4-B283-4241-9655-786DE78283B2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.ActiveCfg = Debug|Win32 - {122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.Build.0 = Debug|Win32 - {122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.ActiveCfg = Release|Win32 - {122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/msgpack/msgpack_vc8.vcproj b/msgpack/msgpack_vc8.vcproj deleted file mode 100644 index 72d47b6b..00000000 --- a/msgpack/msgpack_vc8.vcproj +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/msgpack/pack_define.h b/msgpack/pack_define.h deleted file mode 100644 index 4845d52e..00000000 --- a/msgpack/pack_define.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * MessagePack unpacking routine template - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_PACK_DEFINE_H__ -#define MSGPACK_PACK_DEFINE_H__ - -#include "msgpack/sysdep.h" -#include -#include - -#endif /* msgpack/pack_define.h */ - diff --git a/msgpack/pack_template.h b/msgpack/pack_template.h deleted file mode 100644 index 65c959dd..00000000 --- a/msgpack/pack_template.h +++ /dev/null @@ -1,771 +0,0 @@ -/* - * MessagePack packing routine template - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(__LITTLE_ENDIAN__) -#define TAKE8_8(d) ((uint8_t*)&d)[0] -#define TAKE8_16(d) ((uint8_t*)&d)[0] -#define TAKE8_32(d) ((uint8_t*)&d)[0] -#define TAKE8_64(d) ((uint8_t*)&d)[0] -#elif defined(__BIG_ENDIAN__) -#define TAKE8_8(d) ((uint8_t*)&d)[0] -#define TAKE8_16(d) ((uint8_t*)&d)[1] -#define TAKE8_32(d) ((uint8_t*)&d)[3] -#define TAKE8_64(d) ((uint8_t*)&d)[7] -#endif - -#ifndef msgpack_pack_inline_func -#error msgpack_pack_inline_func template is not defined -#endif - -#ifndef msgpack_pack_user -#error msgpack_pack_user type is not defined -#endif - -#ifndef msgpack_pack_append_buffer -#error msgpack_pack_append_buffer callback is not defined -#endif - - -/* - * Integer - */ - -#define msgpack_pack_real_uint8(x, d) \ -do { \ - if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ - } else { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_8(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ -} while(0) - -#define msgpack_pack_real_uint16(x, d) \ -do { \ - if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ - } else if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } \ -} while(0) - -#define msgpack_pack_real_uint32(x, d) \ -do { \ - if(d < (1<<8)) { \ - if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ - } else { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else { \ - if(d < (1<<16)) { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } \ - } \ -} while(0) - -#define msgpack_pack_real_uint64(x, d) \ -do { \ - if(d < (1ULL<<8)) { \ - if(d < (1ULL<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ - } else { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else { \ - if(d < (1ULL<<16)) { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else if(d < (1ULL<<32)) { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } else { \ - /* unsigned 64 */ \ - unsigned char buf[9]; \ - buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ - msgpack_pack_append_buffer(x, buf, 9); \ - } \ - } \ -} while(0) - -#define msgpack_pack_real_int8(x, d) \ -do { \ - if(d < -(1<<5)) { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_8(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ - } \ -} while(0) - -#define msgpack_pack_real_int16(x, d) \ -do { \ - if(d < -(1<<5)) { \ - if(d < -(1<<7)) { \ - /* signed 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_16(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ - } else { \ - if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } \ - } \ -} while(0) - -#define msgpack_pack_real_int32(x, d) \ -do { \ - if(d < -(1<<5)) { \ - if(d < -(1<<15)) { \ - /* signed 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } else if(d < -(1<<7)) { \ - /* signed 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_32(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ - } else { \ - if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else if(d < (1<<16)) { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } \ - } \ -} while(0) - -#define msgpack_pack_real_int64(x, d) \ -do { \ - if(d < -(1LL<<5)) { \ - if(d < -(1LL<<15)) { \ - if(d < -(1LL<<31)) { \ - /* signed 64 */ \ - unsigned char buf[9]; \ - buf[0] = 0xd3; _msgpack_store64(&buf[1], d); \ - msgpack_pack_append_buffer(x, buf, 9); \ - } else { \ - /* signed 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } \ - } else { \ - if(d < -(1<<7)) { \ - /* signed 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_64(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } \ - } else if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ - } else { \ - if(d < (1LL<<16)) { \ - if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } \ - } else { \ - if(d < (1LL<<32)) { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } else { \ - /* unsigned 64 */ \ - unsigned char buf[9]; \ - buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ - msgpack_pack_append_buffer(x, buf, 9); \ - } \ - } \ - } \ -} while(0) - - -#ifdef msgpack_pack_inline_func_fixint - -msgpack_pack_inline_func_fixint(_uint8)(msgpack_pack_user x, uint8_t d) -{ - unsigned char buf[2] = {0xcc, TAKE8_8(d)}; - msgpack_pack_append_buffer(x, buf, 2); -} - -msgpack_pack_inline_func_fixint(_uint16)(msgpack_pack_user x, uint16_t d) -{ - unsigned char buf[3]; - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 3); -} - -msgpack_pack_inline_func_fixint(_uint32)(msgpack_pack_user x, uint32_t d) -{ - unsigned char buf[5]; - buf[0] = 0xce; _msgpack_store32(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 5); -} - -msgpack_pack_inline_func_fixint(_uint64)(msgpack_pack_user x, uint64_t d) -{ - unsigned char buf[9]; - buf[0] = 0xcf; _msgpack_store64(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 9); -} - -msgpack_pack_inline_func_fixint(_int8)(msgpack_pack_user x, int8_t d) -{ - unsigned char buf[2] = {0xd0, TAKE8_8(d)}; - msgpack_pack_append_buffer(x, buf, 2); -} - -msgpack_pack_inline_func_fixint(_int16)(msgpack_pack_user x, int16_t d) -{ - unsigned char buf[3]; - buf[0] = 0xd1; _msgpack_store16(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 3); -} - -msgpack_pack_inline_func_fixint(_int32)(msgpack_pack_user x, int32_t d) -{ - unsigned char buf[5]; - buf[0] = 0xd2; _msgpack_store32(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 5); -} - -msgpack_pack_inline_func_fixint(_int64)(msgpack_pack_user x, int64_t d) -{ - unsigned char buf[9]; - buf[0] = 0xd3; _msgpack_store64(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 9); -} - -#undef msgpack_pack_inline_func_fixint -#endif - - -msgpack_pack_inline_func(_uint8)(msgpack_pack_user x, uint8_t d) -{ - msgpack_pack_real_uint8(x, d); -} - -msgpack_pack_inline_func(_uint16)(msgpack_pack_user x, uint16_t d) -{ - msgpack_pack_real_uint16(x, d); -} - -msgpack_pack_inline_func(_uint32)(msgpack_pack_user x, uint32_t d) -{ - msgpack_pack_real_uint32(x, d); -} - -msgpack_pack_inline_func(_uint64)(msgpack_pack_user x, uint64_t d) -{ - msgpack_pack_real_uint64(x, d); -} - -msgpack_pack_inline_func(_int8)(msgpack_pack_user x, int8_t d) -{ - msgpack_pack_real_int8(x, d); -} - -msgpack_pack_inline_func(_int16)(msgpack_pack_user x, int16_t d) -{ - msgpack_pack_real_int16(x, d); -} - -msgpack_pack_inline_func(_int32)(msgpack_pack_user x, int32_t d) -{ - msgpack_pack_real_int32(x, d); -} - -msgpack_pack_inline_func(_int64)(msgpack_pack_user x, int64_t d) -{ - msgpack_pack_real_int64(x, d); -} - - -#ifdef msgpack_pack_inline_func_cint - -msgpack_pack_inline_func_cint(_short)(msgpack_pack_user x, short d) -{ -#if defined(SIZEOF_SHORT) -#if SIZEOF_SHORT == 2 - msgpack_pack_real_int16(x, d); -#elif SIZEOF_SHORT == 4 - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#elif defined(SHRT_MAX) -#if SHRT_MAX == 0x7fff - msgpack_pack_real_int16(x, d); -#elif SHRT_MAX == 0x7fffffff - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#else -if(sizeof(short) == 2) { - msgpack_pack_real_int16(x, d); -} else if(sizeof(short) == 4) { - msgpack_pack_real_int32(x, d); -} else { - msgpack_pack_real_int64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_int)(msgpack_pack_user x, int d) -{ -#if defined(SIZEOF_INT) -#if SIZEOF_INT == 2 - msgpack_pack_real_int16(x, d); -#elif SIZEOF_INT == 4 - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#elif defined(INT_MAX) -#if INT_MAX == 0x7fff - msgpack_pack_real_int16(x, d); -#elif INT_MAX == 0x7fffffff - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#else -if(sizeof(int) == 2) { - msgpack_pack_real_int16(x, d); -} else if(sizeof(int) == 4) { - msgpack_pack_real_int32(x, d); -} else { - msgpack_pack_real_int64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_long)(msgpack_pack_user x, long d) -{ -#if defined(SIZEOF_LONG) -#if SIZEOF_LONG == 2 - msgpack_pack_real_int16(x, d); -#elif SIZEOF_LONG == 4 - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#elif defined(LONG_MAX) -#if LONG_MAX == 0x7fffL - msgpack_pack_real_int16(x, d); -#elif LONG_MAX == 0x7fffffffL - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#else -if(sizeof(long) == 2) { - msgpack_pack_real_int16(x, d); -} else if(sizeof(long) == 4) { - msgpack_pack_real_int32(x, d); -} else { - msgpack_pack_real_int64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_long_long)(msgpack_pack_user x, long long d) -{ -#if defined(SIZEOF_LONG_LONG) -#if SIZEOF_LONG_LONG == 2 - msgpack_pack_real_int16(x, d); -#elif SIZEOF_LONG_LONG == 4 - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#elif defined(LLONG_MAX) -#if LLONG_MAX == 0x7fffL - msgpack_pack_real_int16(x, d); -#elif LLONG_MAX == 0x7fffffffL - msgpack_pack_real_int32(x, d); -#else - msgpack_pack_real_int64(x, d); -#endif - -#else -if(sizeof(long long) == 2) { - msgpack_pack_real_int16(x, d); -} else if(sizeof(long long) == 4) { - msgpack_pack_real_int32(x, d); -} else { - msgpack_pack_real_int64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_unsigned_short)(msgpack_pack_user x, unsigned short d) -{ -#if defined(SIZEOF_SHORT) -#if SIZEOF_SHORT == 2 - msgpack_pack_real_uint16(x, d); -#elif SIZEOF_SHORT == 4 - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#elif defined(USHRT_MAX) -#if USHRT_MAX == 0xffffU - msgpack_pack_real_uint16(x, d); -#elif USHRT_MAX == 0xffffffffU - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#else -if(sizeof(unsigned short) == 2) { - msgpack_pack_real_uint16(x, d); -} else if(sizeof(unsigned short) == 4) { - msgpack_pack_real_uint32(x, d); -} else { - msgpack_pack_real_uint64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_unsigned_int)(msgpack_pack_user x, unsigned int d) -{ -#if defined(SIZEOF_INT) -#if SIZEOF_INT == 2 - msgpack_pack_real_uint16(x, d); -#elif SIZEOF_INT == 4 - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#elif defined(UINT_MAX) -#if UINT_MAX == 0xffffU - msgpack_pack_real_uint16(x, d); -#elif UINT_MAX == 0xffffffffU - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#else -if(sizeof(unsigned int) == 2) { - msgpack_pack_real_uint16(x, d); -} else if(sizeof(unsigned int) == 4) { - msgpack_pack_real_uint32(x, d); -} else { - msgpack_pack_real_uint64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_unsigned_long)(msgpack_pack_user x, unsigned long d) -{ -#if defined(SIZEOF_LONG) -#if SIZEOF_LONG == 2 - msgpack_pack_real_uint16(x, d); -#elif SIZEOF_LONG == 4 - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#elif defined(ULONG_MAX) -#if ULONG_MAX == 0xffffUL - msgpack_pack_real_uint16(x, d); -#elif ULONG_MAX == 0xffffffffUL - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#else -if(sizeof(unsigned long) == 2) { - msgpack_pack_real_uint16(x, d); -} else if(sizeof(unsigned long) == 4) { - msgpack_pack_real_uint32(x, d); -} else { - msgpack_pack_real_uint64(x, d); -} -#endif -} - -msgpack_pack_inline_func_cint(_unsigned_long_long)(msgpack_pack_user x, unsigned long long d) -{ -#if defined(SIZEOF_LONG_LONG) -#if SIZEOF_LONG_LONG == 2 - msgpack_pack_real_uint16(x, d); -#elif SIZEOF_LONG_LONG == 4 - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#elif defined(ULLONG_MAX) -#if ULLONG_MAX == 0xffffUL - msgpack_pack_real_uint16(x, d); -#elif ULLONG_MAX == 0xffffffffUL - msgpack_pack_real_uint32(x, d); -#else - msgpack_pack_real_uint64(x, d); -#endif - -#else -if(sizeof(unsigned long long) == 2) { - msgpack_pack_real_uint16(x, d); -} else if(sizeof(unsigned long long) == 4) { - msgpack_pack_real_uint32(x, d); -} else { - msgpack_pack_real_uint64(x, d); -} -#endif -} - -#undef msgpack_pack_inline_func_cint -#endif - - - -/* - * Float - */ - -msgpack_pack_inline_func(_float)(msgpack_pack_user x, float d) -{ - union { float f; uint32_t i; } mem; - mem.f = d; - unsigned char buf[5]; - buf[0] = 0xca; _msgpack_store32(&buf[1], mem.i); - msgpack_pack_append_buffer(x, buf, 5); -} - -msgpack_pack_inline_func(_double)(msgpack_pack_user x, double d) -{ - union { double f; uint64_t i; } mem; - mem.f = d; - unsigned char buf[9]; - buf[0] = 0xcb; -#if defined(__arm__) && !(__ARM_EABI__) // arm-oabi - // https://github.com/msgpack/msgpack-perl/pull/1 - mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); -#endif - _msgpack_store64(&buf[1], mem.i); - msgpack_pack_append_buffer(x, buf, 9); -} - - -/* - * Nil - */ - -msgpack_pack_inline_func(_nil)(msgpack_pack_user x) -{ - static const unsigned char d = 0xc0; - msgpack_pack_append_buffer(x, &d, 1); -} - - -/* - * Boolean - */ - -msgpack_pack_inline_func(_true)(msgpack_pack_user x) -{ - static const unsigned char d = 0xc3; - msgpack_pack_append_buffer(x, &d, 1); -} - -msgpack_pack_inline_func(_false)(msgpack_pack_user x) -{ - static const unsigned char d = 0xc2; - msgpack_pack_append_buffer(x, &d, 1); -} - - -/* - * Array - */ - -msgpack_pack_inline_func(_array)(msgpack_pack_user x, unsigned int n) -{ - if(n < 16) { - unsigned char d = 0x90 | n; - msgpack_pack_append_buffer(x, &d, 1); - } else if(n < 65536) { - unsigned char buf[3]; - buf[0] = 0xdc; _msgpack_store16(&buf[1], (uint16_t)n); - msgpack_pack_append_buffer(x, buf, 3); - } else { - unsigned char buf[5]; - buf[0] = 0xdd; _msgpack_store32(&buf[1], (uint32_t)n); - msgpack_pack_append_buffer(x, buf, 5); - } -} - - -/* - * Map - */ - -msgpack_pack_inline_func(_map)(msgpack_pack_user x, unsigned int n) -{ - if(n < 16) { - unsigned char d = 0x80 | n; - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); - } else if(n < 65536) { - unsigned char buf[3]; - buf[0] = 0xde; _msgpack_store16(&buf[1], (uint16_t)n); - msgpack_pack_append_buffer(x, buf, 3); - } else { - unsigned char buf[5]; - buf[0] = 0xdf; _msgpack_store32(&buf[1], (uint32_t)n); - msgpack_pack_append_buffer(x, buf, 5); - } -} - - -/* - * Raw - */ - -msgpack_pack_inline_func(_raw)(msgpack_pack_user x, size_t l) -{ - if(l < 32) { - unsigned char d = 0xa0 | (uint8_t)l; - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); - } else if(l < 65536) { - unsigned char buf[3]; - buf[0] = 0xda; _msgpack_store16(&buf[1], (uint16_t)l); - msgpack_pack_append_buffer(x, buf, 3); - } else { - unsigned char buf[5]; - buf[0] = 0xdb; _msgpack_store32(&buf[1], (uint32_t)l); - msgpack_pack_append_buffer(x, buf, 5); - } -} - -msgpack_pack_inline_func(_raw_body)(msgpack_pack_user x, const void* b, size_t l) -{ - msgpack_pack_append_buffer(x, (const unsigned char*)b, l); -} - -#undef msgpack_pack_inline_func -#undef msgpack_pack_user -#undef msgpack_pack_append_buffer - -#undef TAKE8_8 -#undef TAKE8_16 -#undef TAKE8_32 -#undef TAKE8_64 - -#undef msgpack_pack_real_uint8 -#undef msgpack_pack_real_uint16 -#undef msgpack_pack_real_uint32 -#undef msgpack_pack_real_uint64 -#undef msgpack_pack_real_int8 -#undef msgpack_pack_real_int16 -#undef msgpack_pack_real_int32 -#undef msgpack_pack_real_int64 - diff --git a/msgpack/preprocess b/msgpack/preprocess deleted file mode 100755 index 839eb137..00000000 --- a/msgpack/preprocess +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -preprocess() { - ruby -r erb -e 'puts ERB.new(ARGF.read).result' $1.erb > $1.tmp - if [ "$?" != 0 ]; then - echo "" - echo "** preprocess failed **" - echo "" - exit 1 - else - mv $1.tmp $1 - fi -} - -if [ "$1" = "clean" ];then - rm -f src/msgpack/type/tuple.hpp - rm -f src/msgpack/type/define.hpp - rm -f src/msgpack/zone.hpp -else - preprocess src/msgpack/type/tuple.hpp - preprocess src/msgpack/type/define.hpp - preprocess src/msgpack/zone.hpp -fi -cp -f sysdep.h src/msgpack/ -cp -f pack_define.h src/msgpack/ -cp -f pack_template.h src/msgpack/ -cp -f unpack_define.h src/msgpack/ -cp -f unpack_template.h src/msgpack/ -cp -f cases.mpac test/ -cp -f cases_compact.mpac test/ - -sed -e 's/8\.00/9.00/' < msgpack_vc8.vcproj > msgpack_vc2008.vcproj -sed -e 's/9\.00/10.00/' -e 's/msgpack_vc8/msgpack_vc2008/' < msgpack_vc8.sln > msgpack_vc2008.sln - diff --git a/msgpack/src/Makefile.am b/msgpack/src/Makefile.am deleted file mode 100644 index 59c65010..00000000 --- a/msgpack/src/Makefile.am +++ /dev/null @@ -1,107 +0,0 @@ - -lib_LTLIBRARIES = libmsgpack.la - -libmsgpack_la_SOURCES = \ - unpack.c \ - objectc.c \ - version.c \ - vrefbuffer.c \ - zone.c - -if ENABLE_CXX -libmsgpack_la_SOURCES += \ - object.cpp -endif - -if ENABLE_GCC_CXX_ATOMIC -libmsgpack_la_SOURCES += \ - gcc_atomic.cpp -endif - - -# -version-info CURRENT:REVISION:AGE -libmsgpack_la_LDFLAGS = -version-info 3:0:0 -no-undefined - - -# backward compatibility -lib_LTLIBRARIES += libmsgpackc.la - -libmsgpackc_la_SOURCES = \ - unpack.c \ - objectc.c \ - version.c \ - vrefbuffer.c \ - zone.c - -libmsgpackc_la_LDFLAGS = -version-info 2:0:0 -no-undefined - - -nobase_include_HEADERS = \ - msgpack/pack_define.h \ - msgpack/pack_template.h \ - msgpack/unpack_define.h \ - msgpack/unpack_template.h \ - msgpack/sysdep.h \ - msgpack.h \ - msgpack/sbuffer.h \ - msgpack/version.h \ - msgpack/vrefbuffer.h \ - msgpack/zbuffer.h \ - msgpack/pack.h \ - msgpack/unpack.h \ - msgpack/object.h \ - msgpack/zone.h - -if ENABLE_CXX -nobase_include_HEADERS += \ - msgpack.hpp \ - msgpack/sbuffer.hpp \ - msgpack/vrefbuffer.hpp \ - msgpack/zbuffer.hpp \ - msgpack/pack.hpp \ - msgpack/unpack.hpp \ - msgpack/object.hpp \ - msgpack/zone.hpp \ - msgpack/type.hpp \ - msgpack/type/bool.hpp \ - msgpack/type/deque.hpp \ - msgpack/type/float.hpp \ - msgpack/type/fixint.hpp \ - msgpack/type/int.hpp \ - msgpack/type/list.hpp \ - msgpack/type/map.hpp \ - msgpack/type/nil.hpp \ - msgpack/type/pair.hpp \ - msgpack/type/raw.hpp \ - msgpack/type/set.hpp \ - msgpack/type/string.hpp \ - msgpack/type/vector.hpp \ - msgpack/type/tuple.hpp \ - msgpack/type/define.hpp \ - msgpack/type/tr1/unordered_map.hpp \ - msgpack/type/tr1/unordered_set.hpp -endif - -EXTRA_DIST = \ - msgpack/version.h.in \ - msgpack/zone.hpp.erb \ - msgpack/type/define.hpp.erb \ - msgpack/type/tuple.hpp.erb - - -doxygen_c: - cat ../Doxyfile > Doxyfile_c - echo "FILE_PATTERNS = *.h" >> Doxyfile_c - echo "OUTPUT_DIRECTORY = doc_c" >> Doxyfile_c - echo "PROJECT_NAME = \"MessagePack for C\"" >> Doxyfile_c - doxygen Doxyfile_c - -doxygen_cpp: - cat ../Doxyfile > Doxyfile_cpp - echo "FILE_PATTERNS = *.hpp" >> Doxyfile_cpp - echo "OUTPUT_DIRECTORY = doc_cpp" >> Doxyfile_cpp - echo "PROJECT_NAME = \"MessagePack for C++\"" >> Doxyfile_cpp - doxygen Doxyfile_cpp - -doxygen: doxygen_c doxygen_cpp - diff --git a/msgpack/src/gcc_atomic.cpp b/msgpack/src/gcc_atomic.cpp deleted file mode 100644 index 25681b67..00000000 --- a/msgpack/src/gcc_atomic.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#if defined(__GNUC__) && ((__GNUC__*10 + __GNUC_MINOR__) < 41) - -#include "gcc_atomic.h" -#include - -int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr) -{ - return __gnu_cxx::__exchange_and_add(ptr, -1) - 1; -} - -int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr) -{ - return __gnu_cxx::__exchange_and_add(ptr, 1) + 1; -} - - -#endif // old gcc workaround diff --git a/msgpack/src/gcc_atomic.h b/msgpack/src/gcc_atomic.h deleted file mode 100644 index 842a48fb..00000000 --- a/msgpack/src/gcc_atomic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MSGPACK_GCC_ATOMIC_H__ -#define MSGPACK_GCC_ATOMIC_H__ - -#if defined(__cplusplus) -extern "C" { -#endif - -typedef int _msgpack_atomic_counter_t; - -int _msgpack_sync_decr_and_fetch(volatile _msgpack_atomic_counter_t* ptr); -int _msgpack_sync_incr_and_fetch(volatile _msgpack_atomic_counter_t* ptr); - - -#if defined(__cplusplus) -} -#endif - - -#endif // MSGPACK_GCC_ATOMIC_H__ diff --git a/msgpack/src/msgpack.h b/msgpack/src/msgpack.h deleted file mode 100644 index 08f27688..00000000 --- a/msgpack/src/msgpack.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * MessagePack for C - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @defgroup msgpack MessagePack C - * @{ - * @} - */ -#include "msgpack/object.h" -#include "msgpack/zone.h" -#include "msgpack/pack.h" -#include "msgpack/unpack.h" -#include "msgpack/sbuffer.h" -#include "msgpack/vrefbuffer.h" -#include "msgpack/version.h" - diff --git a/msgpack/src/msgpack.hpp b/msgpack/src/msgpack.hpp deleted file mode 100644 index e14680dd..00000000 --- a/msgpack/src/msgpack.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// MessagePack for C++ -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#include "msgpack/object.hpp" -#include "msgpack/zone.hpp" -#include "msgpack/pack.hpp" -#include "msgpack/unpack.hpp" -#include "msgpack/sbuffer.hpp" -#include "msgpack/vrefbuffer.hpp" -#include "msgpack.h" diff --git a/msgpack/src/msgpack/object.h b/msgpack/src/msgpack/object.h deleted file mode 100644 index baeeb9b2..00000000 --- a/msgpack/src/msgpack/object.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * MessagePack for C dynamic typing routine - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_OBJECT_H__ -#define MSGPACK_OBJECT_H__ - -#include "zone.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_object Dynamically typed object - * @ingroup msgpack - * @{ - */ - -typedef enum { - MSGPACK_OBJECT_NIL = 0x00, - MSGPACK_OBJECT_BOOLEAN = 0x01, - MSGPACK_OBJECT_POSITIVE_INTEGER = 0x02, - MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x03, - MSGPACK_OBJECT_DOUBLE = 0x04, - MSGPACK_OBJECT_RAW = 0x05, - MSGPACK_OBJECT_ARRAY = 0x06, - MSGPACK_OBJECT_MAP = 0x07, -} msgpack_object_type; - - -struct msgpack_object; -struct msgpack_object_kv; - -typedef struct { - uint32_t size; - struct msgpack_object* ptr; -} msgpack_object_array; - -typedef struct { - uint32_t size; - struct msgpack_object_kv* ptr; -} msgpack_object_map; - -typedef struct { - uint32_t size; - const char* ptr; -} msgpack_object_raw; - -typedef union { - bool boolean; - uint64_t u64; - int64_t i64; - double dec; - msgpack_object_array array; - msgpack_object_map map; - msgpack_object_raw raw; -} msgpack_object_union; - -typedef struct msgpack_object { - msgpack_object_type type; - msgpack_object_union via; -} msgpack_object; - -typedef struct msgpack_object_kv { - msgpack_object key; - msgpack_object val; -} msgpack_object_kv; - - -void msgpack_object_print(FILE* out, msgpack_object o); - -bool msgpack_object_equal(const msgpack_object x, const msgpack_object y); - -/** @} */ - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/object.h */ - diff --git a/msgpack/src/msgpack/object.hpp b/msgpack/src/msgpack/object.hpp deleted file mode 100644 index 97c8d4aa..00000000 --- a/msgpack/src/msgpack/object.hpp +++ /dev/null @@ -1,412 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2010 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_OBJECT_HPP__ -#define MSGPACK_OBJECT_HPP__ - -#include "object.h" -#include "pack.hpp" -#include "zone.hpp" -#include -#include -#include -#include -#include - -namespace msgpack { - - -class type_error : public std::bad_cast { }; - - -namespace type { - enum object_type { - NIL = MSGPACK_OBJECT_NIL, - BOOLEAN = MSGPACK_OBJECT_BOOLEAN, - POSITIVE_INTEGER = MSGPACK_OBJECT_POSITIVE_INTEGER, - NEGATIVE_INTEGER = MSGPACK_OBJECT_NEGATIVE_INTEGER, - DOUBLE = MSGPACK_OBJECT_DOUBLE, - RAW = MSGPACK_OBJECT_RAW, - ARRAY = MSGPACK_OBJECT_ARRAY, - MAP = MSGPACK_OBJECT_MAP, - }; -} - - -struct object; -struct object_kv; - -struct object_array { - uint32_t size; - object* ptr; -}; - -struct object_map { - uint32_t size; - object_kv* ptr; -}; - -struct object_raw { - uint32_t size; - const char* ptr; -}; - -struct object { - union union_type { - bool boolean; - uint64_t u64; - int64_t i64; - double dec; - object_array array; - object_map map; - object_raw raw; - object_raw ref; // obsolete - }; - - type::object_type type; - union_type via; - - bool is_nil() const { return type == type::NIL; } - - template - T as() const; - - template - void convert(T* v) const; - - object(); - - object(msgpack_object o); - - template - explicit object(const T& v); - - template - object(const T& v, zone* z); - - template - object& operator=(const T& v); - - operator msgpack_object() const; - - struct with_zone; - -private: - struct implicit_type; - -public: - implicit_type convert() const; -}; - -struct object_kv { - object key; - object val; -}; - -struct object::with_zone : object { - with_zone(msgpack::zone* zone) : zone(zone) { } - msgpack::zone* zone; -private: - with_zone(); -}; - - -bool operator==(const object x, const object y); -bool operator!=(const object x, const object y); - -template -bool operator==(const object x, const T& y); - -template -bool operator==(const T& y, const object x); - -template -bool operator!=(const object x, const T& y); - -template -bool operator!=(const T& y, const object x); - -std::ostream& operator<< (std::ostream& s, const object o); - - -// serialize operator -template -packer& operator<< (packer& o, const T& v); - -// convert operator -template -T& operator>> (object o, T& v); - -// deconvert operator -template -void operator<< (object::with_zone& o, const T& v); - - -struct object::implicit_type { - implicit_type(object o) : obj(o) { } - ~implicit_type() { } - - template - operator T() { return obj.as(); } - -private: - object obj; -}; - - -// obsolete -template -class define : public Type { -public: - typedef Type msgpack_type; - typedef define define_type; - - define() {} - define(const msgpack_type& v) : msgpack_type(v) {} - - template - void msgpack_pack(Packer& o) const - { - o << static_cast(*this); - } - - void msgpack_unpack(object o) - { - o >> static_cast(*this); - } -}; - - -template -template -inline packer& packer::pack(const T& v) -{ - *this << v; - return *this; -} - -inline object& operator>> (object o, object& v) -{ - v = o; - return v; -} - -template -inline T& operator>> (object o, T& v) -{ - v.msgpack_unpack(o.convert()); - return v; -} - -template -inline packer& operator<< (packer& o, const T& v) -{ - v.msgpack_pack(o); - return o; -} - -template -void operator<< (object::with_zone& o, const T& v) -{ - v.msgpack_object(static_cast(&o), o.zone); -} - - -inline bool operator==(const object x, const object y) -{ - return msgpack_object_equal(x, y); -} - -template -inline bool operator==(const object x, const T& y) -try { - return x == object(y); -} catch (msgpack::type_error&) { - return false; -} - -inline bool operator!=(const object x, const object y) -{ return !(x == y); } - -template -inline bool operator==(const T& y, const object x) -{ return x == y; } - -template -inline bool operator!=(const object x, const T& y) -{ return !(x == y); } - -template -inline bool operator!=(const T& y, const object x) -{ return x != y; } - - -inline object::implicit_type object::convert() const -{ - return implicit_type(*this); -} - -template -inline void object::convert(T* v) const -{ - *this >> *v; -} - -template -inline T object::as() const -{ - T v; - convert(&v); - return v; -} - - -inline object::object() -{ - type = type::NIL; -} - -template -inline object::object(const T& v) -{ - *this << v; -} - -template -inline object& object::operator=(const T& v) -{ - *this = object(v); - return *this; -} - -template -object::object(const T& v, zone* z) -{ - with_zone oz(z); - oz << v; - type = oz.type; - via = oz.via; -} - - -inline object::object(msgpack_object o) -{ - // FIXME beter way? - ::memcpy(this, &o, sizeof(o)); -} - -inline void operator<< (object& o, msgpack_object v) -{ - // FIXME beter way? - ::memcpy(&o, &v, sizeof(v)); -} - -inline object::operator msgpack_object() const -{ - // FIXME beter way? - msgpack_object obj; - ::memcpy(&obj, this, sizeof(obj)); - return obj; -} - - -// obsolete -template -inline void convert(T& v, object o) -{ - o.convert(&v); -} - -// obsolete -template -inline void pack(packer& o, const T& v) -{ - o.pack(v); -} - -// obsolete -template -inline void pack_copy(packer& o, T v) -{ - pack(o, v); -} - - -template -packer& operator<< (packer& o, const object& v) -{ - switch(v.type) { - case type::NIL: - o.pack_nil(); - return o; - - case type::BOOLEAN: - if(v.via.boolean) { - o.pack_true(); - } else { - o.pack_false(); - } - return o; - - case type::POSITIVE_INTEGER: - o.pack_uint64(v.via.u64); - return o; - - case type::NEGATIVE_INTEGER: - o.pack_int64(v.via.i64); - return o; - - case type::DOUBLE: - o.pack_double(v.via.dec); - return o; - - case type::RAW: - o.pack_raw(v.via.raw.size); - o.pack_raw_body(v.via.raw.ptr, v.via.raw.size); - return o; - - case type::ARRAY: - o.pack_array(v.via.array.size); - for(object* p(v.via.array.ptr), - * const pend(v.via.array.ptr + v.via.array.size); - p < pend; ++p) { - o << *p; - } - return o; - - case type::MAP: - o.pack_map(v.via.map.size); - for(object_kv* p(v.via.map.ptr), - * const pend(v.via.map.ptr + v.via.map.size); - p < pend; ++p) { - o << p->key; - o << p->val; - } - return o; - - default: - throw type_error(); - } -} - - -} // namespace msgpack - -#include "msgpack/type.hpp" - -#endif /* msgpack/object.hpp */ - diff --git a/msgpack/src/msgpack/pack.h b/msgpack/src/msgpack/pack.h deleted file mode 100644 index f86e9299..00000000 --- a/msgpack/src/msgpack/pack.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * MessagePack for C packing routine - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_PACK_H__ -#define MSGPACK_PACK_H__ - -#include "pack_define.h" -#include "object.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_buffer Buffers - * @ingroup msgpack - * @{ - * @} - */ - -/** - * @defgroup msgpack_pack Serializer - * @ingroup msgpack - * @{ - */ - -typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len); - -typedef struct msgpack_packer { - void* data; - msgpack_packer_write callback; -} msgpack_packer; - -static void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback); - -static msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback); -static void msgpack_packer_free(msgpack_packer* pk); - -static int msgpack_pack_short(msgpack_packer* pk, short d); -static int msgpack_pack_int(msgpack_packer* pk, int d); -static int msgpack_pack_long(msgpack_packer* pk, long d); -static int msgpack_pack_long_long(msgpack_packer* pk, long long d); -static int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d); -static int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d); -static int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d); -static int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d); - -static int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d); -static int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d); -static int msgpack_pack_uint32(msgpack_packer* pk, uint32_t d); -static int msgpack_pack_uint64(msgpack_packer* pk, uint64_t d); -static int msgpack_pack_int8(msgpack_packer* pk, int8_t d); -static int msgpack_pack_int16(msgpack_packer* pk, int16_t d); -static int msgpack_pack_int32(msgpack_packer* pk, int32_t d); -static int msgpack_pack_int64(msgpack_packer* pk, int64_t d); - -static int msgpack_pack_fix_uint8(msgpack_packer* pk, uint8_t d); -static int msgpack_pack_fix_uint16(msgpack_packer* pk, uint16_t d); -static int msgpack_pack_fix_uint32(msgpack_packer* pk, uint32_t d); -static int msgpack_pack_fix_uint64(msgpack_packer* pk, uint64_t d); -static int msgpack_pack_fix_int8(msgpack_packer* pk, int8_t d); -static int msgpack_pack_fix_int16(msgpack_packer* pk, int16_t d); -static int msgpack_pack_fix_int32(msgpack_packer* pk, int32_t d); -static int msgpack_pack_fix_int64(msgpack_packer* pk, int64_t d); - -static int msgpack_pack_float(msgpack_packer* pk, float d); -static int msgpack_pack_double(msgpack_packer* pk, double d); - -static int msgpack_pack_nil(msgpack_packer* pk); -static int msgpack_pack_true(msgpack_packer* pk); -static int msgpack_pack_false(msgpack_packer* pk); - -static int msgpack_pack_array(msgpack_packer* pk, unsigned int n); - -static int msgpack_pack_map(msgpack_packer* pk, unsigned int n); - -static int msgpack_pack_raw(msgpack_packer* pk, size_t l); -static int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l); - -int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); - - -/** @} */ - - -#define msgpack_pack_inline_func(name) \ - inline int msgpack_pack ## name - -#define msgpack_pack_inline_func_cint(name) \ - inline int msgpack_pack ## name - -#define msgpack_pack_inline_func_fixint(name) \ - inline int msgpack_pack_fix ## name - -#define msgpack_pack_user msgpack_packer* - -#define msgpack_pack_append_buffer(user, buf, len) \ - return (*(user)->callback)((user)->data, (const char*)buf, len) - -#include "pack_template.h" - -inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback) -{ - pk->data = data; - pk->callback = callback; -} - -inline msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback) -{ - msgpack_packer* pk = (msgpack_packer*)calloc(1, sizeof(msgpack_packer)); - if(!pk) { return NULL; } - msgpack_packer_init(pk, data, callback); - return pk; -} - -inline void msgpack_packer_free(msgpack_packer* pk) -{ - free(pk); -} - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/pack.h */ - diff --git a/msgpack/src/msgpack/pack.hpp b/msgpack/src/msgpack/pack.hpp deleted file mode 100644 index 0090b961..00000000 --- a/msgpack/src/msgpack/pack.hpp +++ /dev/null @@ -1,318 +0,0 @@ -// -// MessagePack for C++ serializing routine -// -// Copyright (C) 2008-2010 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_PACK_HPP__ -#define MSGPACK_PACK_HPP__ - -#include "pack_define.h" -#include -#include - -namespace msgpack { - - -template -class packer { -public: - packer(Stream* s); - packer(Stream& s); - ~packer(); - -public: - template - packer& pack(const T& v); - - packer& pack_uint8(uint8_t d); - packer& pack_uint16(uint16_t d); - packer& pack_uint32(uint32_t d); - packer& pack_uint64(uint64_t d); - packer& pack_int8(int8_t d); - packer& pack_int16(int16_t d); - packer& pack_int32(int32_t d); - packer& pack_int64(int64_t d); - - packer& pack_fix_uint8(uint8_t d); - packer& pack_fix_uint16(uint16_t d); - packer& pack_fix_uint32(uint32_t d); - packer& pack_fix_uint64(uint64_t d); - packer& pack_fix_int8(int8_t d); - packer& pack_fix_int16(int16_t d); - packer& pack_fix_int32(int32_t d); - packer& pack_fix_int64(int64_t d); - - packer& pack_short(short d); - packer& pack_int(int d); - packer& pack_long(long d); - packer& pack_long_long(long long d); - packer& pack_unsigned_short(unsigned short d); - packer& pack_unsigned_int(unsigned int d); - packer& pack_unsigned_long(unsigned long d); - packer& pack_unsigned_long_long(unsigned long long d); - - packer& pack_float(float d); - packer& pack_double(double d); - - packer& pack_nil(); - packer& pack_true(); - packer& pack_false(); - - packer& pack_array(unsigned int n); - - packer& pack_map(unsigned int n); - - packer& pack_raw(size_t l); - packer& pack_raw_body(const char* b, size_t l); - -private: - static void _pack_uint8(Stream& x, uint8_t d); - static void _pack_uint16(Stream& x, uint16_t d); - static void _pack_uint32(Stream& x, uint32_t d); - static void _pack_uint64(Stream& x, uint64_t d); - static void _pack_int8(Stream& x, int8_t d); - static void _pack_int16(Stream& x, int16_t d); - static void _pack_int32(Stream& x, int32_t d); - static void _pack_int64(Stream& x, int64_t d); - - static void _pack_fix_uint8(Stream& x, uint8_t d); - static void _pack_fix_uint16(Stream& x, uint16_t d); - static void _pack_fix_uint32(Stream& x, uint32_t d); - static void _pack_fix_uint64(Stream& x, uint64_t d); - static void _pack_fix_int8(Stream& x, int8_t d); - static void _pack_fix_int16(Stream& x, int16_t d); - static void _pack_fix_int32(Stream& x, int32_t d); - static void _pack_fix_int64(Stream& x, int64_t d); - - static void _pack_short(Stream& x, short d); - static void _pack_int(Stream& x, int d); - static void _pack_long(Stream& x, long d); - static void _pack_long_long(Stream& x, long long d); - static void _pack_unsigned_short(Stream& x, unsigned short d); - static void _pack_unsigned_int(Stream& x, unsigned int d); - static void _pack_unsigned_long(Stream& x, unsigned long d); - static void _pack_unsigned_long_long(Stream& x, unsigned long long d); - - static void _pack_float(Stream& x, float d); - static void _pack_double(Stream& x, double d); - - static void _pack_nil(Stream& x); - static void _pack_true(Stream& x); - static void _pack_false(Stream& x); - - static void _pack_array(Stream& x, unsigned int n); - - static void _pack_map(Stream& x, unsigned int n); - - static void _pack_raw(Stream& x, size_t l); - static void _pack_raw_body(Stream& x, const void* b, size_t l); - - static void append_buffer(Stream& x, const unsigned char* buf, unsigned int len) - { x.write((const char*)buf, len); } - -private: - Stream& m_stream; - -private: - packer(); -}; - - -template -inline void pack(Stream* s, const T& v) -{ - packer(s).pack(v); -} - -template -inline void pack(Stream& s, const T& v) -{ - packer(s).pack(v); -} - - -#define msgpack_pack_inline_func(name) \ - template \ - inline void packer::_pack ## name - -#define msgpack_pack_inline_func_cint(name) \ - template \ - inline void packer::_pack ## name - -#define msgpack_pack_inline_func_fixint(name) \ - template \ - inline void packer::_pack_fix ## name - -#define msgpack_pack_user Stream& - -#define msgpack_pack_append_buffer append_buffer - -#include "pack_template.h" - - -template -packer::packer(Stream* s) : m_stream(*s) { } - -template -packer::packer(Stream& s) : m_stream(s) { } - -template -packer::~packer() { } - - -template -inline packer& packer::pack_uint8(uint8_t d) -{ _pack_uint8(m_stream, d); return *this; } - -template -inline packer& packer::pack_uint16(uint16_t d) -{ _pack_uint16(m_stream, d); return *this; } - -template -inline packer& packer::pack_uint32(uint32_t d) -{ _pack_uint32(m_stream, d); return *this; } - -template -inline packer& packer::pack_uint64(uint64_t d) -{ _pack_uint64(m_stream, d); return *this; } - -template -inline packer& packer::pack_int8(int8_t d) -{ _pack_int8(m_stream, d); return *this; } - -template -inline packer& packer::pack_int16(int16_t d) -{ _pack_int16(m_stream, d); return *this; } - -template -inline packer& packer::pack_int32(int32_t d) -{ _pack_int32(m_stream, d); return *this; } - -template -inline packer& packer::pack_int64(int64_t d) -{ _pack_int64(m_stream, d); return *this;} - - -template -inline packer& packer::pack_fix_uint8(uint8_t d) -{ _pack_fix_uint8(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_uint16(uint16_t d) -{ _pack_fix_uint16(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_uint32(uint32_t d) -{ _pack_fix_uint32(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_uint64(uint64_t d) -{ _pack_fix_uint64(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_int8(int8_t d) -{ _pack_fix_int8(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_int16(int16_t d) -{ _pack_fix_int16(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_int32(int32_t d) -{ _pack_fix_int32(m_stream, d); return *this; } - -template -inline packer& packer::pack_fix_int64(int64_t d) -{ _pack_fix_int64(m_stream, d); return *this;} - - -template -inline packer& packer::pack_short(short d) -{ _pack_short(m_stream, d); return *this; } - -template -inline packer& packer::pack_int(int d) -{ _pack_int(m_stream, d); return *this; } - -template -inline packer& packer::pack_long(long d) -{ _pack_long(m_stream, d); return *this; } - -template -inline packer& packer::pack_long_long(long long d) -{ _pack_long_long(m_stream, d); return *this; } - -template -inline packer& packer::pack_unsigned_short(unsigned short d) -{ _pack_unsigned_short(m_stream, d); return *this; } - -template -inline packer& packer::pack_unsigned_int(unsigned int d) -{ _pack_unsigned_int(m_stream, d); return *this; } - -template -inline packer& packer::pack_unsigned_long(unsigned long d) -{ _pack_unsigned_long(m_stream, d); return *this; } - -template -inline packer& packer::pack_unsigned_long_long(unsigned long long d) -{ _pack_unsigned_long_long(m_stream, d); return *this; } - - -template -inline packer& packer::pack_float(float d) -{ _pack_float(m_stream, d); return *this; } - -template -inline packer& packer::pack_double(double d) -{ _pack_double(m_stream, d); return *this; } - - -template -inline packer& packer::pack_nil() -{ _pack_nil(m_stream); return *this; } - -template -inline packer& packer::pack_true() -{ _pack_true(m_stream); return *this; } - -template -inline packer& packer::pack_false() -{ _pack_false(m_stream); return *this; } - - -template -inline packer& packer::pack_array(unsigned int n) -{ _pack_array(m_stream, n); return *this; } - - -template -inline packer& packer::pack_map(unsigned int n) -{ _pack_map(m_stream, n); return *this; } - - -template -inline packer& packer::pack_raw(size_t l) -{ _pack_raw(m_stream, l); return *this; } - -template -inline packer& packer::pack_raw_body(const char* b, size_t l) -{ _pack_raw_body(m_stream, b, l); return *this; } - - -} // namespace msgpack - -#endif /* msgpack/pack.hpp */ - diff --git a/msgpack/src/msgpack/sbuffer.h b/msgpack/src/msgpack/sbuffer.h deleted file mode 100644 index 778dea71..00000000 --- a/msgpack/src/msgpack/sbuffer.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * MessagePack for C simple buffer implementation - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_SBUFFER_H__ -#define MSGPACK_SBUFFER_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_sbuffer Simple buffer - * @ingroup msgpack_buffer - * @{ - */ - -typedef struct msgpack_sbuffer { - size_t size; - char* data; - size_t alloc; -} msgpack_sbuffer; - -static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf) -{ - memset(sbuf, 0, sizeof(msgpack_sbuffer)); -} - -static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf) -{ - free(sbuf->data); -} - -static inline msgpack_sbuffer* msgpack_sbuffer_new(void) -{ - return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer)); -} - -static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf) -{ - if(sbuf == NULL) { return; } - msgpack_sbuffer_destroy(sbuf); - free(sbuf); -} - -#ifndef MSGPACK_SBUFFER_INIT_SIZE -#define MSGPACK_SBUFFER_INIT_SIZE 8192 -#endif - -static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len) -{ - msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data; - - if(sbuf->alloc - sbuf->size < len) { - size_t nsize = (sbuf->alloc) ? - sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; - - while(nsize < sbuf->size + len) { nsize *= 2; } - - void* tmp = realloc(sbuf->data, nsize); - if(!tmp) { return -1; } - - sbuf->data = (char*)tmp; - sbuf->alloc = nsize; - } - - memcpy(sbuf->data + sbuf->size, buf, len); - sbuf->size += len; - return 0; -} - -static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf) -{ - char* tmp = sbuf->data; - sbuf->size = 0; - sbuf->data = NULL; - sbuf->alloc = 0; - return tmp; -} - -static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf) -{ - sbuf->size = 0; -} - -/** @} */ - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/sbuffer.h */ - diff --git a/msgpack/src/msgpack/sbuffer.hpp b/msgpack/src/msgpack/sbuffer.hpp deleted file mode 100644 index 14c5d2a2..00000000 --- a/msgpack/src/msgpack/sbuffer.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// -// MessagePack for C++ simple buffer implementation -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_SBUFFER_HPP__ -#define MSGPACK_SBUFFER_HPP__ - -#include "sbuffer.h" -#include - -namespace msgpack { - - -class sbuffer : public msgpack_sbuffer { -public: - sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE) - { - if(initsz == 0) { - base::data = NULL; - } else { - base::data = (char*)::malloc(initsz); - if(!base::data) { - throw std::bad_alloc(); - } - } - - base::size = 0; - base::alloc = initsz; - } - - ~sbuffer() - { - ::free(base::data); - } - -public: - void write(const char* buf, unsigned int len) - { - if(base::alloc - base::size < len) { - expand_buffer(len); - } - memcpy(base::data + base::size, buf, len); - base::size += len; - } - - char* data() - { - return base::data; - } - - const char* data() const - { - return base::data; - } - - size_t size() const - { - return base::size; - } - - char* release() - { - return msgpack_sbuffer_release(this); - } - - void clear() - { - msgpack_sbuffer_clear(this); - } - -private: - void expand_buffer(size_t len) - { - size_t nsize = (base::alloc > 0) ? - base::alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; - - while(nsize < base::size + len) { nsize *= 2; } - - void* tmp = realloc(base::data, nsize); - if(!tmp) { - throw std::bad_alloc(); - } - - base::data = (char*)tmp; - base::alloc = nsize; - } - -private: - typedef msgpack_sbuffer base; - -private: - sbuffer(const sbuffer&); -}; - - -} // namespace msgpack - -#endif /* msgpack/sbuffer.hpp */ - diff --git a/msgpack/src/msgpack/type.hpp b/msgpack/src/msgpack/type.hpp deleted file mode 100644 index bca69bfd..00000000 --- a/msgpack/src/msgpack/type.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "type/bool.hpp" -#include "type/deque.hpp" -#include "type/fixint.hpp" -#include "type/float.hpp" -#include "type/int.hpp" -#include "type/list.hpp" -#include "type/map.hpp" -#include "type/nil.hpp" -#include "type/pair.hpp" -#include "type/raw.hpp" -#include "type/set.hpp" -#include "type/string.hpp" -#include "type/vector.hpp" -#include "type/tuple.hpp" -#include "type/define.hpp" - diff --git a/msgpack/src/msgpack/type/bool.hpp b/msgpack/src/msgpack/type/bool.hpp deleted file mode 100644 index 9433a982..00000000 --- a/msgpack/src/msgpack/type/bool.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_BOOL_HPP__ -#define MSGPACK_TYPE_BOOL_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -inline bool& operator>> (object o, bool& v) -{ - if(o.type != type::BOOLEAN) { throw type_error(); } - v = o.via.boolean; - return v; -} - -template -inline packer& operator<< (packer& o, const bool& v) -{ - if(v) { o.pack_true(); } - else { o.pack_false(); } - return o; -} - -inline void operator<< (object& o, bool v) -{ - o.type = type::BOOLEAN; - o.via.boolean = v; -} - -inline void operator<< (object::with_zone& o, bool v) - { static_cast(o) << v; } - - -} // namespace msgpack - -#endif /* msgpack/type/bool.hpp */ - diff --git a/msgpack/src/msgpack/type/define.hpp.erb b/msgpack/src/msgpack/type/define.hpp.erb deleted file mode 100644 index c8a86512..00000000 --- a/msgpack/src/msgpack/type/define.hpp.erb +++ /dev/null @@ -1,136 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_DEFINE_HPP__ -#define MSGPACK_TYPE_DEFINE_HPP__ - -#define MSGPACK_DEFINE(...) \ - template \ - void msgpack_pack(Packer& pk) const \ - { \ - msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \ - } \ - void msgpack_unpack(msgpack::object o) \ - { \ - msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \ - }\ - template \ - void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \ - { \ - msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ - } - -// MSGPACK_ADD_ENUM must be used in the global namespace. -#define MSGPACK_ADD_ENUM(enum) \ - namespace msgpack { \ - template <> \ - inline enum& operator>> (object o, enum& v) \ - { \ - int tmp; \ - o >> tmp; \ - v = static_cast(tmp); \ - return v; \ - } \ - template <> \ - void operator<< (object::with_zone& o, const enum& v) \ - { \ - int tmp = static_cast(v); \ - o << tmp; \ - } \ - } - -namespace msgpack { -namespace type { - - -<% GENERATION_LIMIT = 31 %> -template , typename A<%=i%> = void<%}%>> -struct define; - - -template <> -struct define<> { - typedef define<> value_type; - typedef tuple<> tuple_type; - template - void msgpack_pack(Packer& pk) const - { - pk.pack_array(0); - } - void msgpack_unpack(msgpack::object o) - { - if(o.type != type::ARRAY) { throw type_error(); } - } - void msgpack_object(msgpack::object* o, msgpack::zone* z) const - { - o->type = type::ARRAY; - o->via.array.ptr = NULL; - o->via.array.size = 0; - } -}; -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -struct define, A<%=j%><%}%>> { - typedef define, A<%=j%><%}%>> value_type; - typedef tuple, A<%=j%><%}%>> tuple_type; - define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) : - a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} - template - void msgpack_pack(Packer& pk) const - { - pk.pack_array(<%=i+1%>); - <%0.upto(i) {|j|%> - pk.pack(a<%=j%>);<%}%> - } - void msgpack_unpack(msgpack::object o) - { - if(o.type != type::ARRAY) { throw type_error(); } - const size_t size = o.via.array.size; - <%0.upto(i) {|j|%> - if(size <= <%=j%>) { return; } o.via.array.ptr[<%=j%>].convert(&a<%=j%>);<%}%> - } - void msgpack_object(msgpack::object* o, msgpack::zone* z) const - { - o->type = type::ARRAY; - o->via.array.ptr = (object*)z->malloc(sizeof(object)*<%=i+1%>); - o->via.array.size = <%=i+1%>; - <%0.upto(i) {|j|%> - o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%> - } - <%0.upto(i) {|j|%> - A<%=j%>& a<%=j%>;<%}%> -}; -<%}%> - -inline define<> make_define() -{ - return define<>(); -} -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -define, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>) -{ - return define, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>); -} -<%}%> - -} // namespace type -} // namespace msgpack - - -#endif /* msgpack/type/define.hpp */ - diff --git a/msgpack/src/msgpack/type/deque.hpp b/msgpack/src/msgpack/type/deque.hpp deleted file mode 100644 index d21ceeae..00000000 --- a/msgpack/src/msgpack/type/deque.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_DEQUE_HPP__ -#define MSGPACK_TYPE_DEQUE_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::deque& operator>> (object o, std::deque& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - v.resize(o.via.array.size); - object* p = o.via.array.ptr; - object* const pend = o.via.array.ptr + o.via.array.size; - typename std::deque::iterator it = v.begin(); - for(; p < pend; ++p, ++it) { - p->convert(&*it); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::deque& v) -{ - o.pack_array(v.size()); - for(typename std::deque::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::deque& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::deque::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/deque.hpp */ - diff --git a/msgpack/src/msgpack/type/fixint.hpp b/msgpack/src/msgpack/type/fixint.hpp deleted file mode 100644 index ebe2696f..00000000 --- a/msgpack/src/msgpack/type/fixint.hpp +++ /dev/null @@ -1,172 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2020 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_FIXINT_HPP__ -#define MSGPACK_TYPE_FIXINT_HPP__ - -#include "msgpack/object.hpp" -#include "msgpack/type/int.hpp" - -namespace msgpack { - -namespace type { - - -template -struct fix_int { - fix_int() : value(0) { } - fix_int(T value) : value(value) { } - - operator T() const { return value; } - - T get() const { return value; } - -private: - T value; -}; - - -typedef fix_int fix_uint8; -typedef fix_int fix_uint16; -typedef fix_int fix_uint32; -typedef fix_int fix_uint64; - -typedef fix_int fix_int8; -typedef fix_int fix_int16; -typedef fix_int fix_int32; -typedef fix_int fix_int64; - - -} // namespace type - - -inline type::fix_int8& operator>> (object o, type::fix_int8& v) - { v = type::detail::convert_integer(o); return v; } - -inline type::fix_int16& operator>> (object o, type::fix_int16& v) - { v = type::detail::convert_integer(o); return v; } - -inline type::fix_int32& operator>> (object o, type::fix_int32& v) - { v = type::detail::convert_integer(o); return v; } - -inline type::fix_int64& operator>> (object o, type::fix_int64& v) - { v = type::detail::convert_integer(o); return v; } - - -inline type::fix_uint8& operator>> (object o, type::fix_uint8& v) - { v = type::detail::convert_integer(o); return v; } - -inline type::fix_uint16& operator>> (object o, type::fix_uint16& v) - { v = type::detail::convert_integer(o); return v; } - -inline type::fix_uint32& operator>> (object o, type::fix_uint32& v) - { v = type::detail::convert_integer(o); return v; } - -inline type::fix_uint64& operator>> (object o, type::fix_uint64& v) - { v = type::detail::convert_integer(o); return v; } - - -template -inline packer& operator<< (packer& o, const type::fix_int8& v) - { o.pack_fix_int8(v); return o; } - -template -inline packer& operator<< (packer& o, const type::fix_int16& v) - { o.pack_fix_int16(v); return o; } - -template -inline packer& operator<< (packer& o, const type::fix_int32& v) - { o.pack_fix_int32(v); return o; } - -template -inline packer& operator<< (packer& o, const type::fix_int64& v) - { o.pack_fix_int64(v); return o; } - - -template -inline packer& operator<< (packer& o, const type::fix_uint8& v) - { o.pack_fix_uint8(v); return o; } - -template -inline packer& operator<< (packer& o, const type::fix_uint16& v) - { o.pack_fix_uint16(v); return o; } - -template -inline packer& operator<< (packer& o, const type::fix_uint32& v) - { o.pack_fix_uint32(v); return o; } - -template -inline packer& operator<< (packer& o, const type::fix_uint64& v) - { o.pack_fix_uint64(v); return o; } - - -inline void operator<< (object& o, type::fix_int8 v) - { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - -inline void operator<< (object& o, type::fix_int16 v) - { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - -inline void operator<< (object& o, type::fix_int32 v) - { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - -inline void operator<< (object& o, type::fix_int64 v) - { v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - - -inline void operator<< (object& o, type::fix_uint8 v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - -inline void operator<< (object& o, type::fix_uint16 v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - -inline void operator<< (object& o, type::fix_uint32 v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - -inline void operator<< (object& o, type::fix_uint64 v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); } - - -inline void operator<< (object::with_zone& o, type::fix_int8 v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, type::fix_int16 v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, type::fix_int32 v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, type::fix_int64 v) - { static_cast(o) << v; } - - -inline void operator<< (object::with_zone& o, type::fix_uint8 v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, type::fix_uint16 v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, type::fix_uint32 v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, type::fix_uint64 v) - { static_cast(o) << v; } - - -} // namespace msgpack - -#endif /* msgpack/type/fixint.hpp */ - diff --git a/msgpack/src/msgpack/type/float.hpp b/msgpack/src/msgpack/type/float.hpp deleted file mode 100644 index 11df6b2c..00000000 --- a/msgpack/src/msgpack/type/float.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_FLOAT_HPP__ -#define MSGPACK_TYPE_FLOAT_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -// FIXME check overflow, underflow - - -inline float& operator>> (object o, float& v) -{ - if(o.type != type::DOUBLE) { throw type_error(); } - v = (float)o.via.dec; - return v; -} - -template -inline packer& operator<< (packer& o, const float& v) -{ - o.pack_float(v); - return o; -} - - -inline double& operator>> (object o, double& v) -{ - if(o.type != type::DOUBLE) { throw type_error(); } - v = o.via.dec; - return v; -} - -template -inline packer& operator<< (packer& o, const double& v) -{ - o.pack_double(v); - return o; -} - - -inline void operator<< (object& o, float v) -{ - o.type = type::DOUBLE; - o.via.dec = (double)v; -} - -inline void operator<< (object& o, double v) -{ - o.type = type::DOUBLE; - o.via.dec = v; -} - -inline void operator<< (object::with_zone& o, float v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, double v) - { static_cast(o) << v; } - - -} // namespace msgpack - -#endif /* msgpack/type/float.hpp */ - diff --git a/msgpack/src/msgpack/type/int.hpp b/msgpack/src/msgpack/type/int.hpp deleted file mode 100644 index e45121df..00000000 --- a/msgpack/src/msgpack/type/int.hpp +++ /dev/null @@ -1,211 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_INT_HPP__ -#define MSGPACK_TYPE_INT_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -namespace type { -namespace detail { - template - struct convert_integer_sign; - - template - struct convert_integer_sign { - static inline T convert(object o) { - if(o.type == type::POSITIVE_INTEGER) { - if(o.via.u64 > (uint64_t)std::numeric_limits::max()) - { throw type_error(); } - return (T)o.via.u64; - } else if(o.type == type::NEGATIVE_INTEGER) { - if(o.via.i64 < (int64_t)std::numeric_limits::min()) - { throw type_error(); } - return (T)o.via.i64; - } - throw type_error(); - } - }; - - template - struct convert_integer_sign { - static inline T convert(object o) { - if(o.type == type::POSITIVE_INTEGER) { - if(o.via.u64 > (uint64_t)std::numeric_limits::max()) - { throw type_error(); } - return (T)o.via.u64; - } - throw type_error(); - } - }; - - template - static inline T convert_integer(object o) - { - return detail::convert_integer_sign::is_signed>::convert(o); - } - -} // namespace detail -} // namespace type - - -inline signed char& operator>> (object o, signed char& v) - { v = type::detail::convert_integer(o); return v; } - -inline signed short& operator>> (object o, signed short& v) - { v = type::detail::convert_integer(o); return v; } - -inline signed int& operator>> (object o, signed int& v) - { v = type::detail::convert_integer(o); return v; } - -inline signed long& operator>> (object o, signed long& v) - { v = type::detail::convert_integer(o); return v; } - -inline signed long long& operator>> (object o, signed long long& v) - { v = type::detail::convert_integer(o); return v; } - - -inline unsigned char& operator>> (object o, unsigned char& v) - { v = type::detail::convert_integer(o); return v; } - -inline unsigned short& operator>> (object o, unsigned short& v) - { v = type::detail::convert_integer(o); return v; } - -inline unsigned int& operator>> (object o, unsigned int& v) - { v = type::detail::convert_integer(o); return v; } - -inline unsigned long& operator>> (object o, unsigned long& v) - { v = type::detail::convert_integer(o); return v; } - -inline unsigned long long& operator>> (object o, unsigned long long& v) - { v = type::detail::convert_integer(o); return v; } - - -template -inline packer& operator<< (packer& o, const signed char& v) - { o.pack_int8(v); return o; } - -template -inline packer& operator<< (packer& o, const signed short& v) - { o.pack_short(v); return o; } - -template -inline packer& operator<< (packer& o, const signed int& v) - { o.pack_int(v); return o; } - -template -inline packer& operator<< (packer& o, const signed long& v) - { o.pack_long(v); return o; } - -template -inline packer& operator<< (packer& o, const signed long long& v) - { o.pack_long_long(v); return o; } - - -template -inline packer& operator<< (packer& o, const unsigned char& v) - { o.pack_uint8(v); return o; } - -template -inline packer& operator<< (packer& o, const unsigned short& v) - { o.pack_unsigned_short(v); return o; } - -template -inline packer& operator<< (packer& o, const unsigned int& v) - { o.pack_unsigned_int(v); return o; } - -template -inline packer& operator<< (packer& o, const unsigned long& v) - { o.pack_unsigned_long(v); return o; } - -template -inline packer& operator<< (packer& o, const unsigned long long& v) - { o.pack_unsigned_long_long(v); return o; } - - -inline void operator<< (object& o, signed char v) - { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, signed short v) - { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, signed int v) - { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, signed long v) - { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, signed long long v) - { v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - - -inline void operator<< (object& o, unsigned char v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, unsigned short v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, unsigned int v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, unsigned long v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - -inline void operator<< (object& o, unsigned long long v) - { o.type = type::POSITIVE_INTEGER, o.via.u64 = v; } - - -inline void operator<< (object::with_zone& o, signed char v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, signed short v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, signed int v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, signed long v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, signed long long v) - { static_cast(o) << v; } - - -inline void operator<< (object::with_zone& o, unsigned char v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, unsigned short v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, unsigned int v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, unsigned long v) - { static_cast(o) << v; } - -inline void operator<< (object::with_zone& o, unsigned long long v) - { static_cast(o) << v; } - - -} // namespace msgpack - -#endif /* msgpack/type/int.hpp */ - diff --git a/msgpack/src/msgpack/type/list.hpp b/msgpack/src/msgpack/type/list.hpp deleted file mode 100644 index c0f8ce63..00000000 --- a/msgpack/src/msgpack/type/list.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_LIST_HPP__ -#define MSGPACK_TYPE_LIST_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::list& operator>> (object o, std::list& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - v.resize(o.via.array.size); - object* p = o.via.array.ptr; - object* const pend = o.via.array.ptr + o.via.array.size; - typename std::list::iterator it = v.begin(); - for(; p < pend; ++p, ++it) { - p->convert(&*it); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::list& v) -{ - o.pack_array(v.size()); - for(typename std::list::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::list& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::list::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/list.hpp */ - diff --git a/msgpack/src/msgpack/type/map.hpp b/msgpack/src/msgpack/type/map.hpp deleted file mode 100644 index 958447d5..00000000 --- a/msgpack/src/msgpack/type/map.hpp +++ /dev/null @@ -1,205 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_MAP_HPP__ -#define MSGPACK_TYPE_MAP_HPP__ - -#include "msgpack/object.hpp" -#include -#include -#include - -namespace msgpack { - - -namespace type { - -template -class assoc_vector : public std::vector< std::pair > {}; - -namespace detail { - template - struct pair_first_less { - bool operator() (const std::pair& x, const std::pair& y) const - { return x.first < y.first; } - }; -} - -} //namespace type - - -template -inline type::assoc_vector& operator>> (object o, type::assoc_vector& v) -{ - if(o.type != type::MAP) { throw type_error(); } - v.resize(o.via.map.size); - object_kv* p = o.via.map.ptr; - object_kv* const pend = o.via.map.ptr + o.via.map.size; - std::pair* it(&v.front()); - for(; p < pend; ++p, ++it) { - p->key.convert(&it->first); - p->val.convert(&it->second); - } - std::sort(v.begin(), v.end(), type::detail::pair_first_less()); - return v; -} - -template -inline packer& operator<< (packer& o, const type::assoc_vector& v) -{ - o.pack_map(v.size()); - for(typename type::assoc_vector::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(it->first); - o.pack(it->second); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const type::assoc_vector& v) -{ - o.type = type::MAP; - if(v.empty()) { - o.via.map.ptr = NULL; - o.via.map.size = 0; - } else { - object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); - object_kv* const pend = p + v.size(); - o.via.map.ptr = p; - o.via.map.size = v.size(); - typename type::assoc_vector::const_iterator it(v.begin()); - do { - p->key = object(it->first, o.zone); - p->val = object(it->second, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -template -inline std::map operator>> (object o, std::map& v) -{ - if(o.type != type::MAP) { throw type_error(); } - object_kv* p(o.via.map.ptr); - object_kv* const pend(o.via.map.ptr + o.via.map.size); - for(; p != pend; ++p) { - K key; - p->key.convert(&key); - typename std::map::iterator it(v.lower_bound(key)); - if(it != v.end() && !(key < it->first)) { - p->val.convert(&it->second); - } else { - V val; - p->val.convert(&val); - v.insert(it, std::pair(key, val)); - } - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::map& v) -{ - o.pack_map(v.size()); - for(typename std::map::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(it->first); - o.pack(it->second); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::map& v) -{ - o.type = type::MAP; - if(v.empty()) { - o.via.map.ptr = NULL; - o.via.map.size = 0; - } else { - object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); - object_kv* const pend = p + v.size(); - o.via.map.ptr = p; - o.via.map.size = v.size(); - typename std::map::const_iterator it(v.begin()); - do { - p->key = object(it->first, o.zone); - p->val = object(it->second, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -template -inline std::multimap operator>> (object o, std::multimap& v) -{ - if(o.type != type::MAP) { throw type_error(); } - object_kv* p(o.via.map.ptr); - object_kv* const pend(o.via.map.ptr + o.via.map.size); - for(; p != pend; ++p) { - std::pair value; - p->key.convert(&value.first); - p->val.convert(&value.second); - v.insert(value); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::multimap& v) -{ - o.pack_map(v.size()); - for(typename std::multimap::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(it->first); - o.pack(it->second); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::multimap& v) -{ - o.type = type::MAP; - if(v.empty()) { - o.via.map.ptr = NULL; - o.via.map.size = 0; - } else { - object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); - object_kv* const pend = p + v.size(); - o.via.map.ptr = p; - o.via.map.size = v.size(); - typename std::multimap::const_iterator it(v.begin()); - do { - p->key = object(it->first, o.zone); - p->val = object(it->second, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/map.hpp */ - diff --git a/msgpack/src/msgpack/type/nil.hpp b/msgpack/src/msgpack/type/nil.hpp deleted file mode 100644 index f44e45e4..00000000 --- a/msgpack/src/msgpack/type/nil.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_NIL_HPP__ -#define MSGPACK_TYPE_NIL_HPP__ - -#include "msgpack/object.hpp" - -namespace msgpack { - -namespace type { - -struct nil { }; - -} // namespace type - - -inline type::nil& operator>> (object o, type::nil& v) -{ - if(o.type != type::NIL) { throw type_error(); } - return v; -} - -template -inline packer& operator<< (packer& o, const type::nil& v) -{ - o.pack_nil(); - return o; -} - -inline void operator<< (object& o, type::nil v) -{ - o.type = type::NIL; -} - -inline void operator<< (object::with_zone& o, type::nil v) - { static_cast(o) << v; } - - -template <> -inline void object::as() const -{ - msgpack::type::nil v; - convert(&v); -} - - -} // namespace msgpack - -#endif /* msgpack/type/nil.hpp */ - diff --git a/msgpack/src/msgpack/type/pair.hpp b/msgpack/src/msgpack/type/pair.hpp deleted file mode 100644 index 296a8b64..00000000 --- a/msgpack/src/msgpack/type/pair.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_PAIR_HPP__ -#define MSGPACK_TYPE_PAIR_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::pair& operator>> (object o, std::pair& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - if(o.via.array.size != 2) { throw type_error(); } - o.via.array.ptr[0].convert(&v.first); - o.via.array.ptr[1].convert(&v.second); - return v; -} - -template -inline packer& operator<< (packer& o, const std::pair& v) -{ - o.pack_array(2); - o.pack(v.first); - o.pack(v.second); - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::pair& v) -{ - o.type = type::ARRAY; - object* p = (object*)o.zone->malloc(sizeof(object)*2); - o.via.array.ptr = p; - o.via.array.size = 2; - p[0] = object(v.first, o.zone); - p[1] = object(v.second, o.zone); -} - - -} // namespace msgpack - -#endif /* msgpack/type/pair.hpp */ - diff --git a/msgpack/src/msgpack/type/raw.hpp b/msgpack/src/msgpack/type/raw.hpp deleted file mode 100644 index 87d188f6..00000000 --- a/msgpack/src/msgpack/type/raw.hpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_RAW_HPP__ -#define MSGPACK_TYPE_RAW_HPP__ - -#include "msgpack/object.hpp" -#include -#include - -namespace msgpack { - -namespace type { - -struct raw_ref { - raw_ref() : size(0), ptr(NULL) {} - raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {} - - uint32_t size; - const char* ptr; - - std::string str() const { return std::string(ptr, size); } - - bool operator== (const raw_ref& x) const - { - return size == x.size && memcmp(ptr, x.ptr, size) == 0; - } - - bool operator!= (const raw_ref& x) const - { - return !(*this != x); - } - - bool operator< (const raw_ref& x) const - { - if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; } - else { return size < x.size; } - } - - bool operator> (const raw_ref& x) const - { - if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; } - else { return size > x.size; } - } -}; - -} // namespace type - - -inline type::raw_ref& operator>> (object o, type::raw_ref& v) -{ - if(o.type != type::RAW) { throw type_error(); } - v.ptr = o.via.raw.ptr; - v.size = o.via.raw.size; - return v; -} - -template -inline packer& operator<< (packer& o, const type::raw_ref& v) -{ - o.pack_raw(v.size); - o.pack_raw_body(v.ptr, v.size); - return o; -} - -inline void operator<< (object& o, const type::raw_ref& v) -{ - o.type = type::RAW; - o.via.raw.ptr = v.ptr; - o.via.raw.size = v.size; -} - -inline void operator<< (object::with_zone& o, const type::raw_ref& v) - { static_cast(o) << v; } - - -} // namespace msgpack - -#endif /* msgpack/type/raw.hpp */ - diff --git a/msgpack/src/msgpack/type/set.hpp b/msgpack/src/msgpack/type/set.hpp deleted file mode 100644 index bcf1030a..00000000 --- a/msgpack/src/msgpack/type/set.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_SET_HPP__ -#define MSGPACK_TYPE_SET_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::set& operator>> (object o, std::set& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - object* p = o.via.array.ptr + o.via.array.size; - object* const pbegin = o.via.array.ptr; - while(p > pbegin) { - --p; - v.insert(p->as()); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::set& v) -{ - o.pack_array(v.size()); - for(typename std::set::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::set& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::set::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -template -inline std::multiset& operator>> (object o, std::multiset& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - object* p = o.via.array.ptr + o.via.array.size; - object* const pbegin = o.via.array.ptr; - while(p > pbegin) { - --p; - v.insert(p->as()); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::multiset& v) -{ - o.pack_array(v.size()); - for(typename std::multiset::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::multiset& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::multiset::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/set.hpp */ - diff --git a/msgpack/src/msgpack/type/string.hpp b/msgpack/src/msgpack/type/string.hpp deleted file mode 100644 index 37d4a172..00000000 --- a/msgpack/src/msgpack/type/string.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_STRING_HPP__ -#define MSGPACK_TYPE_STRING_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -inline std::string& operator>> (object o, std::string& v) -{ - if(o.type != type::RAW) { throw type_error(); } - v.assign(o.via.raw.ptr, o.via.raw.size); - return v; -} - -template -inline packer& operator<< (packer& o, const std::string& v) -{ - o.pack_raw(v.size()); - o.pack_raw_body(v.data(), v.size()); - return o; -} - -inline void operator<< (object::with_zone& o, const std::string& v) -{ - o.type = type::RAW; - char* ptr = (char*)o.zone->malloc(v.size()); - o.via.raw.ptr = ptr; - o.via.raw.size = (uint32_t)v.size(); - memcpy(ptr, v.data(), v.size()); -} - -inline void operator<< (object& o, const std::string& v) -{ - o.type = type::RAW; - o.via.raw.ptr = v.data(); - o.via.raw.size = (uint32_t)v.size(); -} - - -} // namespace msgpack - -#endif /* msgpack/type/string.hpp */ - diff --git a/msgpack/src/msgpack/type/tr1/unordered_map.hpp b/msgpack/src/msgpack/type/tr1/unordered_map.hpp deleted file mode 100644 index 4b29f0ca..00000000 --- a/msgpack/src/msgpack/type/tr1/unordered_map.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__ -#define MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::tr1::unordered_map operator>> (object o, std::tr1::unordered_map& v) -{ - if(o.type != type::MAP) { throw type_error(); } - object_kv* p(o.via.map.ptr); - object_kv* const pend(o.via.map.ptr + o.via.map.size); - for(; p != pend; ++p) { - K key; - p->key.convert(&key); - p->val.convert(&v[key]); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::tr1::unordered_map& v) -{ - o.pack_map(v.size()); - for(typename std::tr1::unordered_map::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(it->first); - o.pack(it->second); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_map& v) -{ - o.type = type::MAP; - if(v.empty()) { - o.via.map.ptr = NULL; - o.via.map.size = 0; - } else { - object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); - object_kv* const pend = p + v.size(); - o.via.map.ptr = p; - o.via.map.size = v.size(); - typename std::tr1::unordered_map::const_iterator it(v.begin()); - do { - p->key = object(it->first, o.zone); - p->val = object(it->second, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -template -inline std::tr1::unordered_multimap operator>> (object o, std::tr1::unordered_multimap& v) -{ - if(o.type != type::MAP) { throw type_error(); } - object_kv* p(o.via.map.ptr); - object_kv* const pend(o.via.map.ptr + o.via.map.size); - for(; p != pend; ++p) { - std::pair value; - p->key.convert(&value.first); - p->val.convert(&value.second); - v.insert(value); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::tr1::unordered_multimap& v) -{ - o.pack_map(v.size()); - for(typename std::tr1::unordered_multimap::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(it->first); - o.pack(it->second); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap& v) -{ - o.type = type::MAP; - if(v.empty()) { - o.via.map.ptr = NULL; - o.via.map.size = 0; - } else { - object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size()); - object_kv* const pend = p + v.size(); - o.via.map.ptr = p; - o.via.map.size = v.size(); - typename std::tr1::unordered_multimap::const_iterator it(v.begin()); - do { - p->key = object(it->first, o.zone); - p->val = object(it->second, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/map.hpp */ - diff --git a/msgpack/src/msgpack/type/tr1/unordered_set.hpp b/msgpack/src/msgpack/type/tr1/unordered_set.hpp deleted file mode 100644 index 4af6801c..00000000 --- a/msgpack/src/msgpack/type/tr1/unordered_set.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__ -#define MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::tr1::unordered_set& operator>> (object o, std::tr1::unordered_set& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - object* p = o.via.array.ptr + o.via.array.size; - object* const pbegin = o.via.array.ptr; - while(p > pbegin) { - --p; - v.insert(p->as()); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::tr1::unordered_set& v) -{ - o.pack_array(v.size()); - for(typename std::tr1::unordered_set::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_set& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::tr1::unordered_set::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -template -inline std::tr1::unordered_multiset& operator>> (object o, std::tr1::unordered_multiset& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - object* p = o.via.array.ptr + o.via.array.size; - object* const pbegin = o.via.array.ptr; - while(p > pbegin) { - --p; - v.insert(p->as()); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::tr1::unordered_multiset& v) -{ - o.pack_array(v.size()); - for(typename std::tr1::unordered_multiset::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::tr1::unordered_multiset::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/set.hpp */ - diff --git a/msgpack/src/msgpack/type/tuple.hpp.erb b/msgpack/src/msgpack/type/tuple.hpp.erb deleted file mode 100644 index ebef8163..00000000 --- a/msgpack/src/msgpack/type/tuple.hpp.erb +++ /dev/null @@ -1,206 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_TUPLE_HPP__ -#define MSGPACK_TYPE_TUPLE_HPP__ - -#include "msgpack/object.hpp" - -namespace msgpack { - -namespace type { - -// FIXME operator== -// FIXME operator!= -<% GENERATION_LIMIT = 31 %> - -template , typename A<%=i%> = void<%}%>> -struct tuple; - -template -struct tuple_element; - -template -struct const_tuple_element; - -template -struct tuple_type { - typedef T type; - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T& transparent_reference; -}; - -template -struct tuple_type { - typedef T type; - typedef T& value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T& transparent_reference; -}; - -template -struct tuple_type { - typedef T type; - typedef T& value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T& transparent_reference; -}; - -<%0.upto(GENERATION_LIMIT) {|i|%> -<%0.upto(i) {|j|%> -template , typename A<%=k%><%}%>> -struct tuple_element, A<%=k%><%}%>>, <%=j%>> : tuple_type> { - tuple_element(tuple, A<%=k%> <%}%>>& x) : _x(x.a<%=j%>) {} - typename tuple_type>::reference get() { return _x; } - typename tuple_type>::const_reference get() const { return _x; } -private: - typename tuple_type>::reference _x; -}; -<%}%> -<%}%> - -<%0.upto(GENERATION_LIMIT) {|i|%> -<%0.upto(i) {|j|%> -template , typename A<%=k%><%}%>> -struct const_tuple_element, A<%=k%><%}%>>, <%=j%>> : tuple_type> { - const_tuple_element(const tuple, A<%=k%><%}%>>& x) : _x(x.a<%=j%>) {} - typename tuple_type>::const_reference get() const { return _x; } -private: - typename tuple_type>::const_reference _x; -}; -<%}%> -<%}%> - -template <> -struct tuple<> { - tuple() {} - tuple(object o) { o.convert(this); } - typedef tuple<> value_type; -}; -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -struct tuple, A<%=j%><%}%>> { - typedef tuple, A<%=j%><%}%>> value_type; - tuple() {} - tuple(typename tuple_type::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type>::transparent_reference _a<%=j%><%}%>) : - a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} - tuple(object o) { o.convert(this); } - template typename tuple_element::reference get() - { return tuple_element(*this).get(); } - template typename const_tuple_element::const_reference get() const - { return const_tuple_element(*this).get(); } - <%0.upto(i) {|j|%> - A<%=j%> a<%=j%>;<%}%> -}; -<%}%> - -inline tuple<> make_tuple() -{ - return tuple<>(); -} -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -tuple, A<%=j%><%}%>> make_tuple(typename tuple_type::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type>::transparent_reference a<%=j%><%}%>) -{ - return tuple, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>); -} -<%}%> - -} // namespace type - - -inline type::tuple<>& operator>> ( - object o, - type::tuple<>& v) { - if(o.type != type::ARRAY) { throw type_error(); } - return v; -} -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -type::tuple, A<%=j%><%}%>>& operator>> ( - object o, - type::tuple, A<%=j%><%}%>>& v) { - if(o.type != type::ARRAY) { throw type_error(); } - if(o.via.array.size < <%=i+1%>) { throw type_error(); } - <%0.upto(i) {|j|%> - o.via.array.ptr[<%=j%>].convert>::type>(&v.template get<<%=j%>>());<%}%> - return v; -} -<%}%> - -template -const packer& operator<< ( - packer& o, - const type::tuple<>& v) { - o.pack_array(0); - return o; -} -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -const packer& operator<< ( - packer& o, - const type::tuple, A<%=j%><%}%>>& v) { - o.pack_array(<%=i+1%>); - <%0.upto(i) {|j|%> - o.pack(v.template get<<%=j%>>());<%}%> - return o; -} -<%}%> - -inline void operator<< ( - object::with_zone& o, - const type::tuple<>& v) { - o.type = type::ARRAY; - o.via.array.ptr = NULL; - o.via.array.size = 0; -} -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -inline void operator<< ( - object::with_zone& o, - const type::tuple, A<%=j%><%}%>>& v) { - o.type = type::ARRAY; - o.via.array.ptr = (object*)o.zone->malloc(sizeof(object)*<%=i+1%>); - o.via.array.size = <%=i+1%>; - <%0.upto(i) {|j|%> - o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%> -} -<%}%> - -} // namespace msgpack - - -//inline std::ostream& operator<< (std::ostream& o, const msgpack::type::tuple<>& v) { -// return o << "[]"; -//} -//<%0.upto(GENERATION_LIMIT) {|i|%> -//template , typename A<%=j%><%}%>> -//inline std::ostream& operator<< (std::ostream& o, -// const msgpack::type::tuple, A<%=j%><%}%>>& v) { -// return o << "[" -// <%0.upto(i) {|j|%> -// <<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%> -// << "]"; -//} -//<%}%> - -#endif /* msgpack/type/tuple.hpp */ - diff --git a/msgpack/src/msgpack/type/vector.hpp b/msgpack/src/msgpack/type/vector.hpp deleted file mode 100644 index bd073ef8..00000000 --- a/msgpack/src/msgpack/type/vector.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// MessagePack for C++ static resolution routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_TYPE_VECTOR_HPP__ -#define MSGPACK_TYPE_VECTOR_HPP__ - -#include "msgpack/object.hpp" -#include - -namespace msgpack { - - -template -inline std::vector& operator>> (object o, std::vector& v) -{ - if(o.type != type::ARRAY) { throw type_error(); } - v.resize(o.via.array.size); - if(o.via.array.size > 0) { - object* p = o.via.array.ptr; - object* const pend = o.via.array.ptr + o.via.array.size; - T* it = &v[0]; - do { - p->convert(it); - ++p; - ++it; - } while(p < pend); - } - return v; -} - -template -inline packer& operator<< (packer& o, const std::vector& v) -{ - o.pack_array(v.size()); - for(typename std::vector::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { - o.pack(*it); - } - return o; -} - -template -inline void operator<< (object::with_zone& o, const std::vector& v) -{ - o.type = type::ARRAY; - if(v.empty()) { - o.via.array.ptr = NULL; - o.via.array.size = 0; - } else { - object* p = (object*)o.zone->malloc(sizeof(object)*v.size()); - object* const pend = p + v.size(); - o.via.array.ptr = p; - o.via.array.size = v.size(); - typename std::vector::const_iterator it(v.begin()); - do { - *p = object(*it, o.zone); - ++p; - ++it; - } while(p < pend); - } -} - - -} // namespace msgpack - -#endif /* msgpack/type/vector.hpp */ - diff --git a/msgpack/src/msgpack/unpack.h b/msgpack/src/msgpack/unpack.h deleted file mode 100644 index bea7d922..00000000 --- a/msgpack/src/msgpack/unpack.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * MessagePack for C unpacking routine - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_UNPACKER_H__ -#define MSGPACK_UNPACKER_H__ - -#include "zone.h" -#include "object.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_unpack Deserializer - * @ingroup msgpack - * @{ - */ - -typedef struct msgpack_unpacked { - msgpack_zone* zone; - msgpack_object data; -} msgpack_unpacked; - -bool msgpack_unpack_next(msgpack_unpacked* result, - const char* data, size_t len, size_t* off); - -/** @} */ - - -/** - * @defgroup msgpack_unpacker Streaming deserializer - * @ingroup msgpack - * @{ - */ - -typedef struct msgpack_unpacker { - char* buffer; - size_t used; - size_t free; - size_t off; - size_t parsed; - msgpack_zone* z; - size_t initial_buffer_size; - void* ctx; -} msgpack_unpacker; - - -#ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE -#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024) -#endif - -/** - * Initializes a streaming deserializer. - * The initialized deserializer must be destroyed by msgpack_unpacker_destroy(msgpack_unpacker*). - */ -bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size); - -/** - * Destroys a streaming deserializer initialized by msgpack_unpacker_init(msgpack_unpacker*, size_t). - */ -void msgpack_unpacker_destroy(msgpack_unpacker* mpac); - - -/** - * Creates a streaming deserializer. - * The created deserializer must be destroyed by msgpack_unpacker_free(msgpack_unpacker*). - */ -msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size); - -/** - * Frees a streaming deserializer created by msgpack_unpacker_new(size_t). - */ -void msgpack_unpacker_free(msgpack_unpacker* mpac); - - -#ifndef MSGPACK_UNPACKER_RESERVE_SIZE -#define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024) -#endif - -/** - * Reserves free space of the internal buffer. - * Use this function to fill the internal buffer with - * msgpack_unpacker_buffer(msgpack_unpacker*), - * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and - * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). - */ -static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size); - -/** - * Gets pointer to the free space of the internal buffer. - * Use this function to fill the internal buffer with - * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), - * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and - * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). - */ -static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac); - -/** - * Gets size of the free space of the internal buffer. - * Use this function to fill the internal buffer with - * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), - * msgpack_unpacker_buffer(const msgpack_unpacker*) and - * msgpack_unpacker_buffer_consumed(msgpack_unpacker*). - */ -static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac); - -/** - * Notifies the deserializer that the internal buffer filled. - * Use this function to fill the internal buffer with - * msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t), - * msgpack_unpacker_buffer(msgpack_unpacker*) and - * msgpack_unpacker_buffer_capacity(const msgpack_unpacker*). - */ -static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size); - - -/** - * Deserializes one object. - * Returns true if it successes. Otherwise false is returned. - * @param pac pointer to an initialized msgpack_unpacked object. - */ -bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* pac); - -/** - * Initializes a msgpack_unpacked object. - * The initialized object must be destroyed by msgpack_unpacked_destroy(msgpack_unpacker*). - * Use the object with msgpack_unpacker_next(msgpack_unpacker*, msgpack_unpacked*) or - * msgpack_unpack_next(msgpack_unpacked*, const char*, size_t, size_t*). - */ -static inline void msgpack_unpacked_init(msgpack_unpacked* result); - -/** - * Destroys a streaming deserializer initialized by msgpack_unpacked(). - */ -static inline void msgpack_unpacked_destroy(msgpack_unpacked* result); - -/** - * Releases the memory zone from msgpack_unpacked object. - * The released zone must be freed by msgpack_zone_free(msgpack_zone*). - */ -static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result); - - -int msgpack_unpacker_execute(msgpack_unpacker* mpac); - -msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac); - -msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac); - -void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac); - -void msgpack_unpacker_reset(msgpack_unpacker* mpac); - -static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac); - - -/** @} */ - - -// obsolete -typedef enum { - MSGPACK_UNPACK_SUCCESS = 2, - MSGPACK_UNPACK_EXTRA_BYTES = 1, - MSGPACK_UNPACK_CONTINUE = 0, - MSGPACK_UNPACK_PARSE_ERROR = -1, -} msgpack_unpack_return; - -// obsolete -msgpack_unpack_return -msgpack_unpack(const char* data, size_t len, size_t* off, - msgpack_zone* result_zone, msgpack_object* result); - - -static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac); - -bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac); - -bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size); - -bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size) -{ - if(mpac->free >= size) { return true; } - return msgpack_unpacker_expand_buffer(mpac, size); -} - -char* msgpack_unpacker_buffer(msgpack_unpacker* mpac) -{ - return mpac->buffer + mpac->used; -} - -size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac) -{ - return mpac->free; -} - -void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size) -{ - mpac->used += size; - mpac->free -= size; -} - -size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac) -{ - return mpac->parsed - mpac->off + mpac->used; -} - -size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac) -{ - return mpac->parsed; -} - - -void msgpack_unpacked_init(msgpack_unpacked* result) -{ - memset(result, 0, sizeof(msgpack_unpacked)); -} - -void msgpack_unpacked_destroy(msgpack_unpacked* result) -{ - if(result->zone != NULL) { - msgpack_zone_free(result->zone); - result->zone = NULL; - memset(&result->data, 0, sizeof(msgpack_object)); - } -} - -msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result) -{ - if(result->zone != NULL) { - msgpack_zone* z = result->zone; - result->zone = NULL; - return z; - } - return NULL; -} - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/unpack.h */ - diff --git a/msgpack/src/msgpack/unpack.hpp b/msgpack/src/msgpack/unpack.hpp deleted file mode 100644 index 4d9de32f..00000000 --- a/msgpack/src/msgpack/unpack.hpp +++ /dev/null @@ -1,374 +0,0 @@ -// -// MessagePack for C++ deserializing routine -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_UNPACK_HPP__ -#define MSGPACK_UNPACK_HPP__ - -#include "unpack.h" -#include "object.hpp" -#include "zone.hpp" -#include -#include - -// backward compatibility -#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE -#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE -#endif - -namespace msgpack { - - -struct unpack_error : public std::runtime_error { - unpack_error(const std::string& msg) : - std::runtime_error(msg) { } -}; - - -class unpacked { -public: - unpacked() { } - - unpacked(object obj, std::auto_ptr z) : - m_obj(obj), m_zone(z) { } - - object& get() - { return m_obj; } - - const object& get() const - { return m_obj; } - - std::auto_ptr& zone() - { return m_zone; } - - const std::auto_ptr& zone() const - { return m_zone; } - -private: - object m_obj; - std::auto_ptr m_zone; -}; - - -class unpacker : public msgpack_unpacker { -public: - unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE); - ~unpacker(); - -public: - /*! 1. reserve buffer. at least `size' bytes of capacity will be ready */ - void reserve_buffer(size_t size = MSGPACK_UNPACKER_RESERVE_SIZE); - - /*! 2. read data to the buffer() up to buffer_capacity() bytes */ - char* buffer(); - size_t buffer_capacity() const; - - /*! 3. specify the number of bytes actually copied */ - void buffer_consumed(size_t size); - - /*! 4. repeat next() until it retunrs false */ - bool next(unpacked* result); - - /*! 5. check if the size of message doesn't exceed assumption. */ - size_t message_size() const; - - // Basic usage of the unpacker is as following: - // - // msgpack::unpacker pac; - // while( /* input is readable */ ) { - // - // // 1. - // pac.reserve_buffer(32*1024); - // - // // 2. - // size_t bytes = input.readsome(pac.buffer(), pac.buffer_capacity()); - // - // // error handling ... - // - // // 3. - // pac.buffer_consumed(bytes); - // - // // 4. - // msgpack::unpacked result; - // while(pac.next(&result)) { - // // do some with the object with the zone. - // msgpack::object obj = result.get(); - // std::auto_ptr z = result.zone(); - // on_message(obj, z); - // - // //// boost::shared_ptr is also usable: - // // boost::shared_ptr life(z.release()); - // // on_message(result.get(), life); - // } - // - // // 5. - // if(pac.message_size() > 10*1024*1024) { - // throw std::runtime_error("message is too large"); - // } - // } - // - - /*! for backward compatibility */ - bool execute(); - - /*! for backward compatibility */ - object data(); - - /*! for backward compatibility */ - zone* release_zone(); - - /*! for backward compatibility */ - void reset_zone(); - - /*! for backward compatibility */ - void reset(); - -public: - // These functions are usable when non-MessagePack message follows after - // MessagePack message. - size_t parsed_size() const; - - /*! get address of the buffer that is not parsed */ - char* nonparsed_buffer(); - size_t nonparsed_size() const; - - /*! skip specified size of non-parsed buffer, leaving the buffer */ - // Note that the `size' argument must be smaller than nonparsed_size() - void skip_nonparsed_buffer(size_t size); - - /*! remove unparsed buffer from unpacker */ - // Note that reset() leaves non-parsed buffer. - void remove_nonparsed_buffer(); - -private: - typedef msgpack_unpacker base; - -private: - unpacker(const unpacker&); -}; - - -static void unpack(unpacked* result, - const char* data, size_t len, size_t* offset = NULL); - - -// obsolete -typedef enum { - UNPACK_SUCCESS = 2, - UNPACK_EXTRA_BYTES = 1, - UNPACK_CONTINUE = 0, - UNPACK_PARSE_ERROR = -1, -} unpack_return; - -// obsolete -static unpack_return unpack(const char* data, size_t len, size_t* off, - zone* z, object* result); - - -// obsolete -static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL); - - -inline unpacker::unpacker(size_t initial_buffer_size) -{ - if(!msgpack_unpacker_init(this, initial_buffer_size)) { - throw std::bad_alloc(); - } -} - -inline unpacker::~unpacker() -{ - msgpack_unpacker_destroy(this); -} - - -inline void unpacker::reserve_buffer(size_t size) -{ - if(!msgpack_unpacker_reserve_buffer(this, size)) { - throw std::bad_alloc(); - } -} - -inline char* unpacker::buffer() -{ - return msgpack_unpacker_buffer(this); -} - -inline size_t unpacker::buffer_capacity() const -{ - return msgpack_unpacker_buffer_capacity(this); -} - -inline void unpacker::buffer_consumed(size_t size) -{ - return msgpack_unpacker_buffer_consumed(this, size); -} - -inline bool unpacker::next(unpacked* result) -{ - int ret = msgpack_unpacker_execute(this); - - if(ret < 0) { - throw unpack_error("parse error"); - } - - if(ret == 0) { - if (result->zone().get() != NULL) result->zone().reset(); - result->get() = object(); - return false; - - } else { - if (result->zone().get() != NULL) result->zone().reset( release_zone() ); - result->get() = data(); - reset(); - return true; - } -} - - -inline bool unpacker::execute() -{ - int ret = msgpack_unpacker_execute(this); - if(ret < 0) { - throw unpack_error("parse error"); - } else if(ret == 0) { - return false; - } else { - return true; - } -} - -inline object unpacker::data() -{ - return msgpack_unpacker_data(this); -} - -inline zone* unpacker::release_zone() -{ - return static_cast(msgpack_unpacker_release_zone(static_cast(this))); -} - -inline void unpacker::reset_zone() -{ - msgpack_unpacker_reset_zone(this); -} - -inline void unpacker::reset() -{ - msgpack_unpacker_reset(this); -} - - -inline size_t unpacker::message_size() const -{ - return msgpack_unpacker_message_size(this); -} - -inline size_t unpacker::parsed_size() const -{ - return msgpack_unpacker_parsed_size(this); -} - -inline char* unpacker::nonparsed_buffer() -{ - return base::buffer + base::off; -} - -inline size_t unpacker::nonparsed_size() const -{ - return base::used - base::off; -} - -inline void unpacker::skip_nonparsed_buffer(size_t size) -{ - base::off += size; -} - -inline void unpacker::remove_nonparsed_buffer() -{ - base::used = base::off; -} - - -inline void unpack(unpacked* result, - const char* data, size_t len, size_t* offset) -{ - msgpack::object obj; - std::auto_ptr z(new zone()); - - unpack_return ret = (unpack_return)msgpack_unpack( - data, len, offset, z.get(), - reinterpret_cast(&obj)); - - switch(ret) { - case UNPACK_SUCCESS: - result->get() = obj; - result->zone() = z; - return; - - case UNPACK_EXTRA_BYTES: - result->get() = obj; - result->zone() = z; - return; - - case UNPACK_CONTINUE: - throw unpack_error("insufficient bytes"); - - case UNPACK_PARSE_ERROR: - default: - throw unpack_error("parse error"); - } -} - - -// obsolete -inline unpack_return unpack(const char* data, size_t len, size_t* off, - zone* z, object* result) -{ - return (unpack_return)msgpack_unpack(data, len, off, - z, reinterpret_cast(result)); -} - -// obsolete -inline object unpack(const char* data, size_t len, zone& z, size_t* off) -{ - object result; - - switch( msgpack::unpack(data, len, off, &z, &result) ) { - case UNPACK_SUCCESS: - return result; - - case UNPACK_EXTRA_BYTES: - if(off) { - return result; - } else { - throw unpack_error("extra bytes"); - } - - case UNPACK_CONTINUE: - throw unpack_error("insufficient bytes"); - - case UNPACK_PARSE_ERROR: - default: - throw unpack_error("parse error"); - } -} - - -} // namespace msgpack - -#endif /* msgpack/unpack.hpp */ - diff --git a/msgpack/src/msgpack/version.h.in b/msgpack/src/msgpack/version.h.in deleted file mode 100644 index f1feb331..00000000 --- a/msgpack/src/msgpack/version.h.in +++ /dev/null @@ -1,40 +0,0 @@ -/* - * MessagePack for C version information - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_VERSION_H__ -#define MSGPACK_VERSION_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -const char* msgpack_version(void); -int msgpack_version_major(void); -int msgpack_version_minor(void); - -#define MSGPACK_VERSION "@VERSION@" -#define MSGPACK_VERSION_MAJOR @VERSION_MAJOR@ -#define MSGPACK_VERSION_MINOR @VERSION_MINOR@ - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/version.h */ - diff --git a/msgpack/src/msgpack/vrefbuffer.h b/msgpack/src/msgpack/vrefbuffer.h deleted file mode 100644 index 0643927e..00000000 --- a/msgpack/src/msgpack/vrefbuffer.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * MessagePack for C zero-copy buffer implementation - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_VREFBUFFER_H__ -#define MSGPACK_VREFBUFFER_H__ - -#include "zone.h" -#include - -#ifndef _WIN32 -#include -#else -struct iovec { - void *iov_base; - size_t iov_len; -}; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_vrefbuffer Vectored Referencing buffer - * @ingroup msgpack_buffer - * @{ - */ - -struct msgpack_vrefbuffer_chunk; -typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk; - -typedef struct msgpack_vrefbuffer_inner_buffer { - size_t free; - char* ptr; - msgpack_vrefbuffer_chunk* head; -} msgpack_vrefbuffer_inner_buffer; - -typedef struct msgpack_vrefbuffer { - struct iovec* tail; - struct iovec* end; - struct iovec* array; - - size_t chunk_size; - size_t ref_size; - - msgpack_vrefbuffer_inner_buffer inner_buffer; -} msgpack_vrefbuffer; - - -#ifndef MSGPACK_VREFBUFFER_REF_SIZE -#define MSGPACK_VREFBUFFER_REF_SIZE 32 -#endif - -#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE -#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192 -#endif - -bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, - size_t ref_size, size_t chunk_size); -void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf); - -static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size); -static inline void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf); - -static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len); - -static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref); -static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref); - -int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf, - const char* buf, unsigned int len); - -int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, - const char* buf, unsigned int len); - -int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to); - -void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vref); - -/** @} */ - - -msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size) -{ - msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)malloc(sizeof(msgpack_vrefbuffer)); - if(!msgpack_vrefbuffer_init(vbuf, ref_size, chunk_size)) { - free(vbuf); - return NULL; - } - return vbuf; -} - -void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf) -{ - if(vbuf == NULL) { return; } - msgpack_vrefbuffer_destroy(vbuf); - free(vbuf); -} - -int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len) -{ - msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data; - - if(len < vbuf->ref_size) { - return msgpack_vrefbuffer_append_copy(vbuf, buf, len); - } else { - return msgpack_vrefbuffer_append_ref(vbuf, buf, len); - } -} - -const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref) -{ - return vref->array; -} - -size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref) -{ - return vref->tail - vref->array; -} - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/vrefbuffer.h */ - diff --git a/msgpack/src/msgpack/vrefbuffer.hpp b/msgpack/src/msgpack/vrefbuffer.hpp deleted file mode 100644 index 82335277..00000000 --- a/msgpack/src/msgpack/vrefbuffer.hpp +++ /dev/null @@ -1,97 +0,0 @@ -// -// MessagePack for C++ zero-copy buffer implementation -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_VREFBUFFER_HPP__ -#define MSGPACK_VREFBUFFER_HPP__ - -#include "vrefbuffer.h" -#include - -namespace msgpack { - - -class vrefbuffer : public msgpack_vrefbuffer { -public: - vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE, - size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE) - { - msgpack_vrefbuffer_init(this, ref_size, chunk_size); - } - - ~vrefbuffer() - { - msgpack_vrefbuffer_destroy(this); - } - -public: - void write(const char* buf, unsigned int len) - { - if(len < base::ref_size) { - append_copy(buf, len); - } else { - append_ref(buf, len); - } - } - - void append_ref(const char* buf, size_t len) - { - if(msgpack_vrefbuffer_append_ref(this, buf, len) < 0) { - throw std::bad_alloc(); - } - } - - void append_copy(const char* buf, size_t len) - { - if(msgpack_vrefbuffer_append_copy(this, buf, len) < 0) { - throw std::bad_alloc(); - } - } - - const struct iovec* vector() const - { - return msgpack_vrefbuffer_vec(this); - } - - size_t vector_size() const - { - return msgpack_vrefbuffer_veclen(this); - } - - void migrate(vrefbuffer* to) - { - if(msgpack_vrefbuffer_migrate(this, to) < 0) { - throw std::bad_alloc(); - } - } - - void clear() - { - msgpack_vrefbuffer_clear(this); - } - -private: - typedef msgpack_vrefbuffer base; - -private: - vrefbuffer(const vrefbuffer&); -}; - - -} // namespace msgpack - -#endif /* msgpack/vrefbuffer.hpp */ - diff --git a/msgpack/src/msgpack/zbuffer.h b/msgpack/src/msgpack/zbuffer.h deleted file mode 100644 index efdd3049..00000000 --- a/msgpack/src/msgpack/zbuffer.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * MessagePack for C deflate buffer implementation - * - * Copyright (C) 2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_ZBUFFER_H__ -#define MSGPACK_ZBUFFER_H__ - -#include "sysdep.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_zbuffer Compressed buffer - * @ingroup msgpack_buffer - * @{ - */ - -typedef struct msgpack_zbuffer { - z_stream stream; - char* data; - size_t init_size; -} msgpack_zbuffer; - -#ifndef MSGPACK_ZBUFFER_INIT_SIZE -#define MSGPACK_ZBUFFER_INIT_SIZE 8192 -#endif - -static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf, - int level, size_t init_size); -static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf); - -static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size); -static inline void msgpack_zbuffer_free(msgpack_zbuffer* zbuf); - -static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf); - -static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf); -static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf); - -static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf); -static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf); -static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf); - - -#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE -#define MSGPACK_ZBUFFER_RESERVE_SIZE 512 -#endif - -static inline int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len); - -static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf); - - -bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf, - int level, size_t init_size) -{ - memset(zbuf, 0, sizeof(msgpack_zbuffer)); - zbuf->init_size = init_size; - if(deflateInit(&zbuf->stream, level) != Z_OK) { - free(zbuf->data); - return false; - } - return true; -} - -void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf) -{ - deflateEnd(&zbuf->stream); - free(zbuf->data); -} - -msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size) -{ - msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer)); - if(!msgpack_zbuffer_init(zbuf, level, init_size)) { - free(zbuf); - return NULL; - } - return zbuf; -} - -void msgpack_zbuffer_free(msgpack_zbuffer* zbuf) -{ - if(zbuf == NULL) { return; } - msgpack_zbuffer_destroy(zbuf); - free(zbuf); -} - -bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf) -{ - size_t used = (char*)zbuf->stream.next_out - zbuf->data; - size_t csize = used + zbuf->stream.avail_out; - size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2; - - char* tmp = (char*)realloc(zbuf->data, nsize); - if(tmp == NULL) { - return false; - } - - zbuf->data = tmp; - zbuf->stream.next_out = (Bytef*)(tmp + used); - zbuf->stream.avail_out = nsize - used; - - return true; -} - -int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len) -{ - msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data; - - zbuf->stream.next_in = (Bytef*)buf; - zbuf->stream.avail_in = len; - - do { - if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) { - if(!msgpack_zbuffer_expand(zbuf)) { - return -1; - } - } - - if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) { - return -1; - } - } while(zbuf->stream.avail_in > 0); - - return 0; -} - -char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf) -{ - while(true) { - switch(deflate(&zbuf->stream, Z_FINISH)) { - case Z_STREAM_END: - return zbuf->data; - case Z_OK: - if(!msgpack_zbuffer_expand(zbuf)) { - return NULL; - } - break; - default: - return NULL; - } - } -} - -const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf) -{ - return zbuf->data; -} - -size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf) -{ - return (char*)zbuf->stream.next_out - zbuf->data; -} - -void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf) -{ - zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data; - zbuf->stream.next_out = (Bytef*)zbuf->data; -} - -bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf) -{ - if(deflateReset(&zbuf->stream) != Z_OK) { - return false; - } - msgpack_zbuffer_reset_buffer(zbuf); - return true; -} - -char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf) -{ - char* tmp = zbuf->data; - zbuf->data = NULL; - zbuf->stream.next_out = NULL; - zbuf->stream.avail_out = 0; - return tmp; -} - -/** @} */ - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/zbuffer.h */ - diff --git a/msgpack/src/msgpack/zbuffer.hpp b/msgpack/src/msgpack/zbuffer.hpp deleted file mode 100644 index 08e6fd03..00000000 --- a/msgpack/src/msgpack/zbuffer.hpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// MessagePack for C++ deflate buffer implementation -// -// Copyright (C) 2010 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_ZBUFFER_HPP__ -#define MSGPACK_ZBUFFER_HPP__ - -#include "zbuffer.h" -#include - -namespace msgpack { - - -class zbuffer : public msgpack_zbuffer { -public: - zbuffer(int level = Z_DEFAULT_COMPRESSION, - size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE) - { - msgpack_zbuffer_init(this, level, init_size); - } - - ~zbuffer() - { - msgpack_zbuffer_destroy(this); - } - -public: - void write(const char* buf, unsigned int len) - { - if(msgpack_zbuffer_write(this, buf, len) < 0) { - throw std::bad_alloc(); - } - } - - char* flush() - { - char* buf = msgpack_zbuffer_flush(this); - if(!buf) { - throw std::bad_alloc(); - } - return buf; - } - - char* data() - { - return base::data; - } - - const char* data() const - { - return base::data; - } - - size_t size() const - { - return msgpack_zbuffer_size(this); - } - - void reset() - { - if(!msgpack_zbuffer_reset(this)) { - throw std::bad_alloc(); - } - } - - void reset_buffer() - { - msgpack_zbuffer_reset_buffer(this); - } - - char* release_buffer() - { - return msgpack_zbuffer_release_buffer(this); - } - -private: - typedef msgpack_zbuffer base; - -private: - zbuffer(const zbuffer&); -}; - - -} // namespace msgpack - -#endif /* msgpack/zbuffer.hpp */ - diff --git a/msgpack/src/msgpack/zone.h b/msgpack/src/msgpack/zone.h deleted file mode 100644 index 0f5817f3..00000000 --- a/msgpack/src/msgpack/zone.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * MessagePack for C memory pool implementation - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_ZONE_H__ -#define MSGPACK_ZONE_H__ - -#include "sysdep.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @defgroup msgpack_zone Memory zone - * @ingroup msgpack - * @{ - */ - -typedef struct msgpack_zone_finalizer { - void (*func)(void* data); - void* data; -} msgpack_zone_finalizer; - -typedef struct msgpack_zone_finalizer_array { - msgpack_zone_finalizer* tail; - msgpack_zone_finalizer* end; - msgpack_zone_finalizer* array; -} msgpack_zone_finalizer_array; - -struct msgpack_zone_chunk; -typedef struct msgpack_zone_chunk msgpack_zone_chunk; - -typedef struct msgpack_zone_chunk_list { - size_t free; - char* ptr; - msgpack_zone_chunk* head; -} msgpack_zone_chunk_list; - -typedef struct msgpack_zone { - msgpack_zone_chunk_list chunk_list; - msgpack_zone_finalizer_array finalizer_array; - size_t chunk_size; -} msgpack_zone; - -#ifndef MSGPACK_ZONE_CHUNK_SIZE -#define MSGPACK_ZONE_CHUNK_SIZE 8192 -#endif - -bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size); -void msgpack_zone_destroy(msgpack_zone* zone); - -msgpack_zone* msgpack_zone_new(size_t chunk_size); -void msgpack_zone_free(msgpack_zone* zone); - -static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size); -static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size); - -static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone, - void (*func)(void* data), void* data); - -static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b); - -bool msgpack_zone_is_empty(msgpack_zone* zone); - -void msgpack_zone_clear(msgpack_zone* zone); - -/** @} */ - - -#ifndef MSGPACK_ZONE_ALIGN -#define MSGPACK_ZONE_ALIGN sizeof(int) -#endif - -void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size); - -void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size) -{ - msgpack_zone_chunk_list* cl = &zone->chunk_list; - - if(zone->chunk_list.free < size) { - return msgpack_zone_malloc_expand(zone, size); - } - - char* ptr = cl->ptr; - cl->free -= size; - cl->ptr += size; - - return ptr; -} - -void* msgpack_zone_malloc(msgpack_zone* zone, size_t size) -{ - return msgpack_zone_malloc_no_align(zone, - ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); -} - - -bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone, - void (*func)(void* data), void* data); - -bool msgpack_zone_push_finalizer(msgpack_zone* zone, - void (*func)(void* data), void* data) -{ - msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; - msgpack_zone_finalizer* fin = fa->tail; - - if(fin == fa->end) { - return msgpack_zone_push_finalizer_expand(zone, func, data); - } - - fin->func = func; - fin->data = data; - - ++fa->tail; - - return true; -} - -void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b) -{ - msgpack_zone tmp = *a; - *a = *b; - *b = tmp; -} - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/zone.h */ - diff --git a/msgpack/src/msgpack/zone.hpp.erb b/msgpack/src/msgpack/zone.hpp.erb deleted file mode 100644 index c6f5481a..00000000 --- a/msgpack/src/msgpack/zone.hpp.erb +++ /dev/null @@ -1,155 +0,0 @@ -// -// MessagePack for C++ memory pool -// -// Copyright (C) 2008-2010 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef MSGPACK_ZONE_HPP__ -#define MSGPACK_ZONE_HPP__ - -#include "zone.h" -#include -#include -#include - -<% GENERATION_LIMIT = 15 %> -namespace msgpack { - - -class zone : public msgpack_zone { -public: - zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE); - ~zone(); - -public: - void* malloc(size_t size); - void* malloc_no_align(size_t size); - - void push_finalizer(void (*func)(void*), void* data); - - template - void push_finalizer(std::auto_ptr obj); - - void clear(); - - void swap(zone& o); - - <%0.upto(GENERATION_LIMIT) {|i|%> - template , typename A<%=j%><%}%>> - T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>); - <%}%> - -private: - void undo_malloc(size_t size); - - template - static void object_destructor(void* obj); - - typedef msgpack_zone base; - -private: - zone(const zone&); -}; - - - -inline zone::zone(size_t chunk_size) -{ - msgpack_zone_init(this, chunk_size); -} - -inline zone::~zone() -{ - msgpack_zone_destroy(this); -} - -inline void* zone::malloc(size_t size) -{ - void* ptr = msgpack_zone_malloc(this, size); - if(!ptr) { - throw std::bad_alloc(); - } - return ptr; -} - -inline void* zone::malloc_no_align(size_t size) -{ - void* ptr = msgpack_zone_malloc_no_align(this, size); - if(!ptr) { - throw std::bad_alloc(); - } - return ptr; -} - -inline void zone::push_finalizer(void (*func)(void*), void* data) -{ - if(!msgpack_zone_push_finalizer(this, func, data)) { - throw std::bad_alloc(); - } -} - -template -inline void zone::push_finalizer(std::auto_ptr obj) -{ - if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, obj.get())) { - throw std::bad_alloc(); - } - obj.release(); -} - -inline void zone::clear() -{ - msgpack_zone_clear(this); -} - -inline void zone::swap(zone& o) -{ - msgpack_zone_swap(this, &o); -} - -template -void zone::object_destructor(void* obj) -{ - reinterpret_cast(obj)->~T(); -} - -inline void zone::undo_malloc(size_t size) -{ - base::chunk_list.ptr -= size; - base::chunk_list.free += size; -} - -<%0.upto(GENERATION_LIMIT) {|i|%> -template , typename A<%=j%><%}%>> -T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>) -{ - void* x = malloc(sizeof(T)); - if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { - undo_malloc(sizeof(T)); - throw std::bad_alloc(); - } - try { - return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); - } catch (...) { - --base::finalizer_array.tail; - undo_malloc(sizeof(T)); - throw; - } -} -<%}%> - -} // namespace msgpack - -#endif /* msgpack/zone.hpp */ - diff --git a/msgpack/src/object.cpp b/msgpack/src/object.cpp deleted file mode 100644 index dfe32bbc..00000000 --- a/msgpack/src/object.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// MessagePack for C++ dynamic typed objects -// -// Copyright (C) 2008-2009 FURUHASHI Sadayuki -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#include "msgpack/object.hpp" - -namespace msgpack { - - -std::ostream& operator<< (std::ostream& s, const object o) -{ - switch(o.type) { - case type::NIL: - s << "nil"; - break; - - case type::BOOLEAN: - s << (o.via.boolean ? "true" : "false"); - break; - - case type::POSITIVE_INTEGER: - s << o.via.u64; - break; - - case type::NEGATIVE_INTEGER: - s << o.via.i64; - break; - - case type::DOUBLE: - s << o.via.dec; - break; - - case type::RAW: - (s << '"').write(o.via.raw.ptr, o.via.raw.size) << '"'; - break; - - case type::ARRAY: - s << "["; - if(o.via.array.size != 0) { - object* p(o.via.array.ptr); - s << *p; - ++p; - for(object* const pend(o.via.array.ptr + o.via.array.size); - p < pend; ++p) { - s << ", " << *p; - } - } - s << "]"; - break; - - case type::MAP: - s << "{"; - if(o.via.map.size != 0) { - object_kv* p(o.via.map.ptr); - s << p->key << "=>" << p->val; - ++p; - for(object_kv* const pend(o.via.map.ptr + o.via.map.size); - p < pend; ++p) { - s << ", " << p->key << "=>" << p->val; - } - } - s << "}"; - break; - - default: - // FIXME - s << "#"; - } - return s; -} - - -} // namespace msgpack - diff --git a/msgpack/src/objectc.c b/msgpack/src/objectc.c deleted file mode 100644 index 548e923e..00000000 --- a/msgpack/src/objectc.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * MessagePack for C dynamic typing routine - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "msgpack/object.h" -#include "msgpack/pack.h" -#include -#include - -#ifndef _MSC_VER -#include -#else -#ifndef PRIu64 -#define PRIu64 "I64u" -#endif -#ifndef PRIi64 -#define PRIi64 "I64d" -#endif -#endif - - -int msgpack_pack_object(msgpack_packer* pk, msgpack_object d) -{ - switch(d.type) { - case MSGPACK_OBJECT_NIL: - return msgpack_pack_nil(pk); - - case MSGPACK_OBJECT_BOOLEAN: - if(d.via.boolean) { - return msgpack_pack_true(pk); - } else { - return msgpack_pack_false(pk); - } - - case MSGPACK_OBJECT_POSITIVE_INTEGER: - return msgpack_pack_uint64(pk, d.via.u64); - - case MSGPACK_OBJECT_NEGATIVE_INTEGER: - return msgpack_pack_int64(pk, d.via.i64); - - case MSGPACK_OBJECT_DOUBLE: - return msgpack_pack_double(pk, d.via.dec); - - case MSGPACK_OBJECT_RAW: - { - int ret = msgpack_pack_raw(pk, d.via.raw.size); - if(ret < 0) { return ret; } - return msgpack_pack_raw_body(pk, d.via.raw.ptr, d.via.raw.size); - } - - case MSGPACK_OBJECT_ARRAY: - { - int ret = msgpack_pack_array(pk, d.via.array.size); - if(ret < 0) { return ret; } - - msgpack_object* o = d.via.array.ptr; - msgpack_object* const oend = d.via.array.ptr + d.via.array.size; - for(; o != oend; ++o) { - ret = msgpack_pack_object(pk, *o); - if(ret < 0) { return ret; } - } - - return 0; - } - - case MSGPACK_OBJECT_MAP: - { - int ret = msgpack_pack_map(pk, d.via.map.size); - if(ret < 0) { return ret; } - - msgpack_object_kv* kv = d.via.map.ptr; - msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size; - for(; kv != kvend; ++kv) { - ret = msgpack_pack_object(pk, kv->key); - if(ret < 0) { return ret; } - ret = msgpack_pack_object(pk, kv->val); - if(ret < 0) { return ret; } - } - - return 0; - } - - default: - return -1; - } -} - - -void msgpack_object_print(FILE* out, msgpack_object o) -{ - switch(o.type) { - case MSGPACK_OBJECT_NIL: - fprintf(out, "nil"); - break; - - case MSGPACK_OBJECT_BOOLEAN: - fprintf(out, (o.via.boolean ? "true" : "false")); - break; - - case MSGPACK_OBJECT_POSITIVE_INTEGER: - fprintf(out, "%"PRIu64, o.via.u64); - break; - - case MSGPACK_OBJECT_NEGATIVE_INTEGER: - fprintf(out, "%"PRIi64, o.via.i64); - break; - - case MSGPACK_OBJECT_DOUBLE: - fprintf(out, "%f", o.via.dec); - break; - - case MSGPACK_OBJECT_RAW: - fprintf(out, "\""); - fwrite(o.via.raw.ptr, o.via.raw.size, 1, out); - fprintf(out, "\""); - break; - - case MSGPACK_OBJECT_ARRAY: - fprintf(out, "["); - if(o.via.array.size != 0) { - msgpack_object* p = o.via.array.ptr; - msgpack_object_print(out, *p); - ++p; - msgpack_object* const pend = o.via.array.ptr + o.via.array.size; - for(; p < pend; ++p) { - fprintf(out, ", "); - msgpack_object_print(out, *p); - } - } - fprintf(out, "]"); - break; - - case MSGPACK_OBJECT_MAP: - fprintf(out, "{"); - if(o.via.map.size != 0) { - msgpack_object_kv* p = o.via.map.ptr; - msgpack_object_print(out, p->key); - fprintf(out, "=>"); - msgpack_object_print(out, p->val); - ++p; - msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size; - for(; p < pend; ++p) { - fprintf(out, ", "); - msgpack_object_print(out, p->key); - fprintf(out, "=>"); - msgpack_object_print(out, p->val); - } - } - fprintf(out, "}"); - break; - - default: - // FIXME - fprintf(out, "#", o.type, o.via.u64); - } -} - -bool msgpack_object_equal(const msgpack_object x, const msgpack_object y) -{ - if(x.type != y.type) { return false; } - - switch(x.type) { - case MSGPACK_OBJECT_NIL: - return true; - - case MSGPACK_OBJECT_BOOLEAN: - return x.via.boolean == y.via.boolean; - - case MSGPACK_OBJECT_POSITIVE_INTEGER: - return x.via.u64 == y.via.u64; - - case MSGPACK_OBJECT_NEGATIVE_INTEGER: - return x.via.i64 == y.via.i64; - - case MSGPACK_OBJECT_DOUBLE: - return x.via.dec == y.via.dec; - - case MSGPACK_OBJECT_RAW: - return x.via.raw.size == y.via.raw.size && - memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0; - - case MSGPACK_OBJECT_ARRAY: - if(x.via.array.size != y.via.array.size) { - return false; - } else if(x.via.array.size == 0) { - return true; - } else { - msgpack_object* px = x.via.array.ptr; - msgpack_object* const pxend = x.via.array.ptr + x.via.array.size; - msgpack_object* py = y.via.array.ptr; - do { - if(!msgpack_object_equal(*px, *py)) { - return false; - } - ++px; - ++py; - } while(px < pxend); - return true; - } - - case MSGPACK_OBJECT_MAP: - if(x.via.map.size != y.via.map.size) { - return false; - } else if(x.via.map.size == 0) { - return true; - } else { - msgpack_object_kv* px = x.via.map.ptr; - msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size; - msgpack_object_kv* py = y.via.map.ptr; - do { - if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) { - return false; - } - ++px; - ++py; - } while(px < pxend); - return true; - } - - default: - return false; - } -} - diff --git a/msgpack/src/unpack.c b/msgpack/src/unpack.c deleted file mode 100644 index 4afc05e2..00000000 --- a/msgpack/src/unpack.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * MessagePack for C unpacking routine - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "msgpack/unpack.h" -#include "msgpack/unpack_define.h" -#include - -#ifdef _msgpack_atomic_counter_header -#include _msgpack_atomic_counter_header -#endif - - -typedef struct { - msgpack_zone* z; - bool referenced; -} unpack_user; - - -#define msgpack_unpack_struct(name) \ - struct template ## name - -#define msgpack_unpack_func(ret, name) \ - ret template ## name - -#define msgpack_unpack_callback(name) \ - template_callback ## name - -#define msgpack_unpack_object msgpack_object - -#define msgpack_unpack_user unpack_user - - -struct template_context; -typedef struct template_context template_context; - -static void template_init(template_context* ctx); - -static msgpack_object template_data(template_context* ctx); - -static int template_execute(template_context* ctx, - const char* data, size_t len, size_t* off); - - -static inline msgpack_object template_callback_root(unpack_user* u) -{ msgpack_object o = {}; return o; } - -static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - -static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - -static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - -static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - -static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o) -{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } - -static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o) -{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } - -static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o) -{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } - -static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o) -{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; } - else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } } - -static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; } - -static inline int template_callback_double(unpack_user* u, double d, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; } - -static inline int template_callback_nil(unpack_user* u, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_NIL; return 0; } - -static inline int template_callback_true(unpack_user* u, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = true; return 0; } - -static inline int template_callback_false(unpack_user* u, msgpack_object* o) -{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = false; return 0; } - -static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o) -{ - o->type = MSGPACK_OBJECT_ARRAY; - o->via.array.size = 0; - o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object)); - if(o->via.array.ptr == NULL) { return -1; } - return 0; -} - -static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o) -{ c->via.array.ptr[c->via.array.size++] = o; return 0; } - -static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o) -{ - o->type = MSGPACK_OBJECT_MAP; - o->via.map.size = 0; - o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv)); - if(o->via.map.ptr == NULL) { return -1; } - return 0; -} - -static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v) -{ - c->via.map.ptr[c->via.map.size].key = k; - c->via.map.ptr[c->via.map.size].val = v; - ++c->via.map.size; - return 0; -} - -static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o) -{ - o->type = MSGPACK_OBJECT_RAW; - o->via.raw.ptr = p; - o->via.raw.size = l; - u->referenced = true; - return 0; -} - -#include "msgpack/unpack_template.h" - - -#define CTX_CAST(m) ((template_context*)(m)) -#define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced - -#define COUNTER_SIZE (sizeof(_msgpack_atomic_counter_t)) - - -static inline void init_count(void* buffer) -{ - *(volatile _msgpack_atomic_counter_t*)buffer = 1; -} - -static inline void decl_count(void* buffer) -{ - // atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); } - if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) { - free(buffer); - } -} - -static inline void incr_count(void* buffer) -{ - // atomic ++*(_msgpack_atomic_counter_t*)buffer; - _msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer); -} - -static inline _msgpack_atomic_counter_t get_count(void* buffer) -{ - return *(volatile _msgpack_atomic_counter_t*)buffer; -} - - - -bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size) -{ - if(initial_buffer_size < COUNTER_SIZE) { - initial_buffer_size = COUNTER_SIZE; - } - - char* buffer = (char*)malloc(initial_buffer_size); - if(buffer == NULL) { - return false; - } - - void* ctx = malloc(sizeof(template_context)); - if(ctx == NULL) { - free(buffer); - return false; - } - - msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); - if(z == NULL) { - free(ctx); - free(buffer); - return false; - } - - mpac->buffer = buffer; - mpac->used = COUNTER_SIZE; - mpac->free = initial_buffer_size - mpac->used; - mpac->off = COUNTER_SIZE; - mpac->parsed = 0; - mpac->initial_buffer_size = initial_buffer_size; - mpac->z = z; - mpac->ctx = ctx; - - init_count(mpac->buffer); - - template_init(CTX_CAST(mpac->ctx)); - CTX_CAST(mpac->ctx)->user.z = mpac->z; - CTX_CAST(mpac->ctx)->user.referenced = false; - - return true; -} - -void msgpack_unpacker_destroy(msgpack_unpacker* mpac) -{ - msgpack_zone_free(mpac->z); - free(mpac->ctx); - decl_count(mpac->buffer); -} - - -msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size) -{ - msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker)); - if(mpac == NULL) { - return NULL; - } - - if(!msgpack_unpacker_init(mpac, initial_buffer_size)) { - free(mpac); - return NULL; - } - - return mpac; -} - -void msgpack_unpacker_free(msgpack_unpacker* mpac) -{ - msgpack_unpacker_destroy(mpac); - free(mpac); -} - -bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size) -{ - if(mpac->used == mpac->off && get_count(mpac->buffer) == 1 - && !CTX_REFERENCED(mpac)) { - // rewind buffer - mpac->free += mpac->used - COUNTER_SIZE; - mpac->used = COUNTER_SIZE; - mpac->off = COUNTER_SIZE; - - if(mpac->free >= size) { - return true; - } - } - - if(mpac->off == COUNTER_SIZE) { - size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE - while(next_size < size + mpac->used) { - next_size *= 2; - } - - char* tmp = (char*)realloc(mpac->buffer, next_size); - if(tmp == NULL) { - return false; - } - - mpac->buffer = tmp; - mpac->free = next_size - mpac->used; - - } else { - size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE - size_t not_parsed = mpac->used - mpac->off; - while(next_size < size + not_parsed + COUNTER_SIZE) { - next_size *= 2; - } - - char* tmp = (char*)malloc(next_size); - if(tmp == NULL) { - return false; - } - - init_count(tmp); - - memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed); - - if(CTX_REFERENCED(mpac)) { - if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) { - free(tmp); - return false; - } - CTX_REFERENCED(mpac) = false; - } else { - decl_count(mpac->buffer); - } - - mpac->buffer = tmp; - mpac->used = not_parsed + COUNTER_SIZE; - mpac->free = next_size - mpac->used; - mpac->off = COUNTER_SIZE; - } - - return true; -} - -int msgpack_unpacker_execute(msgpack_unpacker* mpac) -{ - size_t off = mpac->off; - int ret = template_execute(CTX_CAST(mpac->ctx), - mpac->buffer, mpac->used, &mpac->off); - if(mpac->off > off) { - mpac->parsed += mpac->off - off; - } - return ret; -} - -msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac) -{ - return template_data(CTX_CAST(mpac->ctx)); -} - -msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac) -{ - if(!msgpack_unpacker_flush_zone(mpac)) { - return NULL; - } - - msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); - if(r == NULL) { - return NULL; - } - - msgpack_zone* old = mpac->z; - mpac->z = r; - CTX_CAST(mpac->ctx)->user.z = mpac->z; - - return old; -} - -void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac) -{ - msgpack_zone_clear(mpac->z); -} - -bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac) -{ - if(CTX_REFERENCED(mpac)) { - if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) { - return false; - } - CTX_REFERENCED(mpac) = false; - - incr_count(mpac->buffer); - } - - return true; -} - -void msgpack_unpacker_reset(msgpack_unpacker* mpac) -{ - template_init(CTX_CAST(mpac->ctx)); - // don't reset referenced flag - mpac->parsed = 0; -} - -bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result) -{ - if(result->zone != NULL) { - msgpack_zone_free(result->zone); - } - - int ret = msgpack_unpacker_execute(mpac); - - if(ret <= 0) { - result->zone = NULL; - memset(&result->data, 0, sizeof(msgpack_object)); - return false; - } - - result->zone = msgpack_unpacker_release_zone(mpac); - result->data = msgpack_unpacker_data(mpac); - msgpack_unpacker_reset(mpac); - - return true; -} - - -msgpack_unpack_return -msgpack_unpack(const char* data, size_t len, size_t* off, - msgpack_zone* result_zone, msgpack_object* result) -{ - size_t noff = 0; - if(off != NULL) { noff = *off; } - - if(len <= noff) { - // FIXME - return MSGPACK_UNPACK_CONTINUE; - } - - template_context ctx; - template_init(&ctx); - - ctx.user.z = result_zone; - ctx.user.referenced = false; - - int e = template_execute(&ctx, data, len, &noff); - if(e < 0) { - return MSGPACK_UNPACK_PARSE_ERROR; - } - - if(off != NULL) { *off = noff; } - - if(e == 0) { - return MSGPACK_UNPACK_CONTINUE; - } - - *result = template_data(&ctx); - - if(noff < len) { - return MSGPACK_UNPACK_EXTRA_BYTES; - } - - return MSGPACK_UNPACK_SUCCESS; -} - -bool msgpack_unpack_next(msgpack_unpacked* result, - const char* data, size_t len, size_t* off) -{ - msgpack_unpacked_destroy(result); - - size_t noff = 0; - if(off != NULL) { noff = *off; } - - if(len <= noff) { - return false; - } - - msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE); - - template_context ctx; - template_init(&ctx); - - ctx.user.z = z; - ctx.user.referenced = false; - - int e = template_execute(&ctx, data, len, &noff); - if(e <= 0) { - msgpack_zone_free(z); - return false; - } - - if(off != NULL) { *off = noff; } - - result->zone = z; - result->data = template_data(&ctx); - - return true; -} - -// FIXME: Dirty hack to avoid a bus error caused by OS X's old gcc. -static void dummy_function_to_avoid_bus_error() -{ -} diff --git a/msgpack/src/version.c b/msgpack/src/version.c deleted file mode 100644 index 3d956f18..00000000 --- a/msgpack/src/version.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "msgpack.h" - -const char* msgpack_version(void) -{ - return MSGPACK_VERSION; -} - -int msgpack_version_major(void) -{ - return MSGPACK_VERSION_MAJOR; -} - -int msgpack_version_minor(void) -{ - return MSGPACK_VERSION_MINOR; -} - diff --git a/msgpack/src/vrefbuffer.c b/msgpack/src/vrefbuffer.c deleted file mode 100644 index a27b138e..00000000 --- a/msgpack/src/vrefbuffer.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * MessagePack for C zero-copy buffer implementation - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "msgpack/vrefbuffer.h" -#include -#include - -struct msgpack_vrefbuffer_chunk { - struct msgpack_vrefbuffer_chunk* next; - /* data ... */ -}; - -bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf, - size_t ref_size, size_t chunk_size) -{ - vbuf->chunk_size = chunk_size; - vbuf->ref_size = ref_size; - - size_t nfirst = (sizeof(struct iovec) < 72/2) ? - 72 / sizeof(struct iovec) : 8; - - struct iovec* array = (struct iovec*)malloc( - sizeof(struct iovec) * nfirst); - if(array == NULL) { - return false; - } - - vbuf->tail = array; - vbuf->end = array + nfirst; - vbuf->array = array; - - msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc( - sizeof(msgpack_vrefbuffer_chunk) + chunk_size); - if(chunk == NULL) { - free(array); - return false; - } - - msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; - - ib->free = chunk_size; - ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); - ib->head = chunk; - chunk->next = NULL; - - return true; -} - -void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf) -{ - msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head; - while(true) { - msgpack_vrefbuffer_chunk* n = c->next; - free(c); - if(n != NULL) { - c = n; - } else { - break; - } - } - free(vbuf->array); -} - -void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf) -{ - msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next; - msgpack_vrefbuffer_chunk* n; - while(c != NULL) { - n = c->next; - free(c); - c = n; - } - - msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; - msgpack_vrefbuffer_chunk* chunk = ib->head; - chunk->next = NULL; - ib->free = vbuf->chunk_size; - ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); - - vbuf->tail = vbuf->array; -} - -int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf, - const char* buf, unsigned int len) -{ - if(vbuf->tail == vbuf->end) { - const size_t nused = vbuf->tail - vbuf->array; - const size_t nnext = nused * 2; - - struct iovec* nvec = (struct iovec*)realloc( - vbuf->array, sizeof(struct iovec)*nnext); - if(nvec == NULL) { - return -1; - } - - vbuf->array = nvec; - vbuf->end = nvec + nnext; - vbuf->tail = nvec + nused; - } - - vbuf->tail->iov_base = (char*)buf; - vbuf->tail->iov_len = len; - ++vbuf->tail; - - return 0; -} - -int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf, - const char* buf, unsigned int len) -{ - msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; - - if(ib->free < len) { - size_t sz = vbuf->chunk_size; - if(sz < len) { - sz = len; - } - - msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc( - sizeof(msgpack_vrefbuffer_chunk) + sz); - if(chunk == NULL) { - return -1; - } - - chunk->next = ib->head; - ib->head = chunk; - ib->free = sz; - ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk); - } - - char* m = ib->ptr; - memcpy(m, buf, len); - ib->free -= len; - ib->ptr += len; - - if(vbuf->tail != vbuf->array && m == - (const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) { - (vbuf->tail-1)->iov_len += len; - return 0; - } else { - return msgpack_vrefbuffer_append_ref(vbuf, m, len); - } -} - -int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to) -{ - size_t sz = vbuf->chunk_size; - - msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc( - sizeof(msgpack_vrefbuffer_chunk) + sz); - if(empty == NULL) { - return -1; - } - - empty->next = NULL; - - - const size_t nused = vbuf->tail - vbuf->array; - if(to->tail + nused < vbuf->end) { - const size_t tosize = to->tail - to->array; - const size_t reqsize = nused + tosize; - size_t nnext = (to->end - to->array) * 2; - while(nnext < reqsize) { - nnext *= 2; - } - - struct iovec* nvec = (struct iovec*)realloc( - to->array, sizeof(struct iovec)*nnext); - if(nvec == NULL) { - free(empty); - return -1; - } - - to->array = nvec; - to->end = nvec + nnext; - to->tail = nvec + tosize; - } - - memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused); - - to->tail += nused; - vbuf->tail = vbuf->array; - - - msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer; - msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer; - - msgpack_vrefbuffer_chunk* last = ib->head; - while(last->next != NULL) { - last = last->next; - } - last->next = toib->head; - toib->head = ib->head; - - if(toib->free < ib->free) { - toib->free = ib->free; - toib->ptr = ib->ptr; - } - - ib->head = empty; - ib->free = sz; - ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk); - - return 0; -} - diff --git a/msgpack/src/zone.c b/msgpack/src/zone.c deleted file mode 100644 index 8cc8b0de..00000000 --- a/msgpack/src/zone.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * MessagePack for C memory pool implementation - * - * Copyright (C) 2008-2009 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "msgpack/zone.h" -#include -#include - -struct msgpack_zone_chunk { - struct msgpack_zone_chunk* next; - /* data ... */ -}; - -static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size) -{ - msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc( - sizeof(msgpack_zone_chunk) + chunk_size); - if(chunk == NULL) { - return false; - } - - cl->head = chunk; - cl->free = chunk_size; - cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk); - chunk->next = NULL; - - return true; -} - -static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl) -{ - msgpack_zone_chunk* c = cl->head; - while(true) { - msgpack_zone_chunk* n = c->next; - free(c); - if(n != NULL) { - c = n; - } else { - break; - } - } -} - -static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size) -{ - msgpack_zone_chunk* c = cl->head; - while(true) { - msgpack_zone_chunk* n = c->next; - if(n != NULL) { - free(c); - c = n; - } else { - break; - } - } - cl->head->next = NULL; - cl->free = chunk_size; - cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk); -} - -void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size) -{ - msgpack_zone_chunk_list* const cl = &zone->chunk_list; - - size_t sz = zone->chunk_size; - - while(sz < size) { - sz *= 2; - } - - msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc( - sizeof(msgpack_zone_chunk) + sz); - - char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk); - - chunk->next = cl->head; - cl->head = chunk; - cl->free = sz - size; - cl->ptr = ptr + size; - - return ptr; -} - - -static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa) -{ - fa->tail = NULL; - fa->end = NULL; - fa->array = NULL; -} - -static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa) -{ - msgpack_zone_finalizer* fin = fa->tail; - for(; fin != fa->array; --fin) { - (*(fin-1)->func)((fin-1)->data); - } -} - -static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa) -{ - call_finalizer_array(fa); - free(fa->array); -} - -static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa) -{ - call_finalizer_array(fa); - fa->tail = fa->array; -} - -bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone, - void (*func)(void* data), void* data) -{ - msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; - - const size_t nused = fa->end - fa->array; - - size_t nnext; - if(nused == 0) { - nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ? - 72 / sizeof(msgpack_zone_finalizer) : 8; - - } else { - nnext = nused * 2; - } - - msgpack_zone_finalizer* tmp = - (msgpack_zone_finalizer*)realloc(fa->array, - sizeof(msgpack_zone_finalizer) * nnext); - if(tmp == NULL) { - return false; - } - - fa->array = tmp; - fa->end = tmp + nnext; - fa->tail = tmp + nused; - - fa->tail->func = func; - fa->tail->data = data; - - ++fa->tail; - - return true; -} - - -bool msgpack_zone_is_empty(msgpack_zone* zone) -{ - msgpack_zone_chunk_list* const cl = &zone->chunk_list; - msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; - return cl->free == zone->chunk_size && cl->head->next == NULL && - fa->tail == fa->array; -} - - -void msgpack_zone_destroy(msgpack_zone* zone) -{ - destroy_finalizer_array(&zone->finalizer_array); - destroy_chunk_list(&zone->chunk_list); -} - -void msgpack_zone_clear(msgpack_zone* zone) -{ - clear_finalizer_array(&zone->finalizer_array); - clear_chunk_list(&zone->chunk_list, zone->chunk_size); -} - -bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size) -{ - zone->chunk_size = chunk_size; - - if(!init_chunk_list(&zone->chunk_list, chunk_size)) { - return false; - } - - init_finalizer_array(&zone->finalizer_array); - - return true; -} - -msgpack_zone* msgpack_zone_new(size_t chunk_size) -{ - msgpack_zone* zone = (msgpack_zone*)malloc( - sizeof(msgpack_zone) + chunk_size); - if(zone == NULL) { - return NULL; - } - - zone->chunk_size = chunk_size; - - if(!init_chunk_list(&zone->chunk_list, chunk_size)) { - free(zone); - return NULL; - } - - init_finalizer_array(&zone->finalizer_array); - - return zone; -} - -void msgpack_zone_free(msgpack_zone* zone) -{ - if(zone == NULL) { return; } - msgpack_zone_destroy(zone); - free(zone); -} - diff --git a/msgpack/sysdep.h b/msgpack/sysdep.h deleted file mode 100644 index 4fedbd8b..00000000 --- a/msgpack/sysdep.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * MessagePack system dependencies - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_SYSDEP_H__ -#define MSGPACK_SYSDEP_H__ - -#include -#include -#if defined(_MSC_VER) && _MSC_VER < 1600 -typedef __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#elif defined(_MSC_VER) // && _MSC_VER >= 1600 -#include -#else -#include -#include -#endif - -#ifdef _WIN32 -#define _msgpack_atomic_counter_header -typedef long _msgpack_atomic_counter_t; -#define _msgpack_sync_decr_and_fetch(ptr) InterlockedDecrement(ptr) -#define _msgpack_sync_incr_and_fetch(ptr) InterlockedIncrement(ptr) -#elif defined(__GNUC__) && ((__GNUC__*10 + __GNUC_MINOR__) < 41) -#define _msgpack_atomic_counter_header "gcc_atomic.h" -#else -typedef unsigned int _msgpack_atomic_counter_t; -#define _msgpack_sync_decr_and_fetch(ptr) __sync_sub_and_fetch(ptr, 1) -#define _msgpack_sync_incr_and_fetch(ptr) __sync_add_and_fetch(ptr, 1) -#endif - -#ifdef _WIN32 - -#ifdef __cplusplus -/* numeric_limits::min,max */ -#ifdef max -#undef max -#endif -#ifdef min -#undef min -#endif -#endif - -#else -#include /* __BYTE_ORDER */ -#endif - -#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define __LITTLE_ENDIAN__ -#elif __BYTE_ORDER == __BIG_ENDIAN -#define __BIG_ENDIAN__ -#elif _WIN32 -#define __LITTLE_ENDIAN__ -#endif -#endif - - -#ifdef __LITTLE_ENDIAN__ - -#ifdef _WIN32 -# if defined(ntohs) -# define _msgpack_be16(x) ntohs(x) -# elif defined(_byteswap_ushort) || (defined(_MSC_VER) && _MSC_VER >= 1400) -# define _msgpack_be16(x) ((uint16_t)_byteswap_ushort((unsigned short)x)) -# else -# define _msgpack_be16(x) ( \ - ((((uint16_t)x) << 8) ) | \ - ((((uint16_t)x) >> 8) ) ) -# endif -#else -# define _msgpack_be16(x) ntohs(x) -#endif - -#ifdef _WIN32 -# if defined(ntohl) -# define _msgpack_be32(x) ntohl(x) -# elif defined(_byteswap_ulong) || (defined(_MSC_VER) && _MSC_VER >= 1400) -# define _msgpack_be32(x) ((uint32_t)_byteswap_ulong((unsigned long)x)) -# else -# define _msgpack_be32(x) \ - ( ((((uint32_t)x) << 24) ) | \ - ((((uint32_t)x) << 8) & 0x00ff0000U ) | \ - ((((uint32_t)x) >> 8) & 0x0000ff00U ) | \ - ((((uint32_t)x) >> 24) ) ) -# endif -#else -# define _msgpack_be32(x) ntohl(x) -#endif - -#if defined(_byteswap_uint64) || (defined(_MSC_VER) && _MSC_VER >= 1400) -# define _msgpack_be64(x) (_byteswap_uint64(x)) -#elif defined(bswap_64) -# define _msgpack_be64(x) bswap_64(x) -#elif defined(__DARWIN_OSSwapInt64) -# define _msgpack_be64(x) __DARWIN_OSSwapInt64(x) -#else -#define _msgpack_be64(x) \ - ( ((((uint64_t)x) << 56) ) | \ - ((((uint64_t)x) << 40) & 0x00ff000000000000ULL ) | \ - ((((uint64_t)x) << 24) & 0x0000ff0000000000ULL ) | \ - ((((uint64_t)x) << 8) & 0x000000ff00000000ULL ) | \ - ((((uint64_t)x) >> 8) & 0x00000000ff000000ULL ) | \ - ((((uint64_t)x) >> 24) & 0x0000000000ff0000ULL ) | \ - ((((uint64_t)x) >> 40) & 0x000000000000ff00ULL ) | \ - ((((uint64_t)x) >> 56) ) ) -#endif - -#define _msgpack_load16(cast, from) ((cast)( \ - (((uint16_t)((uint8_t*)(from))[0]) << 8) | \ - (((uint16_t)((uint8_t*)(from))[1]) ) )) - -#define _msgpack_load32(cast, from) ((cast)( \ - (((uint32_t)((uint8_t*)(from))[0]) << 24) | \ - (((uint32_t)((uint8_t*)(from))[1]) << 16) | \ - (((uint32_t)((uint8_t*)(from))[2]) << 8) | \ - (((uint32_t)((uint8_t*)(from))[3]) ) )) - -#define _msgpack_load64(cast, from) ((cast)( \ - (((uint64_t)((uint8_t*)(from))[0]) << 56) | \ - (((uint64_t)((uint8_t*)(from))[1]) << 48) | \ - (((uint64_t)((uint8_t*)(from))[2]) << 40) | \ - (((uint64_t)((uint8_t*)(from))[3]) << 32) | \ - (((uint64_t)((uint8_t*)(from))[4]) << 24) | \ - (((uint64_t)((uint8_t*)(from))[5]) << 16) | \ - (((uint64_t)((uint8_t*)(from))[6]) << 8) | \ - (((uint64_t)((uint8_t*)(from))[7]) ) )) - -#else - -#define _msgpack_be16(x) (x) -#define _msgpack_be32(x) (x) -#define _msgpack_be64(x) (x) - -#define _msgpack_load16(cast, from) ((cast)( \ - (((uint16_t)((uint8_t*)from)[0]) << 8) | \ - (((uint16_t)((uint8_t*)from)[1]) ) )) - -#define _msgpack_load32(cast, from) ((cast)( \ - (((uint32_t)((uint8_t*)from)[0]) << 24) | \ - (((uint32_t)((uint8_t*)from)[1]) << 16) | \ - (((uint32_t)((uint8_t*)from)[2]) << 8) | \ - (((uint32_t)((uint8_t*)from)[3]) ) )) - -#define _msgpack_load64(cast, from) ((cast)( \ - (((uint64_t)((uint8_t*)from)[0]) << 56) | \ - (((uint64_t)((uint8_t*)from)[1]) << 48) | \ - (((uint64_t)((uint8_t*)from)[2]) << 40) | \ - (((uint64_t)((uint8_t*)from)[3]) << 32) | \ - (((uint64_t)((uint8_t*)from)[4]) << 24) | \ - (((uint64_t)((uint8_t*)from)[5]) << 16) | \ - (((uint64_t)((uint8_t*)from)[6]) << 8) | \ - (((uint64_t)((uint8_t*)from)[7]) ) )) -#endif - - -#define _msgpack_store16(to, num) \ - do { uint16_t val = _msgpack_be16(num); memcpy(to, &val, 2); } while(0) -#define _msgpack_store32(to, num) \ - do { uint32_t val = _msgpack_be32(num); memcpy(to, &val, 4); } while(0) -#define _msgpack_store64(to, num) \ - do { uint64_t val = _msgpack_be64(num); memcpy(to, &val, 8); } while(0) - -/* -#define _msgpack_load16(cast, from) \ - ({ cast val; memcpy(&val, (char*)from, 2); _msgpack_be16(val); }) -#define _msgpack_load32(cast, from) \ - ({ cast val; memcpy(&val, (char*)from, 4); _msgpack_be32(val); }) -#define _msgpack_load64(cast, from) \ - ({ cast val; memcpy(&val, (char*)from, 8); _msgpack_be64(val); }) -*/ - - -#endif /* msgpack/sysdep.h */ - diff --git a/msgpack/test/Makefile.am b/msgpack/test/Makefile.am deleted file mode 100644 index af56d3be..00000000 --- a/msgpack/test/Makefile.am +++ /dev/null @@ -1,54 +0,0 @@ - -AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src -AM_C_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src -AM_LDFLAGS = $(top_builddir)/src/libmsgpack.la -lgtest_main -pthread - -check_PROGRAMS = \ - zone \ - pack_unpack \ - pack_unpack_c \ - streaming \ - streaming_c \ - object \ - convert \ - buffer \ - cases \ - fixint \ - fixint_c \ - version \ - msgpackc_test \ - msgpack_test - -TESTS = $(check_PROGRAMS) - -zone_SOURCES = zone.cc - -pack_unpack_SOURCES = pack_unpack.cc - -pack_unpack_c_SOURCES = pack_unpack_c.cc - -streaming_SOURCES = streaming.cc - -streaming_c_SOURCES = streaming_c.cc - -object_SOURCES = object.cc - -convert_SOURCES = convert.cc - -buffer_SOURCES = buffer.cc -buffer_LDADD = -lz - -cases_SOURCES = cases.cc - -fixint_SOURCES = fixint.cc - -fixint_c_SOURCES = fixint_c.cc - -version_SOURCES = version.cc - -msgpackc_test_SOURCES = msgpackc_test.cpp - -msgpack_test_SOURCES = msgpack_test.cpp - -EXTRA_DIST = cases.mpac cases_compact.mpac - diff --git a/msgpack/test/buffer.cc b/msgpack/test/buffer.cc deleted file mode 100644 index 0b66f4e2..00000000 --- a/msgpack/test/buffer.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include - -TEST(buffer, sbuffer) -{ - msgpack::sbuffer sbuf; - sbuf.write("a", 1); - sbuf.write("a", 1); - sbuf.write("a", 1); - - EXPECT_EQ(3, sbuf.size()); - EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); - - sbuf.clear(); - sbuf.write("a", 1); - sbuf.write("a", 1); - sbuf.write("a", 1); - - EXPECT_EQ(3, sbuf.size()); - EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); -} - - -TEST(buffer, vrefbuffer) -{ - msgpack::vrefbuffer vbuf; - vbuf.write("a", 1); - vbuf.write("a", 1); - vbuf.write("a", 1); - - const struct iovec* vec = vbuf.vector(); - size_t veclen = vbuf.vector_size(); - - msgpack::sbuffer sbuf; - for(size_t i=0; i < veclen; ++i) { - sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); - } - - EXPECT_EQ(3, sbuf.size()); - EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); - - - vbuf.clear(); - vbuf.write("a", 1); - vbuf.write("a", 1); - vbuf.write("a", 1); - - vec = vbuf.vector(); - veclen = vbuf.vector_size(); - - sbuf.clear(); - for(size_t i=0; i < veclen; ++i) { - sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); - } - - EXPECT_EQ(3, sbuf.size()); - EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); -} - - -TEST(buffer, zbuffer) -{ - msgpack::zbuffer zbuf; - zbuf.write("a", 1); - zbuf.write("a", 1); - zbuf.write("a", 1); - - zbuf.flush(); -} - diff --git a/msgpack/test/cases.cc b/msgpack/test/cases.cc deleted file mode 100644 index eb1286c7..00000000 --- a/msgpack/test/cases.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -static void feed_file(msgpack::unpacker& pac, const char* path) -{ - std::ifstream fin(path); - while(true) { - pac.reserve_buffer(32*1024); - fin.read(pac.buffer(), pac.buffer_capacity()); - if(fin.bad()) { - throw std::runtime_error("read failed"); - } - pac.buffer_consumed(fin.gcount()); - if(fin.fail()) { - break; - } - } -} - -TEST(cases, format) -{ - msgpack::unpacker pac; - msgpack::unpacker pac_compact; - - feed_file(pac, "cases.mpac"); - feed_file(pac_compact, "cases_compact.mpac"); - - msgpack::unpacked result; - while(pac.next(&result)) { - msgpack::unpacked result_compact; - EXPECT_TRUE( pac_compact.next(&result_compact) ); - EXPECT_EQ(result_compact.get(), result.get()); - } - - EXPECT_FALSE( pac_compact.next(&result) ); -} - diff --git a/msgpack/test/convert.cc b/msgpack/test/convert.cc deleted file mode 100644 index f579f33a..00000000 --- a/msgpack/test/convert.cc +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -class compatibility { -public: - compatibility() : str1("default"), str2("default") { } - - std::string str1; - std::string str2; - - MSGPACK_DEFINE(str1, str2); -}; - -TEST(convert, compatibility_less) -{ - std::vector src(1); - src[0] = "kumofs"; - - msgpack::zone z; - msgpack::object obj(src, &z); - - compatibility c; - EXPECT_NO_THROW( obj.convert(&c) ); - - EXPECT_EQ("kumofs", c.str1); - EXPECT_EQ("default", c.str2); -} - -TEST(convert, compatibility_more) -{ - std::vector src(3); - src[0] = "kumofs"; - src[1] = "mpio"; - src[2] = "cloudy"; - - msgpack::zone z; - msgpack::object obj(src, &z); - - compatibility to; - EXPECT_NO_THROW( obj.convert(&to) ); - - EXPECT_EQ("kumofs", to.str1); - EXPECT_EQ("mpio", to.str2); -} - - -class enum_member { -public: - enum_member() : flag(A) { } - - enum flags_t { - A = 0, - B = 1, - }; - - flags_t flag; - - MSGPACK_DEFINE(flag); -}; - -MSGPACK_ADD_ENUM(enum_member::flags_t); - -TEST(convert, enum_member) -{ - enum_member src; - src.flag = enum_member::B; - - msgpack::zone z; - msgpack::object obj(src, &z); - - enum_member to; - EXPECT_NO_THROW( obj.convert(&to) ); - - EXPECT_EQ(enum_member::B, to.flag); -} - diff --git a/msgpack/test/fixint.cc b/msgpack/test/fixint.cc deleted file mode 100644 index 63288a1b..00000000 --- a/msgpack/test/fixint.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -template -void check_size(size_t size) { - T v(0); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, v); - EXPECT_EQ(size, sbuf.size()); -} - -TEST(fixint, size) -{ - check_size(2); - check_size(3); - check_size(5); - check_size(9); - - check_size(2); - check_size(3); - check_size(5); - check_size(9); -} - - -template -void check_convert() { - T v1(-11); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, v1); - - msgpack::unpacked msg; - msgpack::unpack(&msg, sbuf.data(), sbuf.size()); - - T v2; - msg.get().convert(&v2); - - EXPECT_EQ(v1.get(), v2.get()); - - EXPECT_EQ(msg.get(), msgpack::object(T(v1.get()))); -} - -TEST(fixint, convert) -{ - check_convert(); - check_convert(); - check_convert(); - check_convert(); - - check_convert(); - check_convert(); - check_convert(); - check_convert(); -} - diff --git a/msgpack/test/fixint_c.cc b/msgpack/test/fixint_c.cc deleted file mode 100644 index caa4d262..00000000 --- a/msgpack/test/fixint_c.cc +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -TEST(fixint, size) -{ - msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); - msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); - - size_t sum = 0; - - EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0)); - EXPECT_EQ(sum+=2, sbuf->size); - EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0)); - EXPECT_EQ(sum+=3, sbuf->size); - EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0)); - EXPECT_EQ(sum+=5, sbuf->size); - EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0)); - EXPECT_EQ(sum+=9, sbuf->size); - - EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0)); - EXPECT_EQ(sum+=2, sbuf->size); - EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0)); - EXPECT_EQ(sum+=3, sbuf->size); - EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0)); - EXPECT_EQ(sum+=5, sbuf->size); - EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0)); - EXPECT_EQ(sum+=9, sbuf->size); - - msgpack_sbuffer_free(sbuf); - msgpack_packer_free(pk); -} - diff --git a/msgpack/test/msgpack_test.cpp b/msgpack/test/msgpack_test.cpp deleted file mode 100644 index 0dd0ffc6..00000000 --- a/msgpack/test/msgpack_test.cpp +++ /dev/null @@ -1,982 +0,0 @@ -#include "msgpack.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -using namespace std; - -const unsigned int kLoop = 10000; -const unsigned int kElements = 100; -const double kEPS = 1e-10; - -#define GEN_TEST(test_type) \ - do { \ - vector v; \ - v.push_back(0); \ - v.push_back(1); \ - v.push_back(2); \ - v.push_back(numeric_limits::min()); \ - v.push_back(numeric_limits::max()); \ - for (unsigned int i = 0; i < kLoop; i++) \ - v.push_back(rand()); \ - for (unsigned int i = 0; i < v.size() ; i++) { \ - msgpack::sbuffer sbuf; \ - test_type val1 = v[i]; \ - msgpack::pack(sbuf, val1); \ - msgpack::zone z; \ - msgpack::object obj; \ - msgpack::unpack_return ret = \ - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \ - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \ - test_type val2; \ - obj.convert(&val2); \ - EXPECT_EQ(val1, val2); \ - } \ -} while(0) - -TEST(MSGPACK, simple_buffer_short) -{ - GEN_TEST(short); -} - -TEST(MSGPACK, simple_buffer_int) -{ - GEN_TEST(int); -} - -TEST(MSGPACK, simple_buffer_long) -{ - GEN_TEST(long); -} - -TEST(MSGPACK, simple_buffer_long_long) -{ - GEN_TEST(long long); -} - -TEST(MSGPACK, simple_buffer_unsigned_short) -{ - GEN_TEST(unsigned short); -} - -TEST(MSGPACK, simple_buffer_unsigned_int) -{ - GEN_TEST(unsigned int); -} - -TEST(MSGPACK, simple_buffer_unsigned_long) -{ - GEN_TEST(unsigned long); -} - -TEST(MSGPACK, simple_buffer_unsigned_long_long) -{ - GEN_TEST(unsigned long long); -} - -TEST(MSGPACK, simple_buffer_uint8) -{ - GEN_TEST(uint8_t); -} - -TEST(MSGPACK, simple_buffer_uint16) -{ - GEN_TEST(uint16_t); -} - -TEST(MSGPACK, simple_buffer_uint32) -{ - GEN_TEST(uint32_t); -} - -TEST(MSGPACK, simple_buffer_uint64) -{ - GEN_TEST(uint64_t); -} - -TEST(MSGPACK, simple_buffer_int8) -{ - GEN_TEST(int8_t); -} - -TEST(MSGPACK, simple_buffer_int16) -{ - GEN_TEST(int16_t); -} - -TEST(MSGPACK, simple_buffer_int32) -{ - GEN_TEST(int32_t); -} - -TEST(MSGPACK, simple_buffer_int64) -{ - GEN_TEST(int64_t); -} - -TEST(MSGPACK, simple_buffer_float) -{ - vector v; - v.push_back(0.0); - v.push_back(-0.0); - v.push_back(1.0); - v.push_back(-1.0); - v.push_back(numeric_limits::min()); - v.push_back(numeric_limits::max()); - v.push_back(nanf("tag")); - v.push_back(1.0/0.0); // inf - v.push_back(-(1.0/0.0)); // -inf - for (unsigned int i = 0; i < kLoop; i++) { - v.push_back(drand48()); - v.push_back(-drand48()); - } - for (unsigned int i = 0; i < v.size() ; i++) { - msgpack::sbuffer sbuf; - float val1 = v[i]; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - float val2; - obj.convert(&val2); - - if (isnan(val1)) - EXPECT_TRUE(isnan(val2)); - else if (isinf(val1)) - EXPECT_TRUE(isinf(val2)); - else - EXPECT_TRUE(fabs(val2 - val1) <= kEPS); - } -} - -TEST(MSGPACK, simple_buffer_double) -{ - vector v; - v.push_back(0.0); - v.push_back(-0.0); - v.push_back(1.0); - v.push_back(-1.0); - v.push_back(numeric_limits::min()); - v.push_back(numeric_limits::max()); - v.push_back(nanf("tag")); - v.push_back(1.0/0.0); // inf - v.push_back(-(1.0/0.0)); // -inf - for (unsigned int i = 0; i < kLoop; i++) { - v.push_back(drand48()); - v.push_back(-drand48()); - } - for (unsigned int i = 0; i < v.size() ; i++) { - msgpack::sbuffer sbuf; - double val1 = v[i]; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - double val2; - obj.convert(&val2); - - if (isnan(val1)) - EXPECT_TRUE(isnan(val2)); - else if (isinf(val1)) - EXPECT_TRUE(isinf(val2)); - else - EXPECT_TRUE(fabs(val2 - val1) <= kEPS); - } -} - -TEST(MSGPACK, simple_buffer_true) -{ - msgpack::sbuffer sbuf; - bool val1 = true; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - bool val2; - obj.convert(&val2); - EXPECT_EQ(val1, val2); -} - -TEST(MSGPACK, simple_buffer_false) -{ - msgpack::sbuffer sbuf; - bool val1 = false; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - bool val2; - obj.convert(&val2); - EXPECT_EQ(val1, val2); -} - -//----------------------------------------------------------------------------- - -// STL - -TEST(MSGPACK_STL, simple_buffer_string) -{ - for (unsigned int k = 0; k < kLoop; k++) { - string val1; - for (unsigned int i = 0; i < kElements; i++) - val1 += 'a' + rand() % 26; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - string val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(val1, val2); - } -} - -TEST(MSGPACK_STL, simple_buffer_vector) -{ - for (unsigned int k = 0; k < kLoop; k++) { - vector val1; - for (unsigned int i = 0; i < kElements; i++) - val1.push_back(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - vector val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_map) -{ - for (unsigned int k = 0; k < kLoop; k++) { - map val1; - for (unsigned int i = 0; i < kElements; i++) - val1[rand()] = rand(); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - map val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_deque) -{ - for (unsigned int k = 0; k < kLoop; k++) { - deque val1; - for (unsigned int i = 0; i < kElements; i++) - val1.push_back(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - deque val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_list) -{ - for (unsigned int k = 0; k < kLoop; k++) { - list val1; - for (unsigned int i = 0; i < kElements; i++) - val1.push_back(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - list val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_set) -{ - for (unsigned int k = 0; k < kLoop; k++) { - set val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - set val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_pair) -{ - for (unsigned int k = 0; k < kLoop; k++) { - pair val1 = make_pair(rand(), rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - pair val2; - obj.convert(&val2); - EXPECT_EQ(val1.first, val2.first); - EXPECT_EQ(val1.second, val2.second); - } -} - -TEST(MSGPACK_STL, simple_buffer_multimap) -{ - for (unsigned int k = 0; k < kLoop; k++) { - multimap val1; - for (unsigned int i = 0; i < kElements; i++) { - int i1 = rand(); - val1.insert(make_pair(i1, rand())); - val1.insert(make_pair(i1, rand())); - } - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - multimap val2; - obj.convert(&val2); - - vector > v1, v2; - multimap::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(make_pair(it->first, it->second)); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(make_pair(it->first, it->second)); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} - -TEST(MSGPACK_STL, simple_buffer_multiset) -{ - for (unsigned int k = 0; k < kLoop; k++) { - multiset val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - multiset val2; - obj.convert(&val2); - - vector v1, v2; - multiset::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(*it); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(*it); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} - -// TR1 - -#ifdef HAVE_TR1_UNORDERED_MAP -#include -#include "msgpack/type/tr1/unordered_map.hpp" -TEST(MSGPACK_TR1, simple_buffer_unordered_map) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_map val1; - for (unsigned int i = 0; i < kElements; i++) - val1[rand()] = rand(); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_map val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - tr1::unordered_map::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) { - EXPECT_TRUE(val2.find(it->first) != val2.end()); - EXPECT_EQ(it->second, val2.find(it->first)->second); - } - } -} - -TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_multimap val1; - for (unsigned int i = 0; i < kElements; i++) { - int i1 = rand(); - val1.insert(make_pair(i1, rand())); - val1.insert(make_pair(i1, rand())); - } - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_multimap val2; - obj.convert(&val2); - - vector > v1, v2; - tr1::unordered_multimap::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(make_pair(it->first, it->second)); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(make_pair(it->first, it->second)); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} -#endif - -#ifdef HAVE_TR1_UNORDERED_SET -#include -#include "msgpack/type/tr1/unordered_set.hpp" -TEST(MSGPACK_TR1, simple_buffer_unordered_set) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_set val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_set val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - tr1::unordered_set::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - EXPECT_TRUE(val2.find(*it) != val2.end()); - } -} - -TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_multiset val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_multiset val2; - obj.convert(&val2); - - vector v1, v2; - tr1::unordered_multiset::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(*it); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(*it); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} -#endif - -// User-Defined Structures - -class TestClass -{ -public: - TestClass() : i(0), s("kzk") {} - int i; - string s; - MSGPACK_DEFINE(i, s); -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_class) -{ - for (unsigned int k = 0; k < kLoop; k++) { - TestClass val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestClass val2; - val2.i = -1; - val2.s = ""; - obj.convert(&val2); - EXPECT_EQ(val1.i, val2.i); - EXPECT_EQ(val1.s, val2.s); - } -} - -class TestClass2 -{ -public: - TestClass2() : i(0), s("kzk") { - for (unsigned int i = 0; i < kElements; i++) - v.push_back(rand()); - } - int i; - string s; - vector v; - MSGPACK_DEFINE(i, s, v); -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new) -{ - for (unsigned int k = 0; k < kLoop; k++) { - TestClass val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestClass2 val2; - val2.i = -1; - val2.s = ""; - val2.v = vector(); - obj.convert(&val2); - EXPECT_EQ(val1.i, val2.i); - EXPECT_EQ(val1.s, val2.s); - EXPECT_FALSE(val2.s.empty()); - } -} - -TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old) -{ - for (unsigned int k = 0; k < kLoop; k++) { - TestClass2 val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestClass val2; - val2.i = -1; - val2.s = ""; - obj.convert(&val2); - EXPECT_EQ(val1.i, val2.i); - EXPECT_EQ(val1.s, val2.s); - EXPECT_FALSE(val2.s.empty()); - } -} - -class TestEnumMemberClass -{ -public: - TestEnumMemberClass() - : t1(STATE_A), t2(STATE_B), t3(STATE_C) {} - - enum TestEnumType { - STATE_INVALID = 0, - STATE_A = 1, - STATE_B = 2, - STATE_C = 3 - }; - TestEnumType t1; - TestEnumType t2; - TestEnumType t3; - - MSGPACK_DEFINE((int&)t1, (int&)t2, (int&)t3); -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member) -{ - TestEnumMemberClass val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestEnumMemberClass val2; - val2.t1 = TestEnumMemberClass::STATE_INVALID; - val2.t2 = TestEnumMemberClass::STATE_INVALID; - val2.t3 = TestEnumMemberClass::STATE_INVALID; - obj.convert(&val2); - EXPECT_EQ(val1.t1, val2.t1); - EXPECT_EQ(val1.t2, val2.t2); - EXPECT_EQ(val1.t3, val2.t3); -} - -class TestUnionMemberClass -{ -public: - TestUnionMemberClass() {} - TestUnionMemberClass(double f) { - is_double = true; - value.f = f; - } - TestUnionMemberClass(int i) { - is_double = false; - value.i = i; - } - - union { - double f; - int i; - } value; - bool is_double; - - template - void msgpack_pack(Packer& pk) const - { - if (is_double) - pk.pack(msgpack::type::tuple(true, value.f)); - else - pk.pack(msgpack::type::tuple(false, value.i)); - } - - void msgpack_unpack(msgpack::object o) - { - msgpack::type::tuple tuple; - o.convert(&tuple); - - is_double = tuple.get<0>(); - if (is_double) - tuple.get<1>().convert(&value.f); - else - tuple.get<1>().convert(&value.i); - } -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member) -{ - { - // double - TestUnionMemberClass val1(1.0); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestUnionMemberClass val2; - obj.convert(&val2); - EXPECT_EQ(val1.is_double, val2.is_double); - EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS); - } - { - // int - TestUnionMemberClass val1(1); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestUnionMemberClass val2; - obj.convert(&val2); - EXPECT_EQ(val1.is_double, val2.is_double); - EXPECT_EQ(val1.value.i, 1); - EXPECT_EQ(val1.value.i, val2.value.i); - } -} - -//----------------------------------------------------------------------------- - -#define GEN_TEST_VREF(test_type) \ - do { \ - vector v; \ - v.push_back(0); \ - for (unsigned int i = 0; i < v.size(); i++) { \ - test_type val1 = v[i]; \ - msgpack::vrefbuffer vbuf; \ - msgpack::pack(vbuf, val1); \ - msgpack::sbuffer sbuf; \ - const struct iovec* cur = vbuf.vector(); \ - const struct iovec* end = cur + vbuf.vector_size(); \ - for(; cur != end; ++cur) \ - sbuf.write((const char*)cur->iov_base, cur->iov_len); \ - msgpack::zone z; \ - msgpack::object obj; \ - msgpack::unpack_return ret = \ - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \ - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \ - test_type val2; \ - obj.convert(&val2); \ - EXPECT_EQ(val1, val2); \ - } \ - } while(0); - -TEST(MSGPACK, vrefbuffer_short) -{ - GEN_TEST_VREF(short); -} - -TEST(MSGPACK, vrefbuffer_int) -{ - GEN_TEST_VREF(int); -} - -TEST(MSGPACK, vrefbuffer_long) -{ - GEN_TEST_VREF(long); -} - -TEST(MSGPACK, vrefbuffer_long_long) -{ - GEN_TEST_VREF(long long); -} - -TEST(MSGPACK, vrefbuffer_unsigned_short) -{ - GEN_TEST_VREF(unsigned short); -} - -TEST(MSGPACK, vrefbuffer_unsigned_int) -{ - GEN_TEST_VREF(unsigned int); -} - -TEST(MSGPACK, vrefbuffer_unsigned_long) -{ - GEN_TEST_VREF(unsigned long); -} - -TEST(MSGPACK, vrefbuffer_unsigned_long_long) -{ - GEN_TEST_VREF(unsigned long long); -} - -TEST(MSGPACK, vrefbuffer_uint8) -{ - GEN_TEST_VREF(uint8_t); -} - -TEST(MSGPACK, vrefbuffer_uint16) -{ - GEN_TEST_VREF(uint16_t); -} - -TEST(MSGPACK, vrefbuffer_uint32) -{ - GEN_TEST_VREF(uint32_t); -} - -TEST(MSGPACK, vrefbuffer_uint64) -{ - GEN_TEST_VREF(uint64_t); -} - -TEST(MSGPACK, vrefbuffer_int8) -{ - GEN_TEST_VREF(int8_t); -} - -TEST(MSGPACK, vrefbuffer_int16) -{ - GEN_TEST_VREF(int16_t); -} - -TEST(MSGPACK, vrefbuffer_int32) -{ - GEN_TEST_VREF(int32_t); -} - -TEST(MSGPACK, vrefbuffer_int64) -{ - GEN_TEST_VREF(int64_t); -} - -//----------------------------------------------------------------------------- - -#define GEN_TEST_STREAM(test_type) \ - for (unsigned int k = 0; k < kLoop; k++) { \ - msgpack::sbuffer sbuf; \ - msgpack::packer pk(sbuf); \ - typedef std::vector vec_type; \ - vec_type vec; \ - for(unsigned int i = 0; i < rand() % kLoop; ++i) { \ - vec_type::value_type r = rand(); \ - vec.push_back(r); \ - pk.pack(r); \ - } \ - msgpack::unpacker pac; \ - vec_type::const_iterator it = vec.begin(); \ - const char *p = sbuf.data(); \ - const char * const pend = p + sbuf.size(); \ - while (p < pend) { \ - const size_t sz = std::min(pend - p, rand() % 128); \ - pac.reserve_buffer(sz); \ - memcpy(pac.buffer(), p, sz); \ - pac.buffer_consumed(sz); \ - while (pac.execute()) { \ - if (it == vec.end()) goto out; \ - msgpack::object obj = pac.data(); \ - msgpack::zone *life = pac.release_zone(); \ - EXPECT_TRUE(life != NULL); \ - pac.reset(); \ - vec_type::value_type val; \ - obj.convert(&val); \ - EXPECT_EQ(*it, val); \ - ++it; \ - delete life; \ - } \ - p += sz; \ - } \ - out: \ - ; \ - } - -TEST(MSGPACK, stream_short) -{ - GEN_TEST_STREAM(short); -} - -TEST(MSGPACK, stream_int) -{ - GEN_TEST_STREAM(int); -} - -TEST(MSGPACK, stream_long) -{ - GEN_TEST_STREAM(long); -} - -TEST(MSGPACK, stream_long_long) -{ - GEN_TEST_STREAM(long long); -} - -TEST(MSGPACK, stream_unsigned_short) -{ - GEN_TEST_STREAM(unsigned short); -} - -TEST(MSGPACK, stream_unsigned_int) -{ - GEN_TEST_STREAM(unsigned int); -} - -TEST(MSGPACK, stream_unsigned_long) -{ - GEN_TEST_STREAM(unsigned long); -} - -TEST(MSGPACK, stream_unsigned_long_long) -{ - GEN_TEST_STREAM(unsigned long long); -} - -TEST(MSGPACK, stream_uint8) -{ - GEN_TEST_STREAM(uint8_t); -} - -TEST(MSGPACK, stream_uint16) -{ - GEN_TEST_STREAM(uint16_t); -} - -TEST(MSGPACK, stream_uint32) -{ - GEN_TEST_STREAM(uint32_t); -} - -TEST(MSGPACK, stream_uint64) -{ - GEN_TEST_STREAM(uint64_t); -} - -TEST(MSGPACK, stream_int8) -{ - GEN_TEST_STREAM(int8_t); -} - -TEST(MSGPACK, stream_int16) -{ - GEN_TEST_STREAM(int16_t); -} - -TEST(MSGPACK, stream_int32) -{ - GEN_TEST_STREAM(int32_t); -} - -TEST(MSGPACK, stream_int64) -{ - GEN_TEST_STREAM(int64_t); -} diff --git a/msgpack/test/msgpackc_test.cpp b/msgpack/test/msgpackc_test.cpp deleted file mode 100644 index f5646ea7..00000000 --- a/msgpack/test/msgpackc_test.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#include "msgpack.h" - -#include -#include -#include - -#include - -using namespace std; - -const unsigned int kLoop = 10000; -const double kEPS = 1e-10; - -#define GEN_TEST_SIGNED(test_type, func_type) \ - do { \ - vector v; \ - v.push_back(0); \ - v.push_back(1); \ - v.push_back(-1); \ - v.push_back(numeric_limits::min()); \ - v.push_back(numeric_limits::max()); \ - for (unsigned int i = 0; i < kLoop; i++) \ - v.push_back(rand()); \ - for (unsigned int i = 0; i < v.size() ; i++) { \ - test_type val = v[i]; \ - msgpack_sbuffer sbuf; \ - msgpack_sbuffer_init(&sbuf); \ - msgpack_packer pk; \ - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \ - msgpack_pack_##func_type(&pk, val); \ - msgpack_zone z; \ - msgpack_zone_init(&z, 2048); \ - msgpack_object obj; \ - msgpack_unpack_return ret = \ - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \ - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \ - if (val < 0) { \ - EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, obj.type); \ - EXPECT_EQ(val, obj.via.i64); \ - } else { \ - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \ - EXPECT_EQ(val, obj.via.u64); \ - } \ - msgpack_zone_destroy(&z); \ - msgpack_sbuffer_destroy(&sbuf); \ - } \ - } while(0) - -#define GEN_TEST_UNSIGNED(test_type, func_type) \ - do { \ - vector v; \ - v.push_back(0); \ - v.push_back(1); \ - v.push_back(2); \ - v.push_back(numeric_limits::min()); \ - v.push_back(numeric_limits::max()); \ - for (unsigned int i = 0; i < kLoop; i++) \ - v.push_back(rand()); \ - for (unsigned int i = 0; i < v.size() ; i++) { \ - test_type val = v[i]; \ - msgpack_sbuffer sbuf; \ - msgpack_sbuffer_init(&sbuf); \ - msgpack_packer pk; \ - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \ - msgpack_pack_##func_type(&pk, val); \ - msgpack_zone z; \ - msgpack_zone_init(&z, 2048); \ - msgpack_object obj; \ - msgpack_unpack_return ret = \ - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \ - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \ - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \ - EXPECT_EQ(val, obj.via.u64); \ - msgpack_zone_destroy(&z); \ - msgpack_sbuffer_destroy(&sbuf); \ - } \ - } while(0) - -TEST(MSGPACKC, simple_buffer_short) -{ - GEN_TEST_SIGNED(short, short); -} - -TEST(MSGPACKC, simple_buffer_int) -{ - GEN_TEST_SIGNED(int, int); -} - -TEST(MSGPACKC, simple_buffer_long) -{ - GEN_TEST_SIGNED(long, long); -} - -TEST(MSGPACKC, simple_buffer_long_long) -{ - GEN_TEST_SIGNED(long long, long_long); -} - -TEST(MSGPACKC, simple_buffer_unsigned_short) -{ - GEN_TEST_UNSIGNED(unsigned short, unsigned_short); -} - -TEST(MSGPACKC, simple_buffer_unsigned_int) -{ - GEN_TEST_UNSIGNED(unsigned int, unsigned_int); -} - -TEST(MSGPACKC, simple_buffer_unsigned_long) -{ - GEN_TEST_UNSIGNED(unsigned long, unsigned_long); -} - -TEST(MSGPACKC, simple_buffer_unsigned_long_long) -{ - GEN_TEST_UNSIGNED(unsigned long long, unsigned_long_long); -} - -TEST(MSGPACKC, simple_buffer_uint8) -{ - GEN_TEST_UNSIGNED(uint8_t, uint8); -} - -TEST(MSGPACKC, simple_buffer_uint16) -{ - GEN_TEST_UNSIGNED(uint16_t, uint16); -} - -TEST(MSGPACKC, simple_buffer_uint32) -{ - GEN_TEST_UNSIGNED(uint32_t, uint32); -} - -TEST(MSGPACKC, simple_buffer_uint64) -{ - GEN_TEST_UNSIGNED(uint64_t, uint64); -} - -TEST(MSGPACKC, simple_buffer_int8) -{ - GEN_TEST_SIGNED(int8_t, int8); -} - -TEST(MSGPACKC, simple_buffer_int16) -{ - GEN_TEST_SIGNED(int16_t, int16); -} - -TEST(MSGPACKC, simple_buffer_int32) -{ - GEN_TEST_SIGNED(int32_t, int32); -} - -TEST(MSGPACKC, simple_buffer_int64) -{ - GEN_TEST_SIGNED(int64_t, int64); -} - -TEST(MSGPACKC, simple_buffer_float) -{ - vector v; - v.push_back(0.0); - v.push_back(1.0); - v.push_back(-1.0); - v.push_back(numeric_limits::min()); - v.push_back(numeric_limits::max()); - v.push_back(nanf("tag")); - v.push_back(1.0/0.0); // inf - v.push_back(-(1.0/0.0)); // -inf - for (unsigned int i = 0; i < kLoop; i++) { - v.push_back(drand48()); - v.push_back(-drand48()); - } - - for (unsigned int i = 0; i < v.size() ; i++) { - float val = v[i]; - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_float(&pk, val); - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret = - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type); - if (isnan(val)) - EXPECT_TRUE(isnan(obj.via.dec)); - else if (isinf(val)) - EXPECT_TRUE(isinf(obj.via.dec)); - else - EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS); - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); - } -} - -TEST(MSGPACKC, simple_buffer_double) -{ - vector v; - v.push_back(0.0); - v.push_back(-0.0); - v.push_back(1.0); - v.push_back(-1.0); - v.push_back(numeric_limits::min()); - v.push_back(numeric_limits::max()); - v.push_back(nan("tag")); - v.push_back(1.0/0.0); // inf - v.push_back(-(1.0/0.0)); // -inf - for (unsigned int i = 0; i < kLoop; i++) { - v.push_back(drand48()); - v.push_back(-drand48()); - } - - for (unsigned int i = 0; i < v.size() ; i++) { - double val = v[i]; - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_double(&pk, val); - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret = - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type); - if (isnan(val)) - EXPECT_TRUE(isnan(obj.via.dec)); - else if (isinf(val)) - EXPECT_TRUE(isinf(obj.via.dec)); - else - EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS); - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); - } -} - -TEST(MSGPACKC, simple_buffer_nil) -{ - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_nil(&pk); - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret = - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_NIL, obj.type); - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); -} - -TEST(MSGPACKC, simple_buffer_true) -{ - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_true(&pk); - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret = - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type); - EXPECT_EQ(true, obj.via.boolean); - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); -} - -TEST(MSGPACKC, simple_buffer_false) -{ - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_false(&pk); - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret = - msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type); - EXPECT_EQ(false, obj.via.boolean); - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); -} - -TEST(MSGPACKC, simple_buffer_array) -{ - unsigned int array_size = 5; - - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_array(&pk, array_size); - msgpack_pack_nil(&pk); - msgpack_pack_true(&pk); - msgpack_pack_false(&pk); - msgpack_pack_int(&pk, 10); - msgpack_pack_int(&pk, -10); - - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret; - ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type); - EXPECT_EQ(array_size, obj.via.array.size); - - for (unsigned int i = 0; i < obj.via.array.size; i++) { - msgpack_object o = obj.via.array.ptr[i]; - switch (i) { - case 0: - EXPECT_EQ(MSGPACK_OBJECT_NIL, o.type); - break; - case 1: - EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type); - EXPECT_EQ(true, o.via.boolean); - break; - case 2: - EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type); - EXPECT_EQ(false, o.via.boolean); - break; - case 3: - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, o.type); - EXPECT_EQ(10, o.via.u64); - break; - case 4: - EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, o.type); - EXPECT_EQ(-10, o.via.i64); - break; - } - } - - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); -} - -TEST(MSGPACKC, simple_buffer_map) -{ - unsigned int map_size = 2; - - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_map(&pk, map_size); - msgpack_pack_true(&pk); - msgpack_pack_false(&pk); - msgpack_pack_int(&pk, 10); - msgpack_pack_int(&pk, -10); - - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret; - ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type); - EXPECT_EQ(map_size, obj.via.map.size); - - for (unsigned int i = 0; i < map_size; i++) { - msgpack_object key = obj.via.map.ptr[i].key; - msgpack_object val = obj.via.map.ptr[i].val; - switch (i) { - case 0: - EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, key.type); - EXPECT_EQ(true, key.via.boolean); - EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, val.type); - EXPECT_EQ(false, val.via.boolean); - break; - case 1: - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, key.type); - EXPECT_EQ(10, key.via.u64); - EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, val.type); - EXPECT_EQ(-10, val.via.i64); - break; - } - } - - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); -} - -TEST(MSGPACKC, simple_buffer_raw) -{ - unsigned int raw_size = 7; - - msgpack_sbuffer sbuf; - msgpack_sbuffer_init(&sbuf); - msgpack_packer pk; - msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); - msgpack_pack_raw(&pk, raw_size); - msgpack_pack_raw_body(&pk, "fr", 2); - msgpack_pack_raw_body(&pk, "syuki", 5); - // invalid data - msgpack_pack_raw_body(&pk, "", 0); - msgpack_pack_raw_body(&pk, "kzk", 0); - - msgpack_zone z; - msgpack_zone_init(&z, 2048); - msgpack_object obj; - msgpack_unpack_return ret; - ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); - EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); - EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type); - EXPECT_EQ(raw_size, obj.via.raw.size); - EXPECT_EQ(0, memcmp("frsyuki", obj.via.raw.ptr, raw_size)); - - msgpack_zone_destroy(&z); - msgpack_sbuffer_destroy(&sbuf); -} diff --git a/msgpack/test/object.cc b/msgpack/test/object.cc deleted file mode 100644 index 5390c4ae..00000000 --- a/msgpack/test/object.cc +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include - -struct myclass { - myclass() : num(0), str("default") { } - - myclass(int num, const std::string& str) : - num(0), str("default") { } - - ~myclass() { } - - int num; - std::string str; - - MSGPACK_DEFINE(num, str); - - bool operator==(const myclass& o) const - { - return num == o.num && str == o.str; - } -}; - -std::ostream& operator<<(std::ostream& o, const myclass& m) -{ - return o << "myclass("<()); -} - - -TEST(object, print) -{ - msgpack::object obj; - std::cout << obj << std::endl; -} - - -TEST(object, is_nil) -{ - msgpack::object obj; - EXPECT_TRUE(obj.is_nil()); -} - - -TEST(object, type_error) -{ - msgpack::object obj(1); - EXPECT_THROW(obj.as(), msgpack::type_error); - EXPECT_THROW(obj.as >(), msgpack::type_error); - EXPECT_EQ(1, obj.as()); - EXPECT_EQ(1, obj.as()); - EXPECT_EQ(1u, obj.as()); - EXPECT_EQ(1u, obj.as()); -} - - -TEST(object, equal_primitive) -{ - msgpack::object obj_nil; - EXPECT_EQ(obj_nil, msgpack::object()); - - msgpack::object obj_int(1); - EXPECT_EQ(obj_int, msgpack::object(1)); - EXPECT_EQ(obj_int, 1); - - msgpack::object obj_double(1.2); - EXPECT_EQ(obj_double, msgpack::object(1.2)); - EXPECT_EQ(obj_double, 1.2); - - msgpack::object obj_bool(true); - EXPECT_EQ(obj_bool, msgpack::object(true)); - EXPECT_EQ(obj_bool, true); -} - - -TEST(object, construct_primitive) -{ - msgpack::object obj_nil; - EXPECT_EQ(msgpack::type::NIL, obj_nil.type); - - msgpack::object obj_uint(1); - EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type); - EXPECT_EQ(1u, obj_uint.via.u64); - - msgpack::object obj_int(-1); - EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type); - EXPECT_EQ(-1, obj_int.via.i64); - - msgpack::object obj_double(1.2); - EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type); - EXPECT_EQ(1.2, obj_double.via.dec); - - msgpack::object obj_bool(true); - EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type); - EXPECT_EQ(true, obj_bool.via.boolean); -} - diff --git a/msgpack/test/pack_unpack.cc b/msgpack/test/pack_unpack.cc deleted file mode 100644 index fe4625a5..00000000 --- a/msgpack/test/pack_unpack.cc +++ /dev/null @@ -1,123 +0,0 @@ -#include -#include -#include - -TEST(pack, num) -{ - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, 1); -} - - -TEST(pack, vector) -{ - msgpack::sbuffer sbuf; - std::vector vec; - vec.push_back(1); - vec.push_back(2); - vec.push_back(3); - msgpack::pack(sbuf, vec); -} - - -TEST(pack, to_ostream) -{ - std::ostringstream stream; - msgpack::pack(stream, 1); -} - - -struct myclass { - myclass() : num(0), str("default") { } - - myclass(int num, const std::string& str) : - num(0), str("default") { } - - ~myclass() { } - - int num; - std::string str; - - MSGPACK_DEFINE(num, str); -}; - - -TEST(pack, myclass) -{ - msgpack::sbuffer sbuf; - myclass m(1, "msgpack"); - msgpack::pack(sbuf, m); -} - - -TEST(unpack, myclass) -{ - msgpack::sbuffer sbuf; - myclass m1(1, "phraser"); - msgpack::pack(sbuf, m1); - - msgpack::zone z; - msgpack::object obj; - - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - - EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); - - myclass m2 = obj.as(); - EXPECT_EQ(m1.num, m2.num); - EXPECT_EQ(m1.str, m2.str); -} - - -TEST(unpack, sequence) -{ - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, 1); - msgpack::pack(sbuf, 2); - msgpack::pack(sbuf, 3); - - size_t offset = 0; - - msgpack::unpacked msg; - - msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); - EXPECT_EQ(1, msg.get().as()); - - msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); - EXPECT_EQ(2, msg.get().as()); - - msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset); - EXPECT_EQ(3, msg.get().as()); -} - - -TEST(unpack, sequence_compat) -{ - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, 1); - msgpack::pack(sbuf, 2); - msgpack::pack(sbuf, 3); - - size_t offset = 0; - - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret; - - ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); - EXPECT_TRUE(ret >= 0); - EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); - EXPECT_EQ(1, obj.as()); - - ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); - EXPECT_TRUE(ret >= 0); - EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); - EXPECT_EQ(2, obj.as()); - - ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); - EXPECT_TRUE(ret >= 0); - EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); - EXPECT_EQ(3, obj.as()); -} - diff --git a/msgpack/test/pack_unpack_c.cc b/msgpack/test/pack_unpack_c.cc deleted file mode 100644 index e9a03892..00000000 --- a/msgpack/test/pack_unpack_c.cc +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -TEST(pack, num) -{ - msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); - msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); - - EXPECT_EQ(0, msgpack_pack_int(pk, 1)); - - msgpack_sbuffer_free(sbuf); - msgpack_packer_free(pk); -} - - -TEST(pack, array) -{ - msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); - msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); - - EXPECT_EQ(0, msgpack_pack_array(pk, 3)); - EXPECT_EQ(0, msgpack_pack_int(pk, 1)); - EXPECT_EQ(0, msgpack_pack_int(pk, 2)); - EXPECT_EQ(0, msgpack_pack_int(pk, 3)); - - msgpack_sbuffer_free(sbuf); - msgpack_packer_free(pk); -} - - -TEST(unpack, sequence) -{ - msgpack_sbuffer* sbuf = msgpack_sbuffer_new(); - msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write); - - EXPECT_EQ(0, msgpack_pack_int(pk, 1)); - EXPECT_EQ(0, msgpack_pack_int(pk, 2)); - EXPECT_EQ(0, msgpack_pack_int(pk, 3)); - - msgpack_packer_free(pk); - - bool success; - size_t offset = 0; - - msgpack_unpacked msg; - msgpack_unpacked_init(&msg); - - success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); - EXPECT_TRUE(success); - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); - EXPECT_EQ(1, msg.data.via.u64); - - success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); - EXPECT_TRUE(success); - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); - EXPECT_EQ(2, msg.data.via.u64); - - success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); - EXPECT_TRUE(success); - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type); - EXPECT_EQ(3, msg.data.via.u64); - - success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset); - EXPECT_FALSE(success); - - msgpack_sbuffer_free(sbuf); - msgpack_unpacked_destroy(&msg); -} - diff --git a/msgpack/test/streaming.cc b/msgpack/test/streaming.cc deleted file mode 100644 index e80c671b..00000000 --- a/msgpack/test/streaming.cc +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include - -TEST(streaming, basic) -{ - msgpack::sbuffer buffer; - - msgpack::packer pk(&buffer); - pk.pack(1); - pk.pack(2); - pk.pack(3); - - const char* input = buffer.data(); - const char* const eof = input + buffer.size(); - - msgpack::unpacker pac; - msgpack::unpacked result; - - int count = 0; - while(count < 3) { - pac.reserve_buffer(32*1024); - - // read buffer into pac.buffer() upto - // pac.buffer_capacity() bytes. - size_t len = 1; - memcpy(pac.buffer(), input, len); - input += len; - - pac.buffer_consumed(len); - - while(pac.next(&result)) { - msgpack::object obj = result.get(); - switch(count++) { - case 0: - EXPECT_EQ(1, obj.as()); - break; - case 1: - EXPECT_EQ(2, obj.as()); - break; - case 2: - EXPECT_EQ(3, obj.as()); - return; - } - } - - EXPECT_TRUE(input < eof); - } -} - - -class event_handler { -public: - event_handler(std::istream& input) : input(input) { } - ~event_handler() { } - - void on_read() - { - while(true) { - pac.reserve_buffer(32*1024); - - size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); - - if(len == 0) { - return; - } - - pac.buffer_consumed(len); - - msgpack::unpacked result; - while(pac.next(&result)) { - on_message(result.get(), result.zone()); - } - - if(pac.message_size() > 10*1024*1024) { - throw std::runtime_error("message is too large"); - } - } - } - - void on_message(msgpack::object obj, std::auto_ptr z) - { - EXPECT_EQ(expect, obj.as()); - } - - int expect; - -private: - std::istream& input; - msgpack::unpacker pac; -}; - -TEST(streaming, event) -{ - std::stringstream stream; - msgpack::packer pk(&stream); - - event_handler handler(stream); - - pk.pack(1); - handler.expect = 1; - handler.on_read(); - - pk.pack(2); - handler.expect = 2; - handler.on_read(); - - pk.pack(3); - handler.expect = 3; - handler.on_read(); -} - - -// backward compatibility -TEST(streaming, basic_compat) -{ - std::ostringstream stream; - msgpack::packer pk(&stream); - - pk.pack(1); - pk.pack(2); - pk.pack(3); - - std::istringstream input(stream.str()); - - msgpack::unpacker pac; - - int count = 0; - while(count < 3) { - pac.reserve_buffer(32*1024); - - size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); - pac.buffer_consumed(len); - - while(pac.execute()) { - std::auto_ptr z(pac.release_zone()); - msgpack::object obj = pac.data(); - pac.reset(); - - switch(count++) { - case 0: - EXPECT_EQ(1, obj.as()); - break; - case 1: - EXPECT_EQ(2, obj.as()); - break; - case 2: - EXPECT_EQ(3, obj.as()); - return; - } - - } - } -} - - -// backward compatibility -class event_handler_compat { -public: - event_handler_compat(std::istream& input) : input(input) { } - ~event_handler_compat() { } - - void on_read() - { - while(true) { - pac.reserve_buffer(32*1024); - - size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); - - if(len == 0) { - return; - } - - pac.buffer_consumed(len); - - while(pac.execute()) { - std::auto_ptr z(pac.release_zone()); - msgpack::object obj = pac.data(); - pac.reset(); - on_message(obj, z); - } - - if(pac.message_size() > 10*1024*1024) { - throw std::runtime_error("message is too large"); - } - } - } - - void on_message(msgpack::object obj, std::auto_ptr z) - { - EXPECT_EQ(expect, obj.as()); - } - - int expect; - -private: - std::istream& input; - msgpack::unpacker pac; -}; - -TEST(streaming, event_compat) -{ - std::stringstream stream; - msgpack::packer pk(&stream); - - event_handler_compat handler(stream); - - pk.pack(1); - handler.expect = 1; - handler.on_read(); - - pk.pack(2); - handler.expect = 2; - handler.on_read(); - - pk.pack(3); - handler.expect = 3; - handler.on_read(); -} - diff --git a/msgpack/test/streaming_c.cc b/msgpack/test/streaming_c.cc deleted file mode 100644 index 1b7ad8b6..00000000 --- a/msgpack/test/streaming_c.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include - -TEST(streaming, basic) -{ - msgpack_sbuffer* buffer = msgpack_sbuffer_new(); - - msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write); - - // 1, 2, 3, "raw", ["data"], {0.3: 0.4} - EXPECT_EQ(0, msgpack_pack_int(pk, 1)); - EXPECT_EQ(0, msgpack_pack_int(pk, 2)); - EXPECT_EQ(0, msgpack_pack_int(pk, 3)); - EXPECT_EQ(0, msgpack_pack_raw(pk, 3)); - EXPECT_EQ(0, msgpack_pack_raw_body(pk, "raw", 3)); - EXPECT_EQ(0, msgpack_pack_array(pk, 1)); - EXPECT_EQ(0, msgpack_pack_raw(pk, 4)); - EXPECT_EQ(0, msgpack_pack_raw_body(pk, "data", 4)); - EXPECT_EQ(0, msgpack_pack_map(pk, 1)); - EXPECT_EQ(0, msgpack_pack_float(pk, 0.4)); - EXPECT_EQ(0, msgpack_pack_double(pk, 0.8)); - int max_count = 6; - - msgpack_packer_free(pk); - - const char* input = buffer->data; - const char* const eof = input + buffer->size; - - msgpack_unpacker pac; - msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE); - - msgpack_unpacked result; - msgpack_unpacked_init(&result); - - int count = 0; - while(count < max_count) { - bool unpacked = false; - - msgpack_unpacker_reserve_buffer(&pac, 32*1024); - - while(!unpacked) { - /* read buffer into msgpack_unapcker_buffer(&pac) upto - * msgpack_unpacker_buffer_capacity(&pac) bytes. */ - memcpy(msgpack_unpacker_buffer(&pac), input, 1); - input += 1; - - EXPECT_TRUE(input <= eof); - - msgpack_unpacker_buffer_consumed(&pac, 1); - - while(msgpack_unpacker_next(&pac, &result)) { - unpacked = 1; - msgpack_object obj = result.data; - msgpack_object e; - switch(count++) { - case 0: - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); - EXPECT_EQ(1, obj.via.u64); - break; - case 1: - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); - EXPECT_EQ(2, obj.via.u64); - break; - case 2: - EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); - EXPECT_EQ(3, obj.via.u64); - break; - case 3: - EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type); - EXPECT_EQ(std::string("raw",3), std::string(obj.via.raw.ptr, obj.via.raw.size)); - break; - case 4: - EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type); - EXPECT_EQ(1, obj.via.array.size); - e = obj.via.array.ptr[0]; - EXPECT_EQ(MSGPACK_OBJECT_RAW, e.type); - EXPECT_EQ(std::string("data",4), std::string(e.via.raw.ptr, e.via.raw.size)); - break; - case 5: - EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type); - EXPECT_EQ(1, obj.via.map.size); - e = obj.via.map.ptr[0].key; - EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type); - ASSERT_FLOAT_EQ(0.4, (float)e.via.dec); - e = obj.via.map.ptr[0].val; - EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type); - ASSERT_DOUBLE_EQ(0.8, e.via.dec); - break; - } - } - } - } - - msgpack_unpacker_destroy(&pac); - msgpack_unpacked_destroy(&result); -} - diff --git a/msgpack/test/version.cc b/msgpack/test/version.cc deleted file mode 100644 index 9357271e..00000000 --- a/msgpack/test/version.cc +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include - -TEST(version, print) -{ - printf("MSGPACK_VERSION : %s\n", MSGPACK_VERSION); - printf("MSGPACK_VERSION_MAJOR : %d\n", MSGPACK_VERSION_MAJOR); - printf("MSGPACK_VERSION_MINOR : %d\n", MSGPACK_VERSION_MINOR); - printf("msgpack_version() : %s\n", msgpack_version()); - printf("msgpack_version_major() : %d\n", msgpack_version_major()); - printf("msgpack_version_minor() : %d\n", msgpack_version_minor()); -} - diff --git a/msgpack/test/zone.cc b/msgpack/test/zone.cc deleted file mode 100644 index 5274e9f0..00000000 --- a/msgpack/test/zone.cc +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -TEST(zone, malloc) -{ - msgpack::zone z; - char* buf1 = (char*)z.malloc(4); - memcpy(buf1, "test", 4); - char* buf2 = (char*)z.malloc(4); - memcpy(buf2, "test", 4); -} - - -class myclass { -public: - myclass() : num(0), str("default") { } - - myclass(int num, const std::string& str) : - num(num), str(str) { } - - ~myclass() { } - - int num; - std::string str; - -private: - myclass(const myclass&); -}; - - -TEST(zone, allocate) -{ - msgpack::zone z; - myclass* m = z.allocate(); - EXPECT_EQ(m->num, 0); - EXPECT_EQ(m->str, "default"); -} - - -TEST(zone, allocate_constructor) -{ - msgpack::zone z; - myclass* m = z.allocate(7, "msgpack"); - EXPECT_EQ(m->num, 7); - EXPECT_EQ(m->str, "msgpack"); -} - - -static void custom_finalizer_func(void* user) -{ - myclass* m = (myclass*)user; - delete m; -} - -TEST(zone, push_finalizer) -{ - msgpack::zone z; - myclass* m = new myclass(); - z.push_finalizer(custom_finalizer_func, (void*)m); -} - - -TEST(zone, push_finalizer_auto_ptr) -{ - msgpack::zone z; - std::auto_ptr am(new myclass()); - z.push_finalizer(am); -} - - -TEST(zone, malloc_no_align) -{ - msgpack::zone z; - char* buf1 = (char*)z.malloc_no_align(4); - char* buf2 = (char*)z.malloc_no_align(4); - EXPECT_EQ(buf1+4, buf2); -} - diff --git a/msgpack/unpack_define.h b/msgpack/unpack_define.h deleted file mode 100644 index 959d3519..00000000 --- a/msgpack/unpack_define.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * MessagePack unpacking routine template - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MSGPACK_UNPACK_DEFINE_H__ -#define MSGPACK_UNPACK_DEFINE_H__ - -#include "msgpack/sysdep.h" -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef MSGPACK_EMBED_STACK_SIZE -#define MSGPACK_EMBED_STACK_SIZE 32 -#endif - - -typedef enum { - CS_HEADER = 0x00, // nil - - //CS_ = 0x01, - //CS_ = 0x02, // false - //CS_ = 0x03, // true - - //CS_ = 0x04, - //CS_ = 0x05, - //CS_ = 0x06, - //CS_ = 0x07, - - //CS_ = 0x08, - //CS_ = 0x09, - CS_FLOAT = 0x0a, - CS_DOUBLE = 0x0b, - CS_UINT_8 = 0x0c, - CS_UINT_16 = 0x0d, - CS_UINT_32 = 0x0e, - CS_UINT_64 = 0x0f, - CS_INT_8 = 0x10, - CS_INT_16 = 0x11, - CS_INT_32 = 0x12, - CS_INT_64 = 0x13, - - //CS_ = 0x14, - //CS_ = 0x15, - //CS_BIG_INT_16 = 0x16, - //CS_BIG_INT_32 = 0x17, - //CS_BIG_FLOAT_16 = 0x18, - //CS_BIG_FLOAT_32 = 0x19, - CS_RAW_16 = 0x1a, - CS_RAW_32 = 0x1b, - CS_ARRAY_16 = 0x1c, - CS_ARRAY_32 = 0x1d, - CS_MAP_16 = 0x1e, - CS_MAP_32 = 0x1f, - - //ACS_BIG_INT_VALUE, - //ACS_BIG_FLOAT_VALUE, - ACS_RAW_VALUE, -} msgpack_unpack_state; - - -typedef enum { - CT_ARRAY_ITEM, - CT_MAP_KEY, - CT_MAP_VALUE, -} msgpack_container_type; - - -#ifdef __cplusplus -} -#endif - -#endif /* msgpack/unpack_define.h */ - diff --git a/msgpack/unpack_template.h b/msgpack/unpack_template.h deleted file mode 100644 index 711b163a..00000000 --- a/msgpack/unpack_template.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - * MessagePack unpacking routine template - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef msgpack_unpack_func -#error msgpack_unpack_func template is not defined -#endif - -#ifndef msgpack_unpack_callback -#error msgpack_unpack_callback template is not defined -#endif - -#ifndef msgpack_unpack_struct -#error msgpack_unpack_struct template is not defined -#endif - -#ifndef msgpack_unpack_struct_decl -#define msgpack_unpack_struct_decl(name) msgpack_unpack_struct(name) -#endif - -#ifndef msgpack_unpack_object -#error msgpack_unpack_object type is not defined -#endif - -#ifndef msgpack_unpack_user -#error msgpack_unpack_user type is not defined -#endif - -#ifndef USE_CASE_RANGE -#if !defined(_MSC_VER) -#define USE_CASE_RANGE -#endif -#endif - -msgpack_unpack_struct_decl(_stack) { - msgpack_unpack_object obj; - size_t count; - unsigned int ct; - msgpack_unpack_object map_key; -}; - -msgpack_unpack_struct_decl(_context) { - msgpack_unpack_user user; - unsigned int cs; - unsigned int trail; - unsigned int top; - /* - msgpack_unpack_struct(_stack)* stack; - unsigned int stack_size; - msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE]; - */ - msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE]; -}; - - -msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx) -{ - ctx->cs = CS_HEADER; - ctx->trail = 0; - ctx->top = 0; - /* - ctx->stack = ctx->embed_stack; - ctx->stack_size = MSGPACK_EMBED_STACK_SIZE; - */ - ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user); -} - -/* -msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx) -{ - if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) { - free(ctx->stack); - } -} -*/ - -msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx) -{ - return (ctx)->stack[0].obj; -} - - -msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off) -{ - assert(len >= *off); - - const unsigned char* p = (unsigned char*)data + *off; - const unsigned char* const pe = (unsigned char*)data + len; - const void* n = NULL; - - unsigned int trail = ctx->trail; - unsigned int cs = ctx->cs; - unsigned int top = ctx->top; - msgpack_unpack_struct(_stack)* stack = ctx->stack; - /* - unsigned int stack_size = ctx->stack_size; - */ - msgpack_unpack_user* user = &ctx->user; - - msgpack_unpack_object obj; - msgpack_unpack_struct(_stack)* c = NULL; - - int ret; - -#define push_simple_value(func) \ - if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \ - goto _push -#define push_fixed_value(func, arg) \ - if(msgpack_unpack_callback(func)(user, arg, &obj) < 0) { goto _failed; } \ - goto _push -#define push_variable_value(func, base, pos, len) \ - if(msgpack_unpack_callback(func)(user, \ - (const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \ - goto _push - -#define again_fixed_trail(_cs, trail_len) \ - trail = trail_len; \ - cs = _cs; \ - goto _fixed_trail_again -#define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \ - trail = trail_len; \ - if(trail == 0) { goto ifzero; } \ - cs = _cs; \ - goto _fixed_trail_again - -#define start_container(func, count_, ct_) \ - if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \ - if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \ - if((count_) == 0) { obj = stack[top].obj; goto _push; } \ - stack[top].ct = ct_; \ - stack[top].count = count_; \ - ++top; \ - /*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \ - /*printf("stack push %d\n", top);*/ \ - /* FIXME \ - if(top >= stack_size) { \ - if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \ - size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \ - size_t nsize = csize * 2; \ - msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \ - if(tmp == NULL) { goto _failed; } \ - memcpy(tmp, ctx->stack, csize); \ - ctx->stack = stack = tmp; \ - ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \ - } else { \ - size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \ - msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \ - if(tmp == NULL) { goto _failed; } \ - ctx->stack = stack = tmp; \ - ctx->stack_size = stack_size = stack_size * 2; \ - } \ - } \ - */ \ - goto _header_again - -#define NEXT_CS(p) \ - ((unsigned int)*p & 0x1f) - -#ifdef USE_CASE_RANGE -#define SWITCH_RANGE_BEGIN switch(*p) { -#define SWITCH_RANGE(FROM, TO) case FROM ... TO: -#define SWITCH_RANGE_DEFAULT default: -#define SWITCH_RANGE_END } -#else -#define SWITCH_RANGE_BEGIN { if(0) { -#define SWITCH_RANGE(FROM, TO) } else if(FROM <= *p && *p <= TO) { -#define SWITCH_RANGE_DEFAULT } else { -#define SWITCH_RANGE_END } } -#endif - - if(p == pe) { goto _out; } - do { - switch(cs) { - case CS_HEADER: - SWITCH_RANGE_BEGIN - SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum - push_fixed_value(_uint8, *(uint8_t*)p); - SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum - push_fixed_value(_int8, *(int8_t*)p); - SWITCH_RANGE(0xc0, 0xdf) // Variable - switch(*p) { - case 0xc0: // nil - push_simple_value(_nil); - //case 0xc1: // string - // again_terminal_trail(NEXT_CS(p), p+1); - case 0xc2: // false - push_simple_value(_false); - case 0xc3: // true - push_simple_value(_true); - //case 0xc4: - //case 0xc5: - //case 0xc6: - //case 0xc7: - //case 0xc8: - //case 0xc9: - case 0xca: // float - case 0xcb: // double - case 0xcc: // unsigned int 8 - case 0xcd: // unsigned int 16 - case 0xce: // unsigned int 32 - case 0xcf: // unsigned int 64 - case 0xd0: // signed int 8 - case 0xd1: // signed int 16 - case 0xd2: // signed int 32 - case 0xd3: // signed int 64 - again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); - //case 0xd4: - //case 0xd5: - //case 0xd6: // big integer 16 - //case 0xd7: // big integer 32 - //case 0xd8: // big float 16 - //case 0xd9: // big float 32 - case 0xda: // raw 16 - case 0xdb: // raw 32 - case 0xdc: // array 16 - case 0xdd: // array 32 - case 0xde: // map 16 - case 0xdf: // map 32 - again_fixed_trail(NEXT_CS(p), 2 << (((unsigned int)*p) & 0x01)); - default: - goto _failed; - } - SWITCH_RANGE(0xa0, 0xbf) // FixRaw - again_fixed_trail_if_zero(ACS_RAW_VALUE, ((unsigned int)*p & 0x1f), _raw_zero); - SWITCH_RANGE(0x90, 0x9f) // FixArray - start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM); - SWITCH_RANGE(0x80, 0x8f) // FixMap - start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY); - - SWITCH_RANGE_DEFAULT - goto _failed; - SWITCH_RANGE_END - // end CS_HEADER - - - _fixed_trail_again: - ++p; - - default: - if((size_t)(pe - p) < trail) { goto _out; } - n = p; p += trail - 1; - switch(cs) { - //case CS_ - //case CS_ - case CS_FLOAT: { - union { uint32_t i; float f; } mem; - mem.i = _msgpack_load32(uint32_t,n); - push_fixed_value(_float, mem.f); } - case CS_DOUBLE: { - union { uint64_t i; double f; } mem; - mem.i = _msgpack_load64(uint64_t,n); -#if defined(__arm__) && !(__ARM_EABI__) // arm-oabi - // https://github.com/msgpack/msgpack-perl/pull/1 - mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); -#endif - push_fixed_value(_double, mem.f); } - case CS_UINT_8: - push_fixed_value(_uint8, *(uint8_t*)n); - case CS_UINT_16: - push_fixed_value(_uint16, _msgpack_load16(uint16_t,n)); - case CS_UINT_32: - push_fixed_value(_uint32, _msgpack_load32(uint32_t,n)); - case CS_UINT_64: - push_fixed_value(_uint64, _msgpack_load64(uint64_t,n)); - - case CS_INT_8: - push_fixed_value(_int8, *(int8_t*)n); - case CS_INT_16: - push_fixed_value(_int16, _msgpack_load16(int16_t,n)); - case CS_INT_32: - push_fixed_value(_int32, _msgpack_load32(int32_t,n)); - case CS_INT_64: - push_fixed_value(_int64, _msgpack_load64(int64_t,n)); - - //case CS_ - //case CS_ - //case CS_BIG_INT_16: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load16(uint16_t,n), _big_int_zero); - //case CS_BIG_INT_32: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load32(uint32_t,n), _big_int_zero); - //case ACS_BIG_INT_VALUE: - //_big_int_zero: - // // FIXME - // push_variable_value(_big_int, data, n, trail); - - //case CS_BIG_FLOAT_16: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load16(uint16_t,n), _big_float_zero); - //case CS_BIG_FLOAT_32: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load32(uint32_t,n), _big_float_zero); - //case ACS_BIG_FLOAT_VALUE: - //_big_float_zero: - // // FIXME - // push_variable_value(_big_float, data, n, trail); - - case CS_RAW_16: - again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load16(uint16_t,n), _raw_zero); - case CS_RAW_32: - again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load32(uint32_t,n), _raw_zero); - case ACS_RAW_VALUE: - _raw_zero: - push_variable_value(_raw, data, n, trail); - - case CS_ARRAY_16: - start_container(_array, _msgpack_load16(uint16_t,n), CT_ARRAY_ITEM); - case CS_ARRAY_32: - /* FIXME security guard */ - start_container(_array, _msgpack_load32(uint32_t,n), CT_ARRAY_ITEM); - - case CS_MAP_16: - start_container(_map, _msgpack_load16(uint16_t,n), CT_MAP_KEY); - case CS_MAP_32: - /* FIXME security guard */ - start_container(_map, _msgpack_load32(uint32_t,n), CT_MAP_KEY); - - default: - goto _failed; - } - } - -_push: - if(top == 0) { goto _finish; } - c = &stack[top-1]; - switch(c->ct) { - case CT_ARRAY_ITEM: - if(msgpack_unpack_callback(_array_item)(user, &c->obj, obj) < 0) { goto _failed; } - if(--c->count == 0) { - obj = c->obj; - --top; - /*printf("stack pop %d\n", top);*/ - goto _push; - } - goto _header_again; - case CT_MAP_KEY: - c->map_key = obj; - c->ct = CT_MAP_VALUE; - goto _header_again; - case CT_MAP_VALUE: - if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; } - if(--c->count == 0) { - obj = c->obj; - --top; - /*printf("stack pop %d\n", top);*/ - goto _push; - } - c->ct = CT_MAP_KEY; - goto _header_again; - - default: - goto _failed; - } - -_header_again: - cs = CS_HEADER; - ++p; - } while(p != pe); - goto _out; - - -_finish: - stack[0].obj = obj; - ++p; - ret = 1; - /*printf("-- finish --\n"); */ - goto _end; - -_failed: - /*printf("** FAILED **\n"); */ - ret = -1; - goto _end; - -_out: - ret = 0; - goto _end; - -_end: - ctx->cs = cs; - ctx->trail = trail; - ctx->top = top; - *off = p - (const unsigned char*)data; - - return ret; -} - - -#undef msgpack_unpack_func -#undef msgpack_unpack_callback -#undef msgpack_unpack_struct -#undef msgpack_unpack_object -#undef msgpack_unpack_user - -#undef push_simple_value -#undef push_fixed_value -#undef push_variable_value -#undef again_fixed_trail -#undef again_fixed_trail_if_zero -#undef start_container - -#undef NEXT_CS - diff --git a/tmate-slave.c b/tmate-slave.c index a98082b3..5557617d 100644 --- a/tmate-slave.c +++ b/tmate-slave.c @@ -271,8 +271,8 @@ static void jail(void) if (chdir("/") < 0) tmate_fatal("Cannot chdir()"); - if (unshare(CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWNET) < 0) - tmate_fatal("Cannot create new namespace"); + /* if (unshare(CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWNET) < 0) */ + /* tmate_fatal("Cannot create new namespace"); */ if (setgroups(1, (gid_t[]){gid}) < 0) tmate_fatal("Cannot setgroups()"); diff --git a/tmate.h b/tmate.h index d6703ddf..d5abceea 100644 --- a/tmate.h +++ b/tmate.h @@ -43,7 +43,7 @@ extern void tmate_encoder_init(struct tmate_encoder *encoder, tmate_encoder_write_cb *callback, void *userdata); -#define NEW_MSGPACK_API 0 +#define NEW_MSGPACK_API 1 #if NEW_MSG_PACK #define msgpack_pack_buffer(pk, buf, len) ({ \