Compare commits

..

2 Commits
v0-3 ... v0-2

Author SHA1 Message Date
Andreas Schneider
62de58d8e5 Add extern C declatrion to server header file.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/branches/v0.2@199 7dcaeef0-15fb-0310-b436-a5af3365683c
2009-01-08 17:48:35 +00:00
Andreas Schneider
1c9ed8d41d Create a branch for further libssh 0.2 maintenance versions.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/branches/v0.2@194 7dcaeef0-15fb-0310-b436-a5af3365683c
2008-12-22 09:45:31 +00:00
101 changed files with 11457 additions and 22621 deletions

6
.gitignore vendored
View File

@@ -1,6 +0,0 @@
.*
*.swp
*~$
build
cscope.*
tags

View File

@@ -1,7 +1,5 @@
Author(s):
Aris Adamantiadis <aris@0xbadc0de.be> (project initiator)
Andreas Schneider <mail@cynapses.org> (developer)
Aris Adamantiadis <aris (at) 0xbadc0de (dot) be> (project initiator)
Nick Zitzmann <seiryu (at) comcast (dot) net> (mostly client SFTP stuff)

View File

@@ -1,70 +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 "0.3.4")
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "3")
set(APPLICATION_VERSION_PATCH "4")
set(LIBRARY_VERSION "3.4.0")
set(LIBRARY_SOVERSION "3")
# 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(DefineCompilerFlags)
include(DefineInstallationPaths)
include(DefineOptions.cmake)
include(CPackConfig.cmake)
# disallow in-source build
include(MacroEnsureOutOfSourceBuild)
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
# add macros
include(MacroAddPlugin)
include(MacroCopyFile)
# search for libraries
find_package(ZLIB REQUIRED)
find_package(OpenSSL)
if (NOT CRYPTO_FOUND)
find_package(GCrypt)
if (NOT GCRYPT_FOUND)
message(FATAL_ERROR "Could not find OpenSSL or GCrypt")
endif (NOT GCRYPT_FOUND)
endif (NOT CRYPTO_FOUND)
# 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(libssh)
# build samples
include_directories(${CMAKE_SOURCE_DIR}/include)
if (UNIX AND NOT WIN32)
if (WITH_SFTP AND WITH_SERVER)
add_executable(samplessh sample.c)
add_executable(samplesshd samplesshd.c)
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY})
endif (WITH_SFTP AND WITH_SERVER)
endif (UNIX AND NOT WIN32)

View File

@@ -1,50 +0,0 @@
include(InstallRequiredSystemLibraries)
# 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 "3")
set(CPACK_PACKAGE_VERSION_PATCH "4")
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
### source generator
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
### nsis generator
set(CPACK_GENERATOR "NSIS")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "libssh")
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")
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)

226
ChangeLog
View File

@@ -1,154 +1,80 @@
ChangeLog
==========
libssh-0.11-dev
-server implementation development. I won't document it before it even works.
-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.
-sftp_file_set_nonblocking added. It's now possible to have 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.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.
5th march 2004 : libssh-0.1
-Begining of sftp subsystem implementation. It's stable enough to be used :)
-some cleanup into channels implementation
-Now every channel functions is called by its CHANNEL handler. no any way to play again with numbers.
-added channel_poll() and channel_read(). Now, it's possible to manipulate channel streams only with channel_read() and channel_write(),
with help of channel_poll().
-changed the client so it uses the new channel_poll and channel_read interface
-small use-after-free bug with channels resolved, and a noninitialised data of SIGNATURE struct.
-changed stupidities in lot of function names.
-removed a debug output file opened by default.
-Added API.txt, the libssh programmer handbook. (I hate documentation)
-Various bug fixes from Nick Zitzmann. Thank to him, libssh now runs under macosX !
-Developed a cryptographic structure for handling protocols. Adding a custom-based cipher should be the story of thirty
minutes. It now supports aes-256,aes-192,aes-128 and blowfish-128 !
-An autoconf script which took me half of a day to set up. Respect it!
-A ssh_select wrapper has been written.
It all means the API has changed. not a lot but enough to be incompatible with anything which has been written.
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).
10th october 2003 : libssh-0.0.4
-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 (but you're advised to upgrade)
-RSA pubkey authentication code now works !
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.
15th september 2003 : libssh-0.0.3
-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 : now packet are completely read (and read blocks if waiting the packet)
-new misc.c contains misc functions
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.
3rd september 2003: libssh-0.0.2
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.

View File

@@ -1,56 +0,0 @@
include(CheckIncludeFile)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckTypeSize)
include(CheckCXXSourceCompiles)
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})
# HEADER FILES
check_include_file(pty.h HAVE_PTY_H)
check_include_file(terminos.h HAVE_TERMIOS_H)
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
# FUNCTIONS
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
if (WIN32)
set(HAVE_GETADDRINFO TRUE)
set(HAVE_GETHOSTBYNAME TRUE)
set(HAVE_SELECT TRUE)
else (WIN32)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_function_exists(gethostbyname HAVE_GETHOSTBYNAME)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
endif (WIN32)
# LIBRARIES
if (CRYPTO_FOUND)
set(HAVE_LIBCRYPTO 1)
endif (CRYPTO_FOUND)
if (GCRYPT_FOUND)
set(HAVE_LIBGCRYPT 1)
endif (GCRYPT_FOUND)
if (Z_LIBRARY)
set(HAVE_LIBZ 1)
endif (Z_LIBRARY)
# OPTIONS
if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO)

View File

@@ -1,6 +0,0 @@
option(WITH_LIBZ "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 debut output" OFF)

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = libssh
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.3-svn
PROJECT_NUMBER = 0.2.1-svn
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = libssh
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.3-svn
PROJECT_NUMBER = 0.2.1-svn
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

258
INSTALL
View File

@@ -1,78 +1,236 @@
# How to build from source
Installation Instructions
*************************
## Requirements
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
Software Foundation, Inc.
### Common requirements
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
In order to build libssh, you need to install several components:
Basic Installation
==================
- 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
These are generic installation instructions.
optional:
- [libz](http://www.zlib.net) >= 1.2
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
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.
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
## Building
First, you need to configure the compilation, using CMake. Go inside the
`build` dir. Create it if it doesn't exist.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
GNU/Linux and MacOS X:
The simplest way to compile this package is:
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
make
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
### CMake standard options
Here is a list of the most interesting options provided out of the box by
CMake.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
- 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
2. Type `make' to compile the package.
### CMake options defined for libssh
3. Optionally, type `make check' to run any self-tests that come with
the package.
Options are defined in the following files:
4. Type `make install' to install the programs and any data files and
documentation.
- DefineOptions.cmake
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
They can be changed with the -D option:
Compilers and Options
=====================
`cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DWITH_LIBZ=OFF ..`
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
### Browsing/editing CMake options
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
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).
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
- Go to the build dir
- On Windows: run `cmakesetup`
- On GNU/Linux and MacOS X: run `ccmake ..`
*Note Defining Variables::, for more details.
## Installing
Compiling For Multiple Architectures
====================================
If you want to install libssh after compilation run:
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
make install
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
## Running
Installation Names
==================
The libssh binary can be found in the `build/libssh` directory.
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
## About this document
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
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.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script). Here is a another example:
/bin/bash ./configure CONFIG_SHELL=/bin/bash
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
configuration-related scripts to be executed by `/bin/bash'.
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
[markdown]: http://www.daringfireball.net/projects/markdown

41
Makefile.Windows Normal file
View File

@@ -0,0 +1,41 @@
CC= gcc
DLLWRAP=dllwrap.exe
DEFFILE=libssh.def
STATICLIB=libssh.a
LIB="c:\Program files\Microsoft Visual Studio .NET 2003\vc7\bin\lib.exe"
INCS= -I. -Iinclude -Ic:/openssl/include -I"c:\Program files\gnuwin32\include"
CFLAGS= $(INCS)
LINK= -L. c:/openssl/lib/MinGW/libeay32.a "c:\program files\gnuwin32\lib\libz.a" c:\Dev-cpp\lib\libws2_32.a #-lws2_32 ##-lgdi32 -lshell32
libssh_HEADERS= config.h include/libssh/crypto.h include/libssh/libssh.h include/libssh/priv.h include/libssh/server.h include/libssh/sftp.h include/libssh/ssh1.h include/libssh/ssh2.h
libssh_OBJS = libssh/auth1.o libssh/auth.o libssh/base64.o libssh/buffer.o \
libssh/channels1.o libssh/channels.o libssh/client.o libssh/connect.o \
libssh/crc32.o libssh/crypt.o libssh/dh.o libssh/error.o libssh/gcrypt_missing.o \
libssh/gzip.o libssh/init.o libssh/kex.o libssh/keyfiles.o \
libssh/keys.o libssh/messages.o libssh/misc.o libssh/options.o \
libssh/packet.o libssh/server.o libssh/session.o libssh/sftp.o \
libssh/sftpserver.o libssh/string.o libssh/wrapper.o libssh/socket.o \
libssh/log.o
all: libssh.dll samplesshd.exe libssh.lib
config.h: config.h.win32-openssl
copy config.h.win32-openssl config.h
%.o: %.c $(libssh_HEADERS)
$(CC) -c $< -o $@ $(CFLAGS)
sample.exe: sample.o $(libssh_OBJS)
$(CC) $< -o $@ $(libssh_OBJS) $(LINK)
samplesshd.exe: samplesshd.o $(libssh_OBJS)
$(CC) $< -o $@ $(libssh_OBJS) $(LINK)
libssh.dll: $(libssh_OBJS)
# $(CC) -shared $(libssh_OBJS) -o libssh.dll $(LINK)
$(DLLWRAP) --export-all-symbols --output-def $(DEFFILE) --implib $(STATICLIB) $(libssh_OBJS) $(LINK) -o libssh.dll
libssh.lib: libssh.dll
lib.bat
clean:
rm -f $(libssh_OBJS) samplesshd.exe sample.exe samplesshd.o sample.o libssh.dll config.h

44
Makefile.am Normal file
View File

@@ -0,0 +1,44 @@
SUBDIRS = libssh include
AM_CPPFLAGS = -I$(srcdir)/include
LDADD = $(top_builddir)/libssh/libssh.la
noinst_PROGRAMS = samplesshd samplessh
noinst_DATA = samplesftp doxygen
samplessh_SOURCES = sample.c
samplesshd_SOURCES = samplesshd.c
samplesftp: samplessh
$(LN_S) -f samplessh samplesftp
if HAS_DOXYGEN
install-doc: doxygen
$(INSTALL) -d $(DESTDIR)$(docdir)/html
$(INSTALL) --mode=644 doxygen/html/* $(DESTDIR)$(docdir)/html
$(INSTALL) -d $(DESTDIR)$(docdir)/examples
$(INSTALL) --mode=644 sample.c samplesshd.c $(DESTDIR)$(docdir)/examples
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
$(INSTALL) --mode=644 doxygen/man/man3/* $(DESTDIR)$(mandir)/man3
doxygen: clean-local
@echo "Running doxygen..."
doxygen $(srcdir)/Doxyfile
doxygen-dev: clean-local
@echo "Running internal doxygen"
doxygen $(srcdir)/Doxyfile.internal
else
doxygen:
doxygen-dev:
install-doc: doxygen
endif
clean-local:
-rm -rf doxygen
EXTRA_DIST = Doxyfile Doxyfile.internal
CLEANFILES = samplesftp

0
NEWS Normal file
View File

8
autogen.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh -e
aclocal
libtoolize --force --copy
autoheader
autoconf
automake --add-missing --copy --gnu
./configure $@

View File

@@ -1,152 +0,0 @@
#!/bin/bash
#
# Last Change: 2008-06-18 14:13:46
#
# Script to build libssh on UNIX.
#
# Copyright (c) 2006-2007 Andreas Schneider <mail@cynapses.org>
#
SOURCE_DIR=".."
LANG=C
export LANG
SCRIPT="$0"
COUNT=0
while [ -L "${SCRIPT}" ]
do
SCRIPT=$(readlink ${SCRIPT})
COUNT=$(expr ${COUNT} + 1)
if [ ${COUNT} -gt 100 ]; then
echo "Too many symbolic links"
exit 1
fi
done
BUILDDIR=$(dirname ${SCRIPT})
cleanup_and_exit () {
if test "$1" = 0 -o -z "$1" ; then
exit 0
else
exit $1
fi
}
function configure() {
cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
}
function compile() {
CPUCOUNT=$(grep -c processor /proc/cpuinfo)
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]"
cleanup_and_exit
}
cd ${BUILDDIR}
OPTIONS="--graphviz=${BUILDDIR}/libssh.dot -DUNIT_TESTING=ON -DWITH_SSH1=ON -DWITH_SERVER=ON"
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
;;
*-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
;;
----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} -eq 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

View File

@@ -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.

View File

@@ -1,27 +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)

View File

@@ -1,50 +0,0 @@
# define system dependent compiler flags
include(CheckCCompilerFlag)
if (UNIX AND NOT WIN32)
if (CMAKE_COMPILER_IS_GNUCC)
add_definitions(-Wall -Wextra -Wmissing-prototypes -Wdeclaration-after-statement -Wunused)
# with -fPIC
check_c_compiler_flag("-fPIC" WITH_FPIC)
if (WITH_FPIC)
add_definitions(-fPIC)
endif (WITH_FPIC)
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
)
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
add_definitions(${_lfs_CFLAGS})
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
check_c_compiler_flag("-fstack-protector" WITH_STACK_PROTECTOR)
if (WITH_STACK_PROTECTOR)
add_definitions(-fstack-protector)
endif (WITH_STACK_PROTECTOR)
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
if (WITH_FORTIFY_SOURCE)
add_definitions(-D_FORTIFY_SOURCE=2)
endif (WITH_FORTIFY_SOURCE)
endif (CMAKE_COMPILER_IS_GNUCC)
endif (UNIX AND NOT WIN32)

View File

@@ -1,107 +0,0 @@
if (UNIX)
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(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)"
)
endif (UNIX)
if (WIN32)
# Same same
set(BIN_INSTALL_DIR "." CACHE PATH "-")
set(SBIN_INSTALL_DIR "." CACHE PATH "-")
set(LIB_INSTALL_DIR "lib" CACHE PATH "-")
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
set(ICON_INSTALL_DIR "." CACHE PATH "-")
set(SOUND_INSTALL_DIR "." CACHE PATH "-")
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
endif (WIN32)

View File

@@ -1,77 +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 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
# in cache already
set(GCRYPT_FOUND TRUE)
else (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
find_path(GCRYPT_INCLUDE_DIR
NAMES
gcrypt.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
mark_as_advanced(GCRYPT_INCLUDE_DIR)
find_library(GCRYPT_LIBRARY
NAMES
gcrypt
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(GCRYPT_LIBRARY)
if (GCRYPT_LIBRARY)
set(GCRYPT_FOUND TRUE CACHE INTERNAL "Wether the gcrypt library has been found" FORCE)
endif (GCRYPT_LIBRARY)
set(GCRYPT_INCLUDE_DIRS
${GCRYPT_INCLUDE_DIR}
)
if (GCRYPT_FOUND)
set(GCRYPT_LIBRARIES
${GCRYPT_LIBRARIES}
${GCRYPT_LIBRARY}
)
endif (GCRYPT_FOUND)
if (GCRYPT_INCLUDE_DIRS AND GCRYPT_LIBRARIES)
set(GCRYPT_FOUND TRUE)
endif (GCRYPT_INCLUDE_DIRS AND GCRYPT_LIBRARIES)
if (GCRYPT_FOUND)
if (NOT GCrypt_FIND_QUIETLY)
message(STATUS "Found GCrypt: ${GCRYPT_LIBRARIES}")
endif (NOT GCrypt_FIND_QUIETLY)
else (GCRYPT_FOUND)
if (GCrypt_FIND_REQUIRED)
message(FATAL_ERROR "Could not find GCrypt")
endif (GCrypt_FIND_REQUIRED)
endif (GCRYPT_FOUND)
# show the GCRYPT_INCLUDE_DIRS and GCRYPT_LIBRARIES variables only in the advanced view
mark_as_advanced(GCRYPT_INCLUDE_DIRS GCRYPT_LIBRARIES)
endif (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)

View File

@@ -1,159 +0,0 @@
# - Try to find OpenSSL
# Once done this will define
#
# 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) 2009 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
# in cache already
set(OPENSSL_FOUND TRUE)
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
include(UsePkgConfig)
pkgconfig(openssl _OPENSSL_INCLUDEDIR _OPENSSL_LIBDIR _OPENSSL_LDFLAGS _OPENSSL_CFLAGS)
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_OPENSSL openssl)
endif (PKG_CONFIG_FOUND)
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_path(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
PATHS
${_OPENSSL_INCLUDEDIR}
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
mark_as_advanced(OPENSSL_INCLUDE_DIR)
find_library(SSL_LIBRARY
NAMES
ssl
PATHS
${_OPENSSL_LIBDIR}
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(SSL_LIBRARY)
find_library(SSLEAY32_LIBRARY
NAMES
ssleay32
PATHS
${_OPENSSL_LIBDIR}
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(SSLEAY32_LIBRARY)
find_library(SSLEAY32MD_LIBRARY
NAMES
ssleay32MD
PATHS
${_OPENSSL_LIBDIR}
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(SSLEAY32MD_LIBRARY)
find_library(CRYPTO_LIBRARY
NAMES
crypto
PATHS
${_OPENSSL_LIBDIR}
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(CRYPTO_LIBRARY)
if (SSL_LIBRARY)
set(SSL_FOUND TRUE CACHE INTERNAL "Wether the ssl library has been found" FORCE)
endif (SSL_LIBRARY)
if (SSLEAY32_LIBRARY)
set(SSLEAY32_FOUND TRUE CACHE INTERNAL "Wether the ssleay32 library has been found" FORCE)
endif (SSLEAY32_LIBRARY)
if (SSLEAY32MD_LIBRARY)
set(SSLEAY32MD_FOUND TRUE CACHE INTERNAL "Wether the ssleay32MD library has been found" FORCE)
endif (SSLEAY32MD_LIBRARY)
if (CRYPTO_LIBRARY)
set(CRYPTO_FOUND TRUE CACHE INTERNAL "Wether the crypto library has been found" FORCE)
endif (CRYPTO_LIBRARY)
set(OPENSSL_INCLUDE_DIRS
${OPENSSL_INCLUDE_DIR}
)
if (SSL_FOUND)
set(OPENSSL_LIBRARIES
${OPENSSL_LIBRARIES}
${SSL_LIBRARY}
)
endif (SSL_FOUND)
if (SSLEAY32_FOUND)
set(OPENSSL_LIBRARIES
${OPENSSL_LIBRARIES}
${SSLEAY32_LIBRARY}
)
endif (SSLEAY32_FOUND)
if (SSLEAY32MD_FOUND)
set(OPENSSL_LIBRARIES
${OPENSSL_LIBRARIES}
${SSLEAY32MD_LIBRARY}
)
endif (SSLEAY32MD_FOUND)
if (CRYPTO_FOUND)
set(OPENSSL_LIBRARIES
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARY}
)
endif (CRYPTO_FOUND)
if (OPENSSL_INCLUDE_DIRS AND OPENSSL_LIBRARIES)
set(OPENSSL_FOUND TRUE)
endif (OPENSSL_INCLUDE_DIRS AND OPENSSL_LIBRARIES)
if (OPENSSL_FOUND)
if (NOT OpenSSL_FIND_QUIETLY)
message(STATUS "Found OpenSSL: ${OPENSSL_LIBRARIES}")
endif (NOT OpenSSL_FIND_QUIETLY)
else (OPENSSL_FOUND)
if (OpenSSL_FIND_REQUIRED)
message(FATAL_ERROR "Could not find OpenSSL")
endif (OpenSSL_FIND_REQUIRED)
endif (OPENSSL_FOUND)
# show the OPENSSL_INCLUDE_DIRS and OPENSSL_LIBRARIES variables only in the advanced view
mark_as_advanced(OPENSSL_INCLUDE_DIRS OPENSSL_LIBRARIES)
endif (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)

View File

@@ -1,79 +0,0 @@
# - Try to find ZLIB
# Once done this will define
#
# ZLIB_FOUND - system has ZLIB
# ZLIB_INCLUDE_DIRS - the ZLIB include directory
# ZLIB_LIBRARIES - Link these to use ZLIB
# ZLIB_DEFINITIONS - Compiler switches required for using ZLIB
#
# Copyright (c) 2009 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
# in cache already
set(ZLIB_FOUND TRUE)
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
find_path(ZLIB_INCLUDE_DIR
NAMES
zlib.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
mark_as_advanced(ZLIB_INCLUDE_DIR)
find_library(Z_LIBRARY
NAMES
z
zlib
zlib1
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(Z_LIBRARY)
if (Z_LIBRARY)
set(Z_FOUND TRUE)
endif (Z_LIBRARY)
set(ZLIB_INCLUDE_DIRS
${ZLIB_INCLUDE_DIR}
)
if (Z_FOUND)
set(ZLIB_LIBRARIES
${ZLIB_LIBRARIES}
${Z_LIBRARY}
)
endif (Z_FOUND)
if (ZLIB_INCLUDE_DIRS AND ZLIB_LIBRARIES)
set(ZLIB_FOUND TRUE)
endif (ZLIB_INCLUDE_DIRS AND ZLIB_LIBRARIES)
if (ZLIB_FOUND)
if (NOT ZLIB_FIND_QUIETLY)
message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES}")
endif (NOT ZLIB_FIND_QUIETLY)
else (ZLIB_FOUND)
if (ZLIB_FIND_REQUIRED)
message(FATAL_ERROR "Could not find ZLIB")
endif (ZLIB_FIND_REQUIRED)
endif (ZLIB_FOUND)
# show the ZLIB_INCLUDE_DIRS and ZLIB_LIBRARIES variables only in the advanced view
mark_as_advanced(ZLIB_INCLUDE_DIRS ZLIB_LIBRARIES)
endif (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)

View File

@@ -1,21 +0,0 @@
# - MACRO_ADD_COMPILE_FLAGS(target_name flag1 ... flagN)
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
macro (MACRO_ADD_COMPILE_FLAGS _target)
get_target_property(_flags ${_target} COMPILE_FLAGS)
if (_flags)
set(_flags ${_flags} ${ARGN})
else (_flags)
set(_flags ${ARGN})
endif (_flags)
set_target_properties(${_target} PROPERTIES COMPILE_FLAGS ${_flags})
endmacro (MACRO_ADD_COMPILE_FLAGS)

View File

@@ -1,20 +0,0 @@
# - MACRO_ADD_LINK_FLAGS(target_name flag1 ... flagN)
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
macro (MACRO_ADD_LINK_FLAGS _target)
get_target_property(_flags ${_target} LINK_FLAGS)
if (_flags)
set(_flags "${_flags} ${ARGN}")
else (_flags)
set(_flags "${ARGN}")
endif (_flags)
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${_flags}")
endmacro (MACRO_ADD_LINK_FLAGS)

View File

@@ -1,30 +0,0 @@
# - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN)
#
# Create a plugin from the given source files.
# If WITH_PREFIX is given, the resulting plugin will have the
# prefix "lib", otherwise it won't.
#
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX)
if (${_with_PREFIX} STREQUAL "WITH_PREFIX")
set(_first_SRC)
else (${_with_PREFIX} STREQUAL "WITH_PREFIX")
set(_first_SRC ${_with_PREFIX})
endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN})
if (_first_SRC)
set_target_properties(${_target_NAME} PROPERTIES PREFIX "")
endif (_first_SRC)
endmacro (MACRO_ADD_PLUGIN _name _sources)

View File

@@ -1,33 +0,0 @@
# - macro_copy_file(_src _dst)
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
#
# Example:
# macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.)
# Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory
#
# Copyright (c) 2006-2007 Wengo
# Copyright (c) 2006-2008 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING file.
macro (macro_copy_file _src _dst)
# Removes all path containing .svn or CVS or CMakeLists.txt during the copy
if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
if (CMAKE_VERBOSE_MAKEFILE)
message(STATUS "Copy file from ${_src} to ${_dst}")
endif (CMAKE_VERBOSE_MAKEFILE)
# Creates directory if necessary
get_filename_component(_path ${_dst} PATH)
file(MAKE_DIRECTORY ${_path})
execute_process(
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst}
OUTPUT_QUIET
)
endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
endmacro (macro_copy_file)

View File

@@ -1,17 +0,0 @@
# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage)
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource)
if (_insource)
message(SEND_ERROR "${_errorMessage}")
message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.")
endif (_insource)
endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

View File

@@ -1,127 +0,0 @@
# -helper macro to add a "doc" target with CMake build system.
# and configure doxy.config.in to doxy.config
#
# target "doc" allows building the documentation with doxygen/dot on WIN32 and Linux
# Creates .chm windows help file if MS HTML help workshop
# (available from http://msdn.microsoft.com/workshop/author/htmlhelp)
# is installed with its DLLs in PATH.
#
#
# Please note, that the tools, e.g.:
# doxygen, dot, latex, dvips, makeindex, gswin32, etc.
# must be in path.
#
# Note about Visual Studio Projects:
# MSVS has its own path environment which may differ from the shell.
# See "Menu Tools/Options/Projects/VC++ Directories" in VS 7.1
#
# author Jan Woetzel 2004-2006
# www.mip.informatik.uni-kiel.de/~jw
FIND_PACKAGE(Doxygen)
IF (DOXYGEN_FOUND)
# click+jump in Emacs and Visual Studio (for doxy.config) (jw)
IF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
SET(DOXY_WARN_FORMAT "\"$file($line) : $text \"")
ELSE (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
SET(DOXY_WARN_FORMAT "\"$file:$line: $text \"")
ENDIF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
# we need latex for doxygen because of the formulas
FIND_PACKAGE(LATEX)
IF (NOT LATEX_COMPILER)
MESSAGE(STATUS "latex command LATEX_COMPILER not found but usually required. You will probably get warnings and user inetraction on doxy run.")
ENDIF (NOT LATEX_COMPILER)
IF (NOT MAKEINDEX_COMPILER)
MESSAGE(STATUS "makeindex command MAKEINDEX_COMPILER not found but usually required.")
ENDIF (NOT MAKEINDEX_COMPILER)
IF (NOT DVIPS_CONVERTER)
MESSAGE(STATUS "dvips command DVIPS_CONVERTER not found but usually required.")
ENDIF (NOT DVIPS_CONVERTER)
FIND_PROGRAM(DOXYGEN_DOT_EXECUTABLE_PATH NAMES dot)
IF (DOXYGEN_DOT_EXECUTABLE_PATH)
SET(DOXYGEN_DOT_FOUND "YES")
ENDIF (DOXYGEN_DOT_EXECUTABLE_PATH)
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
MESSAGE(STATUS "Generate ${CMAKE_CURRENT_BINARY_DIR}/doxy.config from doxy.config.in")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in
${CMAKE_CURRENT_BINARY_DIR}/doxy.config
@ONLY )
# use (configured) doxy.config from (out of place) BUILD tree:
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/doxy.config")
ELSE (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
# use static hand-edited doxy.config from SOURCE tree:
SET(DOXY_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
MESSAGE(STATUS "WARNING: using existing ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config instead of configuring from doxy.config.in file.")
ELSE (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
IF (EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
# using template doxy.config.in
MESSAGE(STATUS "Generate ${CMAKE_CURRENT_BINARY_DIR}/doxy.config from doxy.config.in")
CONFIGURE_FILE(${CMAKE_MODULE_PATH}/doxy.config.in
${CMAKE_CURRENT_BINARY_DIR}/doxy.config
@ONLY )
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/doxy.config")
ELSE (EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
# failed completely...
MESSAGE(SEND_ERROR "Please create ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in (or doxy.config as fallback)")
ENDIF(EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
ADD_CUSTOM_TARGET(doc ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
# create a windows help .chm file using hhc.exe
# HTMLHelp DLL must be in path!
# fallback: use hhw.exe interactively
IF (WIN32)
FIND_PACKAGE(HTMLHelp)
IF (HTML_HELP_COMPILER)
SET (TMP "${CMAKE_CURRENT_BINARY_DIR}\\doc\\html\\index.hhp")
STRING(REGEX REPLACE "[/]" "\\\\" HHP_FILE ${TMP} )
# MESSAGE(SEND_ERROR "DBG HHP_FILE=${HHP_FILE}")
ADD_CUSTOM_TARGET(winhelp ${HTML_HELP_COMPILER} ${HHP_FILE})
ADD_DEPENDENCIES (winhelp doc)
IF (NOT TARGET_DOC_SKIP_INSTALL)
# install windows help?
# determine useful name for output file
# should be project and version unique to allow installing
# multiple projects into one global directory
IF (EXISTS "${PROJECT_BINARY_DIR}/doc/html/index.chm")
IF (PROJECT_NAME)
SET(OUT "${PROJECT_NAME}")
ELSE (PROJECT_NAME)
SET(OUT "Documentation") # default
ENDIF(PROJECT_NAME)
IF (${PROJECT_NAME}_VERSION_MAJOR)
SET(OUT "${OUT}-${${PROJECT_NAME}_VERSION_MAJOR}")
IF (${PROJECT_NAME}_VERSION_MINOR)
SET(OUT "${OUT}.${${PROJECT_NAME}_VERSION_MINOR}")
IF (${PROJECT_NAME}_VERSION_PATCH)
SET(OUT "${OUT}.${${PROJECT_NAME}_VERSION_PATCH}")
ENDIF(${PROJECT_NAME}_VERSION_PATCH)
ENDIF(${PROJECT_NAME}_VERSION_MINOR)
ENDIF(${PROJECT_NAME}_VERSION_MAJOR)
# keep suffix
SET(OUT "${OUT}.chm")
#MESSAGE("DBG ${PROJECT_BINARY_DIR}/doc/html/index.chm \n${OUT}")
# create target used by install and package commands
INSTALL(FILES "${PROJECT_BINARY_DIR}/doc/html/index.chm"
DESTINATION "doc"
RENAME "${OUT}"
)
ENDIF(EXISTS "${PROJECT_BINARY_DIR}/doc/html/index.chm")
ENDIF(NOT TARGET_DOC_SKIP_INSTALL)
ENDIF(HTML_HELP_COMPILER)
# MESSAGE(SEND_ERROR "HTML_HELP_COMPILER=${HTML_HELP_COMPILER}")
ENDIF (WIN32)
ENDIF(DOXYGEN_FOUND)

View File

@@ -1,87 +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 <pty.h> header file. */
#cmakedefine HAVE_PTY_H 1
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H 1
/* Define to 1 if you have the <openssl/aes.h> header file. */
#cmakedefine HAVE_OPENSSL_AES_H 1
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
#cmakedefine HAVE_OPENSSL_BLOWFISH_H 1
/* Define to 1 if you have the <openssl/des.h> header file. */
#cmakedefine HAVE_OPENSSL_DES_H 1
/*************************** FUNCTIONS ***************************/
/* 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 `gethostbyname' function. */
#cmakedefine HAVE_GETHOSTBYNAME 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
/*************************** 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 `z' library (-lz). */
#cmakedefine HAVE_LIBZ 1
/**************************** OPTIONS ****************************/
/* Define to 1 if you want to enable ZLIB */
#cmakedefine WITH_LIBZ 1
/* Define to 1 if you want to enable SSH1 */
#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 WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif

193
config.h.win32-openssl Normal file
View File

@@ -0,0 +1,193 @@
/* config.h. Manually tweaked for Windows. */
/* Define to 1 if you have the `cfmakeraw' function. */
#define HAVE_CFMAKERAW 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */
/* Define to 1 if you have the `endpwent' function. */
/* #undef HAVE_ENDPWENT */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <gcrypt.h> header file. */
/* #undef HAVE_GCRYPT_H */
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the `gethostbyname' function. */
#define HAVE_GETHOSTBYNAME 1
/* Define to 1 if you have the `getpass' function. */
/* #undef HAVE_GETPASS */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#define HAVE_LIBCRYPTO 1
/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
/* #undef HAVE_LIBGCRYPT */
/* Define to 1 if you have the `z' library (-lz). */
#define HAVE_LIBZ 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <netdb.h> header file. */
/* #undef HAVE_NETDB_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Define to 1 if you have the <openssl/aes.h> header file. */
#define HAVE_OPENSSL_AES_H 1
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
#define HAVE_OPENSSL_BLOWFISH_H 1
/* Define to 1 if you have the <openssl/des.h> header file. */
#define HAVE_OPENSSL_DES_H 1
/* Define to 1 if you have the `poll' function. */
/* #undef HAVE_POLL */
/* Define to 1 if you have the <pty.h> header file. */
/* #undef HAVE_PTY_H */
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC 1
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you want to enable SSH1 */
/* #undef HAVE_SSH1 */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
/* Define to 1 if you have the <sys/poll.h> header file. */
/* #undef HAVE_SYS_POLL_H */
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <termios.h> header file. */
/* #undef HAVE_TERMIOS_H */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Name of package */
#define PACKAGE "libssh"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "aris@0xbadc0de.be"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libssh"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libssh 0.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libssh"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.2.1-win-svn"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to the type of arg 1 for `select'. */
#define SELECT_TYPE_ARG1 int
/* Define to the type of args 2, 3 and 4 for `select'. */
#define SELECT_TYPE_ARG234 (fd_set *)
/* Define to the type of arg 5 for `select'. */
#define SELECT_TYPE_ARG5 (struct timeval *)
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Version number of package */
#define VERSION "0.2.1-win-svn"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */

135
configure.ac Normal file
View File

@@ -0,0 +1,135 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT([libssh], 0.2.1-svn, [aris@0xbadc0de.be])
AM_INIT_AUTOMAKE(1.9)
AC_CONFIG_SRCDIR([sample.c])
AC_CONFIG_HEADER([config.h])
AM_MAINTAINER_MODE
# LT Version numbers, remember to change them just *before* a release.
# (Interfaces removed: CURRENT++, AGE=0, REVISION=0)
# (Interfaces added: CURRENT++, AGE++, REVISION=0)
# (No interfaces changed: REVISION++)
LIBSSH_CURRENT=3
LIBSSH_AGE=1
LIBSSH_REVISION=0
AC_SUBST(LIBSSH_CURRENT)
AC_SUBST(LIBSSH_AGE)
AC_SUBST(LIBSSH_REVISION)
# Check for the OS.
AC_CANONICAL_HOST
case "$host" in
*-apple*)
LIBSSH_LDFLAGS="-prebind -seg1addr 0x3a000000 -headerpad_max_install_names"
;;
*)
LIBSSH_LDFLAGS=""
;;
esac
AC_SUBST(LIBSSH_LDFLAGS)
AC_MSG_CHECKING([version script options])
case "$host" in
*-*-linux*)
LIBSSH_VERS="$LIBSSH_LDFLAGS -Wl,--version-script,libssh.vers"
;;
*-*-gnu*)
LIBSSH_VERS="$LIBSSH_LDFLAGS -Wl,--version-script,libssh.vers"
;;
esac
AC_ARG_WITH([versioned-symbol],
AC_HELP_STRING([--with-versioned-symbol],[Use versioned symbols]),
[if test "$withval" = "yes"; then
LIBSSH_VERS="$LIBSSH_LDFLAGS -Wl,--version-script,libssh.vers"
else
LIBSSH_VERS=""
fi], [ : ])
AC_SUBST(LIBSSH_VERS)
enable_ssh1=${enable_ssh1:-"no"}
AC_ARG_ENABLE(ssh1, AC_HELP_STRING([--enable-ssh1], [enable SSH1 support]))
AC_MSG_CHECKING([for SSH1 support])
if test "$enable_ssh1" = "yes" ; then
AC_DEFINE(HAVE_SSH1,1,[Define to 1 if you want to enable SSH1])
fi
AC_MSG_RESULT([$enable_ssh1])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL
AC_C_BIGENDIAN
AC_CHECK_PROG([DOXYGEN], [doxygen], [yes], [no])
AM_CONDITIONAL([HAS_DOXYGEN], [test x"$DOXYGEN" = xyes])
# Checks for libraries.
with_gcrypt=${with_gcrypt:-"no"}
AC_ARG_WITH([libgcrypt],
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt instead of libcrypto]),
[if test "$withval" = "yes"; then
with_gcrypt="yes"
AC_CHECK_LIB([gcrypt], [gcry_md_open])
fi], [ : ])
if test "$with_gcrypt" = "no"; then
AC_CHECK_LIB([crypto], [BN_init])
fi
AC_CHECK_LIB([z], [deflateInit_])
AC_SEARCH_LIBS([hstrerror],[nsl resolv])
AC_SEARCH_LIBS([getaddrinfo],[nsl socket])
AC_SEARCH_LIBS([gethostbyname],[nsl resolv])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h \
sys/time.h termios.h unistd.h openssl/aes.h openssl/blowfish.h \
openssl/des.h zlib.h sys/poll.h stdint.h pty.h gcrypt.h])
#Warn user when no openssl available
if test "$with_gcrypt" = "no" && (test "$ac_cv_header_openssl_aes_h" != "yes" ||
test "$ac_cv_header_openssl_blowfish_h" != "yes"); then
echo "Can't find valid openssl files [e.g openssl/aes.h]"
echo "Please install Openssl-devel"
exit
fi
#Warn user when no libgcrypt available
if test "$with_gcrypt" = "yes" && test "$ac_cv_header_gcrypt_h" != "yes"; then
echo "Can't find valid libgcrypt files [e.g gcrypt.h]"
echo "Please install libgcrypt-devel"
exit
fi
#if ! test x"$ac_cv_header_zlib_h" != x"yes"; then
# echo "Can't find zlib.h"
# echo "Compression support won't be compiled in"
#fi
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_HEADER_TIME
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_REALLOC
AC_FUNC_SELECT_ARGTYPES
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([endpwent getaddrinfo gethostbyname getpass memmove memset \
cfmakeraw select socket strchr strdup strerror strstr poll])
AC_CONFIG_FILES([Makefile
libssh/Makefile
include/Makefile
include/libssh/Makefile])
AC_OUTPUT

7
debian/README.Debian vendored Normal file
View File

@@ -0,0 +1,7 @@
libssh for Debian
----------------------
This is a package for the library libssh with the soname 2.
There are some other projects which have nearly the same name, so be careful.
-- Laurent Bigonville <bigon@bigon.be> Fri, 27 Jul 2007 14:59:00 +0200

50
debian/changelog vendored Normal file
View File

@@ -0,0 +1,50 @@
libssh (0.2+svn20070321-5) UNRELEASED; urgency=low
* NOT RELEASED YET
* Use now official Vcs-* field
* Use new Homepage field instead of old pseudo-field
* BumpStandards-Version to 3.7.3 (no further changes)
* debian/libssh-2-doc.doc-base: fix doc-base-unknown-section
-- Laurent Bigonville <bigon@bigon.be> Thu, 08 Nov 2007 05:59:18 +0100
libssh (0.2+svn20070321-4) unstable; urgency=low
* debian/control:
- Add XS-Vcs-Svn and XS-Vcs-Browser fields.
- Change to ${binary:Version} for versionized dependencies.
* Add debian/README.Debian to disambiguate the package name
-- Laurent Bigonville <bigon@bigon.be> Fri, 27 Jul 2007 15:00:06 +0200
libssh (0.2+svn20070321-3) unstable; urgency=low
* Fix wrong versionized Replaces for -doc package
-- Laurent Bigonville <bigon@bigon.be> Thu, 5 Apr 2007 17:58:27 +0200
libssh (0.2+svn20070321-2) unstable; urgency=low
* Split devel package into devel and documentation packages
-- Laurent Bigonville <bigon@bigon.be> Mon, 26 Mar 2007 15:29:51 +0200
libssh (0.2+svn20070321-1) unstable; urgency=low
* New svn snapshot:
- Fix broken include in include/libssh/server.h (Closes: #410020)
- Fix nasty bug in server side code
-- Laurent Bigonville <bigon@bigon.be> Mon, 26 Mar 2007 15:06:40 +0200
libssh (0.2-1) unstable; urgency=low
* New upstream release.
-- Laurent Bigonville <bigon@bigon.be> Fri, 29 Dec 2006 07:40:20 +0100
libssh (0.2~rc-1) unstable; urgency=low
* Initial release (Closes: #316872)
-- Jean-Philippe Garcia Ballester <giga@le-pec.org> Wed, 20 Dec 2006 23:56:50 +0100

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
5

65
debian/control vendored Normal file
View File

@@ -0,0 +1,65 @@
Source: libssh
Section: libs
Priority: optional
Maintainer: Jean-Philippe Garcia Ballester <giga@le-pec.org>
Uploaders: Laurent Bigonville <bigon@bigon.be>
Build-Depends: cdbs, debhelper (>= 5), libgcrypt11-dev, libz-dev, doxygen
Standards-Version: 3.7.3
Vcs-Svn: svn://svn.berlios.de/libssh/trunk
Vcs-Browser: http://svn.berlios.de/wsvn/libssh/trunk/
Homepage: http://0xbadc0de.be/wiki/doku.php?id=libssh:libssh
Package: libssh-2
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: A tiny C SSH library
The ssh library was designed to be used by programmers needing a working SSH
implementation by the mean of a library. The complete control of the client
is made by the programmer. With libssh, you can remotely execute programs,
transfer files, use a secure and transparent tunnel for your remote programs.
With its SFTP implementation, you can play with remote files easily.
Package: libssh-2-dev
Provides: libssh-dev
Section: libdevel
Architecture: any
Depends: libssh-2 (= ${binary:Version}), libgcrypt11-dev, zlib1g-dev
Suggests: libssh-2-doc
Conflicts: libssh-dev
Description: A tiny C SSH library. Development files
The ssh library was designed to be used by programmers needing a working SSH
implementation by the mean of a library. The complete control of the client
is made by the programmer. With libssh, you can remotely execute programs,
transfer files, use a secure and transparent tunnel for your remote programs.
With its SFTP implementation, you can play with remote files easily.
.
This package contains development files.
Package: libssh-2-dbg
Priority: extra
Section: libdevel
Architecture: any
Depends: libssh-2 (= ${binary:Version})
Description: A tiny C SSH library. Debug symbols
The ssh library was designed to be used by programmers needing a working SSH
implementation by the mean of a library. The complete control of the client
is made by the programmer. With libssh, you can remotely execute programs,
transfer files, use a secure and transparent tunnel for your remote programs.
With its SFTP implementation, you can play with remote files easily.
.
This package contains debug symbols.
Package: libssh-2-doc
Section: doc
Architecture: all
Suggests: doc-base
Replaces: libssh-2-dev (<< 0.2+svn20070321-2)
Description: A tiny C SSH library. Documentation files
The ssh library was designed to be used by programmers needing a working SSH
implementation by the mean of a library. The complete control of the client
is made by the programmer. With libssh, you can remotely execute programs,
transfer files, use a secure and transparent tunnel for your remote programs.
With its SFTP implementation, you can play with remote files easily.
.
This package contains documentation files.

33
debian/copyright vendored Normal file
View File

@@ -0,0 +1,33 @@
This package was debianized by Laurent Bigonville <bigon@bigon.be> on
Thu, 16 Nov 2006 20:34:01 +0100.
It was downloaded from http://www.0xbadc0de.be/
Upstream Author: Aris Adamantiadis (aka spacewalker) <aris@0xbadc0de.be>
Copyright: 2003 Aris Adamantiadis
License:
This package 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 of the License, or (at your option) any later version.
This package 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 package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU Lesser General
Public License can be found in `/usr/share/common-licenses/LGPL'.
The Debian packaging is
(C) 2005-2006, Jean-Philippe Garcia Ballester <giga@le-pec.org>,
(C) 2006-2007, Laurent Bigonville <bigon@bigon.be> and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.

2
debian/libssh-2-dev.install vendored Normal file
View File

@@ -0,0 +1,2 @@
debian/tmp/usr/include/*
debian/tmp/usr/lib/libssh.{a,la,so}

9
debian/libssh-2-doc.doc-base vendored Normal file
View File

@@ -0,0 +1,9 @@
Document: libssh
Title: Debian libssh Manual
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Abstract: This manual describes libssh API.
Section: Apps/Programming
Format: HTML
Index: /usr/share/doc/libssh-2-doc/html/index.html
Files: /usr/share/doc/libssh-2-doc/html/*

1
debian/libssh-2-doc.docs vendored Normal file
View File

@@ -0,0 +1 @@
debian/tmp/usr/share/doc/libssh/html

1
debian/libssh-2-doc.examples vendored Normal file
View File

@@ -0,0 +1 @@
debian/tmp/usr/share/doc/libssh/examples/*

1
debian/libssh-2-doc.manpages vendored Normal file
View File

@@ -0,0 +1 @@
doxygen/man/man3/ssh_*

1
debian/libssh-2.install vendored Normal file
View File

@@ -0,0 +1 @@
debian/tmp/usr/lib/libssh.so.*

2
debian/libssh-2.lintian-overrides vendored Normal file
View File

@@ -0,0 +1,2 @@
# We use libssh-2 name to avoid name clash with libssh2 package.
libssh-2: package-name-doesnt-match-sonames libssh2

21
debian/rules vendored Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/make -f
# Sample debian/rules that uses cdbs. Originaly written by Robert Millan.
# This file is public domain.
DEB_AUTO_CLEANUP_RCS := yes
# Add here any variable or target overrides you need
include /usr/share/cdbs/1/class/autotools.mk
include /usr/share/cdbs/1/rules/debhelper.mk
#include /usr/share/cdbs/1/rules/simple-patchsys.mk
DEB_CONFIGURE_EXTRA_FLAGS = --with-libgcrypt --enable-ssh1
DEB_DBG_PACKAGE_libssh-2 = libssh-2-dbg
install/libssh-2::
install -D -m 644 debian/libssh-2.lintian-overrides debian/libssh-2/usr/share/lintian/overrides/libssh-2
install/libssh-2-doc::
make install-doc DESTDIR=debian/tmp

2
debian/watch vendored Normal file
View File

@@ -0,0 +1,2 @@
version=3
http://0xbadc0de.be/libssh/libssh-(.*)\.tgz

View File

@@ -1,5 +0,0 @@
#
# Build the documentation
#
include(UseDoxygen OPTIONAL)

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
project(headers C)
add_subdirectory(libssh)

1
include/Makefile.am Normal file
View File

@@ -0,0 +1 @@
SUBDIRS = libssh

View File

@@ -1,38 +0,0 @@
project(libssh-headers C)
set(libssh_HDRS
libssh.h
crypto.h
ssh2.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
)

View File

@@ -0,0 +1,8 @@
libsshdir = $(includedir)/libssh
libssh_HEADERS = crypto.h libssh.h priv.h server.h sftp.h ssh1.h ssh2.h
nodist_libssh_HEADERS = config.h
config.h:
$(LN_S) $(top_builddir)/config.h ./config.h
DISTCLEANFILES = config.h

View File

@@ -1,49 +0,0 @@
#ifndef __AGENT_H
#define __AGENT_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
#endif /* __AGENT_H */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,43 +1,44 @@
/*
* 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.
*/
Copyright 2003 Aris Adamantiadis
/*
* crypto.h is an include file for internal structures of libssh
* It hasn't to be into the final development set of files (and btw
* the filename would cause problems on most systems).
*/
This file is part of the SSH Library
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. */
/* Crypto.h is an include file for internal structures of libssh */
/* It hasn't to be into the final development set of files (and btw the filename would cause problems on most systems) */
/* Openssl has (really) stupid defines */
#ifdef set_key
#undef set_key
#endif
#ifdef cbc_encrypt
#undef cbc_encrypt
#endif
#ifdef cbc_decrypt
#undef cbc_decrypt
#endif
#ifdef des_set_key
#undef des_set_key
#endif
#ifdef GCRYPT
#include <gcrypt.h>
#endif
struct crypto_struct {
const char *name; /* ssh name of the algorithm */
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
@@ -47,22 +48,15 @@ struct crypto_struct {
#endif
unsigned int keysize; /* bytes of key used. != keylen */
#ifdef HAVE_LIBGCRYPT
/* sets the new key for immediate use */
int (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
int (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,
unsigned long len);
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,
unsigned long len);
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV); /* sets the new key for immediate use */
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
#elif defined HAVE_LIBCRYPTO
/* sets the new key for immediate use */
int (*set_encrypt_key)(struct crypto_struct *cipher, void *key);
int (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,
unsigned long len, void *IV);
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,
unsigned long len, void *IV);
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key); /* sets the new key for immediate use */
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
#endif
};
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,71 +1,46 @@
/*
* 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.
*/
Copyright (c) 2003-2008 Aris Adamantiadis
This file is part of the SSH Library
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 _LIBSSH_H
#define _LIBSSH_H
#ifndef _MSC_VER
#include <unistd.h>
#include <inttypes.h>
#else /* _MSC_VER */
#else
//visual studio hasn't inttypes.h so it doesn't know uint32_t
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef unsigned long long uint64_t;
#endif /* _MSC_VER */
#ifdef _WIN32
#include <winsock2.h>
#else
#endif
#ifndef _WIN32
#include <sys/select.h> /* for fd_set * */
#include <netdb.h>
#endif /* _WIN32 */
#endif
#ifdef _WIN32
#include <winsock2.h>
#endif
#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 3
#define LIBSSH_VERSION_MICRO 4
#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__ */
#define LIBSSH_VERSION "libssh-0.2.1-svn"
#ifdef __cplusplus
extern "C" {
@@ -77,7 +52,6 @@ typedef struct public_key_struct PUBLIC_KEY;
typedef struct private_key_struct PRIVATE_KEY;
typedef struct ssh_options_struct SSH_OPTIONS;
typedef struct channel_struct CHANNEL;
typedef struct agent_struct AGENT;
typedef struct ssh_session SSH_SESSION;
typedef struct ssh_kbdint SSH_KBDINT;
@@ -133,7 +107,6 @@ typedef int socket_t;
#define SSH_SERVER_KNOWN_OK 1
#define SSH_SERVER_KNOWN_CHANGED 2
#define SSH_SERVER_FOUND_OTHER 3
#define SSH_SERVER_FILE_NOT_FOUND 4
#ifndef MD5_DIGEST_LEN
#define MD5_DIGEST_LEN 16
@@ -145,18 +118,15 @@ typedef int socket_t;
#define SSH_FATAL 2
#define SSH_EINTR 3
/* Error return codes */
/* 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 */
#define SSH_ERROR -1 /* error of some kind */
#define SSH_AGAIN 1 /* the nonblocking call must be repeated */
const char *ssh_get_error(void *error);
char *ssh_get_error(void *error);
int ssh_get_error_code(void *error);
/* version checks */
const char *ssh_version(int req_version);
void ssh_say(int priority, const char *format, ...);
void ssh_set_verbosity(int num);
/** \addtogroup ssh_log
* @{
*/
@@ -189,41 +159,36 @@ enum {
#define SSH_LOG_FUNCTIONS 4 // every function in and return
*/
/* log.c */
void ssh_log(SSH_SESSION *session, int prioriry, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
void ssh_log(SSH_SESSION *session, int prioriry, char *format, ...);
/* session.c */
SSH_SESSION *ssh_new(void);
socket_t ssh_get_fd(SSH_SESSION *session);
int ssh_get_version(SSH_SESSION *session);
int ssh_get_status(SSH_SESSION *session);
const char *ssh_get_disconnect_message(SSH_SESSION *session);
SSH_SESSION *ssh_new();
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options);
socket_t ssh_get_fd(SSH_SESSION *session);
void ssh_silent_disconnect(SSH_SESSION *session);
int ssh_get_version(SSH_SESSION *session);
void ssh_set_fd_toread(SSH_SESSION *session);
void ssh_set_fd_towrite(SSH_SESSION *session);
void ssh_set_fd_except(SSH_SESSION *session);
void ssh_set_blocking(SSH_SESSION *session, int blocking);
void ssh_silent_disconnect(SSH_SESSION *session);
/* client.c */
int ssh_connect(SSH_SESSION *session);
void ssh_disconnect(SSH_SESSION *session);
int ssh_service_request(SSH_SESSION *session, const char *service);
int ssh_service_request(SSH_SESSION *session,char *service);
char *ssh_get_issue_banner(SSH_SESSION *session);
int ssh_get_openssh_version(SSH_SESSION *session);
/* get copyright informations */
const char *ssh_copyright(void);
const char *ssh_copyright();
/* string.h */
/* You can use these functions, they won't change */
/* string_from_char returns a newly allocated string from a char *ptr */
/* makestring returns a newly allocated string from a char * ptr */
STRING *string_from_char(const char *what);
/* it returns the string len in host byte orders. str->size is big endian warning ! */
size_t string_len(STRING *str);
STRING *string_new(size_t size);
/* string_fill copies the data in the string. */
int string_fill(STRING *str, const void *data, size_t len);
int string_len(STRING *str);
STRING *string_new(unsigned int size);
/* string_fill copies the data in the string. it does NOT check for boundary so allocate enough place with string_new */
void string_fill(STRING *str, const void *data,int len);
/* returns a newly allocated char array with the str string and a final nul caracter */
char *string_to_char(STRING *str);
STRING *string_copy(STRING *str);
@@ -232,127 +197,99 @@ void string_burn(STRING *str);
void *string_data(STRING *str);
void string_free(STRING *str);
/* deprecated */
void ssh_crypto_init();
/* useful for debug */
char *ssh_get_hexa(const unsigned char *what, size_t len);
void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
void ssh_print_hexa(char *descr, const unsigned char *what, int len);
int ssh_get_random(void *where,int len,int strong);
/* this one can be called by the client to see the hash of the public key before accepting it */
int ssh_get_pubkey_hash(SSH_SESSION *session, unsigned char **hash);
int ssh_get_pubkey_hash(SSH_SESSION *session,unsigned char hash[MD5_DIGEST_LEN]);
STRING *ssh_get_pubkey(SSH_SESSION *session);
/* in connect.c */
int ssh_fd_poll(SSH_SESSION *session,int *write, int *except);
int ssh_select(CHANNEL **channels, CHANNEL **outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout);
int ssh_select(CHANNEL **channels,CHANNEL **outchannels, socket_t maxfd, fd_set *readfds, struct timeval *timeout);
void publickey_free(PUBLIC_KEY *key);
/* in keyfiles.c */
PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session, const char *filename,
int type, const char *passphrase);
PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,char *passphrase);
STRING *publickey_to_string(PUBLIC_KEY *key);
PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv);
void privatekey_free(PRIVATE_KEY *prv);
STRING *publickey_from_file(SSH_SESSION *session, const char *filename,
int *type);
void private_key_free(PRIVATE_KEY *prv);
STRING *publickey_from_file(SSH_SESSION *session, char *filename,int *_type);
STRING *publickey_from_next_file(SSH_SESSION *session,char **pub_keys_path,char **keys_path,
char **privkeyfile,int *type,int *count);
int ssh_is_server_known(SSH_SESSION *session);
int ssh_write_knownhost(SSH_SESSION *session);
/* in channels.c */
CHANNEL *channel_new(SSH_SESSION *session);
int channel_open_forward(CHANNEL *channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
int channel_open_forward(CHANNEL *channel,char *remotehost, int remoteport, char *sourcehost, int localport);
int channel_open_session(CHANNEL *channel);
void channel_free(CHANNEL *channel);
int channel_request_pty(CHANNEL *channel);
int channel_request_pty_size(CHANNEL *channel, const char *term,
int cols, int rows);
int channel_request_pty_size(CHANNEL *channel, char *term,int cols, int rows);
int channel_change_pty_size(CHANNEL *channel,int cols,int rows);
int channel_request_shell(CHANNEL *channel);
int channel_request_subsystem(CHANNEL *channel, const char *system);
int channel_request_env(CHANNEL *channel, const char *name, const char *value);
int channel_request_exec(CHANNEL *channel, const char *cmd);
int channel_request_subsystem(CHANNEL *channel, char *system);
int channel_request_env(CHANNEL *channel,char *name, char *value);
int channel_request_exec(CHANNEL *channel, char *cmd);
int channel_request_sftp(CHANNEL *channel);
int channel_write(CHANNEL *channel, const void *data, u32 len);
int channel_write(CHANNEL *channel,void *data,int len);
int channel_send_eof(CHANNEL *channel);
int channel_is_eof(CHANNEL *channel);
int channel_read(CHANNEL *channel, void *dest, u32 count, int is_stderr);
int channel_read_buffer(CHANNEL *channel, BUFFER *buffer, u32 count,
int is_stderr);
int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr);
int channel_poll(CHANNEL *channel, int is_stderr);
int channel_close(CHANNEL *channel);
void channel_set_blocking(CHANNEL *channel, int blocking);
int channel_read_nonblocking(CHANNEL *channel, void *dest, u32 count,
int is_stderr);
int channel_read_nonblocking(CHANNEL *channel, char *dest, int len, int is_stderr);
int channel_is_open(CHANNEL *channel);
int channel_is_closed(CHANNEL *channel);
int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptchans, struct
timeval * timeout);
SSH_SESSION *channel_get_session(CHANNEL *channel);
int channel_get_exit_status(CHANNEL *channel);
/* in options.c */
/**
* @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);
SSH_OPTIONS *ssh_options_new(void);
SSH_OPTIONS *ssh_options_new();
SSH_OPTIONS *ssh_options_copy(SSH_OPTIONS *opt);
void ssh_options_free(SSH_OPTIONS *opt);
int ssh_options_set_wanted_algos(SSH_OPTIONS *opt, int algo, const char *list);
int ssh_options_set_username(SSH_OPTIONS *opt, const char *username);
int ssh_options_set_port(SSH_OPTIONS *opt, unsigned int port);
void ssh_options_set_username(SSH_OPTIONS *opt, const char *username);
void ssh_options_set_port(SSH_OPTIONS *opt, unsigned int port);
int ssh_options_getopt(SSH_OPTIONS *options, int *argcptr, char **argv);
int ssh_options_set_host(SSH_OPTIONS *opt, const char *host);
int ssh_options_set_fd(SSH_OPTIONS *opt, socket_t fd);
int ssh_options_set_bind(SSH_OPTIONS *opt, const char *bindaddr, int port);
int ssh_options_set_ssh_dir(SSH_OPTIONS *opt, const char *dir);
int ssh_options_set_known_hosts_file(SSH_OPTIONS *opt, const char *dir);
int ssh_options_set_identity(SSH_OPTIONS *opt, const char *identity);
int ssh_options_set_banner(SSH_OPTIONS *opt, const char *banner);
int ssh_options_set_status_callback(SSH_OPTIONS *opt, void (*callback)
void ssh_options_set_host(SSH_OPTIONS *opt, const char *host);
void ssh_options_set_fd(SSH_OPTIONS *opt, socket_t fd);
void ssh_options_set_bind(SSH_OPTIONS *opt, const char *bindaddr, int port);
void ssh_options_set_identity(SSH_OPTIONS *opt, const char *identity);
void ssh_options_set_status_callback(SSH_OPTIONS *opt, void (*callback)
(void *arg, float status), void *arg);
int ssh_options_set_timeout(SSH_OPTIONS *opt, long seconds, long usec);
int ssh_options_allow_ssh1(SSH_OPTIONS *opt, int allow);
int ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow);
int ssh_options_set_log_function(SSH_OPTIONS *opt,
void (*callback)(const char *message, SSH_SESSION *session, int verbosity));
int ssh_options_set_log_verbosity(SSH_OPTIONS *opt, int verbosity);
int ssh_options_set_dsa_server_key(SSH_OPTIONS *opt, const char *dsakey);
int ssh_options_set_rsa_server_key(SSH_OPTIONS *opt, const char *rsakey);
int ssh_options_set_auth_callback(SSH_OPTIONS *opt, ssh_auth_callback cb,
void *userdata);
void ssh_options_set_timeout(SSH_OPTIONS *opt, long seconds, long usec);
void ssh_options_set_ssh_dir(SSH_OPTIONS *opt, const char *dir);
void ssh_options_set_known_hosts_file(SSH_OPTIONS *opt, const char *dir);
void ssh_options_allow_ssh1(SSH_OPTIONS *opt, int allow);
void ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow);
void ssh_options_set_dsa_server_key(SSH_OPTIONS *opt, const char *dsakey);
void ssh_options_set_rsa_server_key(SSH_OPTIONS *opt, const char *rsakey);
void ssh_options_set_log_function(SSH_OPTIONS *opt,
void (*callback)(const char *message, SSH_SESSION *session, int verbosity ));
void ssh_options_set_log_verbosity(SSH_OPTIONS *opt, int verbosity);
/* buffer.c */
/** creates a new buffer
*/
BUFFER *buffer_new(void);
BUFFER *buffer_new();
void buffer_free(BUFFER *buffer);
/* buffer_get returns a pointer to the begining of the buffer. no position is taken into account */
void *buffer_get(BUFFER *buffer);
/* same here */
u32 buffer_get_len(BUFFER *buffer);
int buffer_get_len(BUFFER *buffer);
/* in auth.c */
int ssh_auth_list(SSH_SESSION *session);
/* these functions returns AUTH_ERROR is some serious error has happened,
AUTH_SUCCESS if success,
AUTH_PARTIAL if partial success,
@@ -362,28 +299,18 @@ int ssh_userauth_none(SSH_SESSION *session, const char *username);
int ssh_userauth_password(SSH_SESSION *session, const char *username, const char *password);
int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username, int type, STRING *publickey);
int ssh_userauth_pubkey(SSH_SESSION *session, const char *username, STRING *publickey, PRIVATE_KEY *privatekey);
int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username,
PUBLIC_KEY *publickey);
int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase);
int ssh_userauth_autopubkey(SSH_SESSION *session);
int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, const char *submethods);
int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session);
const char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
const char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i, char *echo);
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
const char *answer);
char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, int i, char *echo);
void ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i, const char *answer);
/* misc.c */
int ssh_mkdir (const char *pathname, mode_t mode);
char *ssh_dirname (const char *path);
char *ssh_basename (const char *path);
/* init.c */
int ssh_init(void);
int ssh_finalize(void);
int ssh_finalize();
#ifdef __cplusplus
}
}
#endif
#endif /* _LIBSSH_H */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,31 +1,27 @@
/*
* 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.
*/
Copyright (c) 2003-2008 Aris Adamantiadis
/*
* 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
*/
This file is part of the SSH Library
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. */
/* 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
@@ -41,8 +37,8 @@
/* some constants */
#define MAX_PACKET_LEN 262144
#define ERROR_BUFFERLEN 1024
#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
#define CLIENTBANNER1 "SSH-1.5-" LIBSSH_VERSION
#define CLIENTBANNER2 "SSH-2.0-" LIBSSH_VERSION
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
/* some types for public keys */
#define TYPE_DSS 1
@@ -133,28 +129,6 @@ typedef BN_CTX* bignum_CTX;
#include <sys/time.h>
#endif
/* poll support */
#ifdef HAVE_POLL
#include <poll.h>
typedef struct pollfd pollfd_t;
#else /* HAVE_POLL */
typedef struct pollfd_s {
socket_t fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
} pollfd_t;
#define POLLIN 0x001 /* There is data to read. */
#define POLLPRI 0x002 /* There is urgent data to read. */
#define POLLOUT 0x004 /* Writing now will not block. */
#define POLLERR 0x008 /* Error condition. */
#define POLLHUP 0x010 /* Hung up. */
#define POLLNVAL 0x020 /* Invalid polling request. */
typedef unsigned long int nfds_t;
#endif /* HAVE_POLL */
/* wrapper.c */
MD5CTX md5_init(void);
void md5_update(MD5CTX c, const void *data, unsigned long len);
@@ -174,19 +148,15 @@ void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
struct string_struct {
u32 size;
unsigned char string[MAX_PACKET_LEN];
}
#if !defined(__SUNPRO_C)
__attribute__ ((packed))
#endif
;
} __attribute__ ((packed));
/** Describes a buffer state at a moment
*/
struct buffer_struct {
char *data;
u32 used;
u32 allocated;
u32 pos;
int used;
int allocated;
int pos;
};
/* i should remove it one day */
@@ -203,7 +173,7 @@ typedef struct kex_struct {
struct public_key_struct {
int type;
const char *type_c; /* Don't free it ! it is static */
char *type_c; /* Don't free it ! it is static */
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa_pub;
gcry_sexp_t rsa_pub;
@@ -238,7 +208,7 @@ typedef struct signature_struct {
struct error_struct {
/* error handling */
unsigned int error_code;
int error_code;
char error_buffer[ERROR_BUFFERLEN];
};
@@ -258,8 +228,7 @@ struct ssh_options_struct {
int use_nonexisting_algo; /* if user sets a not supported algorithm for kex, don't complain */
char *wanted_methods[10]; /* the kex methods can be choosed. better use the kex fonctions to do that */
void *wanted_cookie; /* wants a specific cookie to be sent ? if null, generate a new one */
ssh_auth_callback auth_function; /* this functions will be called if e.g. a keyphrase is needed. */
void *auth_userdata;
void *passphrase_function; /* this functions will be called if a keyphrase is needed. look keyfiles.c for more info */
void (*connect_status_function)(void *arg, float status); /* status callback function */
void *connect_status_arg; /* arbitrary argument */
long timeout; /* seconds */
@@ -275,7 +244,7 @@ struct ssh_options_struct {
typedef struct ssh_crypto_struct {
bignum e,f,x,k,y;
unsigned char session_id[SHA_DIGEST_LEN];
unsigned char encryptIV[SHA_DIGEST_LEN*2];
unsigned char decryptIV[SHA_DIGEST_LEN*2];
@@ -287,7 +256,7 @@ typedef struct ssh_crypto_struct {
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
struct crypto_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
STRING *server_pubkey;
const char *server_pubkey_type;
char *server_pubkey_type;
int do_compress_out; /* idem */
int do_compress_in; /* don't set them, set the option instead */
void *compress_out_ctx; /* don't touch it */
@@ -314,18 +283,6 @@ struct channel_struct {
void *userarg;
int version;
int blocking;
int exit_status;
};
struct agent_struct {
struct socket *sock;
BUFFER *ident;
unsigned int count;
};
struct keys_struct {
const char *privatekey;
const char *publickey;
};
struct ssh_session {
@@ -337,38 +294,37 @@ struct ssh_session {
int protoversion;
int server;
int client;
int openssh;
u32 send_seq;
u32 recv_seq;
/* status flags */
int closed;
int closed_by_except;
int connected;
int connected;
/* !=0 when the user got a session handle */
int alive;
/* two previous are deprecated */
int auth_service_asked;
/* socket status */
int blocking; // functions should block
STRING *banner; /* that's the issue banner from
STRING *banner; /* that's the issue banner from
the server */
char *remotebanner; /* that's the SSH- banner from
remote host. */
char *discon_msg; /* disconnect message from
char *discon_msg; /* disconnect message from
the remote host */
BUFFER *in_buffer;
PACKET in_packet;
BUFFER *out_buffer;
/* the states are used by the nonblocking stuff to remember */
/* where it was before being interrupted */
int packet_state;
int dh_handshake_state;
STRING *dh_server_signature; //information used by dh_handshake.
KEX server_kex;
KEX client_kex;
BUFFER *in_hashbuf;
@@ -378,9 +334,8 @@ struct ssh_session {
CHANNEL *channels; /* linked list of channels */
int maxchannel;
int exec_channel_opened; /* version 1 only. more
int exec_channel_opened; /* version 1 only. more
info in channels1.c */
AGENT *agent; /* ssh agent */
/* keyb interactive data */
struct ssh_kbdint *kbdint;
@@ -389,7 +344,7 @@ struct ssh_session {
PRIVATE_KEY *rsa_key;
PRIVATE_KEY *dsa_key;
/* auths accepted by server */
int auth_methods;
int auth_methods;
int hostkeys; /* contains type of host key wanted by client, in server impl */
struct ssh_message *ssh_message; /* ssh message */
int log_verbosity; /*cached copy of the option structure */
@@ -443,7 +398,7 @@ struct ssh_channel_request {
u32 pxwidth;
u32 pxheight;
STRING *modes;
/* env type request */
char *var_name;
char *var_value;
@@ -461,72 +416,25 @@ struct ssh_message {
struct ssh_channel_request channel_request;
};
#ifndef _WIN32
/* agent.c */
/**
* @brief Create a new ssh agent structure.
*
* @return An allocated ssh agent structure or NULL on error.
*/
struct agent_struct *agent_new(struct ssh_session *session);
void agent_close(struct agent_struct *agent);
/**
* @brief Free an allocated ssh agent structure.
*
* @param agent The ssh agent structure to free.
*/
void agent_free(struct 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 *session);
int agent_get_ident_count(struct ssh_session *session);
struct public_key_struct *agent_get_next_ident(struct ssh_session *session,
char **comment);
struct public_key_struct *agent_get_first_ident(struct ssh_session *session,
char **comment);
STRING *agent_sign_data(struct ssh_session *session,
struct buffer_struct *data,
struct public_key_struct *pubkey);
#endif
/* poll.c */
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout);
/* socket.c */
struct socket;
int ssh_socket_init(void);
void ssh_socket_init();
struct socket *ssh_socket_new(SSH_SESSION *session);
void ssh_socket_free(struct socket *s);
void ssh_socket_set_fd(struct socket *s, socket_t fd);
socket_t ssh_socket_get_fd(struct socket *s);
#ifndef _WIN32
int ssh_socket_unix(struct socket *s, const char *path);
#endif
void ssh_socket_close(struct socket *s);
int ssh_socket_read(struct socket *s, void *buffer, int len);
int ssh_socket_write(struct socket *s,const void *buffer, int len);
int ssh_socket_is_open(struct socket *s);
int ssh_socket_fd_isset(struct socket *s, fd_set *set);
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max);
int ssh_socket_completeread(struct socket *s, void *buffer, u32 len);
int ssh_socket_completewrite(struct socket *s, const void *buffer, u32 len);
int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session, u32 len);
int ssh_socket_completeread(struct socket *s, void *buffer, int len);
int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len);
int ssh_socket_nonblocking_flush(struct socket *s);
int ssh_socket_blocking_flush(struct socket *s);
int ssh_socket_poll(struct socket *s, int *writeable, int *except);
int ssh_socket_poll(struct socket *s, int *write, int *except);
void ssh_socket_set_towrite(struct socket *s);
void ssh_socket_set_toread(struct socket *s);
void ssh_socket_set_except(struct socket *s);
@@ -543,30 +451,27 @@ int ssh_send_banner(SSH_SESSION *session, int is_server);
char *ssh_get_banner(SSH_SESSION *session);
/* errors.c */
void ssh_set_error(void *error, int code, const char *descr, ...) PRINTF_ATTRIBUTE(3, 4);
void ssh_set_error(void *error,int code,char *descr,...);
/* in dh.c */
/* DH key generation */
void ssh_print_bignum(const char *which,bignum num);
int dh_generate_e(SSH_SESSION *session);
int dh_generate_f(SSH_SESSION *session);
int dh_generate_x(SSH_SESSION *session);
int dh_generate_y(SSH_SESSION *session);
int ssh_crypto_init(void);
void ssh_crypto_finalize(void);
void dh_generate_e(SSH_SESSION *session);
void ssh_print_bignum(char *which,bignum num);
void dh_generate_x(SSH_SESSION *session);
void dh_generate_y(SSH_SESSION *session);
void dh_generate_f(SSH_SESSION *session);
void ssh_crypto_finalize();
STRING *dh_get_e(SSH_SESSION *session);
STRING *dh_get_f(SSH_SESSION *session);
int dh_import_f(SSH_SESSION *session,STRING *f_string);
int dh_import_e(SSH_SESSION *session, STRING *e_string);
void dh_import_f(SSH_SESSION *session,STRING *f_string);
void dh_import_e(SSH_SESSION *session, STRING *e_string);
void dh_import_pubkey(SSH_SESSION *session,STRING *pubkey_string);
int dh_build_k(SSH_SESSION *session);
int make_sessionid(SSH_SESSION *session);
void dh_build_k(SSH_SESSION *session);
void 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);
void hashbufin_add_cookie(SSH_SESSION *session,unsigned char *cookie);
void hashbufout_add_cookie(SSH_SESSION *session);
void generate_session_keys(SSH_SESSION *session);
/* returns 1 if server signature ok, 0 otherwise. The NEXT crypto is checked, not the current one */
int signature_verify(SSH_SESSION *session,STRING *signature);
bignum make_string_bn(STRING *string);
@@ -590,13 +495,13 @@ int packet_wait(SSH_SESSION *session,int type,int blocking);
int packet_flush(SSH_SESSION *session, int enforce_blocking);
/* connect.c */
SSH_SESSION *ssh_session_new();
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,const char
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,const char
*bind_addr, int port, long timeout, long usec);
/* in kex.c */
extern const char *ssh_kex_nums[];
int ssh_send_kex(SSH_SESSION *session, int server_kex);
void ssh_list_kex(SSH_SESSION *session, KEX *kex);
extern char *ssh_kex_nums[];
void ssh_send_kex(SSH_SESSION *session,int server_kex);
void ssh_list_kex(KEX *kex);
int set_kex(SSH_SESSION *session);
int ssh_get_kex(SSH_SESSION *session, int server_kex);
int verify_existing_algo(int algo, const char *name);
@@ -606,79 +511,67 @@ char *ssh_find_matching(const char *in_d, const char *what_d);
/* in keyfiles.c */
PRIVATE_KEY *_privatekey_from_file(void *session, const char *filename,
int type);
STRING *try_publickey_from_file(SSH_SESSION *session,
struct keys_struct keytab,
char **privkeyfile, int *type);
PRIVATE_KEY *_privatekey_from_file(void *session,char *filename,int type);
/* in keys.c */
const char *ssh_type_to_char(int type);
int ssh_type_from_name(const char *name);
PRIVATE_KEY *privatekey_make_dss(SSH_SESSION *session, BUFFER *buffer);
PRIVATE_KEY *privatekey_make_rsa(SSH_SESSION *session, BUFFER *buffer,
const char *type);
PRIVATE_KEY *privatekey_from_string(SSH_SESSION *session, STRING *privkey_s);
char *ssh_type_to_char(int type);
PUBLIC_KEY *publickey_make_dss(SSH_SESSION *session, BUFFER *buffer);
PUBLIC_KEY *publickey_make_rsa(SSH_SESSION *session, BUFFER *buffer, int type);
PUBLIC_KEY *publickey_make_rsa(SSH_SESSION *session, BUFFER *buffer,char *type);
PUBLIC_KEY *publickey_from_string(SSH_SESSION *session, STRING *pubkey_s);
SIGNATURE *signature_from_string(SSH_SESSION *session, STRING *signature,PUBLIC_KEY *pubkey,int needed_type);
void signature_free(SIGNATURE *sign);
STRING *ssh_do_sign_with_agent(struct ssh_session *session,
struct buffer_struct *buf, struct public_key_struct *publickey);
STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf,
STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf,
PRIVATE_KEY *privatekey);
STRING *ssh_sign_session_id(SSH_SESSION *session, PRIVATE_KEY *privatekey);
STRING *ssh_encrypt_rsa1(SSH_SESSION *session, STRING *data, PUBLIC_KEY *key);
/* channel.c */
void channel_handle(SSH_SESSION *session, int type);
CHANNEL *channel_new(SSH_SESSION *session);
int channel_default_bufferize(CHANNEL *channel, void *data, int len,
void channel_default_bufferize(CHANNEL *channel, void *data, int len,
int is_stderr);
u32 ssh_channel_new_id(SSH_SESSION *session);
CHANNEL *ssh_channel_from_local(SSH_SESSION *session, u32 id);
CHANNEL *ssh_channel_from_local(SSH_SESSION *session,u32 num);
/* options.c */
void ssh_options_free(SSH_OPTIONS *opt);
/* this function must be called when no specific username has been asked. it has to guess it */
int ssh_options_default_username(SSH_OPTIONS *opt);
int ssh_options_default_ssh_dir(SSH_OPTIONS *opt);
int ssh_options_default_known_hosts_file(SSH_OPTIONS *opt);
/* buffer.c */
int buffer_add_ssh_string(BUFFER *buffer, STRING *string);
int buffer_add_u8(BUFFER *buffer, u8 data);
int buffer_add_u32(BUFFER *buffer, u32 data);
int buffer_add_u64(BUFFER *buffer, u64 data);
int buffer_add_data(BUFFER *buffer, const void *data, u32 len);
int buffer_prepend_data(BUFFER *buffer, const void *data, u32 len);
int buffer_add_buffer(BUFFER *buffer, BUFFER *source);
int buffer_reinit(BUFFER *buffer);
void buffer_add_ssh_string(BUFFER *buffer,STRING *string);
void buffer_add_u8(BUFFER *buffer, u8 data);
void buffer_add_u32(BUFFER *buffer, u32 data);
void buffer_add_u64(BUFFER *buffer,u64 data);
void buffer_add_data(BUFFER *buffer,const void *data, int len);
void buffer_add_data_begin(BUFFER *buffer,const void *data,int len);
void buffer_add_buffer(BUFFER *buffer, BUFFER *source);
void buffer_reinit(BUFFER *buffer);
/* buffer_get_rest returns a pointer to the current position into the buffer */
void *buffer_get_rest(BUFFER *buffer);
/* buffer_get_rest_len returns the number of bytes which can be read */
u32 buffer_get_rest_len(BUFFER *buffer);
int buffer_get_rest_len(BUFFER *buffer);
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
int buffer_get_u8(BUFFER *buffer, u8 *data);
int buffer_get_u32(BUFFER *buffer, u32 *data);
int buffer_get_u8(BUFFER *buffer,u8 *data);
int buffer_get_u32(BUFFER *buffer,u32 *data);
int buffer_get_u64(BUFFER *buffer, u64 *data);
u32 buffer_get_data(BUFFER *buffer, void *data, u32 requestedlen);
int buffer_get_data(BUFFER *buffer,void *data,int requestedlen);
/* buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
STRING *buffer_get_ssh_string(BUFFER *buffer);
/* gets a string out of a SSH-1 mpint */
STRING *buffer_get_mpint(BUFFER *buffer);
/* buffer_pass_bytes acts as if len bytes have been read (used for padding) */
u32 buffer_pass_bytes_end(BUFFER *buffer, u32 len);
u32 buffer_pass_bytes(BUFFER *buffer, u32 len);
int buffer_pass_bytes_end(BUFFER *buffer,int len);
int buffer_pass_bytes(BUFFER *buffer, int len);
/* in base64.c */
BUFFER *base64_to_bin(const char *source);
unsigned char *bin_to_base64(const unsigned char *source, int len);
BUFFER *base64_to_bin(char *source);
unsigned char *bin_to_base64(unsigned char *source, int len);
/* gzip.c */
int compress_buffer(SSH_SESSION *session,BUFFER *buf);
@@ -687,22 +580,22 @@ int decompress_buffer(SSH_SESSION *session,BUFFER *buf);
/* wrapper.c */
int crypt_set_algorithms(SSH_SESSION *);
int crypt_set_algorithms_server(SSH_SESSION *session);
CRYPTO *crypto_new(void);
CRYPTO *crypto_new();
void crypto_free(CRYPTO *crypto);
/* crc32.c */
u32 ssh_crc32(const char *buf, u32 len);
u32 ssh_crc32(char *buffer, int len);
/* auth1.c */
int ssh_userauth1_none(SSH_SESSION *session, const char *username);
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
int ssh_userauth1_none(SSH_SESSION *session, char *username);
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, char *username,
int type, STRING *pubkey);
int ssh_userauth1_password(SSH_SESSION *session, const char *username,
const char *password);
int ssh_userauth1_password(SSH_SESSION *session, char *username,
char *password);
/* in misc.c */
/* gets the user home dir. */
char *ssh_get_user_home_dir(void);
int ssh_file_readaccess_ok(const char *file);
char *ssh_get_user_home_dir();
int ssh_file_readaccess_ok(char *file);
/* macro for byte ordering */
u64 ntohll(u64);
@@ -710,29 +603,20 @@ u64 ntohll(u64);
/* channels1.c */
int channel_open_session1(CHANNEL *channel);
int channel_request_pty_size1(CHANNEL *channel, const char *terminal,
int cols, int rows);
int channel_request_pty_size1(CHANNEL *channel, char *terminal,int cols,
int rows);
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows);
int channel_request_shell1(CHANNEL *channel);
int channel_request_exec1(CHANNEL *channel, const char *cmd);
int channel_handle1(SSH_SESSION *session, int type);
int channel_write1(CHANNEL *channel, const void *data, int len);
int channel_request_exec1(CHANNEL *channel, char *cmd);
void channel_handle1(SSH_SESSION *session,int type);
int channel_write1(CHANNEL *channel, void *data, int len);
/* session.c */
int ssh_handle_packets(SSH_SESSION *session);
/* match.c */
int match_hostname(const char *host, const char *pattern, unsigned int len);
/* log.c */
#ifndef __FUNCTION__
#if defined(__SUNPRO_C)
#define __FUNCTION__ __func__
#endif
#endif
#define _enter_function(sess) \
do {\
if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \
@@ -752,21 +636,6 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
#define enter_function() _enter_function(session)
#define leave_function() _leave_function(session)
/** Free memory space */
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
/** Zero a structure */
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
/** Zero a structure given a pointer to the structure */
#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
/** Get the size of an array */
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
/** Overwrite the complete string with 'X' */
#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0)
#ifdef HAVE_LIBGCRYPT
/* gcrypt_missing.c */
int my_gcry_dec2bn(bignum *bn, const char *data);
@@ -774,8 +643,7 @@ char *my_gcry_bn2dec(bignum bn);
#endif /* !HAVE_LIBGCRYPT */
#ifdef __cplusplus
}
}
#endif
#endif /* _LIBSSH_PRIV_H */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,29 +1,22 @@
/*
* 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.
*/
Copyright 2004 Aris Adamantiadis
/**
* @defgroup ssh_server SSH Server
* @addtogroup ssh_server
* @{
*/
This file is part of the SSH Library
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 SERVER_H
#define SERVER_H
@@ -37,88 +30,14 @@ extern "C" {
typedef struct ssh_bind_struct SSH_BIND;
/**
* @brief Creates a new SSH server bind.
*
* @return A newly allocated ssh_bind session pointer.
*/
SSH_BIND *ssh_bind_new(void);
/**
* @brief Set the opitons for the current SSH server bind.
*
* @param ssh_bind The ssh server bind to use.
*
* @param options The option structure to set.
*/
SSH_BIND *ssh_bind_new();
void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options);
/**
* @brief Start listening to the socket.
*
* @param ssh_bind The ssh server bind to use.
*
* @return 0 on success, < 0 on error.
*/
int ssh_bind_listen(SSH_BIND *ssh_bind);
/**
* @brief Set the session to blocking/nonblocking mode.
*
* @param ssh_bind The ssh server bind to use.
*
* @param blocking Zero for nonblocking mode.
*/
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking);
/**
* @brief Recover the file descriptor from the session.
*
* @param ssh_bind The ssh server bind to get the fd from.
*
* @return The file descriptor.
*/
socket_t ssh_bind_get_fd(SSH_BIND *ssh_bind);
/**
* @brief Set the file descriptor for a session.
*
* @param ssh_bind The ssh server bind to set the fd.
*
* @param fd The file descriptor.
*/
void ssh_bind_set_fd(SSH_BIND *ssh_bind, socket_t fd);
/**
* @brief Allow the file descriptor to accept new sessions.
*
* @param ssh_bind The ssh server bind to use.
*/
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind);
/**
* @brief Accept an incoming ssh connection and initialize the session.
*
* @param ssh_bind The ssh server bind to accept a connection.
*
* @return A newly allocated ssh session, NULL on error.
*/
void ssh_bind_set_blocking(SSH_BIND *ssh_bind,int blocking);
int ssh_bind_get_fd(SSH_BIND *ssh_bind);
int ssh_bind_set_toaccept(SSH_BIND *ssh_bind);
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind);
/**
* @brief Free a ssh servers bind.
*
* @param ssh_bind The ssh server bind to free.
*/
void ssh_bind_free(SSH_BIND *ssh_bind);
/**
* @brief Exchange the banner and cryptographic keys.
*
* @param session The ssh session to accept a connection.
*
* @return 0 on success, < 0 on error.
*/
int ssh_accept(SSH_SESSION *session);
/* messages.c */
@@ -158,7 +77,7 @@ void ssh_message_free(SSH_MESSAGE *msg);
char *ssh_message_auth_user(SSH_MESSAGE *msg);
char *ssh_message_auth_password(SSH_MESSAGE *msg);
int ssh_message_auth_reply_success(SSH_MESSAGE *msg,int partial);
int ssh_message_auth_set_methods(SSH_MESSAGE *msg, int methods);
void ssh_message_auth_set_methods(SSH_MESSAGE *msg, int methods);
CHANNEL *ssh_message_channel_request_open_reply_accept(SSH_MESSAGE *msg);
@@ -173,8 +92,3 @@ int ssh_message_channel_request_reply_success(SSH_MESSAGE *msg);
#endif /* __cplusplus */
#endif /* SERVER_H */
/**
* @}
*/
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,40 +1,23 @@
/* sftp headers */
/*
* 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.
*/
Copyright 2003-2005 Aris Adamantiadis
/**
* @file sftp.h
*
* @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
* inspecified in which order messages may be sent back to the client
*
* @defgroup ssh_sftp SFTP Functions
* @{
*/
This file is part of the SSH Library
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 SFTP_H
#define SFTP_H
@@ -43,21 +26,6 @@
extern "C" {
#endif
#ifdef __GNUC__
#define SFTP_DEPRECATED __attribute__ ((deprecated))
#else
#define SFTP_DEPRECATED
#endif
#ifdef _WIN32
#ifndef uid_t
typedef long uid_t;
#endif /* uid_t */
#ifndef gid_t
typedef long gid_t;
#endif /* gid_t */
#endif /* _WIN32 */
typedef struct sftp_session_struct {
SSH_SESSION *session;
CHANNEL *channel;
@@ -161,536 +129,65 @@ typedef struct sftp_attributes{
#define LIBSFTP_VERSION 3
/**
* @brief Start a new sftp session.
*
* @param session The ssh session to use.
*
* @return A new sftp session or NULL on error.
*/
SFTP_SESSION *sftp_new(SSH_SESSION *session);
/**
* @brief Close and deallocate a sftp session.
*
* @param sftp The sftp session handle to free.
*/
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.
*/
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.
*/
int sftp_get_error(SFTP_SESSION *sftp);
/**
* @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
*/
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()
*/
/* reads one file and attribute from opened directory. fails at end */
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()
*/
/* returns 1 if the directory was EOF */
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.
*/
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.
*/
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.
*/
/* sftp_lstat stats a file but doesn't follow symlinks */
SFTP_ATTRIBUTES *sftp_fstat(SFTP_FILE *file);
/**
* @brief Free a sftp attribute structure.
*
* @param file The sftp attribute structure to free.
*/
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.
*/
int sftp_closedir(SFTP_DIR *dir);
/**
* @deprecated Use sftp_closedir() instead.
*/
int sftp_dir_close(SFTP_DIR *dir) SFTP_DEPRECATED;
/**
* @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()
*/
int sftp_close(SFTP_FILE *file);
/**
* @deprecated Use sftp_close() instead.
*/
int sftp_file_close(SFTP_FILE *file) SFTP_DEPRECATED;
/**
* @brief Open a file on the server.
*
* @param session The sftp session handle.
*
* @param file The file to be opened.
*
* @param access 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.
*/
SFTP_FILE *sftp_open(SFTP_SESSION *session, const char *file, int flags,
mode_t mode);
void sftp_file_set_nonblocking(SFTP_FILE *handle);
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.
*/
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()
*/
int sftp_async_read_begin(SFTP_FILE *file, u32 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()
*/
int sftp_async_read(SFTP_FILE *file, void *data, u32 len, u32 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()
*/
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.
*/
int sftp_seek(SFTP_FILE *file, u32 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.
*/
int sftp_seek64(SFTP_FILE *file, u64 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.
*/
int sftp_dir_close(SFTP_DIR *dir);
int sftp_file_close(SFTP_FILE *file);
/* access are the sames than the ones from ansi fopen() */
SFTP_FILE *sftp_open(SFTP_SESSION *session, const char *file, int access, SFTP_ATTRIBUTES *attr);
int sftp_read(SFTP_FILE *file, void *dest, int len);
u32 sftp_async_read_begin(SFTP_FILE *file, int len);
int sftp_async_read(SFTP_FILE *file, void *data, int len, u32 id);
int sftp_write(SFTP_FILE *file, const void *source, int len);
void sftp_seek(SFTP_FILE *file, int new_offset);
void sftp_seek64(SFTP_FILE *file, u64 new_offset);
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.
*/
u64 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.
*/
void sftp_rewind(SFTP_FILE *file);
/**
* @deprecated Use sftp_unlink() instead.
*/
int sftp_rm(SFTP_SESSION *sftp, const char *file) SFTP_DEPRECATED;
/**
* @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.
*/
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.
*/
int sftp_rm(SFTP_SESSION *sftp, char *file);
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.
*/
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.
*/
int sftp_mkdir(SFTP_SESSION *sftp, const char *directory, SFTP_ATTRIBUTES *attr);
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
char *sftp_readlink(SFTP_SESSION *sftp, const char *path);
/**
* @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.
*/
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.
*/
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.
*/
#ifndef NO_SERVER
SFTP_SESSION *sftp_server_new(SSH_SESSION *session, CHANNEL *chan);
/**
* @brief Intialize the sftp server.
*
* @param sftp The sftp session to init.
*
* @return 0 on success, < 0 on error.
*/
int sftp_server_init(SFTP_SESSION *sftp);
#endif /* WITH_SERVER */
#endif
/* 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,u8 type, BUFFER *payload);
void sftp_packet_free(SFTP_PACKET *packet);
int buffer_add_attributes(BUFFER *buffer, SFTP_ATTRIBUTES *attr);
void buffer_add_attributes(BUFFER *buffer, SFTP_ATTRIBUTES *attr);
SFTP_ATTRIBUTES *sftp_parse_attr(SFTP_SESSION *session, BUFFER *buf,int expectname);
/* sftpserver.c */
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp);
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg);
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, const char *name,
SFTP_ATTRIBUTES *attr);
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, char *name, SFTP_ATTRIBUTES *attr);
int sftp_reply_handle(SFTP_CLIENT_MESSAGE *msg, STRING *handle);
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, STRING *handle);
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 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_status(SFTP_CLIENT_MESSAGE *msg, u32 status, char *message);
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, char *file, 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);
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, void *data, int len);
void sftp_handle_remove(SFTP_SESSION *sftp, void *handle);
/* SFTP commands and constants */
@@ -773,11 +270,6 @@ void sftp_handle_remove(SFTP_SESSION *sftp, void *handle);
#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
@@ -798,12 +290,8 @@ void sftp_handle_remove(SFTP_SESSION *sftp, void *handle);
#define SFTP_SYMLINK SSH_FXP_SYMLINK
#ifdef __cplusplus
} ;
#endif
#endif /* SFTP_H */
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

15
lib.bat Executable file
View File

@@ -0,0 +1,15 @@
@SET VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE
@SET VCINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003
@SET FrameworkDir=C:\WINDOWS\Microsoft.NET\Framework
@SET FrameworkVersion=v1.1.4322
@SET FrameworkSDKDir=C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1
@set DevEnvDir=%VSINSTALLDIR%
@rem
@rem Root of Visual C++ installed files.
@rem
@set MSVCDir=%VCINSTALLDIR%\VC7
@set PATH=%DevEnvDir%;%MSVCDir%\BIN;%VCINSTALLDIR%\Common7\Tools;%VCINSTALLDIR%\Common7\Tools\bin\prerelease;%VCINSTALLDIR%\Common7\Tools\bin;%FrameworkSDKDir%\bin;%FrameworkDir%\%FrameworkVersion%;%PATH%;
@set INCLUDE=%MSVCDir%\ATLMFC\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\PlatformSDK\include\prerelease;%MSVCDir%\PlatformSDK\include;%FrameworkSDKDir%\include;%INCLUDE%
@set LIB=%MSVCDir%\ATLMFC\LIB;%MSVCDir%\LIB;%MSVCDir%\PlatformSDK\lib\prerelease;%MSVCDir%\PlatformSDK\lib;%FrameworkSDKDir%\lib;%LIB%
"c:\Program files\Microsoft Visual Studio .NET 2003\vc7\bin\lib.exe" /machine:i386 /def:libssh.def

427
libssh.dev Normal file
View File

@@ -0,0 +1,427 @@
[Project]
FileName=libssh.dev
Name=libssh
UnitCount=38
Type=1
Ver=1
ObjFiles=
Includes=
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=
IsCpp=0
Icon=
ExeOutput=
ObjectOutput=
OverrideOutput=0
OverrideOutputName=libssh.exe
HostApplication=
Folders=include
CommandLine=
UseCustomMakefile=1
CustomMakefile=Makefile.Windows
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000
[Unit1]
FileName=libssh\init.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=libssh\kex.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=libssh\keyfiles.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit4]
FileName=libssh\keys.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit5]
FileName=libssh\messages.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=libssh\misc.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit7]
FileName=libssh\options.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit8]
FileName=libssh\packet.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit9]
FileName=libssh\server.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit10]
FileName=libssh\session.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit11]
FileName=libssh\sftp.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit12]
FileName=libssh\sftpserver.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit13]
FileName=libssh\socket.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit14]
FileName=libssh\string.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit15]
FileName=libssh\wrapper.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit16]
FileName=libssh\auth1.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit17]
FileName=libssh\auth.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit18]
FileName=libssh\base64.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit19]
FileName=libssh\buffer.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit20]
FileName=libssh\channels1.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit21]
FileName=libssh\channels.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit22]
FileName=libssh\client.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit23]
FileName=libssh\connect.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit24]
FileName=libssh\crc32.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit25]
FileName=libssh\crypt.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit26]
FileName=libssh\dh.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit27]
FileName=libssh\error.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit28]
FileName=libssh\gcrypt_missing.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit29]
FileName=libssh\gzip.c
CompileCpp=0
Folder=libssh
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit30]
FileName=include\libssh\crypto.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit31]
FileName=include\libssh\libssh.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit32]
FileName=include\libssh\priv.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit33]
FileName=include\libssh\server.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit34]
FileName=include\libssh\sftp.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit35]
FileName=include\libssh\ssh1.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit36]
FileName=include\libssh\ssh2.h
CompileCpp=0
Folder=include
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit37]
FileName=lib.bat
Folder=libssh
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit38]
FileName=Makefile.Windows
Folder=libssh
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@@ -1,178 +0,0 @@
project(libssh-library C)
set(LIBSSH_PUBLIC_INCLUDE_DIRS
${CMAKE_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}
CACHE INTERNAL "libssh public include directories"
)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${CMAKE_BINARY_DIR}
${ZLIB_INCLUDE_DIRS}
)
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_LINK_LIBRARIES
${ZLIB_LIBRARIES}
)
if (WIN32)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
ws2_32
)
endif (WIN32)
if (CRYPTO_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${CRYPTO_LIBRARY}
)
endif (CRYPTO_LIBRARY)
if (GCRYPT_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${GCRYPT_INCLUDE_DIRS}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${GCRYPT_LIBRARY}
)
endif (GCRYPT_LIBRARY)
set(libssh_SRCS
agent.c
auth.c
base64.c
buffer.c
channels.c
client.c
connect.c
crc32.c
crypt.c
dh.c
error.c
gcrypt_missing.c
gzip.c
init.c
kex.c
keyfiles.c
keys.c
log.c
match.c
messages.c
misc.c
options.c
packet.c
poll.c
session.c
socket.c
string.c
wrapper.c
libssh.map
)
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
)
endif (WITH_SSH1)
if (WITH_SERVER)
set(libssh_SRCS
${libssh_SRCS}
server.c
)
endif (WITH_SERVER)
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
)
install(
TARGETS
${LIBSSH_SHARED_LIBRARY}
DESTINATION
${LIB_INSTALL_DIR}
COMPONENT
libraries
)
if (WITH_STATIC_LIB)
add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS})
target_link_libraries(${LIBSSH_STATIC_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
set_target_properties(
${LIBSSH_STATIC_LIBRARY}
PROPERTIES
VERSION
${LIBRARY_VERSION}
SOVERSION
${LIBRARY_SOVERSION}
OUTPUT_NAME
ssh
)
install(
TARGETS
${LIBSSH_STATIC_LIBRARY}
DESTINATION
${LIB_INSTALL_DIR}
COMPONENT
libraries
)
endif (WITH_STATIC_LIB)

14
libssh/Makefile.am Normal file
View File

@@ -0,0 +1,14 @@
lib_LTLIBRARIES = libssh.la
libssh_la_SOURCES = auth1.c auth.c base64.c buffer.c \
channels1.c channels.c client.c connect.c \
crc32.c crypt.c dh.c error.c gcrypt_missing.c \
gzip.c init.c kex.c keyfiles.c \
keys.c messages.c misc.c options.c \
packet.c server.c session.c sftp.c \
sftpserver.c string.c wrapper.c \
socket.c log.c match.c
libssh_la_CPPFLAGS = -I$(top_srcdir)/include
libssh_la_LDFLAGS = -version-info $(LIBSSH_CURRENT):$(LIBSSH_REVISION):$(LIBSSH_AGE)

View File

@@ -1,498 +0,0 @@
/*
* agent.c - ssh agent functions
*
* This file is part of the SSH Library
*
* Copyright (c) 2008-2009 by Andreas Schneider <mail@cynapses.org>
*
* 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 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 cound 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 <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <poll.h>
#include <unistd.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "libssh/agent.h"
#include "libssh/priv.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 u32 agent_get_u32(const void *vp) {
const u8 *p = (const u8 *)vp;
u32 v;
v = (u32)p[0] << 24;
v |= (u32)p[1] << 16;
v |= (u32)p[2] << 8;
v |= (u32)p[3];
return v;
}
static void agent_put_u32(void *vp, u32 v) {
u8 *p = (u8 *)vp;
p[0] = (u8)(v >> 24) & 0xff;
p[1] = (u8)(v >> 16) & 0xff;
p[2] = (u8)(v >> 8) & 0xff;
p[3] = (u8)v & 0xff;
}
static size_t atomicio(struct socket *s, void *buf, size_t n, int do_read) {
char *b = buf;
size_t pos = 0;
ssize_t res;
struct pollfd pfd;
int fd = ssh_socket_get_fd(s);
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) poll(&pfd, 1, -1);
continue;
}
return 0;
case 0:
errno = EPIPE;
return pos;
default:
pos += (size_t) res;
}
}
return pos;
}
AGENT *agent_new(struct ssh_session *session) {
AGENT *agent = NULL;
agent = malloc(sizeof(AGENT));
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;
}
return agent;
}
void agent_close(struct agent_struct *agent) {
if (agent == NULL) {
return;
}
if (getenv("SSH_AUTH_SOCK")) {
ssh_socket_close(agent->sock);
}
}
void agent_free(AGENT *agent) {
if (agent) {
if (agent->ident) {
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;
}
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 *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 *session,
struct buffer_struct *request, struct buffer_struct *reply) {
u32 len = 0;
u8 payload[1024] = {0};
len = buffer_get_len(request);
ssh_log(session, SSH_LOG_PACKET, "agent_talk - len of request: %u", len);
agent_put_u32(payload, len);
/* send length and then the request packet */
if (atomicio(session->agent->sock, payload, 4, 0) == 4) {
if (atomicio(session->agent->sock, buffer_get_rest(request), len, 0)
!= len) {
ssh_log(session, SSH_LOG_PACKET, "atomicio sending request failed: %s",
strerror(errno));
return -1;
}
} else {
ssh_log(session, SSH_LOG_PACKET,
"atomicio sending request length failed: %s",
strerror(errno));
return -1;
}
/* wait for response, read the length of the response packet */
if (atomicio(session->agent->sock, payload, 4, 1) != 4) {
ssh_log(session, SSH_LOG_PACKET, "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(session, SSH_LOG_PACKET, "agent_talk - response length: %u", len);
while (len > 0) {
size_t n = len;
if (n > sizeof(payload)) {
n = sizeof(payload);
}
if (atomicio(session->agent->sock, payload, n, 1) != n) {
ssh_log(session, SSH_LOG_RARE,
"Error reading response from authentication socket.");
return -1;
}
if (buffer_add_data(reply, payload, n) < 0) {
ssh_log(session, SSH_LOG_FUNCTIONS,
"Not enough space");
return -1;
}
len -= n;
}
return 0;
}
int agent_get_ident_count(struct ssh_session *session) {
BUFFER *request = NULL;
BUFFER *reply = NULL;
unsigned int type = 0;
unsigned int c1 = 0, c2 = 0;
u8 buf[4] = {0};
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 = buffer_new();
if (buffer_add_u8(request, c1) < 0) {
ssh_set_error(session, SSH_FATAL, "Not enough space");
return -1;
}
reply = buffer_new();
if (reply == NULL) {
ssh_set_error(session, SSH_FATAL, "Not enough space");
return -1;
}
if (agent_talk(session, request, reply) < 0) {
buffer_free(request);
return 0;
}
buffer_free(request);
/* get message type and verify the answer */
buffer_get_u8(reply, (u8 *) &type);
ssh_log(session, SSH_LOG_PACKET,
"agent_ident_count - answer type: %d, expected answer: %d",
type, c2);
if (agent_failed(type)) {
return 0;
} else if (type != c2) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %d", type);
return -1;
}
buffer_get_u32(reply, (u32 *) buf);
session->agent->count = agent_get_u32(buf);
ssh_log(session, SSH_LOG_PACKET, "agent_ident_count - 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);
buffer_free(reply);
return -1;
}
if (session->agent->ident) {
buffer_reinit(session->agent->ident);
}
session->agent->ident = reply;
return session->agent->count;
}
/* caller has to free commment */
struct public_key_struct *agent_get_first_ident(struct ssh_session *session,
char **comment) {
if (agent_get_ident_count(session) > 0) {
return agent_get_next_ident(session, comment);
}
return NULL;
}
/* caller has to free commment */
struct public_key_struct *agent_get_next_ident(struct ssh_session *session,
char **comment) {
struct public_key_struct *pubkey = NULL;
struct string_struct *blob = NULL;
struct string_struct *tmp = NULL;
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) {
string_free(blob);
return NULL;
}
if (comment) {
*comment = string_to_char(tmp);
} else {
string_free(blob);
string_free(tmp);
return NULL;
}
string_free(tmp);
/* get key from blob */
pubkey = publickey_from_string(session, blob);
string_free(blob);
break;
default:
return NULL;
}
return pubkey;
}
STRING *agent_sign_data(struct ssh_session *session,
struct buffer_struct *data,
struct public_key_struct *pubkey) {
struct string_struct *blob = NULL;
struct string_struct *sig = NULL;
struct buffer_struct *request = NULL;
struct buffer_struct *reply = NULL;
int type = SSH2_AGENT_FAILURE;
int flags = 0;
u32 dlen = 0;
/* create blob from the pubkey */
blob = publickey_to_string(pubkey);
request = buffer_new();
if (request == NULL) {
goto error;
}
/* create request */
if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
goto error;
}
/* adds len + blob */
if (buffer_add_ssh_string(request, blob) < 0) {
goto error;
}
/* Add data */
dlen = buffer_get_len(data);
if (buffer_add_u32(request, htonl(dlen)) < 0) {
goto error;
}
if (buffer_add_data(request, buffer_get(data), dlen) < 0) {
goto error;
}
if (buffer_add_u32(request, htonl(flags)) < 0) {
goto error;
}
string_free(blob);
reply = buffer_new();
if (reply == NULL) {
goto error;
}
/* send the request */
if (agent_talk(session, request, reply) < 0) {
buffer_free(request);
return NULL;
}
buffer_free(request);
/* check if reply is valid */
if (buffer_get_u8(reply, (u8 *) &type) < 0) {
goto error;
}
if (agent_failed(type)) {
ssh_log(session, SSH_LOG_RARE, "Agent reports failure in signing the key");
buffer_free(reply);
return NULL;
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type);
buffer_free(reply);
return NULL;
}
sig = buffer_get_ssh_string(reply);
buffer_free(reply);
return sig;
error:
ssh_set_error(session, SSH_FATAL, "Not enough memory");
string_free(blob);
buffer_free(request);
buffer_free(reply);
return NULL;
}
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;
}
#endif /* _WIN32 */
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,98 +1,77 @@
/* auth1.c deals with authentication with SSH-1 protocol */
/*
* 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.
*/
Copyright (c) 2005-2008 Aris Adamantiadis
#include <string.h>
#include <stdlib.h>
This file is part of the SSH Library
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/priv.h"
#include "libssh/ssh1.h"
#include <string.h>
#include <stdlib.h>
#ifdef WITH_SSH1
static int wait_auth1_status(SSH_SESSION *session) {
/* wait for a packet */
if (packet_read(session) != SSH_OK) {
return SSH_AUTH_ERROR;
}
if(packet_translate(session) != SSH_OK) {
return SSH_AUTH_ERROR;
}
switch(session->in_packet.type) {
case SSH_SMSG_SUCCESS:
return SSH_AUTH_SUCCESS;
case SSH_SMSG_FAILURE:
return SSH_AUTH_DENIED;
}
ssh_set_error(session, SSH_FATAL, "Was waiting for a SUCCESS or "
"FAILURE, got %d", session->in_packet.type);
return SSH_AUTH_ERROR;
/*
static void burn(char *ptr){
if(ptr)
memset(ptr,'X',strlen(ptr));
}
static int send_username(SSH_SESSION *session, const char *username) {
STRING *user = NULL;
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
if(session->auth_service_asked) {
return session->auth_service_asked;
}
if (!username) {
if(!(username = session->options->username)) {
if(ssh_options_default_username(session->options)) {
return session->auth_service_asked = SSH_AUTH_ERROR;
} else {
username = session->options->username;
}
*/
#ifdef HAVE_SSH1
static int wait_auth1_status(SSH_SESSION *session){
/* wait for a packet */
if(packet_read(session))
return SSH_AUTH_ERROR;
if(packet_translate(session))
return SSH_AUTH_ERROR;
switch(session->in_packet.type){
case SSH_SMSG_SUCCESS:
return SSH_AUTH_SUCCESS;
case SSH_SMSG_FAILURE:
return SSH_AUTH_DENIED;
}
}
user = string_from_char(username);
if (user == NULL) {
ssh_set_error(session,SSH_FATAL,"Was waiting for a SUCCESS or "
"FAILURE, got %d",session->in_packet.type);
return SSH_AUTH_ERROR;
}
if (buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) {
string_free(user);
return SSH_AUTH_ERROR;
}
if (buffer_add_ssh_string(session->out_buffer, user) < 0) {
string_free(user);
return SSH_AUTH_ERROR;
}
string_free(user);
if (packet_send(session) != SSH_OK) {
return SSH_AUTH_ERROR;
}
session->auth_service_asked = wait_auth1_status(session);
return session->auth_service_asked;
}
static int send_username(SSH_SESSION *session, char *username){
STRING *user;
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
if(session->auth_service_asked)
return session->auth_service_asked;
buffer_add_u8(session->out_buffer,SSH_CMSG_USER);
if(!username)
if(!(username=session->options->username)){
if(ssh_options_default_username(session->options))
return session->auth_service_asked=SSH_AUTH_ERROR;
else
username=session->options->username;
}
user=string_from_char(username);
buffer_add_ssh_string(session->out_buffer,user);
free(user);
packet_send(session);
session->auth_service_asked=wait_auth1_status(session);
return session->auth_service_asked;
}
/* use the "none" authentication question */
int ssh_userauth1_none(SSH_SESSION *session, const char *username){
return send_username(session, username);
int ssh_userauth1_none(SSH_SESSION *session,char *username){
return send_username(session,username);
}
/*
@@ -136,13 +115,9 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,int type, STR
/** \internal
* \todo implement ssh1 public key
*/
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
int type, STRING *pubkey) {
(void) session;
(void) username;
(void) type;
(void) pubkey;
return SSH_AUTH_DENIED;
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, char *username, int type,
STRING *pubkey){
return SSH_AUTH_DENIED;
}
/*
@@ -192,64 +167,39 @@ int ssh_userauth_pubkey(SSH_SESSION *session, char *username, STRING *publickey,
}
*/
int ssh_userauth1_password(SSH_SESSION *session, const char *username,
const char *password) {
STRING *pwd = NULL;
int rc;
rc = send_username(session, username);
if (rc != SSH_AUTH_DENIED) {
return rc;
}
/* 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 = string_from_char(password);
if (pwd == NULL) {
return SSH_AUTH_ERROR;
}
} else {
/* 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.
int ssh_userauth1_password(SSH_SESSION *session,char *username,char *password){
STRING *password_s;
int err;
err=send_username(session,username);
if(err!=SSH_AUTH_DENIED)
return err;
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
* easy to guess password sizes.
* not that sure ...
*/
pwd = string_new(128);
if (pwd == NULL) {
return SSH_AUTH_ERROR;
/* XXX fix me here ! */
/* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
if(strlen(password)>=0){
/* not risky to disclose the size of such a big password .. */
password_s=string_from_char(password);
} else {
/* 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.
*/
password_s=string_new(128);
ssh_get_random(password_s->string,128,0);
strcpy((char *)password_s->string,password);
}
ssh_get_random( pwd->string, 128, 0);
strcpy((char *) pwd->string, password);
}
if (buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) {
string_burn(pwd);
string_free(pwd);
return SSH_AUTH_ERROR;
}
if (buffer_add_ssh_string(session->out_buffer, pwd) < 0) {
string_burn(pwd);
string_free(pwd);
return SSH_AUTH_ERROR;
}
string_burn(pwd);
string_free(pwd);
if (packet_send(session) != SSH_OK) {
return SSH_AUTH_ERROR;
}
return wait_auth1_status(session);
buffer_add_u8(session->out_buffer,SSH_CMSG_AUTH_PASSWORD);
buffer_add_ssh_string(session->out_buffer,password_s);
string_burn(password_s);
free(password_s);
packet_send(session);
return wait_auth1_status(session);
}
#endif /* WITH_SSH1 */
/* vim: set ts=2 sw=2 et cindent: */
#endif /* HAVE_SSH1 */

View File

@@ -1,286 +1,217 @@
/* base64 contains the needed support for base64 alphabet system, */
/* as described in RFC1521 */
/*
* 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.
*/
Copyright 2003-2005 Aris Adamantiadis
This file is part of the SSH Library
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 <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "libssh/priv.h"
static char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/" ;
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)
/* 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) ((n & 0xff0000) >> 16)
#define GET_B(n) ((n & 0xff00) >> 8)
#define GET_C(n) (n & 0xff)
#define GET_A(n) (((n) & 0xff0000) >> 16)
#define GET_B(n) (((n) & 0xff00) >> 8)
#define GET_C(n) ((n) & 0xff)
static int _base64_to_bin(unsigned char dest[3], const char *source, int num);
static int _base64_to_bin(unsigned char dest[3], char *source,int num);
static int get_equals(char *string);
/* First part: base64 to binary */
/* first part : base 64 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).
/** \brief base64_to_bin translates a base64 string into a binary one. important,
* \returns NULL if something went wrong (ie incorrect char)
* \returns BUFFER containing the decoded string
* \internal
*/
BUFFER *base64_to_bin(const char *source) {
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;
BUFFER *base64_to_bin(char *source){
int len;
int equals;
BUFFER *buffer=buffer_new();
unsigned char block[3];
/* Get the number of equals signs, which mirrors the padding */
equals = get_equals(ptr);
if (equals > 2) {
SAFE_FREE(base64);
return NULL;
}
buffer = buffer_new();
if (buffer == NULL) {
SAFE_FREE(base64);
return NULL;
}
len = strlen(ptr);
while (len > 4) {
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
/* get the number of equals signs, which mirrors the padding */
equals=get_equals(source);
if(equals>2){
buffer_free(buffer);
return NULL;
}
if (buffer_add_data(buffer, block, 3) < 0) {
goto error;
len=strlen(source);
while(len>4){
if(_base64_to_bin(block,source,3)){
buffer_free(buffer);
return NULL;
}
buffer_add_data(buffer,block,3);
len-=4;
source+=4;
}
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 (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 (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 (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);
buffer_free(buffer);
return NULL;
/* depending of 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){
buffer_free(buffer);
return NULL;
}
if(_base64_to_bin(block,source,3)){
buffer_free(buffer);
return NULL;
}
buffer_add_data(buffer,block,3);
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){
buffer_free(buffer);
return NULL;
}
if(_base64_to_bin(block,source,1)){
buffer_free(buffer);
return NULL;
}
buffer_add_data(buffer,block,1);
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){
buffer_free(buffer);
return NULL;
}
if(_base64_to_bin(block,source,2)){
buffer_free(buffer);
return NULL;
}
buffer_add_data(buffer,block,2);
return buffer;
default:
/* 4,3,2 are the only padding size allowed */
buffer_free(buffer);
return NULL;
}
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) {
#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, char *source,int num){
char *ptr;
unsigned int i;
*block=0;
if(num<1)
return 0;
BLOCK(A,0); /* 6 bits */
BLOCK(B,1); /* 12 */
if(num<2)
return 0;
BLOCK(C,2); /* 18 */
if(num < 3)
return 0;
BLOCK(D,3); /* 24 */
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;
static int _base64_to_bin(unsigned char dest[3], char *source,int num){
unsigned long block;
if(to_block4(&block,source,num))
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;
/* counts 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,'='))){
num++;
*ptr=0;
ptr++;
}
while ((ptr=strchr(ptr,'=')) != NULL) {
num++;
*ptr = '\0';
ptr++;
}
return num;
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;
}
#define BITS(n) ((1<<n)-1)
static void _bin_to_base64(unsigned char *dest, 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
/** \brief Converts binary data to a base64 string
* \returns the converted string
* \internal
*/
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;
unsigned char *bin_to_base64(unsigned char *source, int len){
int flen=len + (3 - (len %3)); /* round to upper 3 multiple */
unsigned char *buffer;
unsigned char *ptr;
flen=(4 * flen)/3 + 1 ;
ptr=buffer=malloc(flen);
while(len>0){
_bin_to_base64(ptr,source,len>3?3:len);
ptr+=4;
source +=3;
len -=3;
}
ptr[0]=0;
return buffer;
}
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,33 +1,25 @@
/*
* buffer.c - buffer 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.
*/
Copyright (c) 2003-2008 Aris Adamantiadis
This file is part of the SSH Library
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 <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "libssh/priv.h"
/** \defgroup ssh_buffer SSH Buffers
@@ -39,69 +31,50 @@
*/
/** \brief creates a new buffer
* \return a new initialized buffer, NULL on error.
* \return a new initialized buffer
*/
struct buffer_struct *buffer_new(void) {
struct buffer_struct *buf = malloc(sizeof(struct buffer_struct));
if (buf == NULL) {
return NULL;
}
memset(buf, 0, sizeof(struct buffer_struct));
return buf;
BUFFER *buffer_new(){
BUFFER *buffer=malloc(sizeof(BUFFER));
memset(buffer,0,sizeof(BUFFER));
return buffer;
}
/** \brief deallocate a buffer
* \param buffer buffer to free
*/
void buffer_free(struct buffer_struct *buffer) {
if (buffer == NULL) {
return;
}
if (buffer->data) {
/* burn the data */
memset(buffer->data, 0, buffer->allocated);
SAFE_FREE(buffer->data);
}
memset(buffer, 'X', sizeof(*buffer));
SAFE_FREE(buffer);
void buffer_free(BUFFER *buffer){
// printf("buffer %p : free(%p);\n",buffer,buffer->data);
if(buffer->data){
memset(buffer->data,0,buffer->allocated); /* burn the data */
free(buffer->data);
}
memset(buffer,'x',sizeof (*buffer));
free(buffer);
}
static int realloc_buffer(struct buffer_struct *buffer, int needed) {
int smallest = 1;
char *new = NULL;
/* Find the smallest power of two which is greater or equal to needed */
while(smallest <= needed) {
smallest <<= 1;
}
needed = smallest;
new = realloc(buffer->data, needed);
if (new == NULL) {
return -1;
}
buffer->data = new;
buffer->allocated = needed;
return 0;
static void realloc_buffer(BUFFER *buffer,int needed){
int smallest=1;
// find the smallest power of two which is greater or equal to needed
while(smallest<=needed)
smallest <<= 1;
needed=smallest;
// printf("buffer %p : realloc(%x,%d)=",buffer,buffer->data,needed);
buffer->data=realloc(buffer->data,needed);
// printf("%p\n",buffer->data);
buffer->allocated=needed;
}
/* \internal
* \brief reinitialize a buffer
* \param buffer buffer
* \return 0 on sucess, < 0 on error
*/
int buffer_reinit(struct buffer_struct *buffer) {
memset(buffer->data, 0, buffer->used);
buffer->used = 0;
buffer->pos = 0;
if(buffer->allocated > 127) {
if (realloc_buffer(buffer, 127) < 0) {
return -1;
void buffer_reinit(BUFFER *buffer){
memset(buffer->data,0,buffer->used);
buffer->used=0;
buffer->pos=0;
if(buffer->allocated > 127){
realloc_buffer(buffer,127);
}
}
return 0;
}
/** \internal
@@ -110,74 +83,45 @@ int buffer_reinit(struct buffer_struct *buffer) {
* \param data data pointer
* \param len length of data
*/
int buffer_add_data(struct buffer_struct *buffer, const void *data, u32 len) {
if (buffer->allocated < (buffer->used + len)) {
if (realloc_buffer(buffer, buffer->used + len) < 0) {
return -1;
}
}
memcpy(buffer->data+buffer->used, data, len);
buffer->used+=len;
return 0;
void buffer_add_data(BUFFER *buffer,const void *data,int len){
if(buffer->allocated < buffer->used+len)
realloc_buffer(buffer,buffer->used+len);
memcpy(buffer->data+buffer->used,data,len);
buffer->used+=len;
}
/** \internal
* \brief add a SSH string to the tail of buffer
* \param buffer buffer
* \param string SSH String to add
* \return 0 on success, -1 on error.
*/
int buffer_add_ssh_string(struct buffer_struct *buffer,
struct string_struct *string) {
u32 len = 0;
len = ntohl(string->size);
if (buffer_add_data(buffer, string, len + sizeof(u32)) < 0) {
return -1;
}
return 0;
void buffer_add_ssh_string(BUFFER *buffer,STRING *string){
u32 len=ntohl(string->size);
buffer_add_data(buffer,string,len+sizeof(u32));
}
/** \internal
* \brief add a 32 bits unsigned integer to the tail of buffer
* \param buffer buffer
* \param data 32 bits integer
* \return 0 on success, -1 on error.
*/
int buffer_add_u32(struct buffer_struct *buffer,u32 data){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
return 0;
void buffer_add_u32(BUFFER *buffer,u32 data){
buffer_add_data(buffer,&data,sizeof(data));
}
/** \internal
* \brief add a 64 bits unsigned integer to the tail of buffer
* \param buffer buffer
* \param data 64 bits integer
* \return 0 on success, -1 on error.
*/
int buffer_add_u64(struct buffer_struct *buffer, u64 data){
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
return -1;
}
return 0;
void buffer_add_u64(BUFFER *buffer,u64 data){
buffer_add_data(buffer,&data,sizeof(data));
}
/** \internal
* \brief add a 8 bits unsigned integer to the tail of buffer
* \param buffer buffer
* \param data 8 bits integer
* \return 0 on success, -1 on error.
*/
int buffer_add_u8(struct buffer_struct *buffer,u8 data){
if (buffer_add_data(buffer, &data, sizeof(u8)) < 0) {
return -1;
}
return 0;
void buffer_add_u8(BUFFER *buffer,u8 data){
buffer_add_data(buffer,&data,sizeof(u8));
}
/** \internal
@@ -185,35 +129,22 @@ int buffer_add_u8(struct buffer_struct *buffer,u8 data){
* \param buffer buffer
* \param data data to add
* \param len length of data
* \return 0 on success, -1 on error.
*/
int buffer_prepend_data(struct buffer_struct *buffer, const void *data,
u32 len) {
if (buffer->allocated < (buffer->used + len)) {
if (realloc_buffer(buffer, buffer->used + len) < 0) {
return -1;
}
}
memmove(buffer->data + len, buffer->data, buffer->used);
memcpy(buffer->data, data, len);
buffer->used += len;
return 0;
void buffer_add_data_begin(BUFFER *buffer, const void *data, int len){
if(buffer->allocated < buffer->used + len)
realloc_buffer(buffer,buffer->used+len);
memmove(buffer->data+len,buffer->data,buffer->used);
memcpy(buffer->data,data,len);
buffer->used+=len;
}
/** \internal
* \brief append data from a buffer to tail of another
* \param buffer destination buffer
* \param source source buffer. Doesn't take position in buffer into account
* \return 0 on success, -1 on error.
*/
int buffer_add_buffer(struct buffer_struct *buffer,
struct buffer_struct *source) {
if (buffer_add_data(buffer, buffer_get(source), buffer_get_len(source)) < 0) {
return -1;
}
return 0;
void buffer_add_buffer(BUFFER *buffer, BUFFER *source){
buffer_add_data(buffer,buffer_get(source),buffer_get_len(source));
}
/** \brief get a pointer on the head of the buffer
@@ -223,8 +154,8 @@ int buffer_add_buffer(struct buffer_struct *buffer,
* \see buffer_get_rest()
* \see buffer_get_len()
*/
void *buffer_get(struct buffer_struct *buffer){
return buffer->data;
void *buffer_get(BUFFER *buffer){
return buffer->data;
}
/** \internal
@@ -234,8 +165,8 @@ void *buffer_get(struct buffer_struct *buffer){
* \see buffer_get_rest_len()
* \see buffer_get()
*/
void *buffer_get_rest(struct buffer_struct *buffer){
return buffer->data + buffer->pos;
void *buffer_get_rest(BUFFER *buffer){
return buffer->data+buffer->pos;
}
/** \brief get length of the buffer, not counting position
@@ -243,7 +174,7 @@ void *buffer_get_rest(struct buffer_struct *buffer){
* \return length of the buffer
* \see buffer_get()
*/
u32 buffer_get_len(struct buffer_struct *buffer){
int buffer_get_len(BUFFER *buffer){
return buffer->used;
}
@@ -253,7 +184,7 @@ u32 buffer_get_len(struct buffer_struct *buffer){
* \return length of the buffer
* \see buffer_get_rest()
*/
u32 buffer_get_rest_len(struct buffer_struct *buffer){
int buffer_get_rest_len(BUFFER *buffer){
return buffer->used - buffer->pos;
}
@@ -264,7 +195,7 @@ u32 buffer_get_rest_len(struct buffer_struct *buffer){
* \param len number of bytes to eat
* \return new size of the buffer
*/
u32 buffer_pass_bytes(struct buffer_struct *buffer, u32 len){
int buffer_pass_bytes(BUFFER *buffer,int len){
if(buffer->used < buffer->pos+len)
return 0;
buffer->pos+=len;
@@ -282,7 +213,7 @@ u32 buffer_pass_bytes(struct buffer_struct *buffer, u32 len){
* \param len number of bytes to remove from tail
* \return new size of the buffer
*/
u32 buffer_pass_bytes_end(struct buffer_struct *buffer, u32 len){
int buffer_pass_bytes_end(BUFFER *buffer,int len){
if(buffer->used < buffer->pos + len)
return 0;
buffer->used-=len;
@@ -297,14 +228,9 @@ u32 buffer_pass_bytes_end(struct buffer_struct *buffer, u32 len){
* \returns 0 if there is not enough data in buffer
* \returns len otherwise.
*/
u32 buffer_get_data(struct buffer_struct *buffer, void *data, u32 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;
}
int buffer_get_data(BUFFER *buffer, void *data, int len){
if(buffer->pos+len>buffer->used)
return 0; /*no enough data in buffer */
memcpy(data,buffer->data+buffer->pos,len);
buffer->pos+=len;
return len; /* no yet support for partial reads (is it really needed ?? ) */
@@ -316,7 +242,7 @@ u32 buffer_get_data(struct buffer_struct *buffer, void *data, u32 len){
* \returns 0 if there is not enough data in buffer
* \returns 1 otherwise.
*/
int buffer_get_u8(struct buffer_struct *buffer, u8 *data){
int buffer_get_u8(BUFFER *buffer, u8 *data){
return buffer_get_data(buffer,data,sizeof(u8));
}
@@ -327,7 +253,7 @@ int buffer_get_u8(struct buffer_struct *buffer, u8 *data){
* \returns 0 if there is not enough data in buffer
* \returns 4 otherwise.
*/
int buffer_get_u32(struct buffer_struct *buffer, u32 *data){
int buffer_get_u32(BUFFER *buffer, u32 *data){
return buffer_get_data(buffer,data,sizeof(u32));
}
/** \internal
@@ -337,7 +263,7 @@ int buffer_get_u32(struct buffer_struct *buffer, u32 *data){
* \returns 0 if there is not enough data in buffer
* \returns 8 otherwise.
*/
int buffer_get_u64(struct buffer_struct *buffer, u64 *data){
int buffer_get_u64(BUFFER *buffer, u64 *data){
return buffer_get_data(buffer,data,sizeof(u64));
}
/** \internal
@@ -346,30 +272,23 @@ int buffer_get_u64(struct buffer_struct *buffer, u64 *data){
* \returns The SSH String read
* \returns NULL otherwise.
*/
struct string_struct *buffer_get_ssh_string(struct buffer_struct *buffer) {
u32 stringlen;
u32 hostlen;
struct 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) > buffer->used) {
return NULL; /* it is indeed */
}
str = string_new(hostlen);
if (str == NULL) {
return NULL;
}
if (buffer_get_data(buffer, str->string, hostlen) != hostlen) {
/* should never happen */
SAFE_FREE(str);
return NULL;
}
return str;
STRING *buffer_get_ssh_string(BUFFER *buffer){
u32 stringlen;
u32 hostlen;
STRING *str;
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>buffer->used)
return NULL; /* it is indeed */
str=string_new(hostlen);
if(buffer_get_data(buffer,str->string,hostlen)!=hostlen){
// should never happen
free(str);
return NULL;
}
return str;
}
/** \internal
* \brief gets a mpint out of the buffer. Adjusts the read pointer.
@@ -379,28 +298,22 @@ struct string_struct *buffer_get_ssh_string(struct buffer_struct *buffer) {
* \returns NULL otherwise
*/
struct string_struct *buffer_get_mpint(struct buffer_struct *buffer) {
u16 bits;
u32 len;
struct string_struct *str = NULL;
if (buffer_get_data(buffer, &bits, sizeof(u16)) != sizeof(u16)) {
return NULL;
}
bits = ntohs(bits);
len = (bits + 7) / 8;
if ((buffer->pos + len) > buffer->used) {
return NULL;
}
str = string_new(len);
if (str == NULL) {
return NULL;
}
if (buffer_get_data(buffer, str->string, len) != len) {
SAFE_FREE(str);
return NULL;
}
return str;
STRING *buffer_get_mpint(BUFFER *buffer){
u16 bits;
u32 len;
STRING *str;
if(buffer_get_data(buffer,&bits,sizeof(u16))!= sizeof(u16))
return NULL;
bits=ntohs(bits);
len=(bits+7)/8;
if(buffer->pos+len > buffer->used)
return NULL;
str=string_new(len);
if(buffer_get_data(buffer,str->string,len)!=len){
free(str);
return NULL;
}
return str;
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,24 @@
/* channels1.c */
/* Support for SSH-1 type channels */
/*
* 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 <mail@cynapses.org>
*
* 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.
*/
Copyright 2005 Aris Adamantiadis
This file is part of the SSH Library
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 <string.h>
#include <stdlib.h>
@@ -29,38 +27,29 @@
#include "libssh/priv.h"
#include "libssh/ssh1.h"
#ifdef WITH_SSH1
#ifdef HAVE_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.
/* this is a big hack. In fact, SSH-1 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 behaviour is that you can't only
* request one shell.
* The question is stil how they managed to imbed two "channel" into one
* protocol.
* request one Shell.
* And i don't even know yet how they managed to imbed two "channel"
* into one protocol.
*/
int channel_open_session1(CHANNEL *chan) {
/*
* 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.
*/
SSH_SESSION *session = chan->session;
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->open = 1;
chan->local_maxpacket = 32000;
chan->local_window = 64000;
ssh_log(session, SSH_LOG_PACKET, "Opened a SSH1 channel session");
return 0;
int channel_open_session1(CHANNEL *chan){
// we guess we are requesting an *exec* channel. It can only have
// only one exec channel. so we abort with an error if we need more than
SSH_SESSION *session=chan->session;
if(session->exec_channel_opened){
ssh_set_error(session,SSH_REQUEST_DENIED,"SSH-1 supports only one execution channel. One has already been opened");
return -1;
}
session->exec_channel_opened=1;
chan->open=1;
ssh_say(2,"Opened a ssh1 channel session\n");
return 0;
}
/* 10 SSH_CMSG_REQUEST_PTY
*
* string TERM environment variable value (e.g. vt100)
@@ -73,233 +62,156 @@ int channel_open_session1(CHANNEL *chan) {
* much simplier under ssh2. I just hope the defaults values are ok ...
*/
int channel_request_pty_size1(CHANNEL *channel, const char *terminal, int col,
int row) {
SSH_SESSION *session = channel->session;
STRING *str = NULL;
str = string_from_char(terminal);
if (str == NULL) {
return -1;
}
if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
buffer_add_ssh_string(session->out_buffer, str) < 0) {
string_free(str);
return -1;
}
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(session, SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
if (packet_send(session) != SSH_OK ||
packet_read(session) != SSH_OK ||
packet_translate(session) != SSH_OK) {
return -1;
}
switch (session->in_packet.type) {
case SSH_SMSG_SUCCESS:
ssh_log(session, SSH_LOG_RARE, "PTY: Success");
return 0;
break;
case SSH_SMSG_FAILURE:
ssh_set_error(session, SSH_REQUEST_DENIED,
"Server denied PTY allocation");
ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
break;
default:
ssh_log(session, SSH_LOG_RARE, "PTY: error\n");
ssh_set_error(session, SSH_FATAL,
"Received unexpected packet type %d",
session->in_packet.type);
return -1;
}
return -1;
}
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows) {
SSH_SESSION *session = channel->session;
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 -1;
}
if (packet_send(session)) {
return -1;
}
ssh_log(session, SSH_LOG_RARE, "Change pty size send");
if (packet_wait(session, SSH_SMSG_SUCCESS, 1) != SSH_OK) {
return -1;
}
switch (session->in_packet.type) {
case SSH_SMSG_SUCCESS:
ssh_log(session, SSH_LOG_RARE, "pty size changed");
return 0;
case SSH_SMSG_FAILURE:
ssh_log(session, SSH_LOG_RARE, "pty size change denied");
ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
return -1;
}
ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d",
session->in_packet.type);
return -1;
}
int channel_request_shell1(CHANNEL *channel) {
SSH_SESSION *session = channel->session;
if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) {
return -1;
}
if (packet_send(session) != SSH_OK) {
return -1;
}
ssh_log(session, SSH_LOG_RARE, "Launched a shell");
return 0;
}
int channel_request_exec1(CHANNEL *channel, const char *cmd) {
SSH_SESSION *session = channel->session;
STRING *command = NULL;
command = 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) {
string_free(command);
return -1;
}
string_free(command);
if(packet_send(session) != SSH_OK) {
return -1;
}
ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd);
return 0;
}
static int channel_rcv_data1(SSH_SESSION *session, int is_stderr) {
CHANNEL *channel = session->channels;
STRING *str = NULL;
str = buffer_get_ssh_string(session->in_buffer);
if (str == NULL) {
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n");
return -1;
int channel_request_pty_size1(CHANNEL *channel, char *terminal, int col,
int row){
STRING *str;
SSH_SESSION *session=channel->session;
str=string_from_char(terminal);
buffer_add_u8(session->out_buffer,SSH_CMSG_REQUEST_PTY);
buffer_add_ssh_string(session->out_buffer,str);
free(str);
buffer_add_u32(session->out_buffer,ntohl(row));
buffer_add_u32(session->out_buffer,ntohl(col));
buffer_add_u32(session->out_buffer,0); /* x */
buffer_add_u32(session->out_buffer,0); /* y */
buffer_add_u8(session->out_buffer,0); /* tty things */
ssh_say(2,"Opening a ssh1 pty\n");
if(packet_send(session))
return -1;
if(packet_read(session))
return -1;
if(packet_translate(session))
return -1;
switch (session->in_packet.type){
case SSH_SMSG_SUCCESS:
ssh_say(2,"pty : Success\n");
return 0;
break;
case SSH_SMSG_FAILURE:
ssh_set_error(session,SSH_REQUEST_DENIED,
"Server denied PTY allocation");
ssh_say(2,"pty : denied\n");
break;
default:
ssh_say(2,"pty : error\n");
ssh_set_error(session,SSH_FATAL,
"Received unexpected packet type %d",
session->in_packet.type);
return -1;
}
return -1;
}
ssh_log(session, SSH_LOG_RARE,
"Adding %zu bytes data in %d",
string_len(str), is_stderr);
if (channel_default_bufferize(channel, str->string, string_len(str),
is_stderr) < 0) {
string_free(str);
return -1;
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows){
SSH_SESSION *session=channel->session;
buffer_add_u8(session->out_buffer,SSH_CMSG_WINDOW_SIZE);
buffer_add_u32(session->out_buffer,ntohl(rows));
buffer_add_u32(session->out_buffer,ntohl(cols));
buffer_add_u32(session->out_buffer,0);
buffer_add_u32(session->out_buffer,0);
if(packet_send(session))
return -1;
ssh_say(2,"Change pty size send\n");
packet_wait(session,SSH_SMSG_SUCCESS,1);
switch (session->in_packet.type){
case SSH_SMSG_SUCCESS:
ssh_say(2,"pty size changed\n");
return 0;
break;
case SSH_SMSG_FAILURE:
ssh_say(2,"pty size change denied\n");
ssh_set_error(session,SSH_REQUEST_DENIED,"pty size change denied");
return -1;
}
string_free(str);
ssh_set_error(session,SSH_FATAL,"Received unexpected packet type %d",
session->in_packet.type);
return -1;
}
int channel_request_shell1(CHANNEL *channel){
SSH_SESSION *session=channel->session;
buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL);
if(packet_send(session))
return -1;
ssh_say(2,"Launched a shell\n");
return 0;
}
static int channel_rcv_close1(SSH_SESSION *session) {
CHANNEL *channel = session->channels;
u32 status;
buffer_get_u32(session->in_buffer, &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->open = 0;
channel->remote_eof = 1;
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION) < 0) {
return -1;
}
if (packet_send(session) != SSH_OK) {
return -1;
}
return 0;
}
int channel_handle1(SSH_SESSION *session, int type) {
ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type);
switch (type) {
case SSH_SMSG_STDOUT_DATA:
if (channel_rcv_data1(session,0) < 0) {
int channel_request_exec1(CHANNEL *channel, char *cmd){
SSH_SESSION *session=channel->session;
STRING *command=string_from_char(cmd);
buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_CMD);
buffer_add_ssh_string(session->out_buffer,command);
free(command);
if(packet_send(session))
return -1;
}
break;
case SSH_SMSG_EXITSTATUS:
if (channel_rcv_close1(session) < 0) {
return -1;
}
break;
default:
ssh_log(session, SSH_LOG_FUNCTIONS, "Unexepected message %d", type);
}
return 0;
ssh_say(2,"executing %s...\n",cmd);
return 0;
}
int channel_write1(CHANNEL *channel, const void *data, int len) {
SSH_SESSION *session = channel->session;
int origlen = len;
int effectivelen;
while (len > 0) {
if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) {
return -1;
static void channel_rcv_data1(SSH_SESSION *session, int is_stderr){
CHANNEL *channel;
STRING *str;
channel=session->channels; // Easy. hack this when multiple channel
// are comming
str=buffer_get_ssh_string(session->in_buffer);
if(!str){
ssh_say(0,"Invalid data packet !\n");
return;
}
effectivelen = len > 32000 ? 32000 : len;
if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
buffer_add_data(session->out_buffer, data, effectivelen) < 0) {
return -1;
}
data += effectivelen;
len -= effectivelen;
if (packet_send(session) != SSH_OK) {
return -1;
}
}
return origlen;
ssh_say(3,"adding %d bytes data in %d\n",string_len(str),is_stderr);
channel_default_bufferize(channel,str->string,string_len(str),
is_stderr);
free(str);
}
#endif /* WITH_SSH1 */
/* vim: set ts=2 sw=2 et cindent: */
static void channel_rcv_close1(SSH_SESSION *session){
CHANNEL *channel=session->channels;
u32 status;
buffer_get_u32(session->in_buffer,&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->open=0;
channel->remote_eof=1;
buffer_add_u8(session->out_buffer,SSH_CMSG_EXIT_CONFIRMATION);
packet_send(session);
}
void channel_handle1(SSH_SESSION *session, int type){
ssh_say(3,"Channel_handle1(%d)\n",type);
switch (type){
case SSH_SMSG_STDOUT_DATA:
channel_rcv_data1(session,0);
break;
case SSH_SMSG_EXITSTATUS:
channel_rcv_close1(session);
break;
default:
ssh_say(0,"Unexepected message %d\n",type);
}
}
int channel_write1(CHANNEL *channel, void *data, int len){
SSH_SESSION *session=channel->session;
int origlen=len;
int effectivelen;
while(len>0){
buffer_add_u8(session->out_buffer,SSH_CMSG_STDIN_DATA);
if(len > 32000)
effectivelen=32000;
else
effectivelen=len;
buffer_add_u32(session->out_buffer,htonl(effectivelen));
buffer_add_data(session->out_buffer,data,effectivelen);
data+=effectivelen;
len-=effectivelen;
if(packet_send(session))
return -1;
}
return origlen;
}
#endif /* HAVE_SSH1 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +1,42 @@
/* connect.c */
/* it handles connections to ssh servers */
/*
* connect.c - handles connections to ssh servers
*
* 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.
*/
Copyright (c) 2003-2008 Aris Adamantiadis
This file is part of the SSH Library
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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#ifdef _WIN32
/* getaddrinfo, freeaddrinfo, getnameinfo */
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT 0x0501 //getaddrinfo, freeaddrinfo, getnameinfo
#include <winsock2.h>
#include <ws2tcpip.h>
#include "wspiapi.h" /* Workaround for w2k systems */
#else /* _WIN32 */
#include "wspiapi.h" //workaround for w2k systems
#else
#include <netdb.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#endif /* _WIN32 */
#endif
#include <fcntl.h>
#include "libssh/priv.h"
#ifndef HAVE_SELECT
@@ -56,358 +47,267 @@
#error "Your system must have getaddrinfo()"
#endif
#ifdef _WIN32
#ifndef _WIN32
static void sock_set_nonblocking(socket_t sock) {
u_long nonblocking = 1;
ioctlsocket(sock, FIONBIO, &nonblocking);
fcntl(sock,F_SETFL,O_NONBLOCK);
}
static void sock_set_blocking(socket_t sock) {
u_long nonblocking = 0;
ioctlsocket(sock, FIONBIO, &nonblocking);
static void sock_set_blocking(socket_t sock){
fcntl(sock,F_SETFL,0);
}
#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 */
#else /* _WIN32 */
#else
static void sock_set_nonblocking(socket_t sock) {
fcntl(sock, F_SETFL, O_NONBLOCK);
u_long nonblocking = 1;
ioctlsocket(sock, FIONBIO, &nonblocking);
}
static void sock_set_blocking(socket_t sock){
u_long nonblocking = 0;
ioctlsocket(sock, FIONBIO, &nonblocking);
}
static void sock_set_blocking(socket_t sock) {
fcntl(sock, F_SETFL, 0);
}
#endif /* _WIN32 */
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", port);
service = s_port;
}
return getaddrinfo(host, service, &hints, ai);
char WSAAPI *gai_strerrorA(int code){
static char buffer[256];
snprintf(buffer,256,"Undetermined error code (%d)",code);
return buffer;
}
static int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host,
int port, struct addrinfo *ai, long timeout, long usec, socket_t s) {
struct timeval to;
fd_set set;
int rc = 0;
unsigned int len = sizeof(rc);
#endif
enter_function();
static int getai(const char *host, int port, struct addrinfo **ai)
{
struct addrinfo hints;
char *service=NULL;
char s_port[10];
to.tv_sec = timeout;
to.tv_usec = usec;
sock_set_nonblocking(s);
/* The return value is checked later */
connect(s, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
FD_ZERO(&set);
FD_SET(s, &set);
rc = select(s + 1, NULL, &set, NULL, &to);
if (rc == 0) {
/* timeout */
ssh_set_error(session, SSH_FATAL,
"Timeout while connecting to %s:%d", host, port);
close(s);
leave_function();
return -1;
}
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Select error: %s", strerror(errno));
close(s);
leave_function();
return -1;
}
rc = 0;
/* Get connect(2) return code. Zero means no error */
getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Connect to %s:%d failed: %s", host, port, strerror(rc));
close(s);
leave_function();
return -1;
}
/* s is connected ? */
ssh_log(session, SSH_LOG_PACKET, "Socket connected with timeout\n");
sock_set_blocking(s);
leave_function();
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;
enter_function();
rc = getai(host, port, &ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
leave_function();
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;
memset(&hints,0,sizeof(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",port);
service=s_port;
}
return getaddrinfo(host,service,&hints,ai);
}
if (bind_addr) {
struct addrinfo *bind_ai;
struct addrinfo *bind_itr;
ssh_log(session, SSH_LOG_PACKET, "Resolving %s\n", bind_addr);
rc = getai(host, 0, &bind_ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve bind address %s (%s)",
bind_addr,
gai_strerror(rc));
int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host, int port, struct addrinfo *ai,
long timeout, long usec,socket_t s)
{
struct timeval to;
fd_set set;
int ret=0;
unsigned int len=sizeof(ret);
enter_function();
to.tv_sec=timeout;
to.tv_usec=usec;
sock_set_nonblocking(s);
connect(s,ai->ai_addr,ai->ai_addrlen);
freeaddrinfo(ai);
FD_ZERO(&set);
FD_SET(s,&set);
ret=select(s+1,NULL,&set,NULL,&to);
if(ret==0){
/* timeout */
ssh_set_error(session,SSH_FATAL,"Timeout while connecting to %s:%d",host,port);
close(s);
leave_function();
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) {
}
if(ret<0){
ssh_set_error(session,SSH_FATAL,"Select error : %s",strerror(errno));
close(s);
s = -1;
continue;
}
leave_function();
return -1;
}
if (timeout || usec) {
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
timeout, usec, s);
leave_function();
return ret;
ret = 0;
/* get connect(2) return code. zero means no error */
getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&ret,&len);
if (ret!=0){
ssh_set_error(session,SSH_FATAL,"Connecting : %s",strerror(ret));
close(s);
leave_function();
return -1;
}
if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) {
ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno));
close(s);
s = -1;
continue;
} else {
/* We are connected */
break;
}
}
freeaddrinfo(ai);
leave_function();
return s;
/* s is connected ? */
ssh_log(session,SSH_LOG_PACKET,"socket connected with timeout\n");
sock_set_blocking(s);
leave_function();
return s;
}
/**
* @addtogroup ssh_session
* @{ */
/**
* @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 channels Arrays of channels pointers terminated by a NULL.
* It is never rewritten.
*
* @param outchannels Arrays of same size that "channels", there is no need
* to initialize it.
*
* @param maxfd Maximum +1 file descriptor from readfds.
*
* @param readfds A fd_set of file descriptors to be select'ed for
* reading.
*
* @param timeout A timeout for the select.
*
* @return -1 if an error occured. E_INTR if it was interrupted. In that case,
* just restart it.
*
* @warning libssh is not threadsafe here. That means that if a signal is caught
* during the processing of this function, you cannot call ssh functions on
* sessions that are busy with ssh_select().
*
* @see select(2)
/** \internal
* \brief connect_host connects to an IPv4 (or IPv6) host
* specified by its IP address or hostname.
* \returns file descriptor
* \returns less than 0 value
*/
int ssh_select(CHANNEL **channels, CHANNEL **outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout) {
struct timeval zerotime;
fd_set localset, localset2;
int rep;
int set;
int i;
int j;
zerotime.tv_sec = 0;
zerotime.tv_usec = 0;
/*
* First, poll the maxfd file descriptors from the user with a zero-second
* timeout. They have the bigger priority.
*/
if (maxfd > 0) {
memcpy(&localset, readfds, sizeof(fd_set));
rep = select(maxfd, &localset, NULL, NULL, &zerotime);
/* catch the eventual errors */
if (rep==-1) {
return -1;
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 my_errno;
struct addrinfo *ai, *ai2;
enter_function();
my_errno=getai(host, port, &ai);
if (my_errno){
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,gai_strerror(my_errno));
leave_function();
return -1;
}
}
/* Poll every channel */
j = 0;
for (i = 0; channels[i]; i++) {
if (channels[i]->session->alive) {
if(channel_poll(channels[i], 0) > 0) {
outchannels[j] = channels[i];
j++;
} else {
if(channel_poll(channels[i], 1) > 0) {
outchannels[j] = channels[i];
j++;
for(ai2=ai;ai2!=NULL;ai2=ai2->ai_next){
/* create socket */
s=socket(ai2->ai_family,ai2->ai_socktype,ai2->ai_protocol);
if(s<0){
ssh_set_error(session,SSH_FATAL,"socket : %s",strerror(errno));
continue;
}
}
}
}
outchannels[j] = NULL;
/* Look into the localset for active fd */
set = 0;
for (i = 0; (i < maxfd) && !set; i++) {
if (FD_ISSET(i, &localset)) {
set = 1;
}
}
if(bind_addr){
struct addrinfo *bind_ai, *bind_ai2;
/* j != 0 means a channel has data */
if( (j != 0) || (set != 0)) {
if(maxfd > 0) {
memcpy(readfds, &localset, sizeof(fd_set));
ssh_log(session,SSH_LOG_PACKET,"resolving %s\n",bind_addr);
my_errno=getai(host,0,&bind_ai);
if (my_errno){
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,gai_strerror(my_errno));
leave_function();
return -1;
}
for(bind_ai2=bind_ai;bind_ai2!=NULL;bind_ai2=bind_ai2->ai_next){
if(bind(s,bind_ai2->ai_addr,bind_ai2->ai_addrlen)<0){
ssh_set_error(session,SSH_FATAL,"Binding local address : %s",strerror(errno));
continue;
}
else{
break;
}
}
freeaddrinfo(bind_ai);
if(bind_ai2==NULL){ /*cannot bind to any local addresses*/
close(s);
s=-1;
continue;
}
}
if(timeout||usec){
socket_t ret=ssh_connect_ai_timeout(session,host,port,ai2,timeout,usec,s);
leave_function();
return ret;
}
if(connect(s,ai2->ai_addr,ai2->ai_addrlen)<0){
ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
close(s);
s=-1;
leave_function();
continue;
}
else{ /*we are connected*/
break;
}
}
freeaddrinfo(ai);
leave_function();
return s;
}
/** \addtogroup ssh_session
* * @{ */
/** This functions acts more or less like the select(2) syscall.\n
* There is no support for writing or exceptions.\n
* \brief wrapper for the select syscall
* \param channels arrays of channels pointers finished by an NULL. It is never rewritten/
* \param outchannels arrays of same size that "channels", it hasn't to be initialized
* \param maxfd maximum +1 file descriptor from readfds
* \param readfds an fd_set of file descriptors to be select'ed for reading
* \param timeout a timeout for the select
* \see select(2)
* \return -1 if an error occured. E_INTR if it was interrupted. In that case, just restart it.
* \warning libssh is not threadsafe. That means that if a signal is caught during the processing
* of this function, you cannot call ssh functions on sessions that are busy with ssh_select()
*/
int ssh_select(CHANNEL **channels,CHANNEL **outchannels, socket_t maxfd, fd_set *readfds, struct timeval *timeout){
struct timeval zerotime;
fd_set localset,localset2;
int rep;
int i,j;
int set;
zerotime.tv_sec=0;
zerotime.tv_usec=0;
/* first, poll the maxfd file descriptors from the user with a zero-second timeout. they have the bigger priority */
if(maxfd>0){
memcpy(&localset,readfds, sizeof(fd_set));
rep=select(maxfd,&localset,NULL,NULL,&zerotime);
// catch the eventual errors
if(rep==-1)
return -1;
}
j=0;
// polls every channel.
for(i=0;channels[i];i++){
if(channels[i]->session->alive){
if(channel_poll(channels[i],0)>0){
outchannels[j]=channels[i];
j++;
} else
if(channel_poll(channels[i],1)>0){
outchannels[j]=channels[i];
j++;
}
}
}
outchannels[j]=NULL;
/* look into the localset for active fd */
set=0;
for(i=0;(i<maxfd) && !set;i++)
if(FD_ISSET(i,&localset))
set=1;
// j!=0 means a channel has data
if( (j!=0) || (set!=0)){
if(maxfd>0)
memcpy(readfds,&localset,sizeof(fd_set));
return 0;
}
/* at this point, not any channel had any data ready for reading, nor any fd had data for reading */
memcpy(&localset,readfds,sizeof(fd_set));
for(i=0;channels[i];i++){
if(channels[i]->session->alive){
ssh_socket_fd_set(channels[i]->session->socket,&localset,&maxfd);
}
}
rep=select(maxfd,&localset,NULL,NULL,timeout);
if(rep==-1 && errno==EINTR){
return SSH_EINTR; /* interrupted by a signal */
}
if(rep==-1){
/* was the error due to a libssh's Channel or from a closed descriptor from the user ? user closed descriptors have been
caught in the first select and not closed since that moment. that case shouldn't occur at all */
return -1;
}
/* set the data_to_read flag on each session */
for(i=0;channels[i];i++)
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
ssh_socket_set_toread(channels[i]->session->socket);
/* now, test each channel */
j=0;
for(i=0;channels[i];i++){
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
if((channel_poll(channels[i],0)>0) || (channel_poll(channels[i],1)>0)){
outchannels[j]=channels[i];
j++;
}
}
outchannels[j]=NULL;
FD_ZERO(&localset2);
for(i=0;i<maxfd;i++)
if(FD_ISSET(i,readfds) && FD_ISSET(i,&localset))
FD_SET(i,&localset2);
memcpy(readfds,&localset2,sizeof(fd_set));
return 0;
}
/*
* At this point, not any channel had any data ready for reading, nor any fd
* had data for reading.
*/
memcpy(&localset, readfds, sizeof(fd_set));
for (i = 0; channels[i]; i++) {
if (channels[i]->session->alive) {
ssh_socket_fd_set(channels[i]->session->socket, &localset, &maxfd);
}
}
rep = select(maxfd, &localset, NULL, NULL, timeout);
if (rep == -1 && errno == EINTR) {
/* Interrupted by a signal */
return SSH_EINTR;
}
if (rep == -1) {
/*
* Was the error due to a libssh's channel or from a closed descriptor from
* the user? User closed descriptors have been caught in the first select
* and not closed since that moment. That case shouldn't occur at all
*/
return -1;
}
/* Set the data_to_read flag on each session */
for (i = 0; channels[i]; i++) {
if (channels[i]->session->alive &&
ssh_socket_fd_isset(channels[i]->session->socket,&localset)) {
ssh_socket_set_toread(channels[i]->session->socket);
}
}
/* Now, test each channel */
j = 0;
for (i = 0; channels[i]; i++) {
if (channels[i]->session->alive &&
ssh_socket_fd_isset(channels[i]->session->socket,&localset)) {
if ((channel_poll(channels[i],0) > 0) ||
(channel_poll(channels[i], 1) > 0)) {
outchannels[j] = channels[i];
j++;
}
}
}
outchannels[j] = NULL;
FD_ZERO(&localset2);
for (i = 0; i < maxfd; i++) {
if (FD_ISSET(i, readfds) && FD_ISSET(i, &localset)) {
FD_SET(i, &localset2);
}
}
memcpy(readfds, &localset2, sizeof(fd_set));
return 0;
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,15 +1,15 @@
/* simple CRC32 code */
/*
* crc32.c - simple CRC32 code
* Copyright 2005 Aris Adamantiadis
*
* 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
@@ -18,75 +18,71 @@
* 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.
*/
* MA 02111-1307, USA. */
#include "libssh/priv.h"
static u32 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
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
};
u32 ssh_crc32(const char *buf, u32 len) {
u32 ret = 0;
while(len > 0) {
ret = crc_table[(ret ^ *buf) & 0xff] ^ (ret >> 8);
--len;
++buf;
}
return ret;
u32 ssh_crc32(char *buf, int len) {
u32 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: */

View File

@@ -1,35 +1,30 @@
/* crypt.c */
/* it just contains the shit necessary to make blowfish-cbc work ... */
/*
* 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.
*/
Copyright 2003 Aris Adamantiadis
This file is part of the SSH Library
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 <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#ifdef OPENSSL_CRYPTO
#include <openssl/blowfish.h>
#include <openssl/evp.h>
@@ -40,174 +35,86 @@
#include "libssh/crypto.h"
u32 packet_decrypt_len(SSH_SESSION *session, char *crypted){
u32 decrypted;
if (session->current_crypto) {
if (packet_decrypt(session, crypted,
session->current_crypto->in_cipher->blocksize) < 0) {
return 0;
}
}
memcpy(&decrypted,crypted,sizeof(decrypted));
ssh_log(session, SSH_LOG_PACKET,
"Packet size decrypted: %lu (0x%lx)",
(long unsigned int) ntohl(decrypted),
(long unsigned int) ntohl(decrypted));
return ntohl(decrypted);
u32 decrypted;
if(session->current_crypto)
packet_decrypt(session,crypted,session->current_crypto->in_cipher->blocksize);
memcpy(&decrypted,crypted,sizeof(decrypted));
ssh_log(session,SSH_LOG_PACKET,"packet size decrypted : %d (0x%lx)",ntohl(decrypted),ntohl(decrypted));
return ntohl(decrypted);
}
int packet_decrypt(SSH_SESSION *session, void *data,u32 len) {
struct crypto_struct *crypto = session->current_crypto->in_cipher;
char *out = NULL;
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;
}
ssh_log(session,SSH_LOG_PACKET, "Decrypting %d bytes", len);
int packet_decrypt(SSH_SESSION *session, void *data,u32 len){
struct crypto_struct *crypto=session->current_crypto->in_cipher;
char *out=malloc(len);
ssh_log(session,SSH_LOG_PACKET,"Decrypting %d bytes",len);
#ifdef HAVE_LIBGCRYPT
if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey,
session->current_crypto->decryptIV) < 0) {
SAFE_FREE(out);
return -1;
}
crypto->cbc_decrypt(crypto,data,out,len);
crypto->set_decrypt_key(crypto,session->current_crypto->decryptkey,session->current_crypto->decryptIV);
crypto->cbc_decrypt(crypto,data,out,len);
#elif defined HAVE_LIBCRYPTO
if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey) < 0) {
SAFE_FREE(out);
return -1;
}
crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
crypto->set_decrypt_key(crypto,session->current_crypto->decryptkey);
crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
#endif
memcpy(data,out,len);
memset(out,0,len);
SAFE_FREE(out);
return 0;
}
unsigned char *packet_encrypt(SSH_SESSION *session, void *data, u32 len) {
struct crypto_struct *crypto = NULL;
HMACCTX ctx = NULL;
char *out = NULL;
unsigned int finallen;
u32 seq;
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;
}
seq = ntohl(session->send_seq);
crypto = session->current_crypto->out_cipher;
ssh_log(session, SSH_LOG_PACKET,
"Encrypting packet with seq num: %d, len: %d",
session->send_seq,len);
#ifdef HAVE_LIBGCRYPT
if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey,
session->current_crypto->encryptIV) < 0) {
SAFE_FREE(out);
return NULL;
}
#elif defined HAVE_LIBCRYPTO
if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey) < 0) {
SAFE_FREE(out);
return NULL;
}
#endif
if (session->version == 2) {
ctx = hmac_init(session->current_crypto->encryptMAC,20,HMAC_SHA1);
if (ctx == NULL) {
SAFE_FREE(out);
return NULL;
}
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));
hmac_update(ctx,data,len);
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("mac: ",data,len);
if (finallen != 20) {
printf("Final len is %d\n",finallen);
}
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20);
#endif
}
#ifdef HAVE_LIBGCRYPT
crypto->cbc_encrypt(crypto, data, out, len);
#elif defined HAVE_LIBCRYPTO
crypto->cbc_encrypt(crypto, data, out, len,
session->current_crypto->encryptIV);
#endif
memcpy(data, out, len);
memset(out, 0, 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
* occured.
*/
int packet_hmac_verify(SSH_SESSION *session, BUFFER *buffer,
unsigned char *mac) {
unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0};
HMACCTX ctx;
unsigned int len;
u32 seq;
ctx = hmac_init(session->current_crypto->decryptMAC, 20, HMAC_SHA1);
if (ctx == NULL) {
return -1;
}
seq = htonl(session->recv_seq);
hmac_update(ctx, (unsigned char *) &seq, sizeof(u32));
hmac_update(ctx, buffer_get(buffer), buffer_get_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(u32));
#endif
if (memcmp(mac, hmacbuf, len) == 0) {
memcpy(data,out,len);
memset(out,0,len);
free(out);
return 0;
}
return -1;
}
unsigned char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){
struct crypto_struct *crypto;
HMACCTX ctx;
char *out;
unsigned int finallen;
u32 seq=ntohl(session->send_seq);
if(!session->current_crypto)
return NULL; /* nothing to do here */
crypto= session->current_crypto->out_cipher;
ssh_log(session,SSH_LOG_PACKET,"encrypting packet with seq num: %d, len: %d",session->send_seq,len);
#ifdef HAVE_LIBGCRYPT
crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey,session->current_crypto->encryptIV);
#elif defined HAVE_LIBCRYPTO
crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey);
#endif
out=malloc(len);
if(session->version==2){
ctx=hmac_init(session->current_crypto->encryptMAC,20,HMAC_SHA1);
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));
hmac_update(ctx,data,len);
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("mac :",data,len);
if(finallen!=20)
printf("Final len is %d\n",finallen);
ssh_print_hexa("packet hmac",session->current_crypto->hmacbuf,20);
#endif
}
#ifdef HAVE_LIBGCRYPT
crypto->cbc_encrypt(crypto,data,out,len);
#elif defined HAVE_LIBCRYPTO
crypto->cbc_encrypt(crypto,data,out,len,session->current_crypto->encryptIV);
#endif
memcpy(data,out,len);
memset(out,0,len);
free(out);
if(session->version==2)
return session->current_crypto->hmacbuf;
else
return NULL;
}
/* vim: set ts=2 sw=2 et cindent: */
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,unsigned char *mac){
HMACCTX ctx;
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
unsigned int len;
u32 seq=htonl(session->recv_seq);
ctx=hmac_init(session->current_crypto->decryptMAC,20,HMAC_SHA1);
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));
hmac_update(ctx,buffer_get(buffer),buffer_get_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(u32));
#endif
return memcmp(mac,hmacbuf,len);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,95 +1,79 @@
/*
* 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.
*/
Copyright 2003-2008 Aris Adamantiadis
This file is part of the SSH Library
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 <stdio.h>
#include <stdarg.h>
#include "libssh/priv.h"
/**
* @defgroup ssh_error SSH Errors
*
* @brief Functions for error handling.
/** \defgroup ssh_error SSH Errors
* \brief error handling
*/
/**
* @addtogroup ssh_error
/** \addtogroup ssh_error
* @{
*/
/**
* @internal
*
* @brief Registers an error with a description.
*
* @param error The class of 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 *descr, ...) {
struct error_struct *err = error;
va_list va;
va_start(va, descr);
vsnprintf(err->error_buffer, ERROR_BUFFERLEN, descr, va);
va_end(va);
err->error_code = code;
static int verbosity;
/* ssh_set_error registers an error with a description. the error code is the class of error, and description is obvious.*/
void ssh_set_error(void *error,int code,char *descr,...){
struct error_struct *err= error;
va_list va;
va_start(va,descr);
vsnprintf(err->error_buffer,ERROR_BUFFERLEN,descr,va);
va_end(va);
err->error_code=code;
}
/**
* @brief Retrieve the error text message from the last error.
*
* @param error The SSH session pointer.
*
* @return A static string describing the error.
/** \brief retrieve an error text message
* \param error the ssh session pointer
* \return a static string describing the error
*/
const char *ssh_get_error(void *error) {
struct error_struct *err = error;
return err->error_buffer;
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 The SSH session pointer.
*
* \return SSH_NO_ERROR No error occured\n
* SSH_REQUEST_DENIED The last request was denied but situation is
* recoverable\n
* SSH_FATAL A fatal error occured. This could be an unexpected
* disconnection\n
*
* \nOther error codes are internal but can be considered same than
* SSH_FATAL.
/** \brief retrieve the error code from the last
* error
* \param error the ssh session pointer
* \return SSH_NO_ERROR no error occured\n
* SSH_REQUEST_DENIED The last request was denied but situation
* is recoverable\n
* SSH_FATAL A fatal error occured. 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;
int ssh_get_error_code(void *error){
struct error_struct *err=error;
return err->error_code;
}
return err->error_code;
void ssh_say(int priority, const char *format, ...){
va_list va;
va_start(va,format);
if(priority <= verbosity)
vfprintf(stderr,format,va);
va_end(va);
}
void ssh_set_verbosity(int num){
verbosity=num;
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,99 +1,76 @@
/*
* 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.
*/
/* gcrypt_missing.c */
/* This file contains routines that are in OpenSSL but not in libgcrypt */
/*
Copyright 2003,04,06 Aris Adamantiadis
This file is part of the SSH Library
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 <stdlib.h>
#include "libssh/priv.h"
#ifdef HAVE_LIBGCRYPT
int my_gcry_dec2bn(bignum *bn, const char *data) {
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++) {
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;
char *my_gcry_bn2dec(bignum bn)
{
int count, count2;
int size, rsize;
char *ret;
bignum bndup, num, ten;
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)) {
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--) {
else
{
for (bndup = gcry_mpi_copy(bn), ten = bignum_new(), num = bignum_new(),
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--)
;
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 (count = 0; count < rsize && ret[count] == '0'; ++count)
;
for (count2 = 0; count2 < rsize - count; ++count2) {
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: */

View File

@@ -1,216 +1,141 @@
/* gzip.c */
/* include hooks for compression of packets */
/*
* 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 <mail@cynapses.org>
*
* 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.
*/
Copyright 2003 Aris Adamantiadis
#include "config.h"
This file is part of the SSH Library
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/priv.h"
#ifdef HAVE_LIBZ
#undef NO_GZIP
#else
#define NO_GZIP
#endif
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
#ifndef NO_GZIP
#include <zlib.h>
#include <string.h>
#include <stdlib.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 z_stream *initcompress(SSH_SESSION *session,int level){
z_stream *stream=malloc(sizeof(z_stream));
int status;
memset(stream,0,sizeof(z_stream));
status=deflateInit(stream,level);
if (status!=0)
ssh_set_error(session,SSH_FATAL,"status %d inititalising zlib deflate",status);
return stream;
}
static BUFFER *gzip_compress(SSH_SESSION *session,BUFFER *source,int level){
z_stream *zout = session->current_crypto->compress_out_ctx;
void *in_ptr = buffer_get(source);
unsigned long in_size = buffer_get_len(source);
BUFFER *dest = NULL;
static unsigned char out_buf[BLOCKSIZE] = {0};
unsigned long len;
int status;
BUFFER *gzip_compress(SSH_SESSION *session,BUFFER *source,int level){
BUFFER *dest;
static unsigned char out_buf[BLOCKSIZE];
void *in_ptr=buffer_get(source);
unsigned long in_size=buffer_get_len(source);
unsigned long len;
int status;
z_stream *zout=session->current_crypto->compress_out_ctx;
if(!zout)
zout=session->current_crypto->compress_out_ctx=initcompress(session,level);
dest=buffer_new();
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 !=0){
ssh_set_error(session,SSH_FATAL,"status %d deflating zlib packet",status);
return NULL;
}
len=BLOCKSIZE-zout->avail_out;
buffer_add_data(dest,out_buf,len);
zout->next_out=out_buf;
} while (zout->avail_out == 0);
if(zout == NULL) {
zout = session->current_crypto->compress_out_ctx = initcompress(session, level);
if (zout == NULL) {
return NULL;
}
}
dest = 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) {
buffer_free(dest);
ssh_set_error(session, SSH_FATAL,
"status %d deflating zlib packet", status);
return NULL;
}
len = BLOCKSIZE - zout->avail_out;
if (buffer_add_data(dest, out_buf, len) < 0) {
buffer_free(dest);
return NULL;
}
zout->next_out = out_buf;
} while (zout->avail_out == 0);
return dest;
return dest;
}
int compress_buffer(SSH_SESSION *session, BUFFER *buf) {
BUFFER *dest = NULL;
dest = gzip_compress(session, buf, 9);
if (dest == NULL) {
return -1;
}
if (buffer_reinit(buf) < 0) {
int compress_buffer(SSH_SESSION *session,BUFFER *buf){
BUFFER *dest=gzip_compress(session,buf,9);
if(!dest)
return -1;
buffer_reinit(buf);
buffer_add_data(buf,buffer_get(dest),buffer_get_len(dest));
buffer_free(dest);
return -1;
}
if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
buffer_free(dest);
return -1;
}
buffer_free(dest);
return 0;
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 z_stream *initdecompress(SSH_SESSION *session){
z_stream *stream=malloc(sizeof(z_stream));
int status;
memset(stream,0,sizeof(z_stream));
status=inflateInit(stream);
if (status!=0){
ssh_set_error(session,SSH_FATAL,"Status = %d initiating inflate context !",status);
free(stream);
stream=NULL;
}
return stream;
}
static BUFFER *gzip_decompress(SSH_SESSION *session, BUFFER *source) {
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);
static unsigned char out_buf[BLOCKSIZE] = {0};
BUFFER *dest = NULL;
unsigned long len;
int status;
BUFFER *gzip_decompress(SSH_SESSION *session,BUFFER *source){
BUFFER *dest;
static unsigned char out_buf[BLOCKSIZE];
void *in_ptr=buffer_get_rest(source);
unsigned long in_size=buffer_get_rest_len(source);
unsigned long len;
int status;
z_stream *zin=session->current_crypto->compress_in_ctx;
if(!zin)
zin=session->current_crypto->compress_in_ctx=initdecompress(session);
dest=buffer_new();
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){
ssh_set_error(session,SSH_FATAL,"status %d inflating zlib packet",status);
buffer_free(dest);
return NULL;
}
len=BLOCKSIZE-zin->avail_out;
buffer_add_data(dest,out_buf,len);
zin->next_out=out_buf;
} while (zin->avail_out == 0);
if (zin == NULL) {
zin = session->current_crypto->compress_in_ctx = initdecompress(session);
if (zin == NULL) {
return NULL;
}
}
dest = 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) {
ssh_set_error(session, SSH_FATAL,
"status %d inflating zlib packet", status);
buffer_free(dest);
return NULL;
}
len = BLOCKSIZE - zin->avail_out;
if (buffer_add_data(dest,out_buf,len) < 0) {
buffer_free(dest);
return NULL;
}
zin->next_out = out_buf;
} while (zin->avail_out == 0);
return dest;
return dest;
}
int decompress_buffer(SSH_SESSION *session,BUFFER *buf){
BUFFER *dest = NULL;
dest = gzip_decompress(session,buf);
if (dest == NULL) {
return -1;
}
if (buffer_reinit(buf) < 0) {
BUFFER *dest=gzip_decompress(session,buf);
buffer_reinit(buf);
if(!dest){
return -1; /* failed */
}
buffer_reinit(buf);
buffer_add_data(buf,buffer_get(dest),buffer_get_len(dest));
buffer_free(dest);
return -1;
}
if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
buffer_free(dest);
return -1;
}
buffer_free(dest);
return 0;
return 0;
}
#endif /* HAVE_LIBZ && WITH_LIBZ */
/* vim: set ts=2 sw=2 et cindent: */
#endif /* NO_GZIP */

View File

@@ -1,61 +1,40 @@
/* init.c */
/* This file handles initialization and finalization of the library */
/*
* init.c - initialization and finalization of the library
*
* 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.
*/
Copyright 2003,04,06 Aris Adamantiadis
This file is part of the SSH Library
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/priv.h"
#ifdef _WIN32
#include <winsock2.h>
#endif
/**
* \addtogroup ssh_session
* @{
*/
/**
* @brief initialize global cryptographic data structures.
*
* This function should only be called once, at the begining of the program, in the main thread. It may be omitted if your program is not multithreaded.
*
* @returns 0
* \brief finalize and cleanup all libssh and cryptographic data structures
* \returns 0
*/
int ssh_init(void) {
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 -1 in case of error
@returns 0 otherwise
*/
int ssh_finalize(void) {
int ssh_finalize()
{
ssh_crypto_finalize();
#ifdef HAVE_LIBGCRYPT
gcry_control(GCRYCTL_TERM_SECMEM);
@@ -71,4 +50,3 @@ int ssh_finalize(void) {
/**
* @}
*/
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,35 +1,27 @@
/* kex.c is used well, in key exchange :-) */
/*
* 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.
*/
Copyright (c) 2003-2008 Aris Adamantiadis
This file is part of the SSH Library
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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "config.h"
#include "libssh/priv.h"
#include "libssh/ssh2.h"
#include "libssh/ssh1.h"
@@ -52,68 +44,31 @@
#define DES "3des-cbc"
#endif
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
#ifdef HAVE_LIBZ
#define ZLIB "none,zlib"
#else
#define ZLIB "none"
#endif
const char *default_methods[] = {
"diffie-hellman-group1-sha1",
"ssh-dss,ssh-rsa",
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha1",
"hmac-sha1",
"none",
"none",
"",
"",
NULL
};
const char *supported_methods[] = {
"diffie-hellman-group1-sha1",
"ssh-dss,ssh-rsa",
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha1",
"hmac-sha1",
ZLIB,
ZLIB,
"",
"",
NULL
};
char *default_methods[]={
"diffie-hellman-group1-sha1","ssh-dss,ssh-rsa",AES BLOWFISH DES,AES BLOWFISH
DES, "hmac-sha1","hmac-sha1","none","none","","",NULL };
char *supported_methods[]={
"diffie-hellman-group1-sha1","ssh-dss,ssh-rsa",AES BLOWFISH DES,AES BLOWFISH
DES, "hmac-sha1","hmac-sha1",ZLIB,ZLIB,"","",NULL };
/* descriptions of the key exchange packet */
const char *ssh_kex_nums[] = {
"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
};
char *ssh_kex_nums[]={
"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;
char *tmp = strdup(chain);
char *ptr = tmp;
while(*ptr){
if(*ptr==','){
n++;
@@ -123,10 +78,6 @@ static char **tokenize(const char *chain){
}
/* 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<n;i++){
tokens[i]=ptr;
@@ -139,20 +90,12 @@ static char **tokenize(const char *chain){
}
/* same as tokenize(), but with spaces instead of ',' */
/* TODO FIXME rewrite me! */
char **space_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;
char *tmp = strdup(chain);
char *ptr = tmp;
while(*ptr==' ')
++ptr; /* skip initial spaces */
while(*ptr){
@@ -166,11 +109,7 @@ char **space_tokenize(const char *chain){
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;
}
tokens=malloc(sizeof(char *) * (n+1) ); /* +1 for the null */
ptr=tmp; /* we don't pass the initial spaces because the "tmp" pointer is needed by the caller */
/* function to free the tokens. */
for(i=0;i<n;i++){
@@ -195,26 +134,17 @@ char *ssh_find_matching(const char *in_d, const char *what_d){
char ** tok_in, **tok_what;
int i_in, i_what;
char *ret;
if ((in_d == NULL) || (what_d == NULL)) {
return NULL; /* don't deal with null args */
}
tok_in = tokenize(in_d);
if (tok_in == NULL) {
return NULL;
}
tok_what = tokenize(what_d);
if (tok_what == NULL) {
SAFE_FREE(tok_in[0]);
SAFE_FREE(tok_in);
}
if( ! (in_d && what_d))
return NULL; /* don't deal with null args */
ssh_say(3,"find_matching(\"%s\",\"%s\") = ",in_d,what_d);
tok_in=tokenize(in_d);
tok_what=tokenize(what_d);
for(i_in=0; tok_in[i_in]; ++i_in){
for(i_what=0; tok_what[i_what] ; ++i_what){
if(!strcmp(tok_in[i_in],tok_what[i_what])){
/* match */
ssh_say(3,"\"%s\"\n",tok_in[i_in]);
ret=strdup(tok_in[i_in]);
/* free the tokens */
free(tok_in[0]);
@@ -225,6 +155,7 @@ char *ssh_find_matching(const char *in_d, const char *what_d){
}
}
}
ssh_say(3,"NULL\n");
free(tok_in[0]);
free(tok_what[0]);
free(tok_in);
@@ -232,96 +163,55 @@ char *ssh_find_matching(const char *in_d, const char *what_d){
return NULL;
}
int ssh_get_kex(SSH_SESSION *session, int server_kex) {
STRING *str = NULL;
char *strings[10];
int i;
enter_function();
if (packet_wait(session, SSH2_MSG_KEXINIT, 1) != SSH_OK) {
int ssh_get_kex(SSH_SESSION *session,int server_kex ){
STRING *str;
char *strings[10];
int i;
enter_function();
if(packet_wait(session,SSH2_MSG_KEXINIT,1)){
leave_function();
return -1;
}
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,16)!=16){
ssh_set_error(session,SSH_FATAL,"get_kex(): no cookie in packet");
leave_function();
return -1;
}
hashbufin_add_cookie(session,session->server_kex.cookie);
memset(strings,0,sizeof(char *)*10);
for(i=0;i<10;++i){
str=buffer_get_ssh_string(session->in_buffer);
if(!str)
break;
if(str){
buffer_add_ssh_string(session->in_hashbuf,str);
strings[i]=string_to_char(str);
free(str);
} else
strings[i]=NULL;
}
/* copy the server kex info into an array of strings */
if(server_kex){
session->client_kex.methods=malloc( 10 * sizeof(char **));
for(i=0;i<10;++i)
session->client_kex.methods[i]=strings[i];
} else { // client
session->server_kex.methods=malloc( 10 * sizeof(char **));
for(i=0;i<10;++i)
session->server_kex.methods[i]=strings[i];
}
leave_function();
return -1;
}
if (buffer_get_data(session->in_buffer,session->server_kex.cookie,16) != 16) {
ssh_set_error(session, SSH_FATAL, "get_kex(): no cookie in packet");
leave_function();
return -1;
}
if (hashbufin_add_cookie(session, session->server_kex.cookie) < 0) {
ssh_set_error(session, SSH_FATAL, "get_kex(): adding cookie failed");
leave_function();
return -1;
}
memset(strings, 0, sizeof(char *) * 10);
for (i = 0; i < 10; i++) {
str = buffer_get_ssh_string(session->in_buffer);
if (str == NULL) {
break;
}
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
goto error;
}
strings[i] = string_to_char(str);
if (strings[i] == NULL) {
goto error;
}
string_free(str);
str = NULL;
}
/* copy the server kex info into an array of strings */
if (server_kex) {
session->client_kex.methods = malloc(10 * sizeof(char **));
if (session->client_kex.methods == NULL) {
leave_function();
return -1;
}
for (i = 0; i < 10; i++) {
session->client_kex.methods[i] = strings[i];
}
} else { /* client */
session->server_kex.methods = malloc(10 * sizeof(char **));
if (session->server_kex.methods == NULL) {
leave_function();
return -1;
}
for (i = 0; i < 10; i++) {
session->server_kex.methods[i] = strings[i];
}
}
leave_function();
return 0;
error:
string_free(str);
for (i = 0; i < 10; i++) {
SAFE_FREE(strings[i]);
}
leave_function();
return -1;
return 0;
}
void ssh_list_kex(struct ssh_session *session, KEX *kex) {
int i = 0;
void ssh_list_kex(KEX *kex){
int i=0;
#ifdef DEBUG_CRYPTO
ssh_print_hexa("session cookie", kex->cookie, 16);
ssh_print_hexa("session cookie",kex->cookie,16);
#endif
for(i = 0; i < 10; i++) {
ssh_log(session, SSH_LOG_FUNCTIONS, "%s: %s",
ssh_kex_nums[i], kex->methods[i]);
}
for(i=0;i<10;i++){
ssh_say(2,"%s : %s\n",ssh_kex_nums[i],kex->methods[i]);
}
}
/* set_kex basicaly look at the option structure of the session and set the output kex message */
@@ -333,7 +223,7 @@ int set_kex(SSH_SESSION *session){
KEX *client=&session->client_kex;
SSH_OPTIONS *options=session->options;
int i;
const char *wanted;
char *wanted;
enter_function();
/* the client might ask for a specific cookie to be sent. useful for server debugging */
if(options->wanted_cookie)
@@ -341,11 +231,6 @@ int set_kex(SSH_SESSION *session){
else
ssh_get_random(client->cookie,16,0);
client->methods=malloc(10 * sizeof(char **));
if (client->methods == NULL) {
ssh_set_error(session, SSH_FATAL, "No space left");
leave_function();
return -1;
}
memset(client->methods,0,10*sizeof(char **));
for (i=0;i<10;i++){
if(!(wanted=options->wanted_methods[i]))
@@ -357,76 +242,35 @@ int set_kex(SSH_SESSION *session){
leave_function();
return -1;
} else {
if ((i >= SSH_LANG_C_S) && (client->methods[i] == NULL)) {
/* we can safely do that for languages */
client->methods[i] = strdup("");
if (client->methods[i] == NULL) {
return -1;
}
}
if(i>=SSH_LANG_C_S && !client->methods[i])
client->methods[i]=strdup(""); // we can safely do that for languages
}
}
leave_function();
return 0;
}
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(SSH_SESSION *session, int server_kex) {
KEX *kex = (server_kex ? &session->server_kex : &session->client_kex);
STRING *str = NULL;
int i;
enter_function();
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
goto error;
}
if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
goto error;
}
if (hashbufout_add_cookie(session) < 0) {
goto error;
}
ssh_list_kex(session, kex);
for (i = 0; i < 10; i++) {
str = string_from_char(kex->methods[i]);
if (str == NULL) {
goto error;
/* this function only sends the predefined set of kex methods */
void ssh_send_kex(SSH_SESSION *session, int server_kex){
STRING *str;
int i=0;
KEX *kex=(server_kex ? &session->server_kex : &session->client_kex);
enter_function();
buffer_add_u8(session->out_buffer,SSH2_MSG_KEXINIT);
buffer_add_data(session->out_buffer,kex->cookie,16);
hashbufout_add_cookie(session);
ssh_list_kex(kex);
for(i=0;i<10;i++){
str=string_from_char(kex->methods[i]);
buffer_add_ssh_string(session->out_hashbuf,str);
buffer_add_ssh_string(session->out_buffer,str);
free(str);
}
if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) {
goto error;
}
if (buffer_add_ssh_string(session->out_buffer, str) < 0) {
goto error;
}
string_free(str);
}
if (buffer_add_u8(session->out_buffer, 0) < 0) {
goto error;
}
if (buffer_add_u32(session->out_buffer, 0) < 0) {
goto error;
}
if (packet_send(session) != SSH_OK) {
i=0;
buffer_add_u8(session->out_buffer,0);
buffer_add_u32(session->out_buffer,0);
packet_send(session);
leave_function();
return -1;
}
leave_function();
return 0;
error:
buffer_reinit(session->out_buffer);
buffer_reinit(session->out_hashbuf);
string_free(str);
leave_function();
return -1;
}
/* returns 1 if at least one of the name algos is in the default algorithms table */
@@ -445,58 +289,33 @@ int verify_existing_algo(int algo, const char *name){
/* makes a STRING contating 3 strings : ssh-rsa1,e and n */
/* this is a public key in openssh's format */
static STRING *make_rsa1_string(STRING *e, STRING *n){
BUFFER *buffer = NULL;
STRING *rsa = NULL;
STRING *ret = NULL;
buffer = buffer_new();
rsa = string_from_char("ssh-rsa1");
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 = string_new(buffer_get_len(buffer));
if (ret == NULL) {
goto error;
}
string_fill(ret, buffer_get(buffer), buffer_get_len(buffer));
error:
buffer_free(buffer);
string_free(rsa);
return ret;
BUFFER *buffer=buffer_new();
STRING *rsa=string_from_char("ssh-rsa1");
STRING *ret;
buffer_add_ssh_string(buffer,rsa);
free(rsa);
buffer_add_ssh_string(buffer,e);
buffer_add_ssh_string(buffer,n);
ret=string_new(buffer_get_len(buffer));
string_fill(ret,buffer_get(buffer),buffer_get_len(buffer));
buffer_free(buffer);
return ret;
}
static int build_session_id1(SSH_SESSION *session, STRING *servern,
STRING *hostn) {
MD5CTX md5 = NULL;
md5 = md5_init();
if (md5 == NULL) {
return -1;
}
static void build_session_id1(SSH_SESSION *session, STRING *servern,
STRING *hostn){
MD5CTX md5=md5_init();
#ifdef DEBUG_CRYPTO
ssh_print_hexa("host modulus",hostn->string,string_len(hostn));
ssh_print_hexa("server modulus",servern->string,string_len(servern));
ssh_print_hexa("host modulus",hostn->string,string_len(hostn));
ssh_print_hexa("server modulus",servern->string,string_len(servern));
#endif
md5_update(md5,hostn->string,string_len(hostn));
md5_update(md5,servern->string,string_len(servern));
md5_update(md5,session->server_kex.cookie,8);
md5_final(session->next_crypto->session_id,md5);
md5_update(md5,hostn->string,string_len(hostn));
md5_update(md5,servern->string,string_len(servern));
md5_update(md5,session->server_kex.cookie,8);
md5_final(session->next_crypto->session_id,md5);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN);
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 */
@@ -529,65 +348,39 @@ static int modulus_smaller(PUBLIC_KEY *k1, PUBLIC_KEY *k2){
}
#define ABS(A) ( (A)<0 ? -(A):(A) )
static STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *srvkey,
PUBLIC_KEY *hostkey, int slen, int hlen) {
unsigned char buffer[32] = {0};
int i;
STRING *data1 = NULL;
STRING *data2 = 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);
STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *svrkey,
PUBLIC_KEY *hostkey,int slen, int hlen ){
unsigned char buffer[32];
int i;
STRING *data1,*data2;
/* 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);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("session key",buffer,32);
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 = string_new(32);
if (data1 == NULL) {
return NULL;
}
string_fill(data1, buffer, 32);
if (ABS(hlen - slen) < 128){
ssh_log(session, 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);
string_free(data1);
data1 = NULL;
if (data2 == NULL) {
return NULL;
/* xor session key with session_id */
for (i=0;i<16;++i)
buffer[i]^=session->next_crypto->session_id[i];
data1=string_new(32);
string_fill(data1,buffer,32);
if(ABS(hlen-slen)<128){
ssh_say(1,"Difference between server modulus and host modulus is only %d. It's illegal and may not work\n",
ABS(hlen-slen));
}
data1 = ssh_encrypt_rsa1(session, data2, hostkey);
string_free(data2);
if (data1 == NULL) {
return NULL;
if(modulus_smaller(svrkey,hostkey)){
data2=ssh_encrypt_rsa1(session,data1,svrkey);
free(data1);
data1=ssh_encrypt_rsa1(session,data2,hostkey);
} else {
data2=ssh_encrypt_rsa1(session,data1,hostkey);
free(data1);
data1=ssh_encrypt_rsa1(session,data2,svrkey);
}
} else {
data2 = ssh_encrypt_rsa1(session, data1, hostkey);
string_free(data1);
data1 = NULL;
if (data2 == NULL) {
return NULL;
}
data1 = ssh_encrypt_rsa1(session, data2, srvkey);
string_free(data2);
if (data1 == NULL) {
return NULL;
}
}
return data1;
return data1;
}
@@ -606,186 +399,116 @@ static STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *srvkey,
* 32-bit int supported_authentications_mask
*/
int ssh_get_kex1(SSH_SESSION *session) {
STRING *server_exp = NULL;
STRING *server_mod = NULL;
STRING *host_exp = NULL;
STRING *host_mod = NULL;
STRING *serverkey = NULL;
STRING *hostkey = NULL;
STRING *enc_session = NULL;
PUBLIC_KEY *srv = NULL;
PUBLIC_KEY *host = NULL;
u32 server_bits;
u32 host_bits;
u32 protocol_flags;
u32 supported_ciphers_mask;
u32 supported_authentications_mask;
u16 bits;
int rc = -1;
int ko;
int ssh_get_kex1(SSH_SESSION *session){
u32 server_bits, host_bits, protocol_flags,
supported_ciphers_mask, supported_authentications_mask;
STRING *server_exp=NULL;
STRING *server_mod=NULL;
STRING *host_exp=NULL;
STRING *host_mod=NULL;
STRING *serverkey;
STRING *hostkey;
STRING *enc_session;
PUBLIC_KEY *svr,*host;
int ko;
u16 bits;
enter_function();
ssh_log(session,SSH_LOG_PROTOCOL,"Waiting for a SSH_SMSG_PUBLIC_KEY");
if(packet_wait(session,SSH_SMSG_PUBLIC_KEY,1)){
leave_function();
return -1;
}
ssh_log(session,SSH_LOG_PROTOCOL,"Got a SSH_SMSG_PUBLIC_KEY");
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,8)!=8){
ssh_set_error(session,SSH_FATAL,"Can't get cookie in buffer");
leave_function();
return -1;
}
buffer_get_u32(session->in_buffer,&server_bits);
server_exp=buffer_get_mpint(session->in_buffer);
server_mod=buffer_get_mpint(session->in_buffer);
buffer_get_u32(session->in_buffer,&host_bits);
host_exp=buffer_get_mpint(session->in_buffer);
host_mod=buffer_get_mpint(session->in_buffer);
buffer_get_u32(session->in_buffer,&protocol_flags);
buffer_get_u32(session->in_buffer,&supported_ciphers_mask);
ko=buffer_get_u32(session->in_buffer,&supported_authentications_mask);
if((ko!=sizeof(u32)) || !host_mod || !host_exp || !server_mod || !server_exp){
ssh_log(session,SSH_LOG_RARE,"Invalid SSH_SMSG_PUBLIC_KEY packet");
ssh_set_error(session,SSH_FATAL,"Invalid SSH_SMSG_PUBLIC_KEY packet");
if(host_mod)
free(host_mod);
if(host_exp)
free(host_exp);
if(server_mod)
free(server_mod);
if(server_exp)
free(server_exp);
leave_function();
return -1;
}
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(session,SSH_LOG_PROTOCOL,"server bits: %d ; host bits: %d Protocol flags : %.8lx ; "
"cipher mask : %.8lx ; auth mask: %.8lx",server_bits,
host_bits,protocol_flags,supported_ciphers_mask,
supported_authentications_mask);
serverkey=make_rsa1_string(server_exp,server_mod);
hostkey=make_rsa1_string(host_exp,host_mod);
build_session_id1(session,server_mod,host_mod);
free(server_exp);
free(server_mod);
free(host_exp);
free(host_mod);
svr=publickey_from_string(session, serverkey);
host=publickey_from_string(session, hostkey);
session->next_crypto->server_pubkey=string_copy(hostkey);
session->next_crypto->server_pubkey_type="ssh-rsa1";
enter_function();
ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
if (packet_wait(session, SSH_SMSG_PUBLIC_KEY, 1) != SSH_OK) {
/* now, we must choose an encryption algo */
/* hardcode 3des */
if(!(supported_ciphers_mask & (1<<SSH_CIPHER_3DES))){
ssh_set_error(session,SSH_FATAL,"Remote server doesn't accept 3des");
leave_function();
return -1;
}
ssh_log(session,SSH_LOG_PROTOCOL,"sending SSH_CMSG_SESSION_KEY");
buffer_add_u8(session->out_buffer,SSH_CMSG_SESSION_KEY);
buffer_add_u8(session->out_buffer,SSH_CIPHER_3DES);
buffer_add_data(session->out_buffer,session->server_kex.cookie,8);
enc_session=encrypt_session_key(session,svr,host,server_bits, host_bits);
bits=string_len(enc_session)*8 - 7;
ssh_log(session,SSH_LOG_PROTOCOL,"%d bits,%d bytes encrypted session",bits,string_len(enc_session));
bits=htons(bits);
/* the encrypted mpint */
buffer_add_data(session->out_buffer,&bits,sizeof(u16));
buffer_add_data(session->out_buffer,enc_session->string,
string_len(enc_session));
/* the protocol flags */
buffer_add_u32(session->out_buffer,0);
packet_send(session);
/* we can set encryption */
if(crypt_set_algorithms(session)){
leave_function();
return -1;
}
session->current_crypto=session->next_crypto;
session->next_crypto=NULL;
ssh_log(session,SSH_LOG_PROTOCOL,"Waiting for a SSH_SMSG_SUCCESS");
if(packet_wait(session,SSH_SMSG_SUCCESS,1)){
char buffer[1024];
snprintf(buffer,sizeof(buffer),"Key exchange failed : %s",ssh_get_error(session));
ssh_set_error(session,SSH_FATAL,"%s",buffer);
leave_function();
return -1;
}
ssh_log(session,SSH_LOG_PROTOCOL,"received SSH_SMSG_SUCCESS\n");
leave_function();
return -1;
}
ssh_log(session, SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY");
if (buffer_get_data(session->in_buffer, session->server_kex.cookie, 8) != 8) {
ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer");
leave_function();
return -1;
}
buffer_get_u32(session->in_buffer, &server_bits);
server_exp = buffer_get_mpint(session->in_buffer);
if (server_exp == NULL) {
goto error;
}
server_mod = buffer_get_mpint(session->in_buffer);
if (server_mod == NULL) {
goto error;
}
buffer_get_u32(session->in_buffer, &host_bits);
host_exp = buffer_get_mpint(session->in_buffer);
if (host_exp == NULL) {
goto error;
}
host_mod = buffer_get_mpint(session->in_buffer);
if (host_mod == NULL) {
goto error;
}
buffer_get_u32(session->in_buffer, &protocol_flags);
buffer_get_u32(session->in_buffer, &supported_ciphers_mask);
ko = buffer_get_u32(session->in_buffer, &supported_authentications_mask);
if ((ko != sizeof(u32)) || !host_mod || !host_exp
|| !server_mod || !server_exp) {
ssh_log(session, 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(session, 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 (serverkey == 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 = 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 */
if (!(supported_ciphers_mask & (1 << SSH_CIPHER_3DES))) {
ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
goto error;
}
ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY");
if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
goto error;
}
if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
goto error;
}
if (buffer_add_data(session->out_buffer, session->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 = string_len(enc_session) * 8 - 7;
ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session",
bits, string_len(enc_session));
bits = htons(bits);
/* the encrypted mpint */
if (buffer_add_data(session->out_buffer, &bits, sizeof(u16)) < 0) {
goto error;
}
if (buffer_add_data(session->out_buffer, enc_session->string,
string_len(enc_session)) < 0) {
goto error;
}
/* the protocol flags */
if (buffer_add_u32(session->out_buffer, 0) < 0) {
goto error;
}
if (packet_send(session) != SSH_OK) {
goto error;
}
/* we can set encryption */
if (crypt_set_algorithms(session)) {
goto error;
}
session->current_crypto = session->next_crypto;
session->next_crypto = NULL;
ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
if (packet_wait(session,SSH_SMSG_SUCCESS,1) != SSH_OK) {
char buffer[1024] = {0};
snprintf(buffer, sizeof(buffer),
"Key exchange failed: %s", ssh_get_error(session));
ssh_set_error(session, SSH_FATAL, "%s",buffer);
goto error;
}
ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");
rc = 0;
error:
string_free(host_mod);
string_free(host_exp);
string_free(server_mod);
string_free(server_exp);
string_free(serverkey);
string_free(hostkey);
publickey_free(srv);
publickey_free(host);
leave_function();
return rc;
return 0;
}
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,188 +0,0 @@
SSH_0.3 {
global:
buffer_free;
buffer_get;
buffer_get_len;
buffer_new;
channel_change_pty_size;
channel_close;
channel_free;
channel_get_exit_status;
channel_get_session;
channel_is_closed;
channel_is_eof;
channel_is_open;
channel_new;
channel_open_forward;
channel_open_session;
channel_poll;
channel_read;
channel_read_buffer;
channel_read_nonblocking;
channel_request_env;
channel_request_exec;
channel_request_pty;
channel_request_pty_size;
channel_request_sftp;
channel_request_shell;
channel_request_subsystem;
channel_select;
channel_send_eof;
channel_set_blocking;
channel_write;
privatekey_free;
privatekey_from_file;
publickey_free;
publickey_from_file;
publickey_from_privatekey;
publickey_to_string;
sftp_async_read;
sftp_async_read_begin;
sftp_attributes_free;
sftp_canonicalize_path;
sftp_chmod;
sftp_chown;
sftp_close;
sftp_closedir;
sftp_dir_eof;
sftp_file_set_blocking;
sftp_file_set_nonblocking;
sftp_free;
sftp_fstat;
sftp_get_error;
sftp_init;
sftp_lstat;
sftp_mkdir;
sftp_new;
sftp_open;
sftp_opendir;
sftp_read;
sftp_readdir;
sftp_readlink;
sftp_rename;
sftp_rewind;
sftp_rmdir;
sftp_seek;
sftp_seek64;
sftp_server_init;
sftp_server_new;
sftp_server_version;
sftp_setstat;
sftp_stat;
sftp_symlink;
sftp_tell;
sftp_tell64;
sftp_unlink;
sftp_utimes;
sftp_write;
ssh_accept;
ssh_auth_list;
ssh_bind_accept;
ssh_bind_fd_toaccept;
ssh_bind_free;
ssh_bind_get_fd;
ssh_bind_listen;
ssh_bind_new;
ssh_bind_set_blocking;
ssh_bind_set_fd;
ssh_bind_set_options;
ssh_clean_pubkey_hash;
ssh_connect;
ssh_copyright;
ssh_disconnect;
ssh_fd_poll;
ssh_finalize;
ssh_get_disconnect_message;
ssh_get_error;
ssh_get_error_code;
ssh_get_fd;
ssh_get_hexa;
ssh_get_issue_banner;
ssh_get_openssh_version;
ssh_get_pubkey;
ssh_get_pubkey_hash;
ssh_get_random;
ssh_get_status;
ssh_get_version;
ssh_mkdir;
ssh_basename;
ssh_dirname;
ssh_init;
ssh_is_server_known;
ssh_log;
ssh_message_auth_password;
ssh_message_auth_publickey;
ssh_message_auth_reply_pk_ok;
ssh_message_auth_reply_success;
ssh_message_auth_set_methods;
ssh_message_auth_user;
ssh_message_channel_request_open_reply_accept;
ssh_message_channel_request_reply_success;
ssh_message_free;
ssh_message_get;
ssh_message_reply_default;
ssh_message_retrieve;
ssh_message_service_reply_success;
ssh_message_service_service;
ssh_message_subtype;
ssh_message_type;
ssh_new;
ssh_options_allow_ssh1;
ssh_options_allow_ssh2;
ssh_options_copy;
ssh_options_free;
ssh_options_getopt;
ssh_options_new;
ssh_options_set_auth_callback;
ssh_options_set_banner;
ssh_options_set_bind;
ssh_options_set_dsa_server_key;
ssh_options_set_fd;
ssh_options_set_host;
ssh_options_set_identity;
ssh_options_set_known_hosts_file;
ssh_options_set_log_function;
ssh_options_set_log_verbosity;
ssh_options_set_port;
ssh_options_set_rsa_server_key;
ssh_options_set_ssh_dir;
ssh_options_set_status_callback;
ssh_options_set_timeout;
ssh_options_set_username;
ssh_options_set_wanted_algos;
ssh_print_hexa;
ssh_select;
ssh_service_request;
ssh_set_blocking;
ssh_set_fd_except;
ssh_set_fd_toread;
ssh_set_fd_towrite;
ssh_set_options;
ssh_silent_disconnect;
ssh_userauth_agent_pubkey;
ssh_userauth_autopubkey;
ssh_userauth_kbdint;
ssh_userauth_kbdint_getinstruction;
ssh_userauth_kbdint_getname;
ssh_userauth_kbdint_getnprompts;
ssh_userauth_kbdint_getprompt;
ssh_userauth_kbdint_setanswer;
ssh_userauth_list;
ssh_userauth_none;
ssh_userauth_offer_pubkey;
ssh_userauth_password;
ssh_userauth_pubkey;
ssh_version;
ssh_write_knownhost;
string_burn;
string_copy;
string_data;
string_fill;
string_free;
string_from_char;
string_len;
string_new;
string_to_char;
local:
*;
};

61
libssh/libssh.vers Normal file
View File

@@ -0,0 +1,61 @@
SSH_0.2 {
global:
ssh_get_error; ssh_get_error_code; ssh_say; ssh_set_verbosity;
ssh_new; ssh_set_options; ssh_get_fd; ssh_silent_disconnect;
ssh_connect; ssh_disconnect; ssh_service_request; ssh_get_issue_banner;
ssh_copyright; ssh_get_version; ssh_finalize;
ssh_set_fd_toread; ssh_set_fd_towrite; ssh_set_fd_except;
string_from_char; string_len; string_new; string_fill; string_to_char;
string_copy; string_burn; string_data;
ssh_crypto_init;
ssh_print_hexa; ssh_get_random;
ssh_get_pubkey_hash; ssh_get_pubkey;
ssh_fd_poll; ssh_select; publickey_free;
privatekey_from_file; publickey_to_string; publickey_from_privatekey;
private_key_free; publickey_from_file; publickey_from_next_file;
ssh_is_server_known; ssh_write_knownhost;
channel_new; channel_open_forward; channel_open_session; channel_free;
channel_request_pty; channel_request_pty_size; channel_change_pty_size;
channel_request_shell; channel_request_subsystem; channel_request_env;
channel_request_exec; channel_request_sftp; channel_write;
channel_send_eof; channel_read; channel_poll; channel_close;
channel_read_nonblocking; channel_is_open;
channel_is_closed; channel_is_eof; channel_select;
ssh_options_new; ssh_options_copy; ssh_options_set_wanted_algos;
ssh_options_set_username; ssh_options_set_port; ssh_options_getopt;
ssh_options_set_host; ssh_options_set_fd; ssh_options_set_bind;
ssh_options_set_identity; ssh_options_set_status_callback;
ssh_options_set_timeout; ssh_options_set_ssh_dir;
ssh_options_set_known_hosts_file; ssh_options_allow_ssh1;
ssh_options_allow_ssh2; ssh_options_set_dsa_server_key;
ssh_options_set_rsa_server_key;
buffer_new; buffer_free; buffer_get; buffer_get_len;
ssh_userauth_none; ssh_userauth_password; ssh_userauth_offer_pubkey;
ssh_userauth_pubkey; ssh_userauth_autopubkey; ssh_userauth_kbdint;
ssh_userauth_kbdint_getnprompts; ssh_userauth_kbdint_getname;
ssh_userauth_kbdint_getinstruction; ssh_userauth_kbdint_getprompt;
ssh_userauth_kbdint_setanswer;
sftp_new; sftp_free; sftp_init; sftp_opendir; sftp_readdir; sftp_dir_eof;
sftp_stat; sftp_lstat; sftp_fstat; sftp_attributes_free; sftp_dir_close;
sftp_file_close; sftp_open; sftp_read; sftp_write; sftp_seek; sftp_tell;
sftp_rewind; sftp_rm; sftp_rmdir; sftp_mkdir; sftp_rename; sftp_setstat;
sftp_canonicalize_path; sftp_server_new; sftp_server_init;
sftp_get_client_message; sftp_client_message_free; sftp_reply_name;
sftp_reply_handle; sftp_handle_alloc; sftp_reply_attr; sftp_handle;
sftp_reply_status; sftp_reply_names_add; sftp_reply_names;
sftp_reply_data; sftp_handle_remove;
ssh_bind_new; ssh_bind_set_options; ssh_bind_listen; ssh_bind_set_blocking;
ssh_bind_get_fd; ssh_bind_set_toaccept; ssh_bind_accept; ssh_bind_free;
ssh_accept;
ssh_message_get; ssh_message_type; ssh_message_subtype;
ssh_message_reply_default; ssh_message_free; ssh_message_auth_user;
ssh_message_auth_password; ssh_message_auth_reply_success;
ssh_message_auth_set_methods;
ssh_message_channel_request_open_reply_accept;
ssh_message_channel_request_channel; ssh_message_channel_request_pty_term;
ssh_message_channel_request_subsystem;
ssh_message_channel_request_reply_success;
set_encrypt_key; set_decrypt_key; cbc_encrypt; cbc_decrypt;
local:
*;
};

View File

@@ -1,10 +1,8 @@
/*
* log.c - logging and debugging functions
* Copyright 2008 Aris Adamantiadis
*
* This file is part of the SSH Library
*
* Copyright (c) 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
@@ -18,61 +16,46 @@
* 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.
*/
* MA 02111-1307, USA. */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "libssh/priv.h"
/**
* @defgroup ssh_log SSH Logging
*
* @brief Logging functions for debugging and problem resolving
/** \defgroup ssh_log SSH logging
* \brief Logging functions for debugging and problem resolving
*/
/** \addtogroup ssh_log
* @{ */
/**
* @brief Log a SSH event.
*
* @param session The SSH session.
*
* @param verbosity The verbosity of the event.
*
* @param format The format string of the log entry.
#include "libssh/priv.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
/** \brief logs an event
* \param session the SSH session
* \param verbosity verbosity of the event
* \param format format string of the log entry
*/
void ssh_log(SSH_SESSION *session, int verbosity, const char *format, ...) {
char buffer[1024];
char indent[256];
int min;
va_list va;
if (verbosity <= session->log_verbosity) {
va_start(va, format);
vsnprintf(buffer, sizeof(buffer), format, va);
va_end(va);
if (session->options->log_function) {
session->options->log_function(buffer, session, verbosity);
} else if (verbosity == SSH_LOG_FUNCTIONS) {
if (session->log_indent > 255) {
min = 255;
} else {
min = session->log_indent;
}
memset(indent, ' ', min);
indent[min] = '\0';
fprintf(stderr, "[func] %s%s\n", indent, buffer);
} else {
fprintf(stderr, "[%d] %s\n", verbosity, buffer);
}
}
void ssh_log(SSH_SESSION *session, int verbosity, char *format, ...){
char buffer[1024];
char buf2[256];
int min;
va_list va;
if(verbosity <= session->log_verbosity){
va_start(va,format);
vsnprintf(buffer,sizeof(buffer),format,va);
va_end(va);
if(session->options->log_function)
session->options->log_function(buffer,session,verbosity);
else if(verbosity==SSH_LOG_FUNCTIONS){
if(session->log_indent > 255)
min=255;
else
min=session->log_indent;
memset(buf2,' ',min);
buf2[min]=0;
fprintf(stderr,"[func] %s%s\n",buf2,buffer);
} else {
fprintf(stderr,"[%d] %s\n",verbosity,buffer);
}
}
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -10,7 +10,6 @@
* 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.
*
@@ -35,151 +34,142 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#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) {
for (;;) {
/* If at end of pattern, accept if also at end of string. */
if (!*pattern) {
return !*s;
}
if (*pattern == '*') {
/* Skip the asterisk. */
pattern++;
int
match_pattern(const char *s, const char *pattern)
{
for (;;) {
/* If at end of pattern, accept if also at end of string. */
if (!*pattern)
return !*s;
/* If at end of pattern, accept immediately. */
if (!*pattern)
return 1;
if (*pattern == '*') {
/* Skip the asterisk. */
pattern++;
/* 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;
}
/* If at end of pattern, accept immediately. */
if (!*pattern)
return 1;
/* Check if the next character of the string is acceptable. */
if (*pattern != '?' && *pattern != *s) {
return 0;
}
/* 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;
/* Move to the next character, both in string and in pattern. */
s++;
pattern++;
}
/* Check if the next character of the string is acceptable. */
if (*pattern != '?' && *pattern != *s)
return 0;
/* NOTREACHED */
/* 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.
* 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;
}
int
match_pattern_list(const char *string, const char *pattern, u_int len,
int dolower)
{
char sub[1024];
int negated;
int got_positive;
u_int i, subi;
/*
* 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];
}
got_positive = 0;
for (i = 0; i < len;) {
/* Check if the subpattern is negated. */
if (pattern[i] == '!') {
negated = 1;
i++;
} else
negated = 0;
/* If subpattern too long, return failure (no match). */
if (subi >= sizeof(sub) - 1) {
return 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++;
}
/* If the subpattern was terminated by a comma, skip the comma. */
if (i < len && pattern[i] == ',')
i++;
/* Null-terminate the subpattern. */
sub[subi] = '\0';
/* 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 */
}
}
}
/* 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;
/*
* 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.
* 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);
int
match_hostname(const char *host, const char *pattern, u_int len)
{
return match_pattern_list(host, pattern, len, 1);
}
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,287 +1,86 @@
/* misc.c */
/* some misc routines than aren't really part of the ssh protocols but can be useful to the client */
/*
* misc.c - useful client functions
*
* This file is part of the SSH Library
*
* Copyright (c) 2003 by Aris Adamantiadis
* Copyright (c) 2008-2009 by Andreas Schneider <mail@cynapses.org>
*
* 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.
*/
Copyright 2003 Aris Adamantiadis
This file is part of the SSH Library
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 <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "config.h"
#ifdef _WIN32
#define _WIN32_IE 0x0501 //SHGetSpecialFolderPath
#define _WIN32_IE 0x0400 //SHGetSpecialFolderPath
#include <shlobj.h>
#include <winsock2.h>
#include <direct.h>
#else
#include <pwd.h>
#include <arpa/inet.h>
#endif
#include "libssh/priv.h"
#include "libssh/libssh.h"
#ifdef HAVE_LIBGCRYPT
#define GCRYPT_STRING "/gnutls"
#else
#define GCRYPT_STRING ""
#endif
#ifndef _WIN32
char *ssh_get_user_home_dir(){
static char szPath[PATH_MAX] = {0};
struct passwd *pwd = NULL;
#ifdef HAVE_LIBCRYPTO
#define CRYPTO_STRING "/openssl"
#else
#define CRYPTO_STRING ""
#endif
pwd = getpwuid(getuid());
if (pwd == NULL) {
return NULL;
}
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
#define LIBZ_STRING "/zlib"
#else
#define LIBZ_STRING ""
#endif
snprintf(szPath, PATH_MAX - 1, "%s", pwd->pw_dir);
/** \defgroup ssh_misc SSH Misc
* \brief Misc functions
*/
/** \addtogroup ssh_misc
* @{ */
#ifdef _WIN32
char *ssh_get_user_home_dir(void) {
static char szPath[MAX_PATH] = {0};
if (SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, TRUE)) {
return szPath;
}
return NULL;
}
#else /* _WIN32 */
char *ssh_get_user_home_dir(void) {
static char szPath[PATH_MAX] = {0};
struct passwd *pwd = NULL;
pwd = getpwuid(getuid());
if (pwd == NULL) {
return NULL;
}
snprintf(szPath, PATH_MAX - 1, "%s", pwd->pw_dir);
return szPath;
char *ssh_get_user_home_dir(){
static char szPath[MAX_PATH];
if (SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, TRUE))
return szPath;
else
return NULL;
}
#endif
/* we have read access on file */
int ssh_file_readaccess_ok(const char *file) {
if (access(file, R_OK) < 0) {
int ssh_file_readaccess_ok(char *file){
if(!access(file,R_OK))
return 1;
return 0;
}
return 1;
}
u64 ntohll(u64 a) {
u64 ntohll(u64 a){
#ifdef WORDS_BIGENDIAN
return a;
return a;
#else
u32 low = a & 0xffffffff;
u32 high = a >> 32 ;
low = ntohl(low);
high = ntohl(high);
return ((((u64) low) << 32) | ( high));
u32 low=a & 0xffffffff;
u32 high = a >> 32 ;
low=ntohl(low);
high=ntohl(high);
return (( ((u64)low) << 32) | ( high));
#endif
}
/**
* @brief Check if libssh is the required version or get the version
* string.
*
* @param 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
LIBZ_STRING;
}
return NULL;
}
/**
* @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 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;
unsigned int 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 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;
unsigned int 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 pathname The path name to create the directory.
*
* @param 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;
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,206 +0,0 @@
/*
* poll.c - poll wrapper
*
* 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.
*
* vim: ts=2 sw=2 et cindent
*/
/* This code is based on glib's gpoll */
#include <errno.h>
#include "config.h"
#include "libssh/priv.h"
#ifdef HAVE_POLL
#include <poll.h>
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout) {
return poll((struct pollfd *) fds, nfds, timeout);
}
#else /* HAVE_POLL */
#ifdef _WIN32
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
#include <winsock2.h>
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout) {
return WSAPoll(fds, nfds, timeout);
}
#else /* _WIN32_WINNT */
#ifndef STRICT
#define STRICT
#endif
#include <stdio.h>
#include <windows.h>
static int poll_rest (HANDLE *handles, int nhandles,
pollfd_t *fds, nfds_t nfds, int timeout) {
DWORD ready;
pollfd_t *f;
int recursed_result;
if (nhandles == 0) {
/* No handles to wait for, just the timeout */
if (timeout == INFINITE) {
ready = WAIT_FAILED;
} else {
SleepEx(timeout, 1);
ready = WAIT_TIMEOUT;
}
} else {
/* Wait for just handles */
ready = WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
#if 0
if (ready == WAIT_FAILED) {
fprintf(stderr, "WaitForMultipleObjectsEx failed: %d\n", GetLastError());
}
#endif
}
if (ready == WAIT_FAILED) {
return -1;
} else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
return 0;
} else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles) {
for (f = fds; f < &fds[nfds]; f++) {
if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
f->revents = f->events;
}
}
/*
* If no timeout and polling several handles, recurse to poll
* the rest of them.
*/
if (timeout == 0 && nhandles > 1) {
/* Remove the handle that fired */
int i;
if (ready < nhandles - 1) {
for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
handles[i-1] = handles[i];
}
}
nhandles--;
recursed_result = poll_rest(handles, nhandles, fds, nfds, 0);
if (recursed_result < 0) {
return -1;
}
return recursed_result + 1;
}
return 1;
}
return 0;
}
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout) {
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
pollfd_t *f;
int nhandles = 0;
int rc = -1;
if (fds == NULL) {
errno = EFAULT;
return -1;
}
if (nfds >= MAXIMUM_WAIT_OBJECTS) {
errno = EINVAL;
return -1;
}
for (f = fds; f < &fds[nfds]; f++) {
if (f->fd > 0) {
int i;
/*
* Don't add the same handle several times into the array, as
* docs say that is not allowed, even if it actually does seem
* to work.
*/
for (i = 0; i < nhandles; i++) {
if (handles[i] == (HANDLE) f->fd) {
break;
}
}
if (i == nhandles) {
if (nhandles == MAXIMUM_WAIT_OBJECTS) {
break;
} else {
handles[nhandles++] = (HANDLE) f->fd;
}
}
}
}
if (timeout == -1) {
timeout = INFINITE;
}
if (nhandles > 1) {
/*
* First check if one or several of them are immediately
* available.
*/
rc = poll_rest(handles, nhandles, fds, nfds, 0);
/*
* If not, and we have a significant timeout, poll again with
* timeout then. Note that this will return indication for only
* one event, or only for messages. We ignore timeouts less than
* ten milliseconds as they are mostly pointless on Windows, the
* MsgWaitForMultipleObjectsEx() call will timeout right away
* anyway.
*/
if (rc == 0 && (timeout == INFINITE || timeout >= 10)) {
rc = poll_rest(handles, nhandles, fds, nfds, timeout);
}
} else {
/*
* Just polling for one thing, so no need to check first if
* available immediately
*/
rc = poll_rest(handles, nhandles, fds, nfds, timeout);
}
if (rc < 0) {
for (f = fds; f < &fds[nfds]; f++) {
f->revents = 0;
}
errno = EBADF;
}
return rc;
}
#endif /* _WIN32_WINNT */
#endif /* _WIN32 */
#endif /* HAVE_POLL */

View File

@@ -1,25 +1,23 @@
/* server.c */
/*
* server.c - functions for creating a SSH server
*
* 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.
*/
Copyright 2004,2005 Aris Adamantiadis
This file is part of the SSH Library
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 ssh_server SSH Server
@@ -27,489 +25,279 @@
* @{
*/
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#ifdef _WIN32
#include <winsock2.h>
#define SOCKOPT_TYPE_ARG4 char
/* We need to provide hstrerror. Not we can't call the parameter h_errno because it's #defined */
inline char* hstrerror(int h_errno_val) {
static char text[50];
snprintf(text,sizeof(text),"gethostbyname error %d\n", h_errno_val);
return text;
}
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define SOCKOPT_TYPE_ARG4 int
#endif
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "libssh/priv.h"
#include "libssh/libssh.h"
#include "libssh/server.h"
#include "libssh/ssh2.h"
#ifdef _WIN32
#include <winsock2.h>
#define SOCKOPT_TYPE_ARG4 char
/* We need to provide hstrerror. Not we can't call the parameter h_errno because it's #defined */
inline char *hstrerror(int h_errno_val) {
static char text[50] = {0};
snprintf(text, sizeof(text), "gethostbyname error %d\n", h_errno_val);
return text;
}
#else /* _WIN32 */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define SOCKOPT_TYPE_ARG4 int
#endif /* _WIN32 */
/* TODO FIXME: must use getaddrinfo */
static socket_t bind_socket(SSH_BIND *ssh_bind, const char *hostname,
int port) {
struct sockaddr_in myaddr;
struct hostent *hp=NULL;
socket_t s;
int opt = 1;
s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
ssh_set_error(ssh_bind, SSH_FATAL, "%s", strerror(errno));
return -1;
}
// TODO: must use getaddrinfo
static socket_t bind_socket(SSH_BIND *ssh_bind,char *hostname, int port) {
struct sockaddr_in myaddr;
int opt = 1;
socket_t s = socket(PF_INET, SOCK_STREAM, 0);
struct hostent *hp=NULL;
#ifdef HAVE_GETHOSTBYNAME
hp = gethostbyname(hostname);
hp=gethostbyname(hostname);
#endif
if (hp == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL,
"Resolving %s: %s", hostname, hstrerror(h_errno));
close(s);
return -1;
}
memset(&myaddr, 0, sizeof(myaddr));
memcpy(&myaddr.sin_addr, hp->h_addr, hp->h_length);
myaddr.sin_family = hp->h_addrtype;
myaddr.sin_port = htons(port);
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
"Setting socket options failed: %s", hstrerror(h_errno));
close(s);
return -1;
}
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
ssh_set_error(ssh_bind, SSH_FATAL, "Binding to %s:%d: %s",
hostname,
port,
strerror(errno));
close(s);
return -1;
}
return s;
}
SSH_BIND *ssh_bind_new(void) {
SSH_BIND *ptr;
ptr = malloc(sizeof(SSH_BIND));
if (ptr == NULL) {
return NULL;
}
ZERO_STRUCTP(ptr);
ptr->bindfd = -1;
return ptr;
}
void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options) {
ssh_bind->options = options;
}
int ssh_bind_listen(SSH_BIND *ssh_bind) {
const char *host;
int fd;
if (ssh_bind->options == NULL) {
return -1;
}
if (ssh_init() < 0) {
return -1;
}
host = ssh_bind->options->bindaddr;
if (host == NULL) {
host = "0.0.0.0";
}
fd = bind_socket(ssh_bind, host, ssh_bind->options->bindport);
if (fd < 0) {
return -1;
}
ssh_bind->bindfd = fd;
if (listen(fd, 10) < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
"Listening to socket %d: %s",
fd, strerror(errno));
close(fd);
return -1;
}
return 0;
}
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking) {
ssh_bind->blocking = blocking ? 1 : 0;
}
socket_t ssh_bind_get_fd(SSH_BIND *ssh_bind) {
return ssh_bind->bindfd;
}
void ssh_bind_set_fd(SSH_BIND *ssh_bind, socket_t fd) {
ssh_bind->bindfd = fd;
}
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind) {
ssh_bind->toaccept = 1;
}
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind) {
SSH_SESSION *session;
PRIVATE_KEY *dsa = NULL;
PRIVATE_KEY *rsa = NULL;
int fd = -1;
if (ssh_bind->bindfd < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
"Can't accept new clients on a not bound socket.");
return NULL;
}
if (ssh_bind->options->dsakey == NULL || ssh_bind->options->rsakey == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL,
"DSA or RSA host key file must be set before accept()");
return NULL;
}
if (ssh_bind->options->dsakey) {
dsa = _privatekey_from_file(ssh_bind, ssh_bind->options->dsakey, TYPE_DSS);
if (dsa == NULL) {
return NULL;
if(!hp){
ssh_set_error(ssh_bind,SSH_FATAL,"resolving %s: %s",hostname,hstrerror(h_errno));
close(s);
return -1;
}
}
if (ssh_bind->options->rsakey) {
rsa = _privatekey_from_file(ssh_bind, ssh_bind->options->rsakey, TYPE_RSA);
if (rsa == NULL) {
privatekey_free(dsa);
return NULL;
memset(&myaddr, 0, sizeof(myaddr));
memcpy(&myaddr.sin_addr,hp->h_addr,hp->h_length);
myaddr.sin_family=hp->h_addrtype;
myaddr.sin_port = htons(port);
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
ssh_set_error(ssh_bind,SSH_FATAL,"Binding to %s:%d : %s",hostname,port,
strerror(errno));
close(s);
return -1;
}
}
return s;
}
fd = accept(ssh_bind->bindfd, NULL, NULL);
if (fd < 0) {
ssh_set_error(ssh_bind, SSH_FATAL,
"Accepting a new connection: %s",
strerror(errno));
privatekey_free(dsa);
privatekey_free(rsa);
return NULL;
}
SSH_BIND *ssh_bind_new(){
SSH_BIND *ptr=malloc(sizeof(SSH_BIND));
memset(ptr,0,sizeof(*ptr));
ptr->bindfd=-1;
return ptr;
}
session = ssh_new();
if (session == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL, "Not enough space");
privatekey_free(dsa);
privatekey_free(rsa);
return NULL;
}
session->server = 1;
session->version = 2;
session->options = ssh_options_copy(ssh_bind->options);
if (session->options == NULL) {
ssh_set_error(ssh_bind, SSH_FATAL, "No space left");
privatekey_free(dsa);
privatekey_free(rsa);
ssh_cleanup(session);
return NULL;
}
void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options){
ssh_bind->options=options;
}
ssh_socket_free(session->socket);
session->socket = ssh_socket_new(session);
if (session->socket == NULL) {
privatekey_free(dsa);
privatekey_free(rsa);
ssh_cleanup(session);
return NULL;
}
ssh_socket_set_fd(session->socket,fd);
session->dsa_key = dsa;
session->rsa_key = rsa;
int ssh_bind_listen(SSH_BIND *ssh_bind){
char *host;
int fd;
if(!ssh_bind->options)
return -1;
ssh_socket_init();
host=ssh_bind->options->bindaddr;
if(!host)
host="0.0.0.0";
fd=bind_socket(ssh_bind,host,ssh_bind->options->bindport);
if(fd<0)
return -1;
ssh_bind->bindfd=fd;
if(listen(fd,10)<0){
ssh_set_error(ssh_bind,SSH_FATAL,"listening to socket %d: %s",
fd,strerror(errno));
close(fd);
return -1;
}
return 0;
}
return session;
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking){
ssh_bind->blocking=blocking?1:0;
}
int ssh_bind_get_fd(SSH_BIND *ssh_bind){
return ssh_bind->bindfd;
}
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind){
ssh_bind->toaccept=1;
}
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind){
SSH_SESSION *session;
PRIVATE_KEY *dsa=NULL, *rsa=NULL;
if(ssh_bind->bindfd<0){
ssh_set_error(ssh_bind,SSH_FATAL,"Can't accept new clients on a "
"not bound socket.");
return NULL;
}
if(!ssh_bind->options->dsakey && !ssh_bind->options->rsakey){
ssh_set_error(ssh_bind,SSH_FATAL,"DSA or RSA host key file must be set before accept()");
return NULL;
}
if(ssh_bind->options->dsakey){
dsa=_privatekey_from_file(ssh_bind,ssh_bind->options->dsakey,TYPE_DSS);
if(!dsa)
return NULL;
ssh_say(2,"Dsa private key read successfuly\n");
}
if(ssh_bind->options->rsakey){
rsa=_privatekey_from_file(ssh_bind,ssh_bind->options->rsakey,TYPE_RSA);
if(!rsa){
if(dsa)
private_key_free(dsa);
return NULL;
}
ssh_say(2,"RSA private key read successfuly\n");
}
int fd=accept(ssh_bind->bindfd,NULL,NULL);
if(fd<0){
ssh_set_error(ssh_bind,SSH_FATAL,"Accepting a new connection: %s",
strerror(errno));
if(dsa)
private_key_free(dsa);
if(rsa)
private_key_free(rsa);
return NULL;
}
session=ssh_new();
session->server=1;
session->version=2;
ssh_socket_free(session->socket);
session->socket=ssh_socket_new(session);
ssh_socket_set_fd(session->socket,fd);
session->options=ssh_options_copy(ssh_bind->options);
session->dsa_key=dsa;
session->rsa_key=rsa;
return session;
}
void ssh_bind_free(SSH_BIND *ssh_bind){
if (ssh_bind == NULL) {
return;
}
if (ssh_bind->bindfd >= 0) {
close(ssh_bind->bindfd);
}
ssh_bind->bindfd = -1;
if (ssh_bind->options) {
ssh_options_free(ssh_bind->options);
}
SAFE_FREE(ssh_bind);
if(ssh_bind->bindfd>=0)
close(ssh_bind->bindfd);
ssh_bind->bindfd=-1;
if(ssh_bind->options)
ssh_options_free(ssh_bind->options);
free(ssh_bind);
}
extern char *supported_methods[];
static int server_set_kex(SSH_SESSION * session) {
KEX *server = &session->server_kex;
SSH_OPTIONS *options = session->options;
int i, j;
char *wanted;
ZERO_STRUCTP(server);
/*
* The program might ask for a specific cookie to be sent. Useful for server
* debugging
*/
if (options->wanted_cookie) {
memcpy(server->cookie, options->wanted_cookie, 16);
} else {
ssh_get_random(server->cookie, 16, 0);
}
if (session->dsa_key != NULL && session->rsa_key != NULL) {
if (ssh_options_set_wanted_algos(options, SSH_HOSTKEYS,
"ssh-dss,ssh-rsa") < 0) {
return -1;
int server_set_kex(SSH_SESSION * session) {
KEX *server = &session->server_kex;
SSH_OPTIONS *options = session->options;
int i;
char *wanted;
memset(server,0,sizeof(KEX));
// the program might ask for a specific cookie to be sent. useful for server
// debugging
if (options->wanted_cookie)
memcpy(server->cookie, options->wanted_cookie, 16);
else
ssh_get_random(server->cookie, 16,0);
if(session->dsa_key && session->rsa_key){
ssh_options_set_wanted_algos(options,SSH_HOSTKEYS,"ssh-dss,ssh-rsa");
} else {
if(session->dsa_key)
ssh_options_set_wanted_algos(options,SSH_HOSTKEYS,"ssh-dss");
else
ssh_options_set_wanted_algos(options,SSH_HOSTKEYS,"ssh-rsa");
}
} else if (session->dsa_key != NULL) {
if (ssh_options_set_wanted_algos(options, SSH_HOSTKEYS, "ssh-dss") < 0) {
return -1;
server->methods = malloc(10 * sizeof(char **));
for (i = 0; i < 10; i++) {
if (!(wanted = options->wanted_methods[i]))
wanted = supported_methods[i];
server->methods[i] = strdup(wanted);
//printf("server->methods[%d]=%s\n",i,wanted);
}
} else {
if (ssh_options_set_wanted_algos(options, SSH_HOSTKEYS, "ssh-rsa") < 0) {
return -1;
}
}
server->methods = malloc(10 * sizeof(char **));
if (server->methods == NULL) {
return -1;
}
for (i = 0; i < 10; i++) {
if ((wanted = options->wanted_methods[i]) == NULL) {
wanted = supported_methods[i];
}
server->methods[i] = strdup(wanted);
if (server->methods[i] == NULL) {
for (j = i - 1; j <= 0; j--) {
SAFE_FREE(server->methods[j]);
}
SAFE_FREE(server->methods);
return -1;
}
}
return 0;
return 0;
}
static int dh_handshake_server(SSH_SESSION *session) {
STRING *e;
STRING *f;
STRING *pubkey;
STRING *sign;
PUBLIC_KEY *pub;
PRIVATE_KEY *prv;
static int dh_handshake_server(SSH_SESSION *session){
STRING *e,*f,*pubkey,*sign;
PUBLIC_KEY *pub;
PRIVATE_KEY *prv;
BUFFER *buf=buffer_new();
if(packet_wait(session, SSH2_MSG_KEXDH_INIT ,1))
return -1;
e=buffer_get_ssh_string(session->in_buffer);
if(!e){
ssh_set_error(session,SSH_FATAL,"No e number in client request");
return -1;
}
dh_import_e(session,e);
free(e);
dh_generate_y(session);
dh_generate_f(session);
f=dh_get_f(session);
switch(session->hostkeys){
case TYPE_DSS:
prv=session->dsa_key;
break;
case TYPE_RSA:
prv=session->rsa_key;
break;
default:
prv=NULL;
}
pub=publickey_from_privatekey(prv);
pubkey=publickey_to_string(pub);
publickey_free(pub);
dh_import_pubkey(session,pubkey);
dh_build_k(session);
make_sessionid(session);
sign=ssh_sign_session_id(session,prv);
buffer_free(buf);
/* free private keys as they should not be readable past this point */
if(session->rsa_key){
private_key_free(session->rsa_key);
session->rsa_key=NULL;
}
if(session->dsa_key){
private_key_free(session->dsa_key);
session->dsa_key=NULL;
}
buffer_add_u8(session->out_buffer,SSH2_MSG_KEXDH_REPLY);
buffer_add_ssh_string(session->out_buffer,pubkey);
buffer_add_ssh_string(session->out_buffer,f);
buffer_add_ssh_string(session->out_buffer,sign);
free(sign);
packet_send(session);
free(f);
buffer_add_u8(session->out_buffer,SSH2_MSG_NEWKEYS);
packet_send(session);
ssh_say(2,"SSH_MSG_NEWKEYS sent\n");
if (packet_wait(session, SSH2_MSG_KEXDH_INIT, 1) != SSH_OK) {
return -1;
}
e = buffer_get_ssh_string(session->in_buffer);
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");
string_free(e);
return -1;
}
string_free(e);
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;
}
switch(session->hostkeys){
case TYPE_DSS:
prv = session->dsa_key;
break;
case TYPE_RSA:
prv = session->rsa_key;
break;
default:
prv = NULL;
}
pub = publickey_from_privatekey(prv);
if (pub == NULL) {
ssh_set_error(session, SSH_FATAL,
"Could not get the public key from the private key");
string_free(f);
return -1;
}
pubkey = publickey_to_string(pub);
publickey_free(pub);
if (pubkey == NULL) {
ssh_set_error(session, SSH_FATAL, "Not enough space");
string_free(f);
return -1;
}
dh_import_pubkey(session, pubkey);
if (dh_build_k(session) < 0) {
ssh_set_error(session, SSH_FATAL, "Could not import the public key");
string_free(f);
return -1;
}
if (make_sessionid(session) != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
string_free(f);
return -1;
}
sign = ssh_sign_session_id(session, prv);
if (sign == NULL) {
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
string_free(f);
return -1;
}
/* Free private keys as they should not be readable after this point */
if (session->rsa_key) {
privatekey_free(session->rsa_key);
session->rsa_key = NULL;
}
if (session->dsa_key) {
privatekey_free(session->dsa_key);
session->dsa_key = NULL;
}
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 ||
buffer_add_ssh_string(session->out_buffer, pubkey) < 0 ||
buffer_add_ssh_string(session->out_buffer, f) < 0 ||
buffer_add_ssh_string(session->out_buffer, sign) < 0) {
ssh_set_error(session, SSH_FATAL, "Not enough space");
buffer_reinit(session->out_buffer);
string_free(f);
string_free(sign);
return -1;
}
string_free(f);
string_free(sign);
if (packet_send(session) != SSH_OK) {
return -1;
}
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
buffer_reinit(session->out_buffer);
return -1;
}
if (packet_send(session) != SSH_OK) {
return -1;
}
ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
if (packet_wait(session, SSH2_MSG_NEWKEYS, 1) != SSH_OK) {
return -1;
}
ssh_log(session, SSH_LOG_PACKET, "Got SSH_MSG_NEWKEYS");
if (generate_session_keys(session) < 0) {
return -1;
}
/*
* 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) {
return -1;
}
return 0;
packet_wait(session,SSH2_MSG_NEWKEYS,1);
ssh_say(2,"Got SSH_MSG_NEWKEYS\n");
generate_session_keys(session);
/* once we got SSH2_MSG_NEWKEYS we can switch next_crypto and current_crypto */
if(session->current_crypto)
crypto_free(session->current_crypto);
/* XXX later, include a function to change keys */
session->current_crypto=session->next_crypto;
session->next_crypto=crypto_new();
return 0;
}
/* Do the banner and key exchange */
int ssh_accept(SSH_SESSION *session) {
if (ssh_send_banner(session, 1) < 0) {
return -1;
}
session->alive = 1;
session->clientbanner = ssh_get_banner(session);
if (session->clientbanner == NULL) {
return -1;
}
if (server_set_kex(session) < 0) {
return -1;
}
if (ssh_send_kex(session, 1) < 0) {
return -1;
}
if (ssh_get_kex(session,1) < 0) {
return -1;
}
ssh_list_kex(session, &session->client_kex);
crypt_set_algorithms_server(session);
if (dh_handshake_server(session) < 0) {
return -1;
}
session->connected = 1;
return 0;
/* do the banner and key exchange */
int ssh_accept(SSH_SESSION *session){
ssh_send_banner(session,1);
ssh_crypto_init();
session->alive=1;
session->clientbanner=ssh_get_banner(session);
server_set_kex(session);
ssh_send_kex(session,1);
if(ssh_get_kex(session,1))
return -1;
ssh_list_kex(&session->client_kex);
crypt_set_algorithms_server(session);
if(dh_handshake_server(session))
return -1;
session->connected=1;
return 0;
}
/** @}
*/
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -1,10 +1,10 @@
/* session.c */
/* contains the non-networking functions ssh_* */
/*
* session.c - non-networking functions
* Copyright (c) 2005-2008 Aris Adamantiadis
*
* 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
@@ -18,8 +18,7 @@
* 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.
*/
* MA 02111-1307, USA. */
#include <string.h>
#include <stdlib.h>
@@ -37,119 +36,78 @@
/** \brief creates a new ssh session
* \returns new ssh_session pointer
*/
SSH_SESSION *ssh_new(void) {
SSH_SESSION *session;
session = malloc(sizeof (SSH_SESSION));
if (session == NULL) {
return NULL;
}
memset(session, 0, sizeof(SSH_SESSION));
session->next_crypto = crypto_new();
if (session->next_crypto == NULL) {
goto err;
}
session->maxchannel = FIRST_CHANNEL;
session->socket = ssh_socket_new(session);
if (session->socket == NULL) {
goto err;
}
session->alive = 0;
session->auth_methods = 0;
session->blocking = 1;
session->log_indent = 0;
session->out_buffer = buffer_new();
if (session->out_buffer == NULL) {
goto err;
}
session->in_buffer=buffer_new();
if (session->in_buffer == NULL) {
goto err;
}
#ifndef _WIN32
session->agent = agent_new(session);
if (session->agent == NULL) {
goto err;
}
#endif /* _WIN32 */
SSH_SESSION *ssh_new() {
SSH_SESSION *session=malloc(sizeof (SSH_SESSION));
memset(session,0,sizeof(SSH_SESSION));
session->next_crypto=crypto_new();
session->maxchannel=FIRST_CHANNEL;
session->socket=ssh_socket_new(session);
session->alive=0;
session->auth_methods=0;
session->blocking=1;
session->log_indent=0;
session->out_buffer=buffer_new();
session->in_buffer=buffer_new();
return session;
err:
ssh_cleanup(session);
return NULL;
}
void ssh_cleanup(SSH_SESSION *session) {
int i;
enter_function();
if (session == NULL) {
return;
}
SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner);
SAFE_FREE(session->banner);
buffer_free(session->in_buffer);
buffer_free(session->out_buffer);
session->in_buffer=session->out_buffer=NULL;
crypto_free(session->current_crypto);
crypto_free(session->next_crypto);
ssh_socket_free(session->socket);
/* delete all channels */
while (session->channels) {
channel_free(session->channels);
}
#ifndef _WIN32
agent_free(session->agent);
#endif /* _WIN32 */
if (session->client_kex.methods) {
for (i = 0; i < 10; i++) {
SAFE_FREE(session->client_kex.methods[i]);
void ssh_cleanup(SSH_SESSION *session){
enter_function();
int i;
if(session->serverbanner)
free(session->serverbanner);
if(session->clientbanner)
free(session->clientbanner);
if(session->in_buffer)
buffer_free(session->in_buffer);
if(session->out_buffer)
buffer_free(session->out_buffer);
if(session->banner)
free(session->banner);
if(session->options)
ssh_options_free(session->options);
if(session->current_crypto)
crypto_free(session->current_crypto);
if(session->next_crypto)
crypto_free(session->next_crypto);
if(session->socket)
ssh_socket_free(session->socket);
// delete all channels
while(session->channels)
channel_free(session->channels);
if(session->client_kex.methods)
for(i=0;i<10;i++)
if(session->client_kex.methods[i])
free(session->client_kex.methods[i]);
if(session->server_kex.methods)
for(i=0;i<10;++i)
if(session->server_kex.methods[i])
free(session->server_kex.methods[i]);
free(session->client_kex.methods);
free(session->server_kex.methods);
if(session->dsa_key)
private_key_free(session->dsa_key);
if(session->rsa_key)
private_key_free(session->rsa_key);
if(session->ssh_message){
ssh_message_free(session->ssh_message);
free(session->ssh_message);
}
}
if (session->server_kex.methods) {
for (i = 0; i < 10; i++) {
SAFE_FREE(session->server_kex.methods[i]);
}
}
SAFE_FREE(session->client_kex.methods);
SAFE_FREE(session->server_kex.methods);
privatekey_free(session->dsa_key);
privatekey_free(session->rsa_key);
ssh_message_free(session->ssh_message);
ssh_options_free(session->options);
/* burn connection, it could hang sensitive datas */
memset(session,'X',sizeof(SSH_SESSION));
SAFE_FREE(session);
/* FIXME: leave_function(); ??? */
memset(session,'X',sizeof(SSH_SESSION)); /* burn connection, it could hangs
sensitive datas */
free(session);
//leave_function();
}
/** \brief disconnect impolitely from remote host
* \param session current ssh session
*/
void ssh_silent_disconnect(SSH_SESSION *session) {
enter_function();
if (session == NULL) {
return;
}
ssh_socket_close(session->socket);
session->alive = 0;
ssh_disconnect(session);
/* FIXME: leave_function(); ??? */
void ssh_silent_disconnect(SSH_SESSION *session){
enter_function();
ssh_socket_close(session->socket);
session->alive=0;
ssh_disconnect(session);
//leave_function();
}
/** \brief set the options for the current session
@@ -158,13 +116,9 @@ void ssh_silent_disconnect(SSH_SESSION *session) {
* \see ssh_new()
* \see ssh_options_new()
*/
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options) {
if (session == NULL || options == NULL) {
return;
}
session->options = options;
session->log_verbosity = options->log_verbosity;
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options){
session->options=options;
session->log_verbosity=options->log_verbosity;
}
/** \brief set the session in blocking/nonblocking mode
@@ -172,12 +126,8 @@ void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options) {
* \param blocking zero for nonblocking mode
* \bug nonblocking code is in development and won't work as expected
*/
void ssh_set_blocking(SSH_SESSION *session, int blocking) {
if (session == NULL) {
return;
}
session->blocking = blocking ? 1 : 0;
void ssh_set_blocking(SSH_SESSION *session,int blocking){
session->blocking=blocking?1:0;
}
/** In case you'd need the file descriptor of the connection
@@ -187,109 +137,72 @@ void ssh_set_blocking(SSH_SESSION *session, int blocking) {
* \return 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(session->socket);
socket_t ssh_get_fd(SSH_SESSION *session){
return ssh_socket_get_fd(session->socket);
}
/** \brief say to the session it has data to read on the file descriptor without blocking
* \param session ssh session
*/
void ssh_set_fd_toread(SSH_SESSION *session) {
if (session == NULL) {
return;
}
ssh_socket_set_toread(session->socket);
void ssh_set_fd_toread(SSH_SESSION *session){
ssh_socket_set_toread(session->socket);
}
/** \brief say the session it may write to the file descriptor without blocking
* \param session ssh session
*/
void ssh_set_fd_towrite(SSH_SESSION *session) {
if (session == NULL) {
return;
}
void ssh_set_fd_towrite(SSH_SESSION *session){
ssh_socket_set_towrite(session->socket);
ssh_socket_set_towrite(session->socket);
}
/** \brief say the session it has an exception to catch on the file descriptor
* \param session ssh session
*/
void ssh_set_fd_except(SSH_SESSION *session) {
if (session == NULL) {
return;
}
ssh_socket_set_except(session->socket);
void ssh_set_fd_except(SSH_SESSION *session){
ssh_socket_set_except(session->socket);
}
/** \warning I don't remember if this should be internal or not
*/
/* looks if there is data to read on the socket and parse it. */
int ssh_handle_packets(SSH_SESSION *session) {
int w = 0;
int e = 0;
int rc = -1;
enter_function();
do {
rc = ssh_socket_poll(session->socket, &w, &e);
if (rc <= 0) {
/* error or no data available */
leave_function();
return rc;
}
/* if an exception happened, it will be trapped by packet_read() */
if ((packet_read(session) != SSH_OK) ||
(packet_translate(session) != SSH_OK)) {
leave_function();
return -1;
}
packet_parse(session);
} while(rc > 0);
leave_function();
return rc;
int ssh_handle_packets(SSH_SESSION *session){
int w,err,r,i=0;
enter_function();
do {
r=ssh_socket_poll(session->socket,&w,&err);
if(r<=0){
leave_function();
return r; // error or no data available
}
/* if an exception happened, it will be trapped by packet_read() */
if(packet_read(session)||packet_translate(session)){
leave_function();
return -1;
}
packet_parse(session);
++i;
} while(r>0);
leave_function();
return r;
}
/**
* @brief Get session status
*
* @param session The ssh session to use.
*
* @returns A bitmask including SSH_CLOSED, SSH_READ_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.
/** \brief get session status
* \param session ssh session
* \returns a bitmask including SSH_CLOSED, SSH_READ_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->closed) {
r |= SSH_CLOSED;
}
if (socketstate & SSH_READ_PENDING) {
r |= SSH_READ_PENDING;
}
if (session->closed && (socketstate & SSH_CLOSED_ERROR)) {
r |= SSH_CLOSED_ERROR;
}
return r;
int ssh_get_status(SSH_SESSION *session){
int ret=0;
int socketstate=ssh_socket_get_status(session->socket);
if(session->closed)
ret |= SSH_CLOSED;
if(socketstate & SSH_READ_PENDING)
ret |= SSH_READ_PENDING;
if(session->closed && socketstate & SSH_CLOSED_ERROR)
ret |= SSH_CLOSED_ERROR;
return ret;
}
/** \brief get the disconnect message from the server
@@ -297,41 +210,28 @@ int ssh_get_status(SSH_SESSION *session) {
* \return 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) {
const char *ssh_get_disconnect_message(SSH_SESSION *session){
if(!session->closed)
ssh_set_error(session,SSH_REQUEST_DENIED,"Connection not closed"
" yet");
else if(session->closed_by_except)
ssh_set_error(session,SSH_REQUEST_DENIED,"Connection closed by "
"socket error");
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;
}
if (!session->closed) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"Connection not closed yet");
} else if(session->closed_by_except) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"Connection closed by socket error");
} 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.
/** \brief get the protocol version of the session
* \param session ssh session
* \return 1 or 2, for ssh1 or ssh2
*/
int ssh_get_version(SSH_SESSION *session) {
if (session == NULL) {
return -1;
}
return session->version;
int ssh_get_version(SSH_SESSION *session){
return session->version;
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,489 +1,264 @@
/* sftpserver.c contains server based function for the sftp protocol */
/*
* 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.
*/
Copyright 2005 Aris Adamantiadis
This file is part of the SSH Library
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 <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "libssh/libssh.h"
#include "libssh/sftp.h"
#include "libssh/ssh2.h"
#include "libssh/priv.h"
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp) {
SFTP_PACKET *packet;
SFTP_CLIENT_MESSAGE *msg;
BUFFER *payload;
STRING *tmp;
msg = malloc(sizeof (SFTP_CLIENT_MESSAGE));
if (msg == NULL) {
return NULL;
}
ZERO_STRUCTP(msg);
packet = sftp_packet_read(sftp);
if (packet == NULL) {
sftp_client_message_free(msg);
return NULL;
}
payload = packet->payload;
msg->type = packet->type;
msg->sftp = sftp;
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) {
sftp_client_message_free(msg);
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp){
SFTP_PACKET *packet=sftp_packet_read(sftp);
SFTP_CLIENT_MESSAGE *msg=malloc(sizeof (SFTP_CLIENT_MESSAGE));
BUFFER *payload;
STRING *tmp;
memset(msg,0,sizeof(SFTP_CLIENT_MESSAGE));
if(!packet)
return NULL;
}
break;
case SSH_FXP_READ:
msg->handle = buffer_get_ssh_string(payload);
if (msg->handle == NULL) {
sftp_client_message_free(msg);
return NULL;
}
buffer_get_u64(payload, &msg->offset);
buffer_get_u32(payload, &msg->len);
break;
case SSH_FXP_WRITE:
msg->handle = buffer_get_ssh_string(payload);
if (msg->handle == NULL) {
sftp_client_message_free(msg);
return NULL;
}
buffer_get_u64(payload, &msg->offset);
msg->data = buffer_get_ssh_string(payload);
if (msg->data == NULL) {
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:
tmp = buffer_get_ssh_string(payload);
if (tmp == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->filename = string_to_char(tmp);
string_free(tmp);
if (msg->filename == NULL) {
sftp_client_message_free(msg);
return NULL;
}
break;
case SSH_FXP_RENAME:
case SSH_FXP_SYMLINK:
tmp = buffer_get_ssh_string(payload);
if (tmp == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->filename = string_to_char(tmp);
string_free(tmp);
if (msg->filename == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->data = buffer_get_ssh_string(payload);
if (msg->data == NULL) {
sftp_client_message_free(msg);
return NULL;
}
break;
case SSH_FXP_MKDIR:
case SSH_FXP_SETSTAT:
tmp = buffer_get_ssh_string(payload);
if (tmp == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->filename=string_to_char(tmp);
string_free(tmp);
if (msg->filename == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->attr = sftp_parse_attr(sftp, payload, 0);
if (msg->attr == NULL) {
sftp_client_message_free(msg);
return NULL;
}
break;
case SSH_FXP_FSETSTAT:
msg->handle = buffer_get_ssh_string(payload);
if (msg->handle == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->attr = sftp_parse_attr(sftp, payload, 0);
if (msg->attr == NULL) {
sftp_client_message_free(msg);
return NULL;
}
break;
case SSH_FXP_LSTAT:
case SSH_FXP_STAT:
tmp = buffer_get_ssh_string(payload);
if (tmp == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->filename = string_to_char(tmp);
string_free(tmp);
if (msg->filename == NULL) {
sftp_client_message_free(msg);
return NULL;
}
if(sftp->version > 3) {
buffer_get_u32(payload,&msg->flags);
}
break;
case SSH_FXP_OPEN:
tmp=buffer_get_ssh_string(payload);
if (tmp == NULL) {
sftp_client_message_free(msg);
return NULL;
}
msg->filename = string_to_char(tmp);
string_free(tmp);
if (msg->filename == NULL) {
sftp_client_message_free(msg);
return NULL;
}
buffer_get_u32(payload,&msg->flags);
msg->attr = sftp_parse_attr(sftp, payload, 0);
if (msg->attr == NULL) {
sftp_client_message_free(msg);
return NULL;
}
case SSH_FXP_FSTAT:
msg->handle = buffer_get_ssh_string(payload);
if (msg->handle == NULL) {
sftp_client_message_free(msg);
return NULL;
}
buffer_get_u32(payload, &msg->flags);
break;
default:
fprintf(stderr, "Received unhandled sftp message %d\n", msg->type);
}
msg->flags = ntohl(msg->flags);
msg->offset = ntohll(msg->offset);
msg->len = ntohl(msg->len);
sftp_packet_free(packet);
return msg;
payload=packet->payload;
ssh_say(2,"received sftp packet type %d\n",packet->type);
msg->type=packet->type;
msg->sftp=sftp;
buffer_get_u32(payload,&msg->id);
switch(msg->type){
case SSH_FXP_CLOSE:
case SSH_FXP_READDIR:
msg->handle=buffer_get_ssh_string(payload);
break;
case SSH_FXP_READ:
msg->handle=buffer_get_ssh_string(payload);
buffer_get_u64(payload,&msg->offset);
buffer_get_u32(payload,&msg->len);
break;
case SSH_FXP_WRITE:
msg->handle=buffer_get_ssh_string(payload);
buffer_get_u64(payload,&msg->offset);
msg->data=buffer_get_ssh_string(payload);
break;
case SSH_FXP_REMOVE:
case SSH_FXP_RMDIR:
case SSH_FXP_OPENDIR:
case SSH_FXP_READLINK:
case SSH_FXP_REALPATH:
tmp=buffer_get_ssh_string(payload);
msg->filename=string_to_char(tmp);
free(tmp);
break;
case SSH_FXP_RENAME:
case SSH_FXP_SYMLINK:
tmp=buffer_get_ssh_string(payload);
msg->filename=string_to_char(tmp);
free(tmp);
msg->data=buffer_get_ssh_string(payload);
break;
case SSH_FXP_MKDIR:
case SSH_FXP_SETSTAT:
tmp=buffer_get_ssh_string(payload);
msg->filename=string_to_char(tmp);
free(tmp);
msg->attr=sftp_parse_attr(sftp, payload,0);
break;
case SSH_FXP_FSETSTAT:
msg->handle=buffer_get_ssh_string(payload);
msg->attr=sftp_parse_attr(sftp, payload,0);
break;
case SSH_FXP_LSTAT:
case SSH_FXP_STAT:
tmp=buffer_get_ssh_string(payload);
msg->filename=string_to_char(tmp);
free(tmp);
if(sftp->version >3)
buffer_get_u32(payload,&msg->flags);
break;
case SSH_FXP_OPEN:
tmp=buffer_get_ssh_string(payload);
msg->filename=string_to_char(tmp);
free(tmp);
buffer_get_u32(payload,&msg->flags);
msg->attr=sftp_parse_attr(sftp, payload,0);
case SSH_FXP_FSTAT:
msg->handle=buffer_get_ssh_string(payload);
buffer_get_u32(payload,&msg->flags);
break;
default:
printf("Received handled sftp message %d\n",msg->type);
}
msg->flags=ntohl(msg->flags);
msg->offset=ntohll(msg->offset);
msg->len=ntohl(msg->len);
sftp_packet_free(packet);
return msg;
}
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg) {
if (msg == NULL) {
return;
}
SAFE_FREE(msg->filename);
string_free(msg->data);
string_free(msg->handle);
sftp_attributes_free(msg->attr);
ZERO_STRUCTP(msg);
SAFE_FREE(msg);
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg){
if(msg->filename)
free(msg->filename);
if(msg->data)
free(msg->data);
if(msg->attr)
sftp_attributes_free(msg->attr);
if(msg->handle)
free(msg->handle);
memset(msg,'X',sizeof(*msg));
free(msg);
}
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, const char *name,
SFTP_ATTRIBUTES *attr) {
BUFFER *out;
STRING *file;
out = buffer_new();
if (out == NULL) {
return -1;
}
file = string_from_char(name);
if (file == NULL) {
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, char *name, SFTP_ATTRIBUTES *attr){
BUFFER *out=buffer_new();
STRING *file=string_from_char(name);
int r;
buffer_add_u32(out,msg->id);
buffer_add_u32(out,htonl(1));
buffer_add_ssh_string(out,file);
buffer_add_ssh_string(out,file); /* the protocol is broken here between 3 & 4 */
free(file);
buffer_add_attributes(out,attr);
r=sftp_packet_write(msg->sftp,SSH_FXP_NAME,out);
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) {
buffer_free(out);
string_free(file);
return -1;
}
buffer_free(out);
string_free(file);
return 0;
return r<0;
}
int sftp_reply_handle(SFTP_CLIENT_MESSAGE *msg, STRING *handle){
BUFFER *out;
out = 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) {
BUFFER *out=buffer_new();
int r;
buffer_add_u32(out,msg->id);
buffer_add_ssh_string(out,handle);
r=sftp_packet_write(msg->sftp,SSH_FXP_HANDLE,out);
buffer_free(out);
return -1;
}
buffer_free(out);
return 0;
return r<0;
}
int sftp_reply_attr(SFTP_CLIENT_MESSAGE *msg, SFTP_ATTRIBUTES *attr) {
BUFFER *out;
out = 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) {
int sftp_reply_attr(SFTP_CLIENT_MESSAGE *msg, SFTP_ATTRIBUTES *attr){
BUFFER *out=buffer_new();
int r;
buffer_add_u32(out,msg->id);
buffer_add_attributes(out,attr);
r=sftp_packet_write(msg->sftp,SSH_FXP_ATTRS,out);
buffer_free(out);
return -1;
}
buffer_free(out);
return 0;
return r<0;
}
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, const char *file,
const char *longname, SFTP_ATTRIBUTES *attr) {
STRING *name;
name = string_from_char(file);
if (name == NULL) {
return -1;
}
if (msg->attrbuf == NULL) {
msg->attrbuf = buffer_new();
if (msg->attrbuf == NULL) {
string_free(name);
return -1;
}
}
if (buffer_add_ssh_string(msg->attrbuf, name) < 0) {
string_free(name);
return -1;
}
string_free(name);
name = 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) {
string_free(name);
return -1;
}
string_free(name);
msg->attr_num++;
return 0;
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, char *file, char *longname,
SFTP_ATTRIBUTES *attr){
STRING *name=string_from_char(file);
if(!msg->attrbuf)
msg->attrbuf=buffer_new();
buffer_add_ssh_string(msg->attrbuf,name);
free(name);
name=string_from_char(longname);
buffer_add_ssh_string(msg->attrbuf,name);
free(name);
buffer_add_attributes(msg->attrbuf,attr);
msg->attr_num++;
return 0;
}
int sftp_reply_names(SFTP_CLIENT_MESSAGE *msg) {
BUFFER *out;
out = buffer_new();
if (out == NULL) {
buffer_free(msg->attrbuf);
return -1;
}
if (buffer_add_u32(out, msg->id) < 0 ||
buffer_add_u32(out, htonl(msg->attr_num)) < 0 ||
buffer_add_data(out, buffer_get(msg->attrbuf),
buffer_get_len(msg->attrbuf)) < 0 ||
sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) {
int sftp_reply_names(SFTP_CLIENT_MESSAGE *msg){
BUFFER *out=buffer_new();
int r;
buffer_add_u32(out,msg->id);
buffer_add_u32(out,htonl(msg->attr_num));
buffer_add_data(out,buffer_get(msg->attrbuf),
buffer_get_len(msg->attrbuf));
r=sftp_packet_write(msg->sftp,SSH_FXP_NAME,out);
buffer_free(out);
buffer_free(msg->attrbuf);
return -1;
}
buffer_free(out);
buffer_free(msg->attrbuf);
msg->attr_num = 0;
msg->attrbuf = NULL;
return 0;
msg->attr_num=0;
msg->attrbuf=NULL;
return r<0;
}
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status,
const char *message) {
BUFFER *out;
STRING *s;
out = buffer_new();
if (out == NULL) {
return -1;
}
s = string_from_char(message ? message : "");
if (s == NULL) {
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status, char *message){
BUFFER *out=buffer_new();
int r;
STRING *s;
buffer_add_u32(out,msg->id);
buffer_add_u32(out,htonl(status));
s=string_from_char(message?message:"");
buffer_add_ssh_string(out,s);
free(s);
buffer_add_u32(out,0); // language string
r=sftp_packet_write(msg->sftp,SSH_FXP_STATUS,out);
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) {
buffer_free(out);
string_free(s);
return -1;
}
buffer_free(out);
string_free(s);
return 0;
return r<0;
}
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, const void *data, int len) {
BUFFER *out;
out = buffer_new();
if (out == NULL) {
return -1;
}
if (buffer_add_u32(out, msg->id) < 0 ||
buffer_add_u32(out, ntohl(len)) < 0 ||
buffer_add_data(out, data, len) < 0 ||
sftp_packet_write(msg->sftp, SSH_FXP_DATA, out) < 0) {
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, void *data, int len){
BUFFER *out=buffer_new();
int r;
buffer_add_u32(out,msg->id);
buffer_add_u32(out,ntohl(len));
buffer_add_data(out,data,len);
r=sftp_packet_write(msg->sftp,SSH_FXP_DATA,out);
buffer_free(out);
return -1;
}
buffer_free(out);
return 0;
return r<0;
}
/*
* This function will return you a new handle to give the client.
/* 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).
*/
STRING *sftp_handle_alloc(SFTP_SESSION *sftp, void *info) {
STRING *ret;
u32 val;
int i;
if (sftp->handles == NULL) {
sftp->handles = malloc(sizeof(void *) * SFTP_HANDLES);
if (sftp->handles == NULL) {
return NULL;
* valid info (or worse). */
STRING *sftp_handle_alloc(SFTP_SESSION *sftp, void *info){
int i;
u32 val;
STRING *ret;
if(!sftp->handles){
sftp->handles=malloc(sizeof(void *) * SFTP_HANDLES);
memset(sftp->handles,0,sizeof(void *)*SFTP_HANDLES);
}
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 = string_new(4);
if (ret == NULL) {
return NULL;
}
memcpy(ret->string, &val, sizeof(u32));
sftp->handles[i] = info;
return ret;
for(i=0; i<SFTP_HANDLES;++i)
if(!sftp->handles[i])
break;
if(i==SFTP_HANDLES)
return NULL; // no handle available
val=i;
ret=string_new(4);
memcpy(ret->string,&val,sizeof(u32));
sftp->handles[i]=info;
return ret;
}
void *sftp_handle(SFTP_SESSION *sftp, STRING *handle){
u32 val;
if (sftp->handles == NULL) {
return NULL;
}
if (string_len(handle) != sizeof(u32)) {
return NULL;
}
memcpy(&val, handle->string, sizeof(u32));
if (val > SFTP_HANDLES) {
return NULL;
}
return sftp->handles[val];
u32 val;
if(!sftp->handles)
return NULL;
if(string_len(handle)!=sizeof(val))
return NULL;
memcpy(&val,handle->string,sizeof(u32));
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;
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: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +1,27 @@
/*
* 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.
*/
Copyright 2003-2008 Aris Adamantiadis
This file is part of the SSH Library
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 <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "libssh/priv.h"
/** \defgroup ssh_string SSH Strings
* \brief string manipulations
*/
@@ -42,37 +33,14 @@
* \param size size of the string
* \return the newly allocated string
*/
struct string_struct *string_new(size_t size) {
struct string_struct *str = NULL;
str = malloc(size + 4);
if (str == NULL) {
return NULL;
}
str->size = htonl(size);
return str;
STRING *string_new(unsigned int size){
STRING *str=malloc(size + 4);
str->size=htonl(size);
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 string_fill(struct string_struct *s, const void *data, size_t len) {
if ((s == NULL) || (data == NULL) ||
(len == 0) || (len > s->size)) {
return -1;
}
memcpy(s->string, data, len);
return 0;
void string_fill(STRING *str, const void *data,int len){
memcpy(str->string,data,len);
}
/**
@@ -81,31 +49,22 @@ int string_fill(struct string_struct *s, const void *data, size_t len) {
* \return the newly allocated string.
* \warning The nul byte is not copied nor counted in the ouput string.
*/
struct string_struct *string_from_char(const char *what) {
struct string_struct *ptr = NULL;
size_t len = strlen(what);
ptr = malloc(4 + len);
if (ptr == NULL) {
return NULL;
}
ptr->size = htonl(len);
memcpy(ptr->string, what, len);
return ptr;
STRING *string_from_char(const char *what){
STRING *ptr;
int len=strlen(what);
ptr=malloc(4 + len);
ptr->size=htonl(len);
memcpy(ptr->string,what,len);
return ptr;
}
/**
* \brief returns the size of a SSH string
* \param str the input SSH string
* \return size of the content of str, 0 on error
* \return size of the content of str
*/
size_t string_len(struct string_struct *s) {
if (s == NULL) {
return ntohl(0);
}
return ntohl(s->size);
int string_len(STRING *str){
return ntohl(str->size);
}
/**
@@ -115,70 +74,38 @@ size_t string_len(struct string_struct *s) {
* \warning If the input SSH string contains zeroes, some parts of
* the output string may not be readable with regular libc functions.
*/
char *string_to_char(struct string_struct *s) {
size_t len = ntohl(s->size) + 1;
char *new = malloc(len);
if (new == NULL) {
return NULL;
}
memcpy(new, s->string, len - 1);
new[len - 1] = '\0';
return new;
char *string_to_char(STRING *str){
int len=ntohl(str->size)+1;
char *string=malloc(len);
memcpy(string,str->string,len-1);
string[len-1]=0;
return string;
}
/**
* @brief Copy a string, return a newly allocated string. The caller has to
* free the string.
*
* @param s String to copy.
*
* @return Newly allocated copy of the string, NULL on error.
*/
struct string_struct *string_copy(struct string_struct *s) {
struct string_struct *new = malloc(ntohl(s->size) + 4);
if (new == NULL) {
return NULL;
}
new->size = s->size;
memcpy(new->string, s->string, ntohl(s->size));
return new;
STRING *string_copy(STRING *str){
STRING *ret=malloc(ntohl(str->size)+4);
ret->size=str->size;
memcpy(ret->string,str->string,ntohl(str->size));
return ret;
}
/** \brief destroy data in a string so it couldn't appear in a core dump
* \param s string to burn
*/
void string_burn(struct string_struct *s) {
if (s == NULL) {
return;
}
memset(s->string, 'X', string_len(s));
void string_burn(STRING *s){
memset(s->string,'X',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 *string_data(struct string_struct *s) {
if (s == NULL) {
return NULL;
}
return s->string;
void *string_data(STRING *s){
return s->string;
}
/**
* \brief deallocate a STRING object
* \param s String to delete
*/
void string_free(struct string_struct *s) {
SAFE_FREE(s);
void string_free(STRING *s){
free(s);
}
/** @} */
/* vim: set ts=2 sw=2 et cindent: */

File diff suppressed because it is too large Load Diff

210
sample.c
View File

@@ -40,7 +40,7 @@ char *cmds[MAXCMD];
struct termios terminal;
void do_sftp(SSH_SESSION *session);
static void add_cmd(char *cmd){
void add_cmd(char *cmd){
int n;
for(n=0;cmds[n] && (n<MAXCMD);n++);
if(n==MAXCMD)
@@ -48,19 +48,17 @@ static void add_cmd(char *cmd){
cmds[n]=strdup(cmd);
}
static void usage(){
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",
ssh_version(0));
" -r : use RSA to verify host public key\n");
exit(0);
}
static int opts(int argc, char **argv){
int opts(int argc, char **argv){
int i;
if(strstr(argv[0],"sftp"))
sftp=1;
@@ -94,42 +92,32 @@ static void cfmakeraw(struct termios *termios_p){
#endif
static void do_cleanup(int i) {
/* unused variable */
(void) i;
tcsetattr(0,TCSANOW,&terminal);
void do_cleanup(){
tcsetattr(0,TCSANOW,&terminal);
}
static void do_exit(int i) {
/* unused variable */
(void) i;
do_cleanup(0);
exit(0);
void do_exit(){
do_cleanup();
exit(0);
}
CHANNEL *chan;
int signal_delayed=0;
static void sigwindowchanged(int i){
(void) i;
signal_delayed=1;
void setsignal();
void sigwindowchanged(){
signal_delayed=1;
}
static void setsignal(void){
signal(SIGWINCH, sigwindowchanged);
signal_delayed=0;
}
static void sizechanged(void){
void sizechanged(){
struct winsize win = { 0, 0, 0, 0 };
ioctl(1, TIOCGWINSZ, &win);
channel_change_pty_size(chan,win.ws_col, win.ws_row);
// printf("Changed pty size\n");
setsignal();
}
static void select_loop(SSH_SESSION *session,CHANNEL *channel){
void setsignal(){
signal(SIGWINCH,sigwindowchanged);
signal_delayed=0;
}
void select_loop(SSH_SESSION *session,CHANNEL *channel){
fd_set fds;
struct timeval timeout;
char buffer[10];
@@ -180,39 +168,32 @@ static void select_loop(SSH_SESSION *session,CHANNEL *channel){
// we already looked for input from stdin. Now, we are looking for input from the channel
if(channel && channel_is_closed(channel)){
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
channel_free(channel);
channel=NULL;
channels[0]=NULL;
}
if(channels[0]){
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
lus=channel_read_buffer(channel,readbuf,0,0);
lus=channel_read(channel,readbuf,0,0);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
ssh_say(0,"error reading channel : %s\n",ssh_get_error(session));
return;
}
if(lus==0){
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
ssh_say(1,"EOF received\n");
channel_free(channel);
channel=channels[0]=NULL;
} else
write(1,buffer_get(readbuf),lus);
}
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
lus=channel_read_buffer(channel,readbuf,0,1);
lus=channel_read(channel,readbuf,0,1);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
ssh_say(0,"error reading channel : %s\n",ssh_get_error(session));
return;
}
if(lus==0){
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
ssh_say(1,"EOF received\n");
channel_free(channel);
channel=channels[0]=NULL;
} else
@@ -228,7 +209,7 @@ static void select_loop(SSH_SESSION *session,CHANNEL *channel){
}
static void shell(SSH_SESSION *session){
void shell(SSH_SESSION *session){
CHANNEL *channel;
struct termios terminal_local;
int interactive=isatty(0);
@@ -259,7 +240,7 @@ static void shell(SSH_SESSION *session){
select_loop(session,channel);
}
static void batch_shell(SSH_SESSION *session){
void batch_shell(SSH_SESSION *session){
CHANNEL *channel;
char buffer[1024];
int i,s=0;
@@ -273,11 +254,10 @@ static void batch_shell(SSH_SESSION *session){
}
select_loop(session,channel);
}
#ifdef WITH_SFTP
/* it's just a proof of concept code for sftp, till i write a real documentation about it */
void do_sftp(SSH_SESSION *session){
SFTP_SESSION *sftp_session=sftp_new(session);
SFTP_SESSION *sftp=sftp_new(session);
SFTP_DIR *dir;
SFTP_ATTRIBUTES *file;
SFTP_FILE *fichier;
@@ -285,72 +265,62 @@ void do_sftp(SSH_SESSION *session){
int len=1;
int i;
char data[8000];
if(!sftp_session){
fprintf(stderr, "sftp error initialising channel: %s\n",
ssh_get_error(session));
if(!sftp){
ssh_say(0,"sftp error initialising channel : %s\n",ssh_get_error(session));
return;
}
if(sftp_init(sftp_session)){
fprintf(stderr, "error initialising sftp: %s\n",
ssh_get_error(session));
if(sftp_init(sftp)){
ssh_say(0,"error initialising sftp : %s\n",ssh_get_error(session));
return;
}
/* the connection is made */
/* opening a directory */
dir=sftp_opendir(sftp_session,"./");
dir=sftp_opendir(sftp,"./");
if(!dir) {
fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session));
ssh_say(0,"Directory not opened(%s)\n",ssh_get_error(session));
return ;
}
/* reading the whole directory, file by file */
while((file=sftp_readdir(sftp_session,dir))){
fprintf(stderr, "%30s(%.8o) : %.5d.%.5d : %.10llu bytes\n",
file->name,
file->permissions,
file->uid,
file->gid,
(long long unsigned int) file->size);
while((file=sftp_readdir(sftp,dir))){
ssh_say(0,"%30s(%.8lo) : %.5d.%.5d : %.10lld bytes\n",file->name,file->permissions,file->uid,file->gid,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));
ssh_say(0,"error : %s\n",ssh_get_error(session));
return;
}
if(sftp_closedir(dir)){
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
if(sftp_dir_close(dir)){
ssh_say(0,"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_session,"/usr/bin/ssh",O_RDONLY, 0);
fichier=sftp_open(sftp,"/usr/bin/ssh",O_RDONLY,NULL);
if(!fichier){
fprintf(stderr, "Error opening /usr/bin/ssh: %s\n",
ssh_get_error(session));
ssh_say(0,"Error opening /usr/bin/ssh : %s\n",ssh_get_error(session));
return;
}
/* open a file for writing... */
to=sftp_open(sftp_session,"ssh-copy",O_WRONLY | O_CREAT, 0);
to=sftp_open(sftp,"ssh-copy",O_WRONLY | O_CREAT,NULL);
if(!to){
fprintf(stderr, "Error opening ssh-copy for writing: %s\n",
ssh_get_error(session));
ssh_say(0,"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));
ssh_say(0,"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_session,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644);
ssh_say(0,"Error reading file : %s\n",ssh_get_error(session));
sftp_file_close(fichier);
sftp_file_close(to);
printf("fichiers ferm<EFBFBD>\n");
to=sftp_open(sftp,"/tmp/grosfichier",O_WRONLY|O_CREAT,NULL);
for(i=0;i<1000;++i){
len=sftp_write(to,data,8000);
printf("wrote %d bytes\n",len);
@@ -358,17 +328,15 @@ void do_sftp(SSH_SESSION *session){
printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session));
}
}
sftp_close(to);
sftp_file_close(to);
/* close the sftp session */
sftp_free(sftp_session);
sftp_free(sftp);
printf("session sftp termin<69>\n");
}
#endif
static int auth_kbdint(SSH_SESSION *session){
int auth_kbdint(SSH_SESSION *session){
int err=ssh_userauth_kbdint(session,NULL,NULL);
const char *name, *instruction, *prompt;
char *ptr;
char *name,*instruction,*prompt,*ptr;
char buffer[128];
int i,n;
char echo;
@@ -388,15 +356,11 @@ static int auth_kbdint(SSH_SESSION *session){
buffer[sizeof(buffer)-1]=0;
if((ptr=strchr(buffer,'\n')))
*ptr=0;
if (ssh_userauth_kbdint_setanswer(session,i,buffer) < 0) {
return SSH_AUTH_ERROR;
}
ssh_userauth_kbdint_setanswer(session,i,buffer);
memset(buffer,0,strlen(buffer));
} else {
ptr=getpass(prompt);
if (ssh_userauth_kbdint_setanswer(session,i,ptr) < 0) {
return SSH_AUTH_ERROR;
}
ssh_userauth_kbdint_setanswer(session,i,ptr);
}
}
err=ssh_userauth_kbdint(session,NULL,NULL);
@@ -410,11 +374,9 @@ int main(int argc, char **argv){
int auth=0;
char *password;
char *banner;
char *hexa;
int state;
char buf[10];
unsigned char *hash = NULL;
int hlen;
unsigned char hash[MD5_DIGEST_LEN];
options=ssh_options_new();
if(ssh_options_getopt(options,&argc, argv)){
@@ -422,19 +384,10 @@ int main(int argc, char **argv){
usage();
}
opts(argc,argv);
signal(SIGTERM, do_exit);
if (user) {
if (ssh_options_set_username(options,user) < 0) {
ssh_options_free(options);
return 1;
}
}
if (ssh_options_set_host(options,host) < 0) {
ssh_options_free(options);
return 1;
}
signal(SIGTERM,do_exit);
if(user)
ssh_options_set_username(options,user);
ssh_options_set_host(options,host);
session=ssh_new();
ssh_set_options(session,options);
if(ssh_connect(session)){
@@ -444,20 +397,13 @@ int main(int argc, char **argv){
return 1;
}
state=ssh_is_server_known(session);
hlen = ssh_get_pubkey_hash(session, &hash);
if (hlen < 0) {
ssh_disconnect(session);
ssh_finalize();
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);
free(hash);
ssh_get_pubkey_hash(session,hash);
ssh_print_hexa("Public key hash",hash,MD5_DIGEST_LEN);
fprintf(stderr,"For security reason, connection will be stopped\n");
ssh_disconnect(session);
ssh_finalize();
@@ -470,15 +416,10 @@ int main(int argc, char **argv){
ssh_disconnect(session);
ssh_finalize();
exit(-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 behaviour */
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);
ssh_get_pubkey_hash(session,hash);
ssh_print_hexa("Public key hash",hash,MD5_DIGEST_LEN);
fgets(buf,sizeof(buf),stdin);
if(strncasecmp(buf,"yes",3)!=0){
ssh_disconnect(session);
@@ -487,22 +428,17 @@ int main(int argc, char **argv){
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
fgets(buf,sizeof(buf),stdin);
if(strncasecmp(buf,"yes",3)==0){
if (ssh_write_knownhost(session) < 0) {
free(hash);
fprintf(stderr, "error %s\n", strerror(errno));
exit(-1);
}
if(ssh_write_knownhost(session))
fprintf(stderr,"error %s\n",ssh_get_error(session));
}
break;
case SSH_SERVER_ERROR:
free(hash);
fprintf(stderr,"%s",ssh_get_error(session));
ssh_disconnect(session);
ssh_finalize();
exit(-1);
}
free(hash);
ssh_userauth_none(session, NULL);
@@ -518,7 +454,7 @@ int main(int argc, char **argv){
printf("\n");
/* no ? you should :) */
auth=ssh_userauth_autopubkey(session, NULL);
auth=ssh_userauth_autopubkey(session);
if(auth==SSH_AUTH_ERROR){
fprintf(stderr,"Authenticating with pubkey: %s\n",ssh_get_error(session));
ssh_finalize();
@@ -548,10 +484,10 @@ int main(int argc, char **argv){
}
memset(password,0,strlen(password));
}
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
ssh_say(1,"Authentication success\n");
if(strstr(argv[0],"sftp")){
sftp=1;
ssh_log(session, SSH_LOG_FUNCTIONS, "Doing sftp instead");
ssh_say(1,"doing sftp instead\n");
}
if(!sftp){
if(!cmds[0])
@@ -559,12 +495,10 @@ int main(int argc, char **argv){
else
batch_shell(session);
}
#ifdef WITH_SFTP
else
do_sftp(session);
#endif
do_sftp(session);
if(!sftp && !cmds[0])
do_cleanup(0);
do_cleanup();
ssh_disconnect(session);
ssh_finalize();

View File

@@ -31,7 +31,7 @@ MA 02111-1307, USA. */
#define KEYS_FOLDER "/etc/ssh/"
#endif
static int auth_password(char *user, char *password){
int auth_password(char *user, char *password){
if(strcmp(user,"aris"))
return 0;
if(strcmp(password,"lala"))
@@ -45,7 +45,6 @@ int main(int argc, char **argv){
SSH_BIND *ssh_bind;
SSH_MESSAGE *message;
CHANNEL *chan=0;
BUFFER *buf;
int auth=0;
int sftp=0;
int i;
@@ -63,9 +62,9 @@ int main(int argc, char **argv){
printf("error accepting a connection : %s\n",ssh_get_error(ssh_bind));
return 1;
}
printf("Socket connected: fd = %d\n", ssh_get_fd(session));
printf("Socket connecté : %d\n",ssh_get_fd(session));
if(ssh_accept(session)){
printf("ssh_accept: %s\n",ssh_get_error(session));
printf("ssh_accept : %s\n",ssh_get_error(session));
return 1;
}
do {
@@ -99,7 +98,7 @@ int main(int argc, char **argv){
ssh_message_free(message);
} while (!auth);
if(!auth){
printf("auth error: %s\n",ssh_get_error(session));
printf("error : %s\n",ssh_get_error(session));
ssh_finalize();
return 1;
}
@@ -143,9 +142,9 @@ int main(int argc, char **argv){
return 1;
}
printf("it works !\n");
buf=buffer_new();
BUFFER *buf=buffer_new();
do{
i=channel_read_buffer(chan,buf,0,0);
i=channel_read(chan,buf,0,0);
if(i>0)
write(1,buffer_get(buf),buffer_get_len(buf));
} while (i>0);

View File

@@ -1,12 +1,9 @@
all: test_tunnel test_exec
all: test_tunnel
CFLAGS=-I../include/ -g -Wall
LDFLAGS=-lssh -L../build/libssh/
LDFLAGS=-lssh -L../libssh/.libs
test_tunnel: test_tunnel.o authentication.o connection.o
gcc -o $@ $^ $(LDFLAGS)
test_exec: test_exec.o authentication.o connection.o
gcc -o $@ $^ $(LDFLAGS)
clean:
rm -f *.o test_tunnel

View File

@@ -47,7 +47,7 @@ static int auth_kbdint(SSH_SESSION *session){
}
int authenticate (SSH_SESSION *session){
int auth=ssh_userauth_autopubkey(session, NULL);
int auth=ssh_userauth_autopubkey(session);
char *password;
if(auth==SSH_AUTH_ERROR){
fprintf(stderr,"Authenticating with pubkey: %s\n",ssh_get_error(session));

Some files were not shown because too many files have changed in this diff Show More