mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 10:40:27 +09:00
Compare commits
49 Commits
release-0-
...
release-0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d672dde342 | ||
|
|
86f983962c | ||
|
|
b0d6307d41 | ||
|
|
10920fc678 | ||
|
|
c87b247e01 | ||
|
|
9abdc5ae2a | ||
|
|
e8e874909f | ||
|
|
74eff86a6b | ||
|
|
232aca8969 | ||
|
|
48deb0ca46 | ||
|
|
59889da5a5 | ||
|
|
a958f6498b | ||
|
|
3ec11b46e9 | ||
|
|
c17ce2697b | ||
|
|
7fa1804cf1 | ||
|
|
ad86a378d9 | ||
|
|
ed660c29c3 | ||
|
|
6f47401173 | ||
|
|
d247b86202 | ||
|
|
a1c7dd99be | ||
|
|
11a6ed907d | ||
|
|
a8ce546f69 | ||
|
|
6e56d1dfb2 | ||
|
|
b07ec7a3d1 | ||
|
|
09d4029ac1 | ||
|
|
b62d0732d2 | ||
|
|
90a6d431a7 | ||
|
|
f7448eeb1c | ||
|
|
d411260a68 | ||
|
|
f8f0663eb9 | ||
|
|
cedc635ed0 | ||
|
|
ff819489b7 | ||
|
|
37dc2a5279 | ||
|
|
50ebbe636e | ||
|
|
101bf21d41 | ||
|
|
ae3bb42da5 | ||
|
|
918a912cd5 | ||
|
|
7ba81b974e | ||
|
|
b5e868fb8b | ||
|
|
693c041ba9 | ||
|
|
39c7e3c7dd | ||
|
|
3873489688 | ||
|
|
d14a492019 | ||
|
|
848984f25f | ||
|
|
5a755a8219 | ||
|
|
910689126a | ||
|
|
87995db8fe | ||
|
|
70c9da4fb0 | ||
|
|
1ac654ec6c |
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.*
|
||||||
|
*.swp
|
||||||
|
*~$
|
||||||
|
build
|
||||||
|
cscope.*
|
||||||
|
tags
|
||||||
@@ -6,13 +6,13 @@ cmake_minimum_required(VERSION 2.6.0)
|
|||||||
# global needed variables
|
# global needed variables
|
||||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
|
|
||||||
set(APPLICATION_VERSION "0.3.0")
|
set(APPLICATION_VERSION "0.3.3")
|
||||||
|
|
||||||
set(APPLICATION_VERSION_MAJOR "0")
|
set(APPLICATION_VERSION_MAJOR "0")
|
||||||
set(APPLICATION_VERSION_MINOR "3")
|
set(APPLICATION_VERSION_MINOR "3")
|
||||||
set(APPLICATION_VERSION_PATCH "0")
|
set(APPLICATION_VERSION_PATCH "3")
|
||||||
|
|
||||||
set(LIBRARY_VERSION "3.0.0")
|
set(LIBRARY_VERSION "3.3.0")
|
||||||
set(LIBRARY_SOVERSION "3")
|
set(LIBRARY_SOVERSION "3")
|
||||||
|
|
||||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
|||||||
### versions
|
### versions
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
set(CPACK_PACKAGE_VERSION_PATCH "3")
|
||||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
26
ChangeLog
26
ChangeLog
@@ -1,6 +1,32 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
version 0.3.3 (released 2009-08-18)
|
||||||
|
* Fixed double free pointer crash in dsa_public_to_string.
|
||||||
|
* Fixed channel_get_exit_status bug.
|
||||||
|
* Fixed ssh_finalize which didn't clear the flag.
|
||||||
|
* Fixed memory leak introduced by previous bugfix.
|
||||||
|
* Fixed channel_poll broken when delayed EOF recvd.
|
||||||
|
* Fixed stupid "can't parse known host key" bug.
|
||||||
|
* Fixed possible memory corruption (ticket #14).
|
||||||
|
|
||||||
|
version 0.3.2 (released 2009-08-05)
|
||||||
|
* Added ssh_init() function.
|
||||||
|
* Added sftp_readlink() function.
|
||||||
|
* Added sftp_symlink() function.
|
||||||
|
* Fixed ssh_write_knownhost().
|
||||||
|
* Fixed compilation on Solaris.
|
||||||
|
* Fixed SSHv1 compilation.
|
||||||
|
|
||||||
|
version 0.3.1 (released 2009-07-14)
|
||||||
|
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||||
|
* Fixed compilation of SSHv1.
|
||||||
|
* Fixed several memory leaks.
|
||||||
|
* Fixed possible infinite loops.
|
||||||
|
* Fixed a possible crash bug.
|
||||||
|
* Fixed build warnings.
|
||||||
|
* Fixed cmake on BSD.
|
||||||
|
|
||||||
version 0.3 (released 2009-05-21)
|
version 0.3 (released 2009-05-21)
|
||||||
* Added support for ssh-agent authentication.
|
* Added support for ssh-agent authentication.
|
||||||
* Added POSIX like sftp implementation.
|
* Added POSIX like sftp implementation.
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
|
|
||||||
if (UNIX AND NOT WIN32)
|
if (UNIX AND NOT WIN32)
|
||||||
|
if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
add_definitions(-Wall -Wextra -Wmissing-prototypes -Wdeclaration-after-statement -Wunused)
|
||||||
|
|
||||||
# with -fPIC
|
# with -fPIC
|
||||||
check_c_compiler_flag("-fPIC" WITH_FPIC)
|
check_c_compiler_flag("-fPIC" WITH_FPIC)
|
||||||
if (WITH_FPIC)
|
if (WITH_FPIC)
|
||||||
@@ -29,12 +32,10 @@ if (UNIX AND NOT WIN32)
|
|||||||
ERROR_QUIET
|
ERROR_QUIET
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
|
||||||
|
|
||||||
string(REGEX REPLACE "[\r\n]" " " ${_lfs_CFLAGS} "${${_lfs_CFLAGS}}")
|
|
||||||
|
|
||||||
add_definitions(${_lfs_CFLAGS})
|
add_definitions(${_lfs_CFLAGS})
|
||||||
add_definitions(-Wall -Wextra -Wmissing-prototypes -Wdeclaration-after-statement -Wunused)
|
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||||
|
|
||||||
check_c_compiler_flag("-fstack-protector" WITH_STACK_PROTECTOR)
|
check_c_compiler_flag("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||||
if (WITH_STACK_PROTECTOR)
|
if (WITH_STACK_PROTECTOR)
|
||||||
@@ -45,5 +46,5 @@ if (UNIX AND NOT WIN32)
|
|||||||
if (WITH_FORTIFY_SOURCE)
|
if (WITH_FORTIFY_SOURCE)
|
||||||
add_definitions(-D_FORTIFY_SOURCE=2)
|
add_definitions(-D_FORTIFY_SOURCE=2)
|
||||||
endif (WITH_FORTIFY_SOURCE)
|
endif (WITH_FORTIFY_SOURCE)
|
||||||
|
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||||
endif (UNIX AND NOT WIN32)
|
endif (UNIX AND NOT WIN32)
|
||||||
|
|||||||
7
debian/README.Debian
vendored
7
debian/README.Debian
vendored
@@ -1,7 +0,0 @@
|
|||||||
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
|
|
||||||
55
debian/changelog
vendored
55
debian/changelog
vendored
@@ -1,55 +0,0 @@
|
|||||||
libssh (0.2+svn20070321-5) UNRELEASED; urgency=low
|
|
||||||
|
|
||||||
* NOT RELEASED YET
|
|
||||||
* debian/control:
|
|
||||||
- Use my debian.org address in Uploaders and takeover the package
|
|
||||||
with Jean-Philippe permission
|
|
||||||
- Use now official Vcs-* field
|
|
||||||
- Use new Homepage field instead of old pseudo-field
|
|
||||||
- Bump Standards-Version to 3.8.1 (no further changes)
|
|
||||||
- Use debug section for -dbg package
|
|
||||||
- Add ${misc:Depends} to please lintian
|
|
||||||
* debian/libssh-2-doc.doc-base: Fix doc-base-uses-applications-section
|
|
||||||
|
|
||||||
-- Laurent Bigonville <bigon@debian.org> 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
1
debian/compat
vendored
@@ -1 +0,0 @@
|
|||||||
5
|
|
||||||
65
debian/control
vendored
65
debian/control
vendored
@@ -1,65 +0,0 @@
|
|||||||
Source: libssh
|
|
||||||
Section: libs
|
|
||||||
Priority: optional
|
|
||||||
Maintainer: Laurent Bigonville <bigon@debian.org>
|
|
||||||
Build-Depends: cdbs, debhelper (>= 5), libgcrypt11-dev, libz-dev, doxygen
|
|
||||||
Standards-Version: 3.8.1
|
|
||||||
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}), ${misc:Depends}, 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: debug
|
|
||||||
Architecture: any
|
|
||||||
Depends: libssh-2 (= ${binary:Version}), ${misc:Depends}
|
|
||||||
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
|
|
||||||
Depends: ${misc:Depends}
|
|
||||||
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
33
debian/copyright
vendored
@@ -1,33 +0,0 @@
|
|||||||
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
2
debian/libssh-2-dev.install
vendored
@@ -1,2 +0,0 @@
|
|||||||
debian/tmp/usr/include/*
|
|
||||||
debian/tmp/usr/lib/libssh.{a,la,so}
|
|
||||||
9
debian/libssh-2-doc.doc-base
vendored
9
debian/libssh-2-doc.doc-base
vendored
@@ -1,9 +0,0 @@
|
|||||||
Document: libssh
|
|
||||||
Title: Debian libssh Manual
|
|
||||||
Author: Aris Adamantiadis <aris@0xbadc0de.be>
|
|
||||||
Abstract: This manual describes libssh API.
|
|
||||||
Section: Programming/C
|
|
||||||
|
|
||||||
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
1
debian/libssh-2-doc.docs
vendored
@@ -1 +0,0 @@
|
|||||||
debian/tmp/usr/share/doc/libssh/html
|
|
||||||
1
debian/libssh-2-doc.examples
vendored
1
debian/libssh-2-doc.examples
vendored
@@ -1 +0,0 @@
|
|||||||
debian/tmp/usr/share/doc/libssh/examples/*
|
|
||||||
1
debian/libssh-2-doc.manpages
vendored
1
debian/libssh-2-doc.manpages
vendored
@@ -1 +0,0 @@
|
|||||||
doxygen/man/man3/ssh_*
|
|
||||||
1
debian/libssh-2.install
vendored
1
debian/libssh-2.install
vendored
@@ -1 +0,0 @@
|
|||||||
debian/tmp/usr/lib/libssh.so.*
|
|
||||||
2
debian/libssh-2.lintian-overrides
vendored
2
debian/libssh-2.lintian-overrides
vendored
@@ -1,2 +0,0 @@
|
|||||||
# We use libssh-2 name to avoid name clash with libssh2 package.
|
|
||||||
libssh-2: package-name-doesnt-match-sonames libssh2
|
|
||||||
21
debian/rules
vendored
21
debian/rules
vendored
@@ -1,21 +0,0 @@
|
|||||||
#!/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
2
debian/watch
vendored
@@ -1,2 +0,0 @@
|
|||||||
version=3
|
|
||||||
http://0xbadc0de.be/libssh/libssh-(.*)\.tgz
|
|
||||||
@@ -51,7 +51,7 @@ typedef unsigned long long uint64_t;
|
|||||||
/* libssh version */
|
/* libssh version */
|
||||||
#define LIBSSH_VERSION_MAJOR 0
|
#define LIBSSH_VERSION_MAJOR 0
|
||||||
#define LIBSSH_VERSION_MINOR 3
|
#define LIBSSH_VERSION_MINOR 3
|
||||||
#define LIBSSH_VERSION_MICRO 0
|
#define LIBSSH_VERSION_MICRO 3
|
||||||
|
|
||||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||||
LIBSSH_VERSION_MINOR, \
|
LIBSSH_VERSION_MINOR, \
|
||||||
@@ -80,7 +80,6 @@ typedef struct channel_struct CHANNEL;
|
|||||||
typedef struct agent_struct AGENT;
|
typedef struct agent_struct AGENT;
|
||||||
typedef struct ssh_session SSH_SESSION;
|
typedef struct ssh_session SSH_SESSION;
|
||||||
typedef struct ssh_kbdint SSH_KBDINT;
|
typedef struct ssh_kbdint SSH_KBDINT;
|
||||||
struct keys_struct;
|
|
||||||
|
|
||||||
/* integer values */
|
/* integer values */
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
@@ -134,6 +133,7 @@ typedef int socket_t;
|
|||||||
#define SSH_SERVER_KNOWN_OK 1
|
#define SSH_SERVER_KNOWN_OK 1
|
||||||
#define SSH_SERVER_KNOWN_CHANGED 2
|
#define SSH_SERVER_KNOWN_CHANGED 2
|
||||||
#define SSH_SERVER_FOUND_OTHER 3
|
#define SSH_SERVER_FOUND_OTHER 3
|
||||||
|
#define SSH_SERVER_FILE_NOT_FOUND 4
|
||||||
|
|
||||||
#ifndef MD5_DIGEST_LEN
|
#ifndef MD5_DIGEST_LEN
|
||||||
#define MD5_DIGEST_LEN 16
|
#define MD5_DIGEST_LEN 16
|
||||||
@@ -210,6 +210,7 @@ int ssh_connect(SSH_SESSION *session);
|
|||||||
void ssh_disconnect(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, const char *service);
|
||||||
char *ssh_get_issue_banner(SSH_SESSION *session);
|
char *ssh_get_issue_banner(SSH_SESSION *session);
|
||||||
|
int ssh_get_openssh_version(SSH_SESSION *session);
|
||||||
/* get copyright informations */
|
/* get copyright informations */
|
||||||
const char *ssh_copyright(void);
|
const char *ssh_copyright(void);
|
||||||
|
|
||||||
@@ -256,9 +257,6 @@ PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv);
|
|||||||
void privatekey_free(PRIVATE_KEY *prv);
|
void privatekey_free(PRIVATE_KEY *prv);
|
||||||
STRING *publickey_from_file(SSH_SESSION *session, const char *filename,
|
STRING *publickey_from_file(SSH_SESSION *session, const char *filename,
|
||||||
int *type);
|
int *type);
|
||||||
STRING *try_publickey_from_file(SSH_SESSION *session,
|
|
||||||
struct keys_struct keytab,
|
|
||||||
char **privkeyfile, int *type);
|
|
||||||
int ssh_is_server_known(SSH_SESSION *session);
|
int ssh_is_server_known(SSH_SESSION *session);
|
||||||
int ssh_write_knownhost(SSH_SESSION *session);
|
int ssh_write_knownhost(SSH_SESSION *session);
|
||||||
|
|
||||||
@@ -369,14 +367,15 @@ int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase);
|
int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase);
|
||||||
int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, const char *submethods);
|
int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, const char *submethods);
|
||||||
int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session);
|
int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session);
|
||||||
char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
|
const char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
|
||||||
char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
|
const char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
|
||||||
char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i, char *echo);
|
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,
|
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
|
||||||
const char *answer);
|
const char *answer);
|
||||||
|
|
||||||
|
|
||||||
/* init.c */
|
/* init.c */
|
||||||
|
int ssh_init(void);
|
||||||
int ssh_finalize(void);
|
int ssh_finalize(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -133,6 +133,28 @@ typedef BN_CTX* bignum_CTX;
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#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 */
|
/* wrapper.c */
|
||||||
MD5CTX md5_init(void);
|
MD5CTX md5_init(void);
|
||||||
void md5_update(MD5CTX c, const void *data, unsigned long len);
|
void md5_update(MD5CTX c, const void *data, unsigned long len);
|
||||||
@@ -152,7 +174,11 @@ void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
|
|||||||
struct string_struct {
|
struct string_struct {
|
||||||
u32 size;
|
u32 size;
|
||||||
unsigned char string[MAX_PACKET_LEN];
|
unsigned char string[MAX_PACKET_LEN];
|
||||||
} __attribute__ ((packed));
|
}
|
||||||
|
#if !defined(__SUNPRO_C)
|
||||||
|
__attribute__ ((packed))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
/** Describes a buffer state at a moment
|
/** Describes a buffer state at a moment
|
||||||
*/
|
*/
|
||||||
@@ -311,6 +337,7 @@ struct ssh_session {
|
|||||||
int protoversion;
|
int protoversion;
|
||||||
int server;
|
int server;
|
||||||
int client;
|
int client;
|
||||||
|
int openssh;
|
||||||
u32 send_seq;
|
u32 send_seq;
|
||||||
u32 recv_seq;
|
u32 recv_seq;
|
||||||
/* status flags */
|
/* status flags */
|
||||||
@@ -474,6 +501,9 @@ STRING *agent_sign_data(struct ssh_session *session,
|
|||||||
struct public_key_struct *pubkey);
|
struct public_key_struct *pubkey);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* poll.c */
|
||||||
|
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout);
|
||||||
|
|
||||||
/* socket.c */
|
/* socket.c */
|
||||||
|
|
||||||
struct socket;
|
struct socket;
|
||||||
@@ -578,6 +608,9 @@ char *ssh_find_matching(const char *in_d, const char *what_d);
|
|||||||
|
|
||||||
PRIVATE_KEY *_privatekey_from_file(void *session, const char *filename,
|
PRIVATE_KEY *_privatekey_from_file(void *session, const char *filename,
|
||||||
int type);
|
int type);
|
||||||
|
STRING *try_publickey_from_file(SSH_SESSION *session,
|
||||||
|
struct keys_struct keytab,
|
||||||
|
char **privkeyfile, int *type);
|
||||||
|
|
||||||
/* in keys.c */
|
/* in keys.c */
|
||||||
const char *ssh_type_to_char(int type);
|
const char *ssh_type_to_char(int type);
|
||||||
@@ -694,6 +727,12 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
|
|||||||
|
|
||||||
/* log.c */
|
/* log.c */
|
||||||
|
|
||||||
|
#ifndef __FUNCTION__
|
||||||
|
#if defined(__SUNPRO_C)
|
||||||
|
#define __FUNCTION__ __func__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _enter_function(sess) \
|
#define _enter_function(sess) \
|
||||||
do {\
|
do {\
|
||||||
if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \
|
if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \
|
||||||
|
|||||||
@@ -592,6 +592,30 @@ int sftp_chmod(SFTP_SESSION *sftp, const char *file, mode_t mode);
|
|||||||
*/
|
*/
|
||||||
int sftp_utimes(SFTP_SESSION *sftp, const char *file, const struct timeval *times);
|
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.
|
* @brief Canonicalize a sftp path.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ set(libssh_SRCS
|
|||||||
misc.c
|
misc.c
|
||||||
options.c
|
options.c
|
||||||
packet.c
|
packet.c
|
||||||
|
poll.c
|
||||||
session.c
|
session.c
|
||||||
socket.c
|
socket.c
|
||||||
string.c
|
string.c
|
||||||
|
|||||||
@@ -44,6 +44,10 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/agent.h"
|
#include "libssh/agent.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
@@ -323,7 +327,7 @@ int agent_get_ident_count(struct ssh_session *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->agent->ident) {
|
if (session->agent->ident) {
|
||||||
buffer_free(session->agent->ident);
|
buffer_reinit(session->agent->ident);
|
||||||
}
|
}
|
||||||
session->agent->ident = reply;
|
session->agent->ident = reply;
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,17 @@
|
|||||||
* MA 02111-1307, USA.
|
* MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
|
||||||
#include "libssh/ssh2.h"
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
#include "libssh/ssh2.h"
|
||||||
|
|
||||||
/** \defgroup ssh_auth SSH Authentication functions
|
/** \defgroup ssh_auth SSH Authentication functions
|
||||||
* \brief functions to authenticate to servers
|
* \brief functions to authenticate to servers
|
||||||
*/
|
*/
|
||||||
@@ -203,7 +208,7 @@ int ssh_userauth_none(SSH_SESSION *session, const char *username) {
|
|||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (session->version == 1) {
|
if (session->version == 1) {
|
||||||
ssh_userauth1_none(session, username);
|
ssh_userauth1_none(session, username);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -263,7 +268,7 @@ int ssh_userauth_none(SSH_SESSION *session, const char *username) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
@@ -309,7 +314,7 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (session->version == 1) {
|
if (session->version == 1) {
|
||||||
ssh_userauth1_offer_pubkey(session, username, type, publickey);
|
ssh_userauth1_offer_pubkey(session, username, type, publickey);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -377,7 +382,7 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
@@ -498,7 +503,7 @@ int ssh_userauth_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
@@ -622,7 +627,7 @@ int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username,
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(sign);
|
string_free(sign);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
@@ -666,7 +671,7 @@ int ssh_userauth_password(SSH_SESSION *session, const char *username,
|
|||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (session->version == 1) {
|
if (session->version == 1) {
|
||||||
rc = ssh_userauth1_password(session, username, password);
|
rc = ssh_userauth1_password(session, username, password);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -734,7 +739,7 @@ int ssh_userauth_password(SSH_SESSION *session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(user);
|
string_free(user);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
@@ -1070,10 +1075,10 @@ static void kbdint_clean(struct ssh_kbdint *kbd) {
|
|||||||
* of the draft */
|
* of the draft */
|
||||||
static int kbdauth_init(SSH_SESSION *session, const char *user,
|
static int kbdauth_init(SSH_SESSION *session, const char *user,
|
||||||
const char *submethods) {
|
const char *submethods) {
|
||||||
STRING *usr;
|
STRING *usr = NULL;
|
||||||
STRING *sub;
|
STRING *sub = NULL;
|
||||||
STRING *service;
|
STRING *service = NULL;
|
||||||
STRING *method;
|
STRING *method = NULL;
|
||||||
int rc = SSH_AUTH_ERROR;
|
int rc = SSH_AUTH_ERROR;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
@@ -1118,7 +1123,7 @@ static int kbdauth_init(SSH_SESSION *session, const char *user,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(usr);
|
string_free(usr);
|
||||||
string_free(service);
|
string_free(service);
|
||||||
string_free(method);
|
string_free(method);
|
||||||
@@ -1285,7 +1290,7 @@ static int kbdauth_send(SSH_SESSION *session) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_burn(answer);
|
string_burn(answer);
|
||||||
string_free(answer);
|
string_free(answer);
|
||||||
|
|
||||||
@@ -1412,7 +1417,7 @@ int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session) {
|
|||||||
*
|
*
|
||||||
* @returns The name of the message block. Do not free it.
|
* @returns The name of the message block. Do not free it.
|
||||||
*/
|
*/
|
||||||
char *ssh_userauth_kbdint_getname(SSH_SESSION *session) {
|
const char *ssh_userauth_kbdint_getname(SSH_SESSION *session) {
|
||||||
return session->kbdint->name;
|
return session->kbdint->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1427,7 +1432,7 @@ char *ssh_userauth_kbdint_getname(SSH_SESSION *session) {
|
|||||||
* @returns The instruction of the message block.
|
* @returns The instruction of the message block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session) {
|
const char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session) {
|
||||||
return session->kbdint->instruction;
|
return session->kbdint->instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1447,7 +1452,7 @@ char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session) {
|
|||||||
*
|
*
|
||||||
* @returns A pointer to the prompt. Do not free it.
|
* @returns A pointer to the prompt. Do not free it.
|
||||||
*/
|
*/
|
||||||
char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i,
|
const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i,
|
||||||
char *echo) {
|
char *echo) {
|
||||||
if (i > session->kbdint->nprompts) {
|
if (i > session->kbdint->nprompts) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1470,7 +1475,7 @@ char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i,
|
|||||||
*/
|
*/
|
||||||
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
|
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
|
||||||
const char *answer) {
|
const char *answer) {
|
||||||
if (i > session->kbdint->nprompts) {
|
if (session == NULL || answer == NULL || i > session->kbdint->nprompts) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh1.h"
|
#include "libssh/ssh1.h"
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
static int wait_auth1_status(SSH_SESSION *session) {
|
static int wait_auth1_status(SSH_SESSION *session) {
|
||||||
/* wait for a packet */
|
/* wait for a packet */
|
||||||
if (packet_read(session) != SSH_OK) {
|
if (packet_read(session) != SSH_OK) {
|
||||||
@@ -138,6 +138,10 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,int type, STR
|
|||||||
*/
|
*/
|
||||||
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
|
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
|
||||||
int type, STRING *pubkey) {
|
int type, STRING *pubkey) {
|
||||||
|
(void) session;
|
||||||
|
(void) username;
|
||||||
|
(void) type;
|
||||||
|
(void) pubkey;
|
||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,5 +251,5 @@ int ssh_userauth1_password(SSH_SESSION *session, const char *username,
|
|||||||
return wait_auth1_status(session);
|
return wait_auth1_status(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
/* vim: set ts=2 sw=2 et cindent: */
|
/* vim: set ts=2 sw=2 et cindent: */
|
||||||
|
|||||||
@@ -23,6 +23,11 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
/** \defgroup ssh_buffer SSH Buffers
|
/** \defgroup ssh_buffer SSH Buffers
|
||||||
|
|||||||
@@ -28,6 +28,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
|
|
||||||
@@ -276,7 +280,7 @@ static int grow_window(SSH_SESSION *session, CHANNEL *channel, int minimumsize)
|
|||||||
leave_function();
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
@@ -311,7 +315,7 @@ static void channel_rcv_change_window(SSH_SESSION *session) {
|
|||||||
|
|
||||||
channel = channel_from_msg(session);
|
channel = channel_from_msg(session);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_log(session, SSH_LOG_FUNCTIONS, ssh_get_error(session));
|
ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = buffer_get_u32(session->in_buffer, &bytes);
|
rc = buffer_get_u32(session->in_buffer, &bytes);
|
||||||
@@ -409,7 +413,7 @@ static void channel_rcv_eof(SSH_SESSION *session) {
|
|||||||
|
|
||||||
channel = channel_from_msg(session);
|
channel = channel_from_msg(session);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_log(session, SSH_LOG_FUNCTIONS, ssh_get_error(session));
|
ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
leave_function();
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -431,7 +435,7 @@ static void channel_rcv_close(SSH_SESSION *session) {
|
|||||||
|
|
||||||
channel = channel_from_msg(session);
|
channel = channel_from_msg(session);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_log(session, SSH_LOG_FUNCTIONS, ssh_get_error(session));
|
ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
|
||||||
leave_function();
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -473,7 +477,7 @@ static void channel_rcv_request(SSH_SESSION *session) {
|
|||||||
|
|
||||||
channel = channel_from_msg(session);
|
channel = channel_from_msg(session);
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_log(session, SSH_LOG_FUNCTIONS, ssh_get_error(session));
|
ssh_log(session, SSH_LOG_FUNCTIONS,"%s", ssh_get_error(session));
|
||||||
leave_function();
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -637,7 +641,7 @@ int channel_default_bufferize(CHANNEL *channel, void *data, int len,
|
|||||||
* @see channel_request_exec()
|
* @see channel_request_exec()
|
||||||
*/
|
*/
|
||||||
int channel_open_session(CHANNEL *channel) {
|
int channel_open_session(CHANNEL *channel) {
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (channel->session->version == 1) {
|
if (channel->session->version == 1) {
|
||||||
return channel_open_session1(channel);
|
return channel_open_session1(channel);
|
||||||
}
|
}
|
||||||
@@ -787,7 +791,7 @@ int channel_send_eof(CHANNEL *channel){
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -840,7 +844,7 @@ int channel_close(CHANNEL *channel){
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -881,7 +885,7 @@ int channel_write(CHANNEL *channel, const void *data, u32 len) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (channel->version == 1) {
|
if (channel->version == 1) {
|
||||||
int rc = channel_write1(channel, data, len);
|
int rc = channel_write1(channel, data, len);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -900,7 +904,10 @@ int channel_write(CHANNEL *channel, const void *data, u32 len) {
|
|||||||
/* What happens when the channel window is zero? */
|
/* What happens when the channel window is zero? */
|
||||||
while(channel->remote_window == 0) {
|
while(channel->remote_window == 0) {
|
||||||
/* parse every incoming packet */
|
/* parse every incoming packet */
|
||||||
packet_wait(channel->session, 0, 0);
|
if (packet_wait(channel->session, 0, 0) == SSH_ERROR) {
|
||||||
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
effectivelen = len > channel->remote_window ? channel->remote_window : len;
|
effectivelen = len > channel->remote_window ? channel->remote_window : len;
|
||||||
} else {
|
} else {
|
||||||
@@ -931,7 +938,7 @@ int channel_write(CHANNEL *channel, const void *data, u32 len) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return origlen;
|
return origlen;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@@ -1053,7 +1060,7 @@ static int channel_request(CHANNEL *channel, const char *request,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(req);
|
string_free(req);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -1081,7 +1088,7 @@ int channel_request_pty_size(CHANNEL *channel, const char *terminal,
|
|||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (channel->version==1) {
|
if (channel->version==1) {
|
||||||
channel_request_pty_size1(channel,terminal, col, row);
|
channel_request_pty_size1(channel,terminal, col, row);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -1150,7 +1157,7 @@ int channel_change_pty_size(CHANNEL *channel, int cols, int rows) {
|
|||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (channel->version == 1) {
|
if (channel->version == 1) {
|
||||||
rc = channel_change_pty_size1(channel,cols,rows);
|
rc = channel_change_pty_size1(channel,cols,rows);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -1186,7 +1193,7 @@ error:
|
|||||||
* @returns SSH_SUCCESS on success, SSH_ERROR on error.
|
* @returns SSH_SUCCESS on success, SSH_ERROR on error.
|
||||||
*/
|
*/
|
||||||
int channel_request_shell(CHANNEL *channel) {
|
int channel_request_shell(CHANNEL *channel) {
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (channel->version == 1) {
|
if (channel->version == 1) {
|
||||||
return channel_request_shell1(channel);
|
return channel_request_shell1(channel);
|
||||||
}
|
}
|
||||||
@@ -1305,7 +1312,7 @@ int channel_request_exec(CHANNEL *channel, const char *cmd) {
|
|||||||
STRING *command = NULL;
|
STRING *command = NULL;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (channel->version == 1) {
|
if (channel->version == 1) {
|
||||||
return channel_request_exec1(channel, cmd);
|
return channel_request_exec1(channel, cmd);
|
||||||
}
|
}
|
||||||
@@ -1611,6 +1618,9 @@ int channel_poll(CHANNEL *channel, int is_stderr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buffer_get_rest_len(stdbuf) > 0)
|
||||||
|
return buffer_get_rest_len(stdbuf);
|
||||||
|
|
||||||
if (channel->remote_eof) {
|
if (channel->remote_eof) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_EOF;
|
return SSH_EOF;
|
||||||
@@ -1651,7 +1661,9 @@ int channel_get_exit_status(CHANNEL *channel) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (channel->open == 0) {
|
if (channel->open == 0) {
|
||||||
return -1;
|
/* When a channel is closed, no exit status message can
|
||||||
|
* come anymore */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh1.h"
|
#include "libssh/ssh1.h"
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a big hack. In fact, SSH1 doesn't make a clever use of channels.
|
* This is a big hack. In fact, SSH1 doesn't make a clever use of channels.
|
||||||
@@ -301,5 +301,5 @@ int channel_write1(CHANNEL *channel, const void *data, int len) {
|
|||||||
return origlen;
|
return origlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
/* vim: set ts=2 sw=2 et cindent: */
|
/* vim: set ts=2 sw=2 et cindent: */
|
||||||
|
|||||||
@@ -24,6 +24,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
|
|
||||||
@@ -93,7 +98,10 @@ char *ssh_get_banner(SSH_SESSION *session) {
|
|||||||
* @see ssh_get_banner()
|
* @see ssh_get_banner()
|
||||||
*/
|
*/
|
||||||
static int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2) {
|
static int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2) {
|
||||||
char *banner = session->serverbanner;
|
const char *banner = session->serverbanner;
|
||||||
|
const char *openssh;
|
||||||
|
|
||||||
|
ssh_log(session, SSH_LOG_RARE, "Analyzing banner: %s", banner);
|
||||||
|
|
||||||
if (strncmp(banner, "SSH-", 4) != 0) {
|
if (strncmp(banner, "SSH-", 4) != 0) {
|
||||||
ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner);
|
ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner);
|
||||||
@@ -124,6 +132,17 @@ static int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openssh = strstr(banner, "OpenSSH");
|
||||||
|
if (openssh != NULL) {
|
||||||
|
int major, minor;
|
||||||
|
major = strtol(openssh + 8, (char **) NULL, 10);
|
||||||
|
minor = strtol(openssh + 10, (char **) NULL, 10);
|
||||||
|
session->openssh = SSH_VERSION_INT(major, minor, 0);
|
||||||
|
ssh_log(session, SSH_LOG_RARE,
|
||||||
|
"We are talking to an OpenSSH server version: %d.%d (%x)",
|
||||||
|
major, minor, session->openssh);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +235,7 @@ static int dh_handshake(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
string_burn(e);
|
string_burn(e);
|
||||||
string_free(e);
|
string_free(e);
|
||||||
|
e=NULL;
|
||||||
|
|
||||||
rc = packet_send(session);
|
rc = packet_send(session);
|
||||||
if (rc == SSH_ERROR) {
|
if (rc == SSH_ERROR) {
|
||||||
@@ -256,7 +276,7 @@ static int dh_handshake(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
string_burn(f);
|
string_burn(f);
|
||||||
string_free(f);
|
string_free(f);
|
||||||
|
f=NULL;
|
||||||
signature = buffer_get_ssh_string(session->in_buffer);
|
signature = buffer_get_ssh_string(session->in_buffer);
|
||||||
if (signature == NULL) {
|
if (signature == NULL) {
|
||||||
ssh_set_error(session, SSH_FATAL, "No signature in packet");
|
ssh_set_error(session, SSH_FATAL, "No signature in packet");
|
||||||
@@ -327,13 +347,14 @@ static int dh_handshake(SSH_SESSION *session) {
|
|||||||
/* forget it for now ... */
|
/* forget it for now ... */
|
||||||
string_burn(signature);
|
string_burn(signature);
|
||||||
string_free(signature);
|
string_free(signature);
|
||||||
|
signature=NULL;
|
||||||
/*
|
/*
|
||||||
* Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and
|
* Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and
|
||||||
* current_crypto
|
* current_crypto
|
||||||
*/
|
*/
|
||||||
if (session->current_crypto) {
|
if (session->current_crypto) {
|
||||||
crypto_free(session->current_crypto);
|
crypto_free(session->current_crypto);
|
||||||
|
session->current_crypto=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME later, include a function to change keys */
|
/* FIXME later, include a function to change keys */
|
||||||
@@ -359,14 +380,22 @@ static int dh_handshake(SSH_SESSION *session) {
|
|||||||
|
|
||||||
/* not reached */
|
/* not reached */
|
||||||
error:
|
error:
|
||||||
|
if(e != NULL){
|
||||||
string_burn(e);
|
string_burn(e);
|
||||||
string_free(e);
|
string_free(e);
|
||||||
|
}
|
||||||
|
if(f != NULL){
|
||||||
string_burn(f);
|
string_burn(f);
|
||||||
string_free(f);
|
string_free(f);
|
||||||
|
}
|
||||||
|
if(pubkey != NULL){
|
||||||
string_burn(pubkey);
|
string_burn(pubkey);
|
||||||
string_free(pubkey);
|
string_free(pubkey);
|
||||||
|
}
|
||||||
|
if(signature != NULL){
|
||||||
string_burn(signature);
|
string_burn(signature);
|
||||||
string_free(signature);
|
string_free(signature);
|
||||||
|
}
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -462,15 +491,10 @@ int ssh_connect(SSH_SESSION *session) {
|
|||||||
session->alive = 0;
|
session->alive = 0;
|
||||||
session->client = 1;
|
session->client = 1;
|
||||||
|
|
||||||
if (ssh_crypto_init() < 0) {
|
if (ssh_init() < 0) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if (ssh_socket_init() < 0) {
|
|
||||||
leave_function();
|
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options->fd == -1 && options->host == NULL) {
|
if (options->fd == -1 && options->host == NULL) {
|
||||||
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -605,6 +629,24 @@ char *ssh_get_issue_banner(SSH_SESSION *session) {
|
|||||||
return string_to_char(session->banner);
|
return string_to_char(session->banner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the version of the OpenSSH server, if it is not an OpenSSH server
|
||||||
|
* then 0 will be returned.
|
||||||
|
*
|
||||||
|
* You can use the SSH_VERSION_INT macro to compare version numbers.
|
||||||
|
*
|
||||||
|
* @param session The SSH session to use.
|
||||||
|
*
|
||||||
|
* @return The version number if available, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int ssh_get_openssh_version(SSH_SESSION *session) {
|
||||||
|
if (session == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return session->openssh;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disconnect from a session (client or server).
|
* @brief Disconnect from a session (client or server).
|
||||||
*
|
*
|
||||||
@@ -613,13 +655,12 @@ char *ssh_get_issue_banner(SSH_SESSION *session) {
|
|||||||
void ssh_disconnect(SSH_SESSION *session) {
|
void ssh_disconnect(SSH_SESSION *session) {
|
||||||
STRING *str = NULL;
|
STRING *str = NULL;
|
||||||
|
|
||||||
enter_function();
|
|
||||||
|
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
leave_function();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enter_function();
|
||||||
|
|
||||||
if (ssh_socket_is_open(session->socket)) {
|
if (ssh_socket_is_open(session->socket)) {
|
||||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
|
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OPENSSL_CRYPTO
|
#ifdef OPENSSL_CRYPTO
|
||||||
#include <openssl/blowfish.h>
|
#include <openssl/blowfish.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|||||||
15
libssh/dh.c
15
libssh/dh.c
@@ -44,6 +44,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
|
|
||||||
@@ -145,6 +149,7 @@ void ssh_crypto_finalize(void) {
|
|||||||
g = NULL;
|
g = NULL;
|
||||||
bignum_free(p);
|
bignum_free(p);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
|
ssh_crypto_initialized=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,20 +627,20 @@ int hashbufout_add_cookie(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
|
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->server) {
|
if (session->server) {
|
||||||
if (buffer_add_data(session->out_hashbuf,
|
if (buffer_add_data(session->out_hashbuf,
|
||||||
session->server_kex.cookie, 16) < 0) {
|
session->server_kex.cookie, 16) < 0) {
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (buffer_add_data(session->out_hashbuf,
|
if (buffer_add_data(session->out_hashbuf,
|
||||||
session->client_kex.cookie, 16) < 0) {
|
session->client_kex.cookie, 16) < 0) {
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -650,11 +655,11 @@ int hashbufin_add_cookie(SSH_SESSION *session, unsigned char *cookie) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
|
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
|
||||||
buffer_free(session->in_hashbuf);
|
buffer_reinit(session->in_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
|
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
|
||||||
buffer_free(session->in_hashbuf);
|
buffer_reinit(session->in_hashbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,29 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
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.
|
* @brief Finalize and cleanup all libssh and cryptographic data structures.
|
||||||
*
|
*
|
||||||
* This function should only be called once, at the end of the program!
|
* This function should only be called once, at the end of the program!
|
||||||
*
|
*
|
||||||
* @returns 0
|
* @returns -1 in case of error
|
||||||
|
@returns 0 otherwise
|
||||||
*/
|
*/
|
||||||
int ssh_finalize(void) {
|
int ssh_finalize(void) {
|
||||||
ssh_crypto_finalize();
|
ssh_crypto_finalize();
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
@@ -417,8 +421,8 @@ int ssh_send_kex(SSH_SESSION *session, int server_kex) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
buffer_free(session->out_hashbuf);
|
buffer_reinit(session->out_hashbuf);
|
||||||
string_free(str);
|
string_free(str);
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
|
|||||||
@@ -29,6 +29,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
@@ -1069,6 +1074,7 @@ static char **ssh_get_knownhost_line(SSH_SESSION *session, FILE **file,
|
|||||||
while (fgets(buffer, sizeof(buffer), *file)) {
|
while (fgets(buffer, sizeof(buffer), *file)) {
|
||||||
ptr = strchr(buffer, '\n');
|
ptr = strchr(buffer, '\n');
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
*ptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = strchr(buffer,'\r');
|
ptr = strchr(buffer,'\r');
|
||||||
@@ -1275,9 +1281,9 @@ static int match_hashed_host(SSH_SESSION *session, const char *host,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SAFE_FREE(source);
|
|
||||||
|
|
||||||
hash = base64_to_bin(b64hash);
|
hash = base64_to_bin(b64hash);
|
||||||
|
SAFE_FREE(source);
|
||||||
if (hash == NULL) {
|
if (hash == NULL) {
|
||||||
buffer_free(salt);
|
buffer_free(salt);
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -1337,6 +1343,9 @@ static int match_hashed_host(SSH_SESSION *session, const char *host,
|
|||||||
* possible attack \n
|
* possible attack \n
|
||||||
* SSH_SERVER_NOT_KNOWN: The server is unknown. User should confirm
|
* SSH_SERVER_NOT_KNOWN: The server is unknown. User should confirm
|
||||||
* the MD5 is correct\n
|
* the MD5 is correct\n
|
||||||
|
* SSH_SERVER_FILE_NOT_FOUND:The known host file does not exist. The
|
||||||
|
* host is thus unknown. File will be created
|
||||||
|
* if host key is accepted\n
|
||||||
* SSH_SERVER_ERROR: Some error happened
|
* SSH_SERVER_ERROR: Some error happened
|
||||||
*
|
*
|
||||||
* \see ssh_options_set_wanted_algo()
|
* \see ssh_options_set_wanted_algo()
|
||||||
@@ -1356,10 +1365,10 @@ int ssh_is_server_known(SSH_SESSION *session) {
|
|||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
if (ssh_options_default_known_hosts_file(session->options) < 0) {
|
if (ssh_options_default_known_hosts_file(session->options) < 0) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||||
"Can't find a known_hosts file");
|
"Can't find a known_hosts file");
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_SERVER_ERROR;
|
return SSH_SERVER_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->options->host == NULL) {
|
if (session->options->host == NULL) {
|
||||||
@@ -1413,6 +1422,8 @@ int ssh_is_server_known(SSH_SESSION *session) {
|
|||||||
/* We override the status with the wrong key state */
|
/* We override the status with the wrong key state */
|
||||||
ret = SSH_SERVER_KNOWN_CHANGED;
|
ret = SSH_SERVER_KNOWN_CHANGED;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tokens_free(tokens);
|
||||||
}
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
@@ -1427,7 +1438,7 @@ int ssh_is_server_known(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** You generaly use it when ssh_is_server_known() answered SSH_SERVER_NOT_KNOWN
|
/** You generaly use it when ssh_is_server_known() answered SSH_SERVER_NOT_KNOWN
|
||||||
* \brief write the current server as known in the known hosts file
|
* \brief write the current server as known in the known hosts file. This will create the known hosts file if it does not exist.
|
||||||
* \param session ssh session
|
* \param session ssh session
|
||||||
* \return 0 on success, -1 on error
|
* \return 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
@@ -1566,7 +1577,7 @@ int ssh_write_knownhost(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(buffer);
|
len = strlen(buffer);
|
||||||
if (fwrite(buffer, len, 1, file) != len || ferror(file)) {
|
if (fwrite(buffer, len, 1, file) != 1 || ferror(file)) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -540,7 +540,6 @@ static int dsa_public_to_string(DSA *key, BUFFER *buffer) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
string_fill(n, (char *) tmp, size);
|
string_fill(n, (char *) tmp, size);
|
||||||
gcry_sexp_release(sexp);
|
|
||||||
|
|
||||||
#elif defined HAVE_LIBCRYPTO
|
#elif defined HAVE_LIBCRYPTO
|
||||||
p = make_bignum_string(key->p);
|
p = make_bignum_string(key->p);
|
||||||
|
|||||||
@@ -1,61 +1,185 @@
|
|||||||
SSH_0.3 {
|
SSH_0.3 {
|
||||||
global:
|
global:
|
||||||
ssh_get_error; ssh_get_error_code;
|
buffer_free;
|
||||||
ssh_new; ssh_set_options; ssh_get_fd; ssh_silent_disconnect;
|
buffer_get;
|
||||||
ssh_connect; ssh_disconnect; ssh_service_request; ssh_get_issue_banner;
|
buffer_get_len;
|
||||||
ssh_copyright; ssh_get_version; ssh_finalize;
|
buffer_new;
|
||||||
ssh_set_fd_toread; ssh_set_fd_towrite; ssh_set_fd_except;
|
channel_change_pty_size;
|
||||||
string_from_char; string_len; string_new; string_fill; string_to_char;
|
channel_close;
|
||||||
string_copy; string_burn; string_data;
|
channel_free;
|
||||||
ssh_crypto_init;
|
channel_get_exit_status;
|
||||||
ssh_get_hexa; ssh_print_hexa; ssh_get_random;
|
channel_get_session;
|
||||||
ssh_get_pubkey_hash; ssh_get_pubkey;
|
channel_is_closed;
|
||||||
ssh_fd_poll; ssh_select; publickey_free;
|
channel_is_eof;
|
||||||
privatekey_from_file; publickey_to_string; publickey_from_privatekey;
|
channel_is_open;
|
||||||
private_key_free; publickey_from_file; try_publickey_from_file;
|
channel_new;
|
||||||
ssh_is_server_known; ssh_write_knownhost;
|
channel_open_forward;
|
||||||
channel_new; channel_open_forward; channel_open_session; channel_free;
|
channel_open_session;
|
||||||
channel_request_pty; channel_request_pty_size; channel_change_pty_size;
|
channel_poll;
|
||||||
channel_request_shell; channel_request_subsystem; channel_request_env;
|
channel_read;
|
||||||
channel_request_exec; channel_request_sftp; channel_write;
|
channel_read_buffer;
|
||||||
channel_send_eof; channel_read_buffer; channel_read; channel_read_nonblocking;
|
channel_read_nonblocking;
|
||||||
channel_poll; channel_close; channel_is_open;
|
channel_request_env;
|
||||||
channel_is_closed; channel_is_eof; channel_select;
|
channel_request_exec;
|
||||||
ssh_options_new; ssh_options_copy; ssh_options_free; ssh_options_set_wanted_algos;
|
channel_request_pty;
|
||||||
ssh_options_set_username; ssh_options_set_port; ssh_options_getopt;
|
channel_request_pty_size;
|
||||||
ssh_options_set_host; ssh_options_set_fd; ssh_options_set_bind;
|
channel_request_sftp;
|
||||||
ssh_options_set_identity; ssh_options_set_status_callback;
|
channel_request_shell;
|
||||||
ssh_options_set_timeout; ssh_options_set_ssh_dir;
|
channel_request_subsystem;
|
||||||
ssh_options_set_known_hosts_file; ssh_options_allow_ssh1;
|
channel_select;
|
||||||
ssh_options_allow_ssh2; ssh_options_set_dsa_server_key;
|
channel_send_eof;
|
||||||
ssh_options_set_rsa_server_key;
|
channel_set_blocking;
|
||||||
buffer_new; buffer_free; buffer_get; buffer_get_len;
|
channel_write;
|
||||||
ssh_userauth_none; ssh_userauth_password; ssh_userauth_offer_pubkey;
|
privatekey_free;
|
||||||
ssh_userauth_pubkey; ssh_userauth_autopubkey; ssh_userauth_kbdint;
|
privatekey_from_file;
|
||||||
ssh_userauth_kbdint_getnprompts; ssh_userauth_kbdint_getname;
|
publickey_free;
|
||||||
ssh_userauth_kbdint_getinstruction; ssh_userauth_kbdint_getprompt;
|
publickey_from_file;
|
||||||
ssh_userauth_kbdint_setanswer;
|
publickey_from_privatekey;
|
||||||
sftp_new; sftp_free; sftp_init; sftp_opendir; sftp_readdir; sftp_dir_eof;
|
publickey_to_string;
|
||||||
sftp_stat; sftp_lstat; sftp_fstat; sftp_attributes_free; sftp_dir_close;
|
sftp_async_read;
|
||||||
sftp_file_close; sftp_open; sftp_read; sftp_write; sftp_seek; sftp_tell;
|
sftp_async_read_begin;
|
||||||
sftp_rewind; sftp_rm; sftp_rmdir; sftp_mkdir; sftp_rename; sftp_setstat;
|
sftp_attributes_free;
|
||||||
sftp_canonicalize_path; sftp_server_new; sftp_server_init;
|
sftp_canonicalize_path;
|
||||||
sftp_get_client_message; sftp_client_message_free; sftp_reply_name;
|
sftp_chmod;
|
||||||
sftp_reply_handle; sftp_handle_alloc; sftp_reply_attr; sftp_handle;
|
sftp_chown;
|
||||||
sftp_reply_status; sftp_reply_names_add; sftp_reply_names;
|
sftp_close;
|
||||||
sftp_reply_data; sftp_handle_remove;
|
sftp_closedir;
|
||||||
ssh_bind_new; ssh_bind_set_options; ssh_bind_listen; ssh_bind_set_blocking;
|
sftp_dir_eof;
|
||||||
ssh_bind_get_fd; ssh_bind_set_toaccept; ssh_bind_accept; ssh_bind_free;
|
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_accept;
|
||||||
ssh_message_get; ssh_message_type; ssh_message_subtype;
|
ssh_auth_list;
|
||||||
ssh_message_reply_default; ssh_message_free; ssh_message_auth_user;
|
ssh_bind_accept;
|
||||||
ssh_message_auth_password; ssh_message_auth_reply_success;
|
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_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_set_methods;
|
||||||
|
ssh_message_auth_user;
|
||||||
ssh_message_channel_request_open_reply_accept;
|
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;
|
ssh_message_channel_request_reply_success;
|
||||||
set_encrypt_key; set_decrypt_key; cbc_encrypt; cbc_decrypt;
|
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:
|
local:
|
||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,6 +34,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/libssh.h"
|
#include "libssh/libssh.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/server.h"
|
#include "libssh/server.h"
|
||||||
@@ -778,7 +783,9 @@ void ssh_message_free(SSH_MESSAGE *msg){
|
|||||||
SAFE_FREE(msg->channel_request.subsystem);
|
SAFE_FREE(msg->channel_request.subsystem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZERO_STRUCTP(msg);
|
ZERO_STRUCTP(msg);
|
||||||
|
SAFE_FREE(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ SSH_OPTIONS *ssh_options_new(void) {
|
|||||||
option->port=22; /* set the default port */
|
option->port=22; /* set the default port */
|
||||||
option->fd=-1;
|
option->fd=-1;
|
||||||
option->ssh2allowed=1;
|
option->ssh2allowed=1;
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
option->ssh1allowed=1;
|
option->ssh1allowed=1;
|
||||||
#else
|
#else
|
||||||
option->ssh1allowed=0;
|
option->ssh1allowed=0;
|
||||||
@@ -830,7 +830,7 @@ int ssh_options_getopt(SSH_OPTIONS *options, int *argcptr, char **argv) {
|
|||||||
int compress = 0;
|
int compress = 0;
|
||||||
int cont = 1;
|
int cont = 1;
|
||||||
int current = 0;
|
int current = 0;
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
int ssh1 = 1;
|
int ssh1 = 1;
|
||||||
#else
|
#else
|
||||||
int ssh1 = 0;
|
int ssh1 = 0;
|
||||||
|
|||||||
@@ -27,6 +27,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
@@ -210,7 +214,7 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
/* a slighty modified packet_read2() for SSH-1 protocol */
|
/* a slighty modified packet_read2() for SSH-1 protocol */
|
||||||
static int packet_read1(SSH_SESSION *session) {
|
static int packet_read1(SSH_SESSION *session) {
|
||||||
void *packet = NULL;
|
void *packet = NULL;
|
||||||
@@ -359,11 +363,11 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
|
|
||||||
/* that's where i'd like C to be object ... */
|
/* that's where i'd like C to be object ... */
|
||||||
int packet_read(SSH_SESSION *session) {
|
int packet_read(SSH_SESSION *session) {
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (session->version == 1) {
|
if (session->version == 1) {
|
||||||
return packet_read1(session);
|
return packet_read1(session);
|
||||||
}
|
}
|
||||||
@@ -534,7 +538,7 @@ static int packet_send1(SSH_SESSION *session) {
|
|||||||
"%d bytes after comp + %d padding bytes = %d bytes packet",
|
"%d bytes after comp + %d padding bytes = %d bytes packet",
|
||||||
currentlen, padding, ntohl(finallen));
|
currentlen, padding, ntohl(finallen));
|
||||||
|
|
||||||
if (buffer_prepend_data(session->out_buffer,i &padstring, padding) < 0) {
|
if (buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(u32)) < 0) {
|
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(u32)) < 0) {
|
||||||
@@ -576,7 +580,7 @@ error:
|
|||||||
return rc; /* SSH_OK, AGAIN or ERROR */
|
return rc; /* SSH_OK, AGAIN or ERROR */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
|
|
||||||
int packet_send(SSH_SESSION *session) {
|
int packet_send(SSH_SESSION *session) {
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
@@ -593,7 +597,7 @@ void packet_parse(SSH_SESSION *session) {
|
|||||||
int type = session->in_packet.type;
|
int type = session->in_packet.type;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (session->version == 1) {
|
if (session->version == 1) {
|
||||||
/* SSH-1 */
|
/* SSH-1 */
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@@ -607,7 +611,7 @@ void packet_parse(SSH_SESSION *session) {
|
|||||||
case SSH_SMSG_STDOUT_DATA:
|
case SSH_SMSG_STDOUT_DATA:
|
||||||
case SSH_SMSG_STDERR_DATA:
|
case SSH_SMSG_STDERR_DATA:
|
||||||
case SSH_SMSG_EXITSTATUS:
|
case SSH_SMSG_EXITSTATUS:
|
||||||
channel_handle1(session,type)
|
channel_handle1(session,type);
|
||||||
return;
|
return;
|
||||||
case SSH_MSG_DEBUG:
|
case SSH_MSG_DEBUG:
|
||||||
case SSH_MSG_IGNORE:
|
case SSH_MSG_IGNORE:
|
||||||
@@ -618,7 +622,7 @@ void packet_parse(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
#endif /* HAVE_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case SSH2_MSG_DISCONNECT:
|
case SSH2_MSG_DISCONNECT:
|
||||||
buffer_get_u32(session->in_buffer, &tmp);
|
buffer_get_u32(session->in_buffer, &tmp);
|
||||||
@@ -654,12 +658,12 @@ void packet_parse(SSH_SESSION *session) {
|
|||||||
default:
|
default:
|
||||||
ssh_log(session, SSH_LOG_RARE, "Received unhandled packet %d", type);
|
ssh_log(session, SSH_LOG_RARE, "Received unhandled packet %d", type);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
static int packet_wait1(SSH_SESSION *session, int type, int blocking) {
|
static int packet_wait1(SSH_SESSION *session, int type, int blocking) {
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
@@ -715,7 +719,7 @@ static int packet_wait1(SSH_SESSION *session, int type, int blocking) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
|
|
||||||
static int packet_wait2(SSH_SESSION *session, int type, int blocking) {
|
static int packet_wait2(SSH_SESSION *session, int type, int blocking) {
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
@@ -769,7 +773,7 @@ static int packet_wait2(SSH_SESSION *session, int type, int blocking) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int packet_wait(SSH_SESSION *session, int type, int block) {
|
int packet_wait(SSH_SESSION *session, int type, int block) {
|
||||||
#ifdef HAVE_SSH1
|
#ifdef WITH_SSH1
|
||||||
if (session->version == 1) {
|
if (session->version == 1) {
|
||||||
return packet_wait1(session, type, block);
|
return packet_wait1(session, type, block);
|
||||||
}
|
}
|
||||||
|
|||||||
206
libssh/poll.c
Normal file
206
libssh/poll.c
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ int ssh_bind_listen(SSH_BIND *ssh_bind) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssh_socket_init() < 0) {
|
if (ssh_init() < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ static int dh_handshake_server(SSH_SESSION *session) {
|
|||||||
buffer_add_ssh_string(session->out_buffer, f) < 0 ||
|
buffer_add_ssh_string(session->out_buffer, f) < 0 ||
|
||||||
buffer_add_ssh_string(session->out_buffer, sign) < 0) {
|
buffer_add_ssh_string(session->out_buffer, sign) < 0) {
|
||||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
string_free(f);
|
string_free(f);
|
||||||
string_free(sign);
|
string_free(sign);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -437,7 +437,7 @@ static int dh_handshake_server(SSH_SESSION *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||||
buffer_free(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,10 +479,6 @@ int ssh_accept(SSH_SESSION *session) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssh_crypto_init() < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
session->alive = 1;
|
session->alive = 1;
|
||||||
|
|
||||||
session->clientbanner = ssh_get_banner(session);
|
session->clientbanner = ssh_get_banner(session);
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ void ssh_cleanup(SSH_SESSION *session) {
|
|||||||
SAFE_FREE(session->banner);
|
SAFE_FREE(session->banner);
|
||||||
buffer_free(session->in_buffer);
|
buffer_free(session->in_buffer);
|
||||||
buffer_free(session->out_buffer);
|
buffer_free(session->out_buffer);
|
||||||
|
session->in_buffer=session->out_buffer=NULL;
|
||||||
crypto_free(session->current_crypto);
|
crypto_free(session->current_crypto);
|
||||||
crypto_free(session->next_crypto);
|
crypto_free(session->next_crypto);
|
||||||
ssh_socket_free(session->socket);
|
ssh_socket_free(session->socket);
|
||||||
|
|||||||
188
libssh/sftp.c
188
libssh/sftp.c
@@ -31,6 +31,10 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
#include "libssh/sftp.h"
|
#include "libssh/sftp.h"
|
||||||
@@ -1677,6 +1681,7 @@ ssize_t sftp_write(SFTP_FILE *file, const void *buf, size_t count) {
|
|||||||
BUFFER *buffer;
|
BUFFER *buffer;
|
||||||
u32 id;
|
u32 id;
|
||||||
int len;
|
int len;
|
||||||
|
int packetlen;
|
||||||
|
|
||||||
buffer = buffer_new();
|
buffer = buffer_new();
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
@@ -1700,12 +1705,12 @@ ssize_t sftp_write(SFTP_FILE *file, const void *buf, size_t count) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
string_free(datastring);
|
string_free(datastring);
|
||||||
|
|
||||||
len = sftp_packet_write(file->sftp, SSH_FXP_WRITE, buffer);
|
len = sftp_packet_write(file->sftp, SSH_FXP_WRITE, buffer);
|
||||||
|
packetlen=buffer_get_len(buffer);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if ((u32) len != buffer_get_len(buffer)) {
|
} else if (len != packetlen) {
|
||||||
ssh_log(sftp->session, SSH_LOG_PACKET,
|
ssh_log(sftp->session, SSH_LOG_PACKET,
|
||||||
"Could not write as much data as expected");
|
"Could not write as much data as expected");
|
||||||
}
|
}
|
||||||
@@ -2207,6 +2212,185 @@ int sftp_utimes(SFTP_SESSION *sftp, const char *file,
|
|||||||
return sftp_setstat(sftp, file, &attr);
|
return sftp_setstat(sftp, file, &attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sftp_symlink(SFTP_SESSION *sftp, const char *target, const char *dest) {
|
||||||
|
STATUS_MESSAGE *status = NULL;
|
||||||
|
SFTP_MESSAGE *msg = NULL;
|
||||||
|
STRING *target_s;
|
||||||
|
STRING *dest_s;
|
||||||
|
BUFFER *buffer;
|
||||||
|
u32 id;
|
||||||
|
|
||||||
|
if (sftp == NULL || target == NULL || dest == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = buffer_new();
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_s = string_from_char(target);
|
||||||
|
if (target_s == NULL) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_s = string_from_char(dest);
|
||||||
|
if (dest_s == NULL) {
|
||||||
|
string_free(target_s);
|
||||||
|
buffer_free(buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = sftp_get_new_id(sftp);
|
||||||
|
if (buffer_add_u32(buffer, id) < 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(dest_s);
|
||||||
|
string_free(target_s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ssh_get_openssh_version(sftp->session)) {
|
||||||
|
/* TODO check for version number if they ever fix it. */
|
||||||
|
if (buffer_add_ssh_string(buffer, target_s) < 0 ||
|
||||||
|
buffer_add_ssh_string(buffer, dest_s) < 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(dest_s);
|
||||||
|
string_free(target_s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer_add_ssh_string(buffer, dest_s) < 0 ||
|
||||||
|
buffer_add_ssh_string(buffer, target_s) < 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(dest_s);
|
||||||
|
string_free(target_s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sftp_packet_write(sftp, SSH_FXP_SYMLINK, buffer) < 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(dest_s);
|
||||||
|
string_free(target_s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(dest_s);
|
||||||
|
string_free(target_s);
|
||||||
|
|
||||||
|
while (msg == NULL) {
|
||||||
|
if (sftp_read_and_dispatch(sftp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
msg = sftp_dequeue(sftp, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* By specification, this command only returns SSH_FXP_STATUS */
|
||||||
|
if (msg->packet_type == SSH_FXP_STATUS) {
|
||||||
|
status = parse_status_msg(msg);
|
||||||
|
sftp_message_free(msg);
|
||||||
|
if (status == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sftp_set_error(sftp, status->status);
|
||||||
|
switch (status->status) {
|
||||||
|
case SSH_FX_OK:
|
||||||
|
status_msg_free(status);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* The status should be SSH_FX_OK if the command was successful, if it
|
||||||
|
* didn't, then there was an error
|
||||||
|
*/
|
||||||
|
ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
|
||||||
|
"SFTP server: %s", status->errormsg);
|
||||||
|
status_msg_free(status);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
ssh_set_error(sftp->session, SSH_FATAL,
|
||||||
|
"Received message %d when attempting to set stats", msg->packet_type);
|
||||||
|
sftp_message_free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sftp_readlink(SFTP_SESSION *sftp, const char *path) {
|
||||||
|
STATUS_MESSAGE *status = NULL;
|
||||||
|
SFTP_MESSAGE *msg = NULL;
|
||||||
|
STRING *path_s = NULL;
|
||||||
|
STRING *link_s = NULL;
|
||||||
|
BUFFER *buffer;
|
||||||
|
char *link;
|
||||||
|
u32 ignored;
|
||||||
|
u32 id;
|
||||||
|
|
||||||
|
if (sftp == NULL || path == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = buffer_new();
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_s = string_from_char(path);
|
||||||
|
if (path_s == NULL) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = sftp_get_new_id(sftp);
|
||||||
|
if (buffer_add_u32(buffer, id) < 0 ||
|
||||||
|
buffer_add_ssh_string(buffer, path_s) < 0 ||
|
||||||
|
sftp_packet_write(sftp, SSH_FXP_READLINK, buffer) < 0) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(path_s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buffer_free(buffer);
|
||||||
|
string_free(path_s);
|
||||||
|
|
||||||
|
while (msg == NULL) {
|
||||||
|
if (sftp_read_and_dispatch(sftp) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
msg = sftp_dequeue(sftp, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->packet_type == SSH_FXP_NAME) {
|
||||||
|
/* we don't care about "count" */
|
||||||
|
buffer_get_u32(msg->payload, &ignored);
|
||||||
|
/* we only care about the file name string */
|
||||||
|
link_s = buffer_get_ssh_string(msg->payload);
|
||||||
|
sftp_message_free(msg);
|
||||||
|
if (link_s == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
link = string_to_char(link_s);
|
||||||
|
string_free(link_s);
|
||||||
|
|
||||||
|
return link;
|
||||||
|
} else if (msg->packet_type == SSH_FXP_STATUS) { /* bad response (error) */
|
||||||
|
status = parse_status_msg(msg);
|
||||||
|
sftp_message_free(msg);
|
||||||
|
if (status == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
|
||||||
|
"SFTP server: %s", status->errormsg);
|
||||||
|
status_msg_free(status);
|
||||||
|
} else { /* this shouldn't happen */
|
||||||
|
ssh_set_error(sftp->session, SSH_FATAL,
|
||||||
|
"Received message %d when attempting to set stats", msg->packet_type);
|
||||||
|
sftp_message_free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* another code written by Nick */
|
/* another code written by Nick */
|
||||||
char *sftp_canonicalize_path(SFTP_SESSION *sftp, const char *path) {
|
char *sftp_canonicalize_path(SFTP_SESSION *sftp, const char *path) {
|
||||||
STATUS_MESSAGE *status = NULL;
|
STATUS_MESSAGE *status = NULL;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/libssh.h"
|
#include "libssh/libssh.h"
|
||||||
#include "libssh/sftp.h"
|
#include "libssh/sftp.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
|
|||||||
@@ -36,22 +36,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
#if !defined(HAVE_SELECT) && !defined(HAVE_POLL)
|
|
||||||
#error Your system must have either select() or poll()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(HAVE_POLL) && !defined(_WIN32)
|
|
||||||
#warning your system does not have poll. Select has known limitations
|
|
||||||
#define SELECT_LIMIT_CHECK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_POLL
|
|
||||||
#define USE_POLL
|
|
||||||
#include <poll.h>
|
|
||||||
#else
|
|
||||||
#define USE_SELECT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \defgroup ssh_socket SSH Sockets
|
/** \defgroup ssh_socket SSH Sockets
|
||||||
* \addtogroup ssh_socket
|
* \addtogroup ssh_socket
|
||||||
* @{
|
* @{
|
||||||
@@ -472,86 +456,10 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session, u32 len) {
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SELECT
|
/* ssh_socket_poll */
|
||||||
/* ssh_socket_poll, select() version */
|
|
||||||
|
|
||||||
/* \internal
|
|
||||||
* \brief polls the socket for data
|
|
||||||
* \param session ssh session
|
|
||||||
* \param writeable value pointed to set to 1 if it is possible to write
|
|
||||||
* \param except value pointed to set to 1 if there is an exception
|
|
||||||
* \return 1 if it is possible to read, 0 otherwise, -1 on error
|
|
||||||
*/
|
|
||||||
int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
||||||
SSH_SESSION *session = s->session;
|
SSH_SESSION *session = s->session;
|
||||||
struct timeval sometime;
|
pollfd_t fd[1];
|
||||||
fd_set rdes; // read set
|
|
||||||
fd_set wdes; // writing set
|
|
||||||
fd_set edes; // exception set
|
|
||||||
int fdmax =- 1;
|
|
||||||
|
|
||||||
enter_function();
|
|
||||||
|
|
||||||
FD_ZERO(&rdes);
|
|
||||||
FD_ZERO(&wdes);
|
|
||||||
FD_ZERO(&edes);
|
|
||||||
|
|
||||||
if (!ssh_socket_is_open(s)) {
|
|
||||||
*except = 1;
|
|
||||||
*writeable = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef SELECT_LIMIT_CHECK
|
|
||||||
// some systems don't handle the fds > FD_SETSIZE
|
|
||||||
if(s->fd > FD_SETSIZE){
|
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
|
||||||
"File descriptor out of range for select: %d", s->fd);
|
|
||||||
|
|
||||||
leave_function();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!s->data_to_read) {
|
|
||||||
ssh_socket_fd_set(s, &rdes, &fdmax);
|
|
||||||
}
|
|
||||||
if (!s->data_to_write) {
|
|
||||||
ssh_socket_fd_set(s, &wdes, &fdmax);
|
|
||||||
}
|
|
||||||
ssh_socket_fd_set(s, &edes, &fdmax);
|
|
||||||
|
|
||||||
/* Set to return immediately (no blocking) */
|
|
||||||
sometime.tv_sec = 0;
|
|
||||||
sometime.tv_usec = 0;
|
|
||||||
|
|
||||||
/* Make the call, and listen for errors */
|
|
||||||
if (select(fdmax, &rdes, &wdes, &edes, &sometime) < 0) {
|
|
||||||
ssh_set_error(session, SSH_FATAL, "select(): %s", strerror(errno));
|
|
||||||
leave_function();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s->data_to_read) {
|
|
||||||
s->data_to_read = ssh_socket_fd_isset(s, &rdes);
|
|
||||||
}
|
|
||||||
if (!s->data_to_write) {
|
|
||||||
s->data_to_write = ssh_socket_fd_isset(s, &wdes);
|
|
||||||
}
|
|
||||||
if (!s->data_except) {
|
|
||||||
s->data_except = ssh_socket_fd_isset(s, &edes);
|
|
||||||
}
|
|
||||||
*except = s->data_except;
|
|
||||||
*writeable = s->data_to_write;
|
|
||||||
|
|
||||||
leave_function();
|
|
||||||
return (s->data_to_read || (buffer_get_rest_len(s->in_buffer) > 0));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_POLL
|
|
||||||
/* ssh_socket_poll, poll() version */
|
|
||||||
int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
|
||||||
SSH_SESSION *session = s->session;
|
|
||||||
struct pollfd fd[1];
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
@@ -573,7 +481,7 @@ int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make the call, and listen for errors */
|
/* Make the call, and listen for errors */
|
||||||
rc = poll(fd, 1, 0);
|
rc = ssh_poll(fd, 1, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
ssh_set_error(session, SSH_FATAL, "poll(): %s", strerror(errno));
|
ssh_set_error(session, SSH_FATAL, "poll(): %s", strerror(errno));
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -596,7 +504,6 @@ int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return (s->data_to_read || (buffer_get_rest_len(s->in_buffer) > 0));
|
return (s->data_to_read || (buffer_get_rest_len(s->in_buffer) > 0));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief nonblocking flush of the output buffer
|
* \brief nonblocking flush of the output buffer
|
||||||
|
|||||||
@@ -24,6 +24,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
/** \defgroup ssh_string SSH Strings
|
/** \defgroup ssh_string SSH Strings
|
||||||
|
|||||||
17
sample.c
17
sample.c
@@ -367,7 +367,8 @@ void do_sftp(SSH_SESSION *session){
|
|||||||
|
|
||||||
static int auth_kbdint(SSH_SESSION *session){
|
static int auth_kbdint(SSH_SESSION *session){
|
||||||
int err=ssh_userauth_kbdint(session,NULL,NULL);
|
int err=ssh_userauth_kbdint(session,NULL,NULL);
|
||||||
char *name,*instruction,*prompt,*ptr;
|
const char *name, *instruction, *prompt;
|
||||||
|
char *ptr;
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
int i,n;
|
int i,n;
|
||||||
char echo;
|
char echo;
|
||||||
@@ -469,9 +470,12 @@ int main(int argc, char **argv){
|
|||||||
ssh_disconnect(session);
|
ssh_disconnect(session);
|
||||||
ssh_finalize();
|
ssh_finalize();
|
||||||
exit(-1);
|
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:
|
case SSH_SERVER_NOT_KNOWN:
|
||||||
hexa = ssh_get_hexa(hash, hlen);
|
hexa = ssh_get_hexa(hash, hlen);
|
||||||
free(hash);
|
|
||||||
fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");
|
fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");
|
||||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||||
free(hexa);
|
free(hexa);
|
||||||
@@ -483,8 +487,11 @@ int main(int argc, char **argv){
|
|||||||
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||||
fgets(buf,sizeof(buf),stdin);
|
fgets(buf,sizeof(buf),stdin);
|
||||||
if(strncasecmp(buf,"yes",3)==0){
|
if(strncasecmp(buf,"yes",3)==0){
|
||||||
if(ssh_write_knownhost(session))
|
if (ssh_write_knownhost(session) < 0) {
|
||||||
fprintf(stderr,"error %s\n",ssh_get_error(session));
|
free(hash);
|
||||||
|
fprintf(stderr, "error %s\n", strerror(errno));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -552,8 +559,10 @@ int main(int argc, char **argv){
|
|||||||
else
|
else
|
||||||
batch_shell(session);
|
batch_shell(session);
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_SFTP
|
||||||
else
|
else
|
||||||
do_sftp(session);
|
do_sftp(session);
|
||||||
|
#endif
|
||||||
if(!sftp && !cmds[0])
|
if(!sftp && !cmds[0])
|
||||||
do_cleanup(0);
|
do_cleanup(0);
|
||||||
ssh_disconnect(session);
|
ssh_disconnect(session);
|
||||||
|
|||||||
Reference in New Issue
Block a user