Compare commits

...

526 Commits

Author SHA1 Message Date
Andreas Schneider
8daf03c564 session: Check the session timeout and use it if set
This checks if a timeout has been set using ssh_options_set(). If it has
been set it will use that parameter by default for blocking reads.

This is at least what users are expecting.

Fixes T33

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-12-07 18:09:27 +01:00
Andreas Schneider
8ece2abfab session: Use long for the timeout
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:49:17 +01:00
Anderson Toshiyuki Sasaki
f05717d23e sftp: Add NULL check in sftp_fstat()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-12-07 17:47:22 +01:00
Anderson Toshiyuki Sasaki
eaa97d2062 sftp: Add NULL check in sftp_xstat()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:47:18 +01:00
Anderson Toshiyuki Sasaki
bda2cc69af sftp: Add NULL check in sftp_opendir()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:47:11 +01:00
Anderson Toshiyuki Sasaki
83d827d7dd sftp: Set sftp error when received unexpected message
Set sftp error to SSH_FX_BAD_MESSAGE if an unexpected message is
received.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:47:00 +01:00
Anderson Toshiyuki Sasaki
0f95295966 sftp: Set sftp error code when fail occurs
When an operation fails in sftp subsystem, set the sftp error, so that
it can be obtained by sftp_get_error().

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:44:52 +01:00
Anderson Toshiyuki Sasaki
8e69d435ef channels: Set error state when closed channel is read
When an attempt to read a closed channel happens, set the session error
state properly.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:44:46 +01:00
Anderson Toshiyuki Sasaki
d78a29eb79 sftp: Set error when EOF is received in sftp_packet_read()
When reading a sftp packet and an EOF is received before all requested
bytes are read, set the session and sftp error codes.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 17:43:08 +01:00
Andreas Schneider
58113d489e connect: Fix size type for i an j in ssh_select()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 14:08:31 +01:00
Andreas Schneider
c306a693f3 buffer: Use size_t for argc argument in ssh_buffer_(un)pack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 14:08:31 +01:00
Jakub Jelen
21e2522360 config: Get rid of the dynamic seen array
* This makes the array constant in the session structure, avoiding
   allocations and frees while parsing the file
 * It also drops passing the seen array to all the functions,
   because it is already part of the passed session
 * The test cases are adjusted to match these changes

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 14:08:27 +01:00
Jakub Jelen
8f887e82c7 config: Reformat local_parse_file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 14:07:31 +01:00
Jakub Jelen
993e24a361 config: Reformat ssh_config_parse_file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 14:07:31 +01:00
Jakub Jelen
cf6f1e7a64 tests: Cover also compression with unit tests
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 14:07:31 +01:00
Jakub Jelen
31bc83f366 tests: Do not recreate unnecessary files for every test case
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 13:57:03 +01:00
Jakub Jelen
42ce989488 tests: Cover missing parts of the config parsing
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-07 13:28:11 +01:00
Andreas Schneider
4282f3c664 gitlab-ci: Fix csbuild to run latest 20 commits
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:52:40 +01:00
Andreas Schneider
3784226fd8 sftp: Do not overwrite errors set by channel functions
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:52:40 +01:00
Andreas Schneider
cf24048f02 libcrypto: Fix integer comparison in evp_cipher_aead_encrypt()
src/libcrypto.c:773:27: warning: comparison of integer expressions of
different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’}
[-Wsign-compare] <--[cc]
     if (rc != 1 || outlen != len - aadlen) {
                           ^~
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:47:25 +01:00
Anderson Toshiyuki Sasaki
f427a975b8 tests: Fix a clang possible memory leak warning
clang was reporting a possible memory leak after mkdtemp() call, which
was a false positive, since mkdtemp() returns the same pointer provided
as the parameter, in case of success.  This changes the code so that the
static analyser don't get confused.

Found by csbuild runner.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:28:40 +01:00
Anderson Toshiyuki Sasaki
c413834764 tests: Test calling ssh_init() after ssh_finalize()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:26:55 +01:00
Anderson Toshiyuki Sasaki
41b0d263d6 libcrypto: Fix access violation in ssh_init()
This fixes an access violation when ssh_init() was called after
ssh_finalize() in Windows when using OpenSSL 1.0.2 and libssh statically
linked.

Fixes T120

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:26:55 +01:00
Andreas Schneider
a08a97f9c7 tests: Use UNUSED macros in torture_threads_init
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:25:12 +01:00
Andreas Schneider
c0ae59e102 bignum: Use UNUSED macros 2018-11-30 18:25:12 +01:00
Andreas Schneider
109a203453 include: Add macro for unused arguments and variables
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:25:12 +01:00
Andreas Schneider
ac8b954019 bignum: Use size_t in ssh_make_string_bn*
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:25:12 +01:00
Andreas Schneider
c6ca62d7e1 crypto: Use size_t for len argument in encrypt and decrpyt fn
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:25:12 +01:00
Anderson Toshiyuki Sasaki
6d3672911b gitlab-ci: Added builds for native Windows
This uses a runner configured with the tag "vs2017 or windows".

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 18:25:12 +01:00
Tilo Eckert
95f83c2391 src: Fix multiple typos
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:29:17 +01:00
Jakub Jelen
130256c348 tests: Verify that signatures are sane and can not be verified by non-matching key
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:26:48 +01:00
Jakub Jelen
b72c9eead6 pki: Sanitize input to verification
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:26:07 +01:00
Jakub Jelen
c7628fbfea pki: Return default RSA key type for DIGEST_AUTO
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:24:21 +01:00
Jakub Jelen
783e5fd206 pki: Verify the provided public key has expected type
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:24:14 +01:00
Jakub Jelen
c79c33e224 pki: Sanity-check signature matches base key type
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:22:51 +01:00
Jakub Jelen
968fdf4e18 tests: Do not require base RSA type for SHA2 extension whitelist
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:22:13 +01:00
Jakub Jelen
bc91fa98ea packet_cb: Properly verify the signature type
Issue reported by Tilo Eckert <tilo.eckert@flam.de>

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:21:52 +01:00
Jakub Jelen
d2434c69c0 pki: Separate signature extraction and verification
Initial solution proposed by Tilo Eckert <tilo.eckert@flam.de>

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:21:18 +01:00
Jakub Jelen
7f83a1efae pki: Set correct type for imported signatures
Issue reported by Tilo Eckert <tilo.eckert@flam.de>

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:20:19 +01:00
Jakub Jelen
7b725e6bc7 pki: Use self-explanatory variable names
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:20:10 +01:00
Jakub Jelen
46d8840f7e The largest ECDSA key has 521 bits
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:20:04 +01:00
Jakub Jelen
c1fdb56d23 pki_gcrypt: Do not abort on bad signature
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-30 16:19:59 +01:00
Jakub Jelen
57bdc9cb20 Whitespace cleanup
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-29 14:22:08 +01:00
Anderson Toshiyuki Sasaki
312084731e tests: Use temporary directories in torture_pki_ed25519.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
500bf54a34 tests: Use temporary directories in torture_pki_ecdsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
a56fa14fda tests: Use temporary directories in torture_pki_dsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
ac1377148f tests: Use temporary directories in torture_threads_pki_rsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
f38c6fcc6e tests: Use temporary directories in torture_pki_rsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
0dd2b375c7 tests: Introduce functions to change directories
This introduces torture_get_current_working_dir() and
torture_change_dir() to allow changing directories in tests.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
77be4ce905 tests: use torture_create_temp_file() in torture_knownhosts_parsing
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
78b1f0ead3 tests: Introduce torture_create_temp_file()
Introduced torture_create_temp_file() and torture_close_fp() to allow
creating temprary files transparently in Unix and Windows environment.
This also adds a unit test for the added functions.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
31527d4105 tests: Use torture_make_temp_dir() in torture_setup_socket_dir()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
65e16b8d9e tests: Introduce torture_make_temp_dir()
Introduces a function to create temporary dir for testing purposes.
Also adds a minimal test for the temporary directory creation.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
1f6b929735 tests: Replace tests filtering with cmocka builtin filter
This completely removes the tests filter code from torture.c and calls
cmocka_set_test_filter() instead, if available.  The checks for required
libraries, headers, and the availability of cmocka_set_test_filter()
were added to the cmake configuration.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 15:51:06 +01:00
Anderson Toshiyuki Sasaki
74285d3aca tests: Define flags not present in Windows
Define flags S_IRWXO and S_IRWXG in torture_knownhosts_parsing.c when
building for Windows.  These flags don't exist in Windows and are not
used.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 11:10:29 +01:00
Anderson Toshiyuki Sasaki
7960fbaabb tests: Add Windows alternatives for low level I/O
In Windows environment, there are available low level I/O operations in
io.h, such as _read(), _write(), _open(), and _close().

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-28 11:10:10 +01:00
Anderson Toshiyuki Sasaki
a2baf6e97b tests: Include config.h in torture_pki.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-27 11:52:12 +01:00
Anderson Toshiyuki Sasaki
f9ff53b494 tests: Include unistd.h only if available
Include the header in tests/torture_pki.c only if it is available.  It
is not available in Windows environment.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-27 11:52:12 +01:00
Andreas Schneider
98487f464b gitlab-ci: If there is not old sha check last 20 commits
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
b214f84538 tests: Avoid warnings about unused arguments
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
05417665b9 tests: Drop duplicate log level setup
Already done in the setup phase.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
e639c9d0d8 kex,packet,packet_cb: Reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
bf2c7128ab server: Do not send SSH_MSG_EXT_INFO after rekey
This should not be a problem for well-behaving clients that do not
append the ext-info-c to the rekey, but if they do, we should not
send it either.

Resolves: T121

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
83f2ac4abb kex: Do not negotiate extensions during rekey
The RFC 8308 clearly says, that the additional  ext-info-c  should
be added only to the first SSH_MSG_KEXINIT.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
0b4c2a8e62 session: Reformat ssh_{set,is}_blocking
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
8418a1131e tests: Fix indentation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
c18ed4eafa Drop unused header file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
daabb084fe tests: Check the new AES-GCM ciphers
Signed-off-by: Jakub Jelen <jakuje@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
6709f2edf9 tests: Do not require all the crypto libs to build testsuite
This was failing when I tried to run the testsuite without
gcrypt devel libraries installed.

Signed-off-by: Jakub Jelen <jakuje@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
5bdb7a5079 crypto: Avoid unused parameter warnings
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
824c56067b config: Drop bogus newline in log
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
db5721d041 tests: Verify setting NULL knownhosts does not crash
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Jakub Jelen
3da5fcbb56 options: Do not crash when setting knownhosts to NULL (T108)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Andreas Schneider
9d8c943c68 Update INSTALL
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:30:16 +01:00
Andreas Schneider
21881cde34 libcrypto: Fix checking for config.h defines
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 18:17:56 +01:00
Aris Adamantiadis
55252e4d70 libcrypto: disable AES-NI engine when running inside valgrind
Valgrind detects many uninitialized memory false positives from
libcrypto's AES-NI internals. Roll back to software AES when running
tests.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 16:54:36 +01:00
Aris Adamantiadis
8e002b9415 tests: Add tests for dh-group14, group16 and group18
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 16:54:24 +01:00
Aris Adamantiadis
f4339df577 packets: allow removal of callbacks
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 16:54:20 +01:00
Aris Adamantiadis
0197e5e1e5 libcrypto: detect non matching headers/shared lib
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 16:54:15 +01:00
Aris Adamantiadis
9546b20dec gcrypt: Bugfix for very slow ecdh
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 16:53:40 +01:00
Tilo Eckert
b227c12ad2 socket: Add missing braces
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-21 12:25:50 +01:00
Tilo Eckert
f369d02932 socket: Remove redundant code
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-20 07:59:32 +01:00
Tilo Eckert
0b9e07fbdc socket: Fix potential buffer overrun
If nread is < 0 and no exception callback is set,
the following code block would cause a buffer overrun.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-20 07:58:08 +01:00
Tilo Eckert
c47cdc0f97 pki: Fix typos in documentation
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-20 07:57:33 +01:00
Tilo Eckert
4b6eb05023 packet: Fix timeout on hostkey type mismatch instead of proper error
If the hostkey type was not in the list of acceptable hostkey
types, the function failed to set the error state. Due to the
fact that the calling function ssh_packet_process() does not
handle the SSH_ERROR return code, the newkeys packet from the
server was silently ignored, stalling the connection until a
timeout occurred.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-20 07:56:04 +01:00
Nicolas Viennot
59ada799d7 packets: Fix ssh_send_keepalive()
ssh_send_keepalive() should use global_request() to properly configure
the state machine for packet filtering.

Signed-off-by: Nicolas Viennot <nicolas@viennot.biz>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-20 07:55:08 +01:00
Andreas Schneider
bb5d46c190 COPYING: Reformat the last paragraph
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-17 20:11:51 +01:00
Andreas Schneider
aa56b8ca53 tests: Fix chroot_wrapper location
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-15 13:38:02 +01:00
Sanne Raymaekers
67f418218b knownhosts: Take StrictHostKeyChecking option into account
Signed-off-by: Sanne Raymaekers <sraymaek@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-08 16:19:18 +01:00
Sanne Raymaekers
03c30e9c8a tests: Ensure the ssh session fd is read-/writeable in torture_proxycommand
Signed-off-by: Sanne Raymaekers <sraymaek@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-08 16:18:16 +01:00
Rosen Penev
61cac32288 crypto: Fix compilation for OpenSSL without deprecated APIs
Added missing bn.h include.

Made engine.h include conditional, otherwise it would fail.

DSA_generate_parameters was deprecated long before 1.1.0.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2018-11-08 09:32:28 +01:00
Christophe Giboudeaux
aa899f8ec0 cmake: Refresh the CMake Config files
This commit fixes a couple issues in the CMake configuration files and uses
native features from CMake:

* libssh-build-tree-settings.cmake is deleted. There was a typo that made
this file unusable, anyway.
* use the macros available in CMakePackageConfigHelpers.cmake to generate
the version file and check that the files exist
* Remove the LIBSSH_THREADS_LIBRARY variable, it used the non-existent
  LIBSSH_THREADS_LIBRARY_NAME variable.
* Fix the in tree build. libssh can be used uninstalled again.

Test plan:
The values were tested after installing the new files and also without running
'make install'.

Signed-off-by: Christophe Giboudeaux <christophe@krop.fr>
2018-11-06 13:53:43 +01:00
Andreas Schneider
c88fb4c55b tests: Use correct assert function in torture_client_config
CID 1396565
CID 1396564
CID 1396563

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-05 07:57:13 +01:00
Andreas Schneider
a8ed5e31dc tests: Check for NULL in torture_client_config
CID 1396566

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-05 07:54:30 +01:00
Andreas Schneider
86dabfe7e4 cmake: Only check for bounded attribute on OpenBSD
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 16:42:06 +01:00
Jakub Jelen
1650d8178e config: Avoid potential file descriptor leak
Found by csbuild runner.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 13:26:09 +01:00
Jakub Jelen
6eb43fcbf3 tests: Verify the configuration reparsing with real client
This tests verifies that the only the first seen option is applied
throughout all the configuration files processed. It also verifies
that the configuration files are parsed automatically and that this
behavior can be overridden by configuration option.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:16:38 +01:00
Jakub Jelen
9aa47fef99 tests: Adjust test that require complete config re-parsing
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:16:38 +01:00
Jakub Jelen
de7405f1c7 config: Preserve the seen array among invocations
This follows the OpenSSH behavior of parsing subseqent configuration
files, while applying only the first option.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:16:38 +01:00
Jakub Jelen
4a95a35bc6 tests: Properly set the bob's UID also in other tests than pubkey
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:16:38 +01:00
Jakub Jelen
f6b390084e tests: Make sure that no other configuration options will get pulled to the auth test from system
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:16:38 +01:00
Jakub Jelen
b7fefb0500 options: Provide a way of disabling automatic config parsing
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:16:35 +01:00
Jakub Jelen
89a8a6fcf0 Process OpenSSH configuration files by default.
This will allow to use the same configuration in client applications
including the users aliases or system wide cryptographic configuration.

As the configuration parsing is the last thing before doing the
actual connection, it might overwrite previously set options.
If this is not intended, the client application can
ask the configuration files to be parsed before setting some other
options that should not ve overwritten. The code ensures that
the configuration is not parsed again.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 11:15:30 +01:00
Jakub Jelen
7e44ce1556 tests: Improve error reporting in auth test
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 10:08:20 +01:00
Jakub Jelen
5fc4d5b22a tests: Typo -- the flags should be checked according to the comment
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 10:08:20 +01:00
Jakub Jelen
5159cd96e8 knownhosts: Make sure we have both knownhosts files ready
If either one is missing at this point, fill it with default vaules in
ssh_options_apply().

Previously, when setting up only knownhosts, global_knownhosts file
was left pointing to NULL and the ssh_known_hosts_read_entries()
was trying to open NULL file which is invalid.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-02 10:08:20 +01:00
Jakub Jelen
35c417312c client: Reformat comment
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-30 16:22:17 +01:00
Jakub Jelen
e1a8b359c1 tests/pkd: Properly clean up memory
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-30 16:22:17 +01:00
Jakub Jelen
c8519c435e session: Drop unused structure member (SSHv1)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-30 16:22:17 +01:00
Jakub Jelen
d85bc347d3 misc: Properly check for errors returned from getpwuid_r()
Resolves: T118

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-30 16:22:17 +01:00
Jakub Jelen
9c4baa7fd5 misc: Reformat ssh_get_user_home_dir and ssh_file_readaccess_ok
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-30 16:22:17 +01:00
Andreas Schneider
a4342b97d6 Bump SO version to 4.7.2
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-29 09:33:46 +01:00
Mike Frysinger
963c3077a4 doc: fix up various typos and trailing whitespace
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-28 12:15:02 +01:00
Andreas Schneider
a280747462 libcrypto: Fix memory leak in evp_final()
Fixes T116

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-27 22:15:56 +02:00
Meng Tan
bce8d56705 gssapi: Set correct state after sending GSSAPI_RESPONSE (select mechanism OID)
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-26 07:28:20 +02:00
Sanne Raymaekers
ced05eb6db socket: Undouble socket fds
Signed-off-by: Sanne Raymaekers <sraymaek@redhat.com>
2018-10-25 18:49:29 +02:00
Meng Tan
b796924fea client: Send KEX as soon as banners are exchanged
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 19:56:15 +02:00
Andreas Schneider
2af4e3970e gitlab-ci: Add static analysis with csbuild
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 14:30:38 +02:00
Andreas Schneider
cf3c2ee5b3 tests: Improve asserts in torture_pki_ecdsa
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
57eb6a400a tests: Init pubkey string with NULL in torture_keyfiles
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
8c77a49729 tests: Fix pointer arithmetic in torture_pki_*_publickey_base64
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
8c8026b892 tests: Init cipher structure in thread_crypto_aes256_cbc()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
80be1d0ee9 legacy: Fix possible null pointer dereference
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
9c3ba94960 buffer: Fix size comparison with count
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
194c34ebe3 messages: Use SSH_MESSAGE_FREE
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
00cd5b1c83 messages: Add SSH_MESSAGE_FREE
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
9fbbdcc154 messages: Rework ssh_message_queue()
Return early and make it easier to understand.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
b9ac61d5a3 messages: Use calloc in ssh_message_new()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
ca425ebe67 messages: Make ssh_message_queue() static
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
7e6b540277 exmpales: Init rc in ssh_server_fork
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
12ec1fed2f examples: Zero fds in sshnetcat
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
fb70d0fb41 pki: Add NULL check in ssh_pki_key_ecdsa_name()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
f8b70d6a73 pki_crypto: Mark iqmp as unused
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
74888a6fa4 pki: Remove superfluous statement
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
729384f346 pki: Add log message on error in ssh_pki_openssh_import()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
7e5291668c gssapi: Check return code of gss_indicate_mechs()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
bb081f6681 gssapi: Ignore return codes of gss_release_buffer()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
8a3ea3bdd5 packet: Do not segfault if we don't have packet_second_block
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
a190ff9302 packet: Add missing null pointer check in ssh_packet_socket_callback()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
2e7e0ad6c9 wrapper: Fix size type and loops in crypt_set_algorithms_server()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
39b08af2e8 wrapper: Reformat crypt_set_algorithms2()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
60a3796041 messages: Log message if callback for window change fails
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
cc4f220fd3 messages: Log message if sending reply fails
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
bc72ec5821 messages: Some cleanup for ssh_packet_service_request
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
54ec81db2d messages: Reformat ssh_packet_service_request()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
1ec2ca4202 connect: Zero the origfds struct
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
2fad391456 client: Remove superfluous strlen()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
cde13b0f00 channels: Check return code of ssh_packet_send()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
8f31623947 channels: Reformat ssh_channel_send_eof()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
253bda4bac channels: Check return of ssh_buffer_unpack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
480915c07d libsshpp: Pass username and submethods to ssh_userauth_kbdint()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
e27c6b21b5 include: Fix HAVE_<FEATURE> checks in pki.h
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
f65c00f39d cmake: Fix -Wattributes check in ConfigureChecks.cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Andreas Schneider
1d33a4424d gitlab-ci: Fix -DWITH_PCAP=ON
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-24 09:48:35 +02:00
Jakub Jelen
0386e088eb tests: Verify we can authenticate using ed25519 key
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
e91bb29e9d tests: Global known_hosts are used for host key verification
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
f622c4309b knownhosts: Consult also the global known hosts file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
ae6b0e0f49 options: Set the global known_hosts file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
bdb3bb9ccd tests: Verify the hostkey ordering for negotiation is correct
Previously, not all of the host keys algorithms were used for algorithm
negotiation. This verifies the algorithms list is sane and ordered
with the key types from known hosts in the first place.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
32e502a79d tests: Generate valid known_hosts file, fixing the current test
Previously, the file contained the known_hosts strings separated
by NULL bytes which somehow magically worked.

The test was also expecting all the keys from the file will have
the same key type, which was not indeed true.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
6ec5a08639 tests: Verify the ecdsa key types are handled correctly
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:20 +02:00
Jakub Jelen
35a6455489 kex: Use all supported hostkey algorithms for negotiation
Previously, only the algorithms we had a keys for in known_hosts
were used, which could lead to no-matching algorithms errors if the
one key we used to depend on was removed from the server.

This commit adds also the other algorithms, but lists them only after
all the key types we have in known_hosts file.

Resolves: T105

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:43:17 +02:00
Jakub Jelen
c1a8c41c5d kex: Honor more host key algorithms than the first one (ssh-ed25519)
The code as it was written used only the first algorithm from
preferred_hostkeys  array and compared it with the list returned
from the known hosts.

This commit is fixing the code so we actually compare each of the
algorithms from both of the lists and returns the intersection.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:42:55 +02:00
Jakub Jelen
893b69d82b knownhosts: Use the correct name for ECDSA keys for host key negotiation
The conversion from  ssh_keytype_e  to string does not work for ECDSA keys,
because different key lengths have different string representation.

The usage of  type_c  should work also for every other key type in future,
but it does not reflrect different signature types (SHA2 extension for RSA
keys), but this early in the key exchange phase, we can not make any
assumptions about supported extensions by the server.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:42:55 +02:00
Jakub Jelen
9285e8516b tests: Do not trace sshd
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:42:55 +02:00
Andreas Schneider
91f35eca4d libsshpp: Use ssh_session_update_known_hosts()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 17:42:02 +02:00
Andreas Schneider
49e287006f tests: Add option tests for global and user specific known_hosts
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 12:31:04 +02:00
Andreas Schneider
85fc0d5b83 options: Add support for getting the known_hosts locations
Fixes T111

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 12:31:04 +02:00
Andreas Schneider
0ff566b6dd examples: Explicitly track auth state in samplesshd-kbdint
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 12:31:04 +02:00
Andreas Schneider
9c200d3ef4 messages: Check that the requested service is 'ssh-connection'
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 12:31:04 +02:00
Meng Tan
4ea46eecce server: Set correct state after sending INFO_REQUEST (Kbd Interactive)
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-19 10:20:53 +02:00
Andreas Schneider
009ca5c9dd priv: Add ssize_t if not available with MSVC
Fixes T113

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Tested-by: Wolf Wolfswinkel <wolf.wolfswinkel@objectplus.nl>
2018-10-17 15:37:28 +02:00
Andreas Schneider
fe618a35dc packet: Add missing break in ssh_packet_incoming_filter()
CID 1396239

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-17 08:19:23 +02:00
Andreas Schneider
795389ae1b src: Fix typos
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 16:36:20 +02:00
Andreas Schneider
60037f3275 Bump ABI to 4.7.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:24:39 +02:00
Anderson Toshiyuki Sasaki
e1548a71bd CVE-2018-10933: Add tests for packet filtering
Created the test torture_packet_filter.c which tests if packets are
being correctly filtered.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
75be012b4a CVE-2018-10933: Introduced packet filtering
The packet filter checks required states for the incoming packets and
reject them if they arrived in the wrong state.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
68b0c7a934 CVE-2018-10933: Check channel state when OPEN_FAILURE arrives
When a SSH2_MSG_OPEN_FAILURE arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
459868c4a5 CVE-2018-10933: Check channel state when OPEN_CONFIRMATION arrives
When a SSH2_MSG_OPEN_CONFIRMATION arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
5d7414467d CVE-2018-10933: Set correct state after sending MIC
After sending the client token, the auth state is set as
SSH_AUTH_STATE_GSSAPI_MIC_SENT.  Then this can be expected to be the
state when a USERAUTH_FAILURE or USERAUTH_SUCCESS arrives.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
20981bf229 CVE-2018-10933: Introduce SSH_AUTH_STATE_AUTH_NONE_SENT
The introduced auth state allows to identify when a request without
authentication information was sent.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
825f4ba964 CVE-2018-10933: Introduce SSH_AUTH_STATE_PASSWORD_AUTH_SENT
The introduced auth state allows to identify when authentication using
password was tried.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Anderson Toshiyuki Sasaki
2bddafeb70 CVE-2018-10933: Introduced new auth states
Introduced the states SSH_AUTH_STATE_PUBKEY_OFFER_SENT and
SSH_AUTH_STATE_PUBKEY_AUTH_SENT to know when SSH2_MSG_USERAUTH_PK_OK and
SSH2_MSG_USERAUTH_SUCCESS should be expected.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:03 +02:00
Andreas Schneider
16b876d07f examples: Use ssh_session_update_known_hosts() for updating known_hosts
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 08:58:31 +02:00
Andreas Schneider
a80caec19b cmake: Disable deprecation warnings for old known_hosts API
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 08:56:46 +02:00
Andreas Schneider
d6b6fff7f7 cmake: Only check for -Wno-gnu-zero-variadic-macro-arguments with clang
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 08:46:25 +02:00
Andreas Schneider
259d7de153 include: Mark old known_hosts API as deprecated
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-13 22:08:41 +02:00
Tilo Eckert
d13517e922 chacha: remove re-declared type
re-declaring typedefs are not supported by some compilers

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
2018-10-13 22:08:39 +02:00
Tilo Eckert
45058285fc knownhosts: Fix invalid read of known_hosts token
Fixes invalid read introduced by commit 21962d.
Accessing tokens[4] for a known_hosts line of
three tokens led to randomly rejected host keys.

This commit completely removes the check because
the optional comments field may contain whitespace.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
2018-10-13 22:08:36 +02:00
Jakub Jelen
42bd7cdf6c tests: Add aes-gcm ciphers tests
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 13:05:38 +02:00
Jakub Jelen
72bd2fe197 libmbedtls: Support OpenSSH-compatible AES-GCM ciphers using mbedTLS
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 13:05:38 +02:00
Jakub Jelen
a2120e168b libmbedtls: Simplify the cipher setup
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 13:05:38 +02:00
Jakub Jelen
5790036a23 libgcrypt: Implement OpenSSH-compatible AES-GCM ciphers using libgcrypt
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 13:05:38 +02:00
Jakub Jelen
032f486f27 cmake: Link against gpg-error
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 13:05:38 +02:00
Jakub Jelen
46090facba libcrypto: Implement OpenSSH-compatible AES-GCM ciphers using OpenSSL
The commit also propares the internals throughout the code base
for the inclusion of a new AEAD cipher, because previously, the
source code counted only with chacha20-poly1305 cipher, which
is very specific in many cases.

The SSH_HMAC_AEAD_GCM mac algorithm is not actually used, but the name
needed to be defined so we can match in the algorithms selection per
OpenSSH specification (MACs are ignored in case GCM is select as a cipher [1]).

If the provided OpenSSL does not provide  EVP_aes_128_gcm()  function,
the AES-GCM ciphers will not be compiled in.

[1] https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?annotate=HEAD

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 12:05:40 +02:00
Jakub Jelen
777786d76c libcrypto: Do not use magic numbers for AES block size
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 12:05:40 +02:00
Jakub Jelen
101df98e54 libcrypto: Avoid double free
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 12:05:40 +02:00
Andreas Schneider
f747e46f33 init: Only add DllMain if we create a shared library
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 11:40:31 +02:00
Andreas Schneider
275f73125d packet: Use a stack buffer for the header
This removes the allocation for the header buffer for each packet we
send.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-08 09:27:12 +02:00
Andreas Schneider
422376efd4 packet: Reformat packet_send2()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-08 09:27:09 +02:00
Andreas Schneider
3245b50795 sftp: Only prepend header data once
This reduces memory moving.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-08 09:27:06 +02:00
Andreas Schneider
508dfc5251 sftp: Reformat sftp_packet_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-08 09:26:59 +02:00
Andreas Schneider
43a40999da agent: Use (PUSH|PULL)_BE_U32 in agent_talk()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-05 14:38:43 +02:00
Andreas Schneider
e701913fc8 agent: Just use uint32_t for the count
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-05 14:38:43 +02:00
Andreas Schneider
aec9fa4442 sftp: Use bytearray macros
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-05 14:38:43 +02:00
Andreas Schneider
85a274ff3c include: Add macros for bytearray handling
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-10-05 14:38:43 +02:00
Andreas Schneider
e210b61148 examples: Reformat knownhosts
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-05 14:38:43 +02:00
Andreas Schneider
f09ca85ebf cmake: Always build position independent code
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-02 14:48:02 +02:00
Andreas Schneider
096d966e43 gitlab-ci: Report errors on debian 2018-09-27 18:06:23 +02:00
Anderson Toshiyuki Sasaki
cc513c4c9a messages: Fixed possible memory leak in ssh_message_queue
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
31202822a7 examples: Add null checks in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
6118628424 examples: Fix libssh_scp.c code style
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
00e5ef1b3c examples: Fix possible memory leak in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
6eef4b4a3c tests: Add frees to avoid memory leak errors
The added frees are unnecessary, but the static analyser does not know.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
79e907402e tests: Replace ssh_buffer_free() with SSH_BUFFER_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
ca7da823c3 tests: Replace ssh_string_free() with SSH_STRING_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
2eaa23a20e tests: Replace ssh_key_free() with SSH_KEY_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
143b5e2e50 tests: Use SSH_STRING_FREE_CHAR
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Anderson Toshiyuki Sasaki
11d480134c include: Add SSH_KEY_FREE
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 15:21:30 +02:00
Andreas Schneider
3786db4cdf gitlab-ci: Get build and test errors from mingw
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-27 08:45:41 +02:00
Andreas Schneider
9cf341bad3 gitlab-ci: Use -DCMAKE_BUILD_TYPE=UndefinedSanitizer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-26 16:55:28 +02:00
Andreas Schneider
e57f0273a6 cmake: Add UndefinedSanitizer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-26 16:54:31 +02:00
Andreas Schneider
3d74c3802e cmake: Also add DEFAULT_LINK_FLAGS for Solaris
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-26 16:53:29 +02:00
Anderson Toshiyuki Sasaki
667fb5f9a9 cmake: Rewritten AddCMockaTest.cmake
This changes add_cmocka_test() to receive compiler options, the
libraries to be linked to the test, and the linker options.  The way the
tests are declared in tests/unittests and tests/client were updated.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-26 16:27:22 +02:00
Alberto Aguirre
14f5624ff5 sftpserver: allocate packet on sftp_server_new
Ensure sftp_server_new allocates the packet and payload as
sftp_packet_read now expects the packet and payload to be
pre-allocated.

Similarly, ensure sftp_get_client_message does not free the packet.

Signed-off-by: Alberto Aguirre <albaguirre@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 16:41:54 +02:00
David Wedderwille
9adc2d36eb connector: Add checks if file descriptor is a socket
Fixes T104

Signed-off-by: David Wedderwille <davidwe@posteo.de>
2018-09-25 14:37:25 +02:00
Andreas Schneider
1e5e09563a socket: Pass MSG_NOSIGNAL to send()
This avoid that we get a SIGPIPE.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
35bf5334b8 socket: Return ssize_t for ssh_socket_unbuffered_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
a7604c7d6e socket: Reformat ssh_socket_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
c5cadaa982 socket: Reformat ssh_socket_unbuffered_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
caf50270c6 socket: Return ssize_t for ssh_socket_unbuffered_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
b7a29c7ffd socket: Reformat ssh_socket_pollcallback()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
491a42d046 socket: Reformat ssh_socket_unbuffered_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
642a1b1aa4 connect: Fix build warning on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
f709c3ac58 config: Fix building without globbing support
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
ae2b9a3bde include: Do not declare ssh_channel_new() twice
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
1d7520b68a cmake: Add -Wattributs for configure checks
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-25 14:37:25 +02:00
Andreas Schneider
9c37c8c5a5 cmake: Bump library version 2018-09-20 16:35:13 +02:00
Chris Townsend
6c56c1e0d7 sftpserver: Support some openssh extensions
Add support for "hardlink@openssh.com" and
"posix-rename@openssh.com" extensions.

Signed-off-by: Chris Townsend <christopher.townsend@canonical.com>
Signed-off-by: Alberto Aguirre <albaguirre@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 16:35:13 +02:00
Andreas Schneider
e4711c469f pki: Use strndup in ssh_pki_export_privkey_base64()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 16:35:13 +02:00
Andreas Schneider
8410f43d8b tests: Add a test for ssh_pki_export_privkey_base64()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 16:35:13 +02:00
DavidWed
d0ce2d1ecd pki: Add ssh_pki_export_privkey_base64()
Fixes T53

Signed-off-by: DavidWedderwille <davidwe@posteo.de>
Reviewed-by: Andreas Schneider <asn@samba.org>
2018-09-20 16:35:13 +02:00
Andreas Schneider
5a198732a5 tests: Add test for ssh_get_fingerprint_hash()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 16:35:13 +02:00
Andreas Schneider
92aa2cf496 dh: Use ssh_get_fingerprint_hash() in ssh_print_hash()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 16:35:13 +02:00
Andreas Schneider
bbed139eca dh: Add ssh_get_fingerprint_hash()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 16:35:13 +02:00
Anderson Toshiyuki Sasaki
0eab270754 dh: Removed duplicated code
The code for calculating SHA 512 in ssh_make_sessionid() had been
duplicated; the cases were unified.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-09-20 15:37:23 +02:00
Anderson Toshiyuki Sasaki
71594f9d6c dh: Add diffie-hellman-group18-sha512 support
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-09-20 15:37:23 +02:00
Andreas Schneider
2ae2baf9ca buffer: Don't call va_end() twice
This is handled in the cleanup.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 15:37:23 +02:00
Andreas Schneider
4c47719d98 examples: Reformat authenticaton.c
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-20 15:37:23 +02:00
Andreas Schneider
a30d542207 sftp: Include stdint.h
Thanks to Apex Liu

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-19 12:25:03 +02:00
Anderson Toshiyuki Sasaki
d9d3b65df2 dh: Add diffie-hellman-group16-sha512 support
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-19 12:17:02 +02:00
Harald Sitter
97cb302c0e sftp: fix buffer_unpack argument to be char** rather than char*
Summary:
buffer variable 's' gets unpacked as char**, the previous code was passing
a char* causing segfaults on all readlink calls inside the unpacking code

Test Plan:
- without patchy examples/samplesftp segfaults in readlink
- with patchy it doesn't

Reviewers: asn

Differential Revision: https://bugs.libssh.org/D14

Signed-off-by: Harald Sitter <sitter@kde.org>
2018-09-19 11:18:12 +02:00
Andreas Schneider
90373d8394 buffer: Do cleanup if ssh_buffer_unpack() fails in the first loop
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-19 11:18:12 +02:00
Andreas Schneider
07f7fa7806 buffer: Fix invalid memory access in ssh_buffer_unpack()
Found by oss-fuzz.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-19 11:18:02 +02:00
Andreas Schneider
5123f7955b tests: Add OK: and a new line to ssh_ping
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 18:46:28 +02:00
Jakub Jelen
c15ad753a7 tests: Wait for the server to start
The previous timeout of 500 ms was not enough on slower machines or
while running the tests under valgrind. On much faster machines the
sleep() was bringing unnecessary overhead.

This method opens simple connection to the server verifying it is ready
to accept the connection from the test for 5 seconds. It the server
does not start until then, it fails the tests during initialization,
rather than leaving the cases to run against missing server.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 18:07:27 +02:00
Anderson Toshiyuki Sasaki
63aa274f4b tests: Add null checks in torture_threads_pki_rsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
8170e30073 tests: Add null checks in torture_pki_rsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
77f58a225f tests: Add null checks in torture_pki_ed25519.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
48459c37f6 tests: Add null checks in torture_pki_ecdsa.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
31f24ed23e tests: Add null checks and frees in torture_pki_dsa.c
These frees are unnecessary because the negative tests should not
allocate the keys, but the static analyser reports memory leak errors.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
82c3faa44d tests: Add return and null checks in torture_options.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
7c75e76d10 tests: Add null checks in torture_config.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
f246e31ca0 examples: Fix code style in samplesftp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Anderson Toshiyuki Sasaki
7390db6bbb examples: Fixed possible memory leak in samplesftp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Andreas Schneider
cc83b463ce sftp: Fix a possible null pointer dereference
CID 1395721

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 10:19:59 +02:00
Jakub Jelen
39975fdd6d tests: Verify we can read public key from OpenSSH container
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
1226de875b pki: Implement reading public key from OpenSSH private key container
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
2307be32cf Revert "pkd: Generate host keys in old format"
This is no longer needed since libssh can read the private keys
in new OpenSSH format.

This reverts commit 100c9c98ce.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
eaaa4131de tests: Verify the keys loaded from new OpenSSH format
This runs the same test that are ran on the legacy PEM files
also with the new OpenSSH key files.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
39102224b2 pki: Allow reading keys in new OpenSSH format
This implements reading the OpenSSH key format accross the
cryptographic backends. Most of the code is shared and moved
to pki.c, just the building of the keys is implemented in
pki_privkey_build_*() functions.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
e365aed6d2 tests: Provide testing keys also in OpenSSH format
This extends the torture API to provide a way to request
keys in different formats. This extends the keys with
private keys in the new OpenSSH format (default since
OpenSSH 7.8).

This also needs modifications to the ed25519 tests, which
do not support PEM format and expected the new format out of the
box.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
d23bda8181 pki: Use unpack to simplify public key reading
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Jakub Jelen
86d521cbe7 buffer: Make sure unpack of secure buffers securely cleans up
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:53:49 +02:00
Andreas Schneider
856dc698a9 libmbedcrypto: Fix creating evp hash
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-18 09:51:41 +02:00
Jakub Jelen
4d09c6dc31 buffer: Reformat ssh_buffer_get_ssh_string
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
03a66b8599 tests: Use stdbool for with_passphrase argument
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
c04eac40f3 pki_crypto: Clarify that memory passed with set0 is managed by openssl objects
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
8cc0672c0c pki_mbedcrypto: pki_pubkey_build_rsa: properly clean up on error
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
8f7214a584 pki: Initialize pointers to NULL
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
9d2de880ec tests: Drop duplicate ed25519 key creation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
039c066da5 buffer: Fix typo
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 16:39:38 +02:00
Jakub Jelen
6efbf7a30e tests: Verify the pubkey authentication works with ECDSA keys
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2018-09-17 16:39:38 +02:00
Andreas Schneider
e5170107c9 auth: Fix ecdsa pubkey auth
Pair-Programmed-With: Jakub Jelen <jjelen@redhat.com>
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2018-09-17 16:39:12 +02:00
Andreas Schneider
30df04a8a5 tests: Do not call sftp_canonicalize_path()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 14:35:39 +02:00
Andreas Schneider
aaca395bd3 tests: Add a sftp benchmark test for write/read
The tests writes and reads a file of 128M.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
0762057eb9 sftp: Move the packet payload to the message
This reduces memory allocations and copying.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
57153f6481 sftp: Use SSH_BUFFER_FREE in sftp_message_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
4c32befd93 sftp: Reformat sftp_message_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
be8302e2f3 sftp: Allocate a new buffer in sftp_packet_read() if needed
We will move the buffer to the message instead of duplicating the
memory.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
97d2e1f4cb sftp: Reformat sftp_read_and_dispatch()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
12fc0ea1bf sftp: Validate the packet handle before we allocate memory
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
573eab0d51 sftp: Reformat sftp_get_message()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
0e317e612f sftp: Use bool for is_eof in sftp_packet_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
01135703a3 sftp: Use 's' only in the scope it is needed
This revaled a bug when reading the packet type.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
c070414309 sftp: Use 16K for the transfer buffer size
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
d2cc4eccc7 sftp: Get the packet type directly from the buffer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
38781f69b0 sftp: Limit packet size to 256 MB
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
dc4faf9952 sftp: Directly read and validate the packet size from the bufffer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
cbbc6ddcb6 sftp: Use read_packet from sftp handle
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
a7456bf4d5 sftp: Simplify the code for reading data
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
afc14fe003 sftp: Reformat sftp_packet_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
79a3fcac72 sftp: Keep a ssh_packet for reading in the sftp handle
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
945afaa6b4 sftp: Remove ZERO_STRUCTP from sftp_free()
The structure doesn't hold any sensitive data and this would be
optimized away anyway.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
d840a05be3 sftp: Reformat sftp_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
662c30eb72 sftp: Reformat sftp_new()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
29b5477849 include: Add SSH_BUFFER_FREE
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
2e8f2f03e7 cmake: Correctly detect if glob has gl_flags member
Thanks to Baruch Siach.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-17 10:48:49 +02:00
Andreas Schneider
983d1189d0 gitlab-ci: Add builds with gcc7
It looks like gcc7 has more warning enabled or something is broken in
gcc8.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-10 13:02:40 +02:00
Andreas Schneider
7b2e1c7fb7 gitlab-ci: Big cleanup
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-10 12:02:08 +02:00
Andreas Schneider
ceecd3fd6f config: Fix size type
src/config.c:562:12: error: assuming signed overflow does not occur when
    simplifying conditional to constant [-Werror=strict-overflow]

         if (args < 1) {
            ^

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-06 08:28:24 +02:00
Andreas Schneider
bfd33ecf29 cmake: Use -Wpedantic and remove -pedantic-errors
We get -Werror if -DPICKY_DEVELOPER=ON is set.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-06 08:28:24 +02:00
Jakub Jelen
56317caafc tests: UsePrivilegeSeparation has no effect since OpenSSH 7.5
Additionally, we can already work around the privilege separation.

http://www.openssh.com/txt/release-7.5

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 15:43:11 +02:00
Jakub Jelen
ca4fb9c6f8 tests: Do not trace sshd
OpenSSH's sshd does not work well under valgrind so lets avoid tracing it.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 15:43:00 +02:00
Andreas Schneider
91800eb243 cmake: Move CompilerFlags to own file
They need to be included before the project() call.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 15:28:29 +02:00
Andreas Schneider
2923ad59f9 cmake: Update defaults
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 15:21:34 +02:00
Jakub Jelen
556ad59a5a tests: Verify the Match keyword from configuration file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Jakub Jelen
fcb203cb2d tests: No need to restore log level now
Since the verbosity is now set from the setup phase, we do not
need to reset the verbosity, especially not to any arbirary value
such as WARNING.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Jakub Jelen
6dbcc21921 tests: Use global verbosity in tests
This allows adjusting the log level of config and options tests using
environment variable LIBSSH_VERBOSITY as it works in most of the other
tests.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Jakub Jelen
2eccd04ff6 tests: Missing unlink
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Jakub Jelen
e9b44d26b1 config: Parse Match keyword
Amends f818e63f8, which introduced the constants and matching of this
configuration option, but did not implement the handling of the values
which was causing the configuration parser failing for certain
configurations.

This commit exposes match_pattern_list() from match.c

Red Hat Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=1624425

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Jakub Jelen
9f5f10552b config: Do not overwrite previously matched result in Host blocks
The match_hostname() expects comma separated list, while the Host
config keyword in openssh uses spaces separated list by default.
Therefore any subseqent match or negated match in space separated
list will overwrite the previous matches.

This also adjusts the tests to make sure both of the versions work.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Andreas Schneider
458bda8877 tests: Define LIBSSH_STATIC for torture_cmocka
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Andreas Schneider
3d35250c07 tests: Fix linking unit tests
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Andreas Schneider
ef06ef2c1b channels: Allow infinite timeout for ssh_channel_read_timout()
This is also documented.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-05 11:43:05 +02:00
Andreas Schneider
ba1ff992ce libsshpp: Initialize the string returned by getIssueBanner()
Fixes T13

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-04 20:52:31 +02:00
Andreas Schneider
e558827c4e channels: Don't read from a closed channel
Fixes T76

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-04 20:34:52 +02:00
Andreas Schneider
1e195a232a auth: Use calloc to allocate memory
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:59:07 +02:00
Andreas Schneider
d1cd914012 misc: Use C99 initializer to initialize string
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:59:01 +02:00
Andreas Schneider
c3980d433a pki_container: Use string functions for cleanup
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:47 +02:00
Andreas Schneider
78498ee289 packet: Use C99 initializer to reset session->in_packet
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:38 +02:00
Andreas Schneider
76f5a60a82 packet: Reformat ssh_packet_parse_type()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:30 +02:00
Andreas Schneider
07986731c6 gzip: Use calloc in initcompress() and initdecompress()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:23 +02:00
Andreas Schneider
f1608778be kex: Use C99 initializer instead of memset
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:17 +02:00
Andreas Schneider
72e91d5131 channels: Remove memset in ssh_channel_do_free()
We have nice tools to detect that in the meantime.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:11 +02:00
Andreas Schneider
4af4b59e21 channels: Reformat ssh_channel_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:58:03 +02:00
Andreas Schneider
ca464ca2ba channels: Use calloc() in ssh_channel_new()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:58 +02:00
Andreas Schneider
9ac6ac6c26 channel: Reformat ssh_channel_new()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:53 +02:00
Andreas Schneider
b6b5a61c97 pki_mbedcrypto: Use explicit_bzero()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:48 +02:00
Andreas Schneider
1acb82e38a pki_crypto: Use explicit_bzero()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:43 +02:00
Andreas Schneider
a6d59811bb getpass: Use explicit_bzero()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:31 +02:00
Andreas Schneider
d4a443d56c getpass: Use calloc to allocate memory
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:22 +02:00
Andreas Schneider
62bff4aff1 wrapper: Use explicit_bzero() in crypto_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:16 +02:00
Andreas Schneider
f8e68b92b8 wrapper: Fix size type
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:12 +02:00
Andreas Schneider
9c5d2d4543 wrapper: Reformat crypto_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 19:57:06 +02:00
Andreas Schneider
7867126aa6 tests: Add a test for sftp_canonicalize_path()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-04 18:13:37 +02:00
Andreas Schneider
4774d2b9f7 sftp: Fix segfault in sftp_canonicalize_path()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-04 17:30:18 +02:00
Andreas Schneider
f48dcb26e3 string: Don't allow to allocate strings bigger than 256M
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 12:29:20 +02:00
Andreas Schneider
d1f23cd6d8 string: Reformat ssh_string_new()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2018-09-04 12:29:09 +02:00
Andreas Schneider
e601dbd8e3 sftp: Use ssh_buffer_pack() in sftp_fstat()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
f3ffd8aa41 sftp: Reformat sftp_lstat()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
4d98b1cd7e sftp: Use ssh_buffer_pack() in sftp_xstat()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
b00a0578f9 sftp: Reformat sftp_xstat()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
336c097ae7 sftp: Use ssh_buffer_unpack() in sftp_canonicalize_path()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
1dd8466f66 sftp: Use ssh_buffer_pack() in sftp_canonicalize_path()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
8b19ef05f3 sftp: Reformat sftp_canonicalize_path()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
7e11e41a9f sftp: Use sftp_buffer_pack() in sftp_fstatvfs()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
5914ea7c75 sftp: Reformat sftp_fstatvfs()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
f1e84d5e67 sftp: Use ssh_buffer_pack() in sftp_fsync()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
8e3dd09e11 sftp: Use ssh_buffer_pack() in sftp_statvfs()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
ae0afec98d sftp: Reformat sftp_statvfs()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
0be43c333e sftp: Use ssh_buffer_unpack() in sftp_readlink()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
83a5d3b258 sftp: Use ssh_buffer_pack() in sftp_readlink()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:23 +02:00
Andreas Schneider
bb4bdec184 sftp: Reformat sftp_readlink()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:39:16 +02:00
Andreas Schneider
e0449ba21f sftp: Use ssh_buffer_pack() in sftp_setstat()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:37:24 +02:00
Andreas Schneider
8a56b90c3e sftp: Reformat sftp_setstat()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:36:29 +02:00
Andreas Schneider
218c67a51d sftp: Use ssh_buffer_pack() in sftp_mkdir()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:36:29 +02:00
Andreas Schneider
89c525bbf1 sftp: Reformat sftp_mkdir()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:36:29 +02:00
Andreas Schneider
2c0baef7d4 sftp: Use ssh_buffer_pack in sftp_open()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:34:00 +02:00
Andreas Schneider
bfb6718b50 sftp: Reformat sftp_open()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:34:00 +02:00
Andreas Schneider
d99c066a0b sftp: Use ssh_buffer_pack() in sftp_handle_close()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:34:00 +02:00
Andreas Schneider
2844942c1b sftp: Reformat sftp_handle_close()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:34:00 +02:00
Andreas Schneider
3a729829fd sftp: Use ssh_buffer_pack() in sftp_readdir()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:34:00 +02:00
Andreas Schneider
576fdbe1e8 sftp: Reformat sftp_readdir()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:32:45 +02:00
Andreas Schneider
87df9cfc5d sftp: Use ssh_buffer_pack() in sftp_opendir()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:32:23 +02:00
Andreas Schneider
ea375d1605 sftp: Reformat sftp_opendir()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:32:23 +02:00
Andreas Schneider
c15bd2831f buffer: Precalculate the size required for ssh_buffer_pack()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:32:12 +02:00
Andreas Schneider
efef877356 buffer: Only reduce the buffer size if it gets bigger than 64K
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:29:15 +02:00
Andreas Schneider
254a0f7132 buffer: Only allow to allocate a maximum of 256MB
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:27:32 +02:00
Andreas Schneider
d2131b286f buffer: Always preallocate a buffer with 64 bytes
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:26:36 +02:00
Andreas Schneider
c1c32bda14 buffer: Rewrite ssh_buffer_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 18:19:58 +02:00
Andreas Schneider
a1b57d3b94 buffer: Use bool for secure buffer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 15:00:53 +02:00
Andreas Schneider
be703974e9 buffer: Reformat buffer_shift()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 15:00:53 +02:00
Andreas Schneider
29f36791c9 buffer: Cleanup buffer_verify
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 15:00:53 +02:00
Andreas Schneider
492e3d5c77 cmake: Store Profiling and AddressSanitizer flags in the cache
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 15:00:53 +02:00
Andreas Schneider
9a3f43f4ee cmake: Add -fstack-clash-protection
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-03 14:18:25 +02:00
Andreas Schneider
baa434ebed cmake: Small improvements to AddCMockaTest
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-02 11:25:43 +02:00
Andreas Schneider
f99e6766d6 auth: Fix freeing memory in ssh_userauth_agent_publickey()
CID 1395453

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-02 10:01:47 +02:00
Andreas Schneider
3efc64112a include: Add SSH_STRING_FREE() and SSH_STRING_FREE_CHAR()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-02 09:54:20 +02:00
Andreas Schneider
bc19f892eb gitlab-ci: Correctly run AddressSanitizer with cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 21:26:48 +02:00
Andreas Schneider
f8fc0b9dfb messages: Fix memory leak in ssh_packet_userauth_request
Found by AddressSanitizer.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 21:26:37 +02:00
Andreas Schneider
1b12a2415d gitlab-ci: Enable address sanitzer build
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 10:21:06 +02:00
Andreas Schneider
1c0ac0b12e tests: Fix memory leaks in torture_hashes
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 10:16:56 +02:00
Andreas Schneider
ea2b403ab2 auth: Fix a memory leak in ssh_userauth_agent_publickey()
CID 1230358

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 09:41:11 +02:00
Andreas Schneider
8323cd791f pki: Fix a memory leak in ssh_pki_do_sign()
CID 1395335

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 09:41:11 +02:00
Andreas Schneider
461ebd1e2f packet: Add a bound check for nr_extensions
CID 1395335

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-09-01 09:40:44 +02:00
Andreas Schneider
be147e897d doc: Update Public Key Algorithms
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 15:04:37 +02:00
Andreas Schneider
1d329236b3 gitlab-ci: Move tumbleweed to the end of the file
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Andreas Schneider
0c6544adcb gitlab-ci: Only run static-analysis on tumbleweed
Tumbleweed offers a newer clang version and we don't really have to
waste resources.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Andreas Schneider
09a1d95b69 gitlab-ci: Add a clang build on tumbleweed
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
6b10bbea2f tests: Properly initilize library in threads tests
This was already done in the torture_threads_pki.

Without the explicit initialization, we can observe random
failures tests (at least of the torture_threads_crypto) from
various threads.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
b4c8bd9fe4 pki: Support RSA SHA2 signatures of sessionid for server
This involves mostly creation of host keys proofs but needs
to follow the same procedure as the client authentication
signatures.

At the same time, the SHA2 extension is enabled in the pkd
so we are able to atomicaly provide correct signatures and
pass tests.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
5d13006650 server: We should list SHA2 variants in offered hostkeys
The SHA2 variants should be preferred. Also the buffer needs to be
extended to fit all possible public key algorithms.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
6fa5e8adb0 server: Support for extension negotiation
This includes intercepting the  ext-info-c  string from
the client kex proposal, configuring the server to allow using
this extension and sending the SSH_MSG_EXT_INFO packet back
to the client after the new keys are in use.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
60ad7ee15d messages: Create correct digest for pki signatures
This does not affect old signatures, where the public key algorithm
matches the public key type.

This is a problem when using SHA2 extension for the RSA keys, where
the new signature algorithsm are introduced in addition to the
exitsing ssh-rsa which was ignored throughout the code.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
5fe81e89fb tests: Verify the public key algorithms can be limited by configuration option
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES configuration option can limit
what keys can or can not be used for public key authentication.

This is useful for disabling obsolete algorithms while not completely
removing the support for them or allows to configure what public key
algorithms will be used with the SHA2 RSA extension.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
09cf301eee auth: Prevent authentication with non-allowed key algorithms
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
594c62d718 tests: PUBLICKEY_ACCEPTED_TYPES are effective
Verify the PUBLICKEY_ACCEPTED_TYPES option is handled correctly
and affects the signature algorithm selection based on the
extensions and can be used to limit list of offered mechanisms
to the server.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
4169be45eb pki: Allow filtering accepted public key types based on the configuration
This effectively allows to disable using the SHA2 extension, disable
other old public key mechanisms out of the box (hello DSA) or force
the new SHA2-based key algorithm types if needed.

This exposes the  default_methods  array from  kex.c.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
5d53f519bc tests: Cover PubkeyAcceptedTypes configuration option
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
37864b6575 config: Accept the PubkeyAcceptedTypes configuration option
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
4521ab73b6 options: The new option SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES
This option allows to specify acceptable public key algorithms
and reflects the PubkeyAcceptedTypes configuration option from
OpenSSH.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
9ca6127b91 kex: The public key algorithms are no longer only host keys
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
ebb01549d0 SHA2 extension in the ssh-agent interface
The new constants for flags are defined in draft-miller-ssh-agent-02
are active if the SHA2 extension is negotiated with the server.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
945469c9e0 tests: SHA2 extension signatures
This introduces a new test case for RSA unit tests, verifying that
libraries are able to provide and verify the RSA signatures with
SHA2 hash algorithms.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
82da0c3361 auth: Support SHA2 extension for pubkey authentication (RFC 8332)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
1f08aabe43 pki: RSA signatures with SHA2 hash algorithms (RFC 8332)
* This change introduces a new API to request signature using
   one key and different hash algorithms. This is used only with
   RSA keys, that used to have SHA1 hardcoded, but the new
   algorithsms allow to use the SHA2 hashes, if the extension
   is negotiated.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
3ca7e1eea9 kex: Offer SHA2 extension signature algorithms by default
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
fa60827840 pki: Support RSA verification using different hash algorithms
This changes the private API by adding one more argument to function

  pki_signature_from_blob()

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
761225712a client: Handle the MSG_EXT_INFO packet signalling supported extensions
RFC 8308: The extension negotiation in Secure Shell (SSH) Protocol

RFC 8332: Use of RSA Keys with SHA-256 and SHA-512
          in the Secure Shell (SSH) Protocol

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
df13d8c61f kex: Signalize support for the extension negotiation in client (RFC 8308)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
cbccae795d pkd: Produce more useful logs
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Jakub Jelen
100c9c98ce pkd: Generate host keys in old format
This is required to work against OpenSSH 7.8, which is now
writing keys in new openssh format by default

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Andreas Schneider
d7a64b9519 tests: Ignore SIGPIPE in pkd
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Andreas Schneider
fc212d73ed cmake: Use -fstack-protector-strong if possible
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 14:18:34 +02:00
Andreas Schneider
2b05e46b62 examples: Reformat ssh_client
The example should be clean code if possible.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 10:21:06 +02:00
Andreas Schneider
8d8b64cc3f doc: Update that_style
We don't need the source css files.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-31 08:04:24 +02:00
Andreas Schneider
11d87238b8 poll: Fix size types in ssh_event_free()
src/poll.c:1024:9: error: assuming signed overflow does not occur when
    simplifying conditional to constant [-Werror=strict-overflow]

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-30 08:52:42 +02:00
Andreas Schneider
8243030c55 poll: Reformat ssh_event_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-30 08:51:33 +02:00
Andreas Schneider
111d06eac5 cmake: Set version to 0.8.90
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-30 08:21:25 +02:00
Andreas Schneider
20ca6e09dd cmake: VERSION_GREATER_EQUAL is not suppored by cmake 3.3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-30 07:34:16 +02:00
Andreas Schneider
66a0f14a0c cmake: Only support building docs the on cmake >= 3.9
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 21:51:42 +02:00
Andreas Schneider
aba6e34b63 cmake: Fix SSP compiler flag check
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 21:21:17 +02:00
Andreas Schneider
4fcc0bd407 Bump library version to 4.6.0
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Andreas Schneider
7960b8ed1b cmake: Fix final map generation
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Anderson Toshiyuki Sasaki
2aeee5194c cmake: Fix target to make sure copy runs in the end
The target created to copy the file must be the one make dist is
depending on.  Otherwise it will not copy the generated files to the
desired path.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Anderson Toshiyuki Sasaki
ca925588b0 cmake: Fix extract_symbols COPY_TO
Moved the symbols list formatting to the ExtractSymbols.cmake.  The
resulting list of symbols is sorted and printed in a more readable way
(one symbol per line).  Fixed the script to copy the generated symbols.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Andreas Schneider
5b07c1aa2c examples: Use ssh_print_hash()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Jan-Niklas Burfeind
9510a538c2 tests: Add torture_hashes for pubkey hashes
Signed-off-by: Jan-Niklas Burfeind <libssh@aiyionpri.me>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Jan-Niklas Burfeind
f32cb70675 dh: Add ssh_print_hash() function which can deal with sha256
Signed-off-by: Jan-Niklas Burfeind <libssh@aiyionpri.me>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Jan-Niklas Burfeind
1499b38aef dh: Add SSH_PUBLICKEY_HASH_SHA256 to ssh_get_publickey_hash()
Signed-off-by: Jan-Niklas Burfeind <libssh@aiyionpri.me>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Andreas Schneider
509331ec81 sftp: Use strndup()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Andreas Schneider
247983e982 misc: Add strndup implementation if not provides by the OS
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 19:04:44 +02:00
Andreas Schneider
f0e99961b6 cmake: Require at least abimap-0.3.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 18:08:59 +02:00
Andreas Schneider
2291c75ab0 cmake: Detect abimap version
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 18:08:59 +02:00
Andreas Schneider
77b4801e11 cmake: Fix typo in doc file
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 18:08:59 +02:00
Andreas Schneider
a3c8dac6b6 tests: Fix size types in pkd
tests/pkd/pkd_hello.c:743:12: error: assuming signed overflow does not
    occur when simplifying conditional to constant [-Werror=strict-overflow]

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 11:07:08 +02:00
Andreas Schneider
5334cb9d55 doc: Update doxygen documentation
This fixes some issues with the new docs and uses a new modern style.

https://github.com/jl-wynen/that_style

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 11:05:47 +02:00
Andreas Schneider
9a73fa885a doc: Remove obsolete Doxyfile.in
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-29 11:05:47 +02:00
Alex Hermann
23f60a56f3 misc: Set default port to 22 in ssh_path_expand_escape()
Fixes, among others, ProxyCommand with %p when no port is used on
commandline or config file, thus using the default port.

Fixes T94

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-28 15:44:37 +02:00
Andreas Schneider
648f5cf400 cmake: Fix doxygen generation
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 16:46:01 +02:00
Anderson Toshiyuki Sasaki
f49bb1b6a3 cmake: Fix FindABIMap targets
Fix the targets and output files handling to make the symbols to be
updated correctly when a symbol is added or removed.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 14:42:56 +02:00
Jakub Jelen
f0a4c1e888 doc: There is no hostbased authentication implemented
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 11:29:20 +02:00
Andreas Schneider
a0fec81221 auth: Reset errors on successful authentication
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 11:29:20 +02:00
Andreas Schneider
0aad4de5f4 error: Add ssh_reset_error() function
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 11:29:18 +02:00
Andreas Schneider
280519af29 auth: Also log the current auth method
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 11:25:29 +02:00
Andreas Schneider
0ae376f133 auth: Fix the pending_call_state of ssh_userauth_password()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 11:25:08 +02:00
Andreas Schneider
73c9d60e5a session: Group auth variables in a struct
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 09:30:24 +02:00
Jakub Jelen
ae3825dfb2 sftp: Avoid race condition reading incomplete data messages
This changes amends f561e6bcb3 which
introduces same check in one place, but miss it in other two places.

We encountered this issue with qemu using SFTP to transfer large
data chunks and in some cases, the file transfer was interrupted
without any reason. From the debug messages, it showed up that
last part of data message/packet was not handled in the time
of the sftp_read() call, therefore the ssh_channel_read() returned
zero (there was no more data to read yet), which made the whole
transfer fail hard instead of retrying later.

The proposed change is reusing the code from previously referenced
commit also in the other places.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 09:29:24 +02:00
Andreas Schneider
8f1e995cec auth: Fix possible NULL pointer dereference
explicit_bzero() doesn't handle NULL.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 09:29:24 +02:00
Andreas Schneider
4de8ed684b cmake: Check if the linker supports version scripts
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-27 09:29:24 +02:00
Anderson Toshiyuki Sasaki
d0f3cdfa10 docs: Update threading documentation
Updated threading documentation mentioning changes in the requirements
to use libssh in multithread scenarios.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-24 14:58:52 +02:00
Andreas Schneider
a97e227a9d cmake: Improve compiler flag detection
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-24 07:51:00 +02:00
Andreas Schneider
119a457357 options: Fix size types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-24 07:31:39 +02:00
Andreas Schneider
4ae7e35d9c cmake: Allow zero for variadic macro argument
This is also needed for clang.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-23 22:33:29 +02:00
Andreas Schneider
47bf099c36 cmake: Add header to AddCCompilerFlag.cmake 2018-08-23 22:33:29 +02:00
Andreas Schneider
9a43298b3a options: Fix integer types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-23 22:33:29 +02:00
Andreas Schneider
3f17154367 options: Reformat ssh_options_getopt()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-23 22:33:29 +02:00
Andreas Schneider
f8435e261c cmake: Disable include_guard as oss-fuzz's cmake version is too old
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 12:12:06 +02:00
Andreas Schneider
6162b63d5e gitlab-ci: Add target to build the docs
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
19e081aedb cmake: Remove obsolete UseDoxygen.cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
a154bd9f22 cmake: Use FindDoxygen package provided by cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
e618298bda doc: Update Doxyfile.in
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
7e1b67754c knownhosts: Add knownhosts to libssh_session group
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
868623f9a8 libssh: Document ssh_known_hosts_e
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
49f92cf5cd libsshpp: Match documentation with the code
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
c2fc9ac956 channels: Fix timeout variable to match documentation
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 09:08:39 +02:00
Andreas Schneider
15473426c8 tests: Temporarily increase log verbosity for torture_forward
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:55:21 +02:00
Andreas Schneider
9820a35a9e cmake: Remove obsolete DefineCompilerFlags.cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:54:59 +02:00
Andreas Schneider
5e9435924c cmake: Set -D_FORTIFY_SOURCE=2 if possible
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:54:59 +02:00
Andreas Schneider
64a354159f gssapi: Fix size types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:54:59 +02:00
Andreas Schneider
0a46690eca options: Fix size types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:51:00 +02:00
Andreas Schneider
26263aabd4 kex: Fix size types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:51:00 +02:00
Andreas Schneider
6867a35004 tests: Check return code of setuid()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-22 08:35:19 +02:00
Andreas Schneider
7946104566 known_hosts: Update documentation of deprecated knwon_hosts functions
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-21 11:39:50 +02:00
Andreas Schneider
140ddf5109 gitlab-ci: Add two builds with optimizations turned on
This enables the optimizer and will give use additional compiler
warnings and errors.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
887908107a gitlab-ci: Enable PICKY_DEVELOPER
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
8855a140cf cmake: Add support for picky developer flags
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
a9a99fb31f cmake: Improve compiler flag detection
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
26a4097742 cmake: Check for -Werror in ConfigureChecks.cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
99a9cf0fcb cmake: Respect CMAKE_REQUIRED_* variables in CHECK_C_COMPILER_FLAG_SSP
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
fd157befae tests: Make sure pointer are initialized in torture_pki_ed25519
Fixes compiler warnings.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
6f6840a88a tests: Make sure pointer are initialized in torture_pki_ecdsa
Fixes compiler warnings.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
562e579675 tests: Make sure pointer are initialized in torture_pki_dsa
Fixes compiler warnings.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
1e89896d05 tests: Make sure pointer are initialized in torture_pki_rsa
Fixes compiler warnings.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
3b896750b8 tests: Use ZERO_STRUCT for readfds
This fixes a compiler warning on FreeBSD.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
f433949dcd tests: Fix function declaration in pkd_hello
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
8e418ea020 tests: Fix function declaration in torture_packet
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
6766b0a860 log: Make sure the buffer for date is big enough
src/log.c:71:32: error: '%06ld' directive output may be truncated
writing between 6 and 20 bytes into a region of size between 0 and 63
[-Werror=format-truncation=]
         snprintf(buf, len, "%s.%06ld", tbuf, (long)tv.tv_usec);

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
ce45de9ea2 agent: Fix type of the buffer
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
85d2c0371a mbedtls: Use getter for ssh_mbedtls_ctr_drbg
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
1d9f548204 examples: Fix function declaration in sshnetcat
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Andreas Schneider
dad456a1ee include: Fix shadow variables in libsshpp
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-20 18:42:03 +02:00
Jakub Jelen
a0214dfc9a sftp: Fix the debug message in sftp_enqueue()
This fixes the assignment of variables to comments and makes
the output symmetric with sftp_dequeue().

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-18 10:00:37 +02:00
Jakub Jelen
c004b43fde tests: Unsupported and unknown configuration options do not crash
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2018-08-16 17:51:05 +02:00
Jakub Jelen
6848c23d84 config: Do not access negative indexes of seen array
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2018-08-16 17:51:05 +02:00
Andreas Schneider
4104d2fb91 cmake: Correctly detect support for __bounded__ attribute
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-16 17:45:56 +02:00
Andreas Schneider
86d00f438c init: Fix DllMain
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-16 09:19:58 +02:00
Andreas Schneider
f65882cca6 cmake: Fix optional ABIMap detection
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-08-14 15:54:55 +02:00
Andreas Schneider
a3475c2e4b cmake: Bump library version for release 2018-08-13 22:18:41 +02:00
Andreas Schneider
4d87256ca7 init: Add a library constructor and destructor for VC
If we compile with Visual Studio, we need a DllMain() for running init
and finialize which is the same as a constructor and destructor.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 21:48:48 +02:00
Andreas Schneider
6aa9392699 cmake: Only set -Werror on UNIX
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 21:48:48 +02:00
Andreas Schneider
0656f8a43d cmake: Improve NSIS detection on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 21:48:48 +02:00
Anderson Toshiyuki Sasaki
66a3bc0332 init: ignore init counter if destructor calls finalize
If the destructor calls finalize, ignore the init counter and finalize
the library anyway.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 15:27:36 +02:00
Andreas Schneider
dbce0e5228 cmake: Fix PACKAGE and VERSION in config.h
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 13:44:58 +02:00
Andreas Schneider
8ef35a005c cmake: Fix pkg-config file
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 13:44:58 +02:00
Andreas Schneider
8425dce7b2 cmake: Remove obsolete libssh_threads.pc.cmake
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 13:44:58 +02:00
Anderson Toshiyuki Sasaki
0be1ae0e3b threads: use static error check mutex initializer if available
This changes the condition to use the static error check mutex
initializer.  If it is not available, use the default static mutex
initializer.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 12:00:13 +02:00
Andreas Schneider
83898f3f6c cmake: Only install static lib if built WITH_STATIC_LIB
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 10:27:17 +02:00
Andreas Schneider
a33e71ae88 include: Bump libssh version
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 09:22:39 +02:00
Andreas Schneider
f2b6899298 init: Only use constructor attribute if available
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 09:21:39 +02:00
Andreas Schneider
4c058aefd9 cmake: Detect constructor and destructor attributes
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 09:21:17 +02:00
Andreas Schneider
8c2ad7bdd3 cmake: Fix fallthrough attribute detection
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 09:15:35 +02:00
Andreas Schneider
e04a8b3abd cmake: Fix check for bounded attribute
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 09:14:15 +02:00
Andreas Schneider
15ab612592 cmake: Set the PACKAGE_VERSION correctly
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-13 08:47:39 +02:00
Andreas Schneider
4f0f1a9160 cpack: Fix ignore files
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-08-10 14:18:18 +02:00
206 changed files with 19078 additions and 7293 deletions

View File

@@ -7,12 +7,15 @@ variables:
DEBIAN_CROSS_BUILD: buildenv-debian-cross DEBIAN_CROSS_BUILD: buildenv-debian-cross
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON # torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
centos7/openssl_1.0.x/x86-64: centos7/openssl_1.0.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
script: script:
- mkdir -p obj && cd obj && cmake3 -DUNIT_TESTING=ON -DCMAKE_BUILD_TYPE=Debug - mkdir -p obj && cd obj && cmake3
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DWITH_PCAP=ON .. && make -j$(nproc) && ctest --output-on-failure -DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags: tags:
- shared - shared
except: except:
@@ -23,11 +26,13 @@ centos7/openssl_1.0.x/x86-64:
paths: paths:
- obj/ - obj/
fedora/openssl_1.1.x/x86-64: fedora/openssl_1.1.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script: script:
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug - mkdir -p obj && cd obj && cmake
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. && -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure make -j$(nproc) && ctest --output-on-failure
tags: tags:
@@ -41,14 +46,16 @@ fedora/openssl_1.1.x/x86-64:
- obj/ - obj/
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite # Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
.fedora/address-sanitizer: # so, this is only enabled for unit tests right now.
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
fedora/address-sanitizer:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script: script:
- mkdir -p obj && cd obj && cmake - mkdir -p obj && cd obj && cmake
-DCMAKE_C_FLAGS="-O2 -g -fsanitize=address" -DCMAKE_BUILD_TYPE=AddressSanitizer
-DCMAKE_LINK_FLAGS="-fsanitize=address -static-libasan" -DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. && -DUNIT_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure make -j$(nproc) && ctest --output-on-failure
tags: tags:
- shared - shared
@@ -65,7 +72,7 @@ fedora/undefined-sanitizer:
script: script:
- mkdir -p obj && cd obj && cmake - mkdir -p obj && cd obj && cmake
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" -DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
&& make -j$(nproc) && ctest --output-on-failure && make -j$(nproc) && ctest --output-on-failure
tags: tags:
@@ -78,16 +85,27 @@ fedora/undefined-sanitizer:
paths: paths:
- obj/ - obj/
fedora/static-analysis: fedora/csbuild:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script: script:
- export CCC_CC=clang - |
- export CCC_CXX=clang++ if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON fi
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. && # Check if the commit exists in this branch
scan-build --status-bugs -o scan make -j$(nproc) # This is not the case for a force push
git branch --contains $CI_COMMIT_BEFORE_SHA 2>/dev/null || export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
export CI_COMMIT_RANGE="$CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA"
- csbuild
--build-dir=obj-csbuild
--prep-cmd="cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON @SRCDIR@"
--build-cmd "make clean && make -j$(nproc)"
--git-commit-range $CI_COMMIT_RANGE
--color
--print-current --print-fixed
tags: tags:
- shared - shared
except: except:
@@ -96,15 +114,17 @@ fedora/static-analysis:
expire_in: 1 week expire_in: 1 week
when: on_failure when: on_failure
paths: paths:
- obj/scan - obj-csbuild/
# That is a specific runner that we cannot enable universally. # That is a specific runner that we cannot enable universally.
# We restrict it to builds under the $BUILD_IMAGES_PROJECT project. # We restrict it to builds under the $BUILD_IMAGES_PROJECT project.
freebsd/x86-64: freebsd/x86_64:
image: image:
script: script:
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug - mkdir -p obj && cd obj && cmake
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. && -DUNIT_TESTING=ON .. &&
make && ctest --output-on-failure make && ctest --output-on-failure
tags: tags:
@@ -120,11 +140,13 @@ freebsd/x86-64:
paths: paths:
- obj/ - obj/
fedora/libgcrypt/x86-64: fedora/libgcrypt/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script: script:
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug - mkdir -p obj && cd obj && cmake
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DWITH_GCRYPT=ON .. && -DWITH_GCRYPT=ON .. &&
make -j$(nproc) && ctest --output-on-failure make -j$(nproc) && ctest --output-on-failure
@@ -138,11 +160,13 @@ fedora/libgcrypt/x86-64:
paths: paths:
- obj/ - obj/
fedora/mbedtls/x86-64: fedora/mbedtls/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script: script:
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug - mkdir -p obj && cd obj && cmake
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DWITH_MBEDTLS=ON .. && -DWITH_MBEDTLS=ON .. &&
make -j$(nproc) && ctest --output-on-failure make -j$(nproc) && ctest --output-on-failure
@@ -156,92 +180,20 @@ fedora/mbedtls/x86-64:
paths: paths:
- obj/ - obj/
tumbleweed/openssl_1.1.x/x86-64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/openssl_1.1.x/x86:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/undefined-sanitizer:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
&& make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/static-analysis:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- export CCC_CC=clang
- export CCC_CXX=clang++
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
scan-build --status-bugs -o scan make -j$(nproc)
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/scan
# Unit testing only, no client and pkd testing, because cwrap is not available # Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW # for MinGW
mingw64: fedora/mingw64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
script: script:
- Xvfb :1 -screen 0 1024x768x16 -ac +extension GLX +render -noreset -nolisten tcp &
- export DISPLAY=:1
- mkdir -p obj && cd obj && mingw64-cmake -DCMAKE_BUILD_TYPE=Debug
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc)
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin - export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
- ctest --output-on-failure - export WINEDEBUG=-all
- mkdir -p obj && cd obj && mingw64-cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure
tags: tags:
- shared - shared
except: except:
@@ -254,17 +206,18 @@ mingw64:
# Unit testing only, no client and pkd testing, because cwrap is not available # Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW # for MinGW
mingw32: fedora/mingw32:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
script: script:
- Xvfb :1 -screen 0 1024x768x16 -ac +extension GLX +render -noreset -nolisten tcp &
- export DISPLAY=:1
- mkdir -p obj && cd obj && mingw32-cmake -DCMAKE_BUILD_TYPE=Debug
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc)
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin - export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
- ctest --output-on-failure - export WINEDEBUG=-all
- mkdir -p obj && cd obj && mingw32-cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure
tags: tags:
- shared - shared
except: except:
@@ -284,10 +237,11 @@ mingw32:
- mkdir -p obj && cd obj && cmake - mkdir -p obj && cd obj && cmake
-DCMAKE_C_COMPILER="$(which $host-gcc)" -DCMAKE_C_COMPILER="$(which $host-gcc)"
-DCMAKE_CXX_COMPILER="$(which $host-g++)" -DCMAKE_CXX_COMPILER="$(which $host-g++)"
-DCMAKE_BUILD_TYPE=Debug -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
-DWITH_PCAP=ON .. && make -j$(nproc) -DWITH_PCAP=ON .. &&
- ctest --output-on-failure -j$(nproc) make -j$(nproc) &&
ctest --output-on-failure
tags: tags:
- shared - shared
except: except:
@@ -300,3 +254,214 @@ mingw32:
Debian.cross.mips-linux-gnu: Debian.cross.mips-linux-gnu:
<<: *Debian_cross_template <<: *Debian_cross_template
tumbleweed/openssl_1.1.x/x86_64/gcc:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/openssl_1.1.x/x86/gcc:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/openssl_1.1.x/x86_64/gcc7:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/openssl_1.1.x/x86/gcc7:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/openssl_1.1.x/x86_64/clang:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/docs:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake .. && make docs
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/undefined-sanitizer:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
tumbleweed/static-analysis:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
- export CCC_CC=clang
- export CCC_CXX=clang++
- mkdir -p obj && cd obj && scan-build cmake
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
scan-build --status-bugs -o scan make -j$(nproc)
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/scan
visualstudio/x86_64:
script:
- $env:VCPKG_DEFAULT_TRIPLET="x64-windows"
- cd obj
- cmake
-A x64
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON ..
- cmake --build .
- ctest --output-on-failure
tags:
- vs2017
- windows
except:
- tags
only:
- branches@libssh/libssh-mirror
- branches@ansasaki/libssh-mirror
- branches@cryptomilk/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
visualstudio/x86:
script:
- $env:VCPKG_DEFAULT_TRIPLET="x86-windows"
- cd obj
- cmake
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON ..
- cmake --build .
- ctest --output-on-failure
tags:
- vs2017
- windows
except:
- tags
only:
- branches@libssh/libssh-mirror
- branches@ansasaki/libssh-mirror
- branches@cryptomilk/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/

View File

@@ -1,7 +1,16 @@
cmake_minimum_required(VERSION 3.2.0) cmake_minimum_required(VERSION 3.3.0)
cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0048 NEW)
project(libssh VERSION 0.8.0 LANGUAGES C) # Specify search path for CMake modules to be loaded by include()
# and find_package()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
# Add defaults for cmake
# Those need to be set before the project() call.
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.8.90 LANGUAGES C)
# global needed variable # global needed variable
set(APPLICATION_NAME ${PROJECT_NAME}) set(APPLICATION_NAME ${PROJECT_NAME})
@@ -13,26 +22,26 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0 # Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes: # If the source code was changed, but there were no interface changes:
# Increment REVISION. # Increment REVISION.
set(LIBRARY_VERSION "4.5.0") set(LIBRARY_VERSION "4.7.2")
set(LIBRARY_SOVERSION "4") set(LIBRARY_SOVERSION "4")
# 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
set(CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules
)
# add definitions # add definitions
include(DefineCMakeDefaults)
include(DefinePlatformDefaults) include(DefinePlatformDefaults)
include(DefineCompilerFlags)
include(DefineInstallationPaths) include(DefineInstallationPaths)
include(DefineOptions.cmake) include(DefineOptions.cmake)
include(CPackConfig.cmake) include(CPackConfig.cmake)
include(CompilerChecks.cmake)
# disallow in-source build # disallow in-source build
include(MacroEnsureOutOfSourceBuild) include(MacroEnsureOutOfSourceBuild)
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
# Copy library files to a lib sub-directory
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# search for libraries # search for libraries
if (WITH_ZLIB) if (WITH_ZLIB)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
@@ -61,6 +70,10 @@ else (WITH_GCRYPT)
endif (NOT OPENSSL_FOUND) endif (NOT OPENSSL_FOUND)
endif(WITH_GCRYPT) endif(WITH_GCRYPT)
if (UNIT_TESTING)
find_package(CMocka REQUIRED)
endif ()
# Find out if we have threading available # Find out if we have threading available
set(CMAKE_THREAD_PREFER_PTHREADS ON) set(CMAKE_THREAD_PREFER_PTHREADS ON)
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
@@ -83,7 +96,7 @@ endif (BSD OR SOLARIS OR OSX)
# Disable symbol versioning in non UNIX platforms # Disable symbol versioning in non UNIX platforms
if (UNIX) if (UNIX)
find_package(ABIMap) find_package(ABIMap 0.3.1)
else (UNIX) else (UNIX)
set(WITH_SYMBOL_VERSIONING OFF) set(WITH_SYMBOL_VERSIONING OFF)
endif (UNIX) endif (UNIX)
@@ -110,11 +123,22 @@ install(
) )
endif (UNIX) endif (UNIX)
# cmake config files # CMake config files
include(CMakePackageConfigHelpers)
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX}) set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY) # libssh-config-version.cmake
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY) write_basic_package_version_file(libssh-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
# libssh-config.cmake
configure_package_config_file(${PROJECT_NAME}-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
install( install(
FILES FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
@@ -125,18 +149,13 @@ install(
devel devel
) )
# in tree build settings
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
if (WITH_EXAMPLES) if (WITH_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
endif (WITH_EXAMPLES) endif (WITH_EXAMPLES)
if (UNIT_TESTING) if (UNIT_TESTING)
find_package(CMocka REQUIRED) include(AddCMockaTest)
include(AddCMockaTest) add_subdirectory(tests)
add_subdirectory(tests)
endif (UNIT_TESTING) endif (UNIT_TESTING)
### SOURCE PACKAGE ### SOURCE PACKAGE
@@ -158,13 +177,13 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
message(STATUS "Library version bumped to ${LIBRARY_VERSION}: Updating ABI") message(STATUS "Library version bumped to ${LIBRARY_VERSION}: Updating ABI")
# Get the list of header files # Get the list of header files
get_file_list("${PROJECT_NAME}_header_list" get_file_list(${PROJECT_NAME}_header_list
DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libssh" DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libssh"
FILES_PATTERNS "*.h") FILES_PATTERNS "*.h")
# Extract the symbols marked as "LIBSSH_API" from the header files # Extract the symbols marked as "LIBSSH_API" from the header files
extract_symbols(${PROJECT_NAME}.symbols extract_symbols(${PROJECT_NAME}.symbols
HEADERS_LIST_FILE "${PROJECT_NAME}_header_list" HEADERS_LIST ${PROJECT_NAME}_header_list
FILTER_PATTERN "LIBSSH_API" FILTER_PATTERN "LIBSSH_API"
COPY_TO "${CMAKE_SOURCE_DIR}/src/ABI/${PROJECT_NAME}-${LIBRARY_VERSION}.symbols") COPY_TO "${CMAKE_SOURCE_DIR}/src/ABI/${PROJECT_NAME}-${LIBRARY_VERSION}.symbols")
@@ -180,7 +199,7 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
# Generate the symbol version map file # Generate the symbol version map file
generate_map_file(${_SYMBOL_TARGET} generate_map_file(${_SYMBOL_TARGET}
SYMBOLS "${PROJECT_NAME}.symbols" SYMBOLS ${PROJECT_NAME}.symbols
RELEASE_NAME_VERSION ${PROJECT_NAME}_${LIBRARY_VERSION} RELEASE_NAME_VERSION ${PROJECT_NAME}_${LIBRARY_VERSION}
CURRENT_MAP ${MAP_PATH} CURRENT_MAP ${MAP_PATH}
COPY_TO ${MAP_PATH} COPY_TO ${MAP_PATH}

13
COPYING
View File

@@ -455,6 +455,15 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. DAMAGES.
Linking with OpenSSL Linking with OpenSSL
17. In addition, as a special exception, we give permission to link the code of its release of libssh with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Lesser General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
17. In addition, as a special exception, we give permission to link the code
of its release of libssh with the OpenSSL project's "OpenSSL" library (or with
modified versions of it that use the same license as the "OpenSSL" library),
and distribute the linked executables. You must obey the GNU Lesser General
Public License in all respects for all of the code used other than "OpenSSL".
If you modify this file, you may extend this exception to your version of the
file, but you are not obligated to do so. If you do not wish to do so, delete
this exception statement from your version.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS

View File

@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
# SOURCE GENERATOR # SOURCE GENERATOR
set(CPACK_SOURCE_GENERATOR "TXZ") set(CPACK_SOURCE_GENERATOR "TXZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;build;obj*;tags;cscope.*") set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
### NSIS INSTALLER ### NSIS INSTALLER

120
CompilerChecks.cmake Normal file
View File

@@ -0,0 +1,120 @@
include(AddCCompilerFlag)
include(CheckCCompilerFlagSSP)
if (UNIX)
#
# Check for -Werror turned on if possible
#
# This will prevent that compiler flags are detected incorrectly.
#
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Werror")
if (PICKY_DEVELOPER)
list(APPEND SUPPORTED_COMPILER_FLAGS "-Werror")
endif()
endif()
add_c_compiler_flag("-std=gnu99" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wpedantic" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wall" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wshadow" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wmissing-prototypes" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wcast-align" SUPPORTED_COMPILER_FLAGS)
#add_c_compiler_flag("-Wcast-qual" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=address" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wstrict-prototypes" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=strict-prototypes" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wwrite-strings" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=write-strings" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror-implicit-function-declaration" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wpointer-arith" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=pointer-arith" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wdeclaration-after-statement" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=declaration-after-statement" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wreturn-type" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=return-type" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wuninitialized" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=uninitialized" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wimplicit-fallthrough" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
if (REQUIRED_FLAGS_WFORMAT)
list(APPEND SUPPORTED_COMPILER_FLAGS "-Wformat")
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wformat")
endif()
add_c_compiler_flag("-Wformat-security" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS)
# Allow zero for a variadic macro argument
string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID)
if ("${_C_COMPILER_ID}" STREQUAL "clang")
add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
endif()
add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS)
if (CMAKE_BUILD_TYPE)
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
add_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" SUPPORTED_COMPILER_FLAGS)
endif()
endif()
check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG)
if (WITH_STACK_PROTECTOR_STRONG)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong")
# This is needed as Solaris has a seperate libssp
if (SOLARIS)
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong")
endif()
else (WITH_STACK_PROTECTOR_STRONG)
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
if (WITH_STACK_PROTECTOR)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector")
# This is needed as Solaris has a seperate libssp
if (SOLARIS)
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector")
endif()
endif()
endif (WITH_STACK_PROTECTOR_STRONG)
check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION)
if (WITH_STACK_CLASH_PROTECTION)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection")
endif()
if (PICKY_DEVELOPER)
add_c_compiler_flag("-Wno-error=deprecated-declarations" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS)
endif()
add_c_compiler_flag("-Wno-deprecated-declarations" DEPRECATION_COMPILER_FLAGS)
# Unset CMAKE_REQUIRED_FLAGS
unset(CMAKE_REQUIRED_FLAGS)
endif()
if (MSVC)
add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("/D _CRT_NONSTDC_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("/D _CRT_SECURE_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS)
endif()
# This removes this annoying warning
# "warning: 'BN_CTX_free' is deprecated: first deprecated in OS X 10.7 [-Wdeprecated-declarations]"
if (OSX)
add_c_compiler_flag("-Wno-deprecated-declarations" SUPPORTED_COMPILER_FLAGS)
endif()
set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE)
set(DEFAULT_LINK_FLAGS ${SUPPORTED_LINKER_FLAGS} CACHE INTERNAL "Default C Linker Flags" FORCE)
if (DEPRECATION_COMPILER_FLAGS)
set(DEFAULT_C_NO_DEPRECATION_FLAGS ${DEPRECATION_COMPILER_FLAGS} CACHE INTERNAL "Default no deprecation flags" FORCE)
endif()

View File

@@ -4,11 +4,11 @@ include(CheckSymbolExists)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckLibraryExists) include(CheckLibraryExists)
include(CheckTypeSize) include(CheckTypeSize)
include(CheckCXXSourceCompiles) include(CheckStructHasMember)
include(TestBigEndian) include(TestBigEndian)
set(PACKAGE ${APPLICATION_NAME}) set(PACKAGE ${PROJECT_NAME})
set(VERSION ${APPLICATION_VERSION}) set(VERSION ${PROJECT_VERSION})
set(DATADIR ${DATA_INSTALL_DIR}) set(DATADIR ${DATA_INSTALL_DIR})
set(LIBDIR ${LIB_INSTALL_DIR}) set(LIBDIR ${LIB_INSTALL_DIR})
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}") set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
@@ -64,6 +64,7 @@ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
check_include_file(arpa/inet.h HAVE_ARPA_INET_H) check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(byteswap.h HAVE_BYTESWAP_H) check_include_file(byteswap.h HAVE_BYTESWAP_H)
check_include_file(glob.h HAVE_GLOB_H) check_include_file(glob.h HAVE_GLOB_H)
check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H)
if (WIN32) if (WIN32)
check_include_file(io.h HAVE_IO_H) check_include_file(io.h HAVE_IO_H)
@@ -108,6 +109,10 @@ if (OPENSSL_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC) check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_aes_128_gcm HAVE_OPENSSL_EVP_AES_GCM)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK) check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
@@ -124,6 +129,8 @@ if (OPENSSL_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES) check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES) unset(CMAKE_REQUIRED_LIBRARIES)
endif() endif()
@@ -150,12 +157,14 @@ endif (NOT WITH_MBEDTLS)
check_function_exists(isblank HAVE_ISBLANK) check_function_exists(isblank HAVE_ISBLANK)
check_function_exists(strncpy HAVE_STRNCPY) check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(strndup HAVE_STRNDUP)
check_function_exists(strtoull HAVE_STRTOULL) check_function_exists(strtoull HAVE_STRTOULL)
check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO) check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO)
check_function_exists(memset_s HAVE_MEMSET_S) check_function_exists(memset_s HAVE_MEMSET_S)
if (HAVE_GLOB_H) if (HAVE_GLOB_H)
check_function_exists(glob HAVE_GLOB) check_struct_has_member(glob_t gl_flags glob.h HAVE_GLOB_GL_FLAGS_MEMBER)
check_function_exists(glob HAVE_GLOB)
endif (HAVE_GLOB_H) endif (HAVE_GLOB_H)
if (NOT WIN32) if (NOT WIN32)
@@ -252,6 +261,14 @@ if (CMAKE_USE_PTHREADS_INIT)
set(HAVE_PTHREAD 1) set(HAVE_PTHREAD 1)
endif (CMAKE_USE_PTHREADS_INIT) endif (CMAKE_USE_PTHREADS_INIT)
if (UNIT_TESTING)
if (CMOCKA_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${CMOCKA_LIBRARIES})
check_function_exists(cmocka_set_test_filter HAVE_CMOCKA_SET_TEST_FILTER)
unset(CMAKE_REQUIRED_LIBRARIES)
endif ()
endif ()
# OPTIONS # OPTIONS
check_c_source_compiles(" check_c_source_compiles("
__thread int tls; __thread int tls;
@@ -267,25 +284,57 @@ int main(void) {
return 0; return 0;
}" HAVE_MSC_THREAD_LOCAL_STORAGE) }" HAVE_MSC_THREAD_LOCAL_STORAGE)
###########################################################
# For detecting attributes we need to treat warnings as
# errors
if (UNIX OR MINGW)
# Get warnings for attributs
check_c_compiler_flag("-Wattributes" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
string(APPEND CMAKE_REQUIRED_FLAGS "-Wattributes ")
endif()
# Turn warnings into errors
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
string(APPEND CMAKE_REQUIRED_FLAGS "-Werror ")
endif()
endif ()
check_c_source_compiles("
void test_constructor_attribute(void) __attribute__ ((constructor));
void test_constructor_attribute(void)
{
return;
}
int main(void) {
return 0;
}" HAVE_CONSTRUCTOR_ATTRIBUTE)
check_c_source_compiles("
void test_destructor_attribute(void) __attribute__ ((destructor));
void test_destructor_attribute(void)
{
return;
}
int main(void) {
return 0;
}" HAVE_DESTRUCTOR_ATTRIBUTE)
check_c_source_compiles(" check_c_source_compiles("
#define FALL_THROUGH __attribute__((fallthrough)) #define FALL_THROUGH __attribute__((fallthrough))
enum direction_e {
UP = 0,
DOWN,
};
int main(void) { int main(void) {
enum direction_e key = UP; int i = 2;
int i = 10;
int j = 0;
switch (key) { switch (i) {
case UP: case 0:
i = 5;
FALL_THROUGH; FALL_THROUGH;
case DOWN: case 1:
j = i * 2;
break; break;
default: default:
break; break;
@@ -294,6 +343,28 @@ int main(void) {
return 0; return 0;
}" HAVE_FALLTHROUGH_ATTRIBUTE) }" HAVE_FALLTHROUGH_ATTRIBUTE)
if (NOT WIN32)
check_c_source_compiles("
#define __unused __attribute__((unused))
static int do_nothing(int i __unused)
{
return 0;
}
int main(void)
{
int i;
i = do_nothing(5);
if (i > 5) {
return 1;
}
return 0;
}" HAVE_UNUSED_ATTRIBUTE)
endif()
check_c_source_compiles(" check_c_source_compiles("
#include <string.h> #include <string.h>
@@ -332,11 +403,34 @@ int main(void) {
return 0; return 0;
}" HAVE_COMPILER__FUNCTION__) }" HAVE_COMPILER__FUNCTION__)
# This is only available with OpenBSD's gcc implementation */
if (OPENBSD)
check_c_source_compiles(" check_c_source_compiles("
void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits) #define ARRAY_LEN 16
__attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN))); void test_attr(const unsigned char *k)
int main(void) { return 0; }" HAVE_GCC_BOUNDED_ATTRIBUTE) __attribute__((__bounded__(__minbytes__, 2, 16)));
int main(void) {
return 0;
}" HAVE_GCC_BOUNDED_ATTRIBUTE)
endif(OPENBSD)
# Stop treating warnings as errors
unset(CMAKE_REQUIRED_FLAGS)
# Check for version script support
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "VERS_1 {
global: sym;
};
VERS_2 {
global: sym;
} VERS_1;
")
set(CMAKE_REQUIRED_FLAGS "-Wl,--version-script=\"${CMAKE_CURRENT_BINARY_DIR}/conftest.map\"")
check_c_source_compiles("int main(void) { return 0; }" HAVE_LD_VERSION_SCRIPT)
unset(CMAKE_REQUIRED_FLAGS)
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
if (WITH_DEBUG_CRYPTO) if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1) set(DEBUG_CRYPTO 1)

View File

@@ -19,18 +19,25 @@ option(WITH_NACL "Build with libnacl (curve25519)" ON)
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON) option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
option(WITH_ABI_BREAK "Allow ABI break" OFF) option(WITH_ABI_BREAK "Allow ABI break" OFF)
option(FUZZ_TESTING "Build with fuzzer for the server" OFF) option(FUZZ_TESTING "Build with fuzzer for the server" OFF)
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
if (WITH_ZLIB) if (WITH_ZLIB)
set(WITH_LIBZ ON) set(WITH_LIBZ ON)
else (WITH_ZLIB) else (WITH_ZLIB)
set(WITH_LIBZ OFF) set(WITH_LIBZ OFF)
endif (WITH_ZLIB) endif (WITH_ZLIB)
if(WITH_BENCHMARKS) if (WITH_BENCHMARKS)
set(UNIT_TESTING ON) set(UNIT_TESTING ON)
endif(WITH_BENCHMARKS) set(CLIENT_TESTING ON)
endif()
if (WITH_STATIC_LIB)
set(BUILD_STATIC_LIB ON)
endif (WITH_STATIC_LIB)
if (UNIT_TESTING) if (UNIT_TESTING)
set(WITH_STATIC_LIB ON) set(BUILD_STATIC_LIB ON)
endif (UNIT_TESTING) endif (UNIT_TESTING)
if (WITH_NACL) if (WITH_NACL)

View File

@@ -22,12 +22,12 @@ optional:
Note that these version numbers are version we know works correctly. If you Note that these version numbers are version we know works correctly. If you
build and run libssh successfully with an older version, please let us know. build and run libssh successfully with an older version, please let us know.
Windows binaries known to be working: For Windows use vcpkg:
- http://www.slproweb.com/products/Win32OpenSSL.html https://github.com/Microsoft/vcpkg
- http://zlib.net/ -> zlib compiled DLL
We installed them in C:\Program Files which you can use to install openssl and zilib. libssh itself is also part of
vcpkg!
## Building ## Building
First, you need to configure the compilation, using CMake. Go inside the First, you need to configure the compilation, using CMake. Go inside the

View File

@@ -0,0 +1,21 @@
#
# add_c_compiler_flag("-Werror" SUPPORTED_CFLAGS)
#
# Copyright (c) 2018 Andreas Schneider <asn@cryptomilk.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(CheckCCompilerFlag)
macro(add_c_compiler_flag _COMPILER_FLAG _OUTPUT_VARIABLE)
string(TOUPPER ${_COMPILER_FLAG} _COMPILER_FLAG_NAME)
string(REGEX REPLACE "^-" "" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}")
string(REGEX REPLACE "(-|=|\ )" "_" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}")
check_c_compiler_flag("${_COMPILER_FLAG}" WITH_${_COMPILER_FLAG_NAME}_FLAG)
if (WITH_${_COMPILER_FLAG_NAME}_FLAG)
#string(APPEND ${_OUTPUT_VARIABLE} "${_COMPILER_FLAG} ")
list(APPEND ${_OUTPUT_VARIABLE} ${_COMPILER_FLAG})
endif()
endmacro()

View File

@@ -1,28 +1,66 @@
# - ADD_CHECK_TEST(test_name test_source linklib1 ... linklibN) #
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de> # Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
# Copyright (c) 2007-2010 Andreas Schneider <asn@cryptomilk.org> # Copyright (c) 2007-2018 Andreas Schneider <asn@cryptomilk.org>
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
# #
# Redistribution and use is allowed according to the terms of the BSD license. # Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#.rst:
# AddCMockaTest
# -------------
#
# This file provides a function to add a test
#
# Functions provided
# ------------------
#
# ::
#
# add_cmocka_test(target_name
# SOURCES src1 src2 ... srcN
# [COMPILE_OPTIONS opt1 opt2 ... optN]
# [LINK_LIBRARIES lib1 lib2 ... libN]
# [LINK_OPTIONS lopt1 lop2 .. loptN]
# )
#
# ``target_name``:
# Required, expects the name of the test which will be used to define a target
#
# ``SOURCES``:
# Required, expects one or more source files names
#
# ``COMPILE_OPTIONS``:
# Optional, expects one or more options to be passed to the compiler
#
# ``LINK_LIBRARIES``:
# Optional, expects one or more libraries to be linked with the test
# executable.
#
# ``LINK_OPTIONS``:
# Optional, expects one or more options to be passed to the linker
#
#
# Example:
#
# .. code-block:: cmake
#
# add_cmocka_test(my_test
# SOURCES my_test.c other_source.c
# COMPILE_OPTIONS -g -Wall
# LINK_LIBRARIES mylib
# LINK_OPTIONS -Wl,--enable-syscall-fixup
# )
#
# Where ``my_test`` is the name of the test, ``my_test.c`` and
# ``other_source.c`` are sources for the binary, ``-g -Wall`` are compiler
# options to be used, ``mylib`` is a target of a library to be linked, and
# ``-Wl,--enable-syscall-fixup`` is an option passed to the linker.
#
enable_testing() enable_testing()
include(CTest) include(CTest)
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
# Profiling
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
# Address Sanitizer
set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING "Address sanitizer compiler flags")
set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Address sanitizer shared linker flags")
set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Address sanitizer module linker flags")
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Address sanitizer executable linker flags")
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
if (CMAKE_CROSSCOMPILING) if (CMAKE_CROSSCOMPILING)
if (WIN32) if (WIN32)
find_program(WINE_EXECUTABLE find_program(WINE_EXECUTABLE
@@ -31,8 +69,52 @@ if (CMAKE_CROSSCOMPILING)
endif() endif()
endif() endif()
function (ADD_CMOCKA_TEST _testName _testSource) function(ADD_CMOCKA_TEST _TARGET_NAME)
add_executable(${_testName} ${_testSource})
target_link_libraries(${_testName} ${ARGN}) set(one_value_arguments
add_test(${_testName} ${TARGET_SYSTEM_EMULATOR} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}${CMAKE_EXECUTABLE_SUFFIX}) )
set(multi_value_arguments
SOURCES
COMPILE_OPTIONS
LINK_LIBRARIES
LINK_OPTIONS
)
cmake_parse_arguments(_add_cmocka_test
""
"${one_value_arguments}"
"${multi_value_arguments}"
${ARGN}
)
if (NOT DEFINED _add_cmocka_test_SOURCES)
message(FATAL_ERROR "No sources provided for target ${_TARGET_NAME}")
endif()
add_executable(${_TARGET_NAME} ${_add_cmocka_test_SOURCES})
if (DEFINED _add_cmocka_test_COMPILE_OPTIONS)
target_compile_options(${_TARGET_NAME}
PRIVATE ${_add_cmocka_test_COMPILE_OPTIONS}
)
endif()
if (DEFINED _add_cmocka_test_LINK_LIBRARIES)
target_link_libraries(${_TARGET_NAME}
PRIVATE ${_add_cmocka_test_LINK_LIBRARIES}
)
endif()
if (DEFINED _add_cmocka_test_LINK_OPTIONS)
set_target_properties(${_TARGET_NAME}
PROPERTIES LINK_FLAGS
${_add_cmocka_test_LINK_OPTIONS}
)
endif()
add_test(${_TARGET_NAME}
${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME}
)
endfunction (ADD_CMOCKA_TEST) endfunction (ADD_CMOCKA_TEST)

View File

@@ -15,12 +15,15 @@
# Redistribution and use is allowed according to the terms of the BSD license. # Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Requires cmake 3.10
#include_guard(GLOBAL)
include(CheckCSourceCompiles) include(CheckCSourceCompiles)
function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT) macro(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") set(CMAKE_REQUIRED_FLAGS "${_FLAG}")
check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT}) check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
endfunction(CHECK_C_COMPILER_FLAG_SSP) set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
endmacro(CHECK_C_COMPILER_FLAG_SSP)

View File

@@ -14,17 +14,8 @@ set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
# since cmake 2.4.0 # since cmake 2.4.0
set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_COLOR_MAKEFILE ON)
# Define the generic version of the libraries here
set(GENERIC_LIB_VERSION "0.1.0")
set(GENERIC_LIB_SOVERSION "0")
# Set the default build type to release with debug info
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo
CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
)
endif (NOT CMAKE_BUILD_TYPE)
# Create the compile command database for clang by default # Create the compile command database for clang by default
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Always build with -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

View File

@@ -1,84 +1,37 @@
# define system dependent compiler flags
include(CheckCCompilerFlag)
include(CheckCCompilerFlagSSP)
if (UNIX AND NOT WIN32) if (UNIX AND NOT WIN32)
# # Activate with: -DCMAKE_BUILD_TYPE=Profiling
# Define GNUCC compiler flags set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
# CACHE STRING "Flags used by the C compiler during PROFILING builds.")
if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)") set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the CXX compiler during PROFILING builds.")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during PROFILING builds.")
# add -Wconversion ? # Activate with: -DCMAKE_BUILD_TYPE=AddressSanitizer
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors") set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer"
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement") CACHE STRING "Flags used by the C compiler during ADDRESSSANITIZER builds.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security") set(CMAKE_CXX_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer"
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute") CACHE STRING "Flags used by the CXX compiler during ADDRESSSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
# with -fPIC CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
check_c_compiler_flag("-fPIC" WITH_FPIC) set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
if (WITH_FPIC) CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
endif (WITH_FPIC) CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
if (WITH_STACK_PROTECTOR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
endif (WITH_STACK_PROTECTOR)
if (CMAKE_BUILD_TYPE)
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
check_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
if (WITH_FORTIFY_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-D_FORTIFY_SOURCE=2")
endif (WITH_FORTIFY_SOURCE)
endif()
endif()
endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
#
# Check for large filesystem support
#
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
# with large file support
execute_process(
COMMAND
getconf LFS64_CFLAGS
OUTPUT_VARIABLE
_lfs_CFLAGS
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
# with large file support
execute_process(
COMMAND
getconf LFS_CFLAGS
OUTPUT_VARIABLE
_lfs_CFLAGS
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
if (_lfs_CFLAGS)
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}")
endif (_lfs_CFLAGS)
endif (UNIX AND NOT WIN32)
if (MSVC)
# Use secure functions by defaualt and suppress warnings about
#"deprecated" functions
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
endif (MSVC)
# This removes this annoying warning
# "warning: 'BN_CTX_free' is deprecated: first deprecated in OS X 10.7 [-Wdeprecated-declarations]"
if (OSX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
endif (OSX)
# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.")
set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
set(CMAKE_MODULE_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.")
endif()

View File

@@ -85,4 +85,8 @@ endforeach()
list(REMOVE_DUPLICATES symbols) list(REMOVE_DUPLICATES symbols)
file(WRITE ${OUTPUT_PATH} "${symbols}") list(SORT symbols)
string(REPLACE ";" "\n" symbols_list "${symbols}")
file(WRITE ${OUTPUT_PATH} "${symbols_list}")

View File

@@ -37,7 +37,7 @@
# #
# generate_map_file(target_name # generate_map_file(target_name
# RELEASE_NAME_VERSION release_name # RELEASE_NAME_VERSION release_name
# SYMBOLS symbols_file # SYMBOLS symbols_target
# [CURRENT_MAP cur_map] # [CURRENT_MAP cur_map]
# [FINAL] # [FINAL]
# [BREAK_ABI] # [BREAK_ABI]
@@ -55,8 +55,9 @@
# added to the symbols in the format ``lib_name_1_2_3``. # added to the symbols in the format ``lib_name_1_2_3``.
# #
# ``SYMBOLS``: # ``SYMBOLS``:
# Required, expects a file containing the list of symbols to be added to the # Required, expects a target with the property ``LIST_FILE`` containing a path
# symbol version script. # to a file containing the list of symbols to be added to the symbol version
# script.
# #
# ``CURRENT_MAP``: # ``CURRENT_MAP``:
# Optional. If given, the new set of symbols will be checked against the # Optional. If given, the new set of symbols will be checked against the
@@ -87,9 +88,15 @@
# find_package(ABIMap) # find_package(ABIMap)
# generate_map_file("lib.map" # generate_map_file("lib.map"
# RELEASE_NAME_VERSION "lib_1_0_0" # RELEASE_NAME_VERSION "lib_1_0_0"
# SYMBOLS "symbol1;symbol2" # SYMBOLS symbols
# ) # )
# #
# Where the target ``symbols`` has its property ``LIST_FILE`` set to the path to
# a file containing::
#
# ``symbol1``
# ``symbol2``
#
# This example would result in the symbol version script to be created in # This example would result in the symbol version script to be created in
# ``${CMAKE_CURRENT_BINARY_DIR}/lib.map`` containing the provided symbols. # ``${CMAKE_CURRENT_BINARY_DIR}/lib.map`` containing the provided symbols.
# #
@@ -102,8 +109,8 @@
# ) # )
# #
# ``target_name``: # ``target_name``:
# Required, expects the name of the target to be created. A file named after # Required, expects the name of the target to be created. A file named as
# the string given in ``target_name`` will be created in # ``${target_name}.list`` will be created in
# ``${CMAKE_CURRENT_BINARY_DIR}`` to receive the list of files found. # ``${CMAKE_CURRENT_BINARY_DIR}`` to receive the list of files found.
# #
# ``DIRECTORIES``: # ``DIRECTORIES``:
@@ -112,7 +119,7 @@
# #
# ``FILES_PATTERN``: # ``FILES_PATTERN``:
# Required, expects a list of matching expressions to find the files to be # Required, expects a list of matching expressions to find the files to be
# considered. # considered in the directories.
# #
# ``COPY_TO``: # ``COPY_TO``:
# Optional, expects a string containing the path to where the file containing # Optional, expects a string containing the path to where the file containing
@@ -120,7 +127,9 @@
# #
# This command searches the directories provided in ``DIRECTORIES`` for files # This command searches the directories provided in ``DIRECTORIES`` for files
# matching any of the patterns provided in ``FILES_PATTERNS``. The obtained list # matching any of the patterns provided in ``FILES_PATTERNS``. The obtained list
# is written to the path specified by ``output``. # is written to the path specified by ``output``. A target named ``target_name``
# will be created and its property ``LIST_FILE`` will be set to contain
# ``${CMAKE_CURRENT_BINARY_DIR}/${target_name}.list``
# #
# Example: # Example:
# #
@@ -140,10 +149,13 @@
# #
# ``h1.h;h2.h`` # ``h1.h;h2.h``
# #
# And the target ``target`` will have its property ``LIST_FILE`` set to contain
# ``${CMAKE_CURRENT_BINARY_DIR}/target.list``
#
# :: # ::
# #
# extract_symbols(target_name # extract_symbols(target_name
# HEADERS_LIST_FILE headers_list # HEADERS_LIST headers_list_target
# [FILTER_PATTERN pattern] # [FILTER_PATTERN pattern]
# [COPY_TO output] # [COPY_TO output]
# ) # )
@@ -153,9 +165,9 @@
# the string given in ``target_name`` will be created in # the string given in ``target_name`` will be created in
# ``${CMAKE_CURRENT_BINARY_DIR}`` to receive the list of symbols. # ``${CMAKE_CURRENT_BINARY_DIR}`` to receive the list of symbols.
# #
# ``HEADERS_LIST_FILE``: # ``HEADERS_LIST``:
# Required, expects a path to a file containing the list of header files to be # Required, expects a target with the property ``LIST_FILE`` set, containing a
# parsed. # file path. Such file must contain a list of files paths.
# #
# ``FILTER_PATTERN``: # ``FILTER_PATTERN``:
# Optional, expects a string. Only the lines containing the filter pattern # Optional, expects a string. Only the lines containing the filter pattern
@@ -170,7 +182,9 @@
# is provided, then only the lines containing the string given in ``pattern`` # is provided, then only the lines containing the string given in ``pattern``
# will be considered. It is recommended to provide a ``FILTER_PATTERN`` to mark # will be considered. It is recommended to provide a ``FILTER_PATTERN`` to mark
# the lines containing exported function declaration, since this function is # the lines containing exported function declaration, since this function is
# experimental and can return wrong symbols when parsing the header files. # experimental and can return wrong symbols when parsing the header files. A
# target named ``target_name`` will be created with the property ``LIST_FILE``
# set to contain ``${CMAKE_CURRENT_BINARY_DIR}/${target_name}.list``.
# #
# Example: # Example:
# #
@@ -178,11 +192,12 @@
# #
# find_package(ABIMap) # find_package(ABIMap)
# extract_symbols("lib.symbols" # extract_symbols("lib.symbols"
# HEADERS_LIST_FILE "headers_list" # HEADERS_LIST "headers_target"
# FILTER_PATTERN "API_FUNCTION" # FILTER_PATTERN "API_FUNCTION"
# ) # )
# #
# Where headers_list contains:: # Where ``LIST_FILE`` property in ``headers_target`` points to a file
# containing::
# #
# header1.h;header2.h # header1.h;header2.h
# #
@@ -196,25 +211,52 @@
# #
# int private_func2(int b); # int private_func2(int b);
# #
# Will result in a file ``lib.symbols`` in ``${CMAKE_CURRENT_BINARY_DIR}`` containing:: # Will result in a file ``lib.symbols.list`` in ``${CMAKE_CURRENT_BINARY_DIR}``
# containing::
# #
# ``exported_func1;exported_func2`` # ``exported_func1``
# ``exported_func2``
# #
# Search for python which is required # Search for python which is required
find_package(PythonInterp REQUIRED) if (ABIMap_FIND_REQURIED)
find_package(PythonInterp REQUIRED)
else()
find_package(PythonInterp)
endif()
# Search for abimap tool used to generate the map files
find_program(ABIMAP_EXECUTABLE NAMES abimap DOC "path to the abimap executable")
mark_as_advanced(ABIMAP_EXECUTABLE)
if (NOT ABIMAP_EXECUTABLE AND UNIX) if (PYTHONINTERP_FOUND)
message(STATUS "Could not find `abimap` in PATH." # Search for abimap tool used to generate the map files
" It can be found in PyPI as `abimap`" find_program(ABIMAP_EXECUTABLE NAMES abimap DOC "path to the abimap executable")
" (try `pip install abimap`)") mark_as_advanced(ABIMAP_EXECUTABLE)
else ()
set(ABIMAP_FOUND TRUE) if (NOT ABIMAP_EXECUTABLE AND UNIX)
endif () message(STATUS "Could not find `abimap` in PATH."
" It can be found in PyPI as `abimap`"
" (try `pip install abimap`)")
endif ()
if (ABIMAP_EXECUTABLE)
# Get the abimap version
execute_process(COMMAND ${ABIMAP_EXECUTABLE} version
OUTPUT_VARIABLE ABIMAP_VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE)
# If the version string starts with abimap-, strip it
if ("abimap" STRLESS_EQUAL ${ABIMAP_VERSION_STRING})
string(REGEX REPLACE "abimap-" "" ABIMAP_VERSION_STRING "${ABIMAP_VERSION_STRING}")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ABIMap
REQUIRED_VARS ABIMAP_EXECUTABLE
VERSION_VAR ABIMAP_VERSION_STRING)
endif()
if (ABIMAP_FOUND)
# Define helper scripts # Define helper scripts
set(_EXTRACT_SYMBOLS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/ExtractSymbols.cmake) set(_EXTRACT_SYMBOLS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/ExtractSymbols.cmake)
@@ -224,42 +266,41 @@ set(_GET_FILES_LIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/GetFilesList.cmake)
function(get_file_list _TARGET_NAME) function(get_file_list _TARGET_NAME)
set(one_value_arguments set(one_value_arguments
COPY_TO COPY_TO
) )
set(multi_value_arguments set(multi_value_arguments
DIRECTORIES DIRECTORIES
FILES_PATTERNS FILES_PATTERNS
) )
cmake_parse_arguments(_get_files_list cmake_parse_arguments(_get_files_list
"" ""
"${one_value_arguments}" "${one_value_arguments}"
"${multi_value_arguments}" "${multi_value_arguments}"
${ARGN} ${ARGN}
) )
# The DIRS argument is required # The DIRS argument is required
if (NOT DEFINED _get_files_list_DIRECTORIES) if (NOT DEFINED _get_files_list_DIRECTORIES)
message(FATAL_ERROR "No directories paths provided. Provide a list of" message(FATAL_ERROR "No directories paths provided. Provide a list of"
" directories paths containing header files." " directories paths containing header files.")
) endif()
endif()
# The FILES_PATTERNS argument is required # The FILES_PATTERNS argument is required
if (NOT DEFINED _get_files_list_FILES_PATTERNS) if (NOT DEFINED _get_files_list_FILES_PATTERNS)
message(FATAL_ERROR "No matching expressions provided. Provide a list" message(FATAL_ERROR "No matching expressions provided. Provide a list"
" of matching patterns for the header files." " of matching patterns for the header files.")
)
endif() endif()
get_filename_component(_get_files_list_OUTPUT_PATH set(_FILES_LIST_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}.list)
"${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}"
ABSOLUTE
)
add_custom_command( get_filename_component(_get_files_list_OUTPUT_PATH
OUTPUT ${_TARGET_NAME} "${_FILES_LIST_OUTPUT_PATH}"
ABSOLUTE)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DOUTPUT_PATH="${_get_files_list_OUTPUT_PATH}" -DOUTPUT_PATH="${_get_files_list_OUTPUT_PATH}"
-DDIRECTORIES="${_get_files_list_DIRECTORIES}" -DDIRECTORIES="${_get_files_list_DIRECTORIES}"
@@ -271,59 +312,90 @@ function(get_file_list _TARGET_NAME)
if (DEFINED _get_files_list_COPY_TO) if (DEFINED _get_files_list_COPY_TO)
# Copy the generated file back to the COPY_TO # Copy the generated file back to the COPY_TO
add_custom_target(copy_headers_list_${TARGET_NAME} ALL add_custom_target(${_TARGET_NAME} ALL
COMMAND COMMAND
${CMAKE_COMMAND} -E copy_if_different ${_TARGET_NAME} ${_get_files_list_COPY_TO} ${CMAKE_COMMAND} -E copy_if_different
DEPENDS "${_TARGET_NAME}" ${_FILES_LIST_OUTPUT_PATH} ${_get_files_list_COPY_TO}
DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}" COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}"
) )
else()
add_custom_target(${_TARGET_NAME} ALL
DEPENDS ${_TARGET_NAME}_int
)
endif() endif()
set_target_properties(${_TARGET_NAME}
PROPERTIES LIST_FILE ${_FILES_LIST_OUTPUT_PATH}
)
endfunction() endfunction()
function(extract_symbols _TARGET_NAME) function(extract_symbols _TARGET_NAME)
set(one_value_arguments set(one_value_arguments
FILTER_PATTERN FILTER_PATTERN
HEADERS_LIST_FILE HEADERS_LIST
COPY_TO COPY_TO
) )
set(multi_value_arguments set(multi_value_arguments
) )
cmake_parse_arguments(_extract_symbols cmake_parse_arguments(_extract_symbols
"" ""
"${one_value_arguments}" "${one_value_arguments}"
"${multi_value_arguments}" "${multi_value_arguments}"
${ARGN} ${ARGN}
) )
# The HEADERS_LIST_FILE argument is required # The HEADERS_LIST_FILE argument is required
if (NOT DEFINED _extract_symbols_HEADERS_LIST_FILE) if (NOT DEFINED _extract_symbols_HEADERS_LIST)
message(FATAL_ERROR "No header files given. Provide a list of header" message(FATAL_ERROR "No target provided in HEADERS_LIST. Provide a"
" files containing exported symbols." " target with the property LIST_FILE set as the"
" path to the file containing the list of headers.")
endif()
get_filename_component(_SYMBOLS_OUTPUT_PATH
"${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}.list"
ABSOLUTE
)
get_target_property(_HEADERS_LIST_FILE
${_extract_symbols_HEADERS_LIST}
LIST_FILE
)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND}
-DOUTPUT_PATH="${_SYMBOLS_OUTPUT_PATH}"
-DHEADERS_LIST_FILE="${_HEADERS_LIST_FILE}"
-DFILTER_PATTERN=${_extract_symbols_FILTER_PATTERN}
-P ${_EXTRACT_SYMBOLS_SCRIPT}
DEPENDS ${_extract_symbols_HEADERS_LIST}
COMMENT "Extracting symbols from headers"
)
if (DEFINED _extract_symbols_COPY_TO)
# Copy the generated file back to the COPY_TO
add_custom_target(${_TARGET_NAME} ALL
COMMAND
${CMAKE_COMMAND} -E copy_if_different
${_SYMBOLS_OUTPUT_PATH} ${_extract_symbols_COPY_TO}
DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_TARGET_NAME} to ${_extract_symbols_COPY_TO}"
)
else()
add_custom_target(${_TARGET_NAME} ALL
DEPENDS ${_TARGET_NAME}_int
) )
endif() endif()
get_filename_component(_extract_symbols_OUTPUT_PATH set_target_properties(${_TARGET_NAME}
"${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}" PROPERTIES LIST_FILE ${_SYMBOLS_OUTPUT_PATH}
ABSOLUTE
) )
add_custom_target(${_TARGET_NAME}
COMMAND ${CMAKE_COMMAND}
-DOUTPUT_PATH="${_extract_symbols_OUTPUT_PATH}"
-DHEADERS_LIST_FILE="${_extract_symbols_HEADERS_LIST_FILE}"
-DFILTER_PATTERN=${_extract_symbols_FILTER_PATTERN}
-P ${_EXTRACT_SYMBOLS_SCRIPT}
DEPENDS ${_extract_symbols_HEADERS_LIST_FILE}
COMMENT "Extracting symbols from headers")
if (DEFINED _extract_symbols_COPY_TO)
file(READ "${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}" SYMBOL_CONTENT)
string(REPLACE ";" "\n" SYMBOL_CONTENT_NEW "${SYMBOL_CONTENT}")
file(WRITE "${_extract_symbols_COPY_TO}" "${SYMBOL_CONTENT_NEW}")
endif()
endfunction() endfunction()
function(generate_map_file _TARGET_NAME) function(generate_map_file _TARGET_NAME)
@@ -344,36 +416,42 @@ function(generate_map_file _TARGET_NAME)
) )
cmake_parse_arguments(_generate_map_file cmake_parse_arguments(_generate_map_file
"${options}" "${options}"
"${one_value_arguments}" "${one_value_arguments}"
"${multi_value_arguments}" "${multi_value_arguments}"
${ARGN} ${ARGN}
) )
if (NOT DEFINED _generate_map_file_SYMBOLS) if (NOT DEFINED _generate_map_file_SYMBOLS)
message(FATAL_ERROR "No symbols file provided." message(FATAL_ERROR "No target provided in SYMBOLS. Provide a target"
) " with the property LIST_FILE set as the path to"
" the file containing the list of symbols.")
endif() endif()
if (NOT DEFINED _generate_map_file_RELEASE_NAME_VERSION) if (NOT DEFINED _generate_map_file_RELEASE_NAME_VERSION)
message(FATAL_ERROR "Release name and version not provided." message(FATAL_ERROR "Release name and version not provided."
" (e.g. libname_1_0_0" " (e.g. libname_1_0_0)")
)
endif() endif()
# Set generated map file path
get_filename_component(_generate_map_file_OUTPUT_PATH get_target_property(_SYMBOLS_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}" ${_generate_map_file_SYMBOLS}
ABSOLUTE LIST_FILE
) )
add_custom_command( # Set generated map file path
OUTPUT ${_TARGET_NAME} get_filename_component(_MAP_OUTPUT_PATH
"${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}"
ABSOLUTE
)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE} -DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE}
-DSYMBOLS="${_generate_map_file_SYMBOLS}" -DSYMBOLS="${_SYMBOLS_FILE}"
-DCURRENT_MAP=${_generate_map_file_CURRENT_MAP} -DCURRENT_MAP=${_generate_map_file_CURRENT_MAP}
-DOUTPUT_PATH="${_generate_map_file_OUTPUT_PATH}" -DOUTPUT_PATH="${_MAP_OUTPUT_PATH}"
-DFINAL=${_generate_map_file_FINAL} -DFINAL=${_generate_map_file_FINAL}
-DBREAK_ABI=${_generate_map_file_BREAK_ABI} -DBREAK_ABI=${_generate_map_file_BREAK_ABI}
-DRELEASE_NAME_VERSION=${_generate_map_file_RELEASE_NAME_VERSION} -DRELEASE_NAME_VERSION=${_generate_map_file_RELEASE_NAME_VERSION}
@@ -382,13 +460,27 @@ function(generate_map_file _TARGET_NAME)
COMMENT "Generating the map ${_TARGET_NAME}" COMMENT "Generating the map ${_TARGET_NAME}"
) )
# Add a custom command setting the map as OUTPUT to allow it to be added as
# a generated source
add_custom_command(
OUTPUT ${_MAP_OUTPUT_PATH}
DEPENDS ${_TARGET_NAME}
)
if (DEFINED _generate_map_file_COPY_TO) if (DEFINED _generate_map_file_COPY_TO)
# Copy the generated map back to the COPY_TO # Copy the generated map back to the COPY_TO
add_custom_target(copy_map_${_TARGET_NAME} ALL add_custom_target(${_TARGET_NAME} ALL
COMMAND COMMAND
${CMAKE_COMMAND} -E copy_if_different ${_TARGET_NAME} ${_generate_map_file_COPY_TO} ${CMAKE_COMMAND} -E copy_if_different ${_MAP_OUTPUT_PATH}
DEPENDS "${_TARGET_NAME}" ${_generate_map_file_COPY_TO}
COMMENT "Copying ${_TARGET_NAME} to ${_generate_map_file_COPY_TO}" DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_MAP_OUTPUT_PATH} to ${_generate_map_file_COPY_TO}"
)
else()
add_custom_target(${_TARGET_NAME} ALL
DEPENDS ${_TARGET_NAME}_int
) )
endif() endif()
endfunction() endfunction()
endif (ABIMAP_FOUND)

View File

@@ -49,7 +49,15 @@ find_library(GCRYPT_LIBRARY
PATH_SUFFIXES PATH_SUFFIXES
lib lib
) )
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY}) find_library(GCRYPT_ERROR_LIBRARY
NAMES
gpg-error
libgpg-error-0
libgpg-error6-0
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
)
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} ${GCRYPT_ERROR_LIBRARY})
if (GCRYPT_INCLUDE_DIR) if (GCRYPT_INCLUDE_DIR)
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]") file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")

View File

@@ -21,17 +21,16 @@
# #
if (WIN32) if (WIN32)
set(_NSIS_ROOT_HINTS set(_x86 "(x86)")
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]")
set(_NSIS_ROOT_PATHS set(_NSIS_ROOT_PATHS
$ENV{PROGRAMFILES}/NSIS) "$ENV{ProgramFiles}/NSIS"
"$ENV{ProgramFiles${_x86}}/NSIS"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]")
find_path(NSIS_ROOT_PATH find_path(NSIS_ROOT_PATH
NAMES NAMES
Include/Library.nsh Include/Library.nsh
HINTS
${_NSIS_ROOT_HINTS}
PATHS PATHS
${_NSIS_ROOT_PATHS} ${_NSIS_ROOT_PATHS}
) )

View File

@@ -1,140 +0,0 @@
# - Run Doxygen
#
# Adds a doxygen target that runs doxygen to generate the html
# and optionally the LaTeX API documentation.
# The doxygen target is added to the doc target as a dependency.
# i.e.: the API documentation is built with:
# make doc
#
# USAGE: GLOBAL INSTALL
#
# Install it with:
# cmake ./ && sudo make install
# Add the following to the CMakeLists.txt of your project:
# include(UseDoxygen OPTIONAL)
# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it.
#
# USAGE: INCLUDE IN PROJECT
#
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# include(UseDoxygen)
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
#
#
# CONFIGURATION
#
# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake.
# Variables you may define are:
# DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are.
# Defaults to the current source directory.
# DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan.
# The Paths should be in double quotes and separated by space. e.g.:
# "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/"
#
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored.
# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc".
#
# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation
# to be built.
# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
# the Doxygen LaTeX output is stored. Defaults to "latex".
#
# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
# the Doxygen html output is stored. Defaults to "html".
#
#
# Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz <tobias@rautenkranz.ch>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
macro(usedoxygen_set_default name value type docstring)
if(NOT DEFINED "${name}")
set("${name}" "${value}" CACHE "${type}" "${docstring}")
endif()
endmacro()
find_package(Doxygen)
if(DOXYGEN_FOUND)
find_file(DOXYFILE_IN "Doxyfile.in"
PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/"
NO_DEFAULT_PATH
DOC "Path to the doxygen configuration template file")
set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
endif()
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc"
PATH "Doxygen output directory")
usedoxygen_set_default(DOXYFILE_HTML_DIR "html"
STRING "Doxygen HTML output directory")
usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
PATH "Input files source directory")
usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS ""
STRING "Additional source files/directories separated by space")
set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}")
usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF)
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory")
mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR
DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN)
set_property(DIRECTORY
APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
add_custom_target(doxygen
COMMAND "${DOXYGEN_EXECUTABLE}"
"${DOXYFILE}"
COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..."
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
set(DOXYFILE_DOT "NO")
if(DOXYGEN_DOT_EXECUTABLE)
set(DOXYFILE_DOT "YES")
endif()
## LaTeX
set(DOXYFILE_PDFLATEX "NO")
set_property(DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
if(DOXYFILE_LATEX STREQUAL "ON")
set(DOXYFILE_GENERATE_LATEX "YES")
find_package(LATEX)
find_program(DOXYFILE_MAKE make)
mark_as_advanced(DOXYFILE_MAKE)
if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE)
if(PDFLATEX_COMPILER)
set(DOXYFILE_PDFLATEX "YES")
endif()
add_custom_command(TARGET doxygen
POST_BUILD
COMMAND "${DOXYFILE_MAKE}"
COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..."
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
else()
set(DOXYGEN_LATEX "NO")
endif()
else()
set(DOXYFILE_GENERATE_LATEX "NO")
endif()
configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY)
add_custom_target(doc)
add_dependencies(doc doxygen)
endif()

View File

@@ -1,8 +1,8 @@
/* Name of package */ /* Name of package */
#cmakedefine PACKAGE "${APPLICATION_NAME}" #cmakedefine PACKAGE "${PROJECT_NAME}"
/* Version number of package */ /* Version number of package */
#cmakedefine VERSION "${APPLICATION_VERSION}" #cmakedefine VERSION "${PROJECT_VERSION}"
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}" #cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
#cmakedefine DATADIR "${DATADIR}" #cmakedefine DATADIR "${DATADIR}"
@@ -23,6 +23,9 @@
/* Define to 1 if you have the <glob.h> header file. */ /* Define to 1 if you have the <glob.h> header file. */
#cmakedefine HAVE_GLOB_H 1 #cmakedefine HAVE_GLOB_H 1
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
#cmakedefine HAVE_VALGRIND_VALGRIND_H 1
/* Define to 1 if you have the <pty.h> header file. */ /* Define to 1 if you have the <pty.h> header file. */
#cmakedefine HAVE_PTY_H 1 #cmakedefine HAVE_PTY_H 1
@@ -89,6 +92,9 @@
/* Define to 1 if you have DSA */ /* Define to 1 if you have DSA */
#cmakedefine HAVE_DSA 1 #cmakedefine HAVE_DSA 1
/* Define to 1 if you have gl_flags as a glob_t sturct member */
#cmakedefine HAVE_GLOB_GL_FLAGS_MEMBER 1
/*************************** FUNCTIONS ***************************/ /*************************** FUNCTIONS ***************************/
/* Define to 1 if you have the `EVP_aes128_ctr' function. */ /* Define to 1 if you have the `EVP_aes128_ctr' function. */
@@ -97,6 +103,9 @@
/* Define to 1 if you have the `EVP_aes128_cbc' function. */ /* Define to 1 if you have the `EVP_aes128_cbc' function. */
#cmakedefine HAVE_OPENSSL_EVP_AES_CBC 1 #cmakedefine HAVE_OPENSSL_EVP_AES_CBC 1
/* Define to 1 if you have the `EVP_aes128_gcm' function. */
#cmakedefine HAVE_OPENSSL_EVP_AES_GCM 1
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */ /* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
#cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1 #cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1
@@ -106,6 +115,9 @@
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */ /* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
#cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1 #cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1
/* Define to 1 if you have the `OPENSSL_ia32cap_loc' function. */
#cmakedefine HAVE_OPENSSL_IA32CAP_LOC 1
/* Define to 1 if you have the `snprintf' function. */ /* Define to 1 if you have the `snprintf' function. */
#cmakedefine HAVE_SNPRINTF 1 #cmakedefine HAVE_SNPRINTF 1
@@ -130,6 +142,9 @@
/* Define to 1 if you have the `strncpy' function. */ /* Define to 1 if you have the `strncpy' function. */
#cmakedefine HAVE_STRNCPY 1 #cmakedefine HAVE_STRNCPY 1
/* Define to 1 if you have the `strndup' function. */
#cmakedefine HAVE_STRNDUP 1
/* Define to 1 if you have the `cfmakeraw' function. */ /* Define to 1 if you have the `cfmakeraw' function. */
#cmakedefine HAVE_CFMAKERAW 1 #cmakedefine HAVE_CFMAKERAW 1
@@ -172,6 +187,9 @@
/* Define to 1 if you have the `SecureZeroMemory' function. */ /* Define to 1 if you have the `SecureZeroMemory' function. */
#cmakedefine HAVE_SECURE_ZERO_MEMORY 1 #cmakedefine HAVE_SECURE_ZERO_MEMORY 1
/* Define to 1 if you have the `cmocka_set_test_filter' function. */
#cmakedefine HAVE_CMOCKA_SET_TEST_FILTER 1
/*************************** LIBRARIES ***************************/ /*************************** LIBRARIES ***************************/
/* Define to 1 if you have the `crypto' library (-lcrypto). */ /* Define to 1 if you have the `crypto' library (-lcrypto). */
@@ -186,12 +204,19 @@
/* Define to 1 if you have the `pthread' library (-lpthread). */ /* Define to 1 if you have the `pthread' library (-lpthread). */
#cmakedefine HAVE_PTHREAD 1 #cmakedefine HAVE_PTHREAD 1
/* Define to 1 if you have the `cmocka' library (-lcmocka). */
#cmakedefine HAVE_CMOCKA 1
/**************************** OPTIONS ****************************/ /**************************** OPTIONS ****************************/
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1 #cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
#cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1 #cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1
#cmakedefine HAVE_FALLTHROUGH_ATTRIBUTE 1 #cmakedefine HAVE_FALLTHROUGH_ATTRIBUTE 1
#cmakedefine HAVE_UNUSED_ATTRIBUTE 1
#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1 #cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
#cmakedefine HAVE_GCC_NARG_MACRO 1 #cmakedefine HAVE_GCC_NARG_MACRO 1

View File

@@ -1,5 +1,46 @@
# #
# Build the documentation # Build the documentation
# #
include(UseDoxygen OPTIONAL) if (${CMAKE_VERSION} VERSION_GREATER "3.8.99")
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME})
set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION})
set(DOXYGEN_PROJECT_BRIEF "The SSH library")
set(DOXYGEN_TAB_SIZE 4)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_MARKDOWN_SUPPORT YES)
set(DOXYGEN_PREDEFINED DOXYGEN
PRINTF_ATTRIBUTE(x,y))
set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style)
set(DOXYGEN_HTML_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/that_style/header.html)
set(DOXYGEN_HTML_EXTRA_STYLESHEET ${CMAKE_CURRENT_SOURCE_DIR}/that_style/that_style.css)
set(DOXYGEN_HTML_EXTRA_FILES ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/nav_edge_left.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/nav_edge_right.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/nav_edge_inter.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/sync_off.png
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/sync_on.png
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/splitbar_handle.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/doc.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/mag_glass.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/folderclosed.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/folderopen.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/js/striped_bg.js)
# This updates the Doxyfile if we do changes here
set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in")
set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.docs")
configure_file("${_doxyfile_template}" "${_target_doxyfile}")
doxygen_add_docs(docs
${CMAKE_SOURCE_DIR}/include/libssh
${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR})
endif() # DOXYGEN_FOUND
endif() # CMAKE_VERSION

File diff suppressed because it is too large Load Diff

View File

@@ -187,7 +187,7 @@ keyboard-interactive authentication, coming from the RFC itself (rfc4256):
the name and prompts. If the server presents names or prompts longer than 30 the name and prompts. If the server presents names or prompts longer than 30
characters, the client MAY truncate these fields to the length it can characters, the client MAY truncate these fields to the length it can
display. If the client does truncate any fields, there MUST be an obvious display. If the client does truncate any fields, there MUST be an obvious
indication that such truncation has occured. indication that such truncation has occurred.
The instruction field SHOULD NOT be truncated. Clients SHOULD use control The instruction field SHOULD NOT be truncated. Clients SHOULD use control
character filtering as discussed in [SSH-ARCH] to avoid attacks by character filtering as discussed in [SSH-ARCH] to avoid attacks by

View File

@@ -4,7 +4,7 @@
Port forwarding comes in SSH protocol in two different flavours: Port forwarding comes in SSH protocol in two different flavours:
direct or reverse port forwarding. Direct port forwarding is also direct or reverse port forwarding. Direct port forwarding is also
named local port forwardind, and reverse port forwarding is also called named local port forwarding, and reverse port forwarding is also called
remote port forwarding. SSH also allows X11 tunnels. remote port forwarding. SSH also allows X11 tunnels.
@@ -26,12 +26,12 @@ Mail client application Google Mail
SSH client =====> SSH server SSH client =====> SSH server
Legend: Legend:
--P-->: port connexion through port P --P-->: port connections through port P
=====>: SSH tunnel =====>: SSH tunnel
@endverbatim @endverbatim
A mail client connects to port 5555 of a client. An encrypted tunnel is A mail client connects to port 5555 of a client. An encrypted tunnel is
established to the server. The server connects to port 143 of Google Mail (the established to the server. The server connects to port 143 of Google Mail (the
end point). Now the local mail client can retreive mail. end point). Now the local mail client can retrieve mail.
@subsection forwarding_reverse Reverse port forwarding @subsection forwarding_reverse Reverse port forwarding
@@ -51,7 +51,7 @@ Example of use of reverse port forwarding:
SSH client <===== SSH server SSH client <===== SSH server
Legend: Legend:
--P-->: port connexion through port P --P-->: port connections through port P
=====>: SSH tunnel =====>: SSH tunnel
@endverbatim @endverbatim
In this example, the SSH client establishes the tunnel, In this example, the SSH client establishes the tunnel,
@@ -148,9 +148,9 @@ To do reverse port forwarding, call ssh_channel_listen_forward(),
then ssh_channel_accept_forward(). then ssh_channel_accept_forward().
When you call ssh_channel_listen_forward(), you can let the remote server When you call ssh_channel_listen_forward(), you can let the remote server
chose the non-priviledged port it should listen to. Otherwise, you can chose chose the non-privileged port it should listen to. Otherwise, you can chose
your own priviledged or non-priviledged port. Beware that you should have your own privileged or non-privileged port. Beware that you should have
administrative priviledges on the remote server to open a priviledged port administrative privileges on the remote server to open a privileged port
(port number < 1024). (port number < 1024).
Below is an example of a very rough web server waiting for connections on port Below is an example of a very rough web server waiting for connections on port

View File

@@ -42,7 +42,7 @@ you'll usually open a "sftp session" or a "scp session".
The most important object in a SSH connection is the SSH session. In order The most important object in a SSH connection is the SSH session. In order
to allocate a new SSH session, you use ssh_new(). Don't forget to to allocate a new SSH session, you use ssh_new(). Don't forget to
always verify that the allocation successed. always verify that the allocation succeeded.
@code @code
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <stdlib.h> #include <stdlib.h>
@@ -285,9 +285,9 @@ int verify_knownhost(ssh_session session)
The authentication process is the way a service provider can identify a The authentication process is the way a service provider can identify a
user and verify his/her identity. The authorization process is about enabling user and verify his/her identity. The authorization process is about enabling
the authenticated user the access to ressources. In SSH, the two concepts the authenticated user the access to resources. In SSH, the two concepts
are linked. After authentication, the server can grant the user access to are linked. After authentication, the server can grant the user access to
several ressources such as port forwarding, shell, sftp subsystem, and so on. several resources such as port forwarding, shell, sftp subsystem, and so on.
libssh supports several methods of authentication: libssh supports several methods of authentication:
- "none" method. This method allows to get the available authentications - "none" method. This method allows to get the available authentications
@@ -338,7 +338,7 @@ int main()
} }
// Verify the server's identity // Verify the server's identity
// For the source code of verify_knowhost(), check previous example // For the source code of verify_knownhost(), check previous example
if (verify_knownhost(my_ssh_session) < 0) if (verify_knownhost(my_ssh_session) < 0)
{ {
ssh_disconnect(my_ssh_session); ssh_disconnect(my_ssh_session);
@@ -456,7 +456,7 @@ might be recoverable. SSH_FATAL means the connection has an important
problem and isn't probably recoverable. problem and isn't probably recoverable.
Most of time, the error returned are SSH_FATAL, but some functions Most of time, the error returned are SSH_FATAL, but some functions
(generaly the ssh_request_xxx ones) may fail because of server denying request. (generally the ssh_request_xxx ones) may fail because of server denying request.
In these cases, SSH_REQUEST_DENIED is returned. In these cases, SSH_REQUEST_DENIED is returned.
For thread safety, errors are bound to ssh_session objects. For thread safety, errors are bound to ssh_session objects.

View File

@@ -12,13 +12,13 @@ mean that you should not try to know about and understand these details.
libssh is a Free Software / Open Source project. The libssh library libssh is a Free Software / Open Source project. The libssh library
is distributed under LGPL license. The libssh project has nothing to do with is distributed under LGPL license. The libssh project has nothing to do with
"libssh2", which is a completly different and independant project. "libssh2", which is a completely different and independent project.
libssh can run on top of either libgcrypt or libcrypto, libssh can run on top of either libgcrypt or libcrypto,
two general-purpose cryptographic libraries. two general-purpose cryptographic libraries.
This tutorial concentrates for its main part on the "client" side of libssh. This tutorial concentrates for its main part on the "client" side of libssh.
To learn how to accept incoming SSH connexions (how to write a SSH server), To learn how to accept incoming SSH connections (how to write a SSH server),
you'll have to jump to the end of this document. you'll have to jump to the end of this document.
This tutorial describes libssh version 0.5.0. This version is a little different This tutorial describes libssh version 0.5.0. This version is a little different

View File

@@ -20,11 +20,11 @@ the interesting functions as you go.
The libssh library provides: The libssh library provides:
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1 - <strong>Key Exchange Methods</strong>: <i>curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <strong>Hostkey Types</strong>: <i>ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521</i>, ssh-dss, ssh-rsa - <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256,ssh-dss
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none - <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none - <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512, hmac-md5, none - <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512, hmac-md5, none
- <strong>Authentication</strong>: none, password, public-key, hostbased, keyboard-interactive, <i>gssapi-with-mic</i> - <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i> - <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip - <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
- <strong>Channel Requests</strong>: x11, pty, <i>exit-status, signal, exit-signal, keepalive@openssh.com, auth-agent-req@openssh.com</i> - <strong>Channel Requests</strong>: x11, pty, <i>exit-status, signal, exit-signal, keepalive@openssh.com, auth-agent-req@openssh.com</i>

View File

@@ -2,7 +2,7 @@
@page libssh_tutor_scp Chapter 6: The SCP subsystem @page libssh_tutor_scp Chapter 6: The SCP subsystem
@section scp_subsystem The SCP subsystem @section scp_subsystem The SCP subsystem
The SCP subsystem has far less functionnality than the SFTP subsystem. The SCP subsystem has far less functionality than the SFTP subsystem.
However, if you only need to copy files from and to the remote system, However, if you only need to copy files from and to the remote system,
it does its job. it does its job.
@@ -210,7 +210,7 @@ int scp_receive(ssh_session session, ssh_scp scp)
size = ssh_scp_request_get_size(scp); size = ssh_scp_request_get_size(scp);
filename = strdup(ssh_scp_request_get_filename(scp)); filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp); mode = ssh_scp_request_get_permissions(scp);
printf("Receiving file %s, size %d, permisssions 0%o\n", printf("Receiving file %s, size %d, permissions 0%o\n",
filename, size, mode); filename, size, mode);
free(filename); free(filename);

View File

@@ -100,7 +100,7 @@ Possible errors are:
@subsection sftp_mkdir Creating a directory @subsection sftp_mkdir Creating a directory
The function sftp_mkdir() tahes the "SFTP session" we juste created as The function sftp_mkdir() takes the "SFTP session" we just created as
its first argument. It also needs the name of the file to create, and the its first argument. It also needs the name of the file to create, and the
desired permissions. The permissions are the same as for the usual mkdir() desired permissions. The permissions are the same as for the usual mkdir()
function. To get a comprehensive list of the available permissions, use the function. To get a comprehensive list of the available permissions, use the
@@ -363,14 +363,14 @@ They use a new handle_type, "sftp_dir", which gives access to the
directory being read. directory being read.
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
to a structure with informations about a directory entry: to a structure with information about a directory entry:
- name: the name of the file or directory - name: the name of the file or directory
- size: its size in bytes - size: its size in bytes
- etc. - etc.
sftp_readdir() might return NULL under two conditions: sftp_readdir() might return NULL under two conditions:
- when the end of the directory has been met - when the end of the directory has been met
- when an error occured - when an error occurred
To tell the difference, call sftp_dir_eof(). To tell the difference, call sftp_dir_eof().

View File

@@ -245,7 +245,7 @@ provide a more elegant way to wait for data coming from many sources.
The functions ssh_select() and ssh_channel_select() remind of the standard The functions ssh_select() and ssh_channel_select() remind of the standard
UNIX select(2) function. The idea is to wait for "something" to happen: UNIX select(2) function. The idea is to wait for "something" to happen:
incoming data to be read, outcoming data to block, or an exception to incoming data to be read, outgoing data to block, or an exception to
occur. Both these functions do a "passive wait", i.e. you can safely use occur. Both these functions do a "passive wait", i.e. you can safely use
them repeatedly in a loop, it will not consume exaggerate processor time them repeatedly in a loop, it will not consume exaggerate processor time
and make your computer unresponsive. It is quite common to use these and make your computer unresponsive. It is quite common to use these

21
doc/that_style/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Jan-Lukas Wynen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

22
doc/that_style/README.md Normal file
View File

@@ -0,0 +1,22 @@
# that style
A plain, more modern HTML style for Doxygen
## Requirements
- Doxygen (tested with version 1.8.13)
- *optional*: a sass/scss compiler if you want to modify the style
## Simple usage
Tell Doxygen about the files for that style as shown in [doxyfile.conf](doxyfile.conf). You might need to adjust the
paths depending on where you installed that style.
When you run Doxygen, all files are copied into to generated HTML folder. So you don't need to keep the originals around
unless you want to re-generate the documentation.
## Advanced
that style uses a custom javascript to hack some nice stripes into some tables. It has to be loaded from HTML. Hence you need
to use the provided custom header. Since its default content may change when Doxygen is updated, there might be syntax error in
the generated HTML. If this is the case, you can remove the custom header (adjust your doxyfile.conf). This has no
disadvantages other than removing the stripes.
[that_style.css](that_style.css) was generated from the scss files in the folder [sass](sass). If you want to change the style,
use those files in order to have better control. For instance, you can easily change most colors by modifying the variables
in the beginning of [that_style.scss](sass/that_style.scss).

View File

@@ -0,0 +1,56 @@
<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
<script src="$relpath^striped_bg.js"></script>
$extrastylesheet
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
viewBox="0 0 6.3499999 5.8208335"
version="1.1"
id="svg8"
sodipodi:docname="doc.svg"
inkscape:version="0.92.1 r">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="11.139212"
inkscape:cy="14.811193"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:showpageshadow="false"
units="px"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.17915)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4d4d4d;stroke-width:0.26458329;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 3.315043,291.8406 H 1.4552083 v 4.49792 h 3.1749999 v -3.10055 z"
id="path5095"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 3.1837239,291.84114 v 1.71186 h 1.4472656 v -0.31418 H 3.4473958 v -1.39768 z"
id="path5128"
inkscape:connector-curvature="0" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect5132"
width="2.1166668"
height="0.26458332"
x="1.8520833"
y="293.82498" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect5136"
width="1.0583334"
height="0.26458332"
x="1.8520832"
y="294.35416" />
<rect
y="294.88333"
x="1.8520832"
height="0.26458332"
width="1.8520833"
id="rect5138"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4543"
width="1.5875"
height="0.26458332"
x="1.8520832"
y="295.41248" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
viewBox="0 0 6.3499998 5.8208335"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r"
sodipodi:docname="folderclosed.svg"
inkscape:export-filename="/home/jl/Prog/doxygen_style/folderclosed.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="51.113139"
inkscape:cx="7.7057751"
inkscape:cy="12.584171"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-global="false"
units="px"
inkscape:showpageshadow="false"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:measure-start="0,0"
inkscape:measure-end="0,0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.17915)">
<path
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 0.52916667,292.2374 -0.26458334,0.52925 v 3.43958 H 4.7625001 v -3.43958 H 2.38125 L 2.1166667,292.2374 Z"
id="rect4498"
sodipodi:nodetypes="cccccccc" />
<path
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.66145831;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 2.9104167,292.76665 2.38125,293.56034 H 0.26458333 v 0.26464 H 2.38125 l 0.5291667,-0.79375 h 1.8520834 v -0.26458 z"
id="rect4500"
sodipodi:nodetypes="ccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="22"
viewBox="0 0 6.3499998 5.8208335"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r"
sodipodi:docname="folderopen.svg"
inkscape:export-filename="/home/jl/Prog/doxygen_style/folderopen.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="43.725861"
inkscape:cx="8.2043861"
inkscape:cy="13.464183"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-global="false"
units="px"
inkscape:showpageshadow="false"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:measure-start="0,0"
inkscape:measure-end="0,0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.17915)">
<path
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.66145831;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 0.52916667,292.23748 -0.26458334,0.52917 v 3.43958 H 4.762461 l 7.8e-5,-3.43958 H 2.38125 l -0.2645833,-0.52917 z"
id="path5228"
sodipodi:nodetypes="cccccccc" />
<path
inkscape:connector-curvature="0"
id="path5279"
d="M 1.0583333,293.5604 H 5.55625 L 4.7625,296.20603 H 0.26458333 Z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.66145831;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path5234"
d="M 1.0583333,294.35415 H 3.175 l 0.5291667,-0.52917 H 5.55625 L 4.7625,296.20603 H 0.26458333 Z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.66145831;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="22"
height="22"
viewBox="0 0 5.8208332 5.8208335"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r"
sodipodi:docname="mag_glass.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="8.961936"
inkscape:cy="10.205344"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:showpageshadow="false"
inkscape:snap-bbox="false"
inkscape:bbox-nodes="true"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-global="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.17915)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 6.9101562 2.4082031 C 3.1105656 2.4082031 -5.9211895e-16 5.5081643 0 9.3027344 C 0 13.097342 3.1105656 16.197266 6.9101562 16.197266 C 8.2869348 16.197266 9.5698699 15.787508 10.650391 15.087891 L 15.162109 19.587891 L 16.636719 18.115234 L 12.214844 13.707031 C 13.214837 12.510659 13.818359 10.974238 13.818359 9.3027344 C 13.818359 5.5081643 10.709747 2.4082031 6.9101562 2.4082031 z M 6.9101562 4.9101562 C 9.3624717 4.9101562 11.324219 6.8631249 11.324219 9.3027344 C 11.324219 11.742382 9.3624717 13.695312 6.9101562 13.695312 C 4.4578408 13.695312 2.5019531 11.742382 2.5019531 9.3027344 C 2.5019531 6.8631249 4.4578408 4.9101562 6.9101562 4.9101562 z "
transform="matrix(0.26458333,0,0,0.26458333,0,291.17915)"
id="rect4524" />
<path
transform="matrix(0.99422295,0,0,0.68955299,-0.83134947,91.755588)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.63466448;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:transform-center-y="0.25905895"
d="m 5.6074138,294.49889 -1.0836583,-1.87695 2.1673165,0 z"
id="path4491" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="10.53333"
height="32"
viewBox="0 0 9.8749964 30"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
sodipodi:docname="nav_edge_inter.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="8.6823304"
inkscape:cy="16.225639"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:object-nodes="true"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1022.3622)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 0,1022.3622 v 15 15 l 8,-15 z"
id="path4143"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9375px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 1.2910156,1022.3496 -0.82421872,0.4473 7.87890622,14.5527 -7.87890622,14.5527 0.82421872,0.4473 8.1210938,-15 z"
id="path5240"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="8.5333338"
height="32"
viewBox="0 0 8.0000001 30"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
sodipodi:docname="nav_edge_left.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="5.3721385"
inkscape:cy="14.16429"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="false"
inkscape:snap-bbox-edge-midpoints="false"
inkscape:object-nodes="true"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1022.3622)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 0 0 L 0 32 L 8.5332031 16 L 0 0 z "
transform="matrix(0.93749998,0,0,0.93749998,0,1022.3622)"
id="rect4586" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 0,1022.3622 v 15 15 l 8,-15 z"
id="path4143"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="8"
height="30"
viewBox="0 0 8.0000001 30"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="nav_edge.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="5.3721385"
inkscape:cy="14.16429"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="false"
inkscape:snap-bbox-edge-midpoints="false"
inkscape:object-nodes="true"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1022.3622)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 0,1022.3622 0,15 0,15 8,-15 -8,-15 z"
id="path4143"
inkscape:connector-curvature="0" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 1e-8,1022.3622 7.99999999,15 0,-15 -8,0 z m 7.99999999,15 -8,15 8,0 0,-15 z"
id="rect4136"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="6"
height="9"
viewBox="0 0 1.5875 2.3812501"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r"
sodipodi:docname="splitbar_handle.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="8.7681488"
inkscape:cy="-2.7929517"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:showpageshadow="false"
showguides="false"
inkscape:window-width="2560"
inkscape:window-height="1357"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid4487" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-294.61873)">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4485"
width="0.26458335"
height="0.26458332"
x="0.26458332"
y="294.8833" />
<rect
y="294.8833"
x="1.0583333"
height="0.26458332"
width="0.26458335"
id="rect4489"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
y="295.41248"
x="0.26458329"
height="0.26458332"
width="0.26458335"
id="rect4491"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4493"
width="0.26458335"
height="0.26458332"
x="1.0583333"
y="295.41248" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4495"
width="0.26458335"
height="0.26458332"
x="0.26458332"
y="295.94165" />
<rect
y="295.94165"
x="1.0583333"
height="0.26458332"
width="0.26458335"
id="rect4497"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
y="296.47079"
x="0.26458329"
height="0.26458332"
width="0.26458335"
id="rect4499"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4501"
width="0.26458335"
height="0.26458332"
x="1.0583333"
y="296.47079" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View File

@@ -0,0 +1,32 @@
// Adds extra CSS classes "even" and "odd" to .memberdecls to allow
// striped backgrounds.
function MemberDeclsStriper () {
var counter = 0;
this.stripe = function() {
$(".memberdecls tbody").children().each(function(i) {
// reset counter at every heading -> always start with even
if ($(this).is(".heading")) {
counter = 0;
}
// add extra classes
if (counter % 2 == 1) {
$(this).addClass("odd");
}
else {
$(this).addClass("even");
}
// advance counter at every separator
// this is the only way to reliably detect which table rows belong together
if ($(this).is('[class^="separator"]')) {
counter++;
}
});
}
}
// execute the function
$(document).ready(new MemberDeclsStriper().stripe);

File diff suppressed because it is too large Load Diff

View File

@@ -3,14 +3,15 @@
@section threads_with_libssh How to use libssh with threads @section threads_with_libssh How to use libssh with threads
libssh may be used in multithreaded applications, but under several conditions : libssh may be used in multithreaded applications, but under several conditions :
- Threading must be initialized during the initialization of libssh. This - Your system must support libpthread or, in Windows environment,
initialization must be done outside of any threading context. CriticalSection based mutex control.
- If pthreads is being used by your application (or your framework's backend), - Since version 0.8.0, threads initialization is called automatically in the
you must link with libssh_threads dynamic library and initialize library constructor if libssh is dynamically linked. This means it is no
threading with the ssh_threads_pthreads threading object. longer necessary to call ssh_init()/ssh_finalize().
- If an other threading library is being used by your application, you must - If libssh is statically linked, threading must be initialized by calling
implement all the methods of the ssh_threads_callbacks_struct structure ssh_init() before using any of libssh provided functions. This initialization
and initialize libssh with it. must be done outside of any threading context. Don't forget to call
ssh_finalize() to avoid memory leak
- At all times, you may use different sessions inside threads, make parallel - At all times, you may use different sessions inside threads, make parallel
connections, read/write on different sessions and so on. You *cannot* use a connections, read/write on different sessions and so on. You *cannot* use a
single session (or channels for a single session) in several threads at the same single session (or channels for a single session) in several threads at the same
@@ -19,48 +20,33 @@ libssh may be used in multithreaded applications, but under several conditions :
@subsection threads_init Initialization of threads @subsection threads_init Initialization of threads
To initialize threading, you must first select the threading model you want to Since version 0.8.0, it is no longer necessary to call ssh_init()/ssh_finalize()
use, using ssh_threads_set_callbacks(), then call ssh_init(). if libssh is dynamically linked.
@code If libssh is statically linked, call ssh_init() before using any of libssh
#include <libssh/callbacks.h> provided functions.
...
ssh_threads_set_callbacks(ssh_threads_get_noop());
ssh_init();
@endcode
ssh_threads_noop is the threading structure that does nothing. It's the
threading callbacks being used by default when you're not using threading.
@subsection threads_pthread Using libpthread with libssh @subsection threads_pthread Using libpthread with libssh
If your application is using libpthread, you may simply use the libpthread Since version 0.8.0, libpthread is the default threads library used by libssh.
threading backend:
@code To use libpthread, simply link it to you application.
#include <libssh/callbacks.h>
...
ssh_threads_set_callbacks(ssh_threads_get_pthread());
ssh_init();
@endcode
However, you must be sure to link with the library ssh_threads. If
you're using gcc, you must use the commandline
@code
gcc -o output input.c -lssh -lssh_threads
@endcode
If you are using libssh statically linked, don't forget to call ssh_init()
before using any of libssh provided functions (and ssh_finalize() in the end).
@subsection threads_other Using another threading library @subsection threads_other Using another threading library
You must find your way in the ssh_threads_callbacks_struct structure. You must Since version 0.8.0, libssh does not support custom threading libraries.
implement the following methods : The change makes sense since the newer versions for libcrypto (OpenSSL) and
- mutex_lock libgcrypt don't support custom threading libraries.
- mutex_unlock
- mutex_init The default used threading library is libpthread.
- mutex_destroy Alternatively, in Windows environment, CriticalSection based mutex control can
- thread_id be used.
If your system does not support libpthread nor CriticalSection based mutex
control, unfortunately, you cannot use libssh in multithreaded scenarios.
libgcrypt 1.6 and bigger backend does not support custom callback. Using anything else than pthreads (ssh_threads_get_pthread()) here will fail.
Good luck ! Good luck !
*/ */

View File

@@ -17,46 +17,57 @@ endif()
if (UNIX AND NOT WIN32) if (UNIX AND NOT WIN32)
add_executable(libssh_scp libssh_scp.c ${examples_SRCS}) add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
target_compile_options(libssh_scp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
add_executable(scp_download scp_download.c ${examples_SRCS}) add_executable(scp_download scp_download.c ${examples_SRCS})
target_compile_options(scp_download PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
add_executable(sshnetcat sshnetcat.c ${examples_SRCS}) add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
target_compile_options(sshnetcat PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
if (WITH_SFTP) if (WITH_SFTP)
add_executable(samplesftp samplesftp.c ${examples_SRCS}) add_executable(samplesftp samplesftp.c ${examples_SRCS})
target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
endif (WITH_SFTP) endif (WITH_SFTP)
add_executable(ssh-client ssh_client.c ${examples_SRCS}) add_executable(ssh-client ssh_client.c ${examples_SRCS})
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY})
if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H)) if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H))
if (HAVE_LIBUTIL) if (HAVE_LIBUTIL)
add_executable(ssh_server_fork ssh_server_fork.c) add_executable(ssh_server_fork ssh_server_fork.c)
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util) target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util)
endif (HAVE_LIBUTIL) endif (HAVE_LIBUTIL)
if (WITH_GSSAPI AND GSSAPI_FOUND) if (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-cb samplesshd-cb.c) add_executable(samplesshd-cb samplesshd-cb.c)
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY}) target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
add_executable(proxy proxy.c) add_executable(proxy proxy.c)
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY}) target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
endif (WITH_GSSAPI AND GSSAPI_FOUND) endif (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-kbdint samplesshd-kbdint.c) add_executable(samplesshd-kbdint samplesshd-kbdint.c)
target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY}) target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
endif() endif()
endif (UNIX AND NOT WIN32) endif (UNIX AND NOT WIN32)
add_executable(exec exec.c ${examples_SRCS}) add_executable(exec exec.c ${examples_SRCS})
target_compile_options(exec PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
add_executable(senddata senddata.c ${examples_SRCS}) add_executable(senddata senddata.c ${examples_SRCS})
target_compile_options(senddata PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY}) target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY})
add_executable(libsshpp libsshpp.cpp) add_executable(libsshpp libsshpp.cpp)

View File

@@ -24,7 +24,8 @@ clients must be made or how a client should react.
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include "examples_common.h" #include "examples_common.h"
int authenticate_kbdint(ssh_session session, const char *password) { int authenticate_kbdint(ssh_session session, const char *password)
{
int err; int err;
err = ssh_userauth_kbdint(session, NULL, NULL); err = ssh_userauth_kbdint(session, NULL, NULL);
@@ -99,78 +100,80 @@ int authenticate_kbdint(ssh_session session, const char *password) {
return err; return err;
} }
static void error(ssh_session session){ static void error(ssh_session session)
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session)); {
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
} }
int authenticate_console(ssh_session session){ int authenticate_console(ssh_session session)
int rc; {
int method; int rc;
char password[128] = {0}; int method;
char *banner; char password[128] = {0};
char *banner;
// Try to authenticate
rc = ssh_userauth_none(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
}
method = ssh_userauth_list(session, NULL);
while (rc != SSH_AUTH_SUCCESS) {
if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
rc = ssh_userauth_gssapi(session);
if(rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
// Try to authenticate with public key first
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
// Try to authenticate with keyboard interactive";
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
rc = authenticate_kbdint(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
return SSH_AUTH_ERROR;
}
// Try to authenticate with password
if (method & SSH_AUTH_METHOD_PASSWORD) {
rc = ssh_userauth_password(session, NULL, password);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
memset(password, 0, sizeof(password));
}
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n",banner);
ssh_string_free_char(banner);
}
// Try to authenticate
rc = ssh_userauth_none(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc; return rc;
}
method = ssh_userauth_list(session, NULL);
while (rc != SSH_AUTH_SUCCESS) {
if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
rc = ssh_userauth_gssapi(session);
if(rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
// Try to authenticate with public key first
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
// Try to authenticate with keyboard interactive";
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
rc = authenticate_kbdint(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
return SSH_AUTH_ERROR;
}
// Try to authenticate with password
if (method & SSH_AUTH_METHOD_PASSWORD) {
rc = ssh_userauth_password(session, NULL, password);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
memset(password, 0, sizeof(password));
}
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n",banner);
ssh_string_free_char(banner);
}
return rc;
} }

View File

@@ -14,6 +14,10 @@ clients must be made or how a client should react.
#define EXAMPLES_COMMON_H_ #define EXAMPLES_COMMON_H_
#include <libssh/libssh.h> #include <libssh/libssh.h>
/** Zero a structure */
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
int authenticate_console(ssh_session session); int authenticate_console(ssh_session session);
int authenticate_kbdint(ssh_session session, const char *password); int authenticate_kbdint(ssh_session session, const char *password);
int verify_knownhost(ssh_session session); int verify_knownhost(ssh_session session);

View File

@@ -32,83 +32,86 @@ clients must be made or how a client should react.
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
#endif #endif
int verify_knownhost(ssh_session session){ int verify_knownhost(ssh_session session)
char *hexa; {
enum ssh_known_hosts_e state; enum ssh_known_hosts_e state;
char buf[10]; char buf[10];
unsigned char *hash = NULL; unsigned char *hash = NULL;
size_t hlen; size_t hlen;
ssh_key srv_pubkey; ssh_key srv_pubkey;
int rc; int rc;
rc = ssh_get_server_publickey(session, &srv_pubkey); rc = ssh_get_server_publickey(session, &srv_pubkey);
if (rc < 0) { if (rc < 0) {
return -1; return -1;
} }
rc = ssh_get_publickey_hash(srv_pubkey, rc = ssh_get_publickey_hash(srv_pubkey,
SSH_PUBLICKEY_HASH_SHA1, SSH_PUBLICKEY_HASH_SHA256,
&hash, &hash,
&hlen); &hlen);
ssh_key_free(srv_pubkey); ssh_key_free(srv_pubkey);
if (rc < 0) { if (rc < 0) {
return -1; return -1;
} }
state = ssh_session_is_known_server(session); state = ssh_session_is_known_server(session);
switch(state){ switch(state) {
case SSH_KNOWN_HOSTS_OK:
break; /* ok */
case SSH_KNOWN_HOSTS_CHANGED: case SSH_KNOWN_HOSTS_CHANGED:
fprintf(stderr,"Host key for server changed : server's one is now :\n"); fprintf(stderr,"Host key for server changed : server's one is now :\n");
ssh_print_hexa("Public key hash",hash, hlen); ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
ssh_clean_pubkey_hash(&hash); ssh_clean_pubkey_hash(&hash);
fprintf(stderr,"For security reason, connection will be stopped\n"); fprintf(stderr,"For security reason, connection will be stopped\n");
return -1; return -1;
case SSH_KNOWN_HOSTS_OTHER: case SSH_KNOWN_HOSTS_OTHER:
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n"); fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
fprintf(stderr,"An attacker might change the default server key to confuse your client" fprintf(stderr,"An attacker might change the default server key to confuse your client"
"into thinking the key does not exist\n" "into thinking the key does not exist\n"
"We advise you to rerun the client with -d or -r for more safety.\n"); "We advise you to rerun the client with -d or -r for more safety.\n");
return -1; return -1;
case SSH_KNOWN_HOSTS_NOT_FOUND: case SSH_KNOWN_HOSTS_NOT_FOUND:
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n"); 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"); fprintf(stderr,"the file will be automatically created.\n");
/* fallback to SSH_SERVER_NOT_KNOWN behavior */ /* fallback to SSH_SERVER_NOT_KNOWN behavior */
FALL_THROUGH; FALL_THROUGH;
case SSH_SERVER_NOT_KNOWN: case SSH_SERVER_NOT_KNOWN:
hexa = ssh_get_hexa(hash, hlen); fprintf(stderr,
fprintf(stderr,"The server is unknown. Do you trust the host key ?\n"); "The server is unknown. Do you trust the host key (yes/no)?\n");
fprintf(stderr, "Public key hash: %s\n", hexa); ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
ssh_string_free_char(hexa);
if (fgets(buf, sizeof(buf), stdin) == NULL) {
ssh_clean_pubkey_hash(&hash);
return -1;
}
if(strncasecmp(buf,"yes",3)!=0){
ssh_clean_pubkey_hash(&hash);
return -1;
}
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
if (fgets(buf, sizeof(buf), stdin) == NULL) {
ssh_clean_pubkey_hash(&hash);
return -1;
}
if(strncasecmp(buf,"yes",3)==0){
if (ssh_write_knownhost(session) < 0) {
ssh_clean_pubkey_hash(&hash);
fprintf(stderr, "error %s\n", strerror(errno));
return -1;
}
}
break; if (fgets(buf, sizeof(buf), stdin) == NULL) {
ssh_clean_pubkey_hash(&hash);
return -1;
}
if(strncasecmp(buf,"yes",3)!=0){
ssh_clean_pubkey_hash(&hash);
return -1;
}
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
if (fgets(buf, sizeof(buf), stdin) == NULL) {
ssh_clean_pubkey_hash(&hash);
return -1;
}
if(strncasecmp(buf,"yes",3)==0){
rc = ssh_session_update_known_hosts(session);
if (rc != SSH_OK) {
ssh_clean_pubkey_hash(&hash);
fprintf(stderr, "error %s\n", strerror(errno));
return -1;
}
}
break;
case SSH_KNOWN_HOSTS_ERROR: case SSH_KNOWN_HOSTS_ERROR:
ssh_clean_pubkey_hash(&hash); ssh_clean_pubkey_hash(&hash);
fprintf(stderr,"%s",ssh_get_error(session)); fprintf(stderr,"%s",ssh_get_error(session));
return -1; return -1;
} case SSH_KNOWN_HOSTS_OK:
ssh_clean_pubkey_hash(&hash); break; /* ok */
return 0; }
ssh_clean_pubkey_hash(&hash);
return 0;
} }

View File

@@ -25,148 +25,230 @@ program.
static char **sources; static char **sources;
static int nsources; static int nsources;
static char *destination; static char *destination;
static int verbosity=0; static int verbosity = 0;
struct location { struct location {
int is_ssh; int is_ssh;
char *user; char *user;
char *host; char *host;
char *path; char *path;
ssh_session session; ssh_session session;
ssh_scp scp; ssh_scp scp;
FILE *file; FILE *file;
}; };
enum { enum {
READ, READ,
WRITE WRITE
}; };
static void usage(const char *argv0){ static void usage(const char *argv0) {
fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n" fprintf(stderr, "Usage : %s [options] [[user@]host1:]file1 ... \n"
" [[user@]host2:]destination\n" " [[user@]host2:]destination\n"
"sample scp client - libssh-%s\n", "sample scp client - libssh-%s\n",
// "Options :\n", // "Options :\n",
// " -r : use RSA to verify host public key\n", // " -r : use RSA to verify host public key\n",
argv0, argv0,
ssh_version(0)); ssh_version(0));
exit(0); exit(0);
} }
static int opts(int argc, char **argv){ static int opts(int argc, char **argv) {
int i; int i;
while((i=getopt(argc,argv,"v"))!=-1){
switch(i){ while((i = getopt(argc, argv, "v")) != -1) {
case 'v': switch(i) {
verbosity++; case 'v':
break; verbosity++;
default: break;
fprintf(stderr,"unknown option %c\n",optopt); default:
fprintf(stderr, "unknown option %c\n", optopt);
usage(argv[0]);
return -1;
}
}
nsources = argc - optind - 1;
if (nsources < 1) {
usage(argv[0]); usage(argv[0]);
return -1; return -1;
} }
}
nsources=argc-optind-1; sources = malloc((nsources + 1) * sizeof(char *));
if(nsources < 1){ if (sources == NULL) {
usage(argv[0]); return -1;
return -1; }
}
sources=malloc((nsources + 1) * sizeof(char *)); for(i = 0; i < nsources; ++i) {
if(sources == NULL) sources[i] = argv[optind];
return -1; optind++;
for(i=0;i<nsources;++i){ }
sources[i] = argv[optind];
optind++; sources[i] = NULL;
} destination = argv[optind];
sources[i]=NULL; return 0;
destination=argv[optind];
return 0;
} }
static struct location *parse_location(char *loc){ static void location_free(struct location *loc)
struct location *location; {
char *ptr; if (loc) {
if (loc->path) {
free(loc->path);
}
loc->path = NULL;
if (loc->is_ssh) {
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
if (loc->user) {
free(loc->user);
}
loc->user = NULL;
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
}
free(loc);
}
}
location = malloc(sizeof(struct location)); static struct location *parse_location(char *loc) {
if (location == NULL) { struct location *location;
return NULL; char *ptr;
}
memset(location, 0, sizeof(struct location));
location->host=location->user=NULL; location = malloc(sizeof(struct location));
ptr=strchr(loc,':'); if (location == NULL) {
if(ptr != NULL){ return NULL;
location->is_ssh=1; }
location->path=strdup(ptr+1); memset(location, 0, sizeof(struct location));
*ptr='\0';
ptr=strchr(loc,'@'); location->host = location->user = NULL;
if(ptr != NULL){ ptr = strchr(loc, ':');
location->host=strdup(ptr+1);
*ptr='\0'; if (ptr != NULL) {
location->user=strdup(loc); location->is_ssh = 1;
location->path = strdup(ptr+1);
*ptr = '\0';
ptr = strchr(loc, '@');
if (ptr != NULL) {
location->host = strdup(ptr+1);
*ptr = '\0';
location->user = strdup(loc);
} else {
location->host = strdup(loc);
}
} else { } else {
location->host=strdup(loc); location->is_ssh = 0;
location->path = strdup(loc);
} }
} else { return location;
location->is_ssh=0;
location->path=strdup(loc);
}
return location;
} }
static int open_location(struct location *loc, int flag){ static void close_location(struct location *loc) {
if(loc->is_ssh && flag==WRITE){ int rc;
loc->session=connect_ssh(loc->host,loc->user,verbosity);
if(!loc->session){ if (loc) {
fprintf(stderr,"Couldn't connect to %s\n",loc->host); if (loc->is_ssh) {
return -1; if (loc->scp) {
rc = ssh_scp_close(loc->scp);
if (rc == SSH_ERROR) {
fprintf(stderr,
"Error closing scp: %s\n",
ssh_get_error(loc->session));
}
ssh_scp_free(loc->scp);
loc->scp = NULL;
}
if (loc->session) {
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
}
} else {
if (loc->file) {
fclose(loc->file);
loc->file = NULL;
}
}
} }
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path); }
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session)); static int open_location(struct location *loc, int flag) {
return -1; if (loc->is_ssh && flag == WRITE) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
return 0;
} else if (loc->is_ssh && flag == READ) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_READ, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
return 0;
} else {
loc->file = fopen(loc->path, flag == READ ? "r":"w");
if (!loc->file) {
if (errno == EISDIR) {
if (chdir(loc->path)) {
fprintf(stderr,
"Error changing directory to %s: %s\n",
loc->path, strerror(errno));
return -1;
}
return 0;
}
fprintf(stderr,
"Error opening %s: %s\n",
loc->path, strerror(errno));
return -1;
}
return 0;
} }
if(ssh_scp_init(loc->scp)==SSH_ERROR){ return -1;
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
return -1;
}
return 0;
} else if(loc->is_ssh && flag==READ){
loc->session=connect_ssh(loc->host, loc->user,verbosity);
if(!loc->session){
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
return -1;
}
loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path);
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
return -1;
}
if(ssh_scp_init(loc->scp)==SSH_ERROR){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
return -1;
}
return 0;
} else {
loc->file=fopen(loc->path,flag==READ ? "r":"w");
if(!loc->file){
if(errno==EISDIR){
if(chdir(loc->path)){
fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
return -1;
}
return 0;
}
fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
return -1;
}
return 0;
}
return -1;
} }
/** @brief copies files from source location to destination /** @brief copies files from source location to destination
@@ -174,155 +256,197 @@ static int open_location(struct location *loc, int flag){
* @param dest destination location * @param dest destination location
* @param recursive Copy also directories * @param recursive Copy also directories
*/ */
static int do_copy(struct location *src, struct location *dest, int recursive){ static int do_copy(struct location *src, struct location *dest, int recursive) {
int size; int size;
socket_t fd; socket_t fd;
struct stat s; struct stat s;
int w,r; int w, r;
char buffer[16384]; char buffer[16384];
int total=0; int total = 0;
int mode; int mode;
char *filename = NULL; char *filename = NULL;
/* recursive mode doesn't work yet */ /* recursive mode doesn't work yet */
(void)recursive; (void)recursive;
/* Get the file name and size*/ /* Get the file name and size*/
if(!src->is_ssh){ if (!src->is_ssh) {
fd = fileno(src->file); fd = fileno(src->file);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno)); fprintf(stderr,
return -1; "Invalid file pointer, error: %s\n",
} strerror(errno));
r = fstat(fd, &s); return -1;
if (r < 0) { }
return -1; r = fstat(fd, &s);
} if (r < 0) {
size=s.st_size; return -1;
mode = s.st_mode & ~S_IFMT; }
filename=ssh_basename(src->path); size = s.st_size;
} else { mode = s.st_mode & ~S_IFMT;
size=0; filename = ssh_basename(src->path);
do { } else {
r=ssh_scp_pull_request(src->scp); size = 0;
if(r==SSH_SCP_REQUEST_NEWDIR){ do {
ssh_scp_deny_request(src->scp,"Not in recursive mode"); r = ssh_scp_pull_request(src->scp);
continue; if (r == SSH_SCP_REQUEST_NEWDIR) {
} ssh_scp_deny_request(src->scp, "Not in recursive mode");
if(r==SSH_SCP_REQUEST_NEWFILE){ continue;
size=ssh_scp_request_get_size(src->scp); }
filename=strdup(ssh_scp_request_get_filename(src->scp)); if (r == SSH_SCP_REQUEST_NEWFILE) {
mode=ssh_scp_request_get_permissions(src->scp); size = ssh_scp_request_get_size(src->scp);
//ssh_scp_accept_request(src->scp); filename = strdup(ssh_scp_request_get_filename(src->scp));
break; mode = ssh_scp_request_get_permissions(src->scp);
} //ssh_scp_accept_request(src->scp);
if(r==SSH_ERROR){ break;
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session)); }
if (r == SSH_ERROR) {
fprintf(stderr,
"Error: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename); ssh_string_free_char(filename);
return -1; return -1;
} }
} while(r != SSH_SCP_REQUEST_NEWFILE); } while(r != SSH_SCP_REQUEST_NEWFILE);
} }
if(dest->is_ssh){ if (dest->is_ssh) {
r=ssh_scp_push_file(dest->scp,src->path, size, mode); r = ssh_scp_push_file(dest->scp, src->path, size, mode);
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path); // snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path);
if(r==SSH_ERROR){ if (r == SSH_ERROR) {
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session)); fprintf(stderr,
ssh_string_free_char(filename); "error: %s\n",
ssh_scp_free(dest->scp); ssh_get_error(dest->session));
dest->scp = NULL; ssh_string_free_char(filename);
return -1; ssh_scp_free(dest->scp);
} dest->scp = NULL;
} else { return -1;
if(!dest->file){ }
dest->file=fopen(filename,"w"); } else {
if(!dest->file){ if (!dest->file) {
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno)); dest->file = fopen(filename, "w");
if(src->is_ssh) if (!dest->file) {
ssh_scp_deny_request(src->scp,"Cannot open local file"); fprintf(stderr,
ssh_string_free_char(filename); "Cannot open %s for writing: %s\n",
return -1; filename, strerror(errno));
} if (src->is_ssh) {
} ssh_scp_deny_request(src->scp, "Cannot open local file");
if(src->is_ssh){ }
ssh_scp_accept_request(src->scp); ssh_string_free_char(filename);
} return -1;
} }
do { }
if(src->is_ssh){ if (src->is_ssh) {
r=ssh_scp_read(src->scp,buffer,sizeof(buffer)); ssh_scp_accept_request(src->scp);
if(r==SSH_ERROR){ }
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session)); }
ssh_string_free_char(filename);
return -1;
}
if(r==0)
break;
} else {
r=fread(buffer,1,sizeof(buffer),src->file);
if(r==0)
break;
if(r<0){
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if(dest->is_ssh){
w=ssh_scp_write(dest->scp,buffer,r);
if(w == SSH_ERROR){
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp=NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w=fwrite(buffer,r,1,dest->file);
if(w<=0){
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total+=r;
} while(total < size); do {
ssh_string_free_char(filename); if (src->is_ssh) {
printf("wrote %d bytes\n",total); r = ssh_scp_read(src->scp, buffer, sizeof(buffer));
return 0; if (r == SSH_ERROR) {
fprintf(stderr,
"Error reading scp: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
if (r == 0) {
break;
}
} else {
r = fread(buffer, 1, sizeof(buffer), src->file);
if (r == 0) {
break;
}
if (r < 0) {
fprintf(stderr,
"Error reading file: %s\n",
strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if (dest->is_ssh) {
w = ssh_scp_write(dest->scp, buffer, r);
if (w == SSH_ERROR) {
fprintf(stderr,
"Error writing in scp: %s\n",
ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp = NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w = fwrite(buffer, r, 1, dest->file);
if (w <= 0) {
fprintf(stderr,
"Error writing in local file: %s\n",
strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total += r;
} while(total < size);
ssh_string_free_char(filename);
printf("wrote %d bytes\n", total);
return 0;
} }
int main(int argc, char **argv){ int main(int argc, char **argv) {
struct location *dest, *src; struct location *dest, *src;
int i; int i;
int r; int r;
if(opts(argc,argv)<0) if (opts(argc, argv) < 0) {
return EXIT_FAILURE; r = EXIT_FAILURE;
dest=parse_location(destination); goto end;
if(open_location(dest,WRITE)<0)
return EXIT_FAILURE;
for(i=0;i<nsources;++i){
src=parse_location(sources[i]);
if(open_location(src,READ)<0){
return EXIT_FAILURE;
} }
if(do_copy(src,dest,0) < 0){
break; dest = parse_location(destination);
if (dest == NULL) {
r = EXIT_FAILURE;
goto end;
} }
}
if (dest->is_ssh && dest->scp != NULL) { if (open_location(dest, WRITE) < 0) {
r=ssh_scp_close(dest->scp); location_free(dest);
if(r == SSH_ERROR){ r = EXIT_FAILURE;
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session)); goto end;
ssh_scp_free(dest->scp); }
dest->scp=NULL;
return -1; for (i = 0; i < nsources; ++i) {
} src = parse_location(sources[i]);
} else { if (src == NULL) {
fclose(dest->file); r = EXIT_FAILURE;
dest->file=NULL; goto close_dest;
} }
ssh_disconnect(dest->session);
ssh_finalize(); if (open_location(src, READ) < 0) {
return 0; location_free(src);
r = EXIT_FAILURE;
goto close_dest;
}
if (do_copy(src, dest, 0) < 0) {
close_location(src);
location_free(src);
break;
}
close_location(src);
location_free(src);
}
r = 0;
close_dest:
close_location(dest);
location_free(dest);
end:
return r;
} }

View File

@@ -33,236 +33,259 @@ static int verbosity;
static char *destination; static char *destination;
#define DATALEN 65536 #define DATALEN 65536
static void do_sftp(ssh_session session){
sftp_session sftp=sftp_new(session); static void do_sftp(ssh_session session) {
sftp_session sftp = sftp_new(session);
sftp_dir dir; sftp_dir dir;
sftp_attributes file; sftp_attributes file;
sftp_statvfs_t sftpstatvfs; sftp_statvfs_t sftpstatvfs;
struct statvfs sysstatvfs; struct statvfs sysstatvfs;
sftp_file fichier; sftp_file fichier;
sftp_file to; sftp_file to;
int len=1; int len = 1;
unsigned int i; unsigned int i;
char data[DATALEN]={0}; char data[DATALEN] = {0};
char *lnk; char *lnk;
unsigned int count; unsigned int count;
if(!sftp){ if (!sftp) {
fprintf(stderr, "sftp error initialising channel: %s\n", fprintf(stderr, "sftp error initialising channel: %s\n",
ssh_get_error(session)); ssh_get_error(session));
return; goto end;
} }
if(sftp_init(sftp)){
if (sftp_init(sftp)) {
fprintf(stderr, "error initialising sftp: %s\n", fprintf(stderr, "error initialising sftp: %s\n",
ssh_get_error(session)); ssh_get_error(session));
return; goto end;
} }
printf("Additional SFTP extensions provided by the server:\n"); printf("Additional SFTP extensions provided by the server:\n");
count = sftp_extensions_get_count(sftp); count = sftp_extensions_get_count(sftp);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
printf("\t%s, version: %s\n", printf("\t%s, version: %s\n",
sftp_extensions_get_name(sftp, i), sftp_extensions_get_name(sftp, i),
sftp_extensions_get_data(sftp, i)); sftp_extensions_get_data(sftp, i));
} }
/* test symlink and readlink */ /* test symlink and readlink */
if (sftp_symlink(sftp, "/tmp/this_is_the_link", if (sftp_symlink(sftp, "/tmp/this_is_the_link",
"/tmp/sftp_symlink_test") < 0) { "/tmp/sftp_symlink_test") < 0)
fprintf(stderr, "Could not create link (%s)\n", ssh_get_error(session)); {
return; fprintf(stderr, "Could not create link (%s)\n",
ssh_get_error(session));
goto end;
} }
lnk = sftp_readlink(sftp, "/tmp/sftp_symlink_test"); lnk = sftp_readlink(sftp, "/tmp/sftp_symlink_test");
if (lnk == NULL) { if (lnk == NULL) {
fprintf(stderr, "Could not read link (%s)\n", ssh_get_error(session)); fprintf(stderr, "Could not read link (%s)\n", ssh_get_error(session));
return; goto end;
} }
printf("readlink /tmp/sftp_symlink_test: %s\n", lnk); printf("readlink /tmp/sftp_symlink_test: %s\n", lnk);
sftp_unlink(sftp, "/tmp/sftp_symlink_test"); sftp_unlink(sftp, "/tmp/sftp_symlink_test");
if (sftp_extension_supported(sftp, "statvfs@openssh.com", "2")) { if (sftp_extension_supported(sftp, "statvfs@openssh.com", "2")) {
sftpstatvfs = sftp_statvfs(sftp, "/tmp"); sftpstatvfs = sftp_statvfs(sftp, "/tmp");
if (sftpstatvfs == NULL) { if (sftpstatvfs == NULL) {
fprintf(stderr, "statvfs failed (%s)\n", ssh_get_error(session)); fprintf(stderr, "statvfs failed (%s)\n", ssh_get_error(session));
return; goto end;
} }
printf("sftp statvfs:\n" printf("sftp statvfs:\n"
"\tfile system block size: %llu\n" "\tfile system block size: %llu\n"
"\tfundamental fs block size: %llu\n" "\tfundamental fs block size: %llu\n"
"\tnumber of blocks (unit f_frsize): %llu\n" "\tnumber of blocks (unit f_frsize): %llu\n"
"\tfree blocks in file system: %llu\n" "\tfree blocks in file system: %llu\n"
"\tfree blocks for non-root: %llu\n" "\tfree blocks for non-root: %llu\n"
"\ttotal file inodes: %llu\n" "\ttotal file inodes: %llu\n"
"\tfree file inodes: %llu\n" "\tfree file inodes: %llu\n"
"\tfree file inodes for to non-root: %llu\n" "\tfree file inodes for to non-root: %llu\n"
"\tfile system id: %llu\n" "\tfile system id: %llu\n"
"\tbit mask of f_flag values: %llu\n" "\tbit mask of f_flag values: %llu\n"
"\tmaximum filename length: %llu\n", "\tmaximum filename length: %llu\n",
(unsigned long long) sftpstatvfs->f_bsize, (unsigned long long) sftpstatvfs->f_bsize,
(unsigned long long) sftpstatvfs->f_frsize, (unsigned long long) sftpstatvfs->f_frsize,
(unsigned long long) sftpstatvfs->f_blocks, (unsigned long long) sftpstatvfs->f_blocks,
(unsigned long long) sftpstatvfs->f_bfree, (unsigned long long) sftpstatvfs->f_bfree,
(unsigned long long) sftpstatvfs->f_bavail, (unsigned long long) sftpstatvfs->f_bavail,
(unsigned long long) sftpstatvfs->f_files, (unsigned long long) sftpstatvfs->f_files,
(unsigned long long) sftpstatvfs->f_ffree, (unsigned long long) sftpstatvfs->f_ffree,
(unsigned long long) sftpstatvfs->f_favail, (unsigned long long) sftpstatvfs->f_favail,
(unsigned long long) sftpstatvfs->f_fsid, (unsigned long long) sftpstatvfs->f_fsid,
(unsigned long long) sftpstatvfs->f_flag, (unsigned long long) sftpstatvfs->f_flag,
(unsigned long long) sftpstatvfs->f_namemax); (unsigned long long) sftpstatvfs->f_namemax);
sftp_statvfs_free(sftpstatvfs); sftp_statvfs_free(sftpstatvfs);
if (statvfs("/tmp", &sysstatvfs) < 0) { if (statvfs("/tmp", &sysstatvfs) < 0) {
fprintf(stderr, "statvfs failed (%s)\n", strerror(errno)); fprintf(stderr, "statvfs failed (%s)\n", strerror(errno));
return; goto end;
} }
printf("sys statvfs:\n" printf("sys statvfs:\n"
"\tfile system block size: %llu\n" "\tfile system block size: %llu\n"
"\tfundamental fs block size: %llu\n" "\tfundamental fs block size: %llu\n"
"\tnumber of blocks (unit f_frsize): %llu\n" "\tnumber of blocks (unit f_frsize): %llu\n"
"\tfree blocks in file system: %llu\n" "\tfree blocks in file system: %llu\n"
"\tfree blocks for non-root: %llu\n" "\tfree blocks for non-root: %llu\n"
"\ttotal file inodes: %llu\n" "\ttotal file inodes: %llu\n"
"\tfree file inodes: %llu\n" "\tfree file inodes: %llu\n"
"\tfree file inodes for to non-root: %llu\n" "\tfree file inodes for to non-root: %llu\n"
"\tfile system id: %llu\n" "\tfile system id: %llu\n"
"\tbit mask of f_flag values: %llu\n" "\tbit mask of f_flag values: %llu\n"
"\tmaximum filename length: %llu\n", "\tmaximum filename length: %llu\n",
(unsigned long long) sysstatvfs.f_bsize, (unsigned long long) sysstatvfs.f_bsize,
(unsigned long long) sysstatvfs.f_frsize, (unsigned long long) sysstatvfs.f_frsize,
(unsigned long long) sysstatvfs.f_blocks, (unsigned long long) sysstatvfs.f_blocks,
(unsigned long long) sysstatvfs.f_bfree, (unsigned long long) sysstatvfs.f_bfree,
(unsigned long long) sysstatvfs.f_bavail, (unsigned long long) sysstatvfs.f_bavail,
(unsigned long long) sysstatvfs.f_files, (unsigned long long) sysstatvfs.f_files,
(unsigned long long) sysstatvfs.f_ffree, (unsigned long long) sysstatvfs.f_ffree,
(unsigned long long) sysstatvfs.f_favail, (unsigned long long) sysstatvfs.f_favail,
(unsigned long long) sysstatvfs.f_fsid, (unsigned long long) sysstatvfs.f_fsid,
(unsigned long long) sysstatvfs.f_flag, (unsigned long long) sysstatvfs.f_flag,
(unsigned long long) sysstatvfs.f_namemax); (unsigned long long) sysstatvfs.f_namemax);
} }
/* the connection is made */ /* the connection is made */
/* opening a directory */ /* opening a directory */
dir=sftp_opendir(sftp,"./"); dir = sftp_opendir(sftp, "./");
if(!dir) { if (!dir) {
fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session)); fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session));
return ; goto end;
} }
/* reading the whole directory, file by file */ /* reading the whole directory, file by file */
while((file=sftp_readdir(sftp,dir))){ while ((file = sftp_readdir(sftp, dir))) {
fprintf(stderr, "%30s(%.8o) : %s(%.5d) %s(%.5d) : %.10llu bytes\n", fprintf(stderr, "%30s(%.8o) : %s(%.5d) %s(%.5d) : %.10llu bytes\n",
file->name, file->name,
file->permissions, file->permissions,
file->owner, file->owner,
file->uid, file->uid,
file->group, file->group,
file->gid, file->gid,
(long long unsigned int) file->size); (long long unsigned int) file->size);
sftp_attributes_free(file); sftp_attributes_free(file);
} }
/* when file=NULL, an error has occured OR the directory listing is end of file */
if(!sftp_dir_eof(dir)){ /* when file = NULL, an error has occured OR the directory listing is end of
* file */
if (!sftp_dir_eof(dir)) {
fprintf(stderr, "Error: %s\n", ssh_get_error(session)); fprintf(stderr, "Error: %s\n", ssh_get_error(session));
return; goto end;
} }
if(sftp_closedir(dir)){
if (sftp_closedir(dir)) {
fprintf(stderr, "Error: %s\n", ssh_get_error(session)); fprintf(stderr, "Error: %s\n", ssh_get_error(session));
return; goto end;
} }
/* this will open a file and copy it into your /home directory */ /* this will open a file and copy it into your /home directory */
/* the small buffer size was intended to stress the library. of course, you can use a buffer till 20kbytes without problem */ /* the small buffer size was intended to stress the library. of course, you
* can use a buffer till 20kbytes without problem */
fichier=sftp_open(sftp,"/usr/bin/ssh",O_RDONLY, 0); fichier = sftp_open(sftp, "/usr/bin/ssh", O_RDONLY, 0);
if(!fichier){ if (!fichier) {
fprintf(stderr, "Error opening /usr/bin/ssh: %s\n", fprintf(stderr, "Error opening /usr/bin/ssh: %s\n",
ssh_get_error(session)); ssh_get_error(session));
return; goto end;
} }
/* open a file for writing... */ /* open a file for writing... */
to=sftp_open(sftp,"ssh-copy",O_WRONLY | O_CREAT, 0700); to = sftp_open(sftp, "ssh-copy", O_WRONLY | O_CREAT, 0700);
if(!to){ if (!to) {
fprintf(stderr, "Error opening ssh-copy for writing: %s\n", fprintf(stderr, "Error opening ssh-copy for writing: %s\n",
ssh_get_error(session)); ssh_get_error(session));
return; sftp_close(fichier);
goto end;
} }
while((len=sftp_read(fichier,data,4096)) > 0){
if(sftp_write(to,data,len)!=len){ while ((len = sftp_read(fichier, data, 4096)) > 0) {
if (sftp_write(to, data, len) != len) {
fprintf(stderr, "Error writing %d bytes: %s\n", fprintf(stderr, "Error writing %d bytes: %s\n",
len, ssh_get_error(session)); len, ssh_get_error(session));
return; sftp_close(to);
sftp_close(fichier);
goto end;
} }
} }
printf("finished\n"); printf("finished\n");
if(len<0) if (len < 0) {
fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session)); fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session));
}
sftp_close(fichier); sftp_close(fichier);
sftp_close(to); sftp_close(to);
printf("fichiers ferm\n"); printf("fichiers ferm\n");
to=sftp_open(sftp,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644); to = sftp_open(sftp, "/tmp/grosfichier", O_WRONLY|O_CREAT, 0644);
for(i=0;i<1000;++i){
len=sftp_write(to,data,DATALEN); for (i = 0; i < 1000; ++i) {
printf("wrote %d bytes\n",len); len = sftp_write(to, data, DATALEN);
if(len != DATALEN){ printf("wrote %d bytes\n", len);
printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session)); if (len != DATALEN) {
printf("chunk %d : %d (%s)\n", i, len, ssh_get_error(session));
} }
} }
sftp_close(to);
sftp_close(to);
end:
/* close the sftp session */ /* close the sftp session */
sftp_free(sftp); sftp_free(sftp);
printf("sftp session terminated\n"); printf("sftp session terminated\n");
} }
static void usage(const char *argv0){ static void usage(const char *argv0) {
fprintf(stderr,"Usage : %s [-v] remotehost\n" fprintf(stderr, "Usage : %s [-v] remotehost\n"
"sample sftp test client - libssh-%s\n" "sample sftp test client - libssh-%s\n"
"Options :\n" "Options :\n"
" -v : increase log verbosity\n", " -v : increase log verbosity\n",
argv0, argv0,
ssh_version(0)); ssh_version(0));
exit(0); exit(0);
} }
static int opts(int argc, char **argv){ static int opts(int argc, char **argv) {
int i; int i;
while((i=getopt(argc,argv,"v"))!=-1){
switch(i){ while ((i = getopt(argc, argv, "v")) != -1) {
case 'v': switch(i) {
verbosity++; case 'v':
break; verbosity++;
default: break;
fprintf(stderr,"unknown option %c\n",optopt); default:
fprintf(stderr, "unknown option %c\n", optopt);
usage(argv[0]);
return -1;
}
}
destination = argv[optind];
if (destination == NULL) {
usage(argv[0]); usage(argv[0]);
return -1; return -1;
} }
} return 0;
destination=argv[optind];
if(destination == NULL){
usage(argv[0]);
return -1;
}
return 0;
} }
int main(int argc, char **argv){ int main(int argc, char **argv) {
ssh_session session; ssh_session session;
if(opts(argc,argv)<0)
return EXIT_FAILURE; if (opts(argc, argv) < 0) {
session=connect_ssh(destination,NULL,verbosity); return EXIT_FAILURE;
if(session == NULL) }
return EXIT_FAILURE;
do_sftp(session); session = connect_ssh(destination, NULL, verbosity);
ssh_disconnect(session); if (session == NULL) {
ssh_free(session); return EXIT_FAILURE;
return 0; }
do_sftp(session);
ssh_disconnect(session);
ssh_free(session);
return 0;
} }
#endif #endif

View File

@@ -23,6 +23,7 @@ clients must be made or how a client should react.
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#define SSHD_USER "libssh" #define SSHD_USER "libssh"
#define SSHD_PASSWORD "libssh" #define SSHD_PASSWORD "libssh"
@@ -36,6 +37,7 @@ clients must be made or how a client should react.
#endif #endif
static int port = 22; static int port = 22;
static bool authenticated = false;
#ifdef WITH_PCAP #ifdef WITH_PCAP
static const char *pcap_file = "debug.server.pcap"; static const char *pcap_file = "debug.server.pcap";
@@ -61,11 +63,20 @@ static void cleanup_pcap(void) {
#endif #endif
static int auth_password(const char *user, const char *password){ static int auth_password(const char *user, const char *password)
if(strcmp(user, SSHD_USER)) {
int cmp;
cmp = strcmp(user, SSHD_USER);
if (cmp != 0) {
return 0; return 0;
if(strcmp(password, SSHD_PASSWORD)) }
cmp = strcmp(password, SSHD_PASSWORD);
if (cmp != 0) {
return 0; return 0;
}
authenticated = true;
return 1; // authenticated return 1; // authenticated
} }
#ifdef HAVE_ARGP_H #ifdef HAVE_ARGP_H
@@ -200,6 +211,7 @@ static int kbdint_check_response(ssh_session session) {
return 0; return 0;
} }
authenticated = true;
return 1; return 1;
} }
@@ -328,7 +340,7 @@ int main(int argc, char **argv){
/* proceed to authentication */ /* proceed to authentication */
auth = authenticate(session); auth = authenticate(session);
if(!auth){ if (!auth || !authenticated) {
printf("Authentication error: %s\n", ssh_get_error(session)); printf("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session); ssh_disconnect(session);
return 1; return 1;

View File

@@ -48,12 +48,17 @@ static char *user;
static char *cmds[MAXCMD]; static char *cmds[MAXCMD];
static struct termios terminal; static struct termios terminal;
static char *pcap_file=NULL; static char *pcap_file = NULL;
static char *proxycommand; static char *proxycommand;
static int auth_callback(const char *prompt, char *buf, size_t len, static int auth_callback(const char *prompt,
int echo, int verify, void *userdata) { char *buf,
size_t len,
int echo,
int verify,
void *userdata)
{
(void) verify; (void) verify;
(void) userdata; (void) userdata;
@@ -61,11 +66,12 @@ static int auth_callback(const char *prompt, char *buf, size_t len,
} }
struct ssh_callbacks_struct cb = { struct ssh_callbacks_struct cb = {
.auth_function=auth_callback, .auth_function = auth_callback,
.userdata=NULL .userdata = NULL,
}; };
static void add_cmd(char *cmd){ static void add_cmd(char *cmd)
{
int n; int n;
for (n = 0; (n < MAXCMD) && cmds[n] != NULL; n++); for (n = 0; (n < MAXCMD) && cmds[n] != NULL; n++);
@@ -73,7 +79,8 @@ static void add_cmd(char *cmd){
if (n == MAXCMD) { if (n == MAXCMD) {
return; return;
} }
cmds[n]=strdup(cmd);
cmds[n] = strdup(cmd);
} }
static void usage(void) static void usage(void)
@@ -98,37 +105,43 @@ static void usage(void)
exit(0); exit(0);
} }
static int opts(int argc, char **argv){ static int opts(int argc, char **argv)
{
int i; int i;
// for(i=0;i<argc;i++)
// printf("%d : %s\n",i,argv[i]); while((i = getopt(argc,argv,"T:P:")) != -1) {
/* insert your own arguments here */
while((i=getopt(argc,argv,"T:P:"))!=-1){
switch(i){ switch(i){
case 'P': case 'P':
pcap_file=optarg; pcap_file = optarg;
break; break;
#ifndef _WIN32 #ifndef _WIN32
case 'T': case 'T':
proxycommand=optarg; proxycommand = optarg;
break; break;
#endif #endif
default: default:
fprintf(stderr,"unknown option %c\n",optopt); fprintf(stderr, "Unknown option %c\n", optopt);
usage(); usage();
} }
} }
if(optind < argc) if (optind < argc) {
host=argv[optind++]; host = argv[optind++];
while(optind < argc) }
while(optind < argc) {
add_cmd(argv[optind++]); add_cmd(argv[optind++]);
if(host==NULL) }
if (host == NULL) {
usage(); usage();
}
return 0; return 0;
} }
#ifndef HAVE_CFMAKERAW #ifndef HAVE_CFMAKERAW
static void cfmakeraw(struct termios *termios_p){ static void cfmakeraw(struct termios *termios_p)
{
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST; termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
@@ -138,44 +151,53 @@ static void cfmakeraw(struct termios *termios_p){
#endif #endif
static void do_cleanup(int i) { static void do_cleanup(int i)
{
/* unused variable */ /* unused variable */
(void) i; (void) i;
tcsetattr(0,TCSANOW,&terminal); tcsetattr(0, TCSANOW, &terminal);
} }
static void do_exit(int i) { static void do_exit(int i)
/* unused variable */ {
(void) i; /* unused variable */
(void) i;
do_cleanup(0); do_cleanup(0);
exit(0); exit(0);
} }
ssh_channel chan; static ssh_channel chan;
int signal_delayed=0; static int signal_delayed = 0;
static void sigwindowchanged(int i){ static void sigwindowchanged(int i)
(void) i; {
signal_delayed=1; (void) i;
signal_delayed = 1;
} }
static void setsignal(void){ static void setsignal(void)
{
signal(SIGWINCH, sigwindowchanged); signal(SIGWINCH, sigwindowchanged);
signal_delayed=0; signal_delayed = 0;
} }
static void sizechanged(void){ static void sizechanged(void)
struct winsize win = { 0, 0, 0, 0 }; {
struct winsize win = {
.ws_row = 0,
};
ioctl(1, TIOCGWINSZ, &win); ioctl(1, TIOCGWINSZ, &win);
ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row); ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row);
// printf("Changed pty size\n");
setsignal(); setsignal();
} }
static void select_loop(ssh_session session,ssh_channel channel){ static void select_loop(ssh_session session,ssh_channel channel)
{
ssh_connector connector_in, connector_out, connector_err; ssh_connector connector_in, connector_out, connector_err;
ssh_event event = ssh_event_new(); ssh_event event = ssh_event_new();
/* stdin */ /* stdin */
@@ -196,9 +218,10 @@ static void select_loop(ssh_session session,ssh_channel channel){
ssh_connector_set_in_channel(connector_err, channel, SSH_CONNECTOR_STDERR); ssh_connector_set_in_channel(connector_err, channel, SSH_CONNECTOR_STDERR);
ssh_event_add_connector(event, connector_err); ssh_event_add_connector(event, connector_err);
while(ssh_channel_is_open(channel)){ while (ssh_channel_is_open(channel)) {
if(signal_delayed) if (signal_delayed) {
sizechanged(); sizechanged();
}
ssh_event_dopoll(event, 60000); ssh_event_dopoll(event, 60000);
} }
ssh_event_remove_connector(event, connector_in); ssh_event_remove_connector(event, connector_in);
@@ -213,121 +236,148 @@ static void select_loop(ssh_session session,ssh_channel channel){
ssh_channel_free(channel); ssh_channel_free(channel);
} }
static void shell(ssh_session session){ static void shell(ssh_session session)
{
ssh_channel channel; ssh_channel channel;
struct termios terminal_local; struct termios terminal_local;
int interactive=isatty(0); int interactive=isatty(0);
channel = ssh_channel_new(session); channel = ssh_channel_new(session);
if(interactive){
tcgetattr(0,&terminal_local); if (interactive) {
memcpy(&terminal,&terminal_local,sizeof(struct termios)); tcgetattr(0, &terminal_local);
memcpy(&terminal, &terminal_local, sizeof(struct termios));
} }
if(ssh_channel_open_session(channel)){
printf("error opening channel : %s\n",ssh_get_error(session)); if (ssh_channel_open_session(channel)) {
printf("Error opening channel : %s\n", ssh_get_error(session));
return; return;
} }
chan=channel; chan = channel;
if(interactive){ if (interactive) {
ssh_channel_request_pty(channel); ssh_channel_request_pty(channel);
sizechanged(); sizechanged();
} }
if(ssh_channel_request_shell(channel)){
printf("Requesting shell : %s\n",ssh_get_error(session)); if (ssh_channel_request_shell(channel)) {
printf("Requesting shell : %s\n", ssh_get_error(session));
return; return;
} }
if(interactive){
if (interactive) {
cfmakeraw(&terminal_local); cfmakeraw(&terminal_local);
tcsetattr(0,TCSANOW,&terminal_local); tcsetattr(0, TCSANOW, &terminal_local);
setsignal(); setsignal();
} }
signal(SIGTERM,do_cleanup); signal(SIGTERM, do_cleanup);
select_loop(session,channel); select_loop(session, channel);
if(interactive) if (interactive) {
do_cleanup(0); do_cleanup(0);
}
} }
static void batch_shell(ssh_session session){ static void batch_shell(ssh_session session)
{
ssh_channel channel; ssh_channel channel;
char buffer[1024]; char buffer[1024];
int i,s=0; size_t i;
for(i=0;i<MAXCMD && cmds[i];++i) { int s = 0;
s+=snprintf(buffer+s,sizeof(buffer)-s,"%s ",cmds[i]);
free(cmds[i]); for (i = 0; i < MAXCMD && cmds[i]; ++i) {
cmds[i] = NULL; s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
} free(cmds[i]);
channel=ssh_channel_new(session); cmds[i] = NULL;
}
channel = ssh_channel_new(session);
ssh_channel_open_session(channel); ssh_channel_open_session(channel);
if(ssh_channel_request_exec(channel,buffer)){ if (ssh_channel_request_exec(channel, buffer)) {
printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session)); printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
return; return;
} }
select_loop(session,channel); select_loop(session, channel);
} }
static int client(ssh_session session){ static int client(ssh_session session)
int auth=0; {
char *banner; int auth = 0;
int state; char *banner;
if (user) int state;
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0)
return -1;
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
return -1;
if (proxycommand != NULL){
if(ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand))
return -1;
}
ssh_options_parse_config(session, NULL);
if(ssh_connect(session)){ if (user) {
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session)); if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
return -1; return -1;
} }
state=verify_knownhost(session); }
if (state != 0) if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) {
return -1; return -1;
ssh_userauth_none(session, NULL); }
banner=ssh_get_issue_banner(session); if (proxycommand != NULL) {
if(banner){ if (ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand)) {
printf("%s\n",banner); return -1;
free(banner); }
} }
auth=authenticate_console(session); ssh_options_parse_config(session, NULL);
if(auth != SSH_AUTH_SUCCESS){
return -1; if (ssh_connect(session)) {
} fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
if(!cmds[0]) return -1;
shell(session); }
else
batch_shell(session); state = verify_knownhost(session);
return 0; if (state != 0) {
return -1;
}
ssh_userauth_none(session, NULL);
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n", banner);
free(banner);
}
auth = authenticate_console(session);
if (auth != SSH_AUTH_SUCCESS) {
return -1;
}
if (cmds[0] == NULL) {
shell(session);
} else {
batch_shell(session);
}
return 0;
} }
ssh_pcap_file pcap; static ssh_pcap_file pcap;
void set_pcap(ssh_session session); static void set_pcap(ssh_session session)
void set_pcap(ssh_session session){ {
if(!pcap_file) if (pcap_file == NULL) {
return; return;
pcap=ssh_pcap_file_new(); }
if(!pcap)
return; pcap = ssh_pcap_file_new();
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){ if (pcap == NULL) {
printf("Error opening pcap file\n"); return;
ssh_pcap_file_free(pcap); }
pcap=NULL;
return; if (ssh_pcap_file_open(pcap, pcap_file) == SSH_ERROR) {
} printf("Error opening pcap file\n");
ssh_set_pcap_file(session,pcap); ssh_pcap_file_free(pcap);
pcap = NULL;
return;
}
ssh_set_pcap_file(session, pcap);
} }
void cleanup_pcap(void); static void cleanup_pcap(void)
void cleanup_pcap(){ {
if(pcap) if (pcap != NULL) {
ssh_pcap_file_free(pcap); ssh_pcap_file_free(pcap);
pcap=NULL; }
pcap = NULL;
} }
int main(int argc, char **argv){ int main(int argc, char **argv)
{
ssh_session session; ssh_session session;
session = ssh_new(); session = ssh_new();
@@ -335,12 +385,13 @@ int main(int argc, char **argv){
ssh_callbacks_init(&cb); ssh_callbacks_init(&cb);
ssh_set_callbacks(session,&cb); ssh_set_callbacks(session,&cb);
if(ssh_options_getopt(session, &argc, argv)) { if (ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr, "error parsing command line :%s\n", fprintf(stderr,
ssh_get_error(session)); "Error parsing command line: %s\n",
usage(); ssh_get_error(session));
usage();
} }
opts(argc,argv); opts(argc, argv);
signal(SIGTERM, do_exit); signal(SIGTERM, do_exit);
set_pcap(session); set_pcap(session);

View File

@@ -472,7 +472,8 @@ static int process_stderr(socket_t fd, int revents, void *userdata) {
} }
static void handle_session(ssh_event event, ssh_session session) { static void handle_session(ssh_event event, ssh_session session) {
int n, rc; int n;
int rc = 0;
/* Structure for storing the pty size. */ /* Structure for storing the pty size. */
struct winsize wsize = { struct winsize wsize = {

View File

@@ -43,7 +43,8 @@ const char *port="22";
char *pcap_file=NULL; char *pcap_file=NULL;
#endif #endif
static void usage(){ static void usage(void)
{
fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n"); fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
exit(1); exit(1);
} }
@@ -89,6 +90,7 @@ static void select_loop(ssh_session session,ssh_channel channel){
do{ do{
int fd; int fd;
ZERO_STRUCT(fds);
FD_ZERO(&fds); FD_ZERO(&fds);
if(!eof) if(!eof)
FD_SET(0,&fds); FD_SET(0,&fds);

View File

@@ -66,6 +66,9 @@
#define SSH_COM_AGENT2_FAILURE 102 #define SSH_COM_AGENT2_FAILURE 102
#define SSH_AGENT_OLD_SIGNATURE 0x01 #define SSH_AGENT_OLD_SIGNATURE 0x01
/* Signature flags from draft-miller-ssh-agent-02 */
#define SSH_AGENT_RSA_SHA2_256 0x02
#define SSH_AGENT_RSA_SHA2_512 0x04
struct ssh_agent_struct { struct ssh_agent_struct {
struct ssh_socket_struct *sock; struct ssh_socket_struct *sock;

View File

@@ -76,6 +76,14 @@ enum ssh_auth_state_e {
SSH_AUTH_STATE_GSSAPI_TOKEN, SSH_AUTH_STATE_GSSAPI_TOKEN,
/** We have sent the MIC and expecting to be authenticated */ /** We have sent the MIC and expecting to be authenticated */
SSH_AUTH_STATE_GSSAPI_MIC_SENT, SSH_AUTH_STATE_GSSAPI_MIC_SENT,
/** We have offered a pubkey to check if it is supported */
SSH_AUTH_STATE_PUBKEY_OFFER_SENT,
/** We have sent pubkey and signature expecting to be authenticated */
SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
/** We have sent a password expecting to be authenticated */
SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
/** We have sent a request without auth information (method 'none') */
SSH_AUTH_STATE_AUTH_NONE_SENT,
}; };
/** @internal /** @internal

View File

@@ -24,20 +24,6 @@
#include <stdarg.h> #include <stdarg.h>
#include "libssh/libssh.h" #include "libssh/libssh.h"
/*
* Describes a buffer state
* [XXXXXXXXXXXXDATA PAYLOAD XXXXXXXXXXXXXXXXXXXXXXXX]
* ^ ^ ^ ^]
* \_data points\_pos points here \_used points here | /
* here Allocated
*/
struct ssh_buffer_struct {
char *data;
uint32_t used;
uint32_t allocated;
uint32_t pos;
int secure;
};
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3) #define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
@@ -54,11 +40,11 @@ void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len);
int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len); int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len);
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format, const char *format,
int argc, size_t argc,
va_list ap); va_list ap);
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer, int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
const char *format, const char *format,
int argc, size_t argc,
...); ...);
#define ssh_buffer_pack(buffer, format, ...) \ #define ssh_buffer_pack(buffer, format, ...) \
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END) _ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)

View File

@@ -0,0 +1,90 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2018 Andreas Schneider <asn@cryptomilk.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BYTEARRAY_H
#define _BYTEARRAY_H
#define _DATA_BYTE_CONST(data, pos) \
((uint8_t)(((const uint8_t *)(data))[(pos)]))
#define _DATA_BYTE(data, pos) \
(((uint8_t *)(data))[(pos)])
/*
* These macros pull or push integer values from byte arrays stored in
* little-endian byte order.
*/
#define PULL_LE_U8(data, pos) \
(_DATA_BYTE_CONST(data, pos))
#define PULL_LE_U16(data, pos) \
((uint16_t)PULL_LE_U8(data, pos) | ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8)
#define PULL_LE_U32(data, pos) \
((uint32_t)(PULL_LE_U16(data, pos) | ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16))
#define PULL_LE_U64(data, pos) \
((uint64_t)(PULL_LE_U32(data, pos) | ((uint64_t)PULL_LE_U32(data, (pos) + 4)) << 32))
#define PUSH_LE_U8(data, pos, val) \
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
#define PUSH_LE_U16(data, pos, val) \
(PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)), PUSH_LE_U8((data), (pos) + 1, (uint8_t)((uint16_t)(val) >> 8)))
#define PUSH_LE_U32(data, pos, val) \
(PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)), PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16)))
#define PUSH_LE_U64(data, pos, val) \
(PUSH_LE_U32((data), (pos), (uint32_t)((uint64_t)(val) & 0xffffffff)), PUSH_LE_U32((data), (pos) + 4, (uint32_t)((uint64_t)(val) >> 32)))
/*
* These macros pull or push integer values from byte arrays stored in
* big-endian byte order (network byte order).
*/
#define PULL_BE_U8(data, pos) \
(_DATA_BYTE_CONST(data, pos))
#define PULL_BE_U16(data, pos) \
((((uint16_t)(PULL_BE_U8(data, pos))) << 8) | (uint16_t)PULL_BE_U8(data, (pos) + 1))
#define PULL_BE_U32(data, pos) \
((((uint32_t)PULL_BE_U16(data, pos)) << 16) | (uint32_t)(PULL_BE_U16(data, (pos) + 2)))
#define PULL_BE_U64(data, pos) \
((((uint64_t)PULL_BE_U32(data, pos)) << 32) | (uint64_t)(PULL_BE_U32(data, (pos) + 4)))
#define PUSH_BE_U8(data, pos, val) \
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
#define PUSH_BE_U16(data, pos, val) \
(PUSH_BE_U8((data), (pos), (uint8_t)(((uint16_t)(val)) >> 8)), PUSH_BE_U8((data), (pos) + 1, (uint8_t)((val) & 0xff)))
#define PUSH_BE_U32(data, pos, val) \
(PUSH_BE_U16((data), (pos), (uint16_t)(((uint32_t)(val)) >> 16)), PUSH_BE_U16((data), (pos) + 2, (uint16_t)((val) & 0xffff)))
#define PUSH_BE_U64(data, pos, val) \
(PUSH_BE_U32((data), (pos), (uint32_t)(((uint64_t)(val)) >> 32)), PUSH_BE_U32((data), (pos) + 4, (uint32_t)((val) & 0xffffffff)))
#endif /* _BYTEARRAY_H */

View File

@@ -92,12 +92,15 @@ SSH_PACKET_CALLBACK(channel_rcv_close);
SSH_PACKET_CALLBACK(channel_rcv_request); SSH_PACKET_CALLBACK(channel_rcv_request);
SSH_PACKET_CALLBACK(channel_rcv_data); SSH_PACKET_CALLBACK(channel_rcv_data);
ssh_channel ssh_channel_new(ssh_session session);
int channel_default_bufferize(ssh_channel channel, void *data, int len, int channel_default_bufferize(ssh_channel channel, void *data, int len,
int is_stderr); int is_stderr);
int ssh_channel_flush(ssh_channel channel); int ssh_channel_flush(ssh_channel channel);
uint32_t ssh_channel_new_id(ssh_session session); uint32_t ssh_channel_new_id(ssh_session session);
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id); ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
void ssh_channel_do_free(ssh_channel channel); void ssh_channel_do_free(ssh_channel channel);
int ssh_global_request(ssh_session session,
const char *request,
ssh_buffer buffer,
int reply);
#endif /* CHANNELS_H_ */ #endif /* CHANNELS_H_ */

66
include/libssh/config.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* config.h - parse the ssh config file
*
* This file is part of the SSH Library
*
* Copyright (c) 2009-2018 by Andreas Schneider <asn@cryptomilk.org>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef LIBSSH_CONFIG_H_
#define LIBSSH_CONFIG_H_
enum ssh_config_opcode_e {
/* Unknown opcode */
SOC_UNKNOWN = -3,
/* Known and not applicable to libssh */
SOC_NA = -2,
/* Known but not supported by current libssh version */
SOC_UNSUPPORTED = -1,
SOC_HOST,
SOC_MATCH,
SOC_HOSTNAME,
SOC_PORT,
SOC_USERNAME,
SOC_IDENTITY,
SOC_CIPHERS,
SOC_MACS,
SOC_COMPRESSION,
SOC_TIMEOUT,
SOC_PROTOCOL,
SOC_STRICTHOSTKEYCHECK,
SOC_KNOWNHOSTS,
SOC_PROXYCOMMAND,
SOC_GSSAPISERVERIDENTITY,
SOC_GSSAPICLIENTIDENTITY,
SOC_GSSAPIDELEGATECREDENTIALS,
SOC_INCLUDE,
SOC_BINDADDRESS,
SOC_GLOBALKNOWNHOSTSFILE,
SOC_LOGLEVEL,
SOC_HOSTKEYALGORITHMS,
SOC_KEXALGORITHMS,
SOC_GSSAPIAUTHENTICATION,
SOC_KBDINTERACTIVEAUTHENTICATION,
SOC_PASSWORDAUTHENTICATION,
SOC_PUBKEYAUTHENTICATION,
SOC_PUBKEYACCEPTEDTYPES,
SOC_MAX /* Keep this one last in the list */
};
#endif /* LIBSSH_CONFIG_H_ */

View File

@@ -1,28 +0,0 @@
/*
* crc32.c - simple CRC32 code
*
* This file is part of the SSH Library
*
* Copyright (c) 2005 by Aris Adamantiadis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CRC32_H
#define _CRC32_H
uint32_t ssh_crc32(const char *buf, uint32_t len);
#endif /* _CRC32_H */

View File

@@ -29,6 +29,8 @@
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
#include <gcrypt.h> #include <gcrypt.h>
#elif defined(HAVE_LIBMBEDCRYPTO)
#include <mbedtls/gcm.h>
#endif #endif
#include "libssh/wrapper.h" #include "libssh/wrapper.h"
@@ -48,6 +50,9 @@
#define DIGEST_MAX_LEN 64 #define DIGEST_MAX_LEN 64
#define AES_GCM_TAGLEN 16
#define AES_GCM_IVLEN 12
enum ssh_key_exchange_e { enum ssh_key_exchange_e {
/* diffie-hellman-group1-sha1 */ /* diffie-hellman-group1-sha1 */
SSH_KEX_DH_GROUP1_SHA1=1, SSH_KEX_DH_GROUP1_SHA1=1,
@@ -62,7 +67,11 @@ enum ssh_key_exchange_e {
/* curve25519-sha256@libssh.org */ /* curve25519-sha256@libssh.org */
SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG, SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG,
/* curve25519-sha256 */ /* curve25519-sha256 */
SSH_KEX_CURVE25519_SHA256 SSH_KEX_CURVE25519_SHA256,
/* diffie-hellman-group16-sha512 */
SSH_KEX_DH_GROUP16_SHA512,
/* diffie-hellman-group18-sha512 */
SSH_KEX_DH_GROUP18_SHA512,
}; };
enum ssh_cipher_e { enum ssh_cipher_e {
@@ -74,7 +83,10 @@ enum ssh_cipher_e {
SSH_AES256_CBC, SSH_AES256_CBC,
SSH_AES128_CTR, SSH_AES128_CTR,
SSH_AES192_CTR, SSH_AES192_CTR,
SSH_AES256_CTR SSH_AES256_CTR,
SSH_AEAD_AES128_GCM,
SSH_AEAD_AES256_GCM,
SSH_AEAD_CHACHA20_POLY1305
}; };
struct ssh_crypto_struct { struct ssh_crypto_struct {
@@ -132,6 +144,7 @@ struct ssh_cipher_struct {
size_t keylen; /* length of the key structure */ size_t keylen; /* length of the key structure */
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
gcry_cipher_hd_t *key; gcry_cipher_hd_t *key;
unsigned char last_iv[AES_GCM_IVLEN];
#elif defined HAVE_LIBCRYPTO #elif defined HAVE_LIBCRYPTO
struct ssh_3des_key_schedule *des3_key; struct ssh_3des_key_schedule *des3_key;
struct ssh_aes_key_schedule *aes_key; struct ssh_aes_key_schedule *aes_key;
@@ -141,6 +154,10 @@ struct ssh_cipher_struct {
mbedtls_cipher_context_t encrypt_ctx; mbedtls_cipher_context_t encrypt_ctx;
mbedtls_cipher_context_t decrypt_ctx; mbedtls_cipher_context_t decrypt_ctx;
mbedtls_cipher_type_t type; mbedtls_cipher_type_t type;
#ifdef MBEDTLS_GCM_C
mbedtls_gcm_context gcm_ctx;
unsigned char last_iv[AES_GCM_IVLEN];
#endif /* MBEDTLS_GCM_C */
#endif #endif
struct chacha20_poly1305_keysched *chacha20_schedule; struct chacha20_poly1305_keysched *chacha20_schedule;
unsigned int keysize; /* bytes of key used. != keylen */ unsigned int keysize; /* bytes of key used. != keylen */
@@ -148,10 +165,14 @@ struct ssh_cipher_struct {
/* sets the new key for immediate use */ /* sets the new key for immediate use */
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV); int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV); int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out, void (*encrypt)(struct ssh_cipher_struct *cipher,
unsigned long len); void *in,
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out, void *out,
unsigned long len); size_t len);
void (*decrypt)(struct ssh_cipher_struct *cipher,
void *in,
void *out,
size_t len);
void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out, void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
size_t len, uint8_t *mac, uint64_t seq); size_t len, uint8_t *mac, uint64_t seq);
int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in, int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,

View File

@@ -43,6 +43,8 @@ char **ssh_space_tokenize(const char *chain);
int ssh_get_kex1(ssh_session session); int ssh_get_kex1(ssh_session session);
char *ssh_find_matching(const char *in_d, const char *what_d); char *ssh_find_matching(const char *in_d, const char *what_d);
const char *ssh_kex_get_supported_method(uint32_t algo); const char *ssh_kex_get_supported_method(uint32_t algo);
const char *ssh_kex_get_default_methods(uint32_t algo);
const char *ssh_kex_get_description(uint32_t algo); const char *ssh_kex_get_description(uint32_t algo);
char *ssh_client_select_hostkeys(ssh_session session);
#endif /* KEX_H_ */ #endif /* KEX_H_ */

View File

@@ -23,5 +23,9 @@
#define SSH_KNOWNHOSTS_H_ #define SSH_KNOWNHOSTS_H_
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session); struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry_file(ssh_session session,
const char *filename,
struct ssh_knownhosts_entry **pentry);
#endif /* SSH_KNOWNHOSTS_H_ */ #endif /* SSH_KNOWNHOSTS_H_ */

View File

@@ -101,8 +101,7 @@ int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
mbedtls_mpi_size(num)) mbedtls_mpi_size(num))
#define bignum_cmp(num1, num2) mbedtls_mpi_cmp_mpi(num1, num2) #define bignum_cmp(num1, num2) mbedtls_mpi_cmp_mpi(num1, num2)
mbedtls_entropy_context ssh_mbedtls_entropy; mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void);
mbedtls_ctr_drbg_context ssh_mbedtls_ctr_drbg;
int ssh_mbedtls_random(void *where, int len, int strong); int ssh_mbedtls_random(void *where, int len, int strong);

View File

@@ -78,7 +78,7 @@
/* libssh version */ /* libssh version */
#define LIBSSH_VERSION_MAJOR 0 #define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 7 #define LIBSSH_VERSION_MINOR 8
#define LIBSSH_VERSION_MICRO 90 #define LIBSSH_VERSION_MICRO 90
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \ #define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
@@ -239,11 +239,39 @@ enum ssh_server_known_e {
}; };
enum ssh_known_hosts_e { enum ssh_known_hosts_e {
/**
* There had been an error checking the host.
*/
SSH_KNOWN_HOSTS_ERROR = -2, SSH_KNOWN_HOSTS_ERROR = -2,
/**
* The known host file does not exist. The host is thus unknown. File will
* be created if host key is accepted.
*/
SSH_KNOWN_HOSTS_NOT_FOUND = -1, SSH_KNOWN_HOSTS_NOT_FOUND = -1,
/**
* The server is unknown. User should confirm the public key hash is
* correct.
*/
SSH_KNOWN_HOSTS_UNKNOWN = 0, SSH_KNOWN_HOSTS_UNKNOWN = 0,
/**
* The server is known and has not changed.
*/
SSH_KNOWN_HOSTS_OK, SSH_KNOWN_HOSTS_OK,
/**
* The server key has changed. Either you are under attack or the
* administrator changed the key. You HAVE to warn the user about a
* possible attack.
*/
SSH_KNOWN_HOSTS_CHANGED, SSH_KNOWN_HOSTS_CHANGED,
/**
* The server gave use a key of a type while we had an other type recorded.
* It is a possible attack.
*/
SSH_KNOWN_HOSTS_OTHER, SSH_KNOWN_HOSTS_OTHER,
}; };
@@ -376,6 +404,8 @@ enum ssh_options_e {
SSH_OPTIONS_GSSAPI_AUTH, SSH_OPTIONS_GSSAPI_AUTH,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS, SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
SSH_OPTIONS_NODELAY, SSH_OPTIONS_NODELAY,
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
SSH_OPTIONS_PROCESS_CONFIG,
}; };
enum { enum {
@@ -500,7 +530,8 @@ LIBSSH_API int ssh_get_server_publickey(ssh_session session, ssh_key *key);
enum ssh_publickey_hash_type { enum ssh_publickey_hash_type {
SSH_PUBLICKEY_HASH_SHA1, SSH_PUBLICKEY_HASH_SHA1,
SSH_PUBLICKEY_HASH_MD5 SSH_PUBLICKEY_HASH_MD5,
SSH_PUBLICKEY_HASH_SHA256
}; };
LIBSSH_API int ssh_get_publickey_hash(const ssh_key key, LIBSSH_API int ssh_get_publickey_hash(const ssh_key key,
enum ssh_publickey_hash_type type, enum ssh_publickey_hash_type type,
@@ -513,6 +544,10 @@ SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, in
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port); SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port); SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key); SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
SSH_DEPRECATED LIBSSH_API int ssh_write_knownhost(ssh_session session);
SSH_DEPRECATED LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
SSH_DEPRECATED LIBSSH_API int ssh_is_server_known(ssh_session session);
LIBSSH_API int ssh_get_random(void *where,int len,int strong); LIBSSH_API int ssh_get_random(void *where,int len,int strong);
@@ -522,7 +557,6 @@ LIBSSH_API int ssh_get_poll_flags(ssh_session session);
LIBSSH_API int ssh_init(void); LIBSSH_API int ssh_init(void);
LIBSSH_API int ssh_is_blocking(ssh_session session); LIBSSH_API int ssh_is_blocking(ssh_session session);
LIBSSH_API int ssh_is_connected(ssh_session session); LIBSSH_API int ssh_is_connected(ssh_session session);
LIBSSH_API int ssh_is_server_known(ssh_session session);
/* KNOWN HOSTS */ /* KNOWN HOSTS */
LIBSSH_API void ssh_knownhosts_entry_free(struct ssh_knownhosts_entry *entry); LIBSSH_API void ssh_knownhosts_entry_free(struct ssh_knownhosts_entry *entry);
@@ -563,6 +597,8 @@ SSH_DEPRECATED LIBSSH_API void ssh_log(ssh_session session,
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg); LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg); LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
#define SSH_MESSAGE_FREE(x) \
do { if ((x) != NULL) { ssh_message_free(x); (x) = NULL; } } while(0)
LIBSSH_API void ssh_message_free(ssh_message msg); LIBSSH_API void ssh_message_free(ssh_message msg);
LIBSSH_API ssh_message ssh_message_get(ssh_session session); LIBSSH_API ssh_message ssh_message_get(ssh_session session);
LIBSSH_API int ssh_message_subtype(ssh_message msg); LIBSSH_API int ssh_message_subtype(ssh_message msg);
@@ -600,6 +636,8 @@ typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata); int echo, int verify, void *userdata);
LIBSSH_API ssh_key ssh_key_new(void); LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
LIBSSH_API void ssh_key_free (ssh_key key); LIBSSH_API void ssh_key_free (ssh_key key);
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key); LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type); LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);
@@ -617,6 +655,11 @@ LIBSSH_API int ssh_pki_import_privkey_base64(const char *b64_key,
ssh_auth_callback auth_fn, ssh_auth_callback auth_fn,
void *auth_data, void *auth_data,
ssh_key *pkey); ssh_key *pkey);
LIBSSH_API int ssh_pki_export_privkey_base64(const ssh_key privkey,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
char **b64_key);
LIBSSH_API int ssh_pki_import_privkey_file(const char *filename, LIBSSH_API int ssh_pki_import_privkey_file(const char *filename,
const char *passphrase, const char *passphrase,
ssh_auth_callback auth_fn, ssh_auth_callback auth_fn,
@@ -652,6 +695,10 @@ LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key); LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key);
LIBSSH_API char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
unsigned char *hash,
size_t len);
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len); LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data); LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display); LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
@@ -719,19 +766,21 @@ LIBSSH_API int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i
const char *answer); const char *answer);
LIBSSH_API int ssh_userauth_gssapi(ssh_session session); LIBSSH_API int ssh_userauth_gssapi(ssh_session session);
LIBSSH_API const char *ssh_version(int req_version); LIBSSH_API const char *ssh_version(int req_version);
LIBSSH_API int ssh_write_knownhost(ssh_session session);
LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
LIBSSH_API void ssh_string_burn(ssh_string str); LIBSSH_API void ssh_string_burn(ssh_string str);
LIBSSH_API ssh_string ssh_string_copy(ssh_string str); LIBSSH_API ssh_string ssh_string_copy(ssh_string str);
LIBSSH_API void *ssh_string_data(ssh_string str); LIBSSH_API void *ssh_string_data(ssh_string str);
LIBSSH_API int ssh_string_fill(ssh_string str, const void *data, size_t len); LIBSSH_API int ssh_string_fill(ssh_string str, const void *data, size_t len);
#define SSH_STRING_FREE(x) \
do { if ((x) != NULL) { ssh_string_free(x); x = NULL; } } while(0)
LIBSSH_API void ssh_string_free(ssh_string str); LIBSSH_API void ssh_string_free(ssh_string str);
LIBSSH_API ssh_string ssh_string_from_char(const char *what); LIBSSH_API ssh_string ssh_string_from_char(const char *what);
LIBSSH_API size_t ssh_string_len(ssh_string str); LIBSSH_API size_t ssh_string_len(ssh_string str);
LIBSSH_API ssh_string ssh_string_new(size_t size); LIBSSH_API ssh_string ssh_string_new(size_t size);
LIBSSH_API const char *ssh_string_get_char(ssh_string str); LIBSSH_API const char *ssh_string_get_char(ssh_string str);
LIBSSH_API char *ssh_string_to_char(ssh_string str); LIBSSH_API char *ssh_string_to_char(ssh_string str);
#define SSH_STRING_FREE_CHAR(x) \
do { if ((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0)
LIBSSH_API void ssh_string_free_char(char *s); LIBSSH_API void ssh_string_free_char(char *s);
LIBSSH_API int ssh_getpass(const char *prompt, char *buf, size_t len, int echo, LIBSSH_API int ssh_getpass(const char *prompt, char *buf, size_t len, int echo,
@@ -760,6 +809,8 @@ LIBSSH_API const char* ssh_get_hmac_out(ssh_session session);
LIBSSH_API ssh_buffer ssh_buffer_new(void); LIBSSH_API ssh_buffer ssh_buffer_new(void);
LIBSSH_API void ssh_buffer_free(ssh_buffer buffer); LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
#define SSH_BUFFER_FREE(x) \
do { if ((x) != NULL) { ssh_buffer_free(x); x = NULL; } } while(0)
LIBSSH_API int ssh_buffer_reinit(ssh_buffer buffer); LIBSSH_API int ssh_buffer_reinit(ssh_buffer buffer);
LIBSSH_API int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len); LIBSSH_API int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
LIBSSH_API uint32_t ssh_buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen); LIBSSH_API uint32_t ssh_buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);

View File

@@ -195,15 +195,24 @@ public:
return ret; return ret;
} }
/** @brief Authenticate through the "keyboard-interactive" method. /**
* @param[in] The username to authenticate. You can specify NULL if ssh_option_set_username() has been used. You cannot try two different logins in a row. * @brief Authenticate through the "keyboard-interactive" method.
* @param[in] Undocumented. Set it to NULL. *
* @param[in] username The username to authenticate. You can specify NULL if
* ssh_option_set_username() has been used. You cannot
* try two different logins in a row.
*
* @param[in] submethods Undocumented. Set it to NULL.
*
* @throws SshException on error * @throws SshException on error
* @returns SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED, SSH_AUTH_ERROR, SSH_AUTH_INFO, SSH_AUTH_AGAIN *
* @returns SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED,
* SSH_AUTH_ERROR, SSH_AUTH_INFO, SSH_AUTH_AGAIN
*
* @see ssh_userauth_kbdint * @see ssh_userauth_kbdint
*/ */
int userauthKbdint(const char* username, const char* submethods){ int userauthKbdint(const char* username, const char* submethods){
int ret=ssh_userauth_kbdint(c_session,NULL,NULL); int ret = ssh_userauth_kbdint(c_session, username, submethods);
ssh_throw(ret); ssh_throw(ret);
return ret; return ret;
} }
@@ -216,15 +225,25 @@ public:
return ssh_userauth_kbdint_getnprompts(c_session); return ssh_userauth_kbdint_getnprompts(c_session);
} }
/** @brief Set the answer for a question from a message block.. /**
* @param[in] index The number of the ith prompt. * @brief Set the answer for a question from a message block.
* @param[in] The answer to give to the server. The answer MUST be encoded UTF-8. It is up to the server how to interpret the value and validate it. However, if you read the answer in some other encoding, you MUST convert it to UTF-8. *
* @param[in] index The index number of the prompt.
* @param[in] answer The answer to give to the server. The answer MUST be
* encoded UTF-8. It is up to the server how to interpret
* the value and validate it. However, if you read the
* answer in some other encoding, you MUST convert it to
* UTF-8.
*
* @throws SshException on error * @throws SshException on error
*
* @returns 0 on success, < 0 on error * @returns 0 on success, < 0 on error
*
* @see ssh_userauth_kbdint_setanswer * @see ssh_userauth_kbdint_setanswer
*/ */
int userauthKbdintSetAnswer(unsigned int i, const char* answer){ int userauthKbdintSetAnswer(unsigned int index, const char *answer)
int ret=ssh_userauth_kbdint_setanswer(c_session, i, answer); {
int ret = ssh_userauth_kbdint_setanswer(c_session, index, answer);
ssh_throw(ret); ssh_throw(ret);
return ret; return ret;
} }
@@ -316,11 +335,10 @@ public:
* @see ssh_get_issue_banner * @see ssh_get_issue_banner
*/ */
std::string getIssueBanner(){ std::string getIssueBanner(){
char *banner=ssh_get_issue_banner(c_session); char *banner = ssh_get_issue_banner(c_session);
std::string ret; std::string ret = "";
if (banner) if (banner != NULL) {
{ ret = std::string(banner);
ret= std::string(banner);
::free(banner); ::free(banner);
} }
return ret; return ret;
@@ -389,7 +407,7 @@ public:
* @see ssh_write_knownhost * @see ssh_write_knownhost
*/ */
int writeKnownhost(){ int writeKnownhost(){
int ret = ssh_write_knownhost(c_session); int ret = ssh_session_update_known_hosts(c_session);
ssh_throw(ret); ssh_throw(ret);
return ret; return ret;
} }
@@ -438,9 +456,9 @@ private:
class Channel { class Channel {
friend class Session; friend class Session;
public: public:
Channel(Session &session){ Channel(Session &ssh_session){
channel=ssh_channel_new(session.getCSession()); channel = ssh_channel_new(ssh_session.getCSession());
this->session=&session; this->session = &ssh_session;
} }
~Channel(){ ~Channel(){
ssh_channel_free(channel); ssh_channel_free(channel);
@@ -641,9 +659,9 @@ protected:
ssh_channel channel; ssh_channel channel;
private: private:
Channel (Session &session, ssh_channel c_channel){ Channel (Session &ssh_session, ssh_channel c_channel){
this->channel=c_channel; this->channel=c_channel;
this->session=&session; this->session = &ssh_session;
} }
/* No copy and no = operator */ /* No copy and no = operator */
Channel(const Channel &); Channel(const Channel &);

View File

@@ -101,7 +101,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request);
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet, int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
const char *request, uint8_t want_reply); const char *request, uint8_t want_reply);
void ssh_message_queue(ssh_session session, ssh_message message);
ssh_message ssh_message_pop_head(ssh_session session); ssh_message ssh_message_pop_head(ssh_session session);
int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan); int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);

View File

@@ -81,4 +81,6 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
int ssh_match_group(const char *group, const char *object); int ssh_match_group(const char *group, const char *object);
void uint64_inc(unsigned char *counter);
#endif /* MISC_H_ */ #endif /* MISC_H_ */

View File

@@ -43,6 +43,12 @@ enum ssh_packet_state_e {
PACKET_STATE_PROCESSING PACKET_STATE_PROCESSING
}; };
enum ssh_packet_filter_result_e {
SSH_PACKET_UNKNOWN,
SSH_PACKET_ALLOWED,
SSH_PACKET_DENIED
};
int ssh_packet_send(ssh_session session); int ssh_packet_send(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_unimplemented); SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
@@ -51,6 +57,7 @@ SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
SSH_PACKET_CALLBACK(ssh_packet_dh_reply); SSH_PACKET_CALLBACK(ssh_packet_dh_reply);
SSH_PACKET_CALLBACK(ssh_packet_newkeys); SSH_PACKET_CALLBACK(ssh_packet_newkeys);
SSH_PACKET_CALLBACK(ssh_packet_service_accept); SSH_PACKET_CALLBACK(ssh_packet_service_accept);
SSH_PACKET_CALLBACK(ssh_packet_ext_info);
#ifdef WITH_SERVER #ifdef WITH_SERVER
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init); SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
@@ -63,6 +70,7 @@ int ssh_packet_parse_type(ssh_session session);
int ssh_packet_socket_callback(const void *data, size_t len, void *user); int ssh_packet_socket_callback(const void *data, size_t len, void *user);
void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s); void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s);
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks); void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
void ssh_packet_remove_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
void ssh_packet_set_default_callbacks(ssh_session session); void ssh_packet_set_default_callbacks(ssh_session session);
void ssh_packet_process(ssh_session session, uint8_t type); void ssh_packet_process(ssh_session session, uint8_t type);

View File

@@ -44,23 +44,23 @@ struct ssh_key_struct {
int flags; int flags;
const char *type_c; /* Don't free it ! it is static */ const char *type_c; /* Don't free it ! it is static */
int ecdsa_nid; int ecdsa_nid;
#ifdef HAVE_LIBGCRYPT #if defined(HAVE_LIBGCRYPT)
gcry_sexp_t dsa; gcry_sexp_t dsa;
gcry_sexp_t rsa; gcry_sexp_t rsa;
gcry_sexp_t ecdsa; gcry_sexp_t ecdsa;
#elif HAVE_LIBMBEDCRYPTO #elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa; mbedtls_pk_context *rsa;
mbedtls_ecdsa_context *ecdsa; mbedtls_ecdsa_context *ecdsa;
void *dsa; void *dsa;
#elif HAVE_LIBCRYPTO #elif defined(HAVE_LIBCRYPTO)
DSA *dsa; DSA *dsa;
RSA *rsa; RSA *rsa;
#ifdef HAVE_OPENSSL_ECC # if defined(HAVE_OPENSSL_ECC)
EC_KEY *ecdsa; EC_KEY *ecdsa;
#else # else
void *ecdsa; void *ecdsa;
#endif /* HAVE_OPENSSL_EC_H */ # endif /* HAVE_OPENSSL_EC_H */
#endif #endif /* HAVE_LIBGCRYPT */
ed25519_pubkey *ed25519_pubkey; ed25519_pubkey *ed25519_pubkey;
ed25519_privkey *ed25519_privkey; ed25519_privkey *ed25519_privkey;
void *cert; void *cert;
@@ -69,12 +69,13 @@ struct ssh_key_struct {
struct ssh_signature_struct { struct ssh_signature_struct {
enum ssh_keytypes_e type; enum ssh_keytypes_e type;
enum ssh_digest_e hash_type;
const char *type_c; const char *type_c;
#ifdef HAVE_LIBGCRYPT #if defined(HAVE_LIBGCRYPT)
gcry_sexp_t dsa_sig; gcry_sexp_t dsa_sig;
gcry_sexp_t rsa_sig; gcry_sexp_t rsa_sig;
gcry_sexp_t ecdsa_sig; gcry_sexp_t ecdsa_sig;
#elif defined HAVE_LIBCRYPTO #elif defined(HAVE_LIBCRYPTO)
DSA_SIG *dsa_sig; DSA_SIG *dsa_sig;
ssh_string rsa_sig; ssh_string rsa_sig;
# ifdef HAVE_OPENSSL_ECC # ifdef HAVE_OPENSSL_ECC
@@ -82,10 +83,10 @@ struct ssh_signature_struct {
# else # else
void *ecdsa_sig; void *ecdsa_sig;
# endif # endif
#elif defined HAVE_LIBMBEDCRYPTO #elif defined(HAVE_LIBMBEDCRYPTO)
ssh_string rsa_sig; ssh_string rsa_sig;
struct mbedtls_ecdsa_sig ecdsa_sig; struct mbedtls_ecdsa_sig ecdsa_sig;
#endif #endif /* HAVE_LIBGCRYPT */
ed25519_signature *ed25519_sig; ed25519_signature *ed25519_sig;
}; };
@@ -95,6 +96,11 @@ typedef struct ssh_signature_struct *ssh_signature;
ssh_key ssh_key_dup(const ssh_key key); ssh_key ssh_key_dup(const ssh_key key);
void ssh_key_clean (ssh_key key); void ssh_key_clean (ssh_key key);
const char *
ssh_key_get_signature_algorithm(ssh_session session,
enum ssh_keytypes_e type);
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
/* SSH Signature Functions */ /* SSH Signature Functions */
ssh_signature ssh_signature_new(void); ssh_signature ssh_signature_new(void);
void ssh_signature_free(ssh_signature sign); void ssh_signature_free(ssh_signature sign);
@@ -104,11 +110,11 @@ int ssh_pki_export_signature_blob(const ssh_signature sign,
int ssh_pki_import_signature_blob(const ssh_string sig_blob, int ssh_pki_import_signature_blob(const ssh_string sig_blob,
const ssh_key pubkey, const ssh_key pubkey,
ssh_signature *psig); ssh_signature *psig);
int ssh_pki_signature_verify_blob(ssh_session session, int ssh_pki_signature_verify(ssh_session session,
ssh_string sig_blob, ssh_signature sig,
const ssh_key key, const ssh_key key,
unsigned char *digest, unsigned char *digest,
size_t dlen); size_t dlen);
/* SSH Public Key Functions */ /* SSH Public Key Functions */
int ssh_pki_export_pubkey_blob(const ssh_key key, int ssh_pki_export_pubkey_blob(const ssh_key key,
@@ -133,4 +139,5 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key); ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);
ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key); ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key);
int ssh_key_algorithm_allowed(ssh_session session, const char *type);
#endif /* PKI_H_ */ #endif /* PKI_H_ */

View File

@@ -45,6 +45,10 @@ int bcrypt_pbkdf(const char *pass,
int pki_key_ecdsa_nid_from_name(const char *name); int pki_key_ecdsa_nid_from_name(const char *name);
const char *pki_key_ecdsa_nid_to_name(int nid); const char *pki_key_ecdsa_nid_to_name(int nid);
const char *ssh_key_signature_to_char(enum ssh_keytypes_e type,
enum ssh_digest_e hash_type);
enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
enum ssh_keytypes_e type);
/* SSH Key Functions */ /* SSH Key Functions */
ssh_key pki_key_dup(const ssh_key key, int demote); ssh_key pki_key_dup(const ssh_key key, int demote);
@@ -68,6 +72,9 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
const char *passphrase, const char *passphrase,
ssh_auth_callback auth_fn, ssh_auth_callback auth_fn,
void *auth_data); void *auth_data);
int pki_import_privkey_buffer(enum ssh_keytypes_e type,
ssh_buffer buffer,
ssh_key *pkey);
/* SSH Public Key Functions */ /* SSH Public Key Functions */
int pki_pubkey_build_dss(ssh_key key, int pki_pubkey_build_dss(ssh_key key,
@@ -81,11 +88,32 @@ int pki_pubkey_build_rsa(ssh_key key,
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e); int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e);
ssh_string pki_publickey_to_blob(const ssh_key key); ssh_string pki_publickey_to_blob(const ssh_key key);
/* SSH Private Key Functions */
int pki_privkey_build_dss(ssh_key key,
ssh_string p,
ssh_string q,
ssh_string g,
ssh_string pubkey,
ssh_string privkey);
int pki_privkey_build_rsa(ssh_key key,
ssh_string n,
ssh_string e,
ssh_string d,
ssh_string iqmp,
ssh_string p,
ssh_string q);
int pki_privkey_build_ecdsa(ssh_key key,
int nid,
ssh_string e,
ssh_string exp);
ssh_string pki_publickey_to_blob(const ssh_key key);
/* SSH Signature Functions */ /* SSH Signature Functions */
ssh_string pki_signature_to_blob(const ssh_signature sign); ssh_string pki_signature_to_blob(const ssh_signature sign);
ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_signature pki_signature_from_blob(const ssh_key pubkey,
const ssh_string sig_blob, const ssh_string sig_blob,
enum ssh_keytypes_e type); enum ssh_keytypes_e type,
enum ssh_digest_e hash_type);
int pki_signature_verify(ssh_session session, int pki_signature_verify(ssh_session session,
const ssh_signature sig, const ssh_signature sig,
const ssh_key key, const ssh_key key,
@@ -93,12 +121,18 @@ int pki_signature_verify(ssh_session session,
size_t hlen); size_t hlen);
/* SSH Signing Functions */ /* SSH Signing Functions */
ssh_signature pki_do_sign(const ssh_key privkey, #define pki_do_sign(key, hash, hlen) \
const unsigned char *hash, pki_do_sign_hash(key, hash, hlen, SSH_DIGEST_AUTO)
size_t hlen); ssh_signature pki_do_sign_hash(const ssh_key privkey,
ssh_signature pki_do_sign_sessionid(const ssh_key key, const unsigned char *hash,
const unsigned char *hash, size_t hlen,
size_t hlen); enum ssh_digest_e hash_type);
#define pki_do_sign_sessionid(key, hash, hlen) \
pki_do_sign_sessionid_hash(key, hash, hlen, SSH_DIGEST_AUTO)
ssh_signature pki_do_sign_sessionid_hash(const ssh_key key,
const unsigned char *hash,
size_t hlen,
enum ssh_digest_e hash_type);
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig, int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
const unsigned char *hash, size_t hlen); const unsigned char *hash, size_t hlen);
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig, int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
@@ -110,8 +144,12 @@ int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key); int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig); ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob); int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
int pki_privkey_build_ed25519(ssh_key key,
ssh_string pubkey,
ssh_string privkey);
/* PKI Container OpenSSH */ /* PKI Container OpenSSH */
ssh_key ssh_pki_openssh_pubkey_import(const char *text_key);
ssh_key ssh_pki_openssh_privkey_import(const char *text_key, ssh_key ssh_pki_openssh_privkey_import(const char *text_key,
const char *passphrase, ssh_auth_callback auth_fn, void *auth_data); const char *passphrase, ssh_auth_callback auth_fn, void *auth_data);
ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey, ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,

View File

@@ -29,6 +29,7 @@
#ifndef _LIBSSH_PRIV_H #ifndef _LIBSSH_PRIV_H
#define _LIBSSH_PRIV_H #define _LIBSSH_PRIV_H
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -44,6 +45,10 @@
# endif # endif
#endif /* !defined(HAVE_STRTOULL) */ #endif /* !defined(HAVE_STRTOULL) */
#if !defined(HAVE_STRNDUP)
char *strndup(const char *s, size_t n);
#endif /* ! HAVE_STRNDUP */
#ifdef HAVE_BYTESWAP_H #ifdef HAVE_BYTESWAP_H
#include <byteswap.h> #include <byteswap.h>
#endif #endif
@@ -124,6 +129,13 @@
# endif /* HAVE__VSNPRINTF */ # endif /* HAVE__VSNPRINTF */
# endif /* HAVE__VSNPRINTF_S */ # endif /* HAVE__VSNPRINTF_S */
# ifndef _SSIZE_T_DEFINED
# undef ssize_t
# include <BaseTsd.h>
typedef _W64 SSIZE_T ssize_t;
# define _SSIZE_T_DEFINED
# endif /* _SSIZE_T_DEFINED */
# endif /* _MSC_VER */ # endif /* _MSC_VER */
struct timeval; struct timeval;
@@ -232,6 +244,7 @@ void _ssh_set_error_oom(void *error, const char *function);
_ssh_set_error_invalid(error, __func__) _ssh_set_error_invalid(error, __func__)
void _ssh_set_error_invalid(void *error, const char *function); void _ssh_set_error_invalid(void *error, const char *function);
void ssh_reset_error(void *error);
/* server.c */ /* server.c */
#ifdef WITH_SERVER #ifdef WITH_SERVER
@@ -257,6 +270,8 @@ int compress_buffer(ssh_session session,ssh_buffer buf);
int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen); int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen);
/* match.c */ /* match.c */
int match_pattern_list(const char *string, const char *pattern,
unsigned int len, int dolower);
int match_hostname(const char *host, const char *pattern, unsigned int len); int match_hostname(const char *host, const char *pattern, unsigned int len);
/* connector.c */ /* connector.c */
@@ -371,6 +386,22 @@ void explicit_bzero(void *s, size_t n);
# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */ # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
#endif /* FALL_THROUGH */ #endif /* FALL_THROUGH */
#ifndef __unused__
# ifdef HAVE_UNUSED_ATTRIBUTE
# define __unused__ __attribute__((unused))
# else /* HAVE_UNUSED_ATTRIBUTE */
# define __unused__
# endif /* HAVE_UNUSED_ATTRIBUTE */
#endif /* __unused__ */
#ifndef UNUSED_PARAM
#define UNUSED_PARAM(param) param __unused__
#endif /* UNUSED_PARAM */
#ifndef UNUSED_VAR
#define UNUSED_VAR(var) __unused__ var
#endif /* UNUSED_VAR */
void ssh_agent_state_free(void *data); void ssh_agent_state_free(void *data);
#endif /* _LIBSSH_PRIV_H */ #endif /* _LIBSSH_PRIV_H */

View File

@@ -20,6 +20,8 @@
#ifndef SESSION_H_ #ifndef SESSION_H_
#define SESSION_H_ #define SESSION_H_
#include <stdbool.h>
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/kex.h" #include "libssh/kex.h"
#include "libssh/packet.h" #include "libssh/packet.h"
@@ -27,6 +29,7 @@
#include "libssh/auth.h" #include "libssh/auth.h"
#include "libssh/channels.h" #include "libssh/channels.h"
#include "libssh/poll.h" #include "libssh/poll.h"
#include "libssh/config.h"
/* These are the different states a SSH session can be into its life */ /* These are the different states a SSH session can be into its life */
enum ssh_session_state_e { enum ssh_session_state_e {
@@ -86,6 +89,12 @@ enum ssh_pending_call_e {
#define SSH_OPT_FLAG_KBDINT_AUTH 0x4 #define SSH_OPT_FLAG_KBDINT_AUTH 0x4
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8 #define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
/* extensions flags */
/* server-sig-algs extension */
#define SSH_EXT_SIG_RSA_SHA256 0x01
#define SSH_EXT_SIG_RSA_SHA512 0x02
#define SSH_EXT_ALL SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512
/* members that are common to ssh_session and ssh_bind */ /* members that are common to ssh_session and ssh_bind */
struct ssh_common_struct { struct ssh_common_struct {
struct error_struct error; struct error_struct error;
@@ -114,6 +123,9 @@ struct ssh_session_struct {
/* session flags (SSH_SESSION_FLAG_*) */ /* session flags (SSH_SESSION_FLAG_*) */
int flags; int flags;
/* Extensions negotiated using RFC 8308 */
uint32_t extensions;
ssh_string banner; /* that's the issue banner from ssh_string banner; /* that's the issue banner from
the server */ the server */
char *discon_msg; /* disconnect message from char *discon_msg; /* disconnect message from
@@ -128,11 +140,16 @@ struct ssh_session_struct {
enum ssh_session_state_e session_state; enum ssh_session_state_e session_state;
int packet_state; int packet_state;
enum ssh_dh_state_e dh_handshake_state; enum ssh_dh_state_e dh_handshake_state;
enum ssh_auth_service_state_e auth_service_state;
enum ssh_auth_state_e auth_state;
enum ssh_channel_request_state_e global_req_state; enum ssh_channel_request_state_e global_req_state;
struct ssh_agent_state_struct *agent_state; struct ssh_agent_state_struct *agent_state;
struct ssh_auth_auto_state_struct *auth_auto_state;
struct {
struct ssh_auth_auto_state_struct *auto_state;
enum ssh_auth_service_state_e service_state;
enum ssh_auth_state_e state;
uint32_t supported_methods;
uint32_t current_method;
} auth;
/* /*
* RFC 4253, 7.1: if the first_kex_packet_follows flag was set in * RFC 4253, 7.1: if the first_kex_packet_follows flag was set in
@@ -150,8 +167,6 @@ struct ssh_session_struct {
struct ssh_list *channels; /* linked list of channels */ struct ssh_list *channels; /* linked list of channels */
int maxchannel; int maxchannel;
int exec_channel_opened; /* version 1 only. more
info in channels1.c */
ssh_agent agent; /* ssh agent */ ssh_agent agent; /* ssh agent */
/* keyb interactive data */ /* keyb interactive data */
@@ -167,8 +182,8 @@ struct ssh_session_struct {
/* The type of host key wanted by client */ /* The type of host key wanted by client */
enum ssh_keytypes_e hostkey; enum ssh_keytypes_e hostkey;
} srv; } srv;
/* auths accepted by server */ /* auths accepted by server */
int auth_methods;
struct ssh_list *ssh_message_list; /* list of delayed SSH messages */ struct ssh_list *ssh_message_list; /* list of delayed SSH messages */
int (*ssh_message_callback)( struct ssh_session_struct *session, ssh_message msg, void *userdata); int (*ssh_message_callback)( struct ssh_session_struct *session, ssh_message msg, void *userdata);
void *ssh_message_callback_data; void *ssh_message_callback_data;
@@ -191,6 +206,7 @@ struct ssh_session_struct {
char *knownhosts; char *knownhosts;
char *global_knownhosts; char *global_knownhosts;
char *wanted_methods[10]; char *wanted_methods[10];
char *pubkey_accepted_types;
char *ProxyCommand; char *ProxyCommand;
char *custombanner; char *custombanner;
unsigned long timeout; /* seconds */ unsigned long timeout; /* seconds */
@@ -204,6 +220,8 @@ struct ssh_session_struct {
int gss_delegate_creds; int gss_delegate_creds;
int flags; int flags;
int nodelay; int nodelay;
bool config_processed;
uint8_t options_seen[SOC_MAX];
} opts; } opts;
/* counters */ /* counters */
ssh_counter socket_counter; ssh_counter socket_counter;
@@ -217,8 +235,10 @@ struct ssh_session_struct {
*/ */
typedef int (*ssh_termination_function)(void *user); typedef int (*ssh_termination_function)(void *user);
int ssh_handle_packets(ssh_session session, int timeout); int ssh_handle_packets(ssh_session session, int timeout);
int ssh_handle_packets_termination(ssh_session session, int timeout, int ssh_handle_packets_termination(ssh_session session,
ssh_termination_function fct, void *user); long timeout,
ssh_termination_function fct,
void *user);
void ssh_socket_exception_callback(int code, int errno_code, void *user); void ssh_socket_exception_callback(int code, int errno_code, void *user);
#endif /* SESSION_H_ */ #endif /* SESSION_H_ */

View File

@@ -53,9 +53,14 @@ extern "C" {
typedef uint32_t gid_t; typedef uint32_t gid_t;
#endif /* gid_t */ #endif /* gid_t */
#ifdef _MSC_VER #ifdef _MSC_VER
#ifndef ssize_t
typedef _W64 SSIZE_T ssize_t; # ifndef _SSIZE_T_DEFINED
#endif /* ssize_t */ # undef ssize_t
# include <BaseTsd.h>
typedef _W64 SSIZE_T ssize_t;
# define _SSIZE_T_DEFINED
# endif /* _SSIZE_T_DEFINED */
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#endif /* _WIN32 */ #endif /* _WIN32 */
@@ -84,6 +89,7 @@ struct sftp_session_struct {
int errnum; int errnum;
void **handles; void **handles;
sftp_ext ext; sftp_ext ext;
sftp_packet read_packet;
}; };
struct sftp_packet_struct { struct sftp_packet_struct {
@@ -134,6 +140,7 @@ struct sftp_client_message_struct {
ssh_string data; /* can be newpath of rename() */ ssh_string data; /* can be newpath of rename() */
ssh_buffer complete_message; /* complete message in case of retransmission*/ ssh_buffer complete_message; /* complete message in case of retransmission*/
char *str_data; /* cstring version of data */ char *str_data; /* cstring version of data */
char *submessage; /* for extended messages */
}; };
struct sftp_request_queue_struct { struct sftp_request_queue_struct {
@@ -862,6 +869,7 @@ LIBSSH_API const char *sftp_client_message_get_filename(sftp_client_message msg)
LIBSSH_API void sftp_client_message_set_filename(sftp_client_message msg, const char *newname); LIBSSH_API void sftp_client_message_set_filename(sftp_client_message msg, const char *newname);
LIBSSH_API const char *sftp_client_message_get_data(sftp_client_message msg); LIBSSH_API const char *sftp_client_message_get_data(sftp_client_message msg);
LIBSSH_API uint32_t sftp_client_message_get_flags(sftp_client_message msg); LIBSSH_API uint32_t sftp_client_message_get_flags(sftp_client_message msg);
LIBSSH_API const char *sftp_client_message_get_submessage(sftp_client_message msg);
LIBSSH_API int sftp_send_client_message(sftp_session sftp, sftp_client_message msg); LIBSSH_API int sftp_send_client_message(sftp_session sftp, sftp_client_message msg);
LIBSSH_API int sftp_reply_name(sftp_client_message msg, const char *name, LIBSSH_API int sftp_reply_name(sftp_client_message msg, const char *name,
sftp_attributes attr); sftp_attributes attr);
@@ -1011,6 +1019,7 @@ LIBSSH_API void sftp_handle_remove(sftp_session sftp, void *handle);
#define SFTP_RENAME SSH_FXP_RENAME #define SFTP_RENAME SSH_FXP_RENAME
#define SFTP_READLINK SSH_FXP_READLINK #define SFTP_READLINK SSH_FXP_READLINK
#define SFTP_SYMLINK SSH_FXP_SYMLINK #define SFTP_SYMLINK SSH_FXP_SYMLINK
#define SFTP_EXTENDED SSH_FXP_EXTENDED
/* openssh flags */ /* openssh flags */
#define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */ #define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */

View File

@@ -34,7 +34,7 @@ ssh_socket ssh_socket_new(ssh_session session);
void ssh_socket_reset(ssh_socket s); void ssh_socket_reset(ssh_socket s);
void ssh_socket_free(ssh_socket s); void ssh_socket_free(ssh_socket s);
void ssh_socket_set_fd(ssh_socket s, socket_t fd); void ssh_socket_set_fd(ssh_socket s, socket_t fd);
socket_t ssh_socket_get_fd_in(ssh_socket s); socket_t ssh_socket_get_fd(ssh_socket s);
#ifndef _WIN32 #ifndef _WIN32
int ssh_socket_unix(ssh_socket s, const char *path); int ssh_socket_unix(ssh_socket s, const char *path);
void ssh_execute_command(const char *command, socket_t in, socket_t out); void ssh_execute_command(const char *command, socket_t in, socket_t out);
@@ -61,8 +61,7 @@ int ssh_socket_set_blocking(socket_t fd);
void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks); void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s); int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_in(ssh_socket s); struct ssh_poll_handle_struct * ssh_socket_get_poll_handle(ssh_socket s);
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_out(ssh_socket s);
int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr); int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr);

View File

@@ -7,6 +7,7 @@
#define SSH2_MSG_DEBUG 4 #define SSH2_MSG_DEBUG 4
#define SSH2_MSG_SERVICE_REQUEST 5 #define SSH2_MSG_SERVICE_REQUEST 5
#define SSH2_MSG_SERVICE_ACCEPT 6 #define SSH2_MSG_SERVICE_ACCEPT 6
#define SSH2_MSG_EXT_INFO 7
#define SSH2_MSG_KEXINIT 20 #define SSH2_MSG_KEXINIT 20
#define SSH2_MSG_NEWKEYS 21 #define SSH2_MSG_NEWKEYS 21

View File

@@ -29,7 +29,7 @@
#include <pthread.h> #include <pthread.h>
#define SSH_MUTEX pthread_mutex_t #define SSH_MUTEX pthread_mutex_t
#if defined _GNU_SOURCE #if defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
#define SSH_MUTEX_STATIC_INIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP #define SSH_MUTEX_STATIC_INIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
#else #else
#define SSH_MUTEX_STATIC_INIT PTHREAD_MUTEX_INITIALIZER #define SSH_MUTEX_STATIC_INIT PTHREAD_MUTEX_INITIALIZER

View File

@@ -27,6 +27,13 @@
#include "libssh/libgcrypt.h" #include "libssh/libgcrypt.h"
#include "libssh/libmbedcrypto.h" #include "libssh/libmbedcrypto.h"
enum ssh_digest_e {
SSH_DIGEST_AUTO=0,
SSH_DIGEST_SHA1=1,
SSH_DIGEST_SHA256,
SSH_DIGEST_SHA512
};
enum ssh_mac_e { enum ssh_mac_e {
SSH_MAC_SHA1=1, SSH_MAC_SHA1=1,
SSH_MAC_SHA256, SSH_MAC_SHA256,
@@ -40,7 +47,8 @@ enum ssh_hmac_e {
SSH_HMAC_SHA384, SSH_HMAC_SHA384,
SSH_HMAC_SHA512, SSH_HMAC_SHA512,
SSH_HMAC_MD5, SSH_HMAC_MD5,
SSH_HMAC_AEAD_POLY1305 SSH_HMAC_AEAD_POLY1305,
SSH_HMAC_AEAD_GCM
}; };
enum ssh_des_e { enum ssh_des_e {

View File

@@ -1 +0,0 @@
set(LIBSSH_INLUDE_DIR @PROJECT_SOURCE_DIR@/include)

View File

@@ -1,11 +0,0 @@
set(PACKAGE_VERSION @APPLICATION_VERSION@)
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()

View File

@@ -1,15 +1,15 @@
get_filename_component(LIBSSH_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) @PACKAGE_INIT@
if (EXISTS "${LIBSSH_CMAKE_DIR}/CMakeCache.txt") if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/CMakeCache.txt")
# In build tree # In tree build
include(${LIBSSH_CMAKE_DIR}/libssh-build-tree-settings.cmake) set_and_check(LIBSSH_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
set_and_check(LIBSSH_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/@LIBSSH_LIBRARY_NAME@")
else() else()
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@) set_and_check(LIBSSH_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(LIBSSH_LIBRARIES "@PACKAGE_LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@")
endif() endif()
set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@) # For backward compatibility
set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@) set(LIBSSH_LIBRARY ${LIBSSH_LIBRARIES})
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@) mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_LIBRARY LIBSSH_INCLUDE_DIR)
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_INCLUDE_DIR)

View File

@@ -1,6 +1,6 @@
Name: ${APPLICATION_NAME} Name: ${PROJECT_NAME}
Description: The SSH Library Description: The SSH Library
Version: ${APPLICATION_VERSION} Version: ${PROJECT_VERSION}
Libs: -L${LIB_INSTALL_DIR} -lssh Libs: -L${LIB_INSTALL_DIR} -lssh
Cflags: -I${INCLUDE_INSTALL_DIR} Cflags: -I${INCLUDE_INSTALL_DIR}

View File

@@ -1,6 +0,0 @@
Name: ${APPLICATION_NAME}_threads
Description: The SSH Library Thread Extension
Version: ${APPLICATION_VERSION}
Libs: -L${LIB_INSTALL_DIR} -lssh_threads
Cflags: -I${INCLUDE_INSTALL_DIR}

View File

@@ -1 +1 @@
4.5.0 4.7.2

View File

View File

@@ -0,0 +1,412 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
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_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
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

View File

@@ -0,0 +1,415 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
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_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
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

View File

@@ -0,0 +1,415 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
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_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
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

View File

@@ -0,0 +1,415 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
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_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
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

View File

@@ -48,7 +48,7 @@ if (MBEDTLS_CRYPTO_LIBRARY)
) )
endif (MBEDTLS_CRYPTO_LIBRARY) endif (MBEDTLS_CRYPTO_LIBRARY)
if (GCRYPT_LIBRARY) if (GCRYPT_LIBRARIES)
set(LIBSSH_PRIVATE_INCLUDE_DIRS set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS} ${LIBSSH_PRIVATE_INCLUDE_DIRS}
${GCRYPT_INCLUDE_DIR} ${GCRYPT_INCLUDE_DIR}
@@ -56,9 +56,8 @@ if (GCRYPT_LIBRARY)
set(LIBSSH_LINK_LIBRARIES set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES} ${LIBSSH_LINK_LIBRARIES}
${GCRYPT_LIBRARY} ${GCRYPT_LIBRARIES})
) endif()
endif (GCRYPT_LIBRARY)
if (WITH_ZLIB) if (WITH_ZLIB)
set(LIBSSH_PRIVATE_INCLUDE_DIRS set(LIBSSH_PRIVATE_INCLUDE_DIRS
@@ -106,12 +105,12 @@ set(LIBSSH_SHARED_LIBRARY
CACHE INTERNAL "libssh shared library" CACHE INTERNAL "libssh shared library"
) )
if (WITH_STATIC_LIB) if (BUILD_STATIC_LIB)
set(LIBSSH_STATIC_LIBRARY set(LIBSSH_STATIC_LIBRARY
ssh_static ssh_static
CACHE INTERNAL "libssh static library" CACHE INTERNAL "libssh static library"
) )
endif (WITH_STATIC_LIB) endif (BUILD_STATIC_LIB)
set(libssh_SRCS set(libssh_SRCS
agent.c agent.c
@@ -165,6 +164,12 @@ set(libssh_SRCS
chachapoly.c chachapoly.c
) )
if (DEFAULT_C_NO_DEPRECATION_FLAGS)
set_source_files_properties(known_hosts.c
PROPERTIES
COMPILE_FLAGS ${DEFAULT_C_NO_DEPRECATION_FLAGS})
endif()
if (CMAKE_USE_PTHREADS_INIT) if (CMAKE_USE_PTHREADS_INIT)
set(libssh_SRCS set(libssh_SRCS
${libssh_SRCS} ${libssh_SRCS}
@@ -266,15 +271,15 @@ include_directories(
# Set the path to the default map file # Set the path to the default map file
set(MAP_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.map") set(MAP_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.map")
if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND) if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
# Get the list of header files # Get the list of header files
get_file_list("dev_header_list" get_file_list(dev_header_list
DIRECTORIES "${LIBSSH_PUBLIC_INCLUDE_DIRS}/libssh" DIRECTORIES "${LIBSSH_PUBLIC_INCLUDE_DIRS}/libssh"
FILES_PATTERNS "*.h") FILES_PATTERNS "*.h")
# Extract the symbols marked as "LIBSSH_API" from the header files # Extract the symbols marked as "LIBSSH_API" from the header files
extract_symbols("${PROJECT_NAME}_dev.symbols" extract_symbols("${PROJECT_NAME}_dev.symbols"
HEADERS_LIST_FILE "dev_header_list" HEADERS_LIST dev_header_list
FILTER_PATTERN "LIBSSH_API") FILTER_PATTERN "LIBSSH_API")
if (WITH_ABI_BREAK) if (WITH_ABI_BREAK)
@@ -292,13 +297,14 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
${libssh_SRCS} ${libssh_SRCS}
${PROJECT_NAME}_dev.map ${PROJECT_NAME}_dev.map
) )
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND) endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS}) add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS})
target_compile_options(${LIBSSH_SHARED_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES}) target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
if (WITH_SYMBOL_VERSIONING) if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
if (ABIMAP_FOUND) if (ABIMAP_FOUND)
# Change path to devel map file # Change path to devel map file
set(MAP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_dev.map") set(MAP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_dev.map")
@@ -307,7 +313,7 @@ if (WITH_SYMBOL_VERSIONING)
set_target_properties(${LIBSSH_SHARED_LIBRARY} set_target_properties(${LIBSSH_SHARED_LIBRARY}
PROPERTIES LINK_FLAGS PROPERTIES LINK_FLAGS
"-Wl,--version-script,\"${MAP_PATH}\"") "-Wl,--version-script,\"${MAP_PATH}\"")
endif (WITH_SYMBOL_VERSIONING) endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
set_target_properties( set_target_properties(
${LIBSSH_SHARED_LIBRARY} ${LIBSSH_SHARED_LIBRARY}
@@ -340,8 +346,9 @@ install(
COMPONENT libraries COMPONENT libraries
) )
if (WITH_STATIC_LIB) if (BUILD_STATIC_LIB)
add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS}) add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS})
target_compile_options(${LIBSSH_STATIC_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
if (MSVC) if (MSVC)
set(OUTPUT_SUFFIX static) set(OUTPUT_SUFFIX static)
@@ -370,14 +377,14 @@ if (WITH_STATIC_LIB)
) )
endif (WIN32) endif (WIN32)
install( if (WITH_STATIC_LIB)
TARGETS install(TARGETS
${LIBSSH_STATIC_LIBRARY} ${LIBSSH_STATIC_LIBRARY}
DESTINATION DESTINATION
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX} ${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
COMPONENT COMPONENT
libraries libraries)
) endif (WITH_STATIC_LIB)
endif (WITH_STATIC_LIB) endif (BUILD_STATIC_LIB)
message(STATUS "Threads_FOUND=${Threads_FOUND}") message(STATUS "Threads_FOUND=${Threads_FOUND}")

View File

@@ -56,33 +56,13 @@
#include "libssh/session.h" #include "libssh/session.h"
#include "libssh/poll.h" #include "libssh/poll.h"
#include "libssh/pki.h" #include "libssh/pki.h"
#include "libssh/bytearray.h"
/* macro to check for "agent failure" message */ /* macro to check for "agent failure" message */
#define agent_failed(x) \ #define agent_failed(x) \
(((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \ (((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
((x) == SSH2_AGENT_FAILURE)) ((x) == SSH2_AGENT_FAILURE))
static uint32_t agent_get_u32(const void *vp) {
const uint8_t *p = (const uint8_t *)vp;
uint32_t v;
v = (uint32_t)p[0] << 24;
v |= (uint32_t)p[1] << 16;
v |= (uint32_t)p[2] << 8;
v |= (uint32_t)p[3];
return v;
}
static void agent_put_u32(void *vp, uint32_t v) {
uint8_t *p = (uint8_t *)vp;
p[0] = (uint8_t)(v >> 24) & 0xff;
p[1] = (uint8_t)(v >> 16) & 0xff;
p[2] = (uint8_t)(v >> 8) & 0xff;
p[3] = (uint8_t)v & 0xff;
}
static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) { static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) {
char *b = buf; char *b = buf;
size_t pos = 0; size_t pos = 0;
@@ -93,7 +73,7 @@ static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int
/* Using a socket ? */ /* Using a socket ? */
if (channel == NULL) { if (channel == NULL) {
fd = ssh_socket_get_fd_in(agent->sock); fd = ssh_socket_get_fd(agent->sock);
pfd.fd = fd; pfd.fd = fd;
pfd.events = do_read ? POLLIN : POLLOUT; pfd.events = do_read ? POLLIN : POLLOUT;
@@ -275,7 +255,7 @@ static int agent_talk(struct ssh_session_struct *session,
len = ssh_buffer_get_len(request); len = ssh_buffer_get_len(request);
SSH_LOG(SSH_LOG_TRACE, "Request length: %u", len); SSH_LOG(SSH_LOG_TRACE, "Request length: %u", len);
agent_put_u32(payload, len); PUSH_BE_U32(payload, 0, len);
/* send length and then the request packet */ /* send length and then the request packet */
if (atomicio(session->agent, payload, 4, 0) == 4) { if (atomicio(session->agent, payload, 4, 0) == 4) {
@@ -299,7 +279,7 @@ static int agent_talk(struct ssh_session_struct *session,
return -1; return -1;
} }
len = agent_get_u32(payload); len = PULL_BE_U32(payload, 0);
if (len > 256 * 1024) { if (len > 256 * 1024) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Authentication response too long: %u", len); "Authentication response too long: %u", len);
@@ -331,7 +311,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
ssh_buffer request = NULL; ssh_buffer request = NULL;
ssh_buffer reply = NULL; ssh_buffer reply = NULL;
unsigned int type = 0; unsigned int type = 0;
uint8_t buf[4] = {0}; uint32_t count = 0;
int rc; int rc;
/* send message to the agent requesting the list of identities */ /* send message to the agent requesting the list of identities */
@@ -386,8 +366,15 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
return -1; return -1;
} }
ssh_buffer_get_u32(reply, (uint32_t *) buf); rc = ssh_buffer_get_u32(reply, &count);
session->agent->count = agent_get_u32(buf); if (rc != 4) {
ssh_set_error(session,
SSH_FATAL,
"Failed to read count");
ssh_buffer_free(reply);
return -1;
}
session->agent->count = ntohl(count);
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d", SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
session->agent->count); session->agent->count);
if (session->agent->count > 1024) { if (session->agent->count > 1024) {
@@ -548,6 +535,14 @@ ssh_string ssh_agent_sign_data(ssh_session session,
return NULL; return NULL;
} }
/* Add Flags: SHA2 extension (RFC 8332) if negotiated */
if (pubkey->type == SSH_KEYTYPE_RSA) {
if (session->extensions & SSH_EXT_SIG_RSA_SHA512) {
flags |= SSH_AGENT_RSA_SHA2_512;
} else if (session->extensions & SSH_EXT_SIG_RSA_SHA256) {
flags |= SSH_AGENT_RSA_SHA2_256;
}
}
if (ssh_buffer_add_u32(request, htonl(flags)) < 0) { if (ssh_buffer_add_u32(request, htonl(flags)) < 0) {
ssh_buffer_free(request); ssh_buffer_free(request);
return NULL; return NULL;

View File

@@ -79,18 +79,52 @@ static int ssh_userauth_request_service(ssh_session session) {
static int ssh_auth_response_termination(void *user) { static int ssh_auth_response_termination(void *user) {
ssh_session session = (ssh_session)user; ssh_session session = (ssh_session)user;
switch (session->auth_state) { switch (session->auth.state) {
case SSH_AUTH_STATE_NONE: case SSH_AUTH_STATE_NONE:
case SSH_AUTH_STATE_KBDINT_SENT: case SSH_AUTH_STATE_KBDINT_SENT:
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN: case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT: case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
return 0; return 0;
default: default:
return 1; return 1;
} }
} }
static const char *ssh_auth_get_current_method(ssh_session session)
{
const char *method = "unknown";
switch (session->auth.current_method) {
case SSH_AUTH_METHOD_NONE:
method = "none";
break;
case SSH_AUTH_METHOD_PASSWORD:
method = "password";
break;
case SSH_AUTH_METHOD_PUBLICKEY:
method = "publickey";
break;
case SSH_AUTH_METHOD_HOSTBASED:
method = "hostbased";
break;
case SSH_AUTH_METHOD_INTERACTIVE:
method = "keyboard interactive";
break;
case SSH_AUTH_METHOD_GSSAPI_MIC:
method = "gssapi";
break;
default:
break;
}
return method;
}
/** /**
* @internal * @internal
* @brief Wait for a response of an authentication function. * @brief Wait for a response of an authentication function.
@@ -116,7 +150,7 @@ static int ssh_userauth_get_response(ssh_session session) {
return SSH_AUTH_AGAIN; return SSH_AUTH_AGAIN;
} }
switch(session->auth_state) { switch(session->auth.state) {
case SSH_AUTH_STATE_ERROR: case SSH_AUTH_STATE_ERROR:
rc = SSH_AUTH_ERROR; rc = SSH_AUTH_ERROR;
break; break;
@@ -137,6 +171,10 @@ static int ssh_userauth_get_response(ssh_session session) {
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN: case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT: case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
case SSH_AUTH_STATE_NONE: case SSH_AUTH_STATE_NONE:
/* not reached */ /* not reached */
rc = SSH_AUTH_ERROR; rc = SSH_AUTH_ERROR;
@@ -181,6 +219,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_banner) {
* This handles the complete or partial authentication failure. * This handles the complete or partial authentication failure.
*/ */
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) { SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) {
const char *current_method = ssh_auth_get_current_method(session);
char *auth_methods = NULL; char *auth_methods = NULL;
uint8_t partial = 0; uint8_t partial = 0;
int rc; int rc;
@@ -191,43 +230,46 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) {
if (rc != SSH_OK) { if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Invalid SSH_MSG_USERAUTH_FAILURE message"); "Invalid SSH_MSG_USERAUTH_FAILURE message");
session->auth_state=SSH_AUTH_STATE_ERROR; session->auth.state = SSH_AUTH_STATE_ERROR;
goto end; goto end;
} }
if (partial) { if (partial) {
session->auth_state=SSH_AUTH_STATE_PARTIAL; session->auth.state = SSH_AUTH_STATE_PARTIAL;
SSH_LOG(SSH_LOG_INFO, SSH_LOG(SSH_LOG_INFO,
"Partial success. Authentication that can continue: %s", "Partial success for '%s'. Authentication that can continue: %s",
current_method,
auth_methods); auth_methods);
} else { } else {
session->auth_state=SSH_AUTH_STATE_FAILED; session->auth.state = SSH_AUTH_STATE_FAILED;
SSH_LOG(SSH_LOG_INFO,
"Access denied. Authentication that can continue: %s",
auth_methods);
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session, SSH_REQUEST_DENIED,
"Access denied. Authentication that can continue: %s", "Access denied for '%s'. Authentication that can continue: %s",
auth_methods); current_method,
auth_methods);
SSH_LOG(SSH_LOG_INFO,
"%s",
ssh_get_error(session));
} }
session->auth_methods = 0; session->auth.supported_methods = 0;
if (strstr(auth_methods, "password") != NULL) { if (strstr(auth_methods, "password") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_PASSWORD; session->auth.supported_methods |= SSH_AUTH_METHOD_PASSWORD;
} }
if (strstr(auth_methods, "keyboard-interactive") != NULL) { if (strstr(auth_methods, "keyboard-interactive") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_INTERACTIVE; session->auth.supported_methods |= SSH_AUTH_METHOD_INTERACTIVE;
} }
if (strstr(auth_methods, "publickey") != NULL) { if (strstr(auth_methods, "publickey") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_PUBLICKEY; session->auth.supported_methods |= SSH_AUTH_METHOD_PUBLICKEY;
} }
if (strstr(auth_methods, "hostbased") != NULL) { if (strstr(auth_methods, "hostbased") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_HOSTBASED; session->auth.supported_methods |= SSH_AUTH_METHOD_HOSTBASED;
} }
if (strstr(auth_methods, "gssapi-with-mic") != NULL) { if (strstr(auth_methods, "gssapi-with-mic") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_GSSAPI_MIC; session->auth.supported_methods |= SSH_AUTH_METHOD_GSSAPI_MIC;
} }
end: end:
session->auth.current_method = SSH_AUTH_METHOD_UNKNOWN;
SAFE_FREE(auth_methods); SAFE_FREE(auth_methods);
return SSH_PACKET_USED; return SSH_PACKET_USED;
@@ -248,7 +290,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
SSH_LOG(SSH_LOG_DEBUG, "Authentication successful"); SSH_LOG(SSH_LOG_DEBUG, "Authentication successful");
SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_SUCCESS"); SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_SUCCESS");
session->auth_state = SSH_AUTH_STATE_SUCCESS; session->auth.state = SSH_AUTH_STATE_SUCCESS;
session->session_state = SSH_SESSION_STATE_AUTHENTICATED; session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED; session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
@@ -261,6 +303,9 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
session->current_crypto->do_compress_in = 1; session->current_crypto->do_compress_in = 1;
} }
/* Reset errors by previous authentication methods. */
ssh_reset_error(session);
session->auth.current_method = SSH_AUTH_METHOD_UNKNOWN;
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
@@ -275,24 +320,30 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok) { SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok) {
int rc; int rc;
SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
if (session->auth_state==SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, assuming SSH_USERAUTH_INFO_REQUEST"); "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
rc = ssh_packet_userauth_info_request(session,type,packet,user);
#ifdef WITH_GSSAPI
} else if (session->auth_state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else {
session->auth_state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
}
return rc; if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, "
"assuming SSH_USERAUTH_INFO_REQUEST");
rc = ssh_packet_userauth_info_request(session,type,packet,user);
#ifdef WITH_GSSAPI
} else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else if (session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT) {
session->auth.state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
} else {
session->auth.state = SSH_AUTH_STATE_ERROR;
SSH_LOG(SSH_LOG_TRACE, "SSH_USERAUTH_PK_OK received in wrong state");
rc = SSH_PACKET_USED;
}
return rc;
} }
/** /**
@@ -323,7 +374,7 @@ int ssh_userauth_list(ssh_session session, const char *username)
return 0; return 0;
} }
return session->auth_methods; return session->auth.supported_methods;
} }
/** /**
@@ -378,7 +429,8 @@ int ssh_userauth_none(ssh_session session, const char *username) {
goto fail; goto fail;
} }
session->auth_state = SSH_AUTH_STATE_NONE; session->auth.current_method = SSH_AUTH_METHOD_NONE;
session->auth.state = SSH_AUTH_STATE_AUTH_NONE_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE; session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -432,6 +484,7 @@ int ssh_userauth_try_publickey(ssh_session session,
const ssh_key pubkey) const ssh_key pubkey)
{ {
ssh_string pubkey_s = NULL; ssh_string pubkey_s = NULL;
const char *sig_type_c = NULL;
int rc; int rc;
if (session == NULL) { if (session == NULL) {
@@ -456,6 +509,34 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_ERROR; return SSH_ERROR;
} }
switch (pubkey->type) {
case SSH_KEYTYPE_UNKNOWN:
ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)");
return SSH_AUTH_DENIED;
case SSH_KEYTYPE_ECDSA:
sig_type_c = ssh_pki_key_ecdsa_name(pubkey);
break;
case SSH_KEYTYPE_DSS:
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_DSS_CERT01:
case SSH_KEYTYPE_RSA_CERT01:
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
break;
}
/* Check if the given public key algorithm is allowed */
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by"
" PUBLICKEY_ACCEPTED_TYPES configuration option",
sig_type_c);
return SSH_AUTH_DENIED;
}
rc = ssh_userauth_request_service(session); rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) { if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN; return SSH_AUTH_AGAIN;
@@ -476,7 +557,7 @@ int ssh_userauth_try_publickey(ssh_session session,
"ssh-connection", "ssh-connection",
"publickey", "publickey",
0, /* private key ? */ 0, /* private key ? */
pubkey->type_c, /* algo */ sig_type_c, /* algo */
pubkey_s /* public key */ pubkey_s /* public key */
); );
if (rc < 0) { if (rc < 0) {
@@ -485,7 +566,8 @@ int ssh_userauth_try_publickey(ssh_session session,
ssh_string_free(pubkey_s); ssh_string_free(pubkey_s);
session->auth_state = SSH_AUTH_STATE_NONE; session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY; session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -536,7 +618,7 @@ int ssh_userauth_publickey(ssh_session session,
{ {
ssh_string str = NULL; ssh_string str = NULL;
int rc; int rc;
const char *type_c; const char *sig_type_c = NULL;
enum ssh_keytypes_e key_type; enum ssh_keytypes_e key_type;
if (session == NULL) { if (session == NULL) {
@@ -560,6 +642,37 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
switch (key_type) {
case SSH_KEYTYPE_UNKNOWN:
ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)");
return SSH_AUTH_DENIED;
case SSH_KEYTYPE_ECDSA:
sig_type_c = ssh_pki_key_ecdsa_name(privkey);
break;
case SSH_KEYTYPE_DSS:
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_DSS_CERT01:
case SSH_KEYTYPE_RSA_CERT01:
sig_type_c = ssh_key_get_signature_algorithm(session, key_type);
break;
}
/* Check if the given public key algorithm is allowed */
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by"
" PUBLICKEY_ACCEPTED_TYPES configuration option",
sig_type_c);
return SSH_AUTH_DENIED;
}
rc = ssh_userauth_request_service(session); rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) { if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN; return SSH_AUTH_AGAIN;
@@ -567,10 +680,6 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
type_c = ssh_key_type_to_char(key_type);
/* get public key or cert */ /* get public key or cert */
rc = ssh_pki_export_pubkey_blob(privkey, &str); rc = ssh_pki_export_pubkey_blob(privkey, &str);
if (rc < 0) { if (rc < 0) {
@@ -584,7 +693,7 @@ int ssh_userauth_publickey(ssh_session session,
"ssh-connection", "ssh-connection",
"publickey", "publickey",
1, /* private key */ 1, /* private key */
type_c, /* algo */ sig_type_c, /* algo */
str /* public key or cert */ str /* public key or cert */
); );
if (rc < 0) { if (rc < 0) {
@@ -605,7 +714,8 @@ int ssh_userauth_publickey(ssh_session session,
goto fail; goto fail;
} }
session->auth_state = SSH_AUTH_STATE_NONE; session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY; session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -632,7 +742,9 @@ static int ssh_userauth_agent_publickey(ssh_session session,
const char *username, const char *username,
ssh_key pubkey) ssh_key pubkey)
{ {
ssh_string str = NULL; ssh_string pubkey_s = NULL;
ssh_string sig_blob = NULL;
const char *sig_type_c = NULL;
int rc; int rc;
switch(session->pending_call_state) { switch(session->pending_call_state) {
@@ -654,12 +766,22 @@ static int ssh_userauth_agent_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
/* public key */ /* public key */
rc = ssh_pki_export_pubkey_blob(pubkey, &str); rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s);
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
/* Check if the given public key algorithm is allowed */
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by"
" PUBLICKEY_ACCEPTED_TYPES configuration option",
sig_type_c);
SSH_STRING_FREE(pubkey_s);
return SSH_AUTH_DENIED;
}
/* request */ /* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
@@ -668,29 +790,28 @@ static int ssh_userauth_agent_publickey(ssh_session session,
"ssh-connection", "ssh-connection",
"publickey", "publickey",
1, /* private key */ 1, /* private key */
pubkey->type_c, /* algo */ sig_type_c, /* algo */
str /* public key */ pubkey_s /* public key */
); );
SSH_STRING_FREE(pubkey_s);
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
ssh_string_free(str);
/* sign the buffer with the private key */ /* sign the buffer with the private key */
str = ssh_pki_do_sign_agent(session, session->out_buffer, pubkey); sig_blob = ssh_pki_do_sign_agent(session, session->out_buffer, pubkey);
if (str == NULL) { if (sig_blob == NULL) {
goto fail; goto fail;
} }
rc = ssh_buffer_add_ssh_string(session->out_buffer, str); rc = ssh_buffer_add_ssh_string(session->out_buffer, sig_blob);
ssh_string_free(str); SSH_STRING_FREE(sig_blob);
str = NULL;
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
session->auth_state = SSH_AUTH_STATE_NONE; session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT; session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -707,7 +828,7 @@ pending:
fail: fail:
ssh_set_error_oom(session); ssh_set_error_oom(session);
ssh_buffer_reinit(session->out_buffer); ssh_buffer_reinit(session->out_buffer);
ssh_string_free(str); SSH_STRING_FREE(pubkey_s);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
@@ -905,23 +1026,22 @@ int ssh_userauth_publickey_auto(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
if (! (session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH)) { if (! (session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH)) {
session->auth_methods &= ~SSH_AUTH_METHOD_PUBLICKEY; session->auth.supported_methods &= ~SSH_AUTH_METHOD_PUBLICKEY;
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
if (session->common.callbacks) { if (session->common.callbacks) {
auth_fn = session->common.callbacks->auth_function; auth_fn = session->common.callbacks->auth_function;
auth_data = session->common.callbacks->userdata; auth_data = session->common.callbacks->userdata;
} }
if (!session->auth_auto_state) { if (!session->auth.auto_state) {
session->auth_auto_state = session->auth.auto_state =
malloc(sizeof(struct ssh_auth_auto_state_struct)); calloc(1, sizeof(struct ssh_auth_auto_state_struct));
if (!session->auth_auto_state) { if (!session->auth.auto_state) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
ZERO_STRUCTP(session->auth_auto_state);
} }
state = session->auth_auto_state; state = session->auth.auto_state;
if (state->state == SSH_AUTH_AUTO_STATE_NONE) { if (state->state == SSH_AUTH_AUTO_STATE_NONE) {
#ifndef _WIN32 #ifndef _WIN32
/* Try authentication with ssh-agent first */ /* Try authentication with ssh-agent first */
@@ -954,7 +1074,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
SSH_FATAL, SSH_FATAL,
"Failed to import public key: %s", "Failed to import public key: %s",
pubkey_file); pubkey_file);
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth.auto_state);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} else if (rc == SSH_EOF) { } else if (rc == SSH_EOF) {
/* Read the private key and save the public key to file */ /* Read the private key and save the public key to file */
@@ -982,7 +1102,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
rc = ssh_pki_export_privkey_to_pubkey(state->privkey, &state->pubkey); rc = ssh_pki_export_privkey_to_pubkey(state->privkey, &state->pubkey);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
ssh_key_free(state->privkey); ssh_key_free(state->privkey);
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth.auto_state);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
@@ -1003,7 +1123,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
privkey_file); privkey_file);
ssh_key_free(state->privkey); ssh_key_free(state->privkey);
ssh_key_free(state->pubkey); ssh_key_free(state->pubkey);
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth.auto_state);
return rc; return rc;
} else if (rc == SSH_AUTH_AGAIN) { } else if (rc == SSH_AUTH_AGAIN) {
return rc; return rc;
@@ -1056,7 +1176,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
if (rc != SSH_AUTH_AGAIN && rc != SSH_AUTH_DENIED) { if (rc != SSH_AUTH_AGAIN && rc != SSH_AUTH_DENIED) {
ssh_key_free(state->privkey); ssh_key_free(state->privkey);
ssh_key_free(state->pubkey); ssh_key_free(state->pubkey);
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth.auto_state);
if (rc == SSH_AUTH_SUCCESS) { if (rc == SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO, SSH_LOG(SSH_LOG_INFO,
"Successfully authenticated using %s", "Successfully authenticated using %s",
@@ -1077,7 +1197,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
} }
SSH_LOG(SSH_LOG_INFO, SSH_LOG(SSH_LOG_INFO,
"Tried every public key, none matched"); "Tried every public key, none matched");
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth.auto_state);
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
@@ -1121,7 +1241,7 @@ int ssh_userauth_password(ssh_session session,
switch(session->pending_call_state) { switch(session->pending_call_state) {
case SSH_PENDING_CALL_NONE: case SSH_PENDING_CALL_NONE:
break; break;
case SSH_PENDING_CALL_AUTH_OFFER_PUBKEY: case SSH_PENDING_CALL_AUTH_PASSWORD:
goto pending; goto pending;
default: default:
ssh_set_error(session, ssh_set_error(session,
@@ -1151,8 +1271,9 @@ int ssh_userauth_password(ssh_session session,
goto fail; goto fail;
} }
session->auth_state = SSH_AUTH_STATE_NONE; session->auth.current_method = SSH_AUTH_METHOD_PASSWORD;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY; session->auth.state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
@@ -1228,7 +1349,9 @@ void ssh_kbdint_free(ssh_kbdint kbd) {
n = kbd->nprompts; n = kbd->nprompts;
if (kbd->prompts) { if (kbd->prompts) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
explicit_bzero(kbd->prompts[i], strlen(kbd->prompts[i])); if (kbd->prompts[i] != NULL) {
explicit_bzero(kbd->prompts[i], strlen(kbd->prompts[i]));
}
SAFE_FREE(kbd->prompts[i]); SAFE_FREE(kbd->prompts[i]);
} }
SAFE_FREE(kbd->prompts); SAFE_FREE(kbd->prompts);
@@ -1237,7 +1360,9 @@ void ssh_kbdint_free(ssh_kbdint kbd) {
n = kbd->nanswers; n = kbd->nanswers;
if (kbd->answers) { if (kbd->answers) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
explicit_bzero(kbd->answers[i], strlen(kbd->answers[i])); if (kbd->answers[i] != NULL) {
explicit_bzero(kbd->answers[i], strlen(kbd->answers[i]));
}
SAFE_FREE(kbd->answers[i]); SAFE_FREE(kbd->answers[i]);
} }
SAFE_FREE(kbd->answers); SAFE_FREE(kbd->answers);
@@ -1319,7 +1444,7 @@ static int ssh_userauth_kbdint_init(ssh_session session,
} }
session->auth_state = SSH_AUTH_STATE_KBDINT_SENT; session->auth.state = SSH_AUTH_STATE_KBDINT_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_INIT; session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_INIT;
SSH_LOG(SSH_LOG_DEBUG, SSH_LOG(SSH_LOG_DEBUG,
@@ -1378,7 +1503,8 @@ static int ssh_userauth_kbdint_send(ssh_session session)
} }
} }
session->auth_state = SSH_AUTH_STATE_KBDINT_SENT; session->auth.current_method = SSH_AUTH_METHOD_INTERACTIVE;
session->auth.state = SSH_AUTH_STATE_KBDINT_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_SEND; session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_SEND;
ssh_kbdint_free(session->kbdint); ssh_kbdint_free(session->kbdint);
session->kbdint = NULL; session->kbdint = NULL;
@@ -1468,7 +1594,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
session->kbdint->echo = malloc(nprompts); session->kbdint->echo = calloc(nprompts, sizeof(unsigned char));
if (session->kbdint->echo == NULL) { if (session->kbdint->echo == NULL) {
session->kbdint->nprompts = 0; session->kbdint->nprompts = 0;
ssh_set_error_oom(session); ssh_set_error_oom(session);
@@ -1477,7 +1603,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
memset(session->kbdint->echo, 0, nprompts);
for (i = 0; i < nprompts; i++) { for (i = 0; i < nprompts; i++) {
rc = ssh_buffer_unpack(packet, "sb", rc = ssh_buffer_unpack(packet, "sb",
@@ -1491,7 +1616,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
} }
session->auth_state=SSH_AUTH_STATE_INFO; session->auth.state=SSH_AUTH_STATE_INFO;
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
@@ -1791,12 +1916,14 @@ int ssh_userauth_gssapi(ssh_session session) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi-with-mic"); SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi-with-mic");
session->auth_state = SSH_AUTH_STATE_NONE;
session->auth.current_method = SSH_AUTH_METHOD_GSSAPI_MIC;
session->auth.state = SSH_AUTH_STATE_NONE;
session->pending_call_state = SSH_PENDING_CALL_AUTH_GSSAPI_MIC; session->pending_call_state = SSH_PENDING_CALL_AUTH_GSSAPI_MIC;
rc = ssh_gssapi_auth_mic(session); rc = ssh_gssapi_auth_mic(session);
if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_DENIED) { if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_DENIED) {
session->auth_state = SSH_AUTH_STATE_NONE; session->auth.state = SSH_AUTH_STATE_NONE;
session->pending_call_state = SSH_PENDING_CALL_NONE; session->pending_call_state = SSH_PENDING_CALL_NONE;
return rc; return rc;
} }

View File

@@ -69,7 +69,7 @@ ssh_string ssh_make_bignum_string(bignum num) {
bignum ssh_make_string_bn(ssh_string string){ bignum ssh_make_string_bn(ssh_string string){
bignum bn = NULL; bignum bn = NULL;
unsigned int len = ssh_string_len(string); size_t len = ssh_string_len(string);
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n", fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
@@ -88,12 +88,12 @@ bignum ssh_make_string_bn(ssh_string string){
return bn; return bn;
} }
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout) { void ssh_make_string_bn_inplace(ssh_string string,
unsigned int len = ssh_string_len(string); UNUSED_PARAM(bignum bnout))
{
UNUSED_VAR(size_t len) = ssh_string_len(string);
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
/* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */ /* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */
(void) len;
(void) bnout;
#elif defined HAVE_LIBCRYPTO #elif defined HAVE_LIBCRYPTO
bignum_bin2bn(string->data, len, bnout); bignum_bin2bn(string->data, len, bnout);
#elif defined HAVE_LIBMBEDCRYPTO #elif defined HAVE_LIBMBEDCRYPTO

View File

@@ -447,7 +447,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
return SSH_ERROR; return SSH_ERROR;
} }
ssh_socket_set_fd(session->socket, fd); ssh_socket_set_fd(session->socket, fd);
ssh_socket_get_poll_handle_out(session->socket); ssh_socket_get_poll_handle(session->socket);
/* We must try to import any keys that could be imported in case /* We must try to import any keys that could be imported in case
* we are not using ssh_bind_listen (which is the other place * we are not using ssh_bind_listen (which is the other place

View File

@@ -25,6 +25,7 @@
#include <limits.h> #include <limits.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#ifndef _WIN32 #ifndef _WIN32
#include <netinet/in.h> #include <netinet/in.h>
@@ -36,6 +37,24 @@
#include "libssh/misc.h" #include "libssh/misc.h"
#include "libssh/bignum.h" #include "libssh/bignum.h"
/*
* Describes a buffer state
* [XXXXXXXXXXXXDATA PAYLOAD XXXXXXXXXXXXXXXXXXXXXXXX]
* ^ ^ ^ ^]
* \_data points\_pos points here \_used points here | /
* here Allocated
*/
struct ssh_buffer_struct {
bool secure;
size_t used;
size_t allocated;
size_t pos;
uint8_t *data;
};
/* Buffer size maximum is 256M */
#define BUFFER_SIZE_MAX 0x10000000
/** /**
* @defgroup libssh_buffer The SSH buffer functions. * @defgroup libssh_buffer The SSH buffer functions.
* @ingroup libssh * @ingroup libssh
@@ -54,24 +73,38 @@
* *
* @param[in] buf The buffer to check. * @param[in] buf The buffer to check.
*/ */
static void buffer_verify(ssh_buffer buf){ static void buffer_verify(ssh_buffer buf)
int doabort=0; {
if(buf->data == NULL) bool do_abort = false;
return;
if(buf->used > buf->allocated){ if (buf->data == NULL) {
fprintf(stderr,"Buffer error : allocated %u, used %u\n",buf->allocated, buf->used); return;
doabort=1; }
}
if(buf->pos > buf->used){ if (buf->used > buf->allocated) {
fprintf(stderr,"Buffer error : position %u, used %u\n",buf->pos, buf->used); fprintf(stderr,
doabort=1; "BUFFER ERROR: allocated %zu, used %zu\n",
} buf->allocated,
if(buf->pos > buf->allocated){ buf->used);
fprintf(stderr,"Buffer error : position %u, allocated %u\n",buf->pos, buf->allocated); do_abort = true;
doabort=1; }
} if (buf->pos > buf->used) {
if(doabort) fprintf(stderr,
abort(); "BUFFER ERROR: position %zu, used %zu\n",
buf->pos,
buf->used);
do_abort = true;
}
if (buf->pos > buf->allocated) {
fprintf(stderr,
"BUFFER ERROR: position %zu, allocated %zu\n",
buf->pos,
buf->allocated);
do_abort = true;
}
if (do_abort) {
abort();
}
} }
#else #else
@@ -83,15 +116,29 @@ static void buffer_verify(ssh_buffer buf){
* *
* @return A newly initialized SSH buffer, NULL on error. * @return A newly initialized SSH buffer, NULL on error.
*/ */
struct ssh_buffer_struct *ssh_buffer_new(void) { struct ssh_buffer_struct *ssh_buffer_new(void)
struct ssh_buffer_struct *buf = {
calloc(1, sizeof(struct ssh_buffer_struct)); struct ssh_buffer_struct *buf = NULL;
if (buf == NULL) { int rc;
return NULL;
}
buffer_verify(buf); buf = calloc(1, sizeof(struct ssh_buffer_struct));
return buf; if (buf == NULL) {
return NULL;
}
/*
* Always preallocate 64 bytes.
*
* -1 for ralloc_buffer magic.
*/
rc = ssh_buffer_allocate_size(buf, 64 - 1);
if (rc != 0) {
SAFE_FREE(buf);
return NULL;
}
buffer_verify(buf);
return buf;
} }
/** /**
@@ -99,19 +146,23 @@ struct ssh_buffer_struct *ssh_buffer_new(void) {
* *
* \param[in] buffer The buffer to free. * \param[in] buffer The buffer to free.
*/ */
void ssh_buffer_free(struct ssh_buffer_struct *buffer) { void ssh_buffer_free(struct ssh_buffer_struct *buffer)
if (buffer == NULL) { {
return; if (buffer == NULL) {
} return;
buffer_verify(buffer); }
buffer_verify(buffer);
if (buffer->data) { if (buffer->secure && buffer->allocated > 0) {
/* burn the data */ /* burn the data */
explicit_bzero(buffer->data, buffer->allocated); explicit_bzero(buffer->data, buffer->allocated);
SAFE_FREE(buffer->data); SAFE_FREE(buffer->data);
}
explicit_bzero(buffer, sizeof(struct ssh_buffer_struct)); explicit_bzero(buffer, sizeof(struct ssh_buffer_struct));
SAFE_FREE(buffer); } else {
SAFE_FREE(buffer->data);
}
SAFE_FREE(buffer);
} }
/** /**
@@ -122,13 +173,15 @@ void ssh_buffer_free(struct ssh_buffer_struct *buffer) {
* *
* @param[in] buffer buffer to set secure. * @param[in] buffer buffer to set secure.
*/ */
void ssh_buffer_set_secure(ssh_buffer buffer){ void ssh_buffer_set_secure(ssh_buffer buffer)
buffer->secure = 1; {
buffer->secure = true;
} }
static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) { static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed)
{
size_t smallest = 1; size_t smallest = 1;
char *new; uint8_t *new = NULL;
buffer_verify(buffer); buffer_verify(buffer);
@@ -140,25 +193,28 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
smallest <<= 1; smallest <<= 1;
} }
needed = smallest; needed = smallest;
if (buffer->secure){
if (needed > BUFFER_SIZE_MAX) {
return -1;
}
if (buffer->secure) {
new = malloc(needed); new = malloc(needed);
if (new == NULL) { if (new == NULL) {
return -1; return -1;
} }
if (buffer->used > 0) { memcpy(new, buffer->data, buffer->used);
memcpy(new, buffer->data,buffer->used); explicit_bzero(buffer->data, buffer->used);
explicit_bzero(buffer->data, buffer->used); SAFE_FREE(buffer->data);
SAFE_FREE(buffer->data);
}
} else { } else {
new = realloc(buffer->data, needed); new = realloc(buffer->data, needed);
if (new == NULL) { if (new == NULL) {
buffer->data = NULL;
return -1; return -1;
} }
} }
buffer->data = new; buffer->data = new;
buffer->allocated = needed; buffer->allocated = needed;
buffer_verify(buffer); buffer_verify(buffer);
return 0; return 0;
} }
@@ -167,45 +223,64 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
* @brief shifts a buffer to remove unused data in the beginning * @brief shifts a buffer to remove unused data in the beginning
* @param buffer SSH buffer * @param buffer SSH buffer
*/ */
static void buffer_shift(ssh_buffer buffer){ static void buffer_shift(ssh_buffer buffer)
uint32_t burn_pos = buffer->pos; {
size_t burn_pos = buffer->pos;
buffer_verify(buffer); buffer_verify(buffer);
if(buffer->pos==0)
return;
memmove(buffer->data, buffer->data + buffer->pos, buffer->used - buffer->pos);
buffer->used -= buffer->pos;
buffer->pos=0;
if (buffer->secure){ if (buffer->pos == 0) {
void *ptr = buffer->data + buffer->used; return;
explicit_bzero(ptr, burn_pos); }
} memmove(buffer->data,
buffer->data + buffer->pos,
buffer->used - buffer->pos);
buffer->used -= buffer->pos;
buffer->pos = 0;
buffer_verify(buffer); if (buffer->secure) {
void *ptr = buffer->data + buffer->used;
explicit_bzero(ptr, burn_pos);
}
buffer_verify(buffer);
} }
/** /**
* @brief Reinitialize a SSH buffer. * @brief Reinitialize a SSH buffer.
* *
* In case the buffer has exceeded 64K in size, the buffer will be reallocated
* to 64K.
*
* @param[in] buffer The buffer to reinitialize. * @param[in] buffer The buffer to reinitialize.
* *
* @return 0 on success, < 0 on error. * @return 0 on success, < 0 on error.
*/ */
int ssh_buffer_reinit(struct ssh_buffer_struct *buffer) int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
{ {
if (buffer == NULL) {
return -1;
}
buffer_verify(buffer); buffer_verify(buffer);
if (buffer->used > 0) {
explicit_bzero(buffer->data, buffer->used); if (buffer->secure && buffer->allocated > 0) {
explicit_bzero(buffer->data, buffer->allocated);
} }
buffer->used = 0; buffer->used = 0;
buffer->pos = 0; buffer->pos = 0;
if (buffer->allocated > 127) { /* If the buffer is bigger then 64K, reset it to 64K */
if (realloc_buffer(buffer, 127) < 0) { if (buffer->allocated > 65536) {
int rc;
/* -1 for realloc_buffer magic */
rc = realloc_buffer(buffer, 65536 - 1);
if (rc != 0) {
return -1; return -1;
} }
} }
buffer_verify(buffer); buffer_verify(buffer);
return 0; return 0;
@@ -683,32 +758,149 @@ int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len)
* *
* @returns The SSH String, NULL on error. * @returns The SSH String, NULL on error.
*/ */
struct ssh_string_struct *ssh_buffer_get_ssh_string(struct ssh_buffer_struct *buffer) { struct ssh_string_struct *
uint32_t stringlen; ssh_buffer_get_ssh_string(struct ssh_buffer_struct *buffer)
uint32_t hostlen; {
struct ssh_string_struct *str = NULL; uint32_t stringlen;
int rc; uint32_t hostlen;
struct ssh_string_struct *str = NULL;
int rc;
if (ssh_buffer_get_u32(buffer, &stringlen) == 0) { rc = ssh_buffer_get_u32(buffer, &stringlen);
return NULL; if (rc == 0) {
} return NULL;
hostlen = ntohl(stringlen); }
/* verify if there is enough space in buffer to get it */ hostlen = ntohl(stringlen);
rc = ssh_buffer_validate_length(buffer, hostlen); /* verify if there is enough space in buffer to get it */
if (rc != SSH_OK) { rc = ssh_buffer_validate_length(buffer, hostlen);
return NULL; /* it is indeed */ if (rc != SSH_OK) {
} return NULL; /* it is indeed */
str = ssh_string_new(hostlen); }
if (str == NULL) { str = ssh_string_new(hostlen);
return NULL; if (str == NULL) {
} return NULL;
if (ssh_buffer_get_data(buffer, ssh_string_data(str), hostlen) != hostlen) { }
/* should never happen */
SAFE_FREE(str);
return NULL;
}
return str; stringlen = ssh_buffer_get_data(buffer, ssh_string_data(str), hostlen);
if (stringlen != hostlen) {
/* should never happen */
SAFE_FREE(str);
return NULL;
}
return str;
}
/**
* @brief Pre-calculate the size we need for packing the buffer.
*
* This makes sure that enough memory is allocated for packing the buffer and
* we only have to do one memory allocation.
*
* @param[in] buffer The buffer to allocate
*
* @param[in] format A format string of arguments.
*
* @param[in] argc The number of arguments.
*
* @param[in] ap The va_list of arguments.
*
* @return SSH_OK on success, SSH_ERROR on error.
*/
static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
va_list ap)
{
const char *p = NULL;
ssh_string string = NULL;
char *cstring = NULL;
size_t needed_size = 0;
size_t len;
size_t count;
int rc = SSH_OK;
for (p = format, count = 0; *p != '\0'; p++, count++) {
/* Invalid number of arguments passed */
if (count > argc) {
return SSH_ERROR;
}
switch(*p) {
case 'b':
va_arg(ap, unsigned int);
needed_size += sizeof(uint8_t);
break;
case 'w':
va_arg(ap, unsigned int);
needed_size += sizeof(uint16_t);
break;
case 'd':
va_arg(ap, uint32_t);
needed_size += sizeof(uint32_t);
break;
case 'q':
va_arg(ap, uint64_t);
needed_size += sizeof(uint64_t);
break;
case 'S':
string = va_arg(ap, ssh_string);
needed_size += 4 + ssh_string_len(string);
string = NULL;
break;
case 's':
cstring = va_arg(ap, char *);
needed_size += sizeof(uint32_t) + strlen(cstring);
cstring = NULL;
break;
case 'P':
len = va_arg(ap, size_t);
needed_size += len;
va_arg(ap, void *);
count++; /* increase argument count */
break;
case 'B':
va_arg(ap, bignum);
/*
* Use a fixed size for a bignum
* (they should normaly be around 32)
*/
needed_size += 64;
break;
case 't':
cstring = va_arg(ap, char *);
needed_size += strlen(cstring);
cstring = NULL;
break;
default:
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
rc = SSH_ERROR;
}
if (rc != SSH_OK){
break;
}
}
if (argc != count) {
return SSH_ERROR;
}
if (rc != SSH_ERROR){
/*
* Check if our canary is intact, if not, something really bad happened.
*/
uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END) {
abort();
}
}
rc = ssh_buffer_allocate_size(buffer, needed_size);
if (rc != 0) {
return SSH_ERROR;
}
return SSH_OK;
} }
/** @internal /** @internal
@@ -722,7 +914,7 @@ struct ssh_string_struct *ssh_buffer_get_ssh_string(struct ssh_buffer_struct *bu
*/ */
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format, const char *format,
int argc, size_t argc,
va_list ap) va_list ap)
{ {
int rc = SSH_ERROR; int rc = SSH_ERROR;
@@ -738,11 +930,15 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
char *cstring; char *cstring;
bignum b; bignum b;
size_t len; size_t len;
int count; size_t count;
if (argc > 256) {
return SSH_ERROR;
}
for (p = format, count = 0; *p != '\0'; p++, count++) { for (p = format, count = 0; *p != '\0'; p++, count++) {
/* Invalid number of arguments passed */ /* Invalid number of arguments passed */
if (argc != -1 && count > argc) { if (count > argc) {
return SSH_ERROR; return SSH_ERROR;
} }
@@ -814,7 +1010,7 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
} }
} }
if (argc != -1 && argc != count) { if (argc != count) {
return SSH_ERROR; return SSH_ERROR;
} }
@@ -822,11 +1018,7 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
/* Check if our canary is intact, if not somthing really bad happened */ /* Check if our canary is intact, if not somthing really bad happened */
uint32_t canary = va_arg(ap, uint32_t); uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END) { if (canary != SSH_BUFFER_PACK_END) {
if (argc == -1){ abort();
return SSH_ERROR;
} else {
abort();
}
} }
} }
return rc; return rc;
@@ -854,15 +1046,28 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
*/ */
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer, int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
const char *format, const char *format,
int argc, size_t argc,
...) ...)
{ {
va_list ap; va_list ap;
int rc; int rc;
if (argc > 256) {
return SSH_ERROR;
}
va_start(ap, argc);
rc = ssh_buffer_pack_allocate_va(buffer, format, argc, ap);
va_end(ap);
if (rc != SSH_OK) {
return rc;
}
va_start(ap, argc); va_start(ap, argc);
rc = ssh_buffer_pack_va(buffer, format, argc, ap); rc = ssh_buffer_pack_va(buffer, format, argc, ap);
va_end(ap); va_end(ap);
return rc; return rc;
} }
@@ -893,7 +1098,7 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
} o; } o;
size_t len, rlen, max_len; size_t len, rlen, max_len;
va_list ap_copy; va_list ap_copy;
int count; int count; /* int for size comparison with argc */
max_len = ssh_buffer_get_len(buffer); max_len = ssh_buffer_get_len(buffer);
@@ -903,8 +1108,8 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
for (p = format, count = 0; *p != '\0'; p++, count++) { for (p = format, count = 0; *p != '\0'; p++, count++) {
/* Invalid number of arguments passed */ /* Invalid number of arguments passed */
if (argc != -1 && count > argc) { if (argc != -1 && count > argc) {
va_end(ap_copy); rc = SSH_ERROR;
return SSH_ERROR; goto cleanup;
} }
switch (*p) { switch (*p) {
@@ -1016,8 +1221,9 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
rc = SSH_ERROR; rc = SSH_ERROR;
} }
cleanup:
if (rc != SSH_ERROR){ if (rc != SSH_ERROR){
/* Check if our canary is intact, if not somthing really bad happened */ /* Check if our canary is intact, if not something really bad happened */
uint32_t canary = va_arg(ap, uint32_t); uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END){ if (canary != SSH_BUFFER_PACK_END){
if (argc == -1){ if (argc == -1){
@@ -1034,22 +1240,53 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
for(p=format;p<last;++p){ for(p=format;p<last;++p){
switch(*p){ switch(*p){
case 'b': case 'b':
o.byte = va_arg(ap_copy, uint8_t *);
if (buffer->secure) {
explicit_bzero(o.byte, sizeof(uint8_t));
break;
}
break;
case 'w': case 'w':
o.word = va_arg(ap_copy, uint16_t *);
if (buffer->secure) {
explicit_bzero(o.word, sizeof(uint16_t));
break;
}
break;
case 'd': case 'd':
o.dword = va_arg(ap_copy, uint32_t *);
if (buffer->secure) {
explicit_bzero(o.dword, sizeof(uint32_t));
break;
}
break;
case 'q': case 'q':
(void)va_arg(ap_copy, void *); o.qword = va_arg(ap_copy, uint64_t *);
if (buffer->secure) {
explicit_bzero(o.qword, sizeof(uint64_t));
break;
}
break; break;
case 'S': case 'S':
o.string=va_arg(ap_copy, ssh_string *); o.string = va_arg(ap_copy, ssh_string *);
if (buffer->secure) {
ssh_string_burn(*o.string);
}
SAFE_FREE(*o.string); SAFE_FREE(*o.string);
break; break;
case 's': case 's':
o.cstring=va_arg(ap_copy, char **); o.cstring = va_arg(ap_copy, char **);
if (buffer->secure) {
explicit_bzero(*o.cstring, strlen(*o.cstring));
}
SAFE_FREE(*o.cstring); SAFE_FREE(*o.cstring);
break; break;
case 'P': case 'P':
(void)va_arg(ap_copy, size_t); len = va_arg(ap_copy, size_t);
o.data = va_arg(ap_copy, void **); o.data = va_arg(ap_copy, void **);
if (buffer->secure) {
explicit_bzero(*o.data, len);
}
SAFE_FREE(*o.data); SAFE_FREE(*o.data);
break; break;
default: default:

View File

@@ -192,6 +192,7 @@ static void chacha20_cleanup(struct ssh_cipher_struct *cipher) {
} }
const struct ssh_cipher_struct chacha20poly1305_cipher = { const struct ssh_cipher_struct chacha20poly1305_cipher = {
.ciphertype = SSH_AEAD_CHACHA20_POLY1305,
.name = "chacha20-poly1305@openssh.com", .name = "chacha20-poly1305@openssh.com",
.blocksize = 8, .blocksize = 8,
.lenfield_blocksize = 4, .lenfield_blocksize = 4,

View File

@@ -76,44 +76,46 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet);
* *
* @return A pointer to a newly allocated channel, NULL on error. * @return A pointer to a newly allocated channel, NULL on error.
*/ */
ssh_channel ssh_channel_new(ssh_session session) { ssh_channel ssh_channel_new(ssh_session session)
ssh_channel channel = NULL; {
ssh_channel channel = NULL;
if(session == NULL) { if (session == NULL) {
return NULL; return NULL;
} }
channel = malloc(sizeof(struct ssh_channel_struct)); channel = calloc(1, sizeof(struct ssh_channel_struct));
if (channel == NULL) { if (channel == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
return NULL; return NULL;
} }
memset(channel,0,sizeof(struct ssh_channel_struct));
channel->stdout_buffer = ssh_buffer_new(); channel->stdout_buffer = ssh_buffer_new();
if (channel->stdout_buffer == NULL) { if (channel->stdout_buffer == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
SAFE_FREE(channel); SAFE_FREE(channel);
return NULL; return NULL;
} }
channel->stderr_buffer = ssh_buffer_new(); channel->stderr_buffer = ssh_buffer_new();
if (channel->stderr_buffer == NULL) { if (channel->stderr_buffer == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
ssh_buffer_free(channel->stdout_buffer); ssh_buffer_free(channel->stdout_buffer);
SAFE_FREE(channel); SAFE_FREE(channel);
return NULL; return NULL;
} }
channel->session = session; channel->session = session;
channel->exit_status = -1; channel->exit_status = -1;
channel->flags = SSH_CHANNEL_FLAG_NOT_BOUND; channel->flags = SSH_CHANNEL_FLAG_NOT_BOUND;
if(session->channels == NULL) { if (session->channels == NULL) {
session->channels = ssh_list_new(); session->channels = ssh_list_new();
} }
ssh_list_prepend(session->channels, channel);
return channel; ssh_list_prepend(session->channels, channel);
return channel;
} }
/** /**
@@ -169,6 +171,15 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
"Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d", "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
channel->local_channel, channel->local_channel,
channel->remote_channel); channel->remote_channel);
if (channel->state != SSH_CHANNEL_STATE_OPENING) {
SSH_LOG(SSH_LOG_RARE,
"SSH2_MSG_CHANNEL_OPEN_CONFIRMATION received in incorrect "
"channel state %d",
channel->state);
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, SSH_LOG(SSH_LOG_PROTOCOL,
"Remote window : %lu, maxpacket : %lu", "Remote window : %lu, maxpacket : %lu",
(long unsigned int) channel->remote_window, (long unsigned int) channel->remote_window,
@@ -209,6 +220,14 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
if (channel->state != SSH_CHANNEL_STATE_OPENING) {
SSH_LOG(SSH_LOG_RARE,
"SSH2_MSG_CHANNEL_OPEN_FAILURE received in incorrect channel "
"state %d",
channel->state);
goto error;
}
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session, SSH_REQUEST_DENIED,
"Channel opening failure: channel %u error (%lu) %s", "Channel opening failure: channel %u error (%lu) %s",
channel->local_channel, channel->local_channel,
@@ -217,6 +236,10 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
SAFE_FREE(error); SAFE_FREE(error);
channel->state=SSH_CHANNEL_STATE_OPEN_DENIED; channel->state=SSH_CHANNEL_STATE_OPEN_DENIED;
return SSH_PACKET_USED; return SSH_PACKET_USED;
error:
ssh_set_error(session, SSH_FATAL, "Invalid packet");
return SSH_PACKET_USED;
} }
static int ssh_channel_open_termination(void *c){ static int ssh_channel_open_termination(void *c){
@@ -660,6 +683,10 @@ SSH_PACKET_CALLBACK(channel_rcv_request) {
if (strcmp(request,"exit-status") == 0) { if (strcmp(request,"exit-status") == 0) {
SAFE_FREE(request); SAFE_FREE(request);
rc = ssh_buffer_unpack(packet, "d", &channel->exit_status); rc = ssh_buffer_unpack(packet, "d", &channel->exit_status);
if (rc != SSH_OK) {
SSH_LOG(SSH_LOG_PACKET, "Invalid exit-status packet");
return SSH_PACKET_USED;
}
SSH_LOG(SSH_LOG_PACKET, "received exit-status %d", channel->exit_status); SSH_LOG(SSH_LOG_PACKET, "received exit-status %d", channel->exit_status);
ssh_callbacks_execute_list(channel->callbacks, ssh_callbacks_execute_list(channel->callbacks,
@@ -1005,22 +1032,24 @@ void ssh_channel_free(ssh_channel channel) {
* @brief Effectively free a channel, without caring about flags * @brief Effectively free a channel, without caring about flags
*/ */
void ssh_channel_do_free(ssh_channel channel){ void ssh_channel_do_free(ssh_channel channel)
struct ssh_iterator *it; {
ssh_session session = channel->session; struct ssh_iterator *it = NULL;
it = ssh_list_find(session->channels, channel); ssh_session session = channel->session;
if(it != NULL){
ssh_list_remove(session->channels, it);
}
ssh_buffer_free(channel->stdout_buffer);
ssh_buffer_free(channel->stderr_buffer);
if (channel->callbacks != NULL){
ssh_list_free(channel->callbacks);
}
/* debug trick to catch use after frees */ it = ssh_list_find(session->channels, channel);
memset(channel, 'X', sizeof(struct ssh_channel_struct)); if (it != NULL) {
SAFE_FREE(channel); ssh_list_remove(session->channels, it);
}
ssh_buffer_free(channel->stdout_buffer);
ssh_buffer_free(channel->stderr_buffer);
if (channel->callbacks != NULL) {
ssh_list_free(channel->callbacks);
}
SAFE_FREE(channel);
} }
/** /**
@@ -1051,43 +1080,47 @@ void ssh_channel_do_free(ssh_channel channel){
* @see ssh_channel_free() * @see ssh_channel_free()
* @see ssh_channel_is_eof() * @see ssh_channel_is_eof()
*/ */
int ssh_channel_send_eof(ssh_channel channel){ int ssh_channel_send_eof(ssh_channel channel)
ssh_session session; {
int rc = SSH_ERROR; ssh_session session;
int err; int rc = SSH_ERROR;
int err;
if(channel == NULL) { if(channel == NULL) {
return rc; return rc;
} }
session = channel->session; session = channel->session;
err = ssh_buffer_pack(session->out_buffer, err = ssh_buffer_pack(session->out_buffer,
"bd", "bd",
SSH2_MSG_CHANNEL_EOF, SSH2_MSG_CHANNEL_EOF,
channel->remote_channel); channel->remote_channel);
if (err != SSH_OK) { if (err != SSH_OK) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
goto error; goto error;
} }
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"Sent a EOF on client channel (%d:%d)", "Sent a EOF on client channel (%d:%d)",
channel->local_channel, channel->local_channel,
channel->remote_channel); channel->remote_channel);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_channel_flush(channel); rc = ssh_channel_flush(channel);
if(rc == SSH_ERROR) if (rc == SSH_ERROR) {
goto error; goto error;
}
channel->local_eof = 1;
channel->local_eof = 1; return rc;
return rc;
error: error:
ssh_buffer_reinit(session->out_buffer); ssh_buffer_reinit(session->out_buffer);
return rc; return rc;
} }
/** /**
@@ -2057,8 +2090,11 @@ static int ssh_global_request_termination(void *s){
* SSH_AGAIN if in nonblocking mode and call has * SSH_AGAIN if in nonblocking mode and call has
* to be done again. * to be done again.
*/ */
static int global_request(ssh_session session, const char *request, int ssh_global_request(ssh_session session,
ssh_buffer buffer, int reply) { const char *request,
ssh_buffer buffer,
int reply)
{
int rc; int rc;
switch (session->global_req_state) { switch (session->global_req_state) {
@@ -2189,7 +2225,7 @@ int ssh_channel_listen_forward(ssh_session session,
goto error; goto error;
} }
pending: pending:
rc = global_request(session, "tcpip-forward", buffer, 1); rc = ssh_global_request(session, "tcpip-forward", buffer, 1);
/* TODO: FIXME no guarantee the last packet we received contains /* TODO: FIXME no guarantee the last packet we received contains
* that info */ * that info */
@@ -2269,7 +2305,7 @@ int ssh_channel_cancel_forward(ssh_session session,
goto error; goto error;
} }
pending: pending:
rc = global_request(session, "cancel-tcpip-forward", buffer, 1); rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
error: error:
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -2631,7 +2667,11 @@ static int ssh_channel_read_termination(void *s){
*/ */
int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr) int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr)
{ {
return ssh_channel_read_timeout(channel, dest, count, is_stderr, -1); return ssh_channel_read_timeout(channel,
dest,
count,
is_stderr,
SSH_TIMEOUT_DEFAULT);
} }
/** /**
@@ -2661,7 +2701,7 @@ int ssh_channel_read_timeout(ssh_channel channel,
void *dest, void *dest,
uint32_t count, uint32_t count,
int is_stderr, int is_stderr,
int timeout) int timeout_ms)
{ {
ssh_session session; ssh_session session;
ssh_buffer stdbuf; ssh_buffer stdbuf;
@@ -2711,18 +2751,28 @@ int ssh_channel_read_timeout(ssh_channel channel,
ctx.buffer = stdbuf; ctx.buffer = stdbuf;
ctx.count = 1; ctx.count = 1;
if (timeout < 0) { if (timeout_ms < SSH_TIMEOUT_DEFAULT) {
timeout = SSH_TIMEOUT_DEFAULT; timeout_ms = SSH_TIMEOUT_INFINITE;
} }
rc = ssh_handle_packets_termination(session, rc = ssh_handle_packets_termination(session,
timeout, timeout_ms,
ssh_channel_read_termination, ssh_channel_read_termination,
&ctx); &ctx);
if (rc == SSH_ERROR){ if (rc == SSH_ERROR){
return rc; return rc;
} }
if (session->session_state == SSH_SESSION_STATE_ERROR){
/*
* If the channel is closed or in an error state, reading from it is an error
*/
if (session->session_state == SSH_SESSION_STATE_ERROR) {
return SSH_ERROR;
}
if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
ssh_set_error(session,
SSH_FATAL,
"Remote channel is closed.");
return SSH_ERROR; return SSH_ERROR;
} }
if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) { if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {

View File

@@ -180,7 +180,6 @@ int ssh_send_banner(ssh_session session, int server)
if (server == 1) { if (server == 1) {
if (session->opts.custombanner == NULL){ if (session->opts.custombanner == NULL){
len = strlen(banner);
session->serverbanner = strdup(banner); session->serverbanner = strdup(banner);
if (session->serverbanner == NULL) { if (session->serverbanner == NULL) {
goto end; goto end;
@@ -250,6 +249,8 @@ static int dh_handshake(ssh_session session) {
switch(session->next_crypto->kex_type){ switch(session->next_crypto->kex_type){
case SSH_KEX_DH_GROUP1_SHA1: case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1: case SSH_KEX_DH_GROUP14_SHA1:
case SSH_KEX_DH_GROUP16_SHA512:
case SSH_KEX_DH_GROUP18_SHA512:
rc = ssh_client_dh_init(session); rc = ssh_client_dh_init(session);
break; break;
#ifdef HAVE_ECDH #ifdef HAVE_ECDH
@@ -295,7 +296,7 @@ static int dh_handshake(ssh_session session) {
static int ssh_service_request_termination(void *s){ static int ssh_service_request_termination(void *s){
ssh_session session = (ssh_session)s; ssh_session session = (ssh_session)s;
if(session->session_state == SSH_SESSION_STATE_ERROR || if(session->session_state == SSH_SESSION_STATE_ERROR ||
session->auth_service_state != SSH_AUTH_SERVICE_SENT) session->auth.service_state != SSH_AUTH_SERVICE_SENT)
return 1; return 1;
else else
return 0; return 0;
@@ -319,7 +320,7 @@ static int ssh_service_request_termination(void *s){
int ssh_service_request(ssh_session session, const char *service) { int ssh_service_request(ssh_session session, const char *service) {
int rc=SSH_ERROR; int rc=SSH_ERROR;
if(session->auth_service_state != SSH_AUTH_SERVICE_NONE) if(session->auth.service_state != SSH_AUTH_SERVICE_NONE)
goto pending; goto pending;
rc = ssh_buffer_pack(session->out_buffer, rc = ssh_buffer_pack(session->out_buffer,
@@ -330,7 +331,7 @@ int ssh_service_request(ssh_session session, const char *service) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
return SSH_ERROR; return SSH_ERROR;
} }
session->auth_service_state=SSH_AUTH_SERVICE_SENT; session->auth.service_state = SSH_AUTH_SERVICE_SENT;
if (ssh_packet_send(session) == SSH_ERROR) { if (ssh_packet_send(session) == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Sending SSH2_MSG_SERVICE_REQUEST failed."); "Sending SSH2_MSG_SERVICE_REQUEST failed.");
@@ -345,7 +346,7 @@ pending:
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
return SSH_ERROR; return SSH_ERROR;
} }
switch(session->auth_service_state){ switch(session->auth.service_state) {
case SSH_AUTH_SERVICE_DENIED: case SSH_AUTH_SERVICE_DENIED:
ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied"); ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied");
break; break;
@@ -409,6 +410,14 @@ static void ssh_client_connection_callback(ssh_session session)
ssh_packet_set_default_callbacks(session); ssh_packet_set_default_callbacks(session);
session->session_state = SSH_SESSION_STATE_INITIAL_KEX; session->session_state = SSH_SESSION_STATE_INITIAL_KEX;
rc = ssh_set_client_kex(session);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_send_kex(session, 0);
if (rc < 0) {
goto error;
}
set_status(session, 0.5f); set_status(session, 0.5f);
break; break;
@@ -418,14 +427,19 @@ static void ssh_client_connection_callback(ssh_session session)
case SSH_SESSION_STATE_KEXINIT_RECEIVED: case SSH_SESSION_STATE_KEXINIT_RECEIVED:
set_status(session,0.6f); set_status(session,0.6f);
ssh_list_kex(&session->next_crypto->server_kex); ssh_list_kex(&session->next_crypto->server_kex);
if (ssh_set_client_kex(session) < 0) { if (session->next_crypto->client_kex.methods[0] == NULL) {
goto error; /* in rekeying state if next_crypto client_kex is empty */
rc = ssh_set_client_kex(session);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_send_kex(session, 0);
if (rc < 0) {
goto error;
}
} }
if (ssh_kex_select_methods(session) == SSH_ERROR) if (ssh_kex_select_methods(session) == SSH_ERROR)
goto error; goto error;
if (ssh_send_kex(session, 0) < 0) {
goto error;
}
set_status(session,0.8f); set_status(session,0.8f);
session->session_state=SSH_SESSION_STATE_DH; session->session_state=SSH_SESSION_STATE_DH;
if (dh_handshake(session) == SSH_ERROR) { if (dh_handshake(session) == SSH_ERROR) {
@@ -479,8 +493,8 @@ static int ssh_connect_termination(void *user){
* @param[in] session The ssh session to connect. * @param[in] session The ssh session to connect.
* *
* @returns SSH_OK on success, SSH_ERROR on error. * @returns SSH_OK on success, SSH_ERROR on error.
* @returns SSH_AGAIN, if the session is in nonblocking mode, * @returns SSH_AGAIN, if the session is in nonblocking mode,
* and call must be done again. * and call must be done again.
* *
* @see ssh_new() * @see ssh_new()
* @see ssh_disconnect() * @see ssh_disconnect()
@@ -512,6 +526,16 @@ int ssh_connect(ssh_session session) {
return SSH_ERROR; return SSH_ERROR;
} }
/* If the system configuration files were not yet processed, do it now */
if (!session->opts.config_processed) {
ret = ssh_options_parse_config(session, NULL);
if (ret != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to process system configuration files");
return SSH_ERROR;
}
}
ret = ssh_options_apply(session); ret = ssh_options_apply(session);
if (ret < 0) { if (ret < 0) {
ssh_set_error(session, SSH_FATAL, "Couldn't apply options"); ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
@@ -700,7 +724,7 @@ error:
if (session->out_hashbuf) { if (session->out_hashbuf) {
ssh_buffer_reinit(session->out_hashbuf); ssh_buffer_reinit(session->out_hashbuf);
} }
session->auth_methods = 0; session->auth.supported_methods = 0;
SAFE_FREE(session->serverbanner); SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner); SAFE_FREE(session->clientbanner);

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