Compare commits

..

138 Commits

Author SHA1 Message Date
Andreas Schneider
4919771f0f ChangeLog: Set release date. 2014-01-08 11:17:12 +01:00
Andreas Schneider
8aad24c062 include: Remove warning cause VSC doesn't know about it. 2014-01-08 10:55:39 +01:00
Andreas Schneider
0e5510bb99 include: Fix building if we do not have asm volatile. 2014-01-08 10:52:57 +01:00
Andreas Schneider
de464cb74e src: Update my mail address. 2014-01-07 16:09:04 +01:00
Andreas Schneider
c41f32bcca cmake: Remove unused macro modules. 2014-01-07 16:09:02 +01:00
Aris Adamantiadis
61e701caaa update copyright information 2014-01-07 15:18:44 +01:00
Aris Adamantiadis
1c36642fed tests: avoid reading uninitialized bytes 2014-01-07 14:43:01 +01:00
Aris Adamantiadis
ad287371fb pki: fix gcrypt signature process 2014-01-07 14:21:15 +01:00
Andreas Schneider
ebfdfd9a14 examples: Make sure buffer is initialized. 2014-01-07 09:19:30 +01:00
Andreas Schneider
c9a1be5a85 example: Add missing include for forkpty(). 2014-01-07 09:04:06 +01:00
Aris Adamantiadis
fc0db4d982 test: fixed torture_auth_none condition 2014-01-06 22:10:23 +01:00
Aris Adamantiadis
8f1a350b6e test: test case for async auth_none
This test currently fails
2014-01-06 16:52:35 +01:00
Aris Adamantiadis
15ed51cf20 tests: auth_agent_nonblocking should run in nonblocking 2014-01-06 16:52:35 +01:00
Andreas Schneider
7b2e07ecbc session: Fix a possible memory leak. 2014-01-06 16:18:06 +01:00
Aris Adamantiadis
0404d45c29 poll: fix poll_handles ownerships 2014-01-06 16:18:06 +01:00
Aris Adamantiadis
f2215d14de socket: don't attempt reading a non-connected socket 2014-01-06 16:18:06 +01:00
Aris Adamantiadis
ebbf7988b9 tests: use LC_LIBSSH instead of LANG for env tests.
LANG is stripped and replaced on many distros and LC_* is accepted
by default on debian
2014-01-06 16:17:38 +01:00
Andreas Schneider
ec307d9862 examples: Fix building samplesshd-tty on FreeBSD. 2013-12-26 16:38:38 +01:00
Andreas Schneider
2068973ff3 poll: Correctly free ssh_event_fd_wrapper.
This is allocated by ssh_event_add_fd.
2013-12-22 22:26:51 +01:00
Andreas Schneider
6eea08a9ef config: Support expansion in the Host variable too.
BUG: https://red.libssh.org/issues/127
2013-12-21 14:37:55 +01:00
Andreas Schneider
3ba2e7ace7 tests: Fix non-blocking auth tests.
The ssh_userauth_none() call should already be non-blocking. However
this this function is broken in non-blocking mode. It should reveal the
existing bug.
2013-12-15 21:04:46 +01:00
Andreas Schneider
15c64b2981 tests: Use new auth API in the torture_session test. 2013-12-15 20:30:48 +01:00
Andreas Schneider
ce5d421753 tests: Use new auth API in the torture_auth test. 2013-12-15 20:26:59 +01:00
Andreas Schneider
fd77439a12 tests: Fix pki test with gcrypt. 2013-12-11 21:12:12 +01:00
Jon Simons
a633deb985 channel: fix setting of channel->flags
Fix the setting of 'channel->flags' to use '|='.  Before this
change, one bug symptom can be that channels are never fully
free'd via ssh_channel_free, resulting in memory leaks.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-12-11 21:03:45 +01:00
Jon Simons
50b9a182f5 client: use ssh_channel_do_free in ssh_disconnect
Ensure to use 'ssh_channel_do_free' in 'ssh_disconnect', when removing and
free'ing up a session's channels.  This matches the behavior in 'ssh_free',
and is necessary to fully free any channel which may not have been closed
completely (see usage of flags SSH_CHANNEL_FLAG_CLOSED_REMOTE,
SSH_CHANNEL_FLAG_FREED_LOCAL).

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-12-11 21:03:43 +01:00
Andreas Schneider
bb88b637a9 bind: Correctly free all memory in ssh_bind_free().
Thanks to Jacob Baines.
2013-12-09 19:50:52 +01:00
Jon Simons
60d5824760 session: Add ssh_get_clientbanner(). 2013-12-07 16:24:53 +01:00
Andreas Schneider
397be918cd channels: Add a ssh_channel_read_timeout function. 2013-12-04 20:34:52 +01:00
Andreas Schneider
880fdb4b52 tests: Try to fix torture_forward. 2013-12-04 16:27:19 +01:00
Andreas Schneider
6a74677cef tests: Fix memory leaks. 2013-12-04 16:27:18 +01:00
Andreas Schneider
2c66eeaf75 pki: Fix a memory leak.
CID #1132819
2013-11-28 11:44:34 +01:00
Andreas Schneider
91edc0ee21 tests: Add torture_pki_write_privkey_ecdsa test. 2013-11-27 22:54:40 +01:00
Andreas Schneider
46bda45d95 tests: Add torture_pki_write_privkey_dsa test. 2013-11-27 22:54:40 +01:00
Andreas Schneider
9773c0852a tests: Add torture_pki_write_privkey_rsa test. 2013-11-27 22:54:40 +01:00
Andreas Schneider
f1c56e4309 pki: Add ssh_pki_import_privkey_file(). 2013-11-27 22:54:40 +01:00
Andreas Schneider
1fdc1025a8 pki_crypto: Add pki_private_key_to_pem(). 2013-11-27 22:54:40 +01:00
Andreas Schneider
a375b6c996 pki_gcrypt: Add pki_private_key_to_pem() stub. 2013-11-27 22:54:40 +01:00
Andreas Schneider
ecb01e05a2 curve25519: Fix memory leaks in ssh_server_curve25519_init().
CID #1125255
2013-11-27 22:53:53 +01:00
Andreas Schneider
b3911d0fa2 curve25519: Do not leak q_s_string.
CID #1125256
2013-11-27 22:53:53 +01:00
Andreas Schneider
1ee687ea6f curve25519: Fix a memory leak.
CID #1125257
2013-11-27 22:53:53 +01:00
Andreas Schneider
73e1f2691f examples: Fix else branch.
CID #1127816
2013-11-27 22:53:53 +01:00
Andreas Schneider
84e29f9c06 packet: Remove logically dead code.
CID #1128796
2013-11-27 22:53:53 +01:00
Andreas Schneider
23837b2080 tests: Try to fix valgrind warnings. 2013-11-27 22:53:53 +01:00
Andreas Schneider
4884f1d6fc tests: Fix a valgrind warning. 2013-11-27 22:53:53 +01:00
Andreas Schneider
ead1c4b168 ecdh: Check if we have ECC support. 2013-11-27 22:53:53 +01:00
Andreas Schneider
3e11cb8071 ecdh: Use bignum_bin2bn. 2013-11-27 22:53:48 +01:00
Nicolas Viennot
78e78642e7 server: Add a ssh_send_keepalive() function.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-24 23:21:39 +01:00
Jon Simons
7ab0e3fe62 channel: fix infinite loop in channel_write_common
BUG: https://red.libssh.org/issues/130

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-22 10:34:49 +01:00
Andreas Schneider
5da02d6de2 Update ChangeLog. 2013-11-19 10:29:59 +01:00
Rod Vagg
94db978218 flush channel after EOF and CLOSE 2013-11-18 17:23:52 +01:00
Aris Adamantiadis
78ea8608b0 logging: fix server-side logging 2013-11-18 15:28:59 +01:00
Aris Adamantiadis
7d9940d6eb gssapi: fix logging 2013-11-18 15:10:56 +01:00
Aris Adamantiadis
9f4fa22250 sockets: null pointer check 2013-11-18 14:42:06 +01:00
Simo Sorce
330f6c73f6 gssapi: Fix support of delegated credentials
In a previous refactoring patch, the code underpinning the
ssh_gssapi_set_creds() API was inadvertently removed. This patch
fixes the problem.

Also clarify what variable holds which credentials and insure that
credentials created within the library are propelry freed.

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-17 11:43:52 +01:00
Simo Sorce
4a3934da48 gssapi: Add support for GSSAPIDelegateCredentials config option.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-17 11:43:52 +01:00
Simo Sorce
68b996bdbf options: Add SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS option.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-17 11:43:50 +01:00
Andreas Schneider
d364374422 gssapi: Add error checks and cleanup the code in ssh_gssapi_auth_mic(). 2013-11-15 16:29:49 +01:00
Simo Sorce
00af5bd582 gssapi: Use GSSAPIClientIdentity to acquire creds
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-15 16:29:49 +01:00
Andreas Schneider
1ab5abf0e6 gssapi: Add support for GSSAPIClientIdentity config option. 2013-11-15 16:29:49 +01:00
Andreas Schneider
f5d1d813fb options: Add SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY option. 2013-11-15 16:29:49 +01:00
Andreas Schneider
92928a7d8d gssapi: Add support for GSSAPIServerIdentity config option. 2013-11-15 16:29:49 +01:00
Andreas Schneider
651c173e72 gssapi: Add suppport to set GSSAPI server identity. 2013-11-15 16:29:49 +01:00
Simo Sorce
f76cd8b6d5 Fix gssapi credential handling.
- Properly acquire and inquitre credentials to get the list of available
credentials.
- Avoid enforcing a specific username it breaks some use cases (k5login).
- Remove confusing references to delegated credentials as there is no code
that actually uses delegated credentials in the initialization case.

Signed-off-by: Siom Sorce <simo@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-15 16:29:49 +01:00
Andreas Schneider
2bbeebd505 socket: Fix connect if we pass in a fd.
BUG: https://red.libssh.org/issues/106

Thanks to Saju Panikulam.
2013-11-15 08:54:18 +01:00
Andreas Schneider
fef32b4c14 packet: Remove dead code. 2013-11-14 11:44:12 +01:00
Andreas Schneider
2eaff2b363 packet: Set the packet to the processed data position.
Else we could end up with packet - current_macsize if to_be_read is 0.
2013-11-14 11:44:11 +01:00
Andreas Schneider
2b3e69fd5f dh: Fix wrong assignment.
Ups, sorry.
2013-11-14 08:09:42 +01:00
Andreas Schneider
cd992a90fb poll: Fix realloc in ssh_poll_ctx_resize(). 2013-11-13 16:29:41 +01:00
Andreas Schneider
6ea111fd8a dh: Avoid possible memory leaks with realloc. 2013-11-13 16:29:41 +01:00
Andreas Schneider
cda641176d packet: Refactor ssh_packet_socket_callback().
Make error checking more readable and add additional NULL checks.
2013-11-13 16:29:41 +01:00
Andreas Schneider
5581645500 server: Fix malloc call. 2013-11-13 16:29:41 +01:00
Colin Walters
3e64ef3bf5 session: Always request POLLIN
The assumption is that if libssh functions are being invoked, we want
to read data.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-09 12:29:26 +01:00
Colin Walters
7372cd837a Add ssh_get_poll_flags()
For integration with an external mainloop, we need to know how to
replicate libssh's internal poll() calls.  We originally through
ssh_get_status() was that API, but it's not really - those flags only
get updated from the *result* of a poll(), where what we really need
is to know how libssh would *start* a poll().

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-09 12:29:25 +01:00
Colin Walters
1ecf7003f6 client: If we have a pre-connected FD, set state to SOCKET_CONNECTED
Otherwise applications providing their own fd end up tripping an
assertion, since the session is just in _CONNECTING.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-09 12:29:24 +01:00
Andreas Schneider
70c54d9445 example: Use ssh_get_publickey_hash(). 2013-11-06 17:11:26 +01:00
Andreas Schneider
e52ff2c8ff dh: Move ssh_get_hexa() and ssh_print_hexa() down.
This way they are in the documentation block for the session and we get
documentation for them.
2013-11-06 17:11:25 +01:00
Andreas Schneider
9bf9d52e21 dh: Add new ssh_get_publickey_hash() function. 2013-11-06 17:11:24 +01:00
Andreas Schneider
965000129e doc: Fix doxygen warnings. 2013-11-04 21:55:58 +01:00
Aris Adamantiadis
0940c6f1b0 Fix cast warnings on 64bits 2013-11-04 10:51:17 +01:00
Aris Adamantiadis
2e6dbe8d3d remove warnings on OSX (workaround) 2013-11-04 10:51:09 +01:00
Aris Adamantiadis
8bf6907c1d curve25519: include reference implementation 2013-11-03 14:58:47 +01:00
Aris Adamantiadis
6e9e13cc24 examples: fix forktty() warning on OSX 2013-11-03 14:09:28 +01:00
Aris Adamantiadis
5bc32bfd88 Fix examples compilation on OSX (libargp) 2013-11-03 13:51:03 +01:00
Aris Adamantiadis
7c8a793b0a socket: Fix check for pending data.
BUG: https://red.libssh.org/issues/119

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 12:48:12 +01:00
Nicolas Viennot
e9b0a8210d server: Fix ssh_execute_server_callbacks() client execution
When the public key auth handler is executed and returns SSH_OK,
ssh_execute_server_callbacks() still runs some client callbacks,
which may set rc to SSH_AGAIN, which triggers a default reply on
auth, denying auth.

Signed-off-by: Nicolas Viennot <nicolas@viennot.biz>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 10:53:44 +01:00
Nicolas Viennot
fb63887c16 server kex: enable delayed compression
The code is careful to reenable compression when rekeying.

Signed-off-by: Nicolas Viennot <nicolas@viennot.biz>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-03 10:53:42 +01:00
Andreas Schneider
b113b78dfc session: Make sure we correctly burn the buffer. 2013-11-03 10:53:41 +01:00
Andreas Schneider
646112b4e4 wrapper: Make sure we really burn the buffer. 2013-11-03 10:53:40 +01:00
Andreas Schneider
ba4346f089 priv: Fix brackets of burn macros. 2013-11-03 10:53:38 +01:00
Jon Simons
401865d725 server: fix pubkey reply for key probes
Per RFC 4252, it is required to send back only one of either
SSH_MSG_USERAUTH_PK_OK or SSH_MSG_USERAUTH_FAILURE for public
key probes.

Update the handling of 'auth_pubkey_function' to send back PK_OK
instead of SSH_MSG_USERAUTH_SUCCESS for the case that the state
of the message at hand is SSH_PUBLICKEY_STATE_NONE.

With this change, it is now possible to process an initial key probe
and then subsequent signature validation using the server callbacks.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-02 21:03:20 +01:00
William Orr
d312af1ed5 ssh_options_get can now return ProxyCommand
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-11-02 21:03:19 +01:00
Jon Simons
3cfd8a126b connect: fix memory leak in ssh_select
Balance 'ssh_event_add_fd' with 'ssh_event_remove_fd' in 'ssh_select'.

BUG: https://red.libssh.org/issues/128

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-31 12:48:56 +01:00
Andreas Schneider
24ebbb8b39 tests: Add a test for ssh_channel(). 2013-10-31 12:48:55 +01:00
Jon Simons
447ee309b0 poll: fix leak in ssh_poll_ctx_free
Fix a memory leak in 'ssh_poll_ctx_free': issue 'ssh_poll_free'
to remove the poll handle from its context and free it.

BUG: https://red.libssh.org/issues/128

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-31 11:55:27 +01:00
Alan Dunn
6c213c913b SSH_AUTH_OK -> SSH_AUTH_SUCCESS in comments
A few callback descriptions refer to a non-existent value SSH_AUTH_OK,
which should be SSH_AUTH_SUCCESS.  This commit fixes these.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-31 08:19:35 +01:00
Andreas Schneider
f8f6eb0ce6 cmake: Check for isblank(). 2013-10-30 17:33:32 +01:00
Jon Simons
54f89af6d3 bind: fix leak in ssh_bind_accept error path
Use 'ssh_socket_free' to cleanup if 'ssh_bind_accept_fd'
fails, to be sure to free the ssh_socket in/out buffers.
2013-10-24 10:37:59 +02:00
Andreas Schneider
0e4a1b1f66 tests: Add a sftp_read blocking test. 2013-10-23 15:54:40 +02:00
Colin Walters
5eeadf533f auth: docs: Fix typo optoins -> options
I'm just getting my feet wet with this codebase.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-23 09:55:39 +02:00
Andreas Schneider
a4e2e01d3e doc: Improve sftp_read_sync() example. 2013-10-23 09:55:38 +02:00
Andreas Schneider
3911046f7e include: Fix build on platforms without ECC. 2013-10-21 07:16:26 +02:00
Andreas Schneider
2727af0fe6 tests: Add a test for ssh_channel_request_env(). 2013-10-20 17:06:23 +02:00
Andreas Schneider
c42da23348 tests: We can't test the accept right now. 2013-10-20 17:06:22 +02:00
Andreas Schneider
e0adcea90d tests: Fix torture_forward. 2013-10-20 17:06:21 +02:00
Andreas Schneider
a62399fcd5 channel: Reinit the buffer and reset the state on error.
BUG: https://red.libssh.org/issues/126
2013-10-20 12:47:17 +02:00
Andreas Schneider
0ee68ac2a1 channel: Fix ssh_global_request_termination().
BUG: https://red.libssh.org/issues/126
2013-10-20 12:47:16 +02:00
Andreas Schneider
796d285eaf tests: Add torture forward test. 2013-10-20 12:47:16 +02:00
Andreas Schneider
b5f71f35a3 pki: Don't leak a buffer. 2013-10-19 10:42:18 +02:00
Andreas Schneider
b98ea81903 wrapper: Fix compilation with gcrypt. 2013-10-19 10:39:44 +02:00
Andreas Schneider
beeca3c650 pki_crpypto: Fix ecdsa signature to blob.
BUG: https://red.libssh.org/issues/118
2013-10-18 23:50:09 +02:00
Andreas Schneider
9f5abdb526 pki: Add support for ECDSA private key signing. 2013-10-18 23:50:08 +02:00
Andreas Schneider
02f80eb288 pki: Add the type as a char pointer. 2013-10-18 23:50:08 +02:00
Andreas Schneider
5b7f07b484 wrapper: Add more evp functions. 2013-10-18 23:50:06 +02:00
Andreas Schneider
ec5278e34d client: Fix the build. 2013-10-18 21:19:33 +02:00
Oliver Stöneberg
e554f0dc0d scp: Fixed result of ssh_scp_string_mode() to get SCP working.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-18 14:59:01 +02:00
Oliver Stöneberg
e8e1916d2e client: Added a missing NULL pointer check.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-18 14:58:59 +02:00
Andreas Schneider
58893352b0 doc: Make sure we have the defines to build all docs. 2013-10-14 15:40:18 +02:00
Aris Adamantiadis
cdcc92e344 Compile libssh with nacl if possible
Conflicts:
	DefineOptions.cmake
2013-10-06 17:43:53 +02:00
Andreas Schneider
29b3a94032 channel: Fix packets termination timeout in global_request().
BUG: https://red.libssh.org/issues/126
2013-10-01 14:51:55 +02:00
Andreas Schneider
8f2b26a837 session: Try the ecdsa default key first. 2013-10-01 14:48:20 +02:00
Andreas Schneider
42c07f379d channels: Correctly handle timeouts in channel functions. 2013-10-01 14:47:58 +02:00
Andreas Schneider
f79c4fd7a3 channel: Use the correct timeout option in channel_open().
BUG: https://red.libssh.org/issues/124
2013-10-01 14:47:58 +02:00
Andreas Schneider
7b2aee90f0 callbacks: Improve the documentation of ssh_threads_set_callbacks().
BUG: https://red.libssh.org/issues/123
2013-10-01 14:47:58 +02:00
Andreas Schneider
aaacd18031 callbacks: Improve the documentation of ssh_threads_get_noop().
BUG: https://red.libssh.org/issues/123
2013-10-01 14:47:58 +02:00
Andreas Schneider
9f60352497 session: Document return value of ssh_get_serverbanner().
BUG: https://red.libssh.org/issues/122
2013-10-01 14:47:58 +02:00
Andreas Schneider
70c796e8b8 session: Remove obsolete status variables.
BUG: https://red.libssh.org/issues/121
2013-10-01 14:47:57 +02:00
Andreas Schneider
5b7a696cf2 client: Add example code for ssh_get_openssh_version().
BUG: https://red.libssh.org/issues/120
2013-10-01 14:47:57 +02:00
Andreas Schneider
c59568c3c1 channels: Correctly decrement timeout value in ssh_channel_accept().
BUG: https://red.libssh.org/issues/116
2013-10-01 14:47:57 +02:00
Andreas Schneider
6f10422685 channel: Document SSH_AGAIN in ssh_channel_read().
BUG: https://red.libssh.org/issues/115
2013-10-01 14:47:57 +02:00
Andreas Schneider
44f851d287 cmake: Allow to build without examples.
BUG: https://red.libssh.org/issues/114
2013-10-01 14:47:57 +02:00
Andreas Schneider
3d158fffa0 doc: Improve the PKI documentation a bit. 2013-10-01 14:47:57 +02:00
Andreas Schneider
c8be0201c6 doc: Update documentation of ssh_set_blocking().
This should work correctly in libssh 0.6.0. If not then you hit a bug.
2013-10-01 14:47:57 +02:00
Tristan CACQUERAY
a8969c4be6 callbacks: add support for auth_none_function 2013-09-27 16:06:09 +02:00
Aris Adamantiadis
8ec8d35e1a doc: Documentation of curve25519-sha256@libssh.org 2013-09-27 16:06:09 +02:00
Aris Adamantiadis
666db37e21 kex: implement curve25519-sha256@libssh.org 2013-09-27 16:06:09 +02:00
Andreas Schneider
391bd88355 scp: Document more scp functionts. 2013-08-12 11:25:15 +02:00
Andreas Schneider
5f90b77a1b cmake: Update libssh version. 2013-08-07 17:33:03 +02:00
331 changed files with 20197 additions and 55606 deletions

View File

@@ -1,4 +0,0 @@
{
"phabricator.uri" : "https://bugs.libssh.org/",
"history.immutable": true
}

11
.clang_complete Normal file
View File

@@ -0,0 +1,11 @@
-DWITH_SERVER=1
-DWITH_GSSAPI=1
-DWITH_ZLIB=1
-DWITH_SFTP=1
-DWITH_SSH1=1
-DWITH_PCAP=1
-Iinclude/libssh
-Iinclude
-Ibuild
-Itests
-Isrc

3
.gitignore vendored
View File

@@ -3,7 +3,6 @@
.* .*
*.swp *.swp
*~$ *~$
build
cscope.* cscope.*
tags tags
/build
/obj*

View File

@@ -1,467 +0,0 @@
variables:
BUILD_IMAGES_PROJECT: libssh/build-images
FEDORA_BUILD: buildenv-fedora
CENTOS7_BUILD: buildenv-centos7
TUMBLEWEED_BUILD: buildenv-tumbleweed
MINGW_BUILD: buildenv-mingw
DEBIAN_CROSS_BUILD: buildenv-debian-cross
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
centos7/openssl_1.0.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
script:
- mkdir -p obj && cd obj && cmake3
-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/
fedora/openssl_1.1.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_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
-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/
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
# 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
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=AddressSanitizer
-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/
fedora/undefined-sanitizer:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_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/
fedora/csbuild:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- |
if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then
export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
fi
# Check if the commit exists in this branch
# 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:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj-csbuild/
# That is a specific runner that we cannot enable universally.
# We restrict it to builds under the $BUILD_IMAGES_PROJECT project.
freebsd/x86_64:
image:
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
-DUNIT_TESTING=ON .. &&
make && ctest --output-on-failure
tags:
- freebsd
except:
- tags
only:
- branches@libssh/libssh-mirror
- branches@cryptomilk/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
fedora/libgcrypt/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_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
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DWITH_GCRYPT=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
fedora/mbedtls/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_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
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DWITH_MBEDTLS=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
# Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW
fedora/mingw64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
script:
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
- 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:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
# Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW
fedora/mingw32:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
script:
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
- 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:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
.Debian.cross.template: &Debian_cross_template
stage: test
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_CROSS_BUILD
script:
- build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE)
- host="${CI_JOB_NAME#*.cross.}"
- mkdir -p obj && cd obj && cmake
-DCMAKE_C_COMPILER="$(which $host-gcc)"
-DCMAKE_CXX_COMPILER="$(which $host-g++)"
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
-DWITH_PCAP=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
Debian.cross.mips-linux-gnu:
<<: *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,20 +1,17 @@
cmake_minimum_required(VERSION 3.3.0) project(libssh C)
cmake_policy(SET CMP0048 NEW)
# Specify search path for CMake modules to be loaded by include() # Required cmake version
# and find_package() cmake_minimum_required(VERSION 2.6.0)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
# Add defaults for cmake # global needed variables
# Those need to be set before the project() call.
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.8.90 LANGUAGES C)
# global needed variable
set(APPLICATION_NAME ${PROJECT_NAME}) set(APPLICATION_NAME ${PROJECT_NAME})
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "6")
set(APPLICATION_VERSION_PATCH "0")
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
# SOVERSION scheme: CURRENT.AGE.REVISION # SOVERSION scheme: CURRENT.AGE.REVISION
# If there was an incompatible interface change: # If there was an incompatible interface change:
# Increment CURRENT. Set AGE and REVISION to 0 # Increment CURRENT. Set AGE and REVISION to 0
@@ -22,26 +19,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.7.2") set(LIBRARY_VERSION "4.3.0")
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_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)
@@ -52,31 +49,18 @@ if (WITH_GCRYPT)
if (NOT GCRYPT_FOUND) if (NOT GCRYPT_FOUND)
message(FATAL_ERROR "Could not find GCrypt") message(FATAL_ERROR "Could not find GCrypt")
endif (NOT GCRYPT_FOUND) endif (NOT GCRYPT_FOUND)
elseif(WITH_MBEDTLS)
find_package(MbedTLS REQUIRED)
if (NOT MBEDTLS_FOUND)
message(FATAL_ERROR "Could not find mbedTLS")
endif (NOT MBEDTLS_FOUND)
else (WITH_GCRYPT) else (WITH_GCRYPT)
find_package(OpenSSL) find_package(OpenSSL)
if (NOT OPENSSL_FOUND) if (NOT OPENSSL_FOUND)
find_package(GCrypt) find_package(GCrypt)
if (NOT GCRYPT_FOUND) if (NOT GCRYPT_FOUND)
find_package(MbedTLS) message(FATAL_ERROR "Could not find OpenSSL or GCrypt")
if (NOT MBEDTLS_FOUND)
message(FATAL_ERROR "Could not find OpenSSL, GCrypt or mbedTLS")
endif (NOT MBEDTLS_FOUND)
endif (NOT GCRYPT_FOUND) endif (NOT GCRYPT_FOUND)
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)
find_package(Threads) find_package(Threads)
if (WITH_GSSAPI) if (WITH_GSSAPI)
@@ -90,17 +74,6 @@ if (WITH_NACL)
endif (NOT NACL_FOUND) endif (NOT NACL_FOUND)
endif (WITH_NACL) endif (WITH_NACL)
if (BSD OR SOLARIS OR OSX)
find_package(Argp)
endif (BSD OR SOLARIS OR OSX)
# Disable symbol versioning in non UNIX platforms
if (UNIX)
find_package(ABIMap 0.3.1)
else (UNIX)
set(WITH_SYMBOL_VERSIONING OFF)
endif (UNIX)
# config.h checks # config.h checks
include(ConfigureChecks.cmake) include(ConfigureChecks.cmake)
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
@@ -111,135 +84,64 @@ add_subdirectory(include)
add_subdirectory(src) add_subdirectory(src)
# pkg-config file # pkg-config file
if (UNIX)
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc) configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
install( install(
FILES FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
DESTINATION DESTINATION
${LIB_INSTALL_DIR}/pkgconfig ${LIB_INSTALL_DIR}/pkgconfig
COMPONENT COMPONENT
pkgconfig pkgconfig
) )
endif (UNIX)
# CMake config files
include(CMakePackageConfigHelpers)
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
# libssh-config-version.cmake
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)
# cmake config files
configure_file(libssh-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake @ONLY)
configure_file(libssh-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake @ONLY)
install( install(
FILES FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake
DESTINATION DESTINATION
${CMAKE_INSTALL_DIR}/${PROJECT_NAME} ${CMAKE_INSTALL_DIR}
COMPONENT COMPONENT
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 (WITH_TESTING)
include(AddCMockaTest) find_package(CMocka REQUIRED)
add_subdirectory(tests) include(AddCMockaTest)
endif (UNIT_TESTING) add_subdirectory(tests)
endif (WITH_TESTING)
### SOURCE PACKAGE
if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
# Get the current ABI version from source
get_filename_component(current_abi_path
"${CMAKE_SOURCE_DIR}/src/ABI/current"
ABSOLUTE)
# Check if the ABI version should be updated
file(READ ${current_abi_path} CURRENT_ABI_CONTENT)
string(STRIP "${CURRENT_ABI_CONTENT}" CURRENT_ABI_VERSION)
if (LIBRARY_VERSION VERSION_GREATER CURRENT_ABI_VERSION)
set(UPDATE_ABI TRUE)
endif ()
if (UPDATE_ABI)
message(STATUS "Library version bumped to ${LIBRARY_VERSION}: Updating ABI")
# Get the list of header files
get_file_list(${PROJECT_NAME}_header_list
DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libssh"
FILES_PATTERNS "*.h")
# Extract the symbols marked as "LIBSSH_API" from the header files
extract_symbols(${PROJECT_NAME}.symbols
HEADERS_LIST ${PROJECT_NAME}_header_list
FILTER_PATTERN "LIBSSH_API"
COPY_TO "${CMAKE_SOURCE_DIR}/src/ABI/${PROJECT_NAME}-${LIBRARY_VERSION}.symbols")
if (WITH_ABI_BREAK)
set(ALLOW_ABI_BREAK "BREAK_ABI")
endif()
# Target we can depend on in 'make dist'
set(_SYMBOL_TARGET "${PROJECT_NAME}.map")
# Set the path to the current map file
set(MAP_PATH "${CMAKE_SOURCE_DIR}/src/${_SYMBOL_TARGET}")
# Generate the symbol version map file
generate_map_file(${_SYMBOL_TARGET}
SYMBOLS ${PROJECT_NAME}.symbols
RELEASE_NAME_VERSION ${PROJECT_NAME}_${LIBRARY_VERSION}
CURRENT_MAP ${MAP_PATH}
COPY_TO ${MAP_PATH}
FINAL
${ALLOW_ABI_BREAK})
# Write the current version to the source
file(WRITE ${current_abi_path} ${LIBRARY_VERSION})
endif(UPDATE_ABI)
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET})
message(STATUS "********************************************") message(STATUS "********************************************")
message(STATUS "********** ${PROJECT_NAME} build options : **********") message(STATUS "********** ${PROJECT_NAME} build options : **********")
message(STATUS "zlib support: ${WITH_ZLIB}") message(STATUS "zlib support: ${WITH_ZLIB}")
message(STATUS "libgcrypt support: ${WITH_GCRYPT}") message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
message(STATUS "libmbedTLS support: ${WITH_MBEDTLS}")
message(STATUS "libnacl support: ${WITH_NACL}") message(STATUS "libnacl support: ${WITH_NACL}")
message(STATUS "SSH-1 support: ${WITH_SSH1}")
message(STATUS "SFTP support: ${WITH_SFTP}") message(STATUS "SFTP support: ${WITH_SFTP}")
message(STATUS "Server support : ${WITH_SERVER}") message(STATUS "Server support : ${WITH_SERVER}")
message(STATUS "GSSAPI support : ${WITH_GSSAPI}") message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
message(STATUS "Pcap debugging support : ${WITH_PCAP}") message(STATUS "Pcap debugging support : ${WITH_PCAP}")
message(STATUS "With static library: ${WITH_STATIC_LIB}") message(STATUS "With static library: ${WITH_STATIC_LIB}")
message(STATUS "Unit testing: ${UNIT_TESTING}") message(STATUS "Unit testing: ${WITH_TESTING}")
message(STATUS "Client code testing: ${CLIENT_TESTING}") message(STATUS "Client code Unit testing: ${WITH_CLIENT_TESTING}")
set(_SERVER_TESTING OFF)
if (WITH_SERVER)
set(_SERVER_TESTING ${SERVER_TESTING})
endif()
message(STATUS "Server code testing: ${_SERVER_TESTING}")
if (WITH_INTERNAL_DOC) if (WITH_INTERNAL_DOC)
message(STATUS "Internal documentation generation") message(STATUS "Internal documentation generation")
else (WITH_INTERNAL_DOC) else (WITH_INTERNAL_DOC)
message(STATUS "Public API documentation generation") message(STATUS "Public API documentation generation")
endif (WITH_INTERNAL_DOC) endif (WITH_INTERNAL_DOC)
message(STATUS "Benchmarks: ${WITH_BENCHMARKS}") message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
message(STATUS "Release is final: ${WITH_FINAL}")
message(STATUS "********************************************") message(STATUS "********************************************")

13
COPYING
View File

@@ -455,15 +455,6 @@ 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

@@ -1,19 +1,27 @@
### GENERAL SETTINGS # For help take a look at:
set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) # http://www.cmake.org/Wiki/CMake:CPackConfiguration
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH Library")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README") ### general settings
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH library")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README")
set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team") set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
# SOURCE GENERATOR ### versions
set(CPACK_SOURCE_GENERATOR "TXZ") set(CPACK_PACKAGE_VERSION_MAJOR ${APPLICATION_VERSION_MAJOR})
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*") set(CPACK_PACKAGE_VERSION_MINOR ${APPLICATION_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${APPLICATION_VERSION_PATCH})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
### source generator
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
### NSIS INSTALLER
if (WIN32) if (WIN32)
set(CPACK_GENERATOR "ZIP") set(CPACK_GENERATOR "ZIP")
@@ -38,6 +46,7 @@ set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
set(CPACK_COMPONENT_HEADERS_DESCRIPTION set(CPACK_COMPONENT_HEADERS_DESCRIPTION
"C/C++ header files for use with libssh") "C/C++ header files for use with libssh")
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
#set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime")
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development") set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
set(CPACK_COMPONENT_HEADERS_GROUP "Development") set(CPACK_COMPONENT_HEADERS_GROUP "Development")

View File

@@ -3,7 +3,7 @@ set(UPDATE_TYPE "true")
set(CTEST_PROJECT_NAME "libssh") set(CTEST_PROJECT_NAME "libssh")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
set(CTEST_DROP_METHOD "https") set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "test.libssh.org") set(CTEST_DROP_SITE "test.libssh.org")
set(CTEST_DROP_LOCATION "/submit.php?project=libssh") set(CTEST_DROP_LOCATION "/submit.php?project=libssh")
set(CTEST_DROP_SITE_CDASH TRUE) set(CTEST_DROP_SITE_CDASH TRUE)

102
ChangeLog
View File

@@ -1,108 +1,6 @@
ChangeLog ChangeLog
========== ==========
version 0.8.0 (released 2018-08-10)
* Removed support for deprecated SSHv1 protocol
* Added new connector API for clients
* Added new known_hosts parsing API
* Added support for OpenSSL 1.1
* Added support for chacha20-poly1305 cipher
* Added crypto backend for mbedtls crypto library
* Added ECDSA support with gcrypt backend
* Added advanced client and server testing using cwrap.org
* Added support for curve25519-sha256 alias
* Added support for global known_hosts file
* Added support for symbol versioning
* Improved ssh_config parsing
* Improved threading support
version 0.7.5 (released 2017-04-13)
* Fixed a memory allocation issue with buffers
* Fixed PKI on Windows
* Fixed some SSHv1 functions
* Fixed config hostname expansion
version 0.7.4 (released 2017-02-03)
* Added id_ed25519 to the default identity list
* Fixed sftp EOF packet handling
* Fixed ssh_send_banner() to confirm with RFC 4253
* Fixed some memory leaks
version 0.7.3 (released 2016-01-23)
* Fixed CVE-2016-0739
* Fixed ssh-agent on big endian
* Fixed some documentation issues
version 0.7.2 (released 2015-09-15)
* Fixed OpenSSL detection on Windows
* Fixed return status for ssh_userauth_agent()
* Fixed KEX to prefer hmac-sha2-256
* Fixed sftp packet handling
* Fixed return values of ssh_key_is_(public|private)
* Fixed bug in global success reply
version 0.7.1 (released 2015-06-30)
* Fixed SSH_AUTH_PARTIAL auth with auto public key
* Fixed memory leak in session options
* Fixed allocation of ed25519 public keys
* Fixed channel exit-status and exit-signal
* Reintroduce ssh_forward_listen()
version 0.7.0 (released 2015-05-11)
* Added support for ed25519 keys
* Added SHA2 algorithms for HMAC
* Added improved and more secure buffer handling code
* Added callback for auth_none_function
* Added support for ECDSA private key signing
* Added more tests
* Fixed a lot of bugs
* Improved API documentation
version 0.6.5 (released 2015-04-29)
* Fixed CVE-2015-3146
* Fixed port handling in config file
* Fixed the build with libgcrypt
* Fixed SFTP endian issues (rlo #179)
* Fixed uninitilized sig variable (rlo #167)
* Fixed polling issues which could result in a hang
* Fixed handling of EINTR in ssh_poll() (rlo #186)
* Fixed C99 issues with __func__
* Fixed some memory leaks
* Improved macro detection on Windows
version 0.6.4 (released 2014-12-19)
* Fixed CVE-2014-8132.
* Added SHA-2 for session ID signing with ECDSA keys.
* Added support for ECDSA host keys.
* Added support for more ECDSA hostkey algorithms.
* Added ssh_pki_key_ecdsa_name() API.
* Fixed setting the bindfd only after successful listen.
* Fixed issues with user created sockets.
* Fixed several issues in libssh C++ wrapper.
* Fixed several documentation issues.
* Fixed channel exit-signal request.
* Fixed X11 request screen number in messages.
* Fixed several memory leaks.
version 0.6.3 (released 2014-03-04)
* Fixed CVE-2014-0017.
* Fixed memory leak with ecdsa signatures.
version 0.6.2 (released 2014-03-04)
* security: fix for vulnerability CVE-2014-0017
version 0.6.1 (released 2014-02-08)
* Added support for libgcrypt 1.6.
* Added ssh_channel_accept_forward().
* Added known_hosts heuristic during connection (#138).
* Added getters for session cipher names.
* Fixed decrypt of zero length buffer.
* Fixed padding in RSA signature blobs.
* Fixed DSA signature extraction.
* Fixed some memory leaks.
* Fixed read of non-connected socket.
* Fixed thread dectection.
version 0.6.0 (released 2014-01-08) version 0.6.0 (released 2014-01-08)
* Added new publicy key API. * Added new publicy key API.
* Added new userauth API. * Added new userauth API.

59
CodingStyle Normal file
View File

@@ -0,0 +1,59 @@
Coding Style Conventions
========================
Coding style guidelines are about reducing the number of unnecessary
reformatting patches and making things easier for developers to work together.
You don't have to like them or even agree with them, but once put in place we
all have to abide by them (or vote to change them). However, coding style
should never outweigh coding itself and so the guidelines described here are
hopefully easy enough to follow as they are very common and supported by tools
and editors.
The basic style for C code is the Linux kernel coding style [1] with one
excecption, we use 4 spaces instead of tabs. This closely matches what most
libssh developers use already anyways, with a few exceptions as mentioned
below.
To shorthen this here are the highlights:
* Maximum line width is 80 characters
The reason is not about people with low-res screens but rather sticking
to 80 columns prevents you from easily nesting more than one level of
if statements or other code blocks.
* Use 4 spaces to indent
* No trailing whitespaces
* Follow the K&R guidelines. We won't go through all of them here. Do you
have a copy of "The C Programming Language" anyways right?
Editors
========
VIM
----
set ts=4 sw=4 et cindent
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:
if has("syntax") && (&t_Co > 2 || has("gui_running"))
syntax on
function! ActivateInvisibleCharIndicator()
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
highlight TrailingSpace ctermbg=Red
endf
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
endif
" Show tabs, trailing whitespace, and continued lines visually
set list listchars=tab:»·,trail:·,extends:…
" highlight overly long lines same as TODOs.
set textwidth=80
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
[1] https://www.kernel.org/doc/Documentation/CodingStyle

View File

@@ -1,120 +0,0 @@
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

@@ -1,14 +1,13 @@
include(CheckIncludeFile) include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists) include(CheckSymbolExists)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckLibraryExists) include(CheckLibraryExists)
include(CheckTypeSize) include(CheckTypeSize)
include(CheckStructHasMember) include(CheckCXXSourceCompiles)
include(TestBigEndian) include(TestBigEndian)
set(PACKAGE ${PROJECT_NAME}) set(PACKAGE ${APPLICATION_NAME})
set(VERSION ${PROJECT_VERSION}) set(VERSION ${APPLICATION_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}")
@@ -42,33 +41,18 @@ if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
"void __attribute__((visibility(\"default\"))) test() {} "void __attribute__((visibility(\"default\"))) test() {}
int main(void){ return 0; } int main(void){ return 0; }
" WITH_VISIBILITY_HIDDEN) " WITH_VISIBILITY_HIDDEN)
unset(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS "")
endif (NOT GNUCC_VERSION EQUAL 34) endif (NOT GNUCC_VERSION EQUAL 34)
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2) endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
# HEADER FILES # HEADER FILES
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${ARGP_INCLUDE_DIR})
check_include_file(argp.h HAVE_ARGP_H) check_include_file(argp.h HAVE_ARGP_H)
unset(CMAKE_REQUIRED_INCLUDES)
check_include_file(pty.h HAVE_PTY_H) check_include_file(pty.h HAVE_PTY_H)
check_include_file(utmp.h HAVE_UTMP_H)
check_include_file(termios.h HAVE_TERMIOS_H) check_include_file(termios.h HAVE_TERMIOS_H)
check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(util.h HAVE_UTIL_H) check_include_file(util.h HAVE_UTIL_H)
check_include_file(libutil.h HAVE_LIBUTIL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/utime.h HAVE_SYS_UTIME_H)
check_include_file(sys/param.h HAVE_SYS_PARAM_H)
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(byteswap.h HAVE_BYTESWAP_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_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H) check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
if (NOT HAVE_WSPIAPI_H) if (NOT HAVE_WSPIAPI_H)
message(STATUS "WARNING: Without wspiapi.h, this build will only work on Windows XP and newer versions") message(STATUS "WARNING: Without wspiapi.h, this build will only work on Windows XP and newer versions")
@@ -76,70 +60,29 @@ if (WIN32)
check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H) check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H)
endif (WIN32) endif (WIN32)
if (OPENSSL_FOUND) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
if (NOT HAVE_OPENSSL_DES_H)
message(FATAL_ERROR "Could not detect openssl/des.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H) check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
if (NOT HAVE_OPENSSL_AES_H)
message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H) check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H) check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H) check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H) check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_aes_128_ctr HAVE_OPENSSL_EVP_AES_CTR)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
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_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(CRYPTO_ctr128_encrypt HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
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_LIBRARIES)
endif()
if (CMAKE_HAVE_PTHREAD_H) if (CMAKE_HAVE_PTHREAD_H)
set(HAVE_PTHREAD_H 1) set(HAVE_PTHREAD_H 1)
endif (CMAKE_HAVE_PTHREAD_H) endif (CMAKE_HAVE_PTHREAD_H)
if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS) if (NOT WITH_GCRYPT)
if (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H) if (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H)
set(HAVE_OPENSSL_ECC 1) set(HAVE_OPENSSL_ECC 1)
endif (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H) endif (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H)
@@ -147,80 +90,53 @@ if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS)
if (HAVE_OPENSSL_ECC) if (HAVE_OPENSSL_ECC)
set(HAVE_ECC 1) set(HAVE_ECC 1)
endif (HAVE_OPENSSL_ECC) endif (HAVE_OPENSSL_ECC)
endif () endif (NOT WITH_GCRYPT)
if (NOT WITH_MBEDTLS)
set(HAVE_DSA 1)
endif (NOT WITH_MBEDTLS)
# FUNCTIONS # FUNCTIONS
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(vsnprintf HAVE_VSNPRINTF)
check_function_exists(strtoull HAVE_STRTOULL) check_function_exists(snprintf HAVE_SNPRINTF)
check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO) check_function_exists(poll HAVE_POLL)
check_function_exists(memset_s HAVE_MEMSET_S) check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
if (HAVE_GLOB_H) check_function_exists(ntohll HAVE_NTOHLL)
check_struct_has_member(glob_t gl_flags glob.h HAVE_GLOB_GL_FLAGS_MEMBER) check_function_exists(htonll HAVE_HTONLL)
check_function_exists(glob HAVE_GLOB)
endif (HAVE_GLOB_H)
if (NOT WIN32)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
endif (NOT WIN32)
if (WIN32) if (WIN32)
check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
check_symbol_exists(_vsnprintf_s "stdio.h" HAVE__VSNPRINTF_S)
check_symbol_exists(_vsnprintf "stdio.h" HAVE__VSNPRINTF)
check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
check_symbol_exists(_snprintf_s "stdio.h" HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL)
check_symbol_exists(htonll winsock2.h HAVE_HTONLL)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
check_symbol_exists(select "winsock2.h;ws2tcpip.h" HAVE_SELECT)
check_symbol_exists(poll "winsock2.h;ws2tcpip.h" HAVE_SELECT)
# The getaddrinfo function is defined to the WspiapiGetAddrInfo inline function
check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" HAVE_GETADDRINFO)
unset(CMAKE_REQUIRED_LIBRARIES)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_function_exists(_strtoui64 HAVE__STRTOUI64) check_function_exists(_strtoui64 HAVE__STRTOUI64)
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
check_function_exists(_vsnprintf HAVE__VSNPRINTF)
check_function_exists(_snprintf HAVE__SNPRINTF)
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_GETADDRINFO TRUE)
set(HAVE_GETHOSTBYNAME TRUE)
if (MSVC)
set(HAVE_NTOHLL TRUE)
set(HAVE_HTONLL TRUE)
endif (MSVC)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_SELECT TRUE) set(HAVE_SELECT TRUE)
check_symbol_exists(SecureZeroMemory "windows.h" HAVE_SECURE_ZERO_MEMORY)
else (WIN32)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_symbol_exists(ntohll arpa/inet.h HAVE_NTOHLL)
check_symbol_exists(htonll arpa/inet.h HAVE_HTONLL)
endif (WIN32) endif (WIN32)
if (UNIX) if (UNIX)
if (NOT LINUX) if (NOT LINUX)
# libsocket (Solaris) # libsocket (Solaris)
check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET) check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET)
if (HAVE_LIBSOCKET) if (HAVE_LIBSOCKET)
set(HAVE_GETADDRINFO TRUE) set(HAVE_GETADDRINFO TRUE)
set(_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} socket) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} socket)
endif (HAVE_LIBSOCKET) endif (HAVE_LIBSOCKET)
# libnsl/inet_pton (Solaris) # libnsl/inet_pton (Solaris)
check_library_exists(nsl inet_pton "" HAVE_LIBNSL) check_library_exists(nsl inet_pton "" HAVE_LIBNSL)
if (HAVE_LIBNSL) if (HAVE_LIBNSL)
set(_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} nsl) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} nsl)
endif (HAVE_LIBNSL) endif (HAVE_LIBNSL)
# librt # librt
@@ -229,15 +145,16 @@ if (UNIX)
check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME) check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME) if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
set(_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} rt) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME) endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
check_library_exists(util forkpty "" HAVE_LIBUTIL) check_library_exists(util forkpty "" HAVE_LIBUTIL)
check_function_exists(cfmakeraw HAVE_CFMAKERAW) check_function_exists(cfmakeraw HAVE_CFMAKERAW)
check_function_exists(strtoull HAVE_STRTOULL)
check_function_exists(__strtoull HAVE___STRTOULL) check_function_exists(__strtoull HAVE___STRTOULL)
endif (UNIX) endif (UNIX)
set(LIBSSH_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} CACHE INTERNAL "libssh required system libraries") set(LIBSSH_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "libssh required system libraries")
# LIBRARIES # LIBRARIES
if (OPENSSL_FOUND) if (OPENSSL_FOUND)
@@ -247,27 +164,16 @@ endif (OPENSSL_FOUND)
if (GCRYPT_FOUND) if (GCRYPT_FOUND)
set(HAVE_LIBGCRYPT 1) set(HAVE_LIBGCRYPT 1)
if (GCRYPT_VERSION VERSION_GREATER "1.4.6") if (GCRYPT_VERSION VERSION_GREATER "1.4.6")
set(HAVE_GCRYPT_ECC 1) #set(HAVE_GCRYPT_ECC 1)
set(HAVE_ECC 1) #set(HAVE_ECC 1)
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6") endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
endif (GCRYPT_FOUND) endif (GCRYPT_FOUND)
if (MBEDTLS_FOUND) if (CMAKE_HAVE_THREADS_LIBRARY)
set(HAVE_LIBMBEDCRYPTO 1) if (CMAKE_USE_PTHREADS_INIT)
set(HAVE_ECC 1) set(HAVE_PTHREAD 1)
endif (MBEDTLS_FOUND) endif (CMAKE_USE_PTHREADS_INIT)
endif (CMAKE_HAVE_THREADS_LIBRARY)
if (CMAKE_USE_PTHREADS_INIT)
set(HAVE_PTHREAD 1)
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("
@@ -284,87 +190,6 @@ 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("
#define FALL_THROUGH __attribute__((fallthrough))
int main(void) {
int i = 2;
switch (i) {
case 0:
FALL_THROUGH;
case 1:
break;
default:
break;
}
return 0;
}" 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>
@@ -372,74 +197,15 @@ int main(void)
{ {
char buf[] = \"This is some content\"; char buf[] = \"This is some content\";
memset(buf, '\\\\0', sizeof(buf)); __asm__ volatile(\"\" : : \"g\"(&buf) : \"memory\"); memset(buf, '\\\\0', sizeof(buf)); __asm__ volatile(\"\" : : \"r\"(&buf) : \"memory\");
return 0; return 0;
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION) }" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
check_c_source_compiles("
#include <stdio.h>
#define __VA_NARG__(...) (__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
#define __VA_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,N,...) N
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define myprintf(format, ...) printf((format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__)
int main(void) {
myprintf(\"%d %d %d %d\",1,2,3);
return 0;
}" HAVE_GCC_NARG_MACRO)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __func__);
return 0;
}" HAVE_COMPILER__FUNC__)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __FUNCTION__);
return 0;
}" HAVE_COMPILER__FUNCTION__)
# This is only available with OpenBSD's gcc implementation */
if (OPENBSD)
check_c_source_compiles("
#define ARRAY_LEN 16
void test_attr(const unsigned char *k)
__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)
endif (WITH_DEBUG_CRYPTO) endif (WITH_DEBUG_CRYPTO)
if (WITH_DEBUG_PACKET)
set(DEBUG_PACKET 1)
endif (WITH_DEBUG_PACKET)
if (WITH_DEBUG_CALLTRACE) if (WITH_DEBUG_CALLTRACE)
set(DEBUG_CALLTRACE 1) set(DEBUG_CALLTRACE 1)
endif (WITH_DEBUG_CALLTRACE) endif (WITH_DEBUG_CALLTRACE)

View File

@@ -1,49 +1,33 @@
option(WITH_GSSAPI "Build with GSSAPI support" ON) option(WITH_GSSAPI "Build with GSSAPI support" ON)
option(WITH_ZLIB "Build with ZLIB support" ON) option(WITH_ZLIB "Build with ZLIB support" ON)
option(WITH_SSH1 "Build with SSH1 support" OFF)
option(WITH_SFTP "Build with SFTP support" ON) option(WITH_SFTP "Build with SFTP support" ON)
option(WITH_SERVER "Build with SSH server support" ON) option(WITH_SERVER "Build with SSH server support" ON)
option(WITH_STATIC_LIB "Build with a static library" OFF) option(WITH_STATIC_LIB "Build with a static library" OFF)
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF) option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
option(WITH_DEBUG_PACKET "Build with packet debug output" OFF)
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON) option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
option(WITH_GCRYPT "Compile against libgcrypt" OFF) option(WITH_GCRYPT "Compile against libgcrypt" OFF)
option(WITH_MBEDTLS "Compile against libmbedtls" OFF)
option(WITH_PCAP "Compile with Pcap generation support" ON) option(WITH_PCAP "Compile with Pcap generation support" ON)
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF) option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
option(UNIT_TESTING "Build with unit tests" OFF) option(WITH_TESTING "Build with unit tests" OFF)
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF) option(WITH_CLIENT_TESTING "Build with client tests; requires a running sshd" OFF)
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
option(WITH_BENCHMARKS "Build benchmarks tools" OFF) option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
option(WITH_EXAMPLES "Build examples" ON) option(WITH_EXAMPLES "Build examples" ON)
option(WITH_NACL "Build with libnacl (curve25519)" ON) option(WITH_NACL "Build with libnacl (curve25519" ON)
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
option(WITH_ABI_BREAK "Allow ABI break" 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(WITH_TESTING ON)
set(CLIENT_TESTING ON) endif(WITH_BENCHMARKS)
endif()
if (WITH_STATIC_LIB) if (WITH_TESTING)
set(BUILD_STATIC_LIB ON) set(WITH_STATIC_LIB ON)
endif (WITH_STATIC_LIB) endif (WITH_TESTING)
if (UNIT_TESTING)
set(BUILD_STATIC_LIB ON)
endif (UNIT_TESTING)
if (WITH_NACL) if (WITH_NACL)
set(WITH_NACL ON) set(WITH_NACL ON)
endif (WITH_NACL) endif (WITH_NACL)
if (WITH_ABI_BREAK)
set(WITH_SYMBOL_VERSIONING ON)
endif (WITH_ABI_BREAK)

28
INSTALL
View File

@@ -14,20 +14,16 @@ or
optional: optional:
- [libz](http://www.zlib.net) >= 1.2 - [libz](http://www.zlib.net) >= 1.2
- [socket_wrapper](https://cwrap.org/) >= 1.1.5
- [nss_wrapper](https://cwrap.org/) >= 1.1.2
- [uid_wrapper](https://cwrap.org/) >= 1.2.0
- [pam_wrapper](https://cwrap.org/) >= 1.0.1
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.
For Windows use vcpkg: Windows binaries known to be working:
https://github.com/Microsoft/vcpkg - http://www.slproweb.com/products/Win32OpenSSL.html
- http://zlib.net/ -> zlib compiled DLL
which you can use to install openssl and zilib. libssh itself is also part of We installed them in C:\Program Files
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
@@ -35,27 +31,13 @@ First, you need to configure the compilation, using CMake. Go inside the
GNU/Linux, MacOS X, MSYS/MinGW: GNU/Linux, MacOS X, MSYS/MinGW:
cmake -DUNIT_TESTING=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug .. cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
make make
On Windows you should choose a makefile gernerator with -G or use On Windows you should choose a makefile gernerator with -G or use
cmake-gui.exe .. cmake-gui.exe ..
To enable additional client tests against a local OpenSSH server, add the
compile option -DCLIENT_TESTING=ON. These tests require an OpenSSH
server package and some wrapper libraries (see optional requirements) to
be installed.
If you're interested in server testing, then a OpenSSH client should be
installed on the system and if possible also dropbear. Once that is done
enable server support with -DWITH_SERVER=ON and enable testing of it with
-DSERVER_TESTING=ON.
## Testing build
make test
### CMake standard options ### CMake standard options
Here is a list of the most interesting options provided out of the box by Here is a list of the most interesting options provided out of the box by
CMake. CMake.

125
README
View File

@@ -33,11 +33,130 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
http://www.libssh.org http://www.libssh.org
4* Contributing 4* API Changes !
-_-_-_-_-_-_-_-_-_ -_-_-_-_-_-_-_-_-_
Please read the file 'SubmittingPatches' next to this README file. It explains Changes between 0.4 and 0.5
our copyright policy and how you should send patches for upstream inclusion. ---------------------------
We use the ssh_ prefix as namespace for every function now. There is a legacy.h
which could be used to get the old function names.
Changes between 0.3 and 0.4
---------------------------
We changed libssh to be typesafe now:
SSH_SESSION *session -> ssh_session session
SFTP_SESSION *sftp -> sftp_session sftp
CHANNEL *channel -> ssh_channel channel
STRING *string -> ssh_string string
...
The options structure has been removed and there is a new function. This
function can set all available options now. You can find the enum in the
header file and it is documented. Example:
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
5* Copyright policy
-_-_-_-_-_-_-_-_-_-_
libssh is a project with distributed copyright ownership, which means we prefer
the copyright on parts of libssh to be held by individuals rather than
corporations if possible. There are historical legal reasons for this, but one
of the best ways to explain it is that its much easier to work with
individuals who have ownership than corporate legal departments if we ever need
to make reasonable compromises with people using and working with libssh.
We track the ownership of every part of libssh via git, our source code control
system, so we know the provenance of every piece of code that is committed to
libssh.
So if possible, if youre doing libssh changes on behalf of a company who
normally owns all the work you do please get them to assign personal copyright
ownership of your changes to you as an individual, that makes things very easy
for us to work with and avoids bringing corporate legal departments into the
picture.
If you cant do this we can still accept patches from you owned by your
employer under a standard employment contract with corporate copyright
ownership. It just requires a simple set-up process first.
We use a process very similar to the way things are done in the Linux Kernel
community, so it should be very easy to get a sign off from your corporate
legal department. The only changes weve made are to accommodate the license we
use, which is LGPLv2 (or later) whereas the Linux kernel uses GPLv2.
The process is called signing.
How to sign your work
----------------------
Once you have permission to contribute to libssh from your employer, simply
email a copy of the following text from your corporate email address to:
contributing@libssh.org
--------------------------------------------------------------------------
libssh Developer's Certificate of Origin. Version 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the appropriate
version of the GNU General Public License; or
(b) The contribution is based upon previous work that, to the best of
my knowledge, is covered under an appropriate open source license
and I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under
the GNU General Public License, in the appropriate version; or
(c) The contribution was provided directly to me by some other
person who certified (a) or (b) and I have not modified it.
(d) I understand and agree that this project and the contribution are
public and that a record of the contribution (including all
metadata and personal information I submit with it, including my
sign-off) is maintained indefinitely and may be redistributed
consistent with the libssh Team's policies and the requirements of
the GNU GPL where they are relevant.
(e) I am granting this work to this project under the terms of the
GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of
the License, or (at the option of the project) any later version.
http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------
We will maintain a copy of that email as a record that you have the rights to
contribute code to libssh under the required licenses whilst working for the
company where the email came from.
Then when sending in a patch via the normal mechanisms described above, add a
line that states:
Signed-off-by: Random J Developer <random@developer.example.org>
using your real name and the email address you sent the original email you used
to send the libssh Developers Certificate of Origin to us (sorry, no
pseudonyms or anonymous contributions.)
Thats it! Such code can then quite happily contain changes that have copyright
messages such as:
(c) Example Corporation.
and can be merged into the libssh codebase in the same way as patches from any
other individual. You dont need to send in a copy of the libssh Developers
Certificate of Origin for each patch, or inside each patch. Just the sign-off
message is all that is required once weve received the initial email.
Have fun and happy libssh hacking! Have fun and happy libssh hacking!

View File

@@ -1,375 +0,0 @@
Coding conventions in the libssh tree
======================================
===========
Quick Start
===========
Coding style guidelines are about reducing the number of unnecessary
reformatting patches and making things easier for developers to work together.
You don't have to like them or even agree with them, but once put in place we
all have to abide by them (or vote to change them). However, coding style
should never outweigh coding itself and so the guidelines described here are
hopefully easy enough to follow as they are very common and supported by tools
and editors.
The basic style for C code, is the Linux kernel coding style (See
Documentation/CodingStyle in the kernel source tree). This closely matches what
libssh developers use already anyways, with a few exceptions as mentioned
below.
But to save you the trouble of reading the Linux kernel style guide, here
are the highlights.
* Maximum Line Width is 80 Characters
The reason is not about people with low-res screens but rather sticking
to 80 columns prevents you from easily nesting more than one level of
if statements or other code blocks.
* Use 4 Spaces to Indent
* No Trailing Whitespace
Clean up your files before committing.
* Follow the K&R guidelines. We won't go through all of them here. Do you
have a copy of "The C Programming Language" anyways right?
=============
Editor Hints
=============
Emacs
------
Add the follow to your $HOME/.emacs file:
(add-hook 'c-mode-hook
(lambda ()
(c-set-style "linux")
(c-toggle-auto-state)))
Vim
----
For the basic vi editor included with all variants of \*nix, add the
following to $HOME/.vimrc:
set ts=4 sw=4 et cindent
You can use the Vim gitmodline plugin to store this in the git config:
http://git.cryptomilk.org/projects/vim-gitmodeline.git/
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:
if has("syntax") && (&t_Co > 2 || has("gui_running"))
syntax on
function! ActivateInvisibleCharIndicator()
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
highlight TrailingSpace ctermbg=Red
endf
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
endif
" Show tabs, trailing whitespace, and continued lines visually
set list listchars=tab:»·,trail:·,extends:…
" highlight overly long lines same as TODOs.
set textwidth=80
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
==========================
FAQ & Statement Reference
==========================
Comments
---------
Comments should always use the standard C syntax. C++ style comments are not
currently allowed.
The lines before a comment should be empty. If the comment directly belongs to
the following code, there should be no empty line after the comment, except if
the comment contains a summary of multiple following code blocks.
This is good:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/**
* @brief This is a doxygen comment.
*
* This is a more detailed explanation of
* this simple function.
*
* @param[in] param1 The parameter value of the function.
*
* @param[out] result1 The result value of the function.
*
* @return 0 on success and -1 on error.
*/
int example(int param1, int *result1);
This is bad:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/*This is a one line comment.*/
/* This is a multi line comment,
with some more words...*/
/*
* This is a multi line comment,
* with some more words...*/
Indention & Whitespace & 80 columns
------------------------------------
To avoid confusion, indentations have to be 4 spaces. Do not use tabs!. When
wrapping parameters for function calls, align the parameter list with the first
parameter on the previous line. For example,
var1 = foo(arg1,
arg2,
arg3);
The previous example is intended to illustrate alignment of function
parameters across lines and not as encourage for gratuitous line
splitting. Never split a line before columns 70 - 79 unless you
have a really good reason. Be smart about formatting.
If, switch, & Code blocks
--------------------------
Always follow an 'if' keyword with a space but don't include additional
spaces following or preceding the parentheses in the conditional.
This is good:
if (x == 1)
This is bad:
if ( x == 1 )
or
if (x==1)
Yes we have a lot of code that uses the second and third form and we are trying
to clean it up without being overly intrusive.
Note that this is a rule about parentheses following keywords and not
functions. Don't insert a space between the name and left parentheses when
invoking functions.
Braces for code blocks used by for, if, switch, while, do..while, etc. should
begin on the same line as the statement keyword and end on a line of their own.
You should always include braces, even if the block only contains one
statement. NOTE: Functions are different and the beginning left brace should
be located in the first column on the next line.
If the beginning statement has to be broken across lines due to length, the
beginning brace should be on a line of its own.
The exception to the ending rule is when the closing brace is followed by
another language keyword such as else or the closing while in a do..while loop.
Good examples:
if (x == 1) {
printf("good\n");
}
for (x = 1; x < 10; x++) {
print("%d\n", x);
}
for (really_really_really_really_long_var_name = 0;
really_really_really_really_long_var_name < 10;
really_really_really_really_long_var_name++)
{
print("%d\n", really_really_really_really_long_var_name);
}
do {
printf("also good\n");
} while (1);
Bad examples:
while (1)
{
print("I'm in a loop!\n"); }
for (x=1;
x<10;
x++)
{
print("no good\n");
}
if (i < 10)
print("I should be in braces.\n");
Goto
-----
While many people have been academically taught that "goto"s are fundamentally
evil, they can greatly enhance readability and reduce memory leaks when used as
the single exit point from a function. But in no libssh world what so ever is a
goto outside of a function or block of code a good idea.
Good Examples:
int function foo(int y)
{
int *z = NULL;
int rc = 0;
if (y < 10) {
z = malloc(sizeof(int)*y);
if (z == NULL) {
rc = 1;
goto done;
}
}
print("Allocated %d elements.\n", y);
done:
if (z != NULL) {
free(z);
}
return rc;
}
Initialize pointers
-------------------
All pointer variables MUST be initialized to NULL. History has
demonstrated that uninitialized pointer variables have lead to various
bugs and security issues.
Pointers MUST be initialized even if the assignment directly follows
the declaration, like pointer2 in the example below, because the
instructions sequence may change over time.
Good Example:
char *pointer1 = NULL;
char *pointer2 = NULL;
pointer2 = some_func2();
...
pointer1 = some_func1();
Typedefs
---------
libssh tries to avoid "typedef struct { .. } x_t;" so we do always try to use
"struct x { .. };". We know there are still such typedefs in the code, but for
new code, please don't do that anymore.
Make use of helper variables
-----------------------------
Please try to avoid passing function calls as function parameters in new code.
This makes the code much easier to read and it's also easier to use the "step"
command within gdb.
Good Example:
char *name;
name = get_some_name();
if (name == NULL) {
...
}
rc = some_function_my_name(name);
...
Bad Example:
rc = some_function_my_name(get_some_name());
...
Please try to avoid passing function return values to if- or while-conditions.
The reason for this is better handling of code under a debugger.
Good example:
x = malloc(sizeof(short) * 10);
if (x == NULL) {
fprintf(stderr, "Unable to alloc memory!\n");
}
Bad example:
if ((x = malloc(sizeof(short)*10)) == NULL ) {
fprintf(stderr, "Unable to alloc memory!\n");
}
There are exceptions to this rule. One example is walking a data structure in
an iterator style:
while ((opt = poptGetNextOpt(pc)) != -1) {
... do something with opt ...
}
But in general, please try to avoid this pattern.
Control-Flow changing macros
-----------------------------
Macros like STATUS_NOT_OK_RETURN that change control flow (return/goto/etc)
from within the macro are considered bad, because they look like function calls
that never change control flow. Please do not introduce them.

View File

@@ -1,11 +0,0 @@
mbedTLS and libssh in multithreaded applications
==================================================
To use libssh with mbedTLS in a multithreaded application, mbedTLS has to be
built with threading support enabled.
If threading support is not available and multi threading is used, ssh_init
will fail.
More information about building mbedTLS with threading support can be found
in the mbedTLS documentation.

View File

@@ -1,44 +0,0 @@
[![pipeline status](https://gitlab.com/libssh/libssh-mirror/badges/master/pipeline.svg)](https://gitlab.com/libssh/libssh-mirror/commits/master)
```
_ _ _ _
(_) (_) (_) (_)
(_) _ (_) _ _ _ _ _ (_) _
(_) (_) (_)(_) _ (_)(_) (_)(_) (_)(_) _
(_) (_) (_) (_) _ (_) _ (_) (_) (_)
(_) (_) (_)(_)(_) (_)(_) (_)(_) (_) (_).org
The SSH library
```
# Why?
Why not ? :) I've began to work on my own implementation of the ssh protocol
because i didn't like the currently public ones.
Not any allowed you to import and use the functions as a powerful library,
and so i worked on a library-based SSH implementation which was non-existing
in the free and open source software world.
# How/Who?
If you downloaded this file, you must know what it is : a library for
accessing ssh client services through C libraries calls in a simple manner.
Everybody can use this software under the terms of the LGPL - see the COPYING
file
If you ask yourself how to compile libssh, please read INSTALL before anything.
# Where ?
https://www.libssh.org
# Contributing
Please read the file 'SubmittingPatches' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Have fun and happy libssh hacking!
The libssh Team

View File

@@ -1,9 +1,9 @@
How to contribute a patch to libssh How to contribute a patch to libssh
==================================== ====================================
Please checkout the libssh source code using git. Change the code and then Simple, just make the code change, and email it as either a "diff -u"
use "git format-patch" to create a patch. The patch should be signed (see change, or as a "git format-patch" change against the original source
below) and send it to libssh@libssh.org, or attach it to a bug report at code to libssh@libssh.org, or attach it to a bug report at
https://red.libssh.org/ https://red.libssh.org/
For larger code changes, breaking the changes up into a set of simple For larger code changes, breaking the changes up into a set of simple

View File

@@ -63,7 +63,7 @@ function clean_build_dir() {
function usage () { function usage () {
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make
(gmake|make)|--ccompiler(gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withserver|--withoutsymbolversioning]" (gmake|make)|--ccompiler (gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withssh1|--withserver]"
cleanup_and_exit cleanup_and_exit
} }
@@ -137,20 +137,17 @@ while test -n "$1"; do
OPTIONS="${OPTIONS} -DWITH_STATIC_LIB=ON" OPTIONS="${OPTIONS} -DWITH_STATIC_LIB=ON"
;; ;;
*-unittesting) *-unittesting)
OPTIONS="${OPTIONS} -DUNIT_TESTING=ON" OPTIONS="${OPTIONS} -DWITH_TESTING=ON"
;; ;;
*-clientunittesting) *-clientunittesting)
OPTIONS="${OPTIONS} -DCLIENT_TESTING=ON" OPTIONS="${OPTIONS} -DWITH_CLIENT_TESTING=ON"
;;
*-withssh1)
OPTIONS="${OPTIONS} -DWITH_SSH1=ON"
;; ;;
*-withserver) *-withserver)
OPTIONS="${OPTIONS} -DWITH_SERVER=ON" OPTIONS="${OPTIONS} -DWITH_SERVER=ON"
;; ;;
*-withoutsymbolversioning)
OPTIONS="${OPTIONS} -DWITH_SYMBOL_VERSIONING=OFF"
;;
*-finalrelease)
OPTIONS="${OPTIONS} -DWITH_FINAL=ON"
;;
----noarg) ----noarg)
echo "$ARG does not take an argument" echo "$ARG does not take an argument"
cleanup_and_exit cleanup_and_exit

View File

@@ -1,21 +0,0 @@
#
# 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,120 +1,23 @@
# # - 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-2018 Andreas Schneider <asn@cryptomilk.org> # Copyright (c) 2007-2010 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_CROSSCOMPILING) if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
if (WIN32) 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")
find_program(WINE_EXECUTABLE set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
NAMES wine) set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
set(TARGET_SYSTEM_EMULATOR ${WINE_EXECUTABLE}) set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
endif() endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
endif()
function(ADD_CMOCKA_TEST _TARGET_NAME)
set(one_value_arguments
)
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}
)
function (ADD_CMOCKA_TEST _testName _testSource)
add_executable(${_testName} ${_testSource})
target_link_libraries(${_testName} ${ARGN})
add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName})
endfunction (ADD_CMOCKA_TEST) endfunction (ADD_CMOCKA_TEST)

View File

@@ -15,15 +15,12 @@
# 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)
macro(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT) function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
set(CMAKE_REQUIRED_FLAGS "${_FLAG}") set(CMAKE_REQUIRED_DEFINITIONS "${_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}")
set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") endfunction(CHECK_C_COMPILER_FLAG_SSP)
endmacro(CHECK_C_COMPILER_FLAG_SSP)

View File

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

View File

@@ -1,37 +1,77 @@
# 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 #
set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage" # Define GNUCC compiler flags
CACHE STRING "Flags used by the C compiler during PROFILING builds.") #
set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage" if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
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.")
# Activate with: -DCMAKE_BUILD_TYPE=AddressSanitizer # add -Wconversion ?
set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
CACHE STRING "Flags used by the C compiler during ADDRESSSANITIZER builds.") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
set(CMAKE_CXX_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
CACHE STRING "Flags used by the CXX compiler during ADDRESSSANITIZER builds.") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")
# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer # with -fPIC
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" check_c_compiler_flag("-fPIC" WITH_FPIC)
CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.") if (WITH_FPIC)
set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.") endif (WITH_FPIC)
set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
set(CMAKE_MODULE_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" if (WITH_STACK_PROTECTOR)
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" endif (WITH_STACK_PROTECTOR)
CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.")
endif() 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)

View File

@@ -1,92 +0,0 @@
#
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
#.rst:
# ExtractSymbols
# --------------
#
# This is a helper script for FindABImap.cmake.
#
# Extract symbols from header files and output a list to a file.
# This script is run in build time to extract symbols from the provided header
# files. This way, symbols added or removed can be checked and used to update
# the symbol version script.
#
# All symbols followed by the character ``'('`` are extracted. If a
# ``FILTER_PATTERN`` is provided, only the lines containing the given string are
# considered.
#
# Expected defined variables
# --------------------------
#
# ``HEADERS_LIST_FILE``:
# Required, expects a file containing the list of header files to be parsed.
#
# ``OUTPUT_PATH``:
# Required, expects the output file path.
#
# Optionally defined variables
# ----------------------------
#
# ``FILTER_PATTERN``:
# Expects a string. Only lines containing the given string will be considered
# when extracting symbols.
#
if (NOT DEFINED OUTPUT_PATH)
message(SEND_ERROR "OUTPUT_PATH not defined")
endif()
if (NOT DEFINED HEADERS_LIST_FILE)
message(SEND_ERROR "HEADERS not defined")
endif()
file(READ ${HEADERS_LIST_FILE} HEADERS_LIST)
set(symbols)
foreach(header ${HEADERS_LIST})
# Filter only lines containing the FILTER_PATTERN
file(STRINGS ${header} contain_filter
REGEX "^.*${FILTER_PATTERN}.*[(]"
)
# Remove function-like macros
foreach(line ${contain_filter})
if (NOT ${line} MATCHES ".*#[ ]*define")
list(APPEND not_macro ${line})
endif()
endforeach()
set(functions)
# Get only the function names followed by '('
foreach(line ${not_macro})
string(REGEX MATCHALL "[a-zA-Z0-9_]+[ ]*[(]" func ${line})
list(APPEND functions ${func})
endforeach()
set(extracted_symbols)
# Remove '('
foreach(line ${functions})
string(REGEX REPLACE "[(]" "" symbol ${line})
string(STRIP "${symbol}" symbol)
list(APPEND extracted_symbols ${symbol})
endforeach()
list(APPEND symbols ${extracted_symbols})
endforeach()
list(REMOVE_DUPLICATES symbols)
list(SORT symbols)
string(REPLACE ";" "\n" symbols_list "${symbols}")
file(WRITE ${OUTPUT_PATH} "${symbols_list}")

View File

@@ -1,486 +0,0 @@
#
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
#.rst:
# FindABIMap
# ----------
#
# This file provides functions to generate the symbol version script. It uses
# the ``abimap`` tool to generate and update the linker script file. It can be
# installed by calling::
#
# $ pip install abimap
#
# The ``function generate_map_file`` generates a symbol version script
# containing the provided symbols. It defines a custom command which sets
# ``target_name`` as its ``OUTPUT``.
#
# The experimental function ``extract_symbols()`` is provided as a simple
# parser to extract the symbols from C header files. It simply extracts symbols
# followed by an opening '``(``'. It is recommended to use a filter pattern to
# select the lines to be considered. It defines a custom command which sets
# ``target_name`` as its output.
#
# The helper function ``get_files_list()`` is provided to find files given a
# name pattern. It defines a custom command which sets ``target_name`` as its
# output.
#
# Functions provided
# ------------------
#
# ::
#
# generate_map_file(target_name
# RELEASE_NAME_VERSION release_name
# SYMBOLS symbols_target
# [CURRENT_MAP cur_map]
# [FINAL]
# [BREAK_ABI]
# [COPY_TO output]
# )
#
# ``target_name``:
# Required, expects the name of the file to receive the generated symbol
# version script. It should be added as a dependency for the library. Use the
# linker option ``--version-script filename`` to add the version information
# to the symbols when building the library.
#
# ``RELEASE_NAME_VERSION``:
# Required, expects a string containing the name and version information to be
# added to the symbols in the format ``lib_name_1_2_3``.
#
# ``SYMBOLS``:
# Required, expects a target with the property ``LIST_FILE`` containing a path
# to a file containing the list of symbols to be added to the symbol version
# script.
#
# ``CURRENT_MAP``:
# Optional. If given, the new set of symbols will be checked against the
# ones contained in the ``cur_map`` file and updated properly. If an
# incompatible change is detected and ``BREAK_ABI`` is not defined, the build
# will fail.
#
# ``FINAL``:
# Optional. If given, will provide the ``--final`` option to ``abimap`` tool,
# which will mark the modified release in the symbol version script with a
# special comment, preventing later changes. This option should be set when
# creating a library release and the resulting map file should be stored with
# the source code.
#
# ``BREAK_ABI``:
# Optional. If provided, will use ``abimap`` ``--allow-abi-break`` option, which
# accepts incompatible changes to the set of symbols. This is necessary if any
# previously existing symbol were removed.
#
# ``COPY_TO``:
# Optional, expects a string containing the path to where the generated
# map file will be copied.
#
# Example:
#
# .. code-block:: cmake
#
# find_package(ABIMap)
# generate_map_file("lib.map"
# RELEASE_NAME_VERSION "lib_1_0_0"
# 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
# ``${CMAKE_CURRENT_BINARY_DIR}/lib.map`` containing the provided symbols.
#
# ::
#
# get_files_list(target_name
# DIRECTORIES dir1 [dir2 ...]
# FILES_PATTERNS exp1 [exp2 ...]
# [COPY_TO output]
# )
#
# ``target_name``:
# Required, expects the name of the target to be created. A file named as
# ``${target_name}.list`` will be created in
# ``${CMAKE_CURRENT_BINARY_DIR}`` to receive the list of files found.
#
# ``DIRECTORIES``:
# Required, expects a list of directories paths. Only absolute paths are
# supported.
#
# ``FILES_PATTERN``:
# Required, expects a list of matching expressions to find the files to be
# considered in the directories.
#
# ``COPY_TO``:
# Optional, expects a string containing the path to where the file containing
# the list of files will be copied.
#
# This command searches the directories provided in ``DIRECTORIES`` for files
# matching any of the patterns provided in ``FILES_PATTERNS``. The obtained list
# 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:
#
# .. code-block:: cmake
#
# find_package(ABIMap)
# get_files_list(target
# DIRECTORIES "/include/mylib"
# FILES_PATTERNS "*.h"
# COPY_TO "my_list.txt"
# )
#
# Consider that ``/include/mylib`` contains 3 files, ``h1.h``, ``h2.h``, and
# ``h3.hpp``
#
# Will result in a file ``my_list.txt`` containing::
#
# ``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
# HEADERS_LIST headers_list_target
# [FILTER_PATTERN pattern]
# [COPY_TO output]
# )
#
# ``target_name``:
# Required, expects the name of the target to be created. A file named after
# the string given in ``target_name`` will be created in
# ``${CMAKE_CURRENT_BINARY_DIR}`` to receive the list of symbols.
#
# ``HEADERS_LIST``:
# Required, expects a target with the property ``LIST_FILE`` set, containing a
# file path. Such file must contain a list of files paths.
#
# ``FILTER_PATTERN``:
# Optional, expects a string. Only the lines containing the filter pattern
# will be considered.
#
# ``COPY_TO``:
# Optional, expects a string containing the path to where the file containing
# the found symbols will be copied.
#
# This command extracts the symbols from the files listed in
# ``headers_list`` and write them on the ``output`` file. If ``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
# the lines containing exported function declaration, since this function is
# 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:
#
# .. code-block:: cmake
#
# find_package(ABIMap)
# extract_symbols("lib.symbols"
# HEADERS_LIST "headers_target"
# FILTER_PATTERN "API_FUNCTION"
# )
#
# Where ``LIST_FILE`` property in ``headers_target`` points to a file
# containing::
#
# header1.h;header2.h
#
# Where ``header1.h`` contains::
#
# API_FUNCTION int exported_func1(int a, int b);
#
# ``header2.h`` contains::
#
# API_FUNCTION int exported_func2(int a);
#
# int private_func2(int b);
#
# Will result in a file ``lib.symbols.list`` in ``${CMAKE_CURRENT_BINARY_DIR}``
# containing::
#
# ``exported_func1``
# ``exported_func2``
#
# Search for python which is required
if (ABIMap_FIND_REQURIED)
find_package(PythonInterp REQUIRED)
else()
find_package(PythonInterp)
endif()
if (PYTHONINTERP_FOUND)
# 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)
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
set(_EXTRACT_SYMBOLS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/ExtractSymbols.cmake)
set(_GENERATE_MAP_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/GenerateMap.cmake)
set(_GET_FILES_LIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/GetFilesList.cmake)
function(get_file_list _TARGET_NAME)
set(one_value_arguments
COPY_TO
)
set(multi_value_arguments
DIRECTORIES
FILES_PATTERNS
)
cmake_parse_arguments(_get_files_list
""
"${one_value_arguments}"
"${multi_value_arguments}"
${ARGN}
)
# The DIRS argument is required
if (NOT DEFINED _get_files_list_DIRECTORIES)
message(FATAL_ERROR "No directories paths provided. Provide a list of"
" directories paths containing header files.")
endif()
# The FILES_PATTERNS argument is required
if (NOT DEFINED _get_files_list_FILES_PATTERNS)
message(FATAL_ERROR "No matching expressions provided. Provide a list"
" of matching patterns for the header files.")
endif()
set(_FILES_LIST_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}.list)
get_filename_component(_get_files_list_OUTPUT_PATH
"${_FILES_LIST_OUTPUT_PATH}"
ABSOLUTE)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND}
-DOUTPUT_PATH="${_get_files_list_OUTPUT_PATH}"
-DDIRECTORIES="${_get_files_list_DIRECTORIES}"
-DFILES_PATTERNS="${_get_files_list_FILES_PATTERNS}"
-P ${_GET_FILES_LIST_SCRIPT}
COMMENT
"Searching for files"
)
if (DEFINED _get_files_list_COPY_TO)
# Copy the generated file back to the COPY_TO
add_custom_target(${_TARGET_NAME} ALL
COMMAND
${CMAKE_COMMAND} -E copy_if_different
${_FILES_LIST_OUTPUT_PATH} ${_get_files_list_COPY_TO}
DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}"
)
else()
add_custom_target(${_TARGET_NAME} ALL
DEPENDS ${_TARGET_NAME}_int
)
endif()
set_target_properties(${_TARGET_NAME}
PROPERTIES LIST_FILE ${_FILES_LIST_OUTPUT_PATH}
)
endfunction()
function(extract_symbols _TARGET_NAME)
set(one_value_arguments
FILTER_PATTERN
HEADERS_LIST
COPY_TO
)
set(multi_value_arguments
)
cmake_parse_arguments(_extract_symbols
""
"${one_value_arguments}"
"${multi_value_arguments}"
${ARGN}
)
# The HEADERS_LIST_FILE argument is required
if (NOT DEFINED _extract_symbols_HEADERS_LIST)
message(FATAL_ERROR "No target provided in HEADERS_LIST. Provide a"
" 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()
set_target_properties(${_TARGET_NAME}
PROPERTIES LIST_FILE ${_SYMBOLS_OUTPUT_PATH}
)
endfunction()
function(generate_map_file _TARGET_NAME)
set(options
FINAL
BREAK_ABI
)
set(one_value_arguments
RELEASE_NAME_VERSION
SYMBOLS
CURRENT_MAP
COPY_TO
)
set(multi_value_arguments
)
cmake_parse_arguments(_generate_map_file
"${options}"
"${one_value_arguments}"
"${multi_value_arguments}"
${ARGN}
)
if (NOT DEFINED _generate_map_file_SYMBOLS)
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()
if (NOT DEFINED _generate_map_file_RELEASE_NAME_VERSION)
message(FATAL_ERROR "Release name and version not provided."
" (e.g. libname_1_0_0)")
endif()
get_target_property(_SYMBOLS_FILE
${_generate_map_file_SYMBOLS}
LIST_FILE
)
# Set generated map file path
get_filename_component(_MAP_OUTPUT_PATH
"${CMAKE_CURRENT_BINARY_DIR}/${_TARGET_NAME}"
ABSOLUTE
)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND}
-DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE}
-DSYMBOLS="${_SYMBOLS_FILE}"
-DCURRENT_MAP=${_generate_map_file_CURRENT_MAP}
-DOUTPUT_PATH="${_MAP_OUTPUT_PATH}"
-DFINAL=${_generate_map_file_FINAL}
-DBREAK_ABI=${_generate_map_file_BREAK_ABI}
-DRELEASE_NAME_VERSION=${_generate_map_file_RELEASE_NAME_VERSION}
-P ${_GENERATE_MAP_SCRIPT}
DEPENDS ${_generate_map_file_SYMBOLS}
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)
# Copy the generated map back to the COPY_TO
add_custom_target(${_TARGET_NAME} ALL
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${_MAP_OUTPUT_PATH}
${_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()
endfunction()
endif (ABIMAP_FOUND)

View File

@@ -1,66 +1,60 @@
# - Try to find ARGP # - Try to find Argp
# Once done this will define # Once done this will define
# #
# ARGP_ROOT_DIR - Set this variable to the root installation of ARGP # ARGP_FOUND - system has Argp
# ARGP_INCLUDE_DIRS - the Argp include directory
# ARGP_LIBRARIES - Link these to use Argp
# ARGP_DEFINITIONS - Compiler switches required for using Argp
# #
# Read-Only variables: # Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.org>
# ARGP_FOUND - system has ARGP
# ARGP_INCLUDE_DIR - the ARGP include directory
# ARGP_LIBRARIES - Link these to use ARGP
# ARGP_DEFINITIONS - Compiler switches required for using ARGP
# #
#============================================================================= # Redistribution and use is allowed according to the terms of the New
# Copyright (c) 2011-2016 Andreas Schneider <asn@cryptomilk.org> # BSD license.
# # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# #
set(_ARGP_ROOT_HINTS
)
set(_ARGP_ROOT_PATHS if (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
"$ENV{PROGRAMFILES}/argp" # in cache already
) set(ARGP_FOUND TRUE)
else (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
find_path(ARGP_ROOT_DIR find_path(ARGP_INCLUDE_DIR
NAMES NAMES
include/argp.h argp.h
HINTS
${_ARGP_ROOT_HINTS}
PATHS PATHS
${_ARGP_ROOT_PATHS} /usr/include
) /usr/local/include
mark_as_advanced(ARGP_ROOT_DIR) /opt/local/include
/sw/include
find_path(ARGP_INCLUDE_DIR
NAMES
argp.h
PATHS
${ARGP_ROOT_DIR}/include
)
find_library(ARGP_LIBRARY
NAMES
argp
PATHS
${ARGP_ROOT_DIR}/lib
)
if (ARGP_LIBRARY)
set(ARGP_LIBRARIES
${ARGP_LIBRARIES}
${ARGP_LIBRARY}
) )
endif (ARGP_LIBRARY)
include(FindPackageHandleStandardArgs) find_library(ARGP_LIBRARY
find_package_handle_standard_args(ARGP DEFAULT_MSG ARGP_LIBRARIES ARGP_INCLUDE_DIR) NAMES
argp
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(ARGP_INCLUDE_DIRS
${ARGP_INCLUDE_DIR}
)
if (ARGP_LIBRARY)
set(ARGP_LIBRARIES
${ARGP_LIBRARIES}
${ARGP_LIBRARY}
)
endif (ARGP_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Argp DEFAULT_MSG ARGP_LIBRARIES ARGP_INCLUDE_DIRS)
# show the ARGP_INCLUDE_DIRS and ARGP_LIBRARIES variables only in the advanced view
mark_as_advanced(ARGP_INCLUDE_DIRS ARGP_LIBRARIES)
endif (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
# show the ARGP_INCLUDE_DIR and ARGP_LIBRARIES variables only in the advanced view
mark_as_advanced(ARGP_INCLUDE_DIR ARGP_LIBRARIES)

View File

@@ -35,8 +35,6 @@ find_path(GCRYPT_INCLUDE_DIR
gcrypt.h gcrypt.h
HINTS HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS} ${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
) )
find_library(GCRYPT_LIBRARY find_library(GCRYPT_LIBRARY
@@ -46,23 +44,13 @@ find_library(GCRYPT_LIBRARY
libgcrypt-11 libgcrypt-11
HINTS HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS} ${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
) )
find_library(GCRYPT_ERROR_LIBRARY set(GCRYPT_LIBRARIES ${GCRYPT_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]+\"")
string(REGEX REPLACE "^.*GCRYPT_VERSION.*([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1" GCRYPT_VERSION "${_gcrypt_version_str}") string(REGEX REPLACE "^.*GCRYPT_VERSION.*([0-9]+.[0-9]+.[0-9]+).*" "\\1" GCRYPT_VERSION "${_gcrypt_version_str}")
endif (GCRYPT_INCLUDE_DIR) endif (GCRYPT_INCLUDE_DIR)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)

View File

@@ -54,8 +54,7 @@ if (UNIX)
OUTPUT_VARIABLE OUTPUT_VARIABLE
_GSSAPI_VENDOR_STRING) _GSSAPI_VENDOR_STRING)
if ((_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*") OR (_GSSAPI_VENDOR_STRING if (_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*")
MATCHES ".*MITKerberosShim.*"))
set(GSSAPI_FLAVOR_MIT TRUE) set(GSSAPI_FLAVOR_MIT TRUE)
else() else()
execute_process( execute_process(

View File

@@ -1,104 +0,0 @@
# - Try to find mbedTLS
# Once done this will define
#
# MBEDTLS_FOUND - system has mbedTLS
# MBEDTLS_INCLUDE_DIRS - the mbedTLS include directory
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
# MBEDTLS_DEFINITIONS - Compiler switches required for using mbedTLS
#=============================================================================
# Copyright (c) 2017 Sartura d.o.o.
#
# Author: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
#
set(_MBEDTLS_ROOT_HINTS
$ENV{MBEDTLS_ROOT_DIR}
${MBEDTLS_ROOT_DIR})
set(_MBEDTLS_ROOT_PATHS
"$ENV{PROGRAMFILES}/libmbedtls")
set(_MBEDTLS_ROOT_HINTS_AND_PATHS
HINTS ${_MBEDTLS_ROOT_HINTS}
PATHS ${_MBEDTLS_ROOT_PATHS})
find_path(MBEDTLS_INCLUDE_DIR
NAMES
mbedtls/config.h
HINTS
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
find_library(MBEDTLS_SSL_LIBRARY
NAMES
mbedtls
HINTS
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
find_library(MBEDTLS_CRYPTO_LIBRARY
NAMES
mbedcrypto
HINTS
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
find_library(MBEDTLS_X509_LIBRARY
NAMES
mbedx509
HINTS
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
set(MBEDTLS_LIBRARIES ${MBEDTLS_SSL_LIBRARY} ${MBEDTLS_CRYPTO_LIBRARY}
${MBEDTLS_X509_LIBRARY})
if (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" _mbedtls_version_str REGEX
"^#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"[0-9]+.[0-9]+.[0-9]+\"")
string(REGEX REPLACE "^.*MBEDTLS_VERSION_STRING.*([0-9]+.[0-9]+.[0-9]+).*"
"\\1" MBEDTLS_VERSION "${_mbedtls_version_str}")
endif ()
include(FindPackageHandleStandardArgs)
if (MBEDTLS_VERSION)
find_package_handle_standard_args(MbedTLS
REQUIRED_VARS
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARIES
VERSION_VAR
MBEDTLS_VERSION
FAIL_MESSAGE
"Could NOT find mbedTLS, try to set the path to mbedTLS root folder
in the system variable MBEDTLS_ROOT_DIR"
)
else (MBEDTLS_VERSION)
find_package_handle_standard_args(MBedTLS
"Could NOT find mbedTLS, try to set the path to mbedLS root folder in
the system variable MBEDTLS_ROOT_DIR"
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARIES)
endif (MBEDTLS_VERSION)
# show the MBEDTLS_INCLUDE_DIRS and MBEDTLS_LIBRARIES variables only in the advanced view
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARIES)

View File

@@ -21,16 +21,17 @@
# #
if (WIN32) if (WIN32)
set(_x86 "(x86)") set(_NSIS_ROOT_HINTS
"[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

@@ -0,0 +1,208 @@
# - Try to find OpenSSL
# Once done this will define
#
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
#
# Read-Only variables:
# OPENSSL_FOUND - system has OpenSSL
# OPENSSL_INCLUDE_DIRS - the OpenSSL include directory
# OPENSSL_LIBRARIES - Link these to use OpenSSL
# OPENSSL_DEFINITIONS - Compiler switches required for using OpenSSL
#
#=============================================================================
# Copyright (c) 2006-2009 Kitware, Inc.
# Copyright (c) 2006 Alexander Neundorf <neundorf@kde.org>
# Copyright (c) 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com>
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
#
if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
# in cache already
set(OPENSSL_FOUND TRUE)
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
if (UNIX)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_OPENSSL openssl)
endif (PKG_CONFIG_FOUND)
endif (UNIX)
# http://www.slproweb.com/products/Win32OpenSSL.html
set(_OPENSSL_ROOT_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
)
set(_OPENSSL_ROOT_PATHS
"C:/OpenSSL/"
"C:/OpenSSL-Win32/"
"C:/OpenSSL-Win64/"
"$ENV{PROGRAMFILES}/OpenSSL"
"$ENV{PROGRAMFILES}/OpenSSL-Win32"
"$ENV{PROGRAMFILES}/OpenSSL-Win64"
)
find_path(OPENSSL_ROOT_DIR
NAMES
include/openssl/ssl.h
HINTS
${_OPENSSL_ROOT_HINTS}
PATHS
${_OPENSSL_ROOT_PATHS}
)
mark_as_advanced(OPENSSL_ROOT_DIR)
find_path(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
PATHS
/usr/local/include
/opt/local/include
/sw/include
/usr/lib/sfw/include
${OPENSSL_ROOT_DIR}/include
)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
mark_as_advanced(OPENSSL_INCLUDE_DIRS)
if (WIN32 AND NOT CYGWIN)
# MINGW should go here too
if (MSVC)
# /MD and /MDd are the standard values - if someone wants to use
# others, the libnames have to change here too
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
# TODO: handle /MT and static lib
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
# * MD for dynamic-release
# * MDd for dynamic-debug
# * MT for static-release
# * MTd for static-debug
# Implementation details:
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
# libeay32MD.lib is identical to ../libeay32.lib, and
# ssleay32MD.lib is identical to ../ssleay32.lib
find_library(LIB_EAY_DEBUG
NAMES
libeay32MDd
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib/VC
)
find_library(LIB_EAY_RELEASE
NAMES
libeay32MD
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib/VC
)
find_library(SSL_EAY_DEBUG
NAMES
ssleay32MDd
ssleay32
ssl
PATHS ${OPENSSL_ROOT_DIR}/lib/VC
)
find_library(SSL_EAY_RELEASE
NAMES
ssleay32MD
ssleay32
ssl
PATHS
${OPENSSL_ROOT_DIR}/lib/VC
)
if (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
set(OPENSSL_LIBRARIES
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
)
else (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
endif (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
mark_as_advanced(SSL_EAY_DEBUG SSL_EAY_RELEASE)
mark_as_advanced(LIB_EAY_DEBUG LIB_EAY_RELEASE)
elseif (MINGW)
# same player, for MingW
find_library(LIB_EAY
NAMES
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib/MinGW
)
find_library(SSL_EAY
NAMES
ssleay32
PATHS
${OPENSSL_ROOT_DIR}/lib/MinGW
)
mark_as_advanced(SSL_EAY LIB_EAY)
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
else(MSVC)
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
find_library(LIB_EAY
NAMES
libeay32
PATHS
${OPENSSL_ROOT_DIR}/lib
)
find_library(SSL_EAY
NAMES
ssleay32
PATHS
${OPENSSL_ROOT_DIR}/lib
)
mark_as_advanced(SSL_EAY LIB_EAY)
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
endif(MSVC)
else (WIN32 AND NOT CYGWIN)
find_library(OPENSSL_SSL_LIBRARIES
NAMES
ssl
ssleay32
ssleay32MD
PATHS
${_OPENSSL_LIBDIR}
/opt/local/lib
/sw/lib
/usr/sfw/lib/64
/usr/sfw/lib
)
find_library(OPENSSL_CRYPTO_LIBRARIES
NAMES
crypto
PATHS
${_OPENSSL_LIBDIR}
/opt/local/lib
/sw/lib
/usr/sfw/lib/64
/usr/sfw/lib
)
mark_as_advanced(OPENSSL_CRYPTO_LIBRARIES OPENSSL_SSL_LIBRARIES)
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
endif (WIN32 AND NOT CYGWIN)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenSSL DEFAULT_MSG OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIRS)
endif (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)

View File

@@ -0,0 +1,120 @@
# - Try to find ZLIB
# Once done this will define
#
# ZLIB_ROOT_DIR - Set this variable to the root installation of ZLIB
#
# Read-Only variables:
# ZLIB_FOUND - system has ZLIB
# ZLIB_INCLUDE_DIRS - the ZLIB include directory
# ZLIB_LIBRARIES - Link these to use ZLIB
#
# ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
# ZLIB_VERSION_MAJOR - The major version of zlib
# ZLIB_VERSION_MINOR - The minor version of zlib
# ZLIB_VERSION_PATCH - The patch version of zlib
# ZLIB_VERSION_TWEAK - The tweak version of zlib
#
# The following variable are provided for backward compatibility
#
# ZLIB_MAJOR_VERSION - The major version of zlib
# ZLIB_MINOR_VERSION - The minor version of zlib
# ZLIB_PATCH_VERSION - The patch version of zlib
#
#=============================================================================
# Copyright (c) 2001-2009 Kitware, Inc.
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
#
if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
# in cache already
set(ZLIB_FOUND TRUE)
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
set(_ZLIB_ROOT_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/include"
)
set(_ZLIB_ROOT_PATHS
"$ENV{PROGRAMFILES}/zlib"
)
find_path(ZLIB_ROOT_DIR
NAMES
include/zlib.h
HINTS
${_ZLIB_ROOT_HINTS}
PATHS
${_ZLIB_ROOT_PATHS}
)
mark_as_advanced(ZLIB_ROOT_DIR)
# check for header file
find_path(ZLIB_INCLUDE_DIR
NAMES
zlib.h
PATHS
/usr/local/include
/opt/local/include
/sw/include
/usr/lib/sfw/include
${ZLIB_ROOT_DIR}/include
)
mark_as_advanced(ZLIB_INCLUDE_DIR)
# check version number
if (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$")
string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}")
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}")
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}")
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}")
# only append a TWEAK version if it exists:
set(ZLIB_VERSION_TWEAK "")
if ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}")
endif ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
endif (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
find_library(ZLIB_LIBRARY
NAMES
z
zdll
zlib
zlib1
zlibd
PATHS
/usr/local/lib
/opt/local/lib
/sw/lib
/usr/sfw/lib/64
/usr/sfw/lib
${ZLIB_ROOT_DIR}/lib
)
mark_as_advanced(ZLIB_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ZLIB DEFAULT_MSG ZLIB_INCLUDE_DIR ZLIB_LIBRARY)
#find_package_handle_standard_args(ZLIB REQUIRED_VARS ZLIB_INCLUDE_DIR ZLIB_LIBRARY
# VERSION_VAR ZLIB_VERSION_STRING)
if (ZLIB_FOUND)
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
endif (ZLIB_FOUND)
endif (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)

View File

@@ -1,118 +0,0 @@
#
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
#.rst:
# GenerateMap
# -----------
#
# This is a helper script for FindABImap.cmake.
#
# Generates a symbols version script using the abimap tool.
# This script is run in build time to use the correct command depending on the
# existence of the file provided ``CURRENT_MAP``.
#
# If the file exists, the ``abimap update`` subcommand is used to update the
# existing map. Otherwise, the ``abimap new`` subcommand is used to create a new
# map file.
#
# If the file provided in ``CURRENT_MAP`` exists, it is copied to the
# ``OUTPUT_PATH`` before updating.
# This is required because ``abimap`` do not generate output if no symbols were
# changed when updating an existing file.
#
# Expected defined variables
# --------------------------
#
# ``SYMBOLS``:
# Required file containing the symbols to be used as input. Usually this is
# the ``OUTPUT`` generated by ``extract_symbols()`` function provided in
# FindABImap.cmake
#
# ``RELEASE_NAME_VERSION``:
# Required, expects the library name and version information to be added to
# the symbols in the format ``library_name_1_2_3``
#
# ``CURRENT_MAP``:
# Required, expects the path to the current map file (or the path were it
# should be)
#
# ``OUTPUT_PATH``:
# Required, expects the output file path.
#
# ``ABIMAP_EXECUTABLE``:
# Required, expects the path to the ``abimap`` tool.
#
# Optionally defined variables
# ----------------------------
#
# ``FINAL``:
# If defined, will mark the modified set of symbols in the symbol version
# script as final, preventing later changes using ``abimap``.
#
# ``BREAK_ABI``:
# If defined, the build will not fail if symbols were removed.
# If defined and a symbol is removed, a new release is created containing
# all symbols from all released versions. This makes an incompatible release.
#
if (NOT DEFINED RELEASE_NAME_VERSION)
message(SEND_ERROR "RELEASE_NAME_VERSION not defined")
endif()
if (NOT DEFINED SYMBOLS)
message(SEND_ERROR "SYMBOLS not defined")
endif()
if (NOT DEFINED CURRENT_MAP)
message(SEND_ERROR "CURRENT_MAP not defined")
endif()
if (NOT DEFINED OUTPUT_PATH)
message(SEND_ERROR "OUTPUT_PATH not defined")
endif()
if (NOT ABIMAP_EXECUTABLE)
message(SEND_ERROR "ABIMAP_EXECUTABLE not defined")
endif()
set(ARGS_LIST)
if (FINAL)
list(APPEND ARGS_LIST "--final")
endif()
if (EXISTS ${CURRENT_MAP})
if (BREAK_ABI)
list(APPEND ARGS_LIST "--allow-abi-break")
endif()
execute_process(
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${CURRENT_MAP} ${OUTPUT_PATH}
COMMAND
${ABIMAP_EXECUTABLE} update ${ARGS_LIST}
-r ${RELEASE_NAME_VERSION}
-i ${SYMBOLS}
-o ${OUTPUT_PATH}
${CURRENT_MAP}
RESULT_VARIABLE result
)
else ()
execute_process(
COMMAND
${ABIMAP_EXECUTABLE} new ${ARGS_LIST}
-r ${RELEASE_NAME_VERSION}
-i ${SYMBOLS}
-o ${OUTPUT_PATH}
RESULT_VARIABLE result
)
endif()
if (NOT "${result}" STREQUAL "0")
message(SEND_ERROR "Map generation failed")
endif()

View File

@@ -1,59 +0,0 @@
#
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
#.rst:
# GetFilesList
# ------------
#
# This is a helper script for FindABImap.cmake.
#
# Search in the provided directories for files matching the provided pattern.
# The list of files is then written to the output file.
#
# Expected defined variables
# --------------------------
#
# ``DIRECTORIES``:
# Required, expects a list of directories paths.
#
# ``FILES_PATTERNS``:
# Required, expects a list of patterns to be used to search files
#
# ``OUTPUT_PATH``:
# Required, expects the output file path.
if (NOT DEFINED DIRECTORIES)
message(SEND_ERROR "DIRECTORIES not defined")
endif()
if (NOT DEFINED FILES_PATTERNS)
message(SEND_ERROR "FILES_PATTERNS not defined")
endif()
if (NOT DEFINED OUTPUT_PATH)
message(SEND_ERROR "OUTPUT_PATH not defined")
endif()
string(REPLACE " " ";" DIRECTORIES_LIST "${DIRECTORIES}")
string(REPLACE " " ";" FILES_PATTERNS_LIST "${FILES_PATTERNS}")
# Create the list of expressions for the files
set(glob_expressions)
foreach(dir ${DIRECTORIES_LIST})
foreach(exp ${FILES_PATTERNS_LIST})
list(APPEND glob_expressions
"${dir}/${exp}"
)
endforeach()
endforeach()
# Create the list of files
file(GLOB files ${glob_expressions})
# Write to the output
file(WRITE ${OUTPUT_PATH} "${files}")

View File

@@ -0,0 +1,100 @@
# - Run Doxygen
#
# Adds a doxygen target that runs doxygen to generate the html
# and optionally the LaTeX API documentation.
# The doxygen target is added to the doc target as dependency.
# i.e.: the API documentation is built with:
# make doc
#
# USAGE: INCLUDE IN PROJECT
#
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# include(UseDoxygen)
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
#
#
# Variables you may define are:
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. Defaults to "doc".
#
# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is stored. Defaults to "latex".
#
# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is stored. Defaults to "html".
#
#
# Copyright (c) 2009-2010 Tobias Rautenkranz <tobias@rautenkranz.ch>
# Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
macro(usedoxygen_set_default name value)
if(NOT DEFINED "${name}")
set("${name}" "${value}")
endif()
endmacro()
find_package(Doxygen)
if(DOXYGEN_FOUND)
find_file(DOXYFILE_IN
NAMES
doxy.config.in
PATHS
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_ROOT}/Modules/
NO_DEFAULT_PATH)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
endif()
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
usedoxygen_set_default(DOXYFILE_HTML_DIR "html")
set_property(DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
set(DOXYFILE_LATEX FALSE)
set(DOXYFILE_PDFLATEX FALSE)
set(DOXYFILE_DOT FALSE)
#find_package(LATEX)
#if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
# set(DOXYFILE_LATEX TRUE)
# usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex")
#
# set_property(DIRECTORY APPEND PROPERTY
# ADDITIONAL_MAKE_CLEAN_FILES
# "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
#
# if(PDFLATEX_COMPILER)
# set(DOXYFILE_PDFLATEX TRUE)
# endif()
# if(DOXYGEN_DOT_EXECUTABLE)
# set(DOXYFILE_DOT TRUE)
# endif()
#
# add_custom_command(TARGET doxygen
# POST_BUILD
# COMMAND ${CMAKE_MAKE_PROGRAM}
# WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
#endif()
configure_file(${DOXYFILE_IN} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config ESCAPE_QUOTES IMMEDIATE @ONLY)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac ESCAPE_QUOTES IMMEDIATE @ONLY)
add_custom_target(doxygen-trac ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac)
endif()
get_target_property(DOC_TARGET doc TYPE)
if(NOT DOC_TARGET)
add_custom_target(doc)
endif()
add_dependencies(doc doxygen)
endif()

View File

@@ -1,23 +0,0 @@
set(CMAKE_C_FLAGS "-m32" CACHE STRING "C compiler flags" FORCE)
set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "C++ compiler flags" FORCE)
set(LIB32 /usr/lib) # Fedora
if(EXISTS /usr/lib32)
set(LIB32 /usr/lib32) # Arch, Solus
endif()
set(CMAKE_SYSTEM_LIBRARY_PATH ${LIB32} CACHE STRING "system library search path" FORCE)
set(CMAKE_LIBRARY_PATH ${LIB32} CACHE STRING "library search path" FORCE)
# this is probably unlikely to be needed, but just in case
set(CMAKE_EXE_LINKER_FLAGS "-m32 -L${LIB32}" CACHE STRING "executable linker flags" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "-m32 -L${LIB32}" CACHE STRING "shared library linker flags" FORCE)
set(CMAKE_MODULE_LINKER_FLAGS "-m32 -L${LIB32}" CACHE STRING "module linker flags" FORCE)
# on Fedora and Arch and similar, point pkgconfig at 32 bit .pc files. We have
# to include the regular system .pc files as well (at the end), because some
# are not always present in the 32 bit directory
if(EXISTS ${LIB32}/pkgconfig)
set(ENV{PKG_CONFIG_LIBDIR} ${LIB32}/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig:/usr/lib64/pkgconfig)
endiF()

View File

@@ -1,8 +1,8 @@
/* Name of package */ /* Name of package */
#cmakedefine PACKAGE "${PROJECT_NAME}" #cmakedefine PACKAGE "${APPLICATION_NAME}"
/* Version number of package */ /* Version number of package */
#cmakedefine VERSION "${PROJECT_VERSION}" #cmakedefine VERSION "${APPLICATION_VERSION}"
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}" #cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
#cmakedefine DATADIR "${DATADIR}" #cmakedefine DATADIR "${DATADIR}"
@@ -17,45 +17,18 @@
/* Define to 1 if you have the <argp.h> header file. */ /* Define to 1 if you have the <argp.h> header file. */
#cmakedefine HAVE_ARGP_H 1 #cmakedefine HAVE_ARGP_H 1
/* Define to 1 if you have the <aprpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <glob.h> header file. */
#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
/* Define to 1 if you have the <utmp.h> header file. */
#cmakedefine HAVE_UTMP_H 1
/* Define to 1 if you have the <util.h> header file. */ /* Define to 1 if you have the <util.h> header file. */
#cmakedefine HAVE_UTIL_H 1 #cmakedefine HAVE_UTIL_H 1
/* Define to 1 if you have the <libutil.h> header file. */
#cmakedefine HAVE_LIBUTIL_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/utime.h> header file. */
#cmakedefine HAVE_SYS_UTIME_H 1
/* Define to 1 if you have the <io.h> header file. */
#cmakedefine HAVE_IO_H 1
/* Define to 1 if you have the <termios.h> header file. */ /* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H 1 #cmakedefine HAVE_TERMIOS_H 1
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_UNISTD_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
/* Define to 1 if you have the <openssl/aes.h> header file. */ /* Define to 1 if you have the <openssl/aes.h> header file. */
#cmakedefine HAVE_OPENSSL_AES_H 1 #cmakedefine HAVE_OPENSSL_AES_H 1
@@ -89,35 +62,8 @@
/* Define to 1 if you have eliptic curve cryptography */ /* Define to 1 if you have eliptic curve cryptography */
#cmakedefine HAVE_ECC 1 #cmakedefine HAVE_ECC 1
/* Define to 1 if you have DSA */
#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. */
#cmakedefine HAVE_OPENSSL_EVP_AES_CTR 1
/* Define to 1 if you have the `EVP_aes128_cbc' function. */
#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. */
#cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1
/* Define to 1 if you have the `CRYPTO_ctr128_encrypt' function. */
#cmakedefine HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT 1
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
#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
@@ -142,9 +88,6 @@
/* 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
@@ -175,21 +118,6 @@
/* Define to 1 if you have the `_strtoui64' function. */ /* Define to 1 if you have the `_strtoui64' function. */
#cmakedefine HAVE__STRTOUI64 1 #cmakedefine HAVE__STRTOUI64 1
/* Define to 1 if you have the `glob' function. */
#cmakedefine HAVE_GLOB 1
/* Define to 1 if you have the `explicit_bzero' function. */
#cmakedefine HAVE_EXPLICIT_BZERO 1
/* Define to 1 if you have the `memset_s' function. */
#cmakedefine HAVE_MEMSET_S 1
/* Define to 1 if you have the `SecureZeroMemory' function. */
#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). */
@@ -198,33 +126,15 @@
/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */ /* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
#cmakedefine HAVE_LIBGCRYPT 1 #cmakedefine HAVE_LIBGCRYPT 1
/* Define to 1 if you have the 'mbedTLS' library (-lmbedtls). */
#cmakedefine HAVE_LIBMBEDCRYPTO 1
/* 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_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_COMPILER__FUNC__ 1
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
#cmakedefine HAVE_GCC_BOUNDED_ATTRIBUTE 1
/* Define to 1 if you want to enable GSSAPI */ /* Define to 1 if you want to enable GSSAPI */
#cmakedefine WITH_GSSAPI 1 #cmakedefine WITH_GSSAPI 1
@@ -235,15 +145,15 @@
/* Define to 1 if you want to enable SFTP */ /* Define to 1 if you want to enable SFTP */
#cmakedefine WITH_SFTP 1 #cmakedefine WITH_SFTP 1
/* Define to 1 if you want to enable SSH1 */
#cmakedefine WITH_SSH1 1
/* Define to 1 if you want to enable server support */ /* Define to 1 if you want to enable server support */
#cmakedefine WITH_SERVER 1 #cmakedefine WITH_SERVER 1
/* Define to 1 if you want to enable debug output for crypto functions */ /* Define to 1 if you want to enable debug output for crypto functions */
#cmakedefine DEBUG_CRYPTO 1 #cmakedefine DEBUG_CRYPTO 1
/* Define to 1 if you want to enable debug output for packet functions */
#cmakedefine DEBUG_PACKET 1
/* Define to 1 if you want to enable pcap output support (experimental) */ /* Define to 1 if you want to enable pcap output support (experimental) */
#cmakedefine WITH_PCAP 1 #cmakedefine WITH_PCAP 1

View File

@@ -1,46 +1,5 @@
# #
# Build the documentation # Build the documentation
# #
if (${CMAKE_VERSION} VERSION_GREATER "3.8.99") include(UseDoxygen OPTIONAL)
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

View File

@@ -46,7 +46,7 @@ The ssh_userauth_publickey_auto() function also tries to authenticate using the
SSH agent, if you have one running, or the "none" method otherwise. SSH agent, if you have one running, or the "none" method otherwise.
If you wish to authenticate with public key by your own, follow these steps: If you wish to authenticate with public key by your own, follow these steps:
- Retrieve the public key with ssh_pki_import_pubkey_file(). - Retrieve the public key with ssh_import_pubkey_file().
- Offer the public key to the SSH server using ssh_userauth_try_publickey(). - Offer the public key to the SSH server using ssh_userauth_try_publickey().
If the return value is SSH_AUTH_SUCCESS, the SSH server accepts to If the return value is SSH_AUTH_SUCCESS, the SSH server accepts to
authenticate using the public key and you can go to the next step. authenticate using the public key and you can go to the next step.
@@ -127,7 +127,7 @@ The keyboard-interactive method is, as its name tells, interactive. The
server will issue one or more challenges that the user has to answer, server will issue one or more challenges that the user has to answer,
until the server takes an authentication decision. until the server takes an authentication decision.
ssh_userauth_kbdint() is the the main keyboard-interactive function. ssh_userauth_kbdint() is the the main keyboard-interactive function.
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL, It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request. SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
@@ -154,9 +154,9 @@ Here are a few remarks:
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS. - Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
- The server can send an empty question set (this is the default behavior - The server can send an empty question set (this is the default behavior
on my system) after you have sent the answers to the first questions. on my system) after you have sent the answers to the first questions.
You must still parse the answer, it might contain some You must still parse the answer, it might contain some
message from the server saying hello or such things. Just call message from the server saying hello or such things. Just call
ssh_userauth_kbdint() until needed. ssh_userauth_kbdint() until needed.
- The meaning of "name", "prompt", "instruction" may be a little - The meaning of "name", "prompt", "instruction" may be a little
confusing. An explanation is given in the RFC section that follows. confusing. An explanation is given in the RFC section that follows.
@@ -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 occurred. indication that such truncation has occured.
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
@@ -285,7 +285,7 @@ int authenticate_kbdint(ssh_session session)
{ {
int rc; int rc;
rc = ssh_userauth_none(session, NULL); rc = ssh_userauth_none(session, NULL, NULL);
return rc; return rc;
} }
@endcode @endcode
@@ -304,8 +304,8 @@ int test_several_auth_methods(ssh_session session)
{ {
int method, rc; int method, rc;
rc = ssh_userauth_none(session, NULL); rc = ssh_userauth_none(session, NULL, NULL);
if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_ERROR) { if (rc != SSH_AUTH_SUCCESS) {
return rc; return rc;
} }

View File

@@ -56,7 +56,7 @@ If an error has been encountered, it returns a negative value:
@code @code
char buffer[256]; char buffer[256];
int nbytes; unsigned int nbytes;
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) while (nbytes > 0)

View File

@@ -1,6 +1,6 @@
curve25519-sha256@libssh.org.txt Aris Adamantiadis <aris@badcode.be> curve25519-sha256@libssh.org.txt Aris Adamantiadis <aris@badcode.be>
21/9/2013 21/9/2013
1. Introduction 1. Introduction
This document describes the key exchange methode curve25519-sha256@libssh.org This document describes the key exchange methode curve25519-sha256@libssh.org
@@ -22,14 +22,14 @@ claims to be able to eavesdrop. Having a secure replacement would make passive
attacks much harder if such a backdoor exists. attacks much harder if such a backdoor exists.
However an alternative exists in the form of Curve25519. This algorithm has been However an alternative exists in the form of Curve25519. This algorithm has been
proposed in 2006 by DJB [Curve25519]. Its main strengths are its speed, its proposed in 2006 by DJB [Curve25519]. Its main stengths are its speed, its
constant-time run time (and resistance against side-channel attacks), and its constant-time run time (and resistance against side-channel attacks), and its
lack of nebulous hard-coded constants. lack of nebulous hard-coded constants.
The reference version being used in this document is the one described in The reference version being used in this document is the one described in
[Curve25519] as implemented in the library NaCl [NaCl]. [Curve25519] as implemented in the library NaCl [NaCl].
This document does not attempt to provide alternatives to the ecdsa-sha1-* This document does not attempts to provide alternatives to the ecdsa-sha1-*
authentication keys. authentication keys.
2. Key exchange 2. Key exchange
@@ -99,7 +99,7 @@ It should be noted that, in opposition to NIST curves, no special validation
should be done to ensure the received public keys are valid curves point. The should be done to ensure the received public keys are valid curves point. The
Curve25519 algorithm ensure that every possible public key maps to a valid Curve25519 algorithm ensure that every possible public key maps to a valid
ECC Point. ECC Point.
4.3 Shared secret generation 4.3 Shared secret generation
The shared secret, k, is defined in SSH specifications to be a big integer. The shared secret, k, is defined in SSH specifications to be a big integer.
@@ -107,7 +107,7 @@ This number is calculated using the following procedure:
X is the 32 bytes point obtained by the scalar multiplication of the other X is the 32 bytes point obtained by the scalar multiplication of the other
side's public key and the local private key scalar. side's public key and the local private key scalar.
The whole 32 bytes of the number X are then converted into a big integer k. The whole 32 bytes of the number X are then converted into a big integer k.
This conversion follows the network byte order. This step differs from This conversion follows the network byte order. This step differs from
RFC5656. RFC5656.
@@ -115,5 +115,5 @@ This number is calculated using the following procedure:
[RFC5656] http://tools.ietf.org/html/rfc5656 [RFC5656] http://tools.ietf.org/html/rfc5656
[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929 [SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929
[DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf [DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
[Curve25519] "Curve25519: new Diffie-Hellman speed records." [Curve25519] "Curve25519: new Diffie-Hellman speed records."
http://cr.yp.to/ecdh/curve25519-20060209.pdf http://cr.yp.to/ecdh/curve25519-20060209.pdf

1917
doc/doxy.config.in Normal file

File diff suppressed because it is too large Load Diff

1546
doc/doxy.trac.in Normal file

File diff suppressed because it is too large Load Diff

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 forwarding, and reverse port forwarding is also called named local port forwardind, and reverse port forwarding is also called
remote port forwarding. SSH also allows X11 tunnels. remote port forwarding. SSH also allows X11 tunnels.
@@ -23,15 +23,15 @@ Mail client application Google Mail
5555 (arbitrary) | 5555 (arbitrary) |
| 143 (IMAP2) | 143 (IMAP2)
V | V |
SSH client =====> SSH server SSH client =====> SSH server
Legend: Legend:
--P-->: port connections through port P --P-->: port connexion 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 retrieve mail. end point). Now the local mail client can retreive 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 connections through port P --P-->: port connexion 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,
@@ -144,13 +144,13 @@ or whatever use you have for it.
@subsection libssh_reverse Doing reverse port forwarding with libssh @subsection libssh_reverse Doing reverse port forwarding with libssh
To do reverse port forwarding, call ssh_channel_listen_forward(), To do reverse port forwarding, call ssh_forward_listen(),
then ssh_channel_accept_forward(). then ssh_forward_accept().
When you call ssh_channel_listen_forward(), you can let the remote server When you call ssh_forward_listen(), you can let the remote server
chose the non-privileged port it should listen to. Otherwise, you can chose chose the non-priviledged port it should listen to. Otherwise, you can chose
your own privileged or non-privileged port. Beware that you should have your own priviledged or non-priviledged port. Beware that you should have
administrative privileges on the remote server to open a privileged port administrative priviledges on the remote server to open a priviledged 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
@@ -164,7 +164,6 @@ int web_server(ssh_session session)
ssh_channel channel; ssh_channel channel;
char buffer[256]; char buffer[256];
int nbytes, nwritten; int nbytes, nwritten;
int port = 0;
char *helloworld = "" char *helloworld = ""
"HTTP/1.1 200 OK\n" "HTTP/1.1 200 OK\n"
"Content-Type: text/html\n" "Content-Type: text/html\n"
@@ -179,7 +178,7 @@ int web_server(ssh_session session)
" </body>\n" " </body>\n"
"</html>\n"; "</html>\n";
rc = ssh_channel_listen_forward(session, NULL, 8080, NULL); rc = ssh_forward_listen(session, NULL, 8080, NULL);
if (rc != SSH_OK) if (rc != SSH_OK)
{ {
fprintf(stderr, "Error opening remote port: %s\n", fprintf(stderr, "Error opening remote port: %s\n",
@@ -187,7 +186,7 @@ int web_server(ssh_session session)
return rc; return rc;
} }
channel = ssh_channel_accept_forward(session, 60000, &port); channel = ssh_forward_accept(session, 60000);
if (channel == NULL) if (channel == NULL)
{ {
fprintf(stderr, "Error waiting for incoming connection: %s\n", fprintf(stderr, "Error waiting for incoming connection: %s\n",

View File

@@ -31,20 +31,20 @@ A SSH session goes through the following steps:
- Invoke your own subsystem. This is outside the scope of this document, - Invoke your own subsystem. This is outside the scope of this document,
but can be done. but can be done.
- When everything is finished, just close the channels, and then the connection. - When everything is finished, just close the channels, and then the connection.
The sftp and scp subsystems use channels, but libssh hides them to The sftp and scp subsystems use channels, but libssh hides them to
the programmer. If you want to use those subsystems, instead of a channel, the programmer. If you want to use those subsystems, instead of a channel,
you'll usually open a "sftp session" or a "scp session". you'll usually open a "sftp session" or a "scp session".
@subsection setup Creating the session and setting options @subsection setup Creating the session and setting options
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 succeeded. always verify that the allocation successed.
@code @code
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <stdlib.h> #include <stdlib.h>
int main() int main()
@@ -69,12 +69,12 @@ The ssh_options_set() function sets the options of the session. The most importa
The complete list of options can be found in the documentation of ssh_options_set(). The complete list of options can be found in the documentation of ssh_options_set().
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER, The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
the local username of your account will be used. the local username of your account will be used.
Here is a small example of how to use it: Here is a small example of how to use it:
@code @code
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <stdlib.h> #include <stdlib.h>
int main() int main()
@@ -122,7 +122,7 @@ Here's an example:
@code @code
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
int main() int main()
{ {
@@ -158,7 +158,7 @@ you just connected to is known and safe to use (remember, SSH is about security
authentication). authentication).
There are two ways of doing this: There are two ways of doing this:
- The first way (recommended) is to use the ssh_session_is_known_server() - The first way (recommended) is to use the ssh_is_server_known()
function. This function will look into the known host file function. This function will look into the known host file
(~/.ssh/known_hosts on UNIX), look for the server hostname's pattern, (~/.ssh/known_hosts on UNIX), look for the server hostname's pattern,
and determine whether this host is present or not in the list. and determine whether this host is present or not in the list.
@@ -185,89 +185,74 @@ examples/ directory:
int verify_knownhost(ssh_session session) int verify_knownhost(ssh_session session)
{ {
enum ssh_known_hosts_e state; int state, hlen;
unsigned char *hash = NULL; unsigned char *hash = NULL;
ssh_key srv_pubkey = NULL; char *hexa;
size_t hlen; char buf[10];
char buf[10];
char *hexa;
char *p;
int cmp;
int rc;
rc = ssh_get_server_publickey(session, &srv_pubkey); state = ssh_is_server_known(session);
if (rc < 0) {
hlen = ssh_get_pubkey_hash(session, &hash);
if (hlen < 0)
return -1;
switch (state)
{
case SSH_SERVER_KNOWN_OK:
break; /* ok */
case SSH_SERVER_KNOWN_CHANGED:
fprintf(stderr, "Host key for server changed: it is now:\n");
ssh_print_hexa("Public key hash", hash, hlen);
fprintf(stderr, "For security reasons, connection will be stopped\n");
free(hash);
return -1;
case SSH_SERVER_FOUND_OTHER:
fprintf(stderr, "The host key for this server was not found but an other"
"type of key exists.\n");
fprintf(stderr, "An attacker might change the default server key to"
"confuse your client into thinking the key does not exist\n");
free(hash);
return -1;
case SSH_SERVER_FILE_NOT_FOUND:
fprintf(stderr, "Could not find known host file.\n");
fprintf(stderr, "If you accept the host key here, the file will be"
"automatically created.\n");
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
case SSH_SERVER_NOT_KNOWN:
hexa = ssh_get_hexa(hash, hlen);
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
fprintf(stderr, "Public key hash: %s\n", hexa);
free(hexa);
if (fgets(buf, sizeof(buf), stdin) == NULL)
{
free(hash);
return -1; return -1;
} }
if (strncasecmp(buf, "yes", 3) != 0)
rc = ssh_get_publickey_hash(srv_pubkey, {
SSH_PUBLICKEY_HASH_SHA1, free(hash);
&hash,
&hlen);
ssh_key_free(srv_pubkey);
if (rc < 0) {
return -1; return -1;
} }
if (ssh_write_knownhost(session) < 0)
{
fprintf(stderr, "Error %s\n", strerror(errno));
free(hash);
return -1;
}
break;
state = ssh_session_is_known_server(session); case SSH_SERVER_ERROR:
switch (state) { fprintf(stderr, "Error %s", ssh_get_error(session));
case SSH_KNOWN_HOSTS_OK: free(hash);
/* OK */ return -1;
}
break; free(hash);
case SSH_KNOWN_HOSTS_CHANGED: return 0;
fprintf(stderr, "Host key for server changed: it is now:\n");
ssh_print_hexa("Public key hash", hash, hlen);
fprintf(stderr, "For security reasons, connection will be stopped\n");
ssh_clean_pubkey_hash(&hash);
return -1;
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, "An attacker might change the default server key to"
"confuse your client into thinking the key does not exist\n");
ssh_clean_pubkey_hash(&hash);
return -1;
case SSH_KNOWN_HOSTS_NOT_FOUND:
fprintf(stderr, "Could not find known host file.\n");
fprintf(stderr, "If you accept the host key here, the file will be"
"automatically created.\n");
/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
case SSH_KNOWN_HOSTS_UNKNOWN:
hexa = ssh_get_hexa(hash, hlen);
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
fprintf(stderr, "Public key hash: %s\n", hexa);
ssh_string_free_char(hexa);
ssh_clean_pubkey_hash(&hash);
p = fgets(buf, sizeof(buf), stdin);
if (p == NULL) {
return -1;
}
cmp = strncasecmp(buf, "yes", 3);
if (cmp != 0) {
return -1;
}
rc = ssh_session_update_known_hosts(session);
if (rc < 0) {
fprintf(stderr, "Error %s\n", strerror(errno));
return -1;
}
break;
case SSH_KNOWN_HOSTS_ERROR:
fprintf(stderr, "Error %s", ssh_get_error(session));
ssh_clean_pubkey_hash(&hash);
return -1;
}
ssh_clean_pubkey_hash(&hash);
return 0;
} }
@endcode @endcode
@@ -275,19 +260,18 @@ int verify_knownhost(ssh_session session)
@see ssh_disconnect @see ssh_disconnect
@see ssh_get_error @see ssh_get_error
@see ssh_get_error_code @see ssh_get_error_code
@see ssh_get_server_publickey @see ssh_get_pubkey_hash
@see ssh_get_publickey_hash @see ssh_is_server_known
@see ssh_session_is_known_server @see ssh_write_knownhost
@see ssh_session_update_known_hosts
@subsection auth Authenticating the user @subsection auth Authenticating the user
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 resources. In SSH, the two concepts the authenticated user the access to ressources. 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 resources such as port forwarding, shell, sftp subsystem, and so on. several ressources 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
@@ -313,7 +297,7 @@ The example below shows an authentication with password:
@code @code
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
int main() int main()
{ {
@@ -338,7 +322,7 @@ int main()
} }
// Verify the server's identity // Verify the server's identity
// For the source code of verify_knownhost(), check previous example // For the source code of verify_knowhost(), 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);
@@ -383,7 +367,7 @@ int show_remote_processes(ssh_session session)
ssh_channel channel; ssh_channel channel;
int rc; int rc;
char buffer[256]; char buffer[256];
int nbytes; unsigned int nbytes;
channel = ssh_channel_new(session); channel = ssh_channel_new(session);
if (channel == NULL) if (channel == NULL)
@@ -407,7 +391,7 @@ int show_remote_processes(ssh_session session)
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) while (nbytes > 0)
{ {
if (write(1, buffer, nbytes) != (unsigned int) nbytes) if (write(1, buffer, nbytes) != nbytes)
{ {
ssh_channel_close(channel); ssh_channel_close(channel);
ssh_channel_free(channel); ssh_channel_free(channel);
@@ -415,7 +399,7 @@ int show_remote_processes(ssh_session session)
} }
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
} }
if (nbytes < 0) if (nbytes < 0)
{ {
ssh_channel_close(channel); ssh_channel_close(channel);
@@ -456,13 +440,14 @@ 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
(generally the ssh_request_xxx ones) may fail because of server denying request. (generaly 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. ssh_get_error() and ssh_get_error_code() take a ssh_session as a parameter.
As long as your ssh_session object is not NULL, you can retrieve the last error That's for thread safety, error messages that can be attached to a session
message and error code from the ssh_session using ssh_get_error() and aren't static anymore. Any error that happens during ssh_options_xxx()
ssh_get_error_code() respectively. or ssh_connect() (i.e., outside of any session) can be retrieved by
giving NULL as argument.
The SFTP subsystem has its own error codes, in addition to libssh ones. The SFTP subsystem has its own error codes, in addition to libssh ones.

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 completely different and independent project. "libssh2", which is a completly different and independant 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 connections (how to write a SSH server), To learn how to accept incoming SSH connexions (how to write a SSH server),
you'll have to jump to the end of this document. 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

@@ -19,16 +19,16 @@ 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>ecdh-sha2-nistp256</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <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>Hostkey Types</strong>: <i>ecdsa-sha2-nistp256</i>, ssh-dss, ssh-rsa
- <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, des-cbc-ssh1, 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, none
- <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i> - <strong>Authentication</strong>: none, password, public-key, hostbased, 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>
- <strong>Subsystems</strong>: sftp(version 3), <i>OpenSSH Extensions</i> - <strong>Subsystems</strong>: sftp(version 3), publickey(version 2), <i>OpenSSH Extensions</i>
- <strong>SFTP</strong>: <i>statvfs@openssh.com, fstatvfs@openssh.com</i> - <strong>SFTP</strong>: <i>statvfs@openssh.com, fstatvfs@openssh.com</i>
- <strong>Thread-safe</strong>: Just don't share sessions - <strong>Thread-safe</strong>: Just don't share sessions
- <strong>Non-blocking</strong>: it can be used both blocking and non-blocking - <strong>Non-blocking</strong>: it can be used both blocking and non-blocking
@@ -184,8 +184,6 @@ It was later modified and expanded by the following RFCs.
Authentication and Key Exchange for the Secure Shell (SSH) Protocol Authentication and Key Exchange for the Secure Shell (SSH) Protocol
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>, - <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
The Secure Shell (SSH) Public Key File Format The Secure Shell (SSH) Public Key File Format
- <a href="http://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>, - <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
@@ -205,12 +203,6 @@ do the same in libssh.
@subsection main-rfc-extensions Secure Shell Extensions @subsection main-rfc-extensions Secure Shell Extensions
The libssh project has an extension to support Curve25519 which is also supported by
the OpenSSH project.
- <a href="http://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt" target="_blank">curve25519-sha256@libssh.org</a>,
Curve25519-SHA256 for ECDH KEX
The OpenSSH project has defined some extensions to the protocol. We support some of The OpenSSH project has defined some extensions to the protocol. We support some of
them like the statvfs calls in SFTP or the ssh-agent. them like the statvfs calls in SFTP or the ssh-agent.

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 functionality than the SFTP subsystem. The SCP subsystem has far less functionnality than the SFTP subsystem.
However, if you only need to copy files from and to the remote system, However, if you only need to copy files from and to the remote system,
it does its job. it does its job.
@@ -158,7 +158,7 @@ Let's say you want to copy the following tree of files to the remote site:
+-- file1 +-- file1
+-- B --+ +-- B --+
| +-- file2 | +-- file2
-- A --+ -- A --+
| +-- file3 | +-- file3
+-- C --+ +-- C --+
+-- file4 +-- file4
@@ -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, permissions 0%o\n", printf("Receiving file %s, size %d, permisssions 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() takes the "SFTP session" we just created as The function sftp_mkdir() tahes the "SFTP session" we juste created as
its first argument. It also needs the name of the file to create, and the 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
@@ -253,7 +253,7 @@ int sftp_read_sync(ssh_session session, sftp_session sftp)
return SSH_ERROR; return SSH_ERROR;
} }
nwritten = write(fd, buffer, nbytes); nwritten = write(fd, buf, nbytes);
if (nwritten != nbytes) { if (nwritten != nbytes) {
fprintf(stderr, "Error writing: %s\n", fprintf(stderr, "Error writing: %s\n",
strerror(errno)); strerror(errno));
@@ -282,7 +282,7 @@ sftp_async_read() waits for the data to come. To open a file in nonblocking mode
call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode. call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode.
The example below reads a very big file in asynchronous, nonblocking, mode. Each The example below reads a very big file in asynchronous, nonblocking, mode. Each
time the data is not ready yet, a counter is incremented. time the data are not ready yet, a counter is incrementer.
@code @code
// Good chunk size // Good chunk size
@@ -358,19 +358,19 @@ int sftp_read_async(ssh_session session, sftp_session sftp)
@subsection sftp_ls Listing the contents of a directory @subsection sftp_ls Listing the contents of a directory
The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(), The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(),
and sftp_closedir() enable to list the contents of a directory. and sftp_closedir() enable to list the contents of a directory.
They use a new handle_type, "sftp_dir", which gives access to the 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 information about a directory entry: to a structure with informations 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 occurred - when an error occured
To tell the difference, call sftp_dir_eof(). To tell the difference, call sftp_dir_eof().

View File

@@ -209,7 +209,7 @@ int interactive_shell_session(ssh_channel channel)
Of course, this is a poor terminal emulator, since the echo from the keys Of course, this is a poor terminal emulator, since the echo from the keys
pressed should not be done locally, but should be done by the remote side. pressed should not be done locally, but should be done by the remote side.
Also, user's input should not be sent once "Enter" key is pressed, but Also, user's input should not be sent once "Enter" key is pressed, but
immediately after each key is pressed. This can be accomplished immediately after each key is pressed. This can be accomplished
by setting the local terminal to "raw" mode with the cfmakeraw(3) function. by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
cfmakeraw() is a standard function under Linux, on other systems you can cfmakeraw() is a standard function under Linux, on other systems you can
@@ -245,13 +245,13 @@ 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, outgoing data to block, or an exception to incoming data to be read, outcoming data to block, or an exception to
occur. Both these functions do a "passive wait", i.e. you can safely use 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
functions in your application's main loop. functions in your application's main loop.
The difference between ssh_select() and ssh_channel_select() is that The difference between ssh_select() and ssh_channel_select() is that
ssh_channel_select() is simpler, but allows you only to watch SSH channels. ssh_channel_select() is simpler, but allows you only to watch SSH channels.
ssh_select() is more complete and enables watching regular file descriptors ssh_select() is more complete and enables watching regular file descriptors
as well, in the same function call. as well, in the same function call.

View File

@@ -1,21 +0,0 @@
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.

View File

@@ -1,22 +0,0 @@
# 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

@@ -1,56 +0,0 @@
<!-- 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

@@ -1,97 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,77 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,83 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,73 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,73 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,73 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,73 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,120 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

View File

@@ -1,32 +0,0 @@
// 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,50 +3,63 @@
@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 :
- Your system must support libpthread or, in Windows environment, - Threading must be initialized during the initialization of libssh. This
CriticalSection based mutex control. initialization must be done outside of any threading context.
- Since version 0.8.0, threads initialization is called automatically in the - If pthreads is being used by your application (or your framework's backend),
library constructor if libssh is dynamically linked. This means it is no you must link with libssh_threads dynamic library and initialize
longer necessary to call ssh_init()/ssh_finalize(). threading with the ssh_threads_pthreads threading object.
- If libssh is statically linked, threading must be initialized by calling - If an other threading library is being used by your application, you must
ssh_init() before using any of libssh provided functions. This initialization implement all the methods of the ssh_threads_callbacks_struct structure
must be done outside of any threading context. Don't forget to call and initialize libssh with it.
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
time. This will most likely lead to internal state corruption. This limitation is time. This will most likely lead to internal state corruption. This limitation is
being worked out and will maybe disappear later. being worked out and will maybe disappear later.
@subsection threads_init Initialization of threads @subsection threads_init Initialization of threads
Since version 0.8.0, it is no longer necessary to call ssh_init()/ssh_finalize() To initialize threading, you must first select the threading model you want to
if libssh is dynamically linked. use, using ssh_threads_set_callbacks(), then call ssh_init().
If libssh is statically linked, call ssh_init() before using any of libssh @code
provided functions. #include <libssh/callbacks.h>
...
ssh_threads_set_callbacks(ssh_threads_get_noop());
ssh_init();
@endcode
ssh_threads_noop is the threading structure that does nothing. It's the
threading callbacks being used by default when you're not using threading.
@subsection threads_pthread Using libpthread with libssh @subsection threads_pthread Using libpthread with libssh
Since version 0.8.0, libpthread is the default threads library used by libssh. If your application is using libpthread, you may simply use the libpthread
threading backend:
To use libpthread, simply link it to you application. @code
#include <libssh/callbacks.h>
...
ssh_threads_set_callbacks(ssh_threads_get_pthread());
ssh_init();
@endcode
However, you must be sure to link with the library ssh_threads. If
you're using gcc, you must use the commandline
@code
gcc -o output input.c -lssh -lssh_threads
@endcode
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
Since version 0.8.0, libssh does not support custom threading libraries. You must find your way in the ssh_threads_callbacks_struct structure. You must
The change makes sense since the newer versions for libcrypto (OpenSSL) and implement the following methods :
libgcrypt don't support custom threading libraries. - mutex_lock
- mutex_unlock
The default used threading library is libpthread. - mutex_init
Alternatively, in Windows environment, CriticalSection based mutex control can - mutex_destroy
be used. - thread_id
If your system does not support libpthread nor CriticalSection based mutex
control, unfortunately, you cannot use libssh in multithreaded scenarios.
Good luck ! Good luck !
*/ */

View File

@@ -11,63 +11,57 @@ include_directories(
${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}
) )
if (ARGP_INCLUDE_DIR) if (BSD OR SOLARIS OR OSX)
include_directories(${ARGP_INCLUDE_DIR}) find_package(Argp)
endif() endif (BSD OR SOLARIS OR OSX)
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_SERVER)
if (HAVE_LIBUTIL)
add_executable(samplesshd-tty samplesshd-tty.c)
target_link_libraries(samplesshd-tty ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util)
endif (HAVE_LIBUTIL)
endif (WITH_SERVER)
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(samplessh sample.c ${examples_SRCS})
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY})
if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H)) if (WITH_SERVER)
if (HAVE_LIBUTIL) add_executable(samplesshd samplesshd.c)
add_executable(ssh_server_fork ssh_server_fork.c) target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES})
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util)
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_LIBRARIES})
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_LIBRARIES})
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_LIBRARIES})
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
endif() endif (WITH_SERVER)
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,8 +24,7 @@ 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);
@@ -100,80 +99,78 @@ 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 rc; int method;
int method; char password[128] = {0};
char password[128] = {0}; char *banner;
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_auth_list(session);
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_autopubkey(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
// Try to authenticate with keyboard interactive";
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
rc = authenticate_kbdint(session, NULL);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
return SSH_AUTH_ERROR;
}
// Try to authenticate with password
if (method & SSH_AUTH_METHOD_PASSWORD) {
rc = ssh_userauth_password(session, NULL, password);
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
break;
}
}
memset(password, 0, sizeof(password));
}
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n",banner);
ssh_string_free_char(banner);
}
return rc;
} }

View File

@@ -14,10 +14,6 @@ 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

@@ -17,14 +17,11 @@ The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react. clients must be made or how a client should react.
*/ */
#include "config.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "libssh/priv.h"
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include "examples_common.h" #include "examples_common.h"
@@ -32,86 +29,82 @@ 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; int 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); state=ssh_is_server_known(session);
if (rc < 0) {
return -1;
}
rc = ssh_get_publickey_hash(srv_pubkey, rc = ssh_get_publickey(session, &srv_pubkey);
SSH_PUBLICKEY_HASH_SHA256, if (rc < 0) {
&hash, return -1;
&hlen); }
ssh_key_free(srv_pubkey);
if (rc < 0) {
return -1;
}
state = ssh_session_is_known_server(session); rc = ssh_get_publickey_hash(srv_pubkey,
SSH_PUBLICKEY_HASH_SHA1,
&hash,
&hlen);
ssh_key_free(srv_pubkey);
if (rc < 0) {
return -1;
}
switch(state) { switch(state){
case SSH_KNOWN_HOSTS_CHANGED: case SSH_SERVER_KNOWN_OK:
fprintf(stderr,"Host key for server changed : server's one is now :\n"); break; /* ok */
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen); case SSH_SERVER_KNOWN_CHANGED:
ssh_clean_pubkey_hash(&hash); fprintf(stderr,"Host key for server changed : server's one is now :\n");
fprintf(stderr,"For security reason, connection will be stopped\n"); ssh_print_hexa("Public key hash",hash, hlen);
return -1; ssh_clean_pubkey_hash(&hash);
case SSH_KNOWN_HOSTS_OTHER: fprintf(stderr,"For security reason, connection will be stopped\n");
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n"); return -1;
fprintf(stderr,"An attacker might change the default server key to confuse your client" case SSH_SERVER_FOUND_OTHER:
"into thinking the key does not exist\n" fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
"We advise you to rerun the client with -d or -r for more safety.\n"); fprintf(stderr,"An attacker might change the default server key to confuse your client"
return -1; "into thinking the key does not exist\n"
case SSH_KNOWN_HOSTS_NOT_FOUND: "We advise you to rerun the client with -d or -r for more safety.\n");
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n"); return -1;
fprintf(stderr,"the file will be automatically created.\n"); case SSH_SERVER_FILE_NOT_FOUND:
/* fallback to SSH_SERVER_NOT_KNOWN behavior */ fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
FALL_THROUGH; fprintf(stderr,"the file will be automatically created.\n");
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
case SSH_SERVER_NOT_KNOWN: case SSH_SERVER_NOT_KNOWN:
fprintf(stderr, hexa = ssh_get_hexa(hash, hlen);
"The server is unknown. Do you trust the host key (yes/no)?\n"); fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen); fprintf(stderr, "Public key hash: %s\n", hexa);
ssh_string_free_char(hexa);
if (fgets(buf, sizeof(buf), stdin) == NULL) { if (fgets(buf, sizeof(buf), stdin) == NULL) {
ssh_clean_pubkey_hash(&hash); 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:
ssh_clean_pubkey_hash(&hash);
fprintf(stderr,"%s",ssh_get_error(session));
return -1; return -1;
case SSH_KNOWN_HOSTS_OK: }
break; /* ok */ 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;
}
}
ssh_clean_pubkey_hash(&hash); break;
case SSH_SERVER_ERROR:
return 0; ssh_clean_pubkey_hash(&hash);
fprintf(stderr,"%s",ssh_get_error(session));
return -1;
}
ssh_clean_pubkey_hash(&hash);
return 0;
} }

View File

@@ -25,230 +25,148 @@ 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){
while((i = getopt(argc, argv, "v")) != -1) { switch(i){
switch(i) { case 'v':
case 'v': verbosity++;
verbosity++; break;
break; default:
default: fprintf(stderr,"unknown option %c\n",optopt);
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;
} }
}
sources = malloc((nsources + 1) * sizeof(char *)); nsources=argc-optind-1;
if (sources == NULL) { if(nsources < 1){
return -1; usage(argv[0]);
}
for(i = 0; i < nsources; ++i) {
sources[i] = argv[optind];
optind++;
}
sources[i] = NULL;
destination = argv[optind];
return 0;
}
static void location_free(struct location *loc)
{
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);
}
}
static struct location *parse_location(char *loc) {
struct location *location;
char *ptr;
location = malloc(sizeof(struct location));
if (location == NULL) {
return NULL;
}
memset(location, 0, sizeof(struct location));
location->host = location->user = NULL;
ptr = strchr(loc, ':');
if (ptr != NULL) {
location->is_ssh = 1;
location->path = strdup(ptr+1);
*ptr = '\0';
ptr = strchr(loc, '@');
if (ptr != NULL) {
location->host = strdup(ptr+1);
*ptr = '\0';
location->user = strdup(loc);
} else {
location->host = strdup(loc);
}
} else {
location->is_ssh = 0;
location->path = strdup(loc);
}
return location;
}
static void close_location(struct location *loc) {
int rc;
if (loc) {
if (loc->is_ssh) {
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;
}
}
}
}
static int open_location(struct location *loc, int flag) {
if (loc->is_ssh && flag == WRITE) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
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;
}
return -1; return -1;
}
sources=malloc((nsources + 1) * sizeof(char *));
if(sources == NULL)
return -1;
for(i=0;i<nsources;++i){
sources[i] = argv[optind];
optind++;
}
sources[i]=NULL;
destination=argv[optind];
return 0;
}
static struct location *parse_location(char *loc){
struct location *location;
char *ptr;
location = malloc(sizeof(struct location));
if (location == NULL) {
return NULL;
}
memset(location, 0, sizeof(struct location));
location->host=location->user=NULL;
ptr=strchr(loc,':');
if(ptr != NULL){
location->is_ssh=1;
location->path=strdup(ptr+1);
*ptr='\0';
ptr=strchr(loc,'@');
if(ptr != NULL){
location->host=strdup(ptr+1);
*ptr='\0';
location->user=strdup(loc);
} else {
location->host=strdup(loc);
}
} else {
location->is_ssh=0;
location->path=strdup(loc);
}
return location;
}
static int open_location(struct location *loc, int flag){
if(loc->is_ssh && flag==WRITE){
loc->session=connect_ssh(loc->host,loc->user,verbosity);
if(!loc->session){
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
return -1;
}
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path);
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
return -1;
}
if(ssh_scp_init(loc->scp)==SSH_ERROR){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
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
@@ -256,197 +174,154 @@ 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, fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno));
"Invalid file pointer, error: %s\n", return -1;
strerror(errno));
return -1;
}
r = fstat(fd, &s);
if (r < 0) {
return -1;
}
size = s.st_size;
mode = s.st_mode & ~S_IFMT;
filename = ssh_basename(src->path);
} else {
size = 0;
do {
r = ssh_scp_pull_request(src->scp);
if (r == SSH_SCP_REQUEST_NEWDIR) {
ssh_scp_deny_request(src->scp, "Not in recursive mode");
continue;
}
if (r == SSH_SCP_REQUEST_NEWFILE) {
size = ssh_scp_request_get_size(src->scp);
filename = strdup(ssh_scp_request_get_filename(src->scp));
mode = ssh_scp_request_get_permissions(src->scp);
//ssh_scp_accept_request(src->scp);
break;
}
if (r == SSH_ERROR) {
fprintf(stderr,
"Error: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
} while(r != SSH_SCP_REQUEST_NEWFILE);
} }
r = fstat(fd, &s);
if (dest->is_ssh) { if (r < 0) {
r = ssh_scp_push_file(dest->scp, src->path, size, mode); return -1;
// snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path);
if (r == SSH_ERROR) {
fprintf(stderr,
"error: %s\n",
ssh_get_error(dest->session));
ssh_string_free_char(filename);
ssh_scp_free(dest->scp);
dest->scp = NULL;
return -1;
}
} else {
if (!dest->file) {
dest->file = fopen(filename, "w");
if (!dest->file) {
fprintf(stderr,
"Cannot open %s for writing: %s\n",
filename, strerror(errno));
if (src->is_ssh) {
ssh_scp_deny_request(src->scp, "Cannot open local file");
}
ssh_string_free_char(filename);
return -1;
}
}
if (src->is_ssh) {
ssh_scp_accept_request(src->scp);
}
} }
size=s.st_size;
mode = s.st_mode & ~S_IFMT;
filename=ssh_basename(src->path);
} else {
size=0;
do { do {
if (src->is_ssh) { r=ssh_scp_pull_request(src->scp);
r = ssh_scp_read(src->scp, buffer, sizeof(buffer)); if(r==SSH_SCP_REQUEST_NEWDIR){
if (r == SSH_ERROR) { ssh_scp_deny_request(src->scp,"Not in recursive mode");
fprintf(stderr, continue;
"Error reading scp: %s\n", }
ssh_get_error(src->session)); if(r==SSH_SCP_REQUEST_NEWFILE){
size=ssh_scp_request_get_size(src->scp);
filename=strdup(ssh_scp_request_get_filename(src->scp));
mode=ssh_scp_request_get_permissions(src->scp);
//ssh_scp_accept_request(src->scp);
break;
}
if(r==SSH_ERROR){
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
ssh_string_free_char(filename); ssh_string_free_char(filename);
return -1; return -1;
} }
} while(r != SSH_SCP_REQUEST_NEWFILE);
}
if (r == 0) { if(dest->is_ssh){
break; r=ssh_scp_push_file(dest->scp,src->path, size, mode);
} // snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
} else { if(r==SSH_ERROR){
r = fread(buffer, 1, sizeof(buffer), src->file); fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
if (r == 0) { ssh_string_free_char(filename);
break; ssh_scp_free(dest->scp);
} return -1;
}
} else {
if(!dest->file){
dest->file=fopen(filename,"w");
if(!dest->file){
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
if(src->is_ssh)
ssh_scp_deny_request(src->scp,"Cannot open local file");
ssh_string_free_char(filename);
return -1;
}
}
if(src->is_ssh){
ssh_scp_accept_request(src->scp);
}
}
do {
if(src->is_ssh){
r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
if(r==SSH_ERROR){
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
if(r==0)
break;
} else {
r=fread(buffer,1,sizeof(buffer),src->file);
if(r==0)
break;
if(r<0){
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if(dest->is_ssh){
w=ssh_scp_write(dest->scp,buffer,r);
if(w == SSH_ERROR){
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp=NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w=fwrite(buffer,r,1,dest->file);
if(w<=0){
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total+=r;
if (r < 0) { } while(total < size);
fprintf(stderr, ssh_string_free_char(filename);
"Error reading file: %s\n", printf("wrote %d bytes\n",total);
strerror(errno)); return 0;
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)
r = EXIT_FAILURE; return EXIT_FAILURE;
goto end; dest=parse_location(destination);
if(open_location(dest,WRITE)<0)
return EXIT_FAILURE;
for(i=0;i<nsources;++i){
src=parse_location(sources[i]);
if(open_location(src,READ)<0){
return EXIT_FAILURE;
} }
if(do_copy(src,dest,0) < 0){
dest = parse_location(destination); break;
if (dest == NULL) {
r = EXIT_FAILURE;
goto end;
} }
}
if (open_location(dest, WRITE) < 0) { if (dest->is_ssh && dest->scp != NULL) {
location_free(dest); r=ssh_scp_close(dest->scp);
r = EXIT_FAILURE; if(r == SSH_ERROR){
goto end; fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
} ssh_scp_free(dest->scp);
dest->scp=NULL;
for (i = 0; i < nsources; ++i) { return -1;
src = parse_location(sources[i]); }
if (src == NULL) { } else {
r = EXIT_FAILURE; fclose(dest->file);
goto close_dest; dest->file=NULL;
} }
ssh_disconnect(dest->session);
if (open_location(src, READ) < 0) { ssh_finalize();
location_free(src); return 0;
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;
} }

514
examples/sample.c Normal file
View File

@@ -0,0 +1,514 @@
/* client.c */
/*
Copyright 2003-2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <libssh/callbacks.h>
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#include "examples_common.h"
#define MAXCMD 10
static char *host;
static char *user;
static char *cmds[MAXCMD];
static struct termios terminal;
static char *pcap_file=NULL;
static char *proxycommand;
static int auth_callback(const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata) {
(void) verify;
(void) userdata;
return ssh_getpass(prompt, buf, len, echo, verify);
}
struct ssh_callbacks_struct cb = {
.auth_function=auth_callback,
.userdata=NULL
};
static void add_cmd(char *cmd){
int n;
for (n = 0; (n < MAXCMD) && cmds[n] != NULL; n++);
if (n == MAXCMD) {
return;
}
cmds[n]=strdup(cmd);
}
static void usage(){
fprintf(stderr,"Usage : ssh [options] [login@]hostname\n"
"sample client - libssh-%s\n"
"Options :\n"
" -l user : log in as user\n"
" -p port : connect to port\n"
" -d : use DSS to verify host public key\n"
" -r : use RSA to verify host public key\n"
#ifdef WITH_PCAP
" -P file : create a pcap debugging file\n"
#endif
#ifndef _WIN32
" -T proxycommand : command to execute as a socket proxy\n"
#endif
,
ssh_version(0));
exit(0);
}
static int opts(int argc, char **argv){
int i;
// for(i=0;i<argc;i++)
// printf("%d : %s\n",i,argv[i]);
/* insert your own arguments here */
while((i=getopt(argc,argv,"T:P:"))!=-1){
switch(i){
case 'P':
pcap_file=optarg;
break;
#ifndef _WIN32
case 'T':
proxycommand=optarg;
break;
#endif
default:
fprintf(stderr,"unknown option %c\n",optopt);
usage();
}
}
if(optind < argc)
host=argv[optind++];
while(optind < argc)
add_cmd(argv[optind++]);
if(host==NULL)
usage();
return 0;
}
#ifndef HAVE_CFMAKERAW
static void cfmakeraw(struct termios *termios_p){
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag &= ~(CSIZE|PARENB);
termios_p->c_cflag |= CS8;
}
#endif
static void do_cleanup(int i) {
/* unused variable */
(void) i;
tcsetattr(0,TCSANOW,&terminal);
}
static void do_exit(int i) {
/* unused variable */
(void) i;
do_cleanup(0);
exit(0);
}
ssh_channel chan;
int signal_delayed=0;
static void sigwindowchanged(int i){
(void) i;
signal_delayed=1;
}
static void setsignal(void){
signal(SIGWINCH, sigwindowchanged);
signal_delayed=0;
}
static void sizechanged(void){
struct winsize win = { 0, 0, 0, 0 };
ioctl(1, TIOCGWINSZ, &win);
ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row);
// printf("Changed pty size\n");
setsignal();
}
/* There are two flavors of select loop: the one based on
* ssh_select and the one based on channel_select.
* The ssh_select one permits you to give your own file descriptors to
* follow. It is thus a complete select loop.
* The second one only selects on channels. It is simplier to use
* but doesn't permit you to fill in your own file descriptor. It is
* more adapted if you can't use ssh_select as a main loop (because
* you already have another main loop system).
*/
#ifdef USE_CHANNEL_SELECT
/* channel_select base main loop, with a standard select(2)
*/
static void select_loop(ssh_session session,ssh_channel channel){
fd_set fds;
struct timeval timeout;
char buffer[4096];
ssh_buffer readbuf=ssh_buffer_new();
ssh_channel channels[2];
int lus;
int eof=0;
int maxfd;
int ret;
while(channel){
/* when a signal is caught, ssh_select will return
* with SSH_EINTR, which means it should be started
* again. It lets you handle the signal the faster you
* can, like in this window changed example. Of course, if
* your signal handler doesn't call libssh at all, you're
* free to handle signals directly in sighandler.
*/
do{
FD_ZERO(&fds);
if(!eof)
FD_SET(0,&fds);
timeout.tv_sec=30;
timeout.tv_usec=0;
FD_SET(ssh_get_fd(session),&fds);
maxfd=ssh_get_fd(session)+1;
ret=select(maxfd,&fds,NULL,NULL,&timeout);
if(ret==EINTR)
continue;
if(FD_ISSET(0,&fds)){
lus=read(0,buffer,sizeof(buffer));
if(lus)
ssh_channel_write(channel,buffer,lus);
else {
eof=1;
ssh_channel_send_eof(channel);
}
}
if(FD_ISSET(ssh_get_fd(session),&fds)){
ssh_set_fd_toread(session);
}
channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL;
ret=ssh_channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll
if(signal_delayed)
sizechanged();
} while (ret==EINTR || ret==SSH_EINTR);
// we already looked for input from stdin. Now, we are looking for input from the channel
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
channels[0]=NULL;
}
if(channels[0]){
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)>0){
lus=channel_read_buffer(channel,readbuf,0,0);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else
if (write(1,ssh_buffer_get_begin(readbuf),lus) < 0) {
fprintf(stderr, "Error writing to buffer\n");
return;
}
}
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)>0){ /* stderr */
lus=channel_read_buffer(channel,readbuf,0,1);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else
if (write(2,ssh_buffer_get_begin(readbuf),lus) < 0) {
fprintf(stderr, "Error writing to buffer\n");
return;
}
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
}
}
ssh_buffer_free(readbuf);
}
#else /* CHANNEL_SELECT */
static void select_loop(ssh_session session,ssh_channel channel){
fd_set fds;
struct timeval timeout;
char buffer[4096];
/* channels will be set to the channels to poll.
* outchannels will contain the result of the poll
*/
ssh_channel channels[2], outchannels[2];
int lus;
int eof=0;
int maxfd;
unsigned int r;
int ret;
while(channel){
do{
FD_ZERO(&fds);
if(!eof)
FD_SET(0,&fds);
timeout.tv_sec=30;
timeout.tv_usec=0;
FD_SET(ssh_get_fd(session),&fds);
maxfd=ssh_get_fd(session)+1;
channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL;
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
if(signal_delayed)
sizechanged();
if(ret==EINTR)
continue;
if(FD_ISSET(0,&fds)){
lus=read(0,buffer,sizeof(buffer));
if(lus)
ssh_channel_write(channel,buffer,lus);
else {
eof=1;
ssh_channel_send_eof(channel);
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
channels[0]=NULL;
}
if(outchannels[0]){
while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,0))!=0){
lus=ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),0);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else
if (write(1,buffer,lus) < 0) {
fprintf(stderr, "Error writing to buffer\n");
return;
}
}
while(channel && ssh_channel_is_open(channel) && (r = ssh_channel_poll(channel,1))!=0){ /* stderr */
lus=ssh_channel_read(channel,buffer,sizeof(buffer) > r ? r : sizeof(buffer),1);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else
if (write(2,buffer,lus) < 0) {
fprintf(stderr, "Error writing to buffer\n");
return;
}
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
}
} while (ret==EINTR || ret==SSH_EINTR);
}
}
#endif
static void shell(ssh_session session){
ssh_channel channel;
struct termios terminal_local;
int interactive=isatty(0);
channel = ssh_channel_new(session);
if(interactive){
tcgetattr(0,&terminal_local);
memcpy(&terminal,&terminal_local,sizeof(struct termios));
}
if(ssh_channel_open_session(channel)){
printf("error opening channel : %s\n",ssh_get_error(session));
return;
}
chan=channel;
if(interactive){
ssh_channel_request_pty(channel);
sizechanged();
}
if(ssh_channel_request_shell(channel)){
printf("Requesting shell : %s\n",ssh_get_error(session));
return;
}
if(interactive){
cfmakeraw(&terminal_local);
tcsetattr(0,TCSANOW,&terminal_local);
setsignal();
}
signal(SIGTERM,do_cleanup);
select_loop(session,channel);
if(interactive)
do_cleanup(0);
}
static void batch_shell(ssh_session session){
ssh_channel channel;
char buffer[1024];
int i,s=0;
for(i=0;i<MAXCMD && cmds[i];++i) {
s+=snprintf(buffer+s,sizeof(buffer)-s,"%s ",cmds[i]);
free(cmds[i]);
cmds[i] = NULL;
}
channel=ssh_channel_new(session);
ssh_channel_open_session(channel);
if(ssh_channel_request_exec(channel,buffer)){
printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session));
return;
}
select_loop(session,channel);
}
static int client(ssh_session session){
int auth=0;
char *banner;
int state;
if (user)
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0)
return -1;
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
return -1;
if (proxycommand != NULL){
if(ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand))
return -1;
}
ssh_options_parse_config(session, NULL);
if(ssh_connect(session)){
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
return -1;
}
state=verify_knownhost(session);
if (state != 0)
return -1;
ssh_userauth_none(session, NULL);
banner=ssh_get_issue_banner(session);
if(banner){
printf("%s\n",banner);
free(banner);
}
auth=authenticate_console(session);
if(auth != SSH_AUTH_SUCCESS){
return -1;
}
if(!cmds[0])
shell(session);
else
batch_shell(session);
return 0;
}
ssh_pcap_file pcap;
void set_pcap(ssh_session session);
void set_pcap(ssh_session session){
if(!pcap_file)
return;
pcap=ssh_pcap_file_new();
if(!pcap)
return;
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap=NULL;
return;
}
ssh_set_pcap_file(session,pcap);
}
void cleanup_pcap(void);
void cleanup_pcap(){
if(pcap)
ssh_pcap_file_free(pcap);
pcap=NULL;
}
int main(int argc, char **argv){
ssh_session session;
session = ssh_new();
ssh_callbacks_init(&cb);
ssh_set_callbacks(session,&cb);
if(ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr, "error parsing command line :%s\n",
ssh_get_error(session));
usage();
}
opts(argc,argv);
signal(SIGTERM, do_exit);
set_pcap(session);
client(session);
ssh_disconnect(session);
ssh_free(session);
cleanup_pcap();
ssh_finalize();
return 0;
}

View File

@@ -33,259 +33,236 @@ static int verbosity;
static char *destination; static char *destination;
#define DATALEN 65536 #define DATALEN 65536
static void do_sftp(ssh_session session){
static void do_sftp(ssh_session session) { sftp_session sftp=sftp_new(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));
goto end; return;
} }
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));
goto end; return;
} }
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));
fprintf(stderr, "Could not create link (%s)\n", return;
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));
goto end; return;
} }
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));
goto end; return;
} }
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));
goto end; return;
} }
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));
goto end; return ;
} }
/* 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 */
/* when file = NULL, an error has occured OR the directory listing is end of if(!sftp_dir_eof(dir)){
* file */
if (!sftp_dir_eof(dir)) {
fprintf(stderr, "Error: %s\n", ssh_get_error(session)); fprintf(stderr, "Error: %s\n", ssh_get_error(session));
goto end; return;
} }
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));
goto end; return;
} }
/* 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 /* the small buffer size was intended to stress the library. of course, you can use a buffer till 20kbytes without problem */
* 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));
goto end; return;
} }
/* 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));
sftp_close(fichier); return;
goto end;
} }
while((len=sftp_read(fichier,data,4096)) > 0){
while ((len = sftp_read(fichier, data, 4096)) > 0) { if(sftp_write(to,data,len)!=len){
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));
sftp_close(to); return;
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){
for (i = 0; i < 1000; ++i) { len=sftp_write(to,data,DATALEN);
len = sftp_write(to, data, DATALEN); printf("wrote %d bytes\n",len);
printf("wrote %d bytes\n", len); if(len != DATALEN){
if (len != DATALEN) { printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session));
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){
while ((i = getopt(argc, argv, "v")) != -1) { switch(i){
switch(i) { case 'v':
case 'v': verbosity++;
verbosity++; break;
break; default:
default: fprintf(stderr,"unknown option %c\n",optopt);
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)
if (opts(argc, argv) < 0) { return EXIT_FAILURE;
return EXIT_FAILURE; session=connect_ssh(destination,NULL,verbosity);
} if(session == NULL)
return EXIT_FAILURE;
session = connect_ssh(destination, NULL, verbosity); do_sftp(session);
if (session == NULL) { ssh_disconnect(session);
return EXIT_FAILURE; ssh_free(session);
} return 0;
do_sftp(session);
ssh_disconnect(session);
ssh_free(session);
return 0;
} }
#endif #endif

View File

@@ -23,7 +23,6 @@ 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"
@@ -37,7 +36,6 @@ 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";
@@ -63,20 +61,11 @@ 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
@@ -211,7 +200,6 @@ static int kbdint_check_response(ssh_session session) {
return 0; return 0;
} }
authenticated = true;
return 1; return 1;
} }
@@ -340,7 +328,7 @@ int main(int argc, char **argv){
/* proceed to authentication */ /* proceed to authentication */
auth = authenticate(session); auth = authenticate(session);
if (!auth || !authenticated) { if(!auth){
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;

469
examples/samplesshd-tty.c Normal file
View File

@@ -0,0 +1,469 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2003-2011 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <libssh/libssh.h>
#include <libssh/server.h>
#include <libssh/callbacks.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <poll.h>
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#define SSHD_USER "libssh"
#define SSHD_PASSWORD "libssh"
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
static int port = 22;
#ifdef WITH_PCAP
const char *pcap_file="debug.server.pcap";
ssh_pcap_file pcap;
static void set_pcap(ssh_session session){
if(!pcap_file)
return;
pcap=ssh_pcap_file_new();
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap=NULL;
return;
}
ssh_set_pcap_file(session,pcap);
}
static void cleanup_pcap(){
ssh_pcap_file_free(pcap);
pcap=NULL;
}
#endif
static int auth_password(const char *user, const char *password){
if(strcmp(user, SSHD_USER))
return 0;
if(strcmp(password, SSHD_PASSWORD))
return 0;
return 1; // authenticated
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, 0, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure.
*/
ssh_bind sshbind = state->input;
switch (key) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
port = atoi(arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
static int authenticate(ssh_session session) {
ssh_message message;
do {
message=ssh_message_get(session);
if(!message)
break;
switch(ssh_message_type(message)){
case SSH_REQUEST_AUTH:
switch(ssh_message_subtype(message)){
case SSH_AUTH_METHOD_PASSWORD:
printf("User %s wants to auth with pass %s\n",
ssh_message_auth_user(message),
ssh_message_auth_password(message));
if(auth_password(ssh_message_auth_user(message),
ssh_message_auth_password(message))){
ssh_message_auth_reply_success(message,0);
ssh_message_free(message);
return 1;
}
ssh_message_auth_set_methods(message,
SSH_AUTH_METHOD_PASSWORD |
SSH_AUTH_METHOD_INTERACTIVE);
// not authenticated, send default message
ssh_message_reply_default(message);
break;
case SSH_AUTH_METHOD_NONE:
default:
printf("User %s wants to auth with unknown auth %d\n",
ssh_message_auth_user(message),
ssh_message_subtype(message));
ssh_message_auth_set_methods(message,
SSH_AUTH_METHOD_PASSWORD |
SSH_AUTH_METHOD_INTERACTIVE);
ssh_message_reply_default(message);
break;
}
break;
default:
ssh_message_auth_set_methods(message,
SSH_AUTH_METHOD_PASSWORD |
SSH_AUTH_METHOD_INTERACTIVE);
ssh_message_reply_default(message);
}
ssh_message_free(message);
} while (1);
return 0;
}
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) {
ssh_channel chan = (ssh_channel)userdata;
char buf[2048];
int sz = 0;
if(!chan) {
close(fd);
return -1;
}
if(revents & POLLIN) {
sz = read(fd, buf, 2048);
if(sz > 0) {
ssh_channel_write(chan, buf, sz);
}
}
if(revents & POLLHUP) {
ssh_channel_close(chan);
sz = -1;
}
return sz;
}
static int copy_chan_to_fd(ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata) {
int fd = *(int*)userdata;
int sz;
(void)session;
(void)channel;
(void)is_stderr;
sz = write(fd, data, len);
return sz;
}
static void chan_close(ssh_session session, ssh_channel channel, void *userdata) {
int fd = *(int*)userdata;
(void)session;
(void)channel;
close(fd);
}
struct ssh_channel_callbacks_struct cb = {
.channel_data_function = copy_chan_to_fd,
.channel_eof_function = chan_close,
.channel_close_function = chan_close,
.userdata = NULL
};
static int main_loop(ssh_channel chan) {
ssh_session session = ssh_channel_get_session(chan);
socket_t fd;
struct termios *term = NULL;
struct winsize *win = NULL;
pid_t childpid;
ssh_event event;
short events;
int rc;
childpid = forkpty(&fd, NULL, term, win);
if(childpid == 0) {
execl("/bin/bash", "/bin/bash", (char *)NULL);
abort();
}
cb.userdata = &fd;
ssh_callbacks_init(&cb);
ssh_set_channel_callbacks(chan, &cb);
events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
event = ssh_event_new();
if(event == NULL) {
printf("Couldn't get a event\n");
return -1;
}
if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) {
printf("Couldn't add an fd to the event\n");
ssh_event_free(event);
return -1;
}
if(ssh_event_add_session(event, session) != SSH_OK) {
printf("Couldn't add the session to the event\n");
ssh_event_remove_fd(event, fd);
ssh_event_free(event);
return -1;
}
do {
rc = ssh_event_dopoll(event, 1000);
if (rc == SSH_ERROR){
fprintf(stderr, "Error : %s\n", ssh_get_error(session));
ssh_event_free(event);
ssh_disconnect(session);
return -1;
}
} while(!ssh_channel_is_closed(chan));
ssh_event_remove_fd(event, fd);
ssh_event_remove_session(event, session);
ssh_event_free(event);
return 0;
}
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_message message;
ssh_channel chan=0;
int auth=0;
int shell=0;
int r;
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
* Parse our arguments; every option seen by parse_opt will
* be reflected in arguments.
*/
argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
(void) argc;
(void) argv;
#endif
#ifdef WITH_PCAP
set_pcap(session);
#endif
if(ssh_bind_listen(sshbind)<0){
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
return 1;
}
printf("Started sample libssh sshd on port %d\n", port);
printf("You can login as the user %s with the password %s\n", SSHD_USER,
SSHD_PASSWORD);
r = ssh_bind_accept(sshbind, session);
if(r==SSH_ERROR){
printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
return 1;
}
if (ssh_handle_key_exchange(session)) {
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
return 1;
}
/* proceed to authentication */
auth = authenticate(session);
if(!auth){
printf("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session);
return 1;
}
/* wait for a channel session */
do {
message = ssh_message_get(session);
if(message){
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
chan = ssh_message_channel_request_open_reply_accept(message);
ssh_message_free(message);
break;
} else {
ssh_message_reply_default(message);
ssh_message_free(message);
}
} else {
break;
}
} while(!chan);
if(!chan) {
printf("Error: cleint did not ask for a channel session (%s)\n",
ssh_get_error(session));
ssh_finalize();
return 1;
}
/* wait for a shell */
do {
message = ssh_message_get(session);
if(message != NULL) {
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL) {
if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
shell = 1;
ssh_message_channel_request_reply_success(message);
ssh_message_free(message);
break;
} else if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_PTY) {
ssh_message_channel_request_reply_success(message);
ssh_message_free(message);
continue;
}
}
ssh_message_reply_default(message);
ssh_message_free(message);
} else {
break;
}
} while(!shell);
if(!shell) {
printf("Error: No shell requested (%s)\n", ssh_get_error(session));
return 1;
}
printf("it works !\n");
main_loop(chan);
ssh_disconnect(session);
ssh_bind_free(sshbind);
#ifdef WITH_PCAP
cleanup_pcap();
#endif
ssh_finalize();
return 0;
}

314
examples/samplesshd.c Normal file
View File

@@ -0,0 +1,314 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2003-2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <libssh/libssh.h>
#include <libssh/server.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#ifdef WITH_PCAP
static const char *pcap_file="debug.server.pcap";
static ssh_pcap_file pcap;
static void set_pcap(ssh_session session) {
if(!pcap_file)
return;
pcap=ssh_pcap_file_new();
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap=NULL;
return;
}
ssh_set_pcap_file(session,pcap);
}
static void cleanup_pcap(void) {
ssh_pcap_file_free(pcap);
pcap=NULL;
}
#endif
static int auth_password(const char *user, const char *password){
if(strcmp(user,"aris"))
return 0;
if(strcmp(password,"lala"))
return 0;
return 1; // authenticated
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, NULL, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure.
*/
ssh_bind sshbind = state->input;
switch (key) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_message message;
ssh_channel chan=0;
char buf[2048];
int auth=0;
int sftp=0;
int i;
int r;
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
* Parse our arguments; every option seen by parse_opt will
* be reflected in arguments.
*/
argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
(void) argc;
(void) argv;
#endif
#ifdef WITH_PCAP
set_pcap(session);
#endif
if(ssh_bind_listen(sshbind)<0){
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
return 1;
}
r=ssh_bind_accept(sshbind,session);
if(r==SSH_ERROR){
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
return 1;
}
if (ssh_handle_key_exchange(session)) {
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
return 1;
}
do {
message=ssh_message_get(session);
if(!message)
break;
switch(ssh_message_type(message)){
case SSH_REQUEST_AUTH:
switch(ssh_message_subtype(message)){
case SSH_AUTH_METHOD_PASSWORD:
printf("User %s wants to auth with pass %s\n",
ssh_message_auth_user(message),
ssh_message_auth_password(message));
if(auth_password(ssh_message_auth_user(message),
ssh_message_auth_password(message))){
auth=1;
ssh_message_auth_reply_success(message,0);
break;
}
// not authenticated, send default message
case SSH_AUTH_METHOD_NONE:
default:
ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
ssh_message_reply_default(message);
break;
}
break;
default:
ssh_message_reply_default(message);
}
ssh_message_free(message);
} while (!auth);
if(!auth){
printf("auth error: %s\n",ssh_get_error(session));
ssh_disconnect(session);
return 1;
}
do {
message=ssh_message_get(session);
if(message){
switch(ssh_message_type(message)){
case SSH_REQUEST_CHANNEL_OPEN:
if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
chan=ssh_message_channel_request_open_reply_accept(message);
break;
}
default:
ssh_message_reply_default(message);
}
ssh_message_free(message);
}
} while(message && !chan);
if(!chan){
printf("error : %s\n",ssh_get_error(session));
ssh_finalize();
return 1;
}
do {
message=ssh_message_get(session);
if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
(ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL ||
ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_PTY)) {
// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
sftp=1;
ssh_message_channel_request_reply_success(message);
break;
// }
}
if(!sftp){
ssh_message_reply_default(message);
}
ssh_message_free(message);
} while (message && !sftp);
if(!sftp){
printf("error : %s\n",ssh_get_error(session));
return 1;
}
printf("it works !\n");
do{
i=ssh_channel_read(chan,buf, 2048, 0);
if(i>0) {
ssh_channel_write(chan, buf, i);
if (write(1,buf,i) < 0) {
printf("error writing to buffer\n");
return 1;
}
if (buf[0] == '\x0d') {
if (write(1, "\n", 1) < 0) {
printf("error writing to buffer\n");
return 1;
}
ssh_channel_write(chan, "\n", 1);
}
}
} while (i>0);
ssh_disconnect(session);
ssh_bind_free(sshbind);
#ifdef WITH_PCAP
cleanup_pcap();
#endif
ssh_finalize();
return 0;
}

View File

@@ -22,12 +22,9 @@ program.
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include "examples_common.h" #include "examples_common.h"
static int verbosity = 0; int verbosity=0;
static const char *createcommand = const char *createcommand="rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
"rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && " char *host=NULL;
"cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
static char *host = NULL;
static void usage(const char *argv0){ static void usage(const char *argv0){
fprintf(stderr,"Usage : %s [options] host\n" fprintf(stderr,"Usage : %s [options] host\n"
"sample tiny scp downloader client - libssh-%s\n" "sample tiny scp downloader client - libssh-%s\n"

View File

@@ -3,7 +3,7 @@
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include "examples_common.h" #include "examples_common.h"
#define LIMIT 0x100000000UL #define LIMIT 0x100000000
int main(void) { int main(void) {
ssh_session session; ssh_session session;

View File

@@ -1,407 +0,0 @@
/* client.c */
/*
Copyright 2003-2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <libssh/callbacks.h>
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#include "examples_common.h"
#define MAXCMD 10
static char *host;
static char *user;
static char *cmds[MAXCMD];
static struct termios terminal;
static char *pcap_file = NULL;
static char *proxycommand;
static int auth_callback(const char *prompt,
char *buf,
size_t len,
int echo,
int verify,
void *userdata)
{
(void) verify;
(void) userdata;
return ssh_getpass(prompt, buf, len, echo, verify);
}
struct ssh_callbacks_struct cb = {
.auth_function = auth_callback,
.userdata = NULL,
};
static void add_cmd(char *cmd)
{
int n;
for (n = 0; (n < MAXCMD) && cmds[n] != NULL; n++);
if (n == MAXCMD) {
return;
}
cmds[n] = strdup(cmd);
}
static void usage(void)
{
fprintf(stderr,
"Usage : ssh [options] [login@]hostname\n"
"sample client - libssh-%s\n"
"Options :\n"
" -l user : log in as user\n"
" -p port : connect to port\n"
" -d : use DSS to verify host public key\n"
" -r : use RSA to verify host public key\n"
#ifdef WITH_PCAP
" -P file : create a pcap debugging file\n"
#endif
#ifndef _WIN32
" -T proxycommand : command to execute as a socket proxy\n"
#endif
"\n",
ssh_version(0));
exit(0);
}
static int opts(int argc, char **argv)
{
int i;
while((i = getopt(argc,argv,"T:P:")) != -1) {
switch(i){
case 'P':
pcap_file = optarg;
break;
#ifndef _WIN32
case 'T':
proxycommand = optarg;
break;
#endif
default:
fprintf(stderr, "Unknown option %c\n", optopt);
usage();
}
}
if (optind < argc) {
host = argv[optind++];
}
while(optind < argc) {
add_cmd(argv[optind++]);
}
if (host == NULL) {
usage();
}
return 0;
}
#ifndef HAVE_CFMAKERAW
static void cfmakeraw(struct termios *termios_p)
{
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag &= ~(CSIZE|PARENB);
termios_p->c_cflag |= CS8;
}
#endif
static void do_cleanup(int i)
{
/* unused variable */
(void) i;
tcsetattr(0, TCSANOW, &terminal);
}
static void do_exit(int i)
{
/* unused variable */
(void) i;
do_cleanup(0);
exit(0);
}
static ssh_channel chan;
static int signal_delayed = 0;
static void sigwindowchanged(int i)
{
(void) i;
signal_delayed = 1;
}
static void setsignal(void)
{
signal(SIGWINCH, sigwindowchanged);
signal_delayed = 0;
}
static void sizechanged(void)
{
struct winsize win = {
.ws_row = 0,
};
ioctl(1, TIOCGWINSZ, &win);
ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row);
setsignal();
}
static void select_loop(ssh_session session,ssh_channel channel)
{
ssh_connector connector_in, connector_out, connector_err;
ssh_event event = ssh_event_new();
/* stdin */
connector_in = ssh_connector_new(session);
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDOUT);
ssh_connector_set_in_fd(connector_in, 0);
ssh_event_add_connector(event, connector_in);
/* stdout */
connector_out = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_out, 1);
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDOUT);
ssh_event_add_connector(event, connector_out);
/* stderr */
connector_err = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_err, 2);
ssh_connector_set_in_channel(connector_err, channel, SSH_CONNECTOR_STDERR);
ssh_event_add_connector(event, connector_err);
while (ssh_channel_is_open(channel)) {
if (signal_delayed) {
sizechanged();
}
ssh_event_dopoll(event, 60000);
}
ssh_event_remove_connector(event, connector_in);
ssh_event_remove_connector(event, connector_out);
ssh_event_remove_connector(event, connector_err);
ssh_connector_free(connector_in);
ssh_connector_free(connector_out);
ssh_connector_free(connector_err);
ssh_event_free(event);
ssh_channel_free(channel);
}
static void shell(ssh_session session)
{
ssh_channel channel;
struct termios terminal_local;
int interactive=isatty(0);
channel = ssh_channel_new(session);
if (interactive) {
tcgetattr(0, &terminal_local);
memcpy(&terminal, &terminal_local, sizeof(struct termios));
}
if (ssh_channel_open_session(channel)) {
printf("Error opening channel : %s\n", ssh_get_error(session));
return;
}
chan = channel;
if (interactive) {
ssh_channel_request_pty(channel);
sizechanged();
}
if (ssh_channel_request_shell(channel)) {
printf("Requesting shell : %s\n", ssh_get_error(session));
return;
}
if (interactive) {
cfmakeraw(&terminal_local);
tcsetattr(0, TCSANOW, &terminal_local);
setsignal();
}
signal(SIGTERM, do_cleanup);
select_loop(session, channel);
if (interactive) {
do_cleanup(0);
}
}
static void batch_shell(ssh_session session)
{
ssh_channel channel;
char buffer[1024];
size_t i;
int s = 0;
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
free(cmds[i]);
cmds[i] = NULL;
}
channel = ssh_channel_new(session);
ssh_channel_open_session(channel);
if (ssh_channel_request_exec(channel, buffer)) {
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
return;
}
select_loop(session, channel);
}
static int client(ssh_session session)
{
int auth = 0;
char *banner;
int state;
if (user) {
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
return -1;
}
}
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) {
return -1;
}
if (proxycommand != NULL) {
if (ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand)) {
return -1;
}
}
ssh_options_parse_config(session, NULL);
if (ssh_connect(session)) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
return -1;
}
state = verify_knownhost(session);
if (state != 0) {
return -1;
}
ssh_userauth_none(session, NULL);
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n", banner);
free(banner);
}
auth = authenticate_console(session);
if (auth != SSH_AUTH_SUCCESS) {
return -1;
}
if (cmds[0] == NULL) {
shell(session);
} else {
batch_shell(session);
}
return 0;
}
static ssh_pcap_file pcap;
static void set_pcap(ssh_session session)
{
if (pcap_file == NULL) {
return;
}
pcap = ssh_pcap_file_new();
if (pcap == NULL) {
return;
}
if (ssh_pcap_file_open(pcap, pcap_file) == SSH_ERROR) {
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap = NULL;
return;
}
ssh_set_pcap_file(session, pcap);
}
static void cleanup_pcap(void)
{
if (pcap != NULL) {
ssh_pcap_file_free(pcap);
}
pcap = NULL;
}
int main(int argc, char **argv)
{
ssh_session session;
session = ssh_new();
ssh_callbacks_init(&cb);
ssh_set_callbacks(session,&cb);
if (ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr,
"Error parsing command line: %s\n",
ssh_get_error(session));
usage();
}
opts(argc, argv);
signal(SIGTERM, do_exit);
set_pcap(session);
client(session);
ssh_disconnect(session);
ssh_free(session);
cleanup_pcap();
ssh_finalize();
return 0;
}

View File

@@ -1,708 +0,0 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2014 Audrius Butkevicius
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action.
*/
#include "config.h"
#include <libssh/callbacks.h>
#include <libssh/server.h>
#include <poll.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <fcntl.h>
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#include <signal.h>
#include <stdlib.h>
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <stdio.h>
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#define USER "myuser"
#define PASS "mypassword"
#define BUF_SIZE 1048576
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
static void set_default_keys(ssh_bind sshbind,
int rsa_already_set,
int dsa_already_set,
int ecdsa_already_set) {
if (!rsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
KEYS_FOLDER "ssh_host_rsa_key");
}
if (!dsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
KEYS_FOLDER "ssh_host_dsa_key");
}
if (!ecdsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
KEYS_FOLDER "ssh_host_ecdsa_key");
}
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set a host key. Can be used multiple times. "
"Implies no default keys.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "ecdsakey",
.key = 'e',
.arg = "FILE",
.flags = 0,
.doc = "Set the ecdsa key.",
.group = 0
},
{
.name = "no-default-keys",
.key = 'n',
.arg = NULL,
.flags = 0,
.doc = "Do not set default key locations.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, NULL, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure. */
ssh_bind sshbind = state->input;
static int no_default_keys = 0;
static int rsa_already_set = 0, dsa_already_set = 0, ecdsa_already_set = 0;
switch (key) {
case 'n':
no_default_keys = 1;
break;
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
dsa_already_set = 1;
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
/* We can't track the types of keys being added with this
option, so let's ensure we keep the keys we're adding
by just not setting the default keys */
no_default_keys = 1;
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
rsa_already_set = 1;
break;
case 'e':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
ecdsa_already_set = 1;
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
"3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
if (!no_default_keys) {
set_default_keys(sshbind,
rsa_already_set,
dsa_already_set,
ecdsa_already_set);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
/* A userdata struct for channel. */
struct channel_data_struct {
/* pid of the child process the channel will spawn. */
pid_t pid;
/* For PTY allocation */
socket_t pty_master;
socket_t pty_slave;
/* For communication with the child process. */
socket_t child_stdin;
socket_t child_stdout;
/* Only used for subsystem and exec requests. */
socket_t child_stderr;
/* Event which is used to poll the above descriptors. */
ssh_event event;
/* Terminal size struct. */
struct winsize *winsize;
};
/* A userdata struct for session. */
struct session_data_struct {
/* Pointer to the channel the session will allocate. */
ssh_channel channel;
int auth_attempts;
int authenticated;
};
static int data_function(ssh_session session, ssh_channel channel, void *data,
uint32_t len, int is_stderr, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void) session;
(void) channel;
(void) is_stderr;
if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) {
return 0;
}
return write(cdata->child_stdin, (char *) data, len);
}
static int pty_request(ssh_session session, ssh_channel channel,
const char *term, int cols, int rows, int py, int px,
void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
(void) session;
(void) channel;
(void) term;
cdata->winsize->ws_row = rows;
cdata->winsize->ws_col = cols;
cdata->winsize->ws_xpixel = px;
cdata->winsize->ws_ypixel = py;
if (openpty(&cdata->pty_master, &cdata->pty_slave, NULL, NULL,
cdata->winsize) != 0) {
fprintf(stderr, "Failed to open pty\n");
return SSH_ERROR;
}
return SSH_OK;
}
static int pty_resize(ssh_session session, ssh_channel channel, int cols,
int rows, int py, int px, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
(void) session;
(void) channel;
cdata->winsize->ws_row = rows;
cdata->winsize->ws_col = cols;
cdata->winsize->ws_xpixel = px;
cdata->winsize->ws_ypixel = py;
if (cdata->pty_master != -1) {
return ioctl(cdata->pty_master, TIOCSWINSZ, cdata->winsize);
}
return SSH_ERROR;
}
static int exec_pty(const char *mode, const char *command,
struct channel_data_struct *cdata) {
switch(cdata->pid = fork()) {
case -1:
close(cdata->pty_master);
close(cdata->pty_slave);
fprintf(stderr, "Failed to fork\n");
return SSH_ERROR;
case 0:
close(cdata->pty_master);
if (login_tty(cdata->pty_slave) != 0) {
exit(1);
}
execl("/bin/sh", "sh", mode, command, NULL);
exit(0);
default:
close(cdata->pty_slave);
/* pty fd is bi-directional */
cdata->child_stdout = cdata->child_stdin = cdata->pty_master;
}
return SSH_OK;
}
static int exec_nopty(const char *command, struct channel_data_struct *cdata) {
int in[2], out[2], err[2];
/* Do the plumbing to be able to talk with the child process. */
if (pipe(in) != 0) {
goto stdin_failed;
}
if (pipe(out) != 0) {
goto stdout_failed;
}
if (pipe(err) != 0) {
goto stderr_failed;
}
switch(cdata->pid = fork()) {
case -1:
goto fork_failed;
case 0:
/* Finish the plumbing in the child process. */
close(in[1]);
close(out[0]);
close(err[0]);
dup2(in[0], STDIN_FILENO);
dup2(out[1], STDOUT_FILENO);
dup2(err[1], STDERR_FILENO);
close(in[0]);
close(out[1]);
close(err[1]);
/* exec the requested command. */
execl("/bin/sh", "sh", "-c", command, NULL);
exit(0);
}
close(in[0]);
close(out[1]);
close(err[1]);
cdata->child_stdin = in[1];
cdata->child_stdout = out[0];
cdata->child_stderr = err[0];
return SSH_OK;
fork_failed:
close(err[0]);
close(err[1]);
stderr_failed:
close(out[0]);
close(out[1]);
stdout_failed:
close(in[0]);
close(in[1]);
stdin_failed:
return SSH_ERROR;
}
static int exec_request(ssh_session session, ssh_channel channel,
const char *command, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void) session;
(void) channel;
if(cdata->pid > 0) {
return SSH_ERROR;
}
if (cdata->pty_master != -1 && cdata->pty_slave != -1) {
return exec_pty("-c", command, cdata);
}
return exec_nopty(command, cdata);
}
static int shell_request(ssh_session session, ssh_channel channel,
void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void) session;
(void) channel;
if(cdata->pid > 0) {
return SSH_ERROR;
}
if (cdata->pty_master != -1 && cdata->pty_slave != -1) {
return exec_pty("-l", NULL, cdata);
}
/* Client requested a shell without a pty, let's pretend we allow that */
return SSH_OK;
}
static int subsystem_request(ssh_session session, ssh_channel channel,
const char *subsystem, void *userdata) {
/* subsystem requests behave simillarly to exec requests. */
if (strcmp(subsystem, "sftp") == 0) {
return exec_request(session, channel, SFTP_SERVER_PATH, userdata);
}
return SSH_ERROR;
}
static int auth_password(ssh_session session, const char *user,
const char *pass, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
(void) session;
if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0) {
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
sdata->auth_attempts++;
return SSH_AUTH_DENIED;
}
static ssh_channel channel_open(ssh_session session, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
sdata->channel = ssh_channel_new(session);
return sdata->channel;
}
static int process_stdout(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
if (n > 0) {
ssh_channel_write(channel, buf, n);
}
}
return n;
}
static int process_stderr(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
if (n > 0) {
ssh_channel_write_stderr(channel, buf, n);
}
}
return n;
}
static void handle_session(ssh_event event, ssh_session session) {
int n;
int rc = 0;
/* Structure for storing the pty size. */
struct winsize wsize = {
.ws_row = 0,
.ws_col = 0,
.ws_xpixel = 0,
.ws_ypixel = 0
};
/* Our struct holding information about the channel. */
struct channel_data_struct cdata = {
.pid = 0,
.pty_master = -1,
.pty_slave = -1,
.child_stdin = -1,
.child_stdout = -1,
.child_stderr = -1,
.event = NULL,
.winsize = &wsize
};
/* Our struct holding information about the session. */
struct session_data_struct sdata = {
.channel = NULL,
.auth_attempts = 0,
.authenticated = 0
};
struct ssh_channel_callbacks_struct channel_cb = {
.userdata = &cdata,
.channel_pty_request_function = pty_request,
.channel_pty_window_change_function = pty_resize,
.channel_shell_request_function = shell_request,
.channel_exec_request_function = exec_request,
.channel_data_function = data_function,
.channel_subsystem_request_function = subsystem_request
};
struct ssh_server_callbacks_struct server_cb = {
.userdata = &sdata,
.auth_password_function = auth_password,
.channel_open_request_session_function = channel_open,
};
ssh_callbacks_init(&server_cb);
ssh_callbacks_init(&channel_cb);
ssh_set_server_callbacks(session, &server_cb);
if (ssh_handle_key_exchange(session) != SSH_OK) {
fprintf(stderr, "%s\n", ssh_get_error(session));
return;
}
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
ssh_event_add_session(event, session);
n = 0;
while (sdata.authenticated == 0 || sdata.channel == NULL) {
/* If the user has used up all attempts, or if he hasn't been able to
* authenticate in 10 seconds (n * 100ms), disconnect. */
if (sdata.auth_attempts >= 3 || n >= 100) {
return;
}
if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
fprintf(stderr, "%s\n", ssh_get_error(session));
return;
}
n++;
}
ssh_set_channel_callbacks(sdata.channel, &channel_cb);
do {
/* Poll the main event which takes care of the session, the channel and
* even our child process's stdout/stderr (once it's started). */
if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
ssh_channel_close(sdata.channel);
}
/* If child process's stdout/stderr has been registered with the event,
* or the child process hasn't started yet, continue. */
if (cdata.event != NULL || cdata.pid == 0) {
continue;
}
/* Executed only once, once the child process starts. */
cdata.event = event;
/* If stdout valid, add stdout to be monitored by the poll event. */
if (cdata.child_stdout != -1) {
if (ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout,
sdata.channel) != SSH_OK) {
fprintf(stderr, "Failed to register stdout to poll context\n");
ssh_channel_close(sdata.channel);
}
}
/* If stderr valid, add stderr to be monitored by the poll event. */
if (cdata.child_stderr != -1){
if (ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr,
sdata.channel) != SSH_OK) {
fprintf(stderr, "Failed to register stderr to poll context\n");
ssh_channel_close(sdata.channel);
}
}
} while(ssh_channel_is_open(sdata.channel) &&
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
close(cdata.pty_master);
close(cdata.child_stdin);
close(cdata.child_stdout);
close(cdata.child_stderr);
/* Remove the descriptors from the polling context, since they are now
* closed, they will always trigger during the poll calls. */
ssh_event_remove_fd(event, cdata.child_stdout);
ssh_event_remove_fd(event, cdata.child_stderr);
/* If the child process exited. */
if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) {
rc = WEXITSTATUS(rc);
ssh_channel_request_send_exit_status(sdata.channel, rc);
/* If client terminated the channel or the process did not exit nicely,
* but only if something has been forked. */
} else if (cdata.pid > 0) {
kill(cdata.pid, SIGKILL);
}
ssh_channel_send_eof(sdata.channel);
ssh_channel_close(sdata.channel);
/* Wait up to 5 seconds for the client to terminate the session. */
for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
ssh_event_dopoll(event, 100);
}
}
/* SIGCHLD handler for cleaning up dead children. */
static void sigchld_handler(int signo) {
(void) signo;
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main(int argc, char **argv) {
ssh_bind sshbind;
ssh_session session;
ssh_event event;
struct sigaction sa;
int rc;
/* Set up SIGCHLD handler. */
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sa, NULL) != 0) {
fprintf(stderr, "Failed to register SIGCHLD handler\n");
return 1;
}
rc = ssh_init();
if (rc < 0) {
fprintf(stderr, "ssh_init failed\n");
return 1;
}
sshbind = ssh_bind_new();
if (sshbind == NULL) {
fprintf(stderr, "ssh_bind_new failed\n");
return 1;
}
#ifdef HAVE_ARGP_H
argp_parse(&argp, argc, argv, 0, 0, sshbind);
#else
(void) argc;
(void) argv;
set_default_keys(sshbind, 0, 0, 0);
#endif /* HAVE_ARGP_H */
if(ssh_bind_listen(sshbind) < 0) {
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
return 1;
}
while (1) {
session = ssh_new();
if (session == NULL) {
fprintf(stderr, "Failed to allocate session\n");
continue;
}
/* Blocks until there is a new incoming connection. */
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
switch(fork()) {
case 0:
/* Remove the SIGCHLD handler inherited from parent. */
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
/* Remove socket binding, which allows us to restart the
* parent process, without terminating existing sessions. */
ssh_bind_free(sshbind);
event = ssh_event_new();
if (event != NULL) {
/* Blocks until the SSH session ends by either
* child process exiting, or client disconnecting. */
handle_session(event, session);
ssh_event_free(event);
} else {
fprintf(stderr, "Could not create polling context\n");
}
ssh_disconnect(session);
ssh_free(session);
exit(0);
case -1:
fprintf(stderr, "Failed to fork\n");
}
} else {
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
}
/* Since the session has been passed to a child fork, do some cleaning
* up at the parent process. */
ssh_disconnect(session);
ssh_free(session);
}
ssh_bind_free(sshbind);
ssh_finalize();
return 0;
}

View File

@@ -43,8 +43,7 @@ const char *port="22";
char *pcap_file=NULL; char *pcap_file=NULL;
#endif #endif
static void usage(void) static void usage(){
{
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);
} }
@@ -88,24 +87,13 @@ static void select_loop(ssh_session session,ssh_channel channel){
int ret; int ret;
while(channel){ while(channel){
do{ do{
int fd;
ZERO_STRUCT(fds);
FD_ZERO(&fds); FD_ZERO(&fds);
if(!eof) if(!eof)
FD_SET(0,&fds); FD_SET(0,&fds);
timeout.tv_sec=30; timeout.tv_sec=30;
timeout.tv_usec=0; timeout.tv_usec=0;
FD_SET(ssh_get_fd(session),&fds);
fd = ssh_get_fd(session); maxfd=ssh_get_fd(session)+1;
if (fd == -1) {
fprintf(stderr, "Error getting the session file descriptor: %s\n",
ssh_get_error(session));
return;
}
FD_SET(fd, &fds);
maxfd = fd + 1;
channels[0]=channel; // set the first channel we want to read from channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL; channels[1]=NULL;
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout); ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
@@ -114,27 +102,27 @@ static void select_loop(ssh_session session,ssh_channel channel){
if(FD_ISSET(0,&fds)){ if(FD_ISSET(0,&fds)){
lus=read(0,buffer,sizeof(buffer)); lus=read(0,buffer,sizeof(buffer));
if(lus) if(lus)
ssh_channel_write(channel,buffer,lus); channel_write(channel,buffer,lus);
else { else {
eof=1; eof=1;
ssh_channel_send_eof(channel); channel_send_eof(channel);
} }
} }
if(channel && ssh_channel_is_closed(channel)){ if(channel && channel_is_closed(channel)){
ssh_channel_free(channel); channel_free(channel);
channel=NULL; channel=NULL;
channels[0]=NULL; channels[0]=NULL;
} }
if(outchannels[0]){ if(outchannels[0]){
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)){ while(channel && channel_is_open(channel) && channel_poll(channel,0)){
lus = ssh_channel_read(channel,buffer,sizeof(buffer),0); lus=channel_read(channel,buffer,sizeof(buffer),0);
if(lus==-1){ if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n", fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session)); ssh_get_error(session));
return; return;
} }
if(lus==0){ if(lus==0){
ssh_channel_free(channel); channel_free(channel);
channel=channels[0]=NULL; channel=channels[0]=NULL;
} else { } else {
ret = write(1, buffer, lus); ret = write(1, buffer, lus);
@@ -145,15 +133,15 @@ static void select_loop(ssh_session session,ssh_channel channel){
} }
} }
} }
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)){ /* stderr */ while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
lus = ssh_channel_read(channel, buffer, sizeof(buffer), 1); lus=channel_read(channel,buffer,sizeof(buffer),1);
if(lus==-1){ if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n", fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session)); ssh_get_error(session));
return; return;
} }
if(lus==0){ if(lus==0){
ssh_channel_free(channel); channel_free(channel);
channel=channels[0]=NULL; channel=channels[0]=NULL;
} else { } else {
ret = write(2, buffer, lus); ret = write(2, buffer, lus);
@@ -165,8 +153,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
} }
} }
} }
if(channel && ssh_channel_is_closed(channel)){ if(channel && channel_is_closed(channel)){
ssh_channel_free(channel); channel_free(channel);
channel=NULL; channel=NULL;
} }
} while (ret==EINTR || ret==SSH_EINTR); } while (ret==EINTR || ret==SSH_EINTR);
@@ -177,8 +165,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
static void forwarding(ssh_session session){ static void forwarding(ssh_session session){
ssh_channel channel; ssh_channel channel;
int r; int r;
channel = ssh_channel_new(session); channel=channel_new(session);
r = ssh_channel_open_forward(channel, desthost, atoi(port), "localhost", 22); r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
if(r<0) { if(r<0) {
printf("error forwarding port : %s\n",ssh_get_error(session)); printf("error forwarding port : %s\n",ssh_get_error(session));
return; return;

View File

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

View File

@@ -5,7 +5,6 @@ set(libssh_HDRS
libssh.h libssh.h
ssh2.h ssh2.h
legacy.h legacy.h
libsshpp.hpp
) )
if (WITH_SFTP) if (WITH_SFTP)
@@ -15,6 +14,13 @@ if (WITH_SFTP)
) )
endif (WITH_SFTP) endif (WITH_SFTP)
if (WITH_SSH1)
set(libssh_HDRS
${libssh_HDRS}
ssh1.h
)
endif (WITH_SSH1)
if (WITH_SERVER) if (WITH_SERVER)
set(libssh_HDRS set(libssh_HDRS
${libssh_HDRS} ${libssh_HDRS}

View File

@@ -66,9 +66,6 @@
#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;
@@ -84,16 +81,16 @@ struct ssh_agent_struct {
* *
* @return An allocated ssh agent structure or NULL on error. * @return An allocated ssh agent structure or NULL on error.
*/ */
struct ssh_agent_struct *ssh_agent_new(struct ssh_session_struct *session); struct ssh_agent_struct *agent_new(struct ssh_session_struct *session);
void ssh_agent_close(struct ssh_agent_struct *agent); void agent_close(struct ssh_agent_struct *agent);
/** /**
* @brief Free an allocated ssh agent structure. * @brief Free an allocated ssh agent structure.
* *
* @param agent The ssh agent structure to free. * @param agent The ssh agent structure to free.
*/ */
void ssh_agent_free(struct ssh_agent_struct *agent); void agent_free(struct ssh_agent_struct *agent);
/** /**
* @brief Check if the ssh agent is running. * @brief Check if the ssh agent is running.
@@ -102,7 +99,7 @@ void ssh_agent_free(struct ssh_agent_struct *agent);
* *
* @return 1 if it is running, 0 if not. * @return 1 if it is running, 0 if not.
*/ */
int ssh_agent_is_running(struct ssh_session_struct *session); int agent_is_running(struct ssh_session_struct *session);
int ssh_agent_get_ident_count(struct ssh_session_struct *session); int ssh_agent_get_ident_count(struct ssh_session_struct *session);
@@ -118,3 +115,4 @@ ssh_string ssh_agent_sign_data(ssh_session session,
#endif #endif
#endif /* __AGENT_H */ #endif /* __AGENT_H */
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -49,6 +49,20 @@ ssh_kbdint ssh_kbdint_new(void);
void ssh_kbdint_clean(ssh_kbdint kbd); void ssh_kbdint_clean(ssh_kbdint kbd);
void ssh_kbdint_free(ssh_kbdint kbd); void ssh_kbdint_free(ssh_kbdint kbd);
#ifdef WITH_SSH1
void ssh_auth1_handler(ssh_session session, uint8_t type);
/* auth1.c */
int ssh_userauth1_none(ssh_session session, const char *username);
int ssh_userauth1_offer_pubkey(ssh_session session, const char *username,
int type, ssh_string pubkey);
int ssh_userauth1_password(ssh_session session, const char *username,
const char *password);
#endif
/** @internal /** @internal
* States of authentication in the client-side. They describe * States of authentication in the client-side. They describe
* what was the last response from the server * what was the last response from the server
@@ -76,14 +90,6 @@ 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
@@ -98,6 +104,8 @@ enum ssh_auth_service_state_e {
SSH_AUTH_SERVICE_ACCEPTED, SSH_AUTH_SERVICE_ACCEPTED,
/** Access to service denied (fatal) */ /** Access to service denied (fatal) */
SSH_AUTH_SERVICE_DENIED, SSH_AUTH_SERVICE_DENIED,
/** Specific to SSH1 */
SSH_AUTH_SERVICE_USER_SENT
}; };
#endif /* AUTH_H_ */ #endif /* AUTH_H_ */

View File

@@ -36,11 +36,9 @@ struct ssh_bind_struct {
char *ecdsakey; char *ecdsakey;
char *dsakey; char *dsakey;
char *rsakey; char *rsakey;
char *ed25519key;
ssh_key ecdsa; ssh_key ecdsa;
ssh_key dsa; ssh_key dsa;
ssh_key rsa; ssh_key rsa;
ssh_key ed25519;
char *bindaddr; char *bindaddr;
socket_t bindfd; socket_t bindfd;
unsigned int bindport; unsigned int bindport;

View File

@@ -1,87 +0,0 @@
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
/*
* Blowfish - a fast block cipher designed by Bruce Schneier
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLF_H_
#define _BLF_H_
//#include "includes.h"
#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H)
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} ssh_blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
void Blowfish_encipher(ssh_blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_decipher(ssh_blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_initstate(ssh_blf_ctx *);
void Blowfish_expand0state(ssh_blf_ctx *, const uint8_t *, uint16_t);
void Blowfish_expandstate
(ssh_blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
void ssh_blf_key(ssh_blf_ctx *, const uint8_t *, uint16_t);
void ssh_blf_enc(ssh_blf_ctx *, uint32_t *, uint16_t);
void ssh_blf_dec(ssh_blf_ctx *, uint32_t *, uint16_t);
void ssh_blf_ecb_encrypt(ssh_blf_ctx *, uint8_t *, uint32_t);
void ssh_blf_ecb_decrypt(ssh_blf_ctx *, uint8_t *, uint32_t);
void ssh_blf_cbc_encrypt(ssh_blf_ctx *, uint8_t *, uint8_t *, uint32_t);
void ssh_blf_cbc_decrypt(ssh_blf_ctx *, uint8_t *, uint8_t *, uint32_t);
/* Converts uint8_t to uint32_t */
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t , uint16_t *);
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
#endif /* _BLF_H */

View File

@@ -21,57 +21,52 @@
#ifndef BUFFER_H_ #ifndef BUFFER_H_
#define BUFFER_H_ #define BUFFER_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;
};
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3) LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
LIBSSH_API void *ssh_buffer_get_begin(ssh_buffer buffer);
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
LIBSSH_API ssh_buffer ssh_buffer_new(void);
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
int buffer_add_u16(ssh_buffer buffer, uint16_t data);
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
int buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
int buffer_reinit(ssh_buffer buffer);
void ssh_buffer_set_secure(ssh_buffer buffer); /* buffer_get_rest returns a pointer to the current position into the buffer */
int ssh_buffer_add_ssh_string(ssh_buffer buffer, ssh_string string); void *buffer_get_rest(ssh_buffer buffer);
int ssh_buffer_add_u8(ssh_buffer buffer, uint8_t data); /* buffer_get_rest_len returns the number of bytes which can be read */
int ssh_buffer_add_u16(ssh_buffer buffer, uint16_t data); uint32_t buffer_get_rest_len(ssh_buffer buffer);
int ssh_buffer_add_u32(ssh_buffer buffer, uint32_t data);
int ssh_buffer_add_u64(ssh_buffer buffer, uint64_t data);
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len);
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_pack_va(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
va_list ap);
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
...);
#define ssh_buffer_pack(buffer, format, ...) \
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
const char *format, int argc,
va_list ap);
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
const char *format,
int argc,
...);
#define ssh_buffer_unpack(buffer, format, ...) \
_ssh_buffer_unpack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
int ssh_buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
int ssh_buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
/* buffer_read_*() returns the number of bytes read, except for ssh strings */ /* buffer_read_*() returns the number of bytes read, except for ssh strings */
int ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data); int buffer_get_u8(ssh_buffer buffer, uint8_t *data);
int ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data); int buffer_get_u32(ssh_buffer buffer, uint32_t *data);
int ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data); int buffer_get_u64(ssh_buffer buffer, uint64_t *data);
/* ssh_buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */ uint32_t buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer); /* buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
ssh_string buffer_get_ssh_string(ssh_buffer buffer);
/* ssh_buffer_pass_bytes acts as if len bytes have been read (used for padding) */ /* gets a string out of a SSH-1 mpint */
uint32_t ssh_buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len); ssh_string buffer_get_mpint(ssh_buffer buffer);
uint32_t ssh_buffer_pass_bytes(ssh_buffer buffer, uint32_t len); /* buffer_pass_bytes acts as if len bytes have been read (used for padding) */
uint32_t buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
uint32_t buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
#endif /* BUFFER_H_ */ #endif /* BUFFER_H_ */

View File

@@ -1,90 +0,0 @@
/*
* 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

@@ -124,18 +124,6 @@ typedef void (*ssh_global_request_callback) (ssh_session session,
typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session session, typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session session,
const char * originator_address, int originator_port, void *userdata); const char * originator_address, int originator_port, void *userdata);
/**
* @brief Handles an SSH new channel open "auth-agent" request. This happens when the server
* sends back an "auth-agent" connection attempt. This is a client-side API
* @param session current session handler
* @param userdata Userdata to be passed to the callback function.
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the application.
*/
typedef ssh_channel (*ssh_channel_open_request_auth_agent_callback) (ssh_session session,
void *userdata);
/** /**
* The structure to replace libssh functions with appropriate callbacks. * The structure to replace libssh functions with appropriate callbacks.
*/ */
@@ -166,9 +154,6 @@ struct ssh_callbacks_struct {
/** This function will be called when an incoming X11 request is received. /** This function will be called when an incoming X11 request is received.
*/ */
ssh_channel_open_request_x11_callback channel_open_request_x11_function; ssh_channel_open_request_x11_callback channel_open_request_x11_function;
/** This function will be called when an incoming "auth-agent" request is received.
*/
ssh_channel_open_request_auth_agent_callback channel_open_request_auth_agent_function;
}; };
typedef struct ssh_callbacks_struct *ssh_callbacks; typedef struct ssh_callbacks_struct *ssh_callbacks;
@@ -435,69 +420,6 @@ typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
((p)-> c != NULL) \ ((p)-> c != NULL) \
) )
/**
* @internal
*
* @brief Iterate through a list of callback structures
*
* This tests for their validity and executes them. The userdata argument is
* automatically passed through.
*
* @param list list of callbacks
*
* @param cbtype type of the callback
*
* @param c callback name
*
* @param va_args parameters to be passed
*/
#define ssh_callbacks_execute_list(list, cbtype, c, ...) \
do { \
struct ssh_iterator *i = ssh_list_get_iterator(list); \
cbtype cb; \
while (i != NULL){ \
cb = ssh_iterator_value(cbtype, i); \
if (ssh_callbacks_exists(cb, c)) \
cb-> c (__VA_ARGS__, cb->userdata); \
i = i->next; \
} \
} while(0)
/**
* @internal
*
* @brief iterate through a list of callback structures.
*
* This tests for their validity and give control back to the calling code to
* execute them. Caller can decide to break the loop or continue executing the
* callbacks with different parameters
*
* @code
* ssh_callbacks_iterate(channel->callbacks, ssh_channel_callbacks,
* channel_eof_function){
* rc = ssh_callbacks_iterate_exec(session, channel);
* if (rc != SSH_OK){
* break;
* }
* }
* ssh_callbacks_iterate_end();
* @endcode
*/
#define ssh_callbacks_iterate(_cb_list, _cb_type, _cb_name) \
do { \
struct ssh_iterator *_cb_i = ssh_list_get_iterator(_cb_list); \
_cb_type _cb; \
for (; _cb_i != NULL; _cb_i = _cb_i->next) { \
_cb = ssh_iterator_value(_cb_type, _cb_i); \
if (ssh_callbacks_exists(_cb, _cb_name))
#define ssh_callbacks_iterate_exec(_cb_name, ...) \
_cb->_cb_name(__VA_ARGS__, _cb->userdata)
#define ssh_callbacks_iterate_end() \
} \
} while(0)
/** @brief Prototype for a packet callback, to be called when a new packet arrives /** @brief Prototype for a packet callback, to be called when a new packet arrives
* @param session The current session of the packet * @param session The current session of the packet
* @param type packet type (see ssh2.h) * @param type packet type (see ssh2.h)
@@ -573,8 +495,6 @@ LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
* @param len the length of the data * @param len the length of the data
* @param is_stderr is 0 for stdout or 1 for stderr * @param is_stderr is 0 for stdout or 1 for stderr
* @param userdata Userdata to be passed to the callback function. * @param userdata Userdata to be passed to the callback function.
* @returns number of bytes processed by the callee. The remaining bytes will
* be sent in the next callback message, when more data is available.
*/ */
typedef int (*ssh_channel_data_callback) (ssh_session session, typedef int (*ssh_channel_data_callback) (ssh_session session,
ssh_channel channel, ssh_channel channel,
@@ -757,22 +677,6 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
const char *subsystem, const char *subsystem,
void *userdata); void *userdata);
/**
* @brief SSH channel write will not block (flow control).
*
* @param channel the channel
*
* @param[in] bytes size of the remote window in bytes. Writing as much data
* will not block.
*
* @param[in] userdata Userdata to be passed to the callback function.
*
* @returns 0 default return value (other return codes may be added in future).
*/
typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
ssh_channel channel,
size_t bytes,
void *userdata);
struct ssh_channel_callbacks_struct { struct ssh_channel_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */ /** DON'T SET THIS use ssh_callbacks_init() instead. */
@@ -837,10 +741,6 @@ struct ssh_channel_callbacks_struct {
* (like sftp). * (like sftp).
*/ */
ssh_channel_subsystem_request_callback channel_subsystem_request_function; ssh_channel_subsystem_request_callback channel_subsystem_request_function;
/** This function will be called when the channel write is guaranteed
* not to block.
*/
ssh_channel_write_wontblock_callback channel_write_wontblock_function;
}; };
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks; typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
@@ -865,46 +765,10 @@ typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
* @param cb The callback structure itself. * @param cb The callback structure itself.
* *
* @return SSH_OK on success, SSH_ERROR on error. * @return SSH_OK on success, SSH_ERROR on error.
* @warning this function will not replace existing callbacks but set the
* new one atop of them.
*/ */
LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel, LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb); ssh_channel_callbacks cb);
/**
* @brief Add channel callback functions
*
* This function will add channel callback functions to the channel callback
* list.
* Callbacks missing from a callback structure will be probed in the next
* on the list.
*
* @param channel The channel to set the callback structure.
*
* @param cb The callback structure itself.
*
* @return SSH_OK on success, SSH_ERROR on error.
*
* @see ssh_set_channel_callbacks
*/
LIBSSH_API int ssh_add_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb);
/**
* @brief Remove a channel callback.
*
* The channel has been added with ssh_add_channel_callbacks or
* ssh_set_channel_callbacks in this case.
*
* @param channel The channel to remove the callback structure from.
*
* @param cb The callback structure to remove
*
* @returns SSH_OK on success, SSH_ERROR on error.
*/
LIBSSH_API int ssh_remove_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb);
/** @} */ /** @} */
/** @group libssh_threads /** @group libssh_threads
@@ -937,8 +801,6 @@ struct ssh_threads_callbacks_struct {
* *
* @see ssh_threads_callbacks_struct * @see ssh_threads_callbacks_struct
* @see SSH_THREADS_PTHREAD * @see SSH_THREADS_PTHREAD
* @bug libgcrypt 1.6 and bigger backend does not support custom callback.
* Using anything else than pthreads here will fail.
*/ */
LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
*cb); *cb);

View File

@@ -1,41 +0,0 @@
/* $OpenBSD: chacha.h,v 1.3 2014/05/02 03:27:54 djm Exp $ */
/*
chacha-merged.c version 20080118
D. J. Bernstein
Public domain.
*/
#ifndef CHACHA_H
#define CHACHA_H
struct chacha_ctx {
uint32_t input[16];
};
#define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)))
#endif
;
void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr)
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN)))
__attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)))
#endif
;
void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m,
uint8_t *c, uint32_t bytes)
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__buffer__, 2, 4)))
__attribute__((__bounded__(__buffer__, 3, 4)))
#endif
;
#endif /* CHACHA_H */

View File

@@ -71,12 +71,10 @@ struct ssh_channel_struct {
ssh_buffer stdout_buffer; ssh_buffer stdout_buffer;
ssh_buffer stderr_buffer; ssh_buffer stderr_buffer;
void *userarg; void *userarg;
int version;
int exit_status; int exit_status;
enum ssh_channel_request_state_e request_state; enum ssh_channel_request_state_e request_state;
struct ssh_list *callbacks; /* list of ssh_channel_callbacks */ ssh_channel_callbacks callbacks;
/* counters */
ssh_counter counter;
}; };
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf); SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
@@ -92,15 +90,29 @@ 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);
int channel_write_common(ssh_channel channel, const void *data,
uint32_t len, int is_stderr);
void ssh_channel_do_free(ssh_channel channel); void ssh_channel_do_free(ssh_channel channel);
int ssh_global_request(ssh_session session, #ifdef WITH_SSH1
const char *request, SSH_PACKET_CALLBACK(ssh_packet_data1);
ssh_buffer buffer, SSH_PACKET_CALLBACK(ssh_packet_close1);
int reply); SSH_PACKET_CALLBACK(ssh_packet_exist_status1);
/* channels1.c */
int channel_open_session1(ssh_channel channel);
int channel_request_pty_size1(ssh_channel channel, const char *terminal,
int cols, int rows);
int channel_change_pty_size1(ssh_channel channel, int cols, int rows);
int channel_request_shell1(ssh_channel channel);
int channel_request_exec1(ssh_channel channel, const char *cmd);
int channel_write1(ssh_channel channel, const void *data, int len);
ssh_channel ssh_get_channel1(ssh_session session);
#endif
#endif /* CHANNELS_H_ */ #endif /* CHANNELS_H_ */

View File

@@ -1,66 +0,0 @@
/*
* 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,7 +1,9 @@
/* /*
* crc32.c - simple CRC32 code
*
* This file is part of the SSH Library * This file is part of the SSH Library
* *
* Copyright (c) 2014 by Aris Adamantiadis <aris@badcode.be> * Copyright (c) 2005 by Aris Adamantiadis
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -18,17 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef BIGNUM_H_ #ifndef _CRC32_H
#define BIGNUM_H_ #define _CRC32_H
#include "libssh/libcrypto.h" uint32_t ssh_crc32(const char *buf, uint32_t len);
#include "libssh/libgcrypt.h"
#include "libssh/libmbedcrypto.h"
bignum ssh_make_string_bn(ssh_string string); #endif /* _CRC32_H */
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout);
ssh_string ssh_make_bignum_string(bignum num);
void ssh_print_bignum(const char *which, const bignum num);
#endif /* BIGNUM_H_ */

View File

@@ -29,8 +29,6 @@
#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,11 +46,6 @@
#include "libssh/kex.h" #include "libssh/kex.h"
#include "libssh/curve25519.h" #include "libssh/curve25519.h"
#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,
@@ -60,45 +53,14 @@ enum ssh_key_exchange_e {
SSH_KEX_DH_GROUP14_SHA1, SSH_KEX_DH_GROUP14_SHA1,
/* ecdh-sha2-nistp256 */ /* ecdh-sha2-nistp256 */
SSH_KEX_ECDH_SHA2_NISTP256, SSH_KEX_ECDH_SHA2_NISTP256,
/* ecdh-sha2-nistp384 */
SSH_KEX_ECDH_SHA2_NISTP384,
/* ecdh-sha2-nistp521 */
SSH_KEX_ECDH_SHA2_NISTP521,
/* curve25519-sha256@libssh.org */ /* curve25519-sha256@libssh.org */
SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG, SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG
/* 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 {
SSH_NO_CIPHER=0,
SSH_BLOWFISH_CBC,
SSH_3DES_CBC,
SSH_AES128_CBC,
SSH_AES192_CBC,
SSH_AES256_CBC,
SSH_AES128_CTR,
SSH_AES192_CTR,
SSH_AES256_CTR,
SSH_AEAD_AES128_GCM,
SSH_AEAD_AES256_GCM,
SSH_AEAD_CHACHA20_POLY1305
}; };
struct ssh_crypto_struct { struct ssh_crypto_struct {
bignum e,f,x,k,y; bignum e,f,x,k,y;
#ifdef HAVE_ECDH #ifdef HAVE_ECDH
#ifdef HAVE_OPENSSL_ECC
EC_KEY *ecdh_privkey; EC_KEY *ecdh_privkey;
#elif defined HAVE_GCRYPT_ECC
gcry_sexp_t ecdh_privkey;
#elif defined HAVE_LIBMBEDCRYPTO
mbedtls_ecp_keypair *ecdh_privkey;
#endif
ssh_string ecdh_client_pubkey; ssh_string ecdh_client_pubkey;
ssh_string ecdh_server_pubkey; ssh_string ecdh_server_pubkey;
#endif #endif
@@ -117,11 +79,10 @@ struct ssh_crypto_struct {
unsigned char *encryptkey; unsigned char *encryptkey;
unsigned char *encryptMAC; unsigned char *encryptMAC;
unsigned char *decryptMAC; unsigned char *decryptMAC;
unsigned char hmacbuf[DIGEST_MAX_LEN]; unsigned char hmacbuf[EVP_MAX_MD_SIZE];
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */ struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */ ssh_string server_pubkey;
const char *server_pubkey_type;
ssh_key server_pubkey;
int do_compress_out; /* idem */ int do_compress_out; /* idem */
int do_compress_in; /* don't set them, set the option instead */ int do_compress_in; /* don't set them, set the option instead */
int delayed_compress_in; /* Use of zlib@openssh.org */ int delayed_compress_in; /* Use of zlib@openssh.org */
@@ -139,49 +100,22 @@ struct ssh_crypto_struct {
struct ssh_cipher_struct { struct ssh_cipher_struct {
const char *name; /* ssh name of the algorithm */ const char *name; /* ssh name of the algorithm */
unsigned int blocksize; /* blocksize of the algo */ unsigned int blocksize; /* blocksize of the algo */
enum ssh_cipher_e ciphertype; unsigned int keylen; /* length of the key structure */
uint32_t lenfield_blocksize; /* blocksize of the packet length field */
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; void *key; /* a key buffer allocated for the algo */
struct ssh_aes_key_schedule *aes_key; void *IV;
const EVP_CIPHER *cipher;
EVP_CIPHER_CTX *ctx;
#elif defined HAVE_LIBMBEDCRYPTO
mbedtls_cipher_context_t encrypt_ctx;
mbedtls_cipher_context_t decrypt_ctx;
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;
unsigned int keysize; /* bytes of key used. != keylen */ unsigned int keysize; /* bytes of key used. != keylen */
size_t tag_size; /* overhead required for tag */
/* 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 (*cbc_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
void *in, unsigned long len);
void *out, void (*cbc_decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
size_t len); unsigned long 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,
size_t len, uint8_t *mac, uint64_t seq);
int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,
uint8_t *out, size_t len, uint64_t seq);
int (*aead_decrypt)(struct ssh_cipher_struct *cipher, void *complete_packet, uint8_t *out,
size_t encrypted_size, uint64_t seq);
void (*cleanup)(struct ssh_cipher_struct *cipher);
}; };
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void); /* vim: set ts=2 sw=2 et cindent: */
#endif /* _CRYPTO_H_ */ #endif /* _CRYPTO_H_ */

View File

@@ -25,37 +25,31 @@
#include "libssh/crypto.h" #include "libssh/crypto.h"
int ssh_dh_generate_e(ssh_session session); void ssh_print_bignum(const char *which,bignum num);
int ssh_dh_generate_f(ssh_session session); int dh_generate_e(ssh_session session);
int ssh_dh_generate_x(ssh_session session); int dh_generate_f(ssh_session session);
int ssh_dh_generate_y(ssh_session session); int dh_generate_x(ssh_session session);
int dh_generate_y(ssh_session session);
int ssh_dh_init(void); int ssh_crypto_init(void);
void ssh_dh_finalize(void); void ssh_crypto_finalize(void);
ssh_string ssh_dh_get_e(ssh_session session); ssh_string dh_get_e(ssh_session session);
ssh_string ssh_dh_get_f(ssh_session session); ssh_string dh_get_f(ssh_session session);
int ssh_dh_import_f(ssh_session session,ssh_string f_string); int dh_import_f(ssh_session session,ssh_string f_string);
int ssh_dh_import_e(ssh_session session, ssh_string e_string); int dh_import_e(ssh_session session, ssh_string e_string);
void dh_import_pubkey(ssh_session session,ssh_string pubkey_string);
int ssh_dh_import_pubkey_blob(ssh_session session, ssh_string pubkey_blob); int dh_build_k(ssh_session session);
int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
int ssh_dh_build_k(ssh_session session);
int ssh_client_dh_init(ssh_session session); int ssh_client_dh_init(ssh_session session);
int ssh_client_dh_reply(ssh_session session, ssh_buffer packet); int ssh_client_dh_reply(ssh_session session, ssh_buffer packet);
ssh_key ssh_dh_get_current_server_publickey(ssh_session session); int make_sessionid(ssh_session session);
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
ssh_string *pubkey_blob);
ssh_key ssh_dh_get_next_server_publickey(ssh_session session);
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
ssh_string *pubkey_blob);
int ssh_make_sessionid(ssh_session session);
/* add data for the final cookie */ /* add data for the final cookie */
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie); int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int ssh_hashbufout_add_cookie(ssh_session session); int hashbufout_add_cookie(ssh_session session);
int ssh_generate_session_keys(ssh_session session); int generate_session_keys(ssh_session session);
bignum make_string_bn(ssh_string string);
ssh_string make_bignum_string(bignum num);
#endif /* DH_H_ */ #endif /* DH_H_ */

View File

@@ -33,20 +33,8 @@
#endif /* HAVE_OPENSSL_ECDH_H */ #endif /* HAVE_OPENSSL_ECDH_H */
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
#ifdef HAVE_GCRYPT_ECC
#define HAVE_ECDH 1
#endif
#ifdef HAVE_LIBMBEDCRYPTO
#define HAVE_ECDH 1
#endif
/* Common functions. */
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
/* Backend-specific functions. */
int ssh_client_ecdh_init(ssh_session session); int ssh_client_ecdh_init(ssh_session session);
int ecdh_build_k(ssh_session session); int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
#ifdef WITH_SERVER #ifdef WITH_SERVER
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet); int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet);

View File

@@ -1,79 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2014 by Aris Adamantiadis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ED25519_H_
#define ED25519_H_
#include "libssh/priv.h"
/**
* @defgroup ed25519 ed25519 API
* @internal
* @brief API for DJB's ed25519
*
* @{ */
#define ED25519_PK_LEN 32
#define ED25519_SK_LEN 64
#define ED25519_SIG_LEN 64
typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
/** @internal
* @brief generate an ed25519 key pair
* @param[out] pk generated public key
* @param[out] sk generated secret key
* @return 0 on success, -1 on error.
* */
int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
/** @internal
* @brief sign a message with ed25519
* @param[out] sm location to store the signed message.
* Its length should be mlen + 64.
* @param[out] smlen pointer to the size of the signed message
* @param[in] m message to be signed
* @param[in] mlen length of the message to be signed
* @param[in] sk secret key to sign the message with
* @return 0 on success.
*/
int crypto_sign_ed25519(
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
const ed25519_privkey sk);
/** @internal
* @brief "open" and verify the signature of a signed message
* @param[out] m location to store the verified message.
* Its length should be equal to smlen.
* @param[out] mlen pointer to the size of the verified message
* @param[in] sm signed message to verify
* @param[in] smlen length of the signed message to verify
* @param[in] pk public key used to sign the message
* @returns 0 on success (supposedly).
*/
int crypto_sign_ed25519_open(
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
const ed25519_pubkey pk);
/** @} */
#endif /* ED25519_H_ */

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