mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Compare commits
378 Commits
ed52c88a03
...
libssh-0.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da6d026c12 | ||
|
|
240bda21dc | ||
|
|
f3652f6da0 | ||
|
|
d3060bc84e | ||
|
|
948bcb773e | ||
|
|
64b3e358f9 | ||
|
|
2422081e55 | ||
|
|
a10aeb9490 | ||
|
|
a629f687cd | ||
|
|
2dda3514d1 | ||
|
|
c954ff4b2c | ||
|
|
7609ac60a1 | ||
|
|
2356152329 | ||
|
|
180cfd0799 | ||
|
|
3e51232c69 | ||
|
|
d8fea02d2b | ||
|
|
265b826f78 | ||
|
|
c2c5604077 | ||
|
|
51a0adfc18 | ||
|
|
b78db5f5d8 | ||
|
|
5e2a2be6cd | ||
|
|
7cf3866744 | ||
|
|
81b17de7f7 | ||
|
|
a2a79ec68a | ||
|
|
08f96dcca6 | ||
|
|
435f45291d | ||
|
|
09e9167329 | ||
|
|
effb421a88 | ||
|
|
098ae8c4bd | ||
|
|
04824e2f5e | ||
|
|
0a5b93e479 | ||
|
|
761a4d5fa2 | ||
|
|
bd9a4e2498 | ||
|
|
67b7b383b2 | ||
|
|
1736cb0567 | ||
|
|
36e56dcd93 | ||
|
|
f834e10a47 | ||
|
|
deb9fc015e | ||
|
|
f8314af85a | ||
|
|
1fc8266fcb | ||
|
|
0cceefd49d | ||
|
|
8af24251c1 | ||
|
|
645106a1ca | ||
|
|
6672a457fb | ||
|
|
737ba4a680 | ||
|
|
d4b07d1675 | ||
|
|
d462cc30c9 | ||
|
|
c7f35f4d49 | ||
|
|
6a1dc7df87 | ||
|
|
41e54ce042 | ||
|
|
a7c0ccd35e | ||
|
|
9ec6923479 | ||
|
|
d9e37c4e09 | ||
|
|
56ebe3c7d0 | ||
|
|
e0c7d78a39 | ||
|
|
74e162c67f | ||
|
|
039054ea6e | ||
|
|
1da78553dc | ||
|
|
c5dfc2d5ce | ||
|
|
f760781cb8 | ||
|
|
8316bf1177 | ||
|
|
e631ebb3e2 | ||
|
|
dcc0b9d7aa | ||
|
|
b1bbd20dfa | ||
|
|
929a6b7d50 | ||
|
|
88d676cf1a | ||
|
|
b93c9ae641 | ||
|
|
a77d89d3ea | ||
|
|
4276560680 | ||
|
|
a7ce241652 | ||
|
|
1c7cfaba9c | ||
|
|
98c91e68fa | ||
|
|
078cb4c6f3 | ||
|
|
5972d7a98e | ||
|
|
d35fdfbdb4 | ||
|
|
7ee7ff94ba | ||
|
|
c42aab0122 | ||
|
|
69e97057c7 | ||
|
|
3025eeace3 | ||
|
|
ffb0007768 | ||
|
|
a99b8a3979 | ||
|
|
0a450f0251 | ||
|
|
9e9df61244 | ||
|
|
958afb1c6a | ||
|
|
e510de0315 | ||
|
|
34c596182d | ||
|
|
1a18d9cce2 | ||
|
|
4c83d19c48 | ||
|
|
673bf1ff09 | ||
|
|
fe1fe49617 | ||
|
|
316f46f833 | ||
|
|
0dd71375e7 | ||
|
|
9a10cef920 | ||
|
|
6fcd0940e3 | ||
|
|
0c8dbf5c81 | ||
|
|
a0aa62fffe | ||
|
|
402c922a9e | ||
|
|
112e32ba86 | ||
|
|
e2c5f5c7d1 | ||
|
|
6dcfa25c9b | ||
|
|
eed8d8e957 | ||
|
|
1935e15cd4 | ||
|
|
238dbabef8 | ||
|
|
ee7ee2404a | ||
|
|
6205cad534 | ||
|
|
d5a37e2bf5 | ||
|
|
226d2a16b0 | ||
|
|
46105f4aa6 | ||
|
|
62f7004d5a | ||
|
|
d7358ee5a7 | ||
|
|
ec8cedd803 | ||
|
|
92124ae65a | ||
|
|
ea198fee43 | ||
|
|
393cd36c01 | ||
|
|
93bf0ab6a3 | ||
|
|
251f60c031 | ||
|
|
b33dcda94d | ||
|
|
f0335d1b59 | ||
|
|
ed87c2221c | ||
|
|
ac2f4853bb | ||
|
|
64ce53fdba | ||
|
|
295739e0c8 | ||
|
|
101ffd70a7 | ||
|
|
45878b131c | ||
|
|
21adb54dc6 | ||
|
|
13fa009a2e | ||
|
|
8600015b3e | ||
|
|
8f20ece14f | ||
|
|
d15fa16213 | ||
|
|
a91e5f7585 | ||
|
|
7b7b2acd23 | ||
|
|
1c66217875 | ||
|
|
95eb071c22 | ||
|
|
d117de188f | ||
|
|
ae68f13a78 | ||
|
|
ad49f0a556 | ||
|
|
975eb87c19 | ||
|
|
a888b65ff5 | ||
|
|
375724bafe | ||
|
|
b7b9c6d5b9 | ||
|
|
1c7efb7b46 | ||
|
|
128fb03d7e | ||
|
|
994b653161 | ||
|
|
9817d13de0 | ||
|
|
41cd5f4012 | ||
|
|
e6fdb28faf | ||
|
|
b21cba0c3c | ||
|
|
7498167e6c | ||
|
|
f1b1355975 | ||
|
|
83a8c87b08 | ||
|
|
48c34509f2 | ||
|
|
0469458194 | ||
|
|
d0dc57be06 | ||
|
|
7f7c249e15 | ||
|
|
a64aa7406b | ||
|
|
81650a7652 | ||
|
|
26a29ee362 | ||
|
|
7f5d851f6e | ||
|
|
b1f4b6ffec | ||
|
|
1788f98543 | ||
|
|
413ee92572 | ||
|
|
d6664d248b | ||
|
|
14e19ee37e | ||
|
|
7fe7203f06 | ||
|
|
02ed74711f | ||
|
|
55cbb64f44 | ||
|
|
acc109eb67 | ||
|
|
54e7c8d21a | ||
|
|
a8b2a874de | ||
|
|
deaf3f3195 | ||
|
|
123e8448e6 | ||
|
|
ba563611ee | ||
|
|
69b4860404 | ||
|
|
564e298989 | ||
|
|
5a41514d8d | ||
|
|
8f0ab53b7b | ||
|
|
0016888942 | ||
|
|
ce045cf5ed | ||
|
|
5ae2a05ca1 | ||
|
|
8dcaf4bfa3 | ||
|
|
6c392befcc | ||
|
|
5b55eefb96 | ||
|
|
9fc8e095ce | ||
|
|
65918ec38a | ||
|
|
2caedc0d0d | ||
|
|
0187b71912 | ||
|
|
053a23b50d | ||
|
|
2b52a8df4d | ||
|
|
fa33b61102 | ||
|
|
563e1fc821 | ||
|
|
f6c8e87c3e | ||
|
|
0ff2cfe0e6 | ||
|
|
828f8dd106 | ||
|
|
5f5a6e15b3 | ||
|
|
e5b403f83a | ||
|
|
11cb618c75 | ||
|
|
338e6cece5 | ||
|
|
4603105e0b | ||
|
|
ee1f8512a4 | ||
|
|
278ed59501 | ||
|
|
9e9d35164b | ||
|
|
a011f853ed | ||
|
|
c98d024b9a | ||
|
|
d5b10f569d | ||
|
|
31f65d1ffb | ||
|
|
44e37c2546 | ||
|
|
35188b3843 | ||
|
|
76aeedad1b | ||
|
|
66419896f7 | ||
|
|
0cb50ef31a | ||
|
|
88e40516c9 | ||
|
|
f45aa46322 | ||
|
|
dbf757e3e8 | ||
|
|
0a404349bc | ||
|
|
e9b74b5cb7 | ||
|
|
6a0cbc73bd | ||
|
|
40ee7d2b38 | ||
|
|
7db565601d | ||
|
|
95faeb498f | ||
|
|
db97435a41 | ||
|
|
c72a3495d0 | ||
|
|
f2487f07f5 | ||
|
|
675d85e538 | ||
|
|
dfd73d7cb2 | ||
|
|
db68813cb9 | ||
|
|
affb43a45f | ||
|
|
1e71951a51 | ||
|
|
297aed60c4 | ||
|
|
4e5dfd677e | ||
|
|
34fd4ebfc3 | ||
|
|
0080ac1f03 | ||
|
|
dd4eb4a288 | ||
|
|
a967258649 | ||
|
|
e0e3636c60 | ||
|
|
c0e5393927 | ||
|
|
36bdcb85b3 | ||
|
|
cf34ba92bf | ||
|
|
f5f547f35e | ||
|
|
1eed0cbd3d | ||
|
|
1668bd8baf | ||
|
|
245be62438 | ||
|
|
8ce782f9ec | ||
|
|
db34fd44fb | ||
|
|
00dd3f864b | ||
|
|
52550994c5 | ||
|
|
182d363b27 | ||
|
|
f9189a8a9a | ||
|
|
56c079cbb2 | ||
|
|
ab24d64241 | ||
|
|
7856ae594b | ||
|
|
eeb9ae15c7 | ||
|
|
8837d32d92 | ||
|
|
0408d8d851 | ||
|
|
bab8d84d13 | ||
|
|
6ee159d9d2 | ||
|
|
71ff06d04a | ||
|
|
7851f216af | ||
|
|
9b316fe8b9 | ||
|
|
389efc234b | ||
|
|
f1e44a79a9 | ||
|
|
54cf7b92ed | ||
|
|
f0b676a9f0 | ||
|
|
cc190b21b2 | ||
|
|
a775324c35 | ||
|
|
5de765ebd5 | ||
|
|
9de970160d | ||
|
|
8a7abf2480 | ||
|
|
920c08eaf8 | ||
|
|
c0fa85a43d | ||
|
|
be16481be2 | ||
|
|
c4ac076607 | ||
|
|
ff534bc2fe | ||
|
|
27096c3c0f | ||
|
|
8a6ddc0a48 | ||
|
|
0c951b9f27 | ||
|
|
37529f16a8 | ||
|
|
e89106b9f7 | ||
|
|
67c0ce3d21 | ||
|
|
f618689c82 | ||
|
|
aaeaca8c6e | ||
|
|
58c26f4823 | ||
|
|
c888d9c690 | ||
|
|
07df7bb4e6 | ||
|
|
5aecfb5a96 | ||
|
|
50b37f2991 | ||
|
|
a47a291303 | ||
|
|
f199bd4879 | ||
|
|
4f7cb6076a | ||
|
|
3f6820694e | ||
|
|
0da6597fe4 | ||
|
|
0a13045f68 | ||
|
|
b56ffd8424 | ||
|
|
c60ac3fe02 | ||
|
|
84eab65edc | ||
|
|
7c3e37bf4c | ||
|
|
ab9921ee6a | ||
|
|
9296bcd4bb | ||
|
|
24f39761f3 | ||
|
|
49e8a4ef19 | ||
|
|
d7e1141c1e | ||
|
|
fd5c598477 | ||
|
|
de4034bfe0 | ||
|
|
6ccd84bae9 | ||
|
|
e4c281c7ce | ||
|
|
93541fe150 | ||
|
|
e6ba98a0aa | ||
|
|
6dcb960501 | ||
|
|
fcacc7fe8c | ||
|
|
f078f53911 | ||
|
|
27f5bfd129 | ||
|
|
4a0cbe396d | ||
|
|
a1812e9ac1 | ||
|
|
0e3dbd6c69 | ||
|
|
d2af62624d | ||
|
|
93113ccfb9 | ||
|
|
9ffaa12012 | ||
|
|
ae5146f7ba | ||
|
|
dd554ebb32 | ||
|
|
fae61f1d09 | ||
|
|
9e8e5f5cb2 | ||
|
|
80c1dbdb61 | ||
|
|
4505c076b3 | ||
|
|
99dc2002b9 | ||
|
|
878d8320c1 | ||
|
|
80e729fe33 | ||
|
|
47945671af | ||
|
|
b2e7ef6836 | ||
|
|
651fea9f14 | ||
|
|
f10db964b5 | ||
|
|
703f0a0f36 | ||
|
|
7b8d57fbb6 | ||
|
|
8e793d930e | ||
|
|
cc2feabe73 | ||
|
|
4d57d73faf | ||
|
|
4bd9041afb | ||
|
|
74e084f76c | ||
|
|
6c80718c0d | ||
|
|
a330806e4b | ||
|
|
3b01c328ab | ||
|
|
5b981a9e3d | ||
|
|
36dc66da81 | ||
|
|
2a3718de51 | ||
|
|
1fd68ec732 | ||
|
|
fa3caa61fd | ||
|
|
aaa978ad06 | ||
|
|
b9530cedbe | ||
|
|
7ff0af7543 | ||
|
|
b040856ccf | ||
|
|
79900e5246 | ||
|
|
63b0399373 | ||
|
|
39665fd9c5 | ||
|
|
83f0be1f04 | ||
|
|
3bc5f88f77 | ||
|
|
466ca07626 | ||
|
|
b6e757d692 | ||
|
|
3f2375e948 | ||
|
|
4d06c2f283 | ||
|
|
0298bfbbf0 | ||
|
|
2399a9f8de | ||
|
|
79756c5c56 | ||
|
|
e8510043d2 | ||
|
|
1f7889f271 | ||
|
|
89efd56217 | ||
|
|
e3fca31c59 | ||
|
|
d71a7976dd | ||
|
|
8fe8d13e29 | ||
|
|
722f979790 | ||
|
|
2c60ef04d9 | ||
|
|
ec486d13db | ||
|
|
ebfe46f6ad | ||
|
|
3c0897b975 | ||
|
|
993e0df81e | ||
|
|
551188d99b | ||
|
|
cafafe8f5a | ||
|
|
c6c7856b51 | ||
|
|
ea71af9c22 | ||
|
|
bb98413fc1 | ||
|
|
2a8cd81e8f |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,8 @@
|
||||
*.swp
|
||||
*~$
|
||||
cscope.*
|
||||
compile_commands.json
|
||||
/.clangd
|
||||
tags
|
||||
/build
|
||||
/obj*
|
||||
|
||||
128
.gitlab-ci.yml
128
.gitlab-ci.yml
@@ -4,9 +4,8 @@ variables:
|
||||
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
|
||||
# pkd tests fail on CentOS7 docker images, so we don't use -DSERVER_TESTING=ON
|
||||
centos7/openssl_1.0.x/x86_64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
|
||||
script:
|
||||
@@ -14,7 +13,7 @@ centos7/openssl_1.0.x/x86_64:
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -34,6 +33,7 @@ fedora/openssl_1.1.x/x86_64:
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_BLOWFISH_CIPHER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DWITH_DEBUG_CRYPTO=ON
|
||||
-DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
@@ -153,6 +153,8 @@ fedora/undefined-sanitizer:
|
||||
- obj/
|
||||
|
||||
fedora/csbuild:
|
||||
variables:
|
||||
GIT_DEPTH: "100"
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- |
|
||||
@@ -168,8 +170,7 @@ fedora/csbuild:
|
||||
|
||||
- csbuild
|
||||
--build-dir=obj-csbuild
|
||||
--prep-cmd="rm -rf CMakeFiles CMakeCache.txt && 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)"
|
||||
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON @SRCDIR@ && make clean && make -j$(nproc)"
|
||||
--git-commit-range $CI_COMMIT_RANGE
|
||||
--color
|
||||
--print-current --print-fixed
|
||||
@@ -196,11 +197,13 @@ freebsd/x86_64:
|
||||
make && ctest --output-on-failure
|
||||
tags:
|
||||
- freebsd
|
||||
- private
|
||||
except:
|
||||
- tags
|
||||
only:
|
||||
- branches@libssh/libssh-mirror
|
||||
- branches@cryptomilk/libssh-mirror
|
||||
- branches@jjelen/libssh-mirror
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
@@ -215,7 +218,7 @@ fedora/libgcrypt/x86_64:
|
||||
-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 .. &&
|
||||
-DWITH_GCRYPT=ON -DWITH_DEBUG_CRYPTO=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -235,7 +238,7 @@ fedora/mbedtls/x86_64:
|
||||
-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 .. &&
|
||||
-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -295,33 +298,6 @@ fedora/mingw32:
|
||||
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:
|
||||
@@ -330,7 +306,7 @@ tumbleweed/openssl_1.1.x/x86_64/gcc:
|
||||
-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 .. &&
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -371,7 +347,7 @@ tumbleweed/openssl_1.1.x/x86_64/gcc7:
|
||||
-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 .. &&
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -413,7 +389,8 @@ tumbleweed/openssl_1.1.x/x86_64/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 .. &&
|
||||
-DUNIT_TESTING=ON
|
||||
-DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -446,7 +423,7 @@ tumbleweed/undefined-sanitizer:
|
||||
-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 .. &&
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -468,7 +445,7 @@ tumbleweed/static-analysis:
|
||||
-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 .. &&
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
scan-build --status-bugs -o scan make -j$(nproc)
|
||||
tags:
|
||||
- shared
|
||||
@@ -480,10 +457,20 @@ tumbleweed/static-analysis:
|
||||
paths:
|
||||
- obj/scan
|
||||
|
||||
visualstudio/x86_64:
|
||||
###############################################################################
|
||||
# Visual Studio builds #
|
||||
###############################################################################
|
||||
.vs:
|
||||
stage: test
|
||||
cache:
|
||||
key: vcpkg.${CI_JOB_NAME}
|
||||
paths:
|
||||
- .vcpkg
|
||||
variables:
|
||||
ErrorActionPreference: STOP
|
||||
script:
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="x64-windows"
|
||||
- cd obj
|
||||
- mkdir -p obj; if ($?) {cd obj}; if (! $?) {exit 1}
|
||||
- cmake
|
||||
-A x64
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
|
||||
@@ -493,44 +480,45 @@ visualstudio/x86_64:
|
||||
- cmake --build .
|
||||
- ctest --output-on-failure
|
||||
tags:
|
||||
- vs2017
|
||||
- windows
|
||||
- shared-windows
|
||||
except:
|
||||
- tags
|
||||
only:
|
||||
- branches@libssh/libssh-mirror
|
||||
- branches@ansasaki/libssh-mirror
|
||||
- branches@cryptomilk/libssh-mirror
|
||||
- branches@jjelen/libssh-mirror
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
visualstudio/x86:
|
||||
script:
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="x86-windows"
|
||||
- cd obj
|
||||
before_script:
|
||||
- choco install --no-progress -y cmake
|
||||
- $env:Path += ';C:\Program Files\CMake\bin'
|
||||
- If (!(test-path .vcpkg\archives)) { mkdir -p .vcpkg\archives }
|
||||
- $env:VCPKG_DEFAULT_BINARY_CACHE="$PWD\.vcpkg\archives"
|
||||
- echo $env:VCPKG_DEFAULT_BINARY_CACHE
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="$TRIPLET-windows"
|
||||
- vcpkg install cmocka
|
||||
- vcpkg install openssl
|
||||
- vcpkg install zlib
|
||||
- vcpkg integrate install
|
||||
- mkdir -p obj; if ($?) {cd obj}; if (! $?) {exit 1}
|
||||
- cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
|
||||
-A $PLATFORM
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
-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
|
||||
- branches@jjelen/libssh-mirror
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
# The Windows runners are broken for last month
|
||||
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/-/issues/40
|
||||
allow_failure: true
|
||||
|
||||
visualstudio/x86_64:
|
||||
extends: .vs
|
||||
variables:
|
||||
PLATFORM: "x64"
|
||||
TRIPLET: "x64"
|
||||
|
||||
visualstudio/x86:
|
||||
extends: .vs
|
||||
variables:
|
||||
PLATFORM: "win32"
|
||||
TRIPLET: "x86"
|
||||
|
||||
@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
|
||||
project(libssh VERSION 0.8.90 LANGUAGES C)
|
||||
project(libssh VERSION 0.9.6 LANGUAGES C)
|
||||
|
||||
# global needed variable
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
@@ -22,16 +22,16 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
# Increment AGE. Set REVISION to 0
|
||||
# If the source code was changed, but there were no interface changes:
|
||||
# Increment REVISION.
|
||||
set(LIBRARY_VERSION "4.8.1")
|
||||
set(LIBRARY_VERSION "4.8.7")
|
||||
set(LIBRARY_SOVERSION "4")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
|
||||
# add definitions
|
||||
include(DefinePlatformDefaults)
|
||||
include(DefineInstallationPaths)
|
||||
include(DefineOptions.cmake)
|
||||
include(CPackConfig.cmake)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
include(CompilerChecks.cmake)
|
||||
|
||||
@@ -59,7 +59,13 @@ elseif(WITH_MBEDTLS)
|
||||
endif (NOT MBEDTLS_FOUND)
|
||||
else (WITH_GCRYPT)
|
||||
find_package(OpenSSL)
|
||||
if (NOT OPENSSL_FOUND)
|
||||
if (OPENSSL_FOUND)
|
||||
# On CMake < 3.16, OPENSSL_CRYPTO_LIBRARIES is usually a synonym for OPENSSL_CRYPTO_LIBRARY, but is not defined
|
||||
# when building on Windows outside of Cygwin. We provide the synonym here, if FindOpenSSL didn't define it already.
|
||||
if (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
|
||||
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
endif (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
|
||||
else (OPENSSL_FOUND)
|
||||
find_package(GCrypt)
|
||||
if (NOT GCRYPT_FOUND)
|
||||
find_package(MbedTLS)
|
||||
@@ -67,7 +73,7 @@ else (WITH_GCRYPT)
|
||||
message(FATAL_ERROR "Could not find OpenSSL, GCrypt or mbedTLS")
|
||||
endif (NOT MBEDTLS_FOUND)
|
||||
endif (NOT GCRYPT_FOUND)
|
||||
endif (NOT OPENSSL_FOUND)
|
||||
endif (OPENSSL_FOUND)
|
||||
endif(WITH_GCRYPT)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
@@ -117,7 +123,7 @@ install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/pkgconfig
|
||||
${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
COMPONENT
|
||||
pkgconfig
|
||||
)
|
||||
@@ -133,21 +139,13 @@ write_basic_package_version_file(libssh-config-version.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
# libssh-config.cmake
|
||||
configure_package_config_file(${PROJECT_NAME}-config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||
PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
||||
COMPONENT
|
||||
devel
|
||||
)
|
||||
devel)
|
||||
|
||||
if (WITH_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
@@ -211,7 +209,12 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
|
||||
endif(UPDATE_ABI)
|
||||
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
|
||||
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET})
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET} VERBATIM)
|
||||
|
||||
# Link compile database for clangd
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
"${CMAKE_BINARY_DIR}/compile_commands.json"
|
||||
"${CMAKE_SOURCE_DIR}/compile_commands.json")
|
||||
|
||||
message(STATUS "********************************************")
|
||||
message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
||||
@@ -225,7 +228,7 @@ message(STATUS "Server support : ${WITH_SERVER}")
|
||||
message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
|
||||
message(STATUS "GEX support : ${WITH_GEX}")
|
||||
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
|
||||
message(STATUS "With static library: ${WITH_STATIC_LIB}")
|
||||
message(STATUS "Build shared library: ${BUILD_SHARED_LIBS}")
|
||||
message(STATUS "Unit testing: ${UNIT_TESTING}")
|
||||
message(STATUS "Client code testing: ${CLIENT_TESTING}")
|
||||
message(STATUS "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
|
||||
|
||||
@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
# SOURCE GENERATOR
|
||||
set(CPACK_SOURCE_GENERATOR "TXZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;/[.]clangd/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
### NSIS INSTALLER
|
||||
@@ -23,7 +23,7 @@ if (WIN32)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
|
||||
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||
set(CPACK_NSIS_MENU_LINKS "https://www.libssh.org/" "libssh homepage")
|
||||
endif (NSIS_MAKE)
|
||||
endif (WIN32)
|
||||
|
||||
|
||||
135
ChangeLog
135
ChangeLog
@@ -1,7 +1,74 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
version 0.9.0 (released 2019-02-xx)
|
||||
version 0.9.6 (released 2021-08-26)
|
||||
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with
|
||||
different key exchange mechanism
|
||||
* Fix several memory leaks on error paths
|
||||
* Reset pending_call_state on disconnect
|
||||
* Fix handshake bug with AEAD ciphers and no HMAC overlap
|
||||
* Use OPENSSL_CRYPTO_LIBRARIES in CMake
|
||||
* Ignore request success and failure message if they are not expected
|
||||
* Support more identity files in configuration
|
||||
* Avoid setting compiler flags directly in CMake
|
||||
* Support build directories with special characters
|
||||
* Include stdlib.h to avoid crash in Windows
|
||||
* Fix sftp_new_channel constructs an invalid object
|
||||
* Fix Ninja multiple rules error
|
||||
* Several tests fixes
|
||||
|
||||
version 0.9.5 (released 2020-09-10)
|
||||
* CVE-2020-16135: Avoid null pointer dereference in sftpserver (T232)
|
||||
* Improve handling of library initialization (T222)
|
||||
* Fix parsing of subsecond times in SFTP (T219)
|
||||
* Make the documentation reproducible
|
||||
* Remove deprecated API usage in OpenSSL
|
||||
* Fix regression of ssh_channel_poll_timeout() returning SSH_AGAIN
|
||||
* Define version in one place (T226)
|
||||
* Prevent invalid free when using different C runtimes than OpenSSL (T229)
|
||||
* Compatibility improvements to testsuite
|
||||
|
||||
version 0.9.4 (released 2020-04-09)
|
||||
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
|
||||
AES-CTR keys with OpenSSL
|
||||
* Added diffie-hellman-group14-sha256
|
||||
* Fixed serveral possible memory leaks
|
||||
|
||||
version 0.9.3 (released 2019-12-10)
|
||||
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
|
||||
* SSH-01-003 Client: Missing NULL check leads to crash in erroneous state
|
||||
* SSH-01-006 General: Various unchecked Null-derefs cause DOS
|
||||
* SSH-01-007 PKI Gcrypt: Potential UAF/double free with RSA pubkeys
|
||||
* SSH-01-010 SSH: Deprecated hash function in fingerprinting
|
||||
* SSH-01-013 Conf-Parsing: Recursive wildcards in hostnames lead to DOS
|
||||
* SSH-01-014 Conf-Parsing: Integer underflow leads to OOB array access
|
||||
* SSH-01-001 State Machine: Initial machine states should be set explicitly
|
||||
* SSH-01-002 Kex: Differently bound macros used to iterate same array
|
||||
* SSH-01-005 Code-Quality: Integer sign confusion during assignments
|
||||
* SSH-01-008 SCP: Protocol Injection via unescaped File Names
|
||||
* SSH-01-009 SSH: Update documentation which RFCs are implemented
|
||||
* SSH-01-012 PKI: Information leak via uninitialized stack buffer
|
||||
|
||||
version 0.9.2 (released 2019-11-07)
|
||||
* Fixed libssh-config.cmake
|
||||
* Fixed issues with rsa algorithm negotiation (T191)
|
||||
* Fixed detection of OpenSSL ed25519 support (T197)
|
||||
|
||||
version 0.9.1 (released 2019-10-25)
|
||||
* Added support for Ed25519 via OpenSSL
|
||||
* Added support for X25519 via OpenSSL
|
||||
* Added support for localuser in Match keyword
|
||||
* Fixed Match keyword to be case sensitive
|
||||
* Fixed compilation with LibreSSL
|
||||
* Fixed error report of channel open (T75)
|
||||
* Fixed sftp documentation (T137)
|
||||
* Fixed known_hosts parsing (T156)
|
||||
* Fixed build issue with MinGW (T157)
|
||||
* Fixed build with gcc 9 (T164)
|
||||
* Fixed deprecation issues (T165)
|
||||
* Fixed known_hosts directory creation (T166)
|
||||
|
||||
version 0.9.0 (released 2019-06-28)
|
||||
* Added support for AES-GCM
|
||||
* Added improved rekeying support
|
||||
* Added performance improvements
|
||||
@@ -11,10 +78,76 @@ version 0.9.0 (released 2019-02-xx)
|
||||
* Added support for Encrypt-then-MAC mode
|
||||
* Added support for parsing server side configuration file
|
||||
* Added support for ECDSA/Ed25519 certificates
|
||||
* Added FIPS 140-2 compatibility
|
||||
* Improved known_hosts parsing
|
||||
* Improved documentation
|
||||
* Improved OpenSSL API usage for KEX, DH, and signatures
|
||||
|
||||
version 0.8.7 (released 2019-02-25)
|
||||
* Fixed handling extension flags in the server implementation
|
||||
* Fixed exporting ed25519 private keys
|
||||
* Fixed corner cases for rsa-sha2 signatures
|
||||
* Fixed some issues with connector
|
||||
|
||||
version 0.8.6 (released 2018-12-24)
|
||||
* Fixed compilation issues with different OpenSSL versions
|
||||
* Fixed StrictHostKeyChecking in new knownhosts API
|
||||
* Fixed ssh_send_keepalive() with packet filter
|
||||
* Fixed possible crash with knownhosts options
|
||||
* Fixed issus with rekeying
|
||||
* Fixed strong ECDSA keys
|
||||
* Fixed some issues with rsa-sha2 extentions
|
||||
* Fixed access violation in ssh_init() (static linking)
|
||||
* Fixed ssh_channel_close() handling
|
||||
|
||||
version 0.8.5 (released 2018-10-29)
|
||||
* Added support to get known_hosts locations with ssh_options_get()
|
||||
* Fixed preferred algorithm for known hosts negotiations
|
||||
* Fixed KEX with some server implementations (e.g. Cisco)
|
||||
* Fixed issues with MSVC
|
||||
* Fixed keyboard-interactive auth in server mode
|
||||
(regression from CVE-2018-10933)
|
||||
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
|
||||
* Fixed socket fd handling with proxy command
|
||||
* Fixed a memory leak with OpenSSL
|
||||
|
||||
version 0.8.4 (released 2018-10-16)
|
||||
* Fixed CVE-2018-10933
|
||||
* Fixed building without globbing support
|
||||
* Fixed possible memory leaks
|
||||
* Avoid SIGPIPE on sockets
|
||||
|
||||
version 0.8.3 (released 2018-09-21)
|
||||
* Added support for rsa-sha2
|
||||
* Added support to parse private keys in openssh container format
|
||||
(other than ed25519)
|
||||
* Added support for diffie-hellman-group18-sha512 and
|
||||
diffie-hellman-group16-sha512
|
||||
* Added ssh_get_fingerprint_hash()
|
||||
* Added ssh_pki_export_privkey_base64()
|
||||
* Added support for Match keyword in config file
|
||||
* Improved performance and reduced memory footprint for sftp
|
||||
* Fixed ecdsa publickey auth
|
||||
* Fixed reading a closed channel
|
||||
* Added support to announce posix-rename@openssh.com and
|
||||
hardlink@openssh.com in the sftp server
|
||||
|
||||
version 0.8.2 (released 2018-08-30)
|
||||
* Added sha256 fingerprints for pubkeys
|
||||
* Improved compiler flag detection
|
||||
* Fixed race condition in reading sftp messages
|
||||
* Fixed doxygen generation and added modern style
|
||||
* Fixed library initialization on Windows
|
||||
* Fixed __bounded__ attribute detection
|
||||
* Fixed a bug in the options parser
|
||||
* Fixed documentation for new knwon_hosts API
|
||||
|
||||
version 0.8.1 (released 2018-08-13)
|
||||
* Fixed version number in the header
|
||||
* Fixed version number in pkg-config and cmake config
|
||||
* Fixed library initialization
|
||||
* Fixed attribute detection
|
||||
|
||||
version 0.8.0 (released 2018-08-10)
|
||||
* Removed support for deprecated SSHv1 protocol
|
||||
* Added new connector API for clients
|
||||
|
||||
@@ -42,6 +42,7 @@ if (UNIX)
|
||||
add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
|
||||
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
|
||||
add_c_compiler_flag("-Wmissing-field-initializers" SUPPORTED_COMPILER_FLAGS)
|
||||
add_c_compiler_flag("-Wsign-compare" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
|
||||
if (REQUIRED_FLAGS_WFORMAT)
|
||||
|
||||
@@ -9,10 +9,7 @@ include(TestBigEndian)
|
||||
|
||||
set(PACKAGE ${PROJECT_NAME})
|
||||
set(VERSION ${PROJECT_VERSION})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
set(LIBDIR ${LIB_INSTALL_DIR})
|
||||
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
set(SYSCONFDIR ${CMAKE_INSTALL_SYSCONFDIR})
|
||||
|
||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
||||
@@ -104,39 +101,64 @@ if (OPENSSL_FOUND)
|
||||
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_function_exists(EVP_DigestSign HAVE_OPENSSL_EVP_DIGESTSIGN)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_function_exists(EVP_DigestVerify HAVE_OPENSSL_EVP_DIGESTVERIFY)
|
||||
|
||||
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_symbol_exists(EVP_PKEY_ED25519 "openssl/evp.h" FOUND_OPENSSL_ED25519)
|
||||
|
||||
if (HAVE_OPENSSL_EVP_DIGESTSIGN AND HAVE_OPENSSL_EVP_DIGESTVERIFY AND
|
||||
FOUND_OPENSSL_ED25519)
|
||||
set(HAVE_OPENSSL_ED25519 1)
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
check_symbol_exists(EVP_PKEY_X25519 "openssl/evp.h" HAVE_OPENSSL_X25519)
|
||||
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
|
||||
@@ -2,7 +2,6 @@ option(WITH_GSSAPI "Build with GSSAPI support" ON)
|
||||
option(WITH_ZLIB "Build with ZLIB support" ON)
|
||||
option(WITH_SFTP "Build with SFTP support" ON)
|
||||
option(WITH_SERVER "Build with SSH server support" ON)
|
||||
option(WITH_STATIC_LIB "Build with a static library" OFF)
|
||||
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
|
||||
option(WITH_DEBUG_PACKET "Build with packet debug output" OFF)
|
||||
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
||||
@@ -11,6 +10,7 @@ option(WITH_MBEDTLS "Compile against libmbedtls" OFF)
|
||||
option(WITH_BLOWFISH_CIPHER "Compile with blowfish support" OFF)
|
||||
option(WITH_PCAP "Compile with Pcap generation support" ON)
|
||||
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
option(UNIT_TESTING "Build with unit tests" OFF)
|
||||
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF)
|
||||
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
|
||||
@@ -34,13 +34,9 @@ if (WITH_BENCHMARKS)
|
||||
set(CLIENT_TESTING ON)
|
||||
endif()
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
set(BUILD_STATIC_LIB ON)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
if (UNIT_TESTING OR CLIENT_TESTING OR SERVER_TESTING)
|
||||
set(BUILD_STATIC_LIB ON)
|
||||
endif (UNIT_TESTING)
|
||||
endif()
|
||||
|
||||
if (WITH_NACL)
|
||||
set(WITH_NACL ON)
|
||||
|
||||
10
INSTALL
10
INSTALL
@@ -7,11 +7,11 @@
|
||||
In order to build libssh, you need to install several components:
|
||||
|
||||
- A C compiler
|
||||
- [CMake](http://www.cmake.org) >= 2.6.0.
|
||||
- [openssl](http://www.openssl.org) >= 0.9.8
|
||||
- [CMake](https://www.cmake.org) >= 2.6.0.
|
||||
- [openssl](https://www.openssl.org) >= 0.9.8
|
||||
or
|
||||
- [gcrypt](http://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
|
||||
- [libz](http://www.zlib.net) >= 1.2
|
||||
- [gcrypt](https://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
|
||||
- [libz](https://www.zlib.net) >= 1.2
|
||||
|
||||
optional:
|
||||
- [cmocka](https://cmocka.org/) >= 1.1.0
|
||||
@@ -117,4 +117,4 @@ This document is written using [Markdown][] syntax, making it possible to
|
||||
provide usable information in both plain text and HTML format. Whenever
|
||||
modifying this document please use [Markdown][] syntax.
|
||||
|
||||
[markdown]: http://www.daringfireball.net/projects/markdown
|
||||
[markdown]: https://www.daringfireball.net/projects/markdown
|
||||
|
||||
2
README
2
README
@@ -31,7 +31,7 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
|
||||
3* Where ?
|
||||
-_-_-_-_-_-_
|
||||
|
||||
http://www.libssh.org
|
||||
https://www.libssh.org
|
||||
|
||||
4* Contributing
|
||||
-_-_-_-_-_-_-_-_-_
|
||||
|
||||
@@ -60,7 +60,7 @@ following to $HOME/.vimrc:
|
||||
|
||||
You can use the Vim gitmodline plugin to store this in the git config:
|
||||
|
||||
http://git.cryptomilk.org/projects/vim-gitmodeline.git/
|
||||
https://git.cryptomilk.org/projects/vim-gitmodeline.git/
|
||||
|
||||
For Vim, the following settings in $HOME/.vimrc will also deal with
|
||||
displaying trailing whitespace:
|
||||
|
||||
@@ -23,7 +23,7 @@ much easier to work with individuals who have ownership than corporate
|
||||
legal departments if we ever need to make reasonable compromises with
|
||||
people using and working with libssh.
|
||||
|
||||
We track the ownership of every part of libssh via http://git.libssh.org,
|
||||
We track the ownership of every part of libssh via https://git.libssh.org,
|
||||
our source code control system, so we know the provenance of every piece
|
||||
of code that is committed to libssh.
|
||||
|
||||
@@ -85,7 +85,7 @@ By making a contribution to this project, I certify that:
|
||||
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
|
||||
https://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
|
||||
We will maintain a copy of that email as a record that you have the
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
if (UNIX OR OS2)
|
||||
IF (NOT APPLICATION_NAME)
|
||||
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
|
||||
SET(APPLICATION_NAME ${PROJECT_NAME})
|
||||
ENDIF (NOT APPLICATION_NAME)
|
||||
|
||||
# Suffix for Linux
|
||||
SET(LIB_SUFFIX
|
||||
CACHE STRING "Define suffix of directory name (32/64)"
|
||||
)
|
||||
|
||||
SET(EXEC_INSTALL_PREFIX
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
CACHE PATH "Base directory for executables and libraries"
|
||||
)
|
||||
SET(SHARE_INSTALL_PREFIX
|
||||
"${CMAKE_INSTALL_PREFIX}/share"
|
||||
CACHE PATH "Base directory for files which go to share/"
|
||||
)
|
||||
SET(DATA_INSTALL_PREFIX
|
||||
"${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}"
|
||||
CACHE PATH "The parent directory where applications can install their data")
|
||||
|
||||
# The following are directories where stuff will be installed to
|
||||
SET(BIN_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/bin"
|
||||
CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)"
|
||||
)
|
||||
SET(SBIN_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/sbin"
|
||||
CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)"
|
||||
)
|
||||
SET(LIB_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)"
|
||||
)
|
||||
SET(LIBEXEC_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/libexec"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
|
||||
)
|
||||
SET(PLUGIN_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/${APPLICATION_NAME}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})"
|
||||
)
|
||||
SET(INCLUDE_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_PREFIX}/include"
|
||||
CACHE PATH "The subdirectory to the header prefix (default prefix/include)"
|
||||
)
|
||||
|
||||
set(CMAKE_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/cmake"
|
||||
CACHE PATH "The subdirectory to install cmake config files")
|
||||
|
||||
SET(DATA_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}"
|
||||
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})"
|
||||
)
|
||||
SET(HTML_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/doc/HTML"
|
||||
CACHE PATH "The HTML install dir for documentation (default data/doc/html)"
|
||||
)
|
||||
SET(ICON_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/icons"
|
||||
CACHE PATH "The icon install dir (default data/icons/)"
|
||||
)
|
||||
SET(SOUND_INSTALL_DIR
|
||||
"${DATA_INSTALL_PREFIX}/sounds"
|
||||
CACHE PATH "The install dir for sound files (default data/sounds)"
|
||||
)
|
||||
|
||||
SET(LOCALE_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/locale"
|
||||
CACHE PATH "The install dir for translations (default prefix/share/locale)"
|
||||
)
|
||||
|
||||
SET(XDG_APPS_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/applications/"
|
||||
CACHE PATH "The XDG apps dir"
|
||||
)
|
||||
SET(XDG_DIRECTORY_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/desktop-directories"
|
||||
CACHE PATH "The XDG directory"
|
||||
)
|
||||
|
||||
SET(SYSCONF_INSTALL_DIR
|
||||
"${EXEC_INSTALL_PREFIX}/etc"
|
||||
CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)"
|
||||
)
|
||||
SET(MAN_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/man"
|
||||
CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)"
|
||||
)
|
||||
SET(INFO_INSTALL_DIR
|
||||
"${SHARE_INSTALL_PREFIX}/info"
|
||||
CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)"
|
||||
)
|
||||
else()
|
||||
# Same same
|
||||
set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
|
||||
set(SBIN_INSTALL_DIR "sbin" CACHE PATH "-")
|
||||
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "-")
|
||||
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
|
||||
set(CMAKE_INSTALL_DIR "CMake" CACHE PATH "-")
|
||||
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
|
||||
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
|
||||
set(ICON_INSTALL_DIR "icons" CACHE PATH "-")
|
||||
set(SOUND_INSTALL_DIR "soudns" CACHE PATH "-")
|
||||
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
|
||||
endif ()
|
||||
@@ -302,12 +302,13 @@ function(get_file_list _TARGET_NAME)
|
||||
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}"
|
||||
-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"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
if (DEFINED _get_files_list_COPY_TO)
|
||||
@@ -318,6 +319,7 @@ function(get_file_list _TARGET_NAME)
|
||||
${_FILES_LIST_OUTPUT_PATH} ${_get_files_list_COPY_TO}
|
||||
DEPENDS ${_TARGET_NAME}_int
|
||||
COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
add_custom_target(${_TARGET_NAME} ALL
|
||||
@@ -369,12 +371,13 @@ function(extract_symbols _TARGET_NAME)
|
||||
add_custom_target(
|
||||
${_TARGET_NAME}_int ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DOUTPUT_PATH="${_SYMBOLS_OUTPUT_PATH}"
|
||||
-DHEADERS_LIST_FILE="${_HEADERS_LIST_FILE}"
|
||||
-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"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
if (DEFINED _extract_symbols_COPY_TO)
|
||||
@@ -385,6 +388,7 @@ function(extract_symbols _TARGET_NAME)
|
||||
${_SYMBOLS_OUTPUT_PATH} ${_extract_symbols_COPY_TO}
|
||||
DEPENDS ${_TARGET_NAME}_int
|
||||
COMMENT "Copying ${_TARGET_NAME} to ${_extract_symbols_COPY_TO}"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
add_custom_target(${_TARGET_NAME} ALL
|
||||
@@ -449,35 +453,37 @@ function(generate_map_file _TARGET_NAME)
|
||||
${_TARGET_NAME}_int ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE}
|
||||
-DSYMBOLS="${_SYMBOLS_FILE}"
|
||||
-DSYMBOLS=${_SYMBOLS_FILE}
|
||||
-DCURRENT_MAP=${_generate_map_file_CURRENT_MAP}
|
||||
-DOUTPUT_PATH="${_MAP_OUTPUT_PATH}"
|
||||
-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}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# 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}
|
||||
DEPENDS ${_TARGET_NAME}_copy
|
||||
)
|
||||
|
||||
if (DEFINED _generate_map_file_COPY_TO)
|
||||
# Copy the generated map back to the COPY_TO
|
||||
add_custom_target(${_TARGET_NAME} ALL
|
||||
add_custom_target(${_TARGET_NAME}_copy 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}"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
add_custom_target(${_TARGET_NAME} ALL
|
||||
add_custom_target(${_TARGET_NAME}_copy ALL
|
||||
DEPENDS ${_TARGET_NAME}_int
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION "${PROJECT_VERSION}"
|
||||
|
||||
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
|
||||
#cmakedefine DATADIR "${DATADIR}"
|
||||
#cmakedefine LIBDIR "${LIBDIR}"
|
||||
#cmakedefine PLUGINDIR "${PLUGINDIR}"
|
||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
||||
#cmakedefine BINARYDIR "${BINARYDIR}"
|
||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||
@@ -101,6 +97,12 @@
|
||||
/* Define to 1 if you have gl_flags as a glob_t sturct member */
|
||||
#cmakedefine HAVE_GLOB_GL_FLAGS_MEMBER 1
|
||||
|
||||
/* Define to 1 if you have OpenSSL with Ed25519 support */
|
||||
#cmakedefine HAVE_OPENSSL_ED25519 1
|
||||
|
||||
/* Define to 1 if you have OpenSSL with X25519 support */
|
||||
#cmakedefine HAVE_OPENSSL_X25519 1
|
||||
|
||||
/*************************** FUNCTIONS ***************************/
|
||||
|
||||
/* Define to 1 if you have the `EVP_aes128_ctr' function. */
|
||||
@@ -124,6 +126,15 @@
|
||||
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID 1
|
||||
|
||||
/* Define to 1 if you have the `FIPS_mode' function. */
|
||||
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
|
||||
|
||||
/* Define to 1 if you have the `EVP_DigestSign' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_DIGESTSIGN 1
|
||||
|
||||
/* Define to 1 if you have the `EVP_DigestVerify' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_DIGESTVERIFY 1
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_ia32cap_loc' function. */
|
||||
#cmakedefine HAVE_OPENSSL_IA32CAP_LOC 1
|
||||
|
||||
|
||||
@@ -13,8 +13,11 @@ if (DOXYGEN_FOUND)
|
||||
set(DOXYGEN_TAB_SIZE 4)
|
||||
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
|
||||
set(DOXYGEN_MARKDOWN_SUPPORT YES)
|
||||
set(DOXYGEN_FULL_PATH_NAMES NO)
|
||||
|
||||
set(DOXYGEN_PREDEFINED DOXYGEN
|
||||
WITH_SERVER
|
||||
WITH_SFTP
|
||||
PRINTF_ATTRIBUTE(x,y))
|
||||
|
||||
set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style)
|
||||
|
||||
@@ -112,8 +112,8 @@ This number is calculated using the following procedure:
|
||||
This conversion follows the network byte order. This step differs from
|
||||
RFC5656.
|
||||
|
||||
[RFC5656] http://tools.ietf.org/html/rfc5656
|
||||
[RFC5656] https://tools.ietf.org/html/rfc5656
|
||||
[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929
|
||||
[DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
|
||||
[DJB] https://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
|
||||
[Curve25519] "Curve25519: new Diffie-Hellman speed records."
|
||||
http://cr.yp.to/ecdh/curve25519-20060209.pdf
|
||||
https://cr.yp.to/ecdh/curve25519-20060209.pdf
|
||||
|
||||
@@ -28,6 +28,6 @@ the dllimport attribute.
|
||||
@endcode
|
||||
|
||||
If you're are statically linking with OpenSSL, read the "Linking your
|
||||
application" section in the NOTES.<OS> in the OpenSSL source tree!
|
||||
application" section in the NOTES.[OS] in the OpenSSL source tree!
|
||||
|
||||
*/
|
||||
|
||||
@@ -39,8 +39,8 @@ The libssh library provides:
|
||||
|
||||
- Client <b>and</b> server support
|
||||
- SSHv2 and SSHv1 protocol support
|
||||
- Supports <a href="http://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
|
||||
- Automated test cases with nightly <a href="http://test.libssh.org/" target="_blank">tests</a>
|
||||
- Supports <a href="https://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
|
||||
- Automated test cases with nightly <a href="https://test.libssh.org/" target="_blank">tests</a>
|
||||
- Event model based on poll(2), or a poll(2)-emulation.
|
||||
|
||||
@section main-copyright Copyright Policy
|
||||
@@ -111,7 +111,7 @@ By making a contribution to this project, I certify that:
|
||||
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
|
||||
https://www.gnu.org/licenses/lgpl-2.1.html
|
||||
@endverbatim
|
||||
|
||||
We will maintain a copy of that email as a record that you have the rights to
|
||||
@@ -151,47 +151,79 @@ The libssh Team
|
||||
|
||||
The following RFC documents described SSH-2 protcol as an Internet standard.
|
||||
|
||||
- <a href="http://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
|
||||
The Secure Shell (SSH) Protocol Assigned Numbers
|
||||
- <a href="http://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
|
||||
The Secure Shell (SSH) Protocol Architecture
|
||||
- <a href="http://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
|
||||
The Secure Shell (SSH) Authentication Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
|
||||
The Secure Shell (SSH) Transport Layer Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
|
||||
The Secure Shell (SSH) Connection Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
|
||||
Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
||||
- <a href="http://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
|
||||
(not implemented in libssh)
|
||||
- <a href="https://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
|
||||
Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
|
||||
- <a href="http://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
|
||||
The Secure Shell (SSH) Session Channel Break Extension
|
||||
- <a href="http://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
|
||||
The Secure Shell (SSH) Transport Layer Encryption Modes
|
||||
- <a href="http://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
|
||||
Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
|
||||
|
||||
It was later modified and expanded by the following RFCs.
|
||||
|
||||
- <a href="http://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
|
||||
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
|
||||
Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
|
||||
- <a href="https://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
|
||||
RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
|
||||
(not implemented in libssh)
|
||||
- <a href="https://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
|
||||
Generic Security Service Application Program Interface (GSS-API)
|
||||
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
||||
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
||||
(only the authentication implemented in libssh)
|
||||
- <a href="https://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
||||
The Secure Shell (SSH) Public Key File Format
|
||||
- <a href="http://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
|
||||
(not implemented in libssh)
|
||||
- <a href="https://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>,
|
||||
(the algorithm negotiation implemented according to openssh.com)
|
||||
- <a href="https://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
||||
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
||||
- <a href="https://tools.ietf.org/html/rfc6594" target="_blank">RFC 6594</a>,
|
||||
Use of the SHA-256 Algorithm with RSA, DSA, and ECDSA in SSHFP Resource Records
|
||||
(not implemented in libssh)
|
||||
- <a href="https://tools.ietf.org/html/rfc6668" target="_blank">RFC 6668</a>,
|
||||
SHA-2 Data Integrity Verification for the Secure Shell (SSH) Transport Layer Protocol
|
||||
- <a href="https://tools.ietf.org/html/rfc7479" target="_blank">RFC 7479</a>,
|
||||
Using Ed25519 in SSHFP Resource Records
|
||||
(not implemented in libssh)
|
||||
- <a href="https://tools.ietf.org/html/rfc8160" target="_blank">RFC 8160</a>,
|
||||
IUTF8 Terminal Mode in Secure Shell (SSH)
|
||||
(not handled in libssh)
|
||||
- <a href="https://tools.ietf.org/html/rfc8270" target="_blank">RFC 8270</a>,
|
||||
Increase the Secure Shell Minimum Recommended Diffie-Hellman Modulus Size to 2048 Bits
|
||||
- <a href="https://tools.ietf.org/html/rfc8308" target="_blank">RFC 8308</a>,
|
||||
Extension Negotiation in the Secure Shell (SSH) Protocol
|
||||
(only the "server-sig-algs" extension implemented)
|
||||
- <a href="https://tools.ietf.org/html/rfc8332" target="_blank">RFC 8332</a>,
|
||||
Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol
|
||||
|
||||
There are also drafts that are being currently developed and followed.
|
||||
|
||||
- <a href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-kex-sha2-10" target="_blank">draft-ietf-curdle-ssh-kex-sha2-10</a>
|
||||
Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)
|
||||
- <a href="https://tools.ietf.org/html/draft-miller-ssh-agent-03" target="_blank">draft-miller-ssh-agent-03</a>
|
||||
SSH Agent Protocol
|
||||
- <a href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-12" target="_blank">draft-ietf-curdle-ssh-curves-12</a>
|
||||
Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448
|
||||
|
||||
Interesting cryptography documents:
|
||||
|
||||
- <a href="http://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
|
||||
- <a href="https://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
|
||||
|
||||
@subsection main-rfc-sftp Secure Shell File Transfer Protocol (SFTP)
|
||||
|
||||
@@ -199,26 +231,22 @@ The protocol is not an Internet standard but it is still widely implemented.
|
||||
OpenSSH and most other implementation implement Version 3 of the protocol. We
|
||||
do the same in libssh.
|
||||
|
||||
- <a href="http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
|
||||
- <a href="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
|
||||
draft-ietf-secsh-filexfer-02.txt</a>,
|
||||
SSH File Transfer Protocol
|
||||
|
||||
@subsection main-rfc-extensions Secure Shell Extensions
|
||||
|
||||
The libssh project has an extension to support Curve25519 which is also supported by
|
||||
the OpenSSH project.
|
||||
|
||||
- <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
|
||||
them like the statvfs calls in SFTP or the ssh-agent.
|
||||
|
||||
- <a href="http://api.libssh.org/rfc/PROTOCOL" target="_blank">
|
||||
- <a href="https://api.libssh.org/rfc/PROTOCOL" target="_blank">
|
||||
OpenSSH's deviations and extensions</a>
|
||||
- <a href="http://api.libssh.org/rfc/PROTOCOL.agent" target="_blank">
|
||||
OpenSSH's ssh-agent</a>
|
||||
- <a href="http://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
|
||||
- <a href="https://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
|
||||
OpenSSH's pubkey certificate authentication</a>
|
||||
- <a href="https://api.libssh.org/rfc/PROTOCOL.chacha20poly1305" target="_blank">
|
||||
chacha20-poly1305@openssh.com authenticated encryption mode</a>
|
||||
- <a href="https://api.libssh.org/rfc/PROTOCOL.key" target="_blank">
|
||||
OpenSSH private key format (openssh-key-v1)</a>
|
||||
|
||||
*/
|
||||
|
||||
@@ -6,10 +6,7 @@ set(examples_SRCS
|
||||
connect_ssh.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
include_directories(${libssh_BINARY_DIR}/include ${libssh_BINARY_DIR})
|
||||
|
||||
if (ARGP_INCLUDE_DIR)
|
||||
include_directories(${ARGP_INCLUDE_DIR})
|
||||
@@ -18,68 +15,68 @@ endif()
|
||||
if (UNIX AND NOT WIN32)
|
||||
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 ssh::ssh)
|
||||
|
||||
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 ssh::ssh)
|
||||
|
||||
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 ssh::ssh)
|
||||
|
||||
if (WITH_SFTP)
|
||||
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 ssh::ssh)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
add_executable(ssh-client ssh_client.c ${examples_SRCS})
|
||||
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(ssh-client ssh::ssh)
|
||||
|
||||
if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H))
|
||||
if (HAVE_LIBUTIL)
|
||||
add_executable(ssh_server_fork ssh_server_fork.c)
|
||||
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util)
|
||||
target_link_libraries(ssh_server_fork ssh::ssh ${ARGP_LIBRARY} util)
|
||||
endif (HAVE_LIBUTIL)
|
||||
|
||||
if (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
add_executable(samplesshd-cb samplesshd-cb.c)
|
||||
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||
target_link_libraries(samplesshd-cb ssh::ssh ${ARGP_LIBRARY})
|
||||
|
||||
add_executable(proxy proxy.c)
|
||||
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||
target_link_libraries(proxy ssh::ssh ${ARGP_LIBRARY})
|
||||
|
||||
add_executable(sshd_direct-tcpip sshd_direct-tcpip.c)
|
||||
target_compile_options(sshd_direct-tcpip PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(sshd_direct-tcpip ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||
target_link_libraries(sshd_direct-tcpip ssh::ssh ${ARGP_LIBRARY})
|
||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
|
||||
add_executable(samplesshd-kbdint samplesshd-kbdint.c)
|
||||
target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||
target_link_libraries(samplesshd-kbdint ssh::ssh ${ARGP_LIBRARY})
|
||||
|
||||
endif()
|
||||
endif (UNIX AND NOT WIN32)
|
||||
|
||||
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 ssh::ssh)
|
||||
|
||||
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 ssh::ssh)
|
||||
|
||||
add_executable(keygen keygen.c)
|
||||
target_compile_options(keygen PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(keygen ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(keygen ssh::ssh)
|
||||
|
||||
add_executable(libsshpp libsshpp.cpp)
|
||||
target_link_libraries(libsshpp ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(libsshpp ssh::ssh)
|
||||
|
||||
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
|
||||
target_link_libraries(libsshpp_noexcept ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(libsshpp_noexcept ssh::ssh)
|
||||
|
||||
@@ -234,7 +234,7 @@ int authenticate_console(ssh_session session)
|
||||
banner = ssh_get_issue_banner(session);
|
||||
if (banner) {
|
||||
printf("%s\n",banner);
|
||||
ssh_string_free_char(banner);
|
||||
SSH_STRING_FREE_CHAR(banner);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -8,7 +8,7 @@ int main(void) {
|
||||
ssh_session session;
|
||||
ssh_channel channel;
|
||||
char buffer[256];
|
||||
int nbytes;
|
||||
int rbytes, wbytes, total = 0;
|
||||
int rc;
|
||||
|
||||
session = connect_ssh("localhost", NULL, 0);
|
||||
@@ -35,15 +35,30 @@ int main(void) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
while (nbytes > 0) {
|
||||
if (fwrite(buffer, 1, nbytes, stdout) != (unsigned int) nbytes) {
|
||||
goto failed;
|
||||
}
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
rbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
if (rbytes <= 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (nbytes < 0) {
|
||||
do {
|
||||
wbytes = fwrite(buffer + total, 1, rbytes, stdout);
|
||||
if (wbytes <= 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
total += wbytes;
|
||||
|
||||
/* When it was not possible to write the whole buffer to stdout */
|
||||
if (wbytes < rbytes) {
|
||||
rbytes -= wbytes;
|
||||
continue;
|
||||
}
|
||||
|
||||
rbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
total = 0;
|
||||
} while (rbytes > 0);
|
||||
|
||||
if (rbytes < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ static int open_location(struct location *loc, int flag) {
|
||||
loc->file = fopen(loc->path, flag == READ ? "r":"w");
|
||||
if (!loc->file) {
|
||||
if (errno == EISDIR) {
|
||||
if (chdir(loc->path)) {
|
||||
if (loc->path != NULL && chdir(loc->path)) {
|
||||
fprintf(stderr,
|
||||
"Error changing directory to %s: %s\n",
|
||||
loc->path, strerror(errno));
|
||||
@@ -257,14 +257,15 @@ static int open_location(struct location *loc, int flag) {
|
||||
* @param recursive Copy also directories
|
||||
*/
|
||||
static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
int size;
|
||||
size_t size;
|
||||
socket_t fd;
|
||||
struct stat s;
|
||||
int w, r;
|
||||
char buffer[16384];
|
||||
int total = 0;
|
||||
int mode;
|
||||
size_t total = 0;
|
||||
mode_t mode;
|
||||
char *filename = NULL;
|
||||
|
||||
/* recursive mode doesn't work yet */
|
||||
(void)recursive;
|
||||
/* Get the file name and size*/
|
||||
@@ -302,7 +303,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
fprintf(stderr,
|
||||
"Error: %s\n",
|
||||
ssh_get_error(src->session));
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
return -1;
|
||||
}
|
||||
} while(r != SSH_SCP_REQUEST_NEWFILE);
|
||||
@@ -315,7 +316,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
fprintf(stderr,
|
||||
"error: %s\n",
|
||||
ssh_get_error(dest->session));
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
ssh_scp_free(dest->scp);
|
||||
dest->scp = NULL;
|
||||
return -1;
|
||||
@@ -330,7 +331,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
if (src->is_ssh) {
|
||||
ssh_scp_deny_request(src->scp, "Cannot open local file");
|
||||
}
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -346,7 +347,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
fprintf(stderr,
|
||||
"Error reading scp: %s\n",
|
||||
ssh_get_error(src->session));
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -363,7 +364,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
fprintf(stderr,
|
||||
"Error reading file: %s\n",
|
||||
strerror(errno));
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -376,7 +377,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
ssh_get_error(dest->session));
|
||||
ssh_scp_free(dest->scp);
|
||||
dest->scp = NULL;
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
@@ -385,7 +386,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
fprintf(stderr,
|
||||
"Error writing in local file: %s\n",
|
||||
strerror(errno));
|
||||
ssh_string_free_char(filename);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -393,8 +394,8 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
|
||||
|
||||
} while(total < size);
|
||||
|
||||
ssh_string_free_char(filename);
|
||||
printf("wrote %d bytes\n", total);
|
||||
SSH_STRING_FREE_CHAR(filename);
|
||||
printf("wrote %zu bytes\n", total);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
/* client.c */
|
||||
/* ssh_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.
|
||||
*/
|
||||
* Copyright 2003-2015 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>
|
||||
@@ -197,19 +198,20 @@ static void sizechanged(void)
|
||||
static void select_loop(ssh_session session,ssh_channel channel)
|
||||
{
|
||||
ssh_connector connector_in, connector_out, connector_err;
|
||||
int rc;
|
||||
|
||||
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_out_channel(connector_in, channel, SSH_CONNECTOR_STDINOUT);
|
||||
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_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT);
|
||||
ssh_event_add_connector(event, connector_out);
|
||||
|
||||
/* stderr */
|
||||
@@ -222,7 +224,11 @@ static void select_loop(ssh_session session,ssh_channel channel)
|
||||
if (signal_delayed) {
|
||||
sizechanged();
|
||||
}
|
||||
ssh_event_dopoll(event, 60000);
|
||||
rc = ssh_event_dopoll(event, 60000);
|
||||
if (rc == SSH_ERROR) {
|
||||
fprintf(stderr, "Error in ssh_event_dopoll()\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
ssh_event_remove_connector(event, connector_in);
|
||||
ssh_event_remove_connector(event, connector_out);
|
||||
@@ -233,7 +239,6 @@ static void select_loop(ssh_session session,ssh_channel channel)
|
||||
ssh_connector_free(connector_err);
|
||||
|
||||
ssh_event_free(event);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
static void shell(ssh_session session)
|
||||
@@ -241,7 +246,11 @@ static void shell(ssh_session session)
|
||||
ssh_channel channel;
|
||||
struct termios terminal_local;
|
||||
int interactive=isatty(0);
|
||||
|
||||
channel = ssh_channel_new(session);
|
||||
if (channel == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (interactive) {
|
||||
tcgetattr(0, &terminal_local);
|
||||
@@ -250,6 +259,7 @@ static void shell(ssh_session session)
|
||||
|
||||
if (ssh_channel_open_session(channel)) {
|
||||
printf("Error opening channel : %s\n", ssh_get_error(session));
|
||||
ssh_channel_free(channel);
|
||||
return;
|
||||
}
|
||||
chan = channel;
|
||||
@@ -260,6 +270,7 @@ static void shell(ssh_session session)
|
||||
|
||||
if (ssh_channel_request_shell(channel)) {
|
||||
printf("Requesting shell : %s\n", ssh_get_error(session));
|
||||
ssh_channel_free(channel);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -273,6 +284,7 @@ static void shell(ssh_session session)
|
||||
if (interactive) {
|
||||
do_cleanup(0);
|
||||
}
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
static void batch_shell(ssh_session session)
|
||||
@@ -289,12 +301,18 @@ static void batch_shell(ssh_session session)
|
||||
}
|
||||
|
||||
channel = ssh_channel_new(session);
|
||||
if (channel == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_channel_open_session(channel);
|
||||
if (ssh_channel_request_exec(channel, buffer)) {
|
||||
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
|
||||
ssh_channel_free(channel);
|
||||
return;
|
||||
}
|
||||
select_loop(session, channel);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
static int client(ssh_session session)
|
||||
|
||||
@@ -70,6 +70,8 @@ static void set_default_keys(ssh_bind sshbind,
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
|
||||
KEYS_FOLDER "ssh_host_ecdsa_key");
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
|
||||
KEYS_FOLDER "ssh_host_ed25519_key");
|
||||
}
|
||||
#define DEF_STR_SIZE 1024
|
||||
char authorizedkeys[DEF_STR_SIZE] = {0};
|
||||
|
||||
@@ -23,17 +23,32 @@ clients must be made or how a client should react.
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
#include <libssh/callbacks.h>
|
||||
#include <libssh/channels.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
|
||||
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
|
||||
|
||||
#ifndef __unused__
|
||||
# ifdef HAVE_UNUSED_ATTRIBUTE
|
||||
# define __unused__ __attribute__((unused))
|
||||
# else /* HAVE_UNUSED_ATTRIBUTE */
|
||||
# define __unused__
|
||||
# endif /* HAVE_UNUSED_ATTRIBUTE */
|
||||
#endif /* __unused__ */
|
||||
|
||||
#ifndef UNUSED_PARAM
|
||||
#define UNUSED_PARAM(param) param __unused__
|
||||
#endif /* UNUSED_PARAM */
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
@@ -66,11 +81,18 @@ static struct cleanup_node_struct *cleanup_stack = NULL;
|
||||
|
||||
static void _close_socket(struct event_fd_data_struct event_fd_data);
|
||||
|
||||
static void cleanup_push(struct cleanup_node_struct** head_ref, struct event_fd_data_struct *new_data) {
|
||||
static void
|
||||
cleanup_push(struct cleanup_node_struct** head_ref,
|
||||
struct event_fd_data_struct *new_data)
|
||||
{
|
||||
// Allocate memory for node
|
||||
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
|
||||
|
||||
new_node->next = (*head_ref);
|
||||
if (head_ref != NULL) {
|
||||
new_node->next = *head_ref;
|
||||
} else {
|
||||
new_node->next = NULL;
|
||||
}
|
||||
|
||||
// Copy new_data
|
||||
new_node->data = new_data;
|
||||
@@ -79,7 +101,9 @@ static void cleanup_push(struct cleanup_node_struct** head_ref, struct event_fd_
|
||||
(*head_ref) = new_node;
|
||||
}
|
||||
|
||||
static void do_cleanup(struct cleanup_node_struct **head_ref) {
|
||||
static void
|
||||
do_cleanup(struct cleanup_node_struct **head_ref)
|
||||
{
|
||||
struct cleanup_node_struct *current = (*head_ref);
|
||||
struct cleanup_node_struct *previous = NULL, *gone = NULL;
|
||||
|
||||
@@ -118,16 +142,22 @@ static void do_cleanup(struct cleanup_node_struct **head_ref) {
|
||||
}
|
||||
}
|
||||
|
||||
static int auth_password(ssh_session session, const char *user,
|
||||
const char *password, void *userdata) {
|
||||
(void)userdata;
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== auth_password", "Authenticating user %s pwd %s",user, password);
|
||||
if (strcmp(user,USER) == 0 && strcmp(password, PASSWORD) == 0){
|
||||
static int
|
||||
auth_password(ssh_session session,
|
||||
const char *user,
|
||||
const char *password,
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== auth_password", "Authenticating user %s pwd %s",
|
||||
user,
|
||||
password);
|
||||
if (strcmp(user, USER) == 0 && strcmp(password, PASSWORD) == 0) {
|
||||
authenticated = true;
|
||||
printf("Authenticated\n");
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
if (tries >= 3){
|
||||
if (tries >= 3) {
|
||||
printf("Too many authentication tries\n");
|
||||
ssh_disconnect(session);
|
||||
error_set = true;
|
||||
@@ -137,25 +167,34 @@ static int auth_password(ssh_session session, const char *user,
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata) {
|
||||
static int
|
||||
auth_gssapi_mic(ssh_session session,
|
||||
const char *user,
|
||||
const char *principal,
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
ssh_gssapi_creds creds = ssh_gssapi_get_creds(session);
|
||||
(void)userdata;
|
||||
printf("Authenticating user %s with gssapi principal %s\n", user, principal);
|
||||
if (creds != NULL)
|
||||
printf("Authenticating user %s with gssapi principal %s\n",
|
||||
user, principal);
|
||||
if (creds != NULL) {
|
||||
printf("Received some gssapi credentials\n");
|
||||
else
|
||||
} else {
|
||||
printf("Not received any forwardable creds\n");
|
||||
}
|
||||
printf("authenticated\n");
|
||||
authenticated = true;
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
static int subsystem_request(ssh_session session, ssh_channel channel, const char *subsystem, void *userdata) {
|
||||
(void)session;
|
||||
(void)channel;
|
||||
//(void)subsystem;
|
||||
(void)userdata;
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== subsystem_request", "Channel subsystem reqeuest: %s", subsystem);
|
||||
static int
|
||||
subsystem_request(UNUSED_PARAM(ssh_session session),
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
const char *subsystem,
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== subsystem_request", "Channel subsystem reqeuest: %s",
|
||||
subsystem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,9 +202,10 @@ struct ssh_channel_callbacks_struct channel_cb = {
|
||||
.channel_subsystem_request_function = subsystem_request
|
||||
};
|
||||
|
||||
static ssh_channel new_session_channel(ssh_session session, void *userdata) {
|
||||
(void)session;
|
||||
(void)userdata;
|
||||
static ssh_channel
|
||||
new_session_channel(UNUSED_PARAM(ssh_session session),
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== subsystem_request", "Session channel request");
|
||||
/* For TCP forward only there seems to be no need for a session channel */
|
||||
/*if(chan != NULL)
|
||||
@@ -178,18 +218,25 @@ static ssh_channel new_session_channel(ssh_session session, void *userdata) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void stack_socket_close(UNUSED_PARAM(ssh_session session),
|
||||
struct event_fd_data_struct *event_fd_data)
|
||||
static void
|
||||
stack_socket_close(UNUSED_PARAM(ssh_session session),
|
||||
struct event_fd_data_struct *event_fd_data)
|
||||
{
|
||||
if (event_fd_data->stacked != 1) {
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== stack_socket_close", "Closing fd = %d sockets_cnt = %d", *event_fd_data->p_fd, sockets_cnt);
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== stack_socket_close",
|
||||
"Closing fd = %d sockets_cnt = %d", *event_fd_data->p_fd,
|
||||
sockets_cnt);
|
||||
event_fd_data->stacked = 1;
|
||||
cleanup_push(&cleanup_stack, event_fd_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void _close_socket(struct event_fd_data_struct event_fd_data) {
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== close_socket", "Closing fd = %d sockets_cnt = %d", *event_fd_data.p_fd, sockets_cnt);
|
||||
static void
|
||||
_close_socket(struct event_fd_data_struct event_fd_data)
|
||||
{
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== close_socket",
|
||||
"Closing fd = %d sockets_cnt = %d", *event_fd_data.p_fd,
|
||||
sockets_cnt);
|
||||
ssh_event_remove_fd(mainloop, *event_fd_data.p_fd);
|
||||
sockets_cnt--;
|
||||
#ifdef _WIN32
|
||||
@@ -200,51 +247,75 @@ static void _close_socket(struct event_fd_data_struct event_fd_data) {
|
||||
(*event_fd_data.p_fd) = SSH_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
static int service_request(ssh_session session, const char *service, void *userdata) {
|
||||
(void)session;
|
||||
//(void)service;
|
||||
(void)userdata;
|
||||
static int
|
||||
service_request(UNUSED_PARAM(ssh_session session),
|
||||
const char *service,
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== service_request", "Service request: %s", service);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void global_request(ssh_session session, ssh_message message, void *userdata) {
|
||||
(void)session;
|
||||
(void)userdata;
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== global_request", "Global request, message type: %d", ssh_message_type(message));
|
||||
static void
|
||||
global_request(UNUSED_PARAM(ssh_session session),
|
||||
ssh_message message,
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== global_request", "Global request, message type: %d",
|
||||
ssh_message_type(message));
|
||||
}
|
||||
|
||||
static void my_channel_close_function(ssh_session session, ssh_channel channel, void *userdata) {
|
||||
static void
|
||||
my_channel_close_function(ssh_session session,
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
void *userdata)
|
||||
{
|
||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
||||
(void)session;
|
||||
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_channel_close_function", "Channel %d:%d closed by remote. State=%d", channel->local_channel, channel->remote_channel, channel->state);
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== my_channel_close_function",
|
||||
"Channel closed by remote.");
|
||||
|
||||
stack_socket_close(session, event_fd_data);
|
||||
}
|
||||
|
||||
static void my_channel_eof_function(ssh_session session, ssh_channel channel, void *userdata) {
|
||||
static void
|
||||
my_channel_eof_function(ssh_session session,
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
void *userdata)
|
||||
{
|
||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
||||
(void)session;
|
||||
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_channel_eof_function", "Got EOF on channel %d:%d. Shuting down write on socket (fd = %d).", channel->local_channel, channel->remote_channel, *event_fd_data->p_fd);
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== my_channel_eof_function",
|
||||
"Got EOF on channel. Shuting down write on socket (fd = %d).",
|
||||
*event_fd_data->p_fd);
|
||||
|
||||
stack_socket_close(session, event_fd_data);
|
||||
}
|
||||
|
||||
static void my_channel_exit_status_function(ssh_session session, ssh_channel channel, int exit_status, void *userdata) {
|
||||
static void
|
||||
my_channel_exit_status_function(UNUSED_PARAM(ssh_session session),
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
int exit_status,
|
||||
void *userdata)
|
||||
{
|
||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
||||
(void)session;
|
||||
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_channel_exit_status_function", "Got exit status %d on channel %d:%d fd = %d.", exit_status, channel->local_channel, channel->remote_channel, *event_fd_data->p_fd);
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== my_channel_exit_status_function",
|
||||
"Got exit status %d on channel fd = %d.",
|
||||
exit_status, *event_fd_data->p_fd);
|
||||
}
|
||||
|
||||
static int my_channel_data_function(ssh_session session,
|
||||
ssh_channel channel,
|
||||
void *data,
|
||||
uint32_t len,
|
||||
UNUSED_PARAM(int is_stderr),
|
||||
void *userdata)
|
||||
static int
|
||||
my_channel_data_function(ssh_session session,
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
void *data,
|
||||
uint32_t len,
|
||||
UNUSED_PARAM(int is_stderr),
|
||||
void *userdata)
|
||||
{
|
||||
int i = 0;
|
||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
||||
@@ -253,12 +324,18 @@ static int my_channel_data_function(ssh_session session,
|
||||
fprintf(stderr, "Why we're here? Stacked = %d\n", event_fd_data->stacked);
|
||||
}
|
||||
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_channel_data_function", "%d bytes waiting on channel %d:%d for reading. Fd = %d",len, channel->local_channel, channel->remote_channel, *event_fd_data->p_fd);
|
||||
_ssh_log(SSH_LOG_PROTOCOL,
|
||||
"=== my_channel_data_function",
|
||||
"%d bytes waiting on channel for reading. Fd = %d",
|
||||
len,
|
||||
*event_fd_data->p_fd);
|
||||
if (len > 0) {
|
||||
i = send(*event_fd_data->p_fd, data, len, 0);
|
||||
}
|
||||
if (i < 0) {
|
||||
_ssh_log(SSH_LOG_WARNING, "=== my_channel_data_function", "Writing to tcp socket %d: %s", *event_fd_data->p_fd, strerror(errno));
|
||||
_ssh_log(SSH_LOG_WARNING, "=== my_channel_data_function",
|
||||
"Writing to tcp socket %d: %s", *event_fd_data->p_fd,
|
||||
strerror(errno));
|
||||
stack_socket_close(session, event_fd_data);
|
||||
}
|
||||
else {
|
||||
@@ -267,9 +344,10 @@ static int my_channel_data_function(ssh_session session,
|
||||
return i;
|
||||
}
|
||||
|
||||
static int my_fd_data_function(UNUSED_PARAM(socket_t fd),
|
||||
int revents,
|
||||
void *userdata)
|
||||
static int
|
||||
my_fd_data_function(UNUSED_PARAM(socket_t fd),
|
||||
int revents,
|
||||
void *userdata)
|
||||
{
|
||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
||||
ssh_channel channel = event_fd_data->channel;
|
||||
@@ -313,8 +391,10 @@ static int my_fd_data_function(UNUSED_PARAM(socket_t fd),
|
||||
blocking = ssh_is_blocking(session);
|
||||
ssh_set_blocking(session, 0);
|
||||
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "Trying to read from tcp socket fd = %d... (Channel %d:%d state=%d)",
|
||||
*event_fd_data->p_fd, channel->local_channel, channel->remote_channel, channel->state);
|
||||
_ssh_log(SSH_LOG_FUNCTIONS,
|
||||
"=== my_fd_data_function",
|
||||
"Trying to read from tcp socket fd = %d",
|
||||
*event_fd_data->p_fd);
|
||||
#ifdef _WIN32
|
||||
struct sockaddr from;
|
||||
int fromlen = sizeof(from);
|
||||
@@ -360,7 +440,9 @@ static int my_fd_data_function(UNUSED_PARAM(socket_t fd),
|
||||
return len;
|
||||
}
|
||||
|
||||
static int open_tcp_socket(ssh_message msg) {
|
||||
static int
|
||||
open_tcp_socket(ssh_message msg)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int forwardsock = -1;
|
||||
struct hostent *host;
|
||||
@@ -401,17 +483,20 @@ static int open_tcp_socket(ssh_message msg) {
|
||||
return forwardsock;
|
||||
}
|
||||
|
||||
static int message_callback(ssh_session session, ssh_message message, void *userdata) {
|
||||
static int
|
||||
message_callback(UNUSED_PARAM(ssh_session session),
|
||||
ssh_message message,
|
||||
UNUSED_PARAM(void *userdata))
|
||||
{
|
||||
ssh_channel channel;
|
||||
int socket_fd, *pFd;
|
||||
struct ssh_channel_callbacks_struct *cb_chan;
|
||||
struct event_fd_data_struct *event_fd_data;
|
||||
(void)session;
|
||||
(void)message;
|
||||
(void)userdata;
|
||||
|
||||
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d", ssh_message_type(message));
|
||||
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message Subtype: %d", ssh_message_subtype(message));
|
||||
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d",
|
||||
ssh_message_type(message));
|
||||
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message Subtype: %d",
|
||||
ssh_message_subtype(message));
|
||||
if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "channel_request_open");
|
||||
|
||||
@@ -433,6 +518,12 @@ static int message_callback(ssh_session session, ssh_message message, void *user
|
||||
pFd = malloc(sizeof *pFd);
|
||||
cb_chan = malloc(sizeof *cb_chan);
|
||||
event_fd_data = malloc(sizeof *event_fd_data);
|
||||
if (pFd == NULL || cb_chan == NULL || event_fd_data == NULL) {
|
||||
SAFE_FREE(pFd);
|
||||
SAFE_FREE(cb_chan);
|
||||
SAFE_FREE(event_fd_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*pFd) = socket_fd;
|
||||
event_fd_data->channel = channel;
|
||||
@@ -515,7 +606,9 @@ static struct argp_option options[] = {
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
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.
|
||||
*/
|
||||
@@ -561,7 +654,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
struct ssh_server_callbacks_struct cb = {
|
||||
|
||||
@@ -26,8 +26,14 @@ install(
|
||||
FILES
|
||||
${libssh_HDRS}
|
||||
DESTINATION
|
||||
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||
${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}
|
||||
COMPONENT
|
||||
headers
|
||||
)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libssh_version.h.cmake
|
||||
${libssh_BINARY_DIR}/include/libssh/libssh_version.h
|
||||
@ONLY)
|
||||
install(FILES ${libssh_BINARY_DIR}/include/libssh/libssh_version.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}
|
||||
COMPONENT headers)
|
||||
|
||||
@@ -104,7 +104,7 @@ void ssh_agent_free(struct ssh_agent_struct *agent);
|
||||
*/
|
||||
int ssh_agent_is_running(struct ssh_session_struct *session);
|
||||
|
||||
int ssh_agent_get_ident_count(struct ssh_session_struct *session);
|
||||
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session);
|
||||
|
||||
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||
char **comment);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
bignum ssh_make_string_bn(ssh_string string);
|
||||
ssh_string ssh_make_bignum_string(bignum num);
|
||||
void ssh_print_bignum(const char *which, const bignum num);
|
||||
void ssh_print_bignum(const char *which, const_bignum num);
|
||||
|
||||
|
||||
#endif /* BIGNUM_H_ */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define BIND_H_
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/session.h"
|
||||
|
||||
struct ssh_bind_struct {
|
||||
@@ -31,7 +32,7 @@ struct ssh_bind_struct {
|
||||
|
||||
struct ssh_poll_handle_struct *poll;
|
||||
/* options */
|
||||
char *wanted_methods[10];
|
||||
char *wanted_methods[SSH_KEX_METHODS];
|
||||
char *banner;
|
||||
char *ecdsakey;
|
||||
char *dsakey;
|
||||
|
||||
@@ -97,8 +97,9 @@ SSH_PACKET_CALLBACK(channel_rcv_close);
|
||||
SSH_PACKET_CALLBACK(channel_rcv_request);
|
||||
SSH_PACKET_CALLBACK(channel_rcv_data);
|
||||
|
||||
int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||
int is_stderr);
|
||||
int channel_default_bufferize(ssh_channel channel,
|
||||
void *data, size_t len,
|
||||
bool is_stderr);
|
||||
int ssh_channel_flush(ssh_channel channel);
|
||||
uint32_t ssh_channel_new_id(ssh_session session);
|
||||
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
||||
|
||||
@@ -80,6 +80,8 @@ enum ssh_key_exchange_e {
|
||||
SSH_KEX_DH_GROUP16_SHA512,
|
||||
/* diffie-hellman-group18-sha512 */
|
||||
SSH_KEX_DH_GROUP18_SHA512,
|
||||
/* diffie-hellman-group14-sha256 */
|
||||
SSH_KEX_DH_GROUP14_SHA256,
|
||||
};
|
||||
|
||||
enum ssh_cipher_e {
|
||||
@@ -105,7 +107,7 @@ struct ssh_crypto_struct {
|
||||
bignum shared_secret;
|
||||
struct dh_ctx *dh_ctx;
|
||||
#ifdef WITH_GEX
|
||||
size_t dh_pmin; int dh_pn; int dh_pmax; /* preferred group parameters */
|
||||
size_t dh_pmin; size_t dh_pn; size_t dh_pmax; /* preferred group parameters */
|
||||
#endif /* WITH_GEX */
|
||||
#ifdef HAVE_ECDH
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
@@ -124,8 +126,9 @@ struct ssh_crypto_struct {
|
||||
ssh_curve25519_pubkey curve25519_server_pubkey;
|
||||
#endif
|
||||
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
||||
size_t digest_len; /* len of the two fields below */
|
||||
size_t session_id_len;
|
||||
unsigned char *session_id;
|
||||
size_t digest_len; /* len of the secret hash */
|
||||
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
|
||||
unsigned char *encryptIV;
|
||||
unsigned char *decryptIV;
|
||||
|
||||
@@ -48,6 +48,8 @@ int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
|
||||
int ssh_dh_compute_shared_secret(struct dh_ctx *ctx, int local, int remote,
|
||||
bignum *dest);
|
||||
|
||||
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c);
|
||||
|
||||
/* common functions */
|
||||
int ssh_dh_init(void);
|
||||
void ssh_dh_finalize(void);
|
||||
|
||||
@@ -39,7 +39,7 @@ void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
|
||||
|
||||
void fe25519_pack(unsigned char r[32], const fe25519 *x);
|
||||
|
||||
int fe25519_iszero(const fe25519 *x);
|
||||
uint32_t fe25519_iszero(const fe25519 *x);
|
||||
|
||||
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
struct ssh_public_key_struct {
|
||||
int type;
|
||||
const char *type_c; /* Don't free it ! it is static */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#if defined(HAVE_LIBGCRYPT)
|
||||
gcry_sexp_t dsa_pub;
|
||||
gcry_sexp_t rsa_pub;
|
||||
#elif HAVE_LIBCRYPTO
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
DSA *dsa_pub;
|
||||
RSA *rsa_pub;
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
mbedtls_pk_context *rsa_pub;
|
||||
void *dsa_pub;
|
||||
#endif
|
||||
@@ -42,13 +42,13 @@ struct ssh_public_key_struct {
|
||||
|
||||
struct ssh_private_key_struct {
|
||||
int type;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#if defined(HAVE_LIBGCRYPT)
|
||||
gcry_sexp_t dsa_priv;
|
||||
gcry_sexp_t rsa_priv;
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
DSA *dsa_priv;
|
||||
RSA *rsa_priv;
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
mbedtls_pk_context *rsa_priv;
|
||||
void *dsa_priv;
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define SSH_KNOWNHOSTS_H_
|
||||
|
||||
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
|
||||
char *ssh_known_hosts_get_algorithms_names(ssh_session session);
|
||||
enum ssh_known_hosts_e
|
||||
ssh_session_get_known_hosts_entry_file(ssh_session session,
|
||||
const char *filename,
|
||||
|
||||
@@ -96,9 +96,9 @@ typedef BN_CTX* bignum_CTX;
|
||||
#define bignum_add(dest, a, b) BN_add(dest, a, b)
|
||||
#define bignum_sub(dest, a, b) BN_sub(dest, a, b)
|
||||
#define bignum_mod(dest, a, b, ctx) BN_mod(dest, a, b, ctx)
|
||||
#define bignum_num_bytes(num) BN_num_bytes(num)
|
||||
#define bignum_num_bits(num) BN_num_bits(num)
|
||||
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num,bit)
|
||||
#define bignum_num_bytes(num) (size_t)BN_num_bytes(num)
|
||||
#define bignum_num_bits(num) (size_t)BN_num_bits(num)
|
||||
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num, (int)bit)
|
||||
#define bignum_bn2bin(num,len, ptr) BN_bn2bin(num, ptr)
|
||||
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
|
||||
#define bignum_rshift1(dest, src) BN_rshift1(dest, src)
|
||||
@@ -112,7 +112,11 @@ typedef BN_CTX* bignum_CTX;
|
||||
|
||||
|
||||
/* Returns true if the OpenSSL is operating in FIPS mode */
|
||||
#ifdef HAVE_OPENSSL_FIPS_MODE
|
||||
#define ssh_fips_mode() (FIPS_mode() != 0)
|
||||
#else
|
||||
#define ssh_fips_mode() false
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
||||
|
||||
@@ -78,7 +78,10 @@ int ssh_gcry_rand_range(bignum rnd, bignum max);
|
||||
#define bignum_bin2bn(data,datalen,dest) gcry_mpi_scan(dest,GCRYMPI_FMT_USG,data,datalen,NULL)
|
||||
#define bignum_bn2dec(num) ssh_gcry_bn2dec(num)
|
||||
#define bignum_dec2bn(num, data) ssh_gcry_dec2bn(data, num)
|
||||
#define bignum_bn2hex(num,data) gcry_mpi_aprint(GCRYMPI_FMT_HEX,data,NULL,num)
|
||||
|
||||
#define bignum_bn2hex(num, data) \
|
||||
gcry_mpi_aprint(GCRYMPI_FMT_HEX, data, NULL, (const gcry_mpi_t)num)
|
||||
|
||||
#define bignum_hex2bn(data, num) (gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,0,NULL)==0?1:0)
|
||||
#define bignum_rand(num,bits) 1,gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
|
||||
#define bignum_mod_exp(dest,generator,exp,modulo, ctx) 1,gcry_mpi_powm(dest,generator,exp,modulo)
|
||||
|
||||
@@ -75,7 +75,7 @@ struct mbedtls_ecdsa_sig {
|
||||
|
||||
bignum ssh_mbedcry_bn_new(void);
|
||||
void ssh_mbedcry_bn_free(bignum num);
|
||||
unsigned char *ssh_mbedcry_bn2num(bignum num, int radix);
|
||||
unsigned char *ssh_mbedcry_bn2num(const_bignum num, int radix);
|
||||
int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom);
|
||||
int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
|
||||
int ssh_mbedcry_rand_range(bignum dest, bignum max);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2003-2021 by Aris Adamantiadis and the libssh team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef _LIBSSH_H
|
||||
#define _LIBSSH_H
|
||||
|
||||
#include <libssh/libssh_version.h>
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#ifdef LIBSSH_STATIC
|
||||
#define LIBSSH_API
|
||||
@@ -71,23 +73,6 @@
|
||||
#define SSH_STRINGIFY(s) SSH_TOSTRING(s)
|
||||
#define SSH_TOSTRING(s) #s
|
||||
|
||||
/* libssh version macros */
|
||||
#define SSH_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
|
||||
#define SSH_VERSION_DOT(a, b, c) a ##.## b ##.## c
|
||||
#define SSH_VERSION(a, b, c) SSH_VERSION_DOT(a, b, c)
|
||||
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 8
|
||||
#define LIBSSH_VERSION_MICRO 90
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
|
||||
/* GCC have printf type attribute check. */
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||
@@ -168,13 +153,13 @@ enum ssh_auth_e {
|
||||
};
|
||||
|
||||
/* auth flags */
|
||||
#define SSH_AUTH_METHOD_UNKNOWN 0
|
||||
#define SSH_AUTH_METHOD_NONE 0x0001
|
||||
#define SSH_AUTH_METHOD_PASSWORD 0x0002
|
||||
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004
|
||||
#define SSH_AUTH_METHOD_HOSTBASED 0x0008
|
||||
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010
|
||||
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020
|
||||
#define SSH_AUTH_METHOD_UNKNOWN 0x0000u
|
||||
#define SSH_AUTH_METHOD_NONE 0x0001u
|
||||
#define SSH_AUTH_METHOD_PASSWORD 0x0002u
|
||||
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004u
|
||||
#define SSH_AUTH_METHOD_HOSTBASED 0x0008u
|
||||
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010u
|
||||
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020u
|
||||
|
||||
/* messages */
|
||||
enum ssh_requests_e {
|
||||
@@ -441,6 +426,7 @@ enum ssh_scp_request_types {
|
||||
enum ssh_connector_flags_e {
|
||||
/** Only the standard stream of the channel */
|
||||
SSH_CONNECTOR_STDOUT = 1,
|
||||
SSH_CONNECTOR_STDINOUT = 1,
|
||||
/** Only the exception stream of the channel */
|
||||
SSH_CONNECTOR_STDERR = 2,
|
||||
/** Merge both standard and exception streams */
|
||||
@@ -632,7 +618,13 @@ LIBSSH_API ssh_pcap_file ssh_pcap_file_new(void);
|
||||
LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
||||
|
||||
/**
|
||||
* @brief SSH authentication callback.
|
||||
* @addtogroup libssh_auth
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SSH authentication callback for password and publickey auth.
|
||||
*
|
||||
* @param prompt Prompt to be displayed.
|
||||
* @param buf Buffer to save the password. You should null-terminate it.
|
||||
@@ -647,6 +639,8 @@ LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
||||
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
|
||||
int echo, int verify, void *userdata);
|
||||
|
||||
/** @} */
|
||||
|
||||
LIBSSH_API ssh_key ssh_key_new(void);
|
||||
#define SSH_KEY_FREE(x) \
|
||||
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
|
||||
|
||||
41
include/libssh/libssh_version.h.cmake
Normal file
41
include/libssh/libssh_version.h.cmake
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2020 by Heiko Thiery
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LIBSSH_VERSION_H
|
||||
#define _LIBSSH_VERSION_H
|
||||
|
||||
/* libssh version macros */
|
||||
#define SSH_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
|
||||
#define SSH_VERSION_DOT(a, b, c) a ##.## b ##.## c
|
||||
#define SSH_VERSION(a, b, c) SSH_VERSION_DOT(a, b, c)
|
||||
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR @libssh_VERSION_MAJOR@
|
||||
#define LIBSSH_VERSION_MINOR @libssh_VERSION_MINOR@
|
||||
#define LIBSSH_VERSION_MICRO @libssh_VERSION_PATCH@
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
|
||||
#endif /* _LIBSSH_VERSION_H */
|
||||
@@ -28,7 +28,7 @@ struct ssh_auth_request {
|
||||
int method;
|
||||
char *password;
|
||||
struct ssh_key_struct *pubkey;
|
||||
char signature_state;
|
||||
enum ssh_publickey_state_e signature_state;
|
||||
char kbdint_response;
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
char *ssh_get_user_home_dir(void);
|
||||
char *ssh_get_local_username(void);
|
||||
int ssh_file_readaccess_ok(const char *file);
|
||||
int ssh_dir_writeable(const char *path);
|
||||
|
||||
char *ssh_path_expand_tilde(const char *d);
|
||||
char *ssh_path_expand_escape(ssh_session session, const char *s);
|
||||
@@ -50,6 +51,12 @@ struct ssh_timestamp {
|
||||
long useconds;
|
||||
};
|
||||
|
||||
enum ssh_quote_state_e {
|
||||
NO_QUOTE,
|
||||
SINGLE_QUOTE,
|
||||
DOUBLE_QUOTE
|
||||
};
|
||||
|
||||
struct ssh_list *ssh_list_new(void);
|
||||
void ssh_list_free(struct ssh_list *list);
|
||||
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
||||
@@ -83,4 +90,11 @@ int ssh_match_group(const char *group, const char *object);
|
||||
|
||||
void uint64_inc(unsigned char *counter);
|
||||
|
||||
void ssh_log_hexdump(const char *descr, const unsigned char *what, size_t len);
|
||||
|
||||
int ssh_mkdirs(const char *pathname, mode_t mode);
|
||||
|
||||
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
|
||||
int ssh_newline_vis(const char *string, char *buf, size_t buf_len);
|
||||
|
||||
#endif /* MISC_H_ */
|
||||
|
||||
@@ -80,7 +80,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
|
||||
size_t start, size_t encrypted_size);
|
||||
unsigned char *ssh_packet_encrypt(ssh_session session,
|
||||
void *packet,
|
||||
unsigned int len);
|
||||
uint32_t len);
|
||||
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
|
||||
unsigned char *mac, enum ssh_hmac_e type);
|
||||
int ssh_packet_set_newkeys(ssh_session session,
|
||||
|
||||
@@ -30,7 +30,15 @@
|
||||
#endif
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
#ifdef HAVE_OPENSSL_ED25519
|
||||
/* If using OpenSSL implementation, define the signature lenght which would be
|
||||
* defined in libssh/ed25519.h otherwise */
|
||||
#define ED25519_SIG_LEN 64
|
||||
#else
|
||||
#include "libssh/ed25519.h"
|
||||
#endif
|
||||
/* This definition is used for both OpenSSL and internal implementations */
|
||||
#define ED25519_KEY_LEN 32
|
||||
|
||||
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
|
||||
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
|
||||
@@ -61,8 +69,13 @@ struct ssh_key_struct {
|
||||
void *ecdsa;
|
||||
# endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
#ifdef HAVE_OPENSSL_ED25519
|
||||
uint8_t *ed25519_pubkey;
|
||||
uint8_t *ed25519_privkey;
|
||||
#else
|
||||
ed25519_pubkey *ed25519_pubkey;
|
||||
ed25519_privkey *ed25519_privkey;
|
||||
#endif
|
||||
void *cert;
|
||||
enum ssh_keytypes_e cert_type;
|
||||
};
|
||||
@@ -79,7 +92,9 @@ struct ssh_signature_struct {
|
||||
ssh_string rsa_sig;
|
||||
struct mbedtls_ecdsa_sig ecdsa_sig;
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
#ifndef HAVE_OPENSSL_ED25519
|
||||
ed25519_signature *ed25519_sig;
|
||||
#endif
|
||||
ssh_string raw_sig;
|
||||
};
|
||||
|
||||
@@ -96,6 +111,7 @@ enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
|
||||
enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type);
|
||||
enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
|
||||
enum ssh_keytypes_e type);
|
||||
enum ssh_digest_e ssh_key_hash_from_name(const char *name);
|
||||
|
||||
#define is_ecdsa_key_type(t) \
|
||||
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
|
||||
@@ -109,6 +125,8 @@ enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
|
||||
/* SSH Signature Functions */
|
||||
ssh_signature ssh_signature_new(void);
|
||||
void ssh_signature_free(ssh_signature sign);
|
||||
#define SSH_SIGNATURE_FREE(x) \
|
||||
do { ssh_signature_free(x); x = NULL; } while(0)
|
||||
|
||||
int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||
ssh_string *sign_blob);
|
||||
@@ -118,7 +136,7 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
int ssh_pki_signature_verify(ssh_session session,
|
||||
ssh_signature sig,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
const unsigned char *digest,
|
||||
size_t dlen);
|
||||
|
||||
/* SSH Public Key Functions */
|
||||
@@ -138,7 +156,8 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||
struct ssh_buffer_struct *buf,
|
||||
const ssh_key pubkey);
|
||||
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
const ssh_key privkey);
|
||||
const ssh_key privkey,
|
||||
const enum ssh_digest_e digest);
|
||||
|
||||
/* Temporary functions, to be removed after migration to ssh_key */
|
||||
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);
|
||||
|
||||
@@ -124,11 +124,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
enum ssh_keytypes_e type,
|
||||
enum ssh_digest_e hash_type);
|
||||
int pki_signature_verify(ssh_session session,
|
||||
const ssh_signature sig,
|
||||
const ssh_key key,
|
||||
const unsigned char *input,
|
||||
size_t input_len);
|
||||
|
||||
/* SSH Signing Functions */
|
||||
ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
@@ -148,8 +143,8 @@ int pki_ed25519_key_cmp(const ssh_key k1,
|
||||
enum ssh_keycmp_e what);
|
||||
int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
|
||||
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
|
||||
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
|
||||
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
|
||||
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig);
|
||||
int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob);
|
||||
int pki_privkey_build_ed25519(ssh_key key,
|
||||
ssh_string pubkey,
|
||||
ssh_string privkey);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !defined(HAVE_STRTOULL)
|
||||
# if defined(HAVE___STRTOULL)
|
||||
@@ -221,7 +222,17 @@ int gettimeofday(struct timeval *__p, void *__t);
|
||||
struct ssh_common_struct;
|
||||
struct ssh_kex_struct;
|
||||
|
||||
int ssh_get_key_params(ssh_session session, ssh_key *privkey);
|
||||
enum ssh_digest_e {
|
||||
SSH_DIGEST_AUTO=0,
|
||||
SSH_DIGEST_SHA1=1,
|
||||
SSH_DIGEST_SHA256,
|
||||
SSH_DIGEST_SHA384,
|
||||
SSH_DIGEST_SHA512,
|
||||
};
|
||||
|
||||
int ssh_get_key_params(ssh_session session,
|
||||
ssh_key *privkey,
|
||||
enum ssh_digest_e *digest);
|
||||
|
||||
/* LOGGING */
|
||||
void ssh_log_function(int verbosity,
|
||||
@@ -272,14 +283,12 @@ int ssh_auth_reply_success(ssh_session session, int partial);
|
||||
int ssh_send_banner(ssh_session session, int is_server);
|
||||
|
||||
/* connect.c */
|
||||
socket_t ssh_connect_host(ssh_session session, const char *host,const char
|
||||
*bind_addr, int port, long timeout, long usec);
|
||||
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
||||
const char *bind_addr, int port);
|
||||
|
||||
/* in base64.c */
|
||||
ssh_buffer base64_to_bin(const char *source);
|
||||
unsigned char *bin_to_base64(const unsigned char *source, int len);
|
||||
uint8_t *bin_to_base64(const uint8_t *source, size_t len);
|
||||
|
||||
/* gzip.c */
|
||||
int compress_buffer(ssh_session session,ssh_buffer buf);
|
||||
@@ -397,22 +406,24 @@ void explicit_bzero(void *s, size_t n);
|
||||
# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
|
||||
#endif /* FALL_THROUGH */
|
||||
|
||||
#ifndef __unused__
|
||||
#ifndef __attr_unused__
|
||||
# ifdef HAVE_UNUSED_ATTRIBUTE
|
||||
# define __unused__ __attribute__((unused))
|
||||
# define __attr_unused__ __attribute__((unused))
|
||||
# else /* HAVE_UNUSED_ATTRIBUTE */
|
||||
# define __unused__
|
||||
# define __attr_unused__
|
||||
# endif /* HAVE_UNUSED_ATTRIBUTE */
|
||||
#endif /* __unused__ */
|
||||
#endif /* __attr_unused__ */
|
||||
|
||||
#ifndef UNUSED_PARAM
|
||||
#define UNUSED_PARAM(param) param __unused__
|
||||
#define UNUSED_PARAM(param) param __attr_unused__
|
||||
#endif /* UNUSED_PARAM */
|
||||
|
||||
#ifndef UNUSED_VAR
|
||||
#define UNUSED_VAR(var) __unused__ var
|
||||
#define UNUSED_VAR(var) __attr_unused__ var
|
||||
#endif /* UNUSED_VAR */
|
||||
|
||||
void ssh_agent_state_free(void *data);
|
||||
|
||||
bool is_ssh_initialized(void);
|
||||
|
||||
#endif /* _LIBSSH_PRIV_H */
|
||||
|
||||
@@ -145,7 +145,7 @@ struct ssh_session_struct {
|
||||
/* where it was before being interrupted */
|
||||
enum ssh_pending_call_e pending_call_state;
|
||||
enum ssh_session_state_e session_state;
|
||||
int packet_state;
|
||||
enum ssh_packet_state_e packet_state;
|
||||
enum ssh_dh_state_e dh_handshake_state;
|
||||
enum ssh_channel_request_state_e global_req_state;
|
||||
struct ssh_agent_state_struct *agent_state;
|
||||
@@ -188,6 +188,7 @@ struct ssh_session_struct {
|
||||
ssh_key ed25519_key;
|
||||
/* The type of host key wanted by client */
|
||||
enum ssh_keytypes_e hostkey;
|
||||
enum ssh_digest_e hostkey_digest;
|
||||
} srv;
|
||||
|
||||
/* auths accepted by server */
|
||||
@@ -212,7 +213,7 @@ struct ssh_session_struct {
|
||||
char *sshdir;
|
||||
char *knownhosts;
|
||||
char *global_knownhosts;
|
||||
char *wanted_methods[10];
|
||||
char *wanted_methods[SSH_KEX_METHODS];
|
||||
char *pubkey_accepted_types;
|
||||
char *ProxyCommand;
|
||||
char *custombanner;
|
||||
|
||||
@@ -201,13 +201,18 @@ struct sftp_statvfs_struct {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Start a new sftp session.
|
||||
* @brief Creates a new sftp session.
|
||||
*
|
||||
* This function creates a new sftp session and allocates a new sftp channel
|
||||
* with the server inside of the provided ssh session. This function call is
|
||||
* usually followed by the sftp_init(), which initializes SFTP protocol itself.
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @return A new sftp session or NULL on error.
|
||||
*
|
||||
* @see sftp_free()
|
||||
* @see sftp_init()
|
||||
*/
|
||||
LIBSSH_API sftp_session sftp_new(ssh_session session);
|
||||
|
||||
@@ -232,7 +237,10 @@ LIBSSH_API sftp_session sftp_new_channel(ssh_session session, ssh_channel channe
|
||||
LIBSSH_API void sftp_free(sftp_session sftp);
|
||||
|
||||
/**
|
||||
* @brief Initialize the sftp session with the server.
|
||||
* @brief Initialize the sftp protocol with the server.
|
||||
*
|
||||
* This function involves the SFTP protocol initialization (as described
|
||||
* in the SFTP specification), including the version and extensions negotiation.
|
||||
*
|
||||
* @param sftp The sftp session to initialize.
|
||||
*
|
||||
@@ -862,13 +870,6 @@ LIBSSH_API int sftp_server_init(sftp_session sftp);
|
||||
LIBSSH_API void sftp_server_free(sftp_session sftp);
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
/* this is not a public interface */
|
||||
#define SFTP_HANDLES 256
|
||||
sftp_packet sftp_packet_read(sftp_session sftp);
|
||||
int sftp_packet_write(sftp_session sftp,uint8_t type, ssh_buffer payload);
|
||||
void sftp_packet_free(sftp_packet packet);
|
||||
int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr);
|
||||
sftp_attributes sftp_parse_attr(sftp_session session, ssh_buffer buf,int expectname);
|
||||
/* sftpserver.c */
|
||||
|
||||
LIBSSH_API sftp_client_message sftp_get_client_message(sftp_session sftp);
|
||||
|
||||
32
include/libssh/sftp_priv.h
Normal file
32
include/libssh/sftp_priv.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef SFTP_PRIV_H
|
||||
#define SFTP_PRIV_H
|
||||
|
||||
sftp_packet sftp_packet_read(sftp_session sftp);
|
||||
ssize_t sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload);
|
||||
void sftp_packet_free(sftp_packet packet);
|
||||
int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr);
|
||||
sftp_attributes sftp_parse_attr(sftp_session session,
|
||||
ssh_buffer buf,
|
||||
int expectname);
|
||||
|
||||
#endif /* SFTP_PRIV_H */
|
||||
@@ -63,6 +63,9 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
|
||||
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);
|
||||
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle(ssh_socket s);
|
||||
|
||||
int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr);
|
||||
int ssh_socket_connect(ssh_socket s,
|
||||
const char *host,
|
||||
uint16_t port,
|
||||
const char *bind_addr);
|
||||
|
||||
#endif /* SOCKET_H_ */
|
||||
|
||||
@@ -38,7 +38,11 @@ void ssh_tokens_free(struct ssh_tokens_st *tokens);
|
||||
char *ssh_find_matching(const char *available_d,
|
||||
const char *preferred_d);
|
||||
|
||||
|
||||
char *ssh_find_all_matching(const char *available_d,
|
||||
const char *preferred_d);
|
||||
|
||||
char *ssh_remove_duplicates(const char *list);
|
||||
|
||||
char *ssh_append_without_duplicates(const char *list,
|
||||
const char *appended_list);
|
||||
#endif /* TOKEN_H_ */
|
||||
|
||||
@@ -29,14 +29,6 @@
|
||||
#include "libssh/libgcrypt.h"
|
||||
#include "libssh/libmbedcrypto.h"
|
||||
|
||||
enum ssh_digest_e {
|
||||
SSH_DIGEST_AUTO=0,
|
||||
SSH_DIGEST_SHA1=1,
|
||||
SSH_DIGEST_SHA256,
|
||||
SSH_DIGEST_SHA384,
|
||||
SSH_DIGEST_SHA512,
|
||||
};
|
||||
|
||||
enum ssh_kdf_digest {
|
||||
SSH_KDF_SHA1=1,
|
||||
SSH_KDF_SHA256,
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/CMakeCache.txt")
|
||||
# In tree build
|
||||
set_and_check(LIBSSH_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
|
||||
set_and_check(LIBSSH_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/@LIBSSH_LIBRARY_NAME@")
|
||||
else()
|
||||
set_and_check(LIBSSH_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||
set_and_check(LIBSSH_LIBRARIES "@PACKAGE_LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@")
|
||||
endif()
|
||||
|
||||
# For backward compatibility
|
||||
set(LIBSSH_LIBRARY ${LIBSSH_LIBRARIES})
|
||||
|
||||
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_LIBRARY LIBSSH_INCLUDE_DIR)
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: ${PROJECT_NAME}
|
||||
Description: The SSH Library
|
||||
Version: ${PROJECT_VERSION}
|
||||
Libs: -L${LIB_INSTALL_DIR} -lssh
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}
|
||||
Libs: -L${CMAKE_INSTALL_FULL_LIBDIR} -lssh
|
||||
Cflags: -I${CMAKE_INSTALL_FULL_INCLUDEDIR}
|
||||
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Last Change: 2008-06-18 14:13:46
|
||||
#
|
||||
# Script to build libssh on UNIX.
|
||||
#
|
||||
# Copyright (c) 2006-2007 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
|
||||
SOURCE_DIR=".."
|
||||
|
||||
LANG=C
|
||||
export LANG
|
||||
|
||||
SCRIPT="$0"
|
||||
COUNT=0
|
||||
while [ -L "${SCRIPT}" ]
|
||||
do
|
||||
SCRIPT=$(readlink ${SCRIPT})
|
||||
COUNT=$(expr ${COUNT} + 1)
|
||||
if [ ${COUNT} -gt 100 ]; then
|
||||
echo "Too many symbolic links"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
BUILDDIR=$(dirname ${SCRIPT})
|
||||
|
||||
cleanup_and_exit () {
|
||||
if test "$1" = 0 -o -z "$1" ; then
|
||||
exit 0
|
||||
else
|
||||
exit $1
|
||||
fi
|
||||
}
|
||||
|
||||
function configure() {
|
||||
if [ -n "${CMAKEDIR}" ]; then
|
||||
${CMAKEDIR}/bin/cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||
else
|
||||
cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||
fi
|
||||
}
|
||||
|
||||
function compile() {
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
CPUCOUNT=$(grep -c processor /proc/cpuinfo)
|
||||
elif test `uname` = "SunOS" ; then
|
||||
CPUCOUNT=$(psrinfo -p)
|
||||
else
|
||||
CPUCOUNT="1"
|
||||
fi
|
||||
|
||||
if [ "${CPUCOUNT}" -gt "1" ]; then
|
||||
${MAKE} -j${CPUCOUNT} $1 || cleanup_and_exit $?
|
||||
else
|
||||
${MAKE} $1 || exit $?
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_build_dir() {
|
||||
find ! -path "*.svn*" ! -name "*.bat" ! -name "*.sh" ! -name "." -print0 | xargs -0 rm -rf
|
||||
}
|
||||
|
||||
function usage () {
|
||||
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make
|
||||
(gmake|make)|--ccompiler(gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withserver|--withoutsymbolversioning]"
|
||||
cleanup_and_exit
|
||||
}
|
||||
|
||||
cd ${BUILDDIR}
|
||||
|
||||
# the default CMake options:
|
||||
OPTIONS="--graphviz=${BUILDDIR}/libssh.dot"
|
||||
|
||||
# the default 'make' utility:
|
||||
MAKE="make"
|
||||
|
||||
while test -n "$1"; do
|
||||
PARAM="$1"
|
||||
ARG="$2"
|
||||
shift
|
||||
case ${PARAM} in
|
||||
*-*=*)
|
||||
ARG=${PARAM#*=}
|
||||
PARAM=${PARAM%%=*}
|
||||
set -- "----noarg=${PARAM}" "$@"
|
||||
esac
|
||||
case ${PARAM} in
|
||||
*-help|-h)
|
||||
#echo_help
|
||||
usage
|
||||
cleanup_and_exit
|
||||
;;
|
||||
*-build)
|
||||
DOMAKE="1"
|
||||
BUILD_TYPE="${ARG}"
|
||||
test -n "${BUILD_TYPE}" && shift
|
||||
;;
|
||||
*-clean)
|
||||
clean_build_dir
|
||||
cleanup_and_exit
|
||||
;;
|
||||
*-clang)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
|
||||
;;
|
||||
*-verbose)
|
||||
DOVERBOSE="1"
|
||||
;;
|
||||
*-memtest)
|
||||
OPTIONS="${OPTIONS} -DMEM_NULL_TESTS=ON"
|
||||
;;
|
||||
*-libsuffix)
|
||||
OPTIONS="${OPTIONS} -DLIB_SUFFIX=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-prefix)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_INSTALL_PREFIX=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-sysconfdir)
|
||||
OPTIONS="${OPTIONS} -DSYSCONF_INSTALL_DIR=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-cmakedir)
|
||||
CMAKEDIR="${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-make)
|
||||
MAKE="${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-ccompiler)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-withstaticlib)
|
||||
OPTIONS="${OPTIONS} -DWITH_STATIC_LIB=ON"
|
||||
;;
|
||||
*-unittesting)
|
||||
OPTIONS="${OPTIONS} -DUNIT_TESTING=ON"
|
||||
;;
|
||||
*-clientunittesting)
|
||||
OPTIONS="${OPTIONS} -DCLIENT_TESTING=ON"
|
||||
;;
|
||||
*-withserver)
|
||||
OPTIONS="${OPTIONS} -DWITH_SERVER=ON"
|
||||
;;
|
||||
*-withoutsymbolversioning)
|
||||
OPTIONS="${OPTIONS} -DWITH_SYMBOL_VERSIONING=OFF"
|
||||
;;
|
||||
*-finalrelease)
|
||||
OPTIONS="${OPTIONS} -DWITH_FINAL=ON"
|
||||
;;
|
||||
----noarg)
|
||||
echo "$ARG does not take an argument"
|
||||
cleanup_and_exit
|
||||
;;
|
||||
-*)
|
||||
echo Unknown Option "$PARAM". Exit.
|
||||
cleanup_and_exit 1
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "${DOMAKE}" == "1" ]; then
|
||||
OPTIONS="${OPTIONS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE}"
|
||||
fi
|
||||
|
||||
if [ -n "${DOVERBOSE}" ]; then
|
||||
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=1"
|
||||
else
|
||||
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=0"
|
||||
fi
|
||||
|
||||
test -f "${BUILDDIR}/.build.log" && rm -f ${BUILDDIR}/.build.log
|
||||
touch ${BUILDDIR}/.build.log
|
||||
# log everything from here to .build.log
|
||||
exec 1> >(exec -a 'build logging tee' tee -a ${BUILDDIR}/.build.log) 2>&1
|
||||
echo "${HOST} started build at $(date)."
|
||||
echo
|
||||
|
||||
configure ${OPTIONS} "$@"
|
||||
|
||||
if [ -n "${DOMAKE}" ]; then
|
||||
test -n "${DOVERBOSE}" && compile VERBOSE=1 || compile
|
||||
fi
|
||||
|
||||
DOT=$(which dot 2>/dev/null)
|
||||
if [ -n "${DOT}" ]; then
|
||||
${DOT} -Tpng -o${BUILDDIR}/libssh.png ${BUILDDIR}/libssh.dot
|
||||
${DOT} -Tsvg -o${BUILDDIR}/libssh.svg ${BUILDDIR}/libssh.dot
|
||||
fi
|
||||
|
||||
exec >&0 2>&0 # so that the logging tee finishes
|
||||
sleep 1 # wait till tee terminates
|
||||
|
||||
cleanup_and_exit 0
|
||||
@@ -1 +1 @@
|
||||
4.8.1
|
||||
4.8.7
|
||||
421
src/ABI/libssh-4.8.2.symbols
Normal file
421
src/ABI/libssh-4.8.2.symbols
Normal file
@@ -0,0 +1,421 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_free
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_parse_config
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_forward_unix
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_open_reply_accept_channel
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_get_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_default
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
421
src/ABI/libssh-4.8.3.symbols
Normal file
421
src/ABI/libssh-4.8.3.symbols
Normal file
@@ -0,0 +1,421 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_free
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_parse_config
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_forward_unix
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_open_reply_accept_channel
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_get_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_default
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
421
src/ABI/libssh-4.8.4.symbols
Normal file
421
src/ABI/libssh-4.8.4.symbols
Normal file
@@ -0,0 +1,421 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_free
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_parse_config
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_forward_unix
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_open_reply_accept_channel
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_get_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_default
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
421
src/ABI/libssh-4.8.5.symbols
Normal file
421
src/ABI/libssh-4.8.5.symbols
Normal file
@@ -0,0 +1,421 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_free
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_parse_config
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_forward_unix
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_open_reply_accept_channel
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_get_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_default
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
421
src/ABI/libssh-4.8.6.symbols
Normal file
421
src/ABI/libssh-4.8.6.symbols
Normal file
@@ -0,0 +1,421 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_free
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_parse_config
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_forward_unix
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_open_reply_accept_channel
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_get_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_default
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
421
src/ABI/libssh-4.8.7.symbols
Normal file
421
src/ABI/libssh-4.8.7.symbols
Normal file
@@ -0,0 +1,421 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_free
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_parse_config
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_forward_unix
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_open_reply_accept_channel
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_get_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_default
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
@@ -1,9 +1,7 @@
|
||||
set(LIBSSH_PUBLIC_INCLUDE_DIRS
|
||||
${libssh_SOURCE_DIR}/include
|
||||
CACHE INTERNAL "libssh public include directories"
|
||||
)
|
||||
set(LIBSSH_PUBLIC_INCLUDE_DIRS ${libssh_SOURCE_DIR}/include)
|
||||
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${libssh_BINARY_DIR}/include
|
||||
${libssh_BINARY_DIR}
|
||||
)
|
||||
|
||||
@@ -18,14 +16,7 @@ if (WIN32)
|
||||
)
|
||||
endif (WIN32)
|
||||
|
||||
if (HAVE_LIBSOCKET)
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
socket
|
||||
)
|
||||
endif (HAVE_LIBSOCKET)
|
||||
|
||||
if (OPENSSL_CRYPTO_LIBRARY)
|
||||
if (OPENSSL_CRYPTO_LIBRARIES)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
@@ -33,9 +24,9 @@ if (OPENSSL_CRYPTO_LIBRARY)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${OPENSSL_CRYPTO_LIBRARY}
|
||||
${OPENSSL_CRYPTO_LIBRARIES}
|
||||
)
|
||||
endif (OPENSSL_CRYPTO_LIBRARY)
|
||||
endif (OPENSSL_CRYPTO_LIBRARIES)
|
||||
|
||||
if (MBEDTLS_CRYPTO_LIBRARY)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
@@ -95,15 +86,12 @@ if (WITH_NACL AND NACL_FOUND)
|
||||
)
|
||||
endif (WITH_NACL AND NACL_FOUND)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
CACHE INTERNAL "libssh link libraries"
|
||||
)
|
||||
|
||||
set(LIBSSH_SHARED_LIBRARY
|
||||
ssh_shared
|
||||
CACHE INTERNAL "libssh shared library"
|
||||
)
|
||||
if (MINGW AND Threads_FOUND)
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
Threads::Threads
|
||||
)
|
||||
endif()
|
||||
|
||||
if (BUILD_STATIC_LIB)
|
||||
set(LIBSSH_STATIC_LIBRARY
|
||||
@@ -146,7 +134,6 @@ set(libssh_SRCS
|
||||
pcap.c
|
||||
pki.c
|
||||
pki_container_openssh.c
|
||||
pki_ed25519.c
|
||||
poll.c
|
||||
session.c
|
||||
scp.c
|
||||
@@ -157,14 +144,11 @@ set(libssh_SRCS
|
||||
external/bcrypt_pbkdf.c
|
||||
external/blowfish.c
|
||||
external/chacha.c
|
||||
external/ed25519.c
|
||||
external/fe25519.c
|
||||
external/ge25519.c
|
||||
external/poly1305.c
|
||||
external/sc25519.c
|
||||
chachapoly.c
|
||||
config_parser.c
|
||||
token.c
|
||||
pki_ed25519_common.c
|
||||
)
|
||||
|
||||
if (DEFAULT_C_NO_DEPRECATION_FLAGS)
|
||||
@@ -201,6 +185,11 @@ if (WITH_GCRYPT)
|
||||
pki_gcrypt.c
|
||||
ecdh_gcrypt.c
|
||||
dh_key.c
|
||||
pki_ed25519.c
|
||||
external/ed25519.c
|
||||
external/fe25519.c
|
||||
external/ge25519.c
|
||||
external/sc25519.c
|
||||
)
|
||||
elseif (WITH_MBEDTLS)
|
||||
set(libssh_SRCS
|
||||
@@ -211,6 +200,11 @@ elseif (WITH_MBEDTLS)
|
||||
pki_mbedcrypto.c
|
||||
ecdh_mbedcrypto.c
|
||||
dh_key.c
|
||||
pki_ed25519.c
|
||||
external/ed25519.c
|
||||
external/fe25519.c
|
||||
external/ge25519.c
|
||||
external/sc25519.c
|
||||
)
|
||||
else (WITH_GCRYPT)
|
||||
set(libssh_SRCS
|
||||
@@ -221,6 +215,16 @@ else (WITH_GCRYPT)
|
||||
libcrypto.c
|
||||
dh_crypto.c
|
||||
)
|
||||
if (NOT HAVE_OPENSSL_ED25519)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
pki_ed25519.c
|
||||
external/ed25519.c
|
||||
external/fe25519.c
|
||||
external/ge25519.c
|
||||
external/sc25519.c
|
||||
)
|
||||
endif (NOT HAVE_OPENSSL_ED25519)
|
||||
if(OPENSSL_VERSION VERSION_LESS "1.1.0")
|
||||
set(libssh_SRCS ${libssh_SRCS} libcrypto-compat.c)
|
||||
endif()
|
||||
@@ -271,17 +275,14 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
|
||||
if (NOT WITH_NACL)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
external/curve25519_ref.c
|
||||
)
|
||||
if (NOT HAVE_OPENSSL_ED25519)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
external/curve25519_ref.c
|
||||
)
|
||||
endif (NOT HAVE_OPENSSL_ED25519)
|
||||
endif (NOT WITH_NACL)
|
||||
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Set the path to the default map file
|
||||
set(MAP_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.map")
|
||||
|
||||
@@ -313,13 +314,27 @@ if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
|
||||
)
|
||||
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
|
||||
|
||||
add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS})
|
||||
target_compile_options(${LIBSSH_SHARED_LIBRARY}
|
||||
# This gets built as a static library, if -DBUILD_SHARED_LIBS=OFF is passed to
|
||||
# cmake.
|
||||
add_library(ssh ${libssh_SRCS})
|
||||
target_compile_options(ssh
|
||||
PRIVATE
|
||||
${DEFAULT_C_COMPILE_FLAGS}
|
||||
-D_GNU_SOURCE)
|
||||
target_include_directories(ssh
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${libssh_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PRIVATE ${LIBSSH_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
|
||||
target_link_libraries(ssh
|
||||
PRIVATE ${LIBSSH_LINK_LIBRARIES})
|
||||
|
||||
if (WIN32 AND NOT BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(ssh PUBLIC "LIBSSH_STATIC")
|
||||
endif ()
|
||||
|
||||
add_library(ssh::ssh ALIAS ssh)
|
||||
|
||||
if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
|
||||
if (ABIMAP_FOUND)
|
||||
@@ -327,56 +342,62 @@ if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
|
||||
set(MAP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_dev.map")
|
||||
endif (ABIMAP_FOUND)
|
||||
|
||||
set_target_properties(${LIBSSH_SHARED_LIBRARY}
|
||||
PROPERTIES LINK_FLAGS
|
||||
"-Wl,--version-script,\"${MAP_PATH}\"")
|
||||
target_link_libraries(ssh PRIVATE "-Wl,--version-script,\"${MAP_PATH}\"")
|
||||
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
set_target_properties(ssh
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh
|
||||
DEFINE_SYMBOL
|
||||
LIBSSH_EXPORTS
|
||||
)
|
||||
|
||||
if (WITH_VISIBILITY_HIDDEN)
|
||||
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
set_target_properties(ssh PROPERTIES C_VISIBILITY_PRESET hidden)
|
||||
endif (WITH_VISIBILITY_HIDDEN)
|
||||
|
||||
if (MINGW)
|
||||
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
|
||||
target_link_libraries(ssh PRIVATE "-Wl,--enable-stdcall-fixup")
|
||||
target_compile_definitions(ssh PRIVATE "_POSIX_SOURCE")
|
||||
endif ()
|
||||
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
COMPONENT libraries
|
||||
)
|
||||
install(TARGETS ssh
|
||||
EXPORT libssh-config
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT libraries)
|
||||
|
||||
install(EXPORT libssh-config
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
|
||||
if (BUILD_STATIC_LIB)
|
||||
add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS})
|
||||
target_compile_options(${LIBSSH_STATIC_LIBRARY}
|
||||
add_library(ssh-static STATIC ${libssh_SRCS})
|
||||
target_compile_options(ssh-static
|
||||
PRIVATE
|
||||
${DEFAULT_C_COMPILE_FLAGS}
|
||||
-D_GNU_SOURCE)
|
||||
|
||||
target_include_directories(ssh-static
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${libssh_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PRIVATE ${LIBSSH_PRIVATE_INCLUDE_DIRS})
|
||||
target_link_libraries(ssh-static
|
||||
PUBLIC ${LIBSSH_LINK_LIBRARIES})
|
||||
add_library(ssh::static ALIAS ssh-static)
|
||||
|
||||
if (MSVC)
|
||||
set(OUTPUT_SUFFIX static)
|
||||
else (MSVC)
|
||||
set(OUTPUT_SUFFIX )
|
||||
endif (MSVC)
|
||||
set_target_properties(
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
ssh-static
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
@@ -389,22 +410,8 @@ if (BUILD_STATIC_LIB)
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"-DLIBSSH_STATIC"
|
||||
)
|
||||
target_compile_definitions(ssh-static PUBLIC "LIBSSH_STATIC")
|
||||
endif (WIN32)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
install(TARGETS
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
|
||||
COMPONENT
|
||||
libraries)
|
||||
endif (WITH_STATIC_LIB)
|
||||
endif (BUILD_STATIC_LIB)
|
||||
|
||||
message(STATUS "Threads_FOUND=${Threads_FOUND}")
|
||||
|
||||
191
src/agent.c
191
src/agent.c
@@ -196,7 +196,7 @@ void ssh_agent_close(struct ssh_agent_struct *agent) {
|
||||
void ssh_agent_free(ssh_agent agent) {
|
||||
if (agent) {
|
||||
if (agent->ident) {
|
||||
ssh_buffer_free(agent->ident);
|
||||
SSH_BUFFER_FREE(agent->ident);
|
||||
}
|
||||
if (agent->sock) {
|
||||
ssh_agent_close(agent);
|
||||
@@ -307,90 +307,91 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
ssh_buffer request = NULL;
|
||||
ssh_buffer reply = NULL;
|
||||
unsigned int type = 0;
|
||||
uint32_t count = 0;
|
||||
int rc;
|
||||
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
|
||||
{
|
||||
ssh_buffer request = NULL;
|
||||
ssh_buffer reply = NULL;
|
||||
unsigned int type = 0;
|
||||
uint32_t count = 0;
|
||||
int rc;
|
||||
|
||||
/* send message to the agent requesting the list of identities */
|
||||
request = ssh_buffer_new();
|
||||
if (request == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_buffer_add_u8(request, SSH2_AGENTC_REQUEST_IDENTITIES) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(request);
|
||||
return -1;
|
||||
}
|
||||
/* send message to the agent requesting the list of identities */
|
||||
request = ssh_buffer_new();
|
||||
if (request == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return 0;
|
||||
}
|
||||
if (ssh_buffer_add_u8(request, SSH2_AGENTC_REQUEST_IDENTITIES) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reply = ssh_buffer_new();
|
||||
if (reply == NULL) {
|
||||
ssh_buffer_free(request);
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
return -1;
|
||||
}
|
||||
reply = ssh_buffer_new();
|
||||
if (reply == NULL) {
|
||||
SSH_BUFFER_FREE(request);
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (agent_talk(session, request, reply) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
ssh_buffer_free(reply);
|
||||
return 0;
|
||||
}
|
||||
ssh_buffer_free(request);
|
||||
if (agent_talk(session, request, reply) < 0) {
|
||||
SSH_BUFFER_FREE(request);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return 0;
|
||||
}
|
||||
SSH_BUFFER_FREE(request);
|
||||
|
||||
/* get message type and verify the answer */
|
||||
rc = ssh_buffer_get_u8(reply, (uint8_t *) &type);
|
||||
if (rc != sizeof(uint8_t)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad authentication reply size: %d", rc);
|
||||
ssh_buffer_free(reply);
|
||||
return -1;
|
||||
}
|
||||
/* get message type and verify the answer */
|
||||
rc = ssh_buffer_get_u8(reply, (uint8_t *) &type);
|
||||
if (rc != sizeof(uint8_t)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad authentication reply size: %d", rc);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return 0;
|
||||
}
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
type = bswap_32(type);
|
||||
type = bswap_32(type);
|
||||
#endif
|
||||
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Answer type: %d, expected answer: %d",
|
||||
type, SSH2_AGENT_IDENTITIES_ANSWER);
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Answer type: %d, expected answer: %d",
|
||||
type, SSH2_AGENT_IDENTITIES_ANSWER);
|
||||
|
||||
if (agent_failed(type)) {
|
||||
ssh_buffer_free(reply);
|
||||
return 0;
|
||||
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad authentication reply message type: %u", type);
|
||||
ssh_buffer_free(reply);
|
||||
return -1;
|
||||
}
|
||||
if (agent_failed(type)) {
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return 0;
|
||||
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad authentication reply message type: %u", type);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_get_u32(reply, &count);
|
||||
if (rc != 4) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Failed to read count");
|
||||
ssh_buffer_free(reply);
|
||||
return -1;
|
||||
}
|
||||
session->agent->count = ntohl(count);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
|
||||
session->agent->count);
|
||||
if (session->agent->count > 1024) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Too many identities in authentication reply: %d",
|
||||
session->agent->count);
|
||||
ssh_buffer_free(reply);
|
||||
return -1;
|
||||
}
|
||||
rc = ssh_buffer_get_u32(reply, &count);
|
||||
if (rc != 4) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Failed to read count");
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return 0;
|
||||
}
|
||||
session->agent->count = ntohl(count);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
|
||||
session->agent->count);
|
||||
if (session->agent->count > 1024) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Too many identities in authentication reply: %d",
|
||||
session->agent->count);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (session->agent->ident) {
|
||||
ssh_buffer_reinit(session->agent->ident);
|
||||
}
|
||||
session->agent->ident = reply;
|
||||
if (session->agent->ident) {
|
||||
ssh_buffer_reinit(session->agent->ident);
|
||||
}
|
||||
session->agent->ident = reply;
|
||||
|
||||
return session->agent->count;
|
||||
return session->agent->count;
|
||||
}
|
||||
|
||||
/* caller has to free commment */
|
||||
@@ -424,7 +425,7 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||
/* get the comment */
|
||||
tmp = ssh_buffer_get_ssh_string(session->agent->ident);
|
||||
if (tmp == NULL) {
|
||||
ssh_string_free(blob);
|
||||
SSH_STRING_FREE(blob);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -432,12 +433,12 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||
if (comment) {
|
||||
*comment = ssh_string_to_char(tmp);
|
||||
} else {
|
||||
ssh_string_free(blob);
|
||||
ssh_string_free(tmp);
|
||||
SSH_STRING_FREE(blob);
|
||||
SSH_STRING_FREE(tmp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_free(tmp);
|
||||
SSH_STRING_FREE(tmp);
|
||||
|
||||
/* get key from blob */
|
||||
rc = ssh_pki_import_pubkey_blob(blob, &key);
|
||||
@@ -445,7 +446,7 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||
/* Try again as a cert. */
|
||||
rc = ssh_pki_import_cert_blob(blob, &key);
|
||||
}
|
||||
ssh_string_free(blob);
|
||||
SSH_STRING_FREE(blob);
|
||||
if (rc == SSH_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -491,13 +492,13 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
|
||||
/* create request */
|
||||
if (ssh_buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = ssh_pki_export_pubkey_blob(pubkey, &key_blob);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -512,26 +513,26 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
sizeof(uint32_t) * 2 +
|
||||
ssh_string_len(key_blob));
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* adds len + blob */
|
||||
rc = ssh_buffer_add_ssh_string(request, key_blob);
|
||||
ssh_string_free(key_blob);
|
||||
SSH_STRING_FREE(key_blob);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add data */
|
||||
dlen = ssh_buffer_get_len(data);
|
||||
if (ssh_buffer_add_u32(request, htonl(dlen)) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
if (ssh_buffer_add_data(request, ssh_buffer_get(data), dlen) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -544,27 +545,27 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
}
|
||||
}
|
||||
if (ssh_buffer_add_u32(request, htonl(flags)) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reply = ssh_buffer_new();
|
||||
if (reply == NULL) {
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* send the request */
|
||||
if (agent_talk(session, request, reply) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
ssh_buffer_free(reply);
|
||||
SSH_BUFFER_FREE(request);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return NULL;
|
||||
}
|
||||
ssh_buffer_free(request);
|
||||
SSH_BUFFER_FREE(request);
|
||||
|
||||
/* check if reply is valid */
|
||||
if (ssh_buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) {
|
||||
ssh_buffer_free(reply);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
@@ -573,19 +574,19 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
|
||||
if (agent_failed(type)) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key");
|
||||
ssh_buffer_free(reply);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return NULL;
|
||||
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Bad authentication response: %u",
|
||||
type);
|
||||
ssh_buffer_free(reply);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig_blob = ssh_buffer_get_ssh_string(reply);
|
||||
ssh_buffer_free(reply);
|
||||
SSH_BUFFER_FREE(reply);
|
||||
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
37
src/auth.c
37
src/auth.c
@@ -25,6 +25,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -69,7 +70,7 @@ static int ssh_userauth_request_service(ssh_session session) {
|
||||
int rc;
|
||||
|
||||
rc = ssh_service_request(session, "ssh-userauth");
|
||||
if (rc != SSH_OK) {
|
||||
if ((rc != SSH_OK) && (rc != SSH_AGAIN)) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Failed to request \"ssh-userauth\" service");
|
||||
}
|
||||
@@ -204,7 +205,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_banner) {
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Received SSH_USERAUTH_BANNER packet");
|
||||
if (session->banner != NULL)
|
||||
ssh_string_free(session->banner);
|
||||
SSH_STRING_FREE(session->banner);
|
||||
session->banner = banner;
|
||||
}
|
||||
|
||||
@@ -557,7 +558,7 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ssh_string_free(pubkey_s);
|
||||
SSH_STRING_FREE(pubkey_s);
|
||||
|
||||
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
|
||||
session->auth.state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT;
|
||||
@@ -575,7 +576,7 @@ pending:
|
||||
|
||||
return rc;
|
||||
fail:
|
||||
ssh_string_free(pubkey_s);
|
||||
SSH_STRING_FREE(pubkey_s);
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
@@ -680,7 +681,7 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
|
||||
/* Get the hash type to be used in the signature based on the key type */
|
||||
hash_type = ssh_key_type_to_hash(session, privkey->type);
|
||||
@@ -692,7 +693,7 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
}
|
||||
|
||||
rc = ssh_buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
str = NULL;
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
@@ -714,7 +715,7 @@ pending:
|
||||
|
||||
return rc;
|
||||
fail:
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
@@ -840,7 +841,7 @@ void ssh_agent_state_free(void *data) {
|
||||
struct ssh_agent_state_struct *state = data;
|
||||
|
||||
if (state) {
|
||||
ssh_string_free_char(state->comment);
|
||||
SSH_STRING_FREE_CHAR(state->comment);
|
||||
ssh_key_free(state->pubkey);
|
||||
free (state);
|
||||
}
|
||||
@@ -918,7 +919,7 @@ int ssh_userauth_agent(ssh_session session,
|
||||
} else if (rc != SSH_AUTH_SUCCESS) {
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Public key of %s refused by server", state->comment);
|
||||
ssh_string_free_char(state->comment);
|
||||
SSH_STRING_FREE_CHAR(state->comment);
|
||||
state->comment = NULL;
|
||||
ssh_key_free(state->pubkey);
|
||||
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
|
||||
@@ -934,7 +935,7 @@ int ssh_userauth_agent(ssh_session session,
|
||||
rc = ssh_userauth_agent_publickey(session, username, state->pubkey);
|
||||
if (rc == SSH_AUTH_AGAIN)
|
||||
return rc;
|
||||
ssh_string_free_char(state->comment);
|
||||
SSH_STRING_FREE_CHAR(state->comment);
|
||||
state->comment = NULL;
|
||||
if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_PARTIAL) {
|
||||
ssh_agent_state_free (session->agent_state);
|
||||
@@ -1030,6 +1031,9 @@ int ssh_userauth_publickey_auto(ssh_session session,
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* Set state explicitly */
|
||||
session->auth.auto_state->state = SSH_AUTH_AUTO_STATE_NONE;
|
||||
}
|
||||
state = session->auth.auto_state;
|
||||
if (state->state == SSH_AUTH_AUTO_STATE_NONE) {
|
||||
@@ -1112,7 +1116,9 @@ int ssh_userauth_publickey_auto(ssh_session session,
|
||||
"Public key authentication error for %s",
|
||||
privkey_file);
|
||||
ssh_key_free(state->privkey);
|
||||
state->privkey = NULL;
|
||||
ssh_key_free(state->pubkey);
|
||||
state->pubkey = NULL;
|
||||
SAFE_FREE(session->auth.auto_state);
|
||||
return rc;
|
||||
} else if (rc == SSH_AUTH_AGAIN) {
|
||||
@@ -1178,6 +1184,9 @@ int ssh_userauth_publickey_auto(ssh_session session,
|
||||
return rc;
|
||||
}
|
||||
|
||||
ssh_key_free(state->privkey);
|
||||
ssh_key_free(state->pubkey);
|
||||
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"The server accepted the public key but refused the signature");
|
||||
state->it = state->it->next;
|
||||
@@ -1329,7 +1338,7 @@ ssh_kbdint ssh_kbdint_new(void) {
|
||||
|
||||
|
||||
void ssh_kbdint_free(ssh_kbdint kbd) {
|
||||
int i, n;
|
||||
size_t i, n;
|
||||
|
||||
if (kbd == NULL) {
|
||||
return;
|
||||
@@ -1365,7 +1374,7 @@ void ssh_kbdint_free(ssh_kbdint kbd) {
|
||||
}
|
||||
|
||||
void ssh_kbdint_clean(ssh_kbdint kbd) {
|
||||
int i, n;
|
||||
size_t i, n;
|
||||
|
||||
if (kbd == NULL) {
|
||||
return;
|
||||
@@ -1554,7 +1563,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
|
||||
);
|
||||
|
||||
/* We don't care about tmp */
|
||||
ssh_string_free(tmp);
|
||||
SSH_STRING_FREE(tmp);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
|
||||
@@ -1778,7 +1787,7 @@ const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i,
|
||||
}
|
||||
|
||||
if (echo) {
|
||||
*echo = session->kbdint->echo[i];
|
||||
*echo = (char)session->kbdint->echo[i];
|
||||
}
|
||||
|
||||
return session->kbdint->prompts[i];
|
||||
|
||||
98
src/base64.c
98
src/base64.c
@@ -29,7 +29,8 @@
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/buffer.h"
|
||||
|
||||
static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
static
|
||||
const uint8_t alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
@@ -167,19 +168,19 @@ ssh_buffer base64_to_bin(const char *source) {
|
||||
|
||||
error:
|
||||
SAFE_FREE(base64);
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define BLOCK(letter, n) do {ptr = strchr(alphabet, source[n]); \
|
||||
#define BLOCK(letter, n) do {ptr = strchr((const char *)alphabet, source[n]); \
|
||||
if(!ptr) return -1; \
|
||||
i = ptr - alphabet; \
|
||||
i = ptr - (const char *)alphabet; \
|
||||
SET_##letter(*block, i); \
|
||||
} while(0)
|
||||
|
||||
/* Returns 0 if ok, -1 if not (ie invalid char into the stuff) */
|
||||
static int to_block4(unsigned long *block, const char *source, int num) {
|
||||
char *ptr;
|
||||
const char *ptr = NULL;
|
||||
unsigned int i;
|
||||
|
||||
*block = 0;
|
||||
@@ -234,29 +235,32 @@ static int get_equals(char *string) {
|
||||
}
|
||||
|
||||
/* thanks sysk for debugging my mess :) */
|
||||
static void _bin_to_base64(uint8_t *dest,
|
||||
const uint8_t source[3],
|
||||
size_t len)
|
||||
{
|
||||
#define BITS(n) ((1 << (n)) - 1)
|
||||
static void _bin_to_base64(unsigned char *dest, const unsigned char source[3],
|
||||
int len) {
|
||||
switch (len) {
|
||||
case 1:
|
||||
dest[0] = alphabet[(source[0] >> 2)];
|
||||
dest[1] = alphabet[((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = '=';
|
||||
dest[3] = '=';
|
||||
break;
|
||||
case 2:
|
||||
dest[0] = alphabet[source[0] >> 2];
|
||||
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = alphabet[(source[1] & BITS(4)) << 2];
|
||||
dest[3] = '=';
|
||||
break;
|
||||
case 3:
|
||||
dest[0] = alphabet[(source[0] >> 2)];
|
||||
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = alphabet[ (source[2] >> 6) | (source[1] & BITS(4)) << 2];
|
||||
dest[3] = alphabet[source[2] & BITS(6)];
|
||||
break;
|
||||
}
|
||||
switch (len) {
|
||||
case 1:
|
||||
dest[0] = alphabet[(source[0] >> 2)];
|
||||
dest[1] = alphabet[((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = '=';
|
||||
dest[3] = '=';
|
||||
break;
|
||||
case 2:
|
||||
dest[0] = alphabet[source[0] >> 2];
|
||||
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = alphabet[(source[1] & BITS(4)) << 2];
|
||||
dest[3] = '=';
|
||||
break;
|
||||
case 3:
|
||||
dest[0] = alphabet[(source[0] >> 2)];
|
||||
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = alphabet[(source[2] >> 6) | (source[1] & BITS(4)) << 2];
|
||||
dest[3] = alphabet[source[2] & BITS(6)];
|
||||
break;
|
||||
}
|
||||
#undef BITS
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,25 +270,29 @@ static void _bin_to_base64(unsigned char *dest, const unsigned char source[3],
|
||||
*
|
||||
* @returns the converted string
|
||||
*/
|
||||
unsigned char *bin_to_base64(const unsigned char *source, int len) {
|
||||
unsigned char *base64;
|
||||
unsigned char *ptr;
|
||||
int flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
|
||||
flen = (4 * flen) / 3 + 1;
|
||||
uint8_t *bin_to_base64(const uint8_t *source, size_t len)
|
||||
{
|
||||
uint8_t *base64 = NULL;
|
||||
uint8_t *ptr = NULL;
|
||||
size_t flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
|
||||
flen = (4 * flen) / 3 + 1;
|
||||
|
||||
base64 = malloc(flen);
|
||||
if (base64 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = base64;
|
||||
base64 = malloc(flen);
|
||||
if (base64 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = base64;
|
||||
|
||||
while(len > 0){
|
||||
_bin_to_base64(ptr, source, len > 3 ? 3 : len);
|
||||
ptr += 4;
|
||||
source += 3;
|
||||
len -= 3;
|
||||
}
|
||||
ptr[0] = '\0';
|
||||
while(len > 0){
|
||||
_bin_to_base64(ptr, source, len > 3 ? 3 : len);
|
||||
ptr += 4;
|
||||
if (len < 3) {
|
||||
break;
|
||||
}
|
||||
source += 3;
|
||||
len -= 3;
|
||||
}
|
||||
ptr[0] = '\0';
|
||||
|
||||
return base64;
|
||||
return base64;
|
||||
}
|
||||
|
||||
15
src/bignum.c
15
src/bignum.c
@@ -29,9 +29,9 @@
|
||||
|
||||
ssh_string ssh_make_bignum_string(bignum num) {
|
||||
ssh_string ptr = NULL;
|
||||
int pad = 0;
|
||||
unsigned int len = bignum_num_bytes(num);
|
||||
unsigned int bits = bignum_num_bits(num);
|
||||
size_t pad = 0;
|
||||
size_t len = bignum_num_bytes(num);
|
||||
size_t bits = bignum_num_bits(num);
|
||||
|
||||
if (len == 0) {
|
||||
return NULL;
|
||||
@@ -43,7 +43,9 @@ ssh_string ssh_make_bignum_string(bignum num) {
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"%zu bits, %zu bytes, %zu padding\n",
|
||||
bits, len, pad);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
ptr = ssh_string_new(len + pad);
|
||||
@@ -67,7 +69,8 @@ bignum ssh_make_string_bn(ssh_string string)
|
||||
size_t len = ssh_string_len(string);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "Importing a %zu bits, %zu bytes object ...\n",
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Importing a %zu bits, %zu bytes object ...\n",
|
||||
len * 8, len);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
@@ -77,7 +80,7 @@ bignum ssh_make_string_bn(ssh_string string)
|
||||
}
|
||||
|
||||
/* prints the bignum on stderr */
|
||||
void ssh_print_bignum(const char *name, const bignum num)
|
||||
void ssh_print_bignum(const char *name, const_bignum num)
|
||||
{
|
||||
unsigned char *hex = NULL;
|
||||
if (num != NULL) {
|
||||
|
||||
@@ -411,7 +411,7 @@ void ssh_bind_free(ssh_bind sshbind){
|
||||
ssh_key_free(sshbind->ed25519);
|
||||
sshbind->ed25519 = NULL;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
if (sshbind->wanted_methods[i]) {
|
||||
SAFE_FREE(sshbind->wanted_methods[i]);
|
||||
}
|
||||
@@ -442,7 +442,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
session->server = 1;
|
||||
|
||||
/* Copy options from bind to session */
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
if (sshbind->wanted_methods[i]) {
|
||||
session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
|
||||
if (session->opts.wanted_methods[i] == NULL) {
|
||||
|
||||
72
src/buffer.c
72
src/buffer.c
@@ -299,28 +299,33 @@ int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
|
||||
*/
|
||||
int ssh_buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len)
|
||||
{
|
||||
buffer_verify(buffer);
|
||||
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer->used + len < len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer->allocated < (buffer->used + len)) {
|
||||
if(buffer->pos > 0)
|
||||
buffer_shift(buffer);
|
||||
if (realloc_buffer(buffer, buffer->used + len) < 0) {
|
||||
return -1;
|
||||
if (buffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buffer->data+buffer->used, data, len);
|
||||
buffer->used+=len;
|
||||
buffer_verify(buffer);
|
||||
return 0;
|
||||
buffer_verify(buffer);
|
||||
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer->used + len < len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer->allocated < (buffer->used + len)) {
|
||||
if (buffer->pos > 0) {
|
||||
buffer_shift(buffer);
|
||||
}
|
||||
if (realloc_buffer(buffer, buffer->used + len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buffer->data + buffer->used, data, len);
|
||||
buffer->used += len;
|
||||
buffer_verify(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1119,6 +1124,7 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = SSH_ERROR;
|
||||
switch (*p) {
|
||||
case 'b':
|
||||
o.byte = va_arg(ap, uint8_t *);
|
||||
@@ -1128,27 +1134,32 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
case 'w':
|
||||
o.word = va_arg(ap, uint16_t *);
|
||||
rlen = ssh_buffer_get_data(buffer, o.word, sizeof(uint16_t));
|
||||
*o.word = ntohs(*o.word);
|
||||
rc = rlen==2 ? SSH_OK : SSH_ERROR;
|
||||
if (rlen == 2) {
|
||||
*o.word = ntohs(*o.word);
|
||||
rc = SSH_OK;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
o.dword = va_arg(ap, uint32_t *);
|
||||
rlen = ssh_buffer_get_u32(buffer, o.dword);
|
||||
*o.dword = ntohl(*o.dword);
|
||||
rc = rlen==4 ? SSH_OK : SSH_ERROR;
|
||||
if (rlen == 4) {
|
||||
*o.dword = ntohl(*o.dword);
|
||||
rc = SSH_OK;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
o.qword = va_arg(ap, uint64_t*);
|
||||
rlen = ssh_buffer_get_u64(buffer, o.qword);
|
||||
*o.qword = ntohll(*o.qword);
|
||||
rc = rlen==8 ? SSH_OK : SSH_ERROR;
|
||||
if (rlen == 8) {
|
||||
*o.qword = ntohll(*o.qword);
|
||||
rc = SSH_OK;
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
o.bignum = va_arg(ap, bignum *);
|
||||
*o.bignum = NULL;
|
||||
tmp_string = ssh_buffer_get_ssh_string(buffer);
|
||||
if (tmp_string == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
*o.bignum = ssh_make_string_bn(tmp_string);
|
||||
@@ -1167,14 +1178,12 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
|
||||
o.cstring = va_arg(ap, char **);
|
||||
*o.cstring = NULL;
|
||||
rc = ssh_buffer_get_u32(buffer, &u32len);
|
||||
if (rc != 4){
|
||||
rc = SSH_ERROR;
|
||||
rlen = ssh_buffer_get_u32(buffer, &u32len);
|
||||
if (rlen != 4){
|
||||
break;
|
||||
}
|
||||
len = ntohl(u32len);
|
||||
if (len > max_len - 1) {
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1230,7 +1239,6 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
break;
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
if (rc != SSH_OK) {
|
||||
break;
|
||||
|
||||
@@ -109,11 +109,11 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
|
||||
out_packet->payload,
|
||||
len - sizeof(uint32_t));
|
||||
|
||||
/* ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
|
||||
/* ssh_log_hexdump("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
|
||||
/* step 4, compute the MAC */
|
||||
poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx);
|
||||
/* ssh_print_hexa("poly1305 src", (uint8_t *)out_packet, len);
|
||||
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN); */
|
||||
/* ssh_log_hexdump("poly1305 src", (uint8_t *)out_packet, len);
|
||||
ssh_log_hexdump("poly1305 tag", tag, POLY1305_TAGLEN); */
|
||||
}
|
||||
|
||||
static int chacha20_poly1305_aead_decrypt_length(
|
||||
@@ -159,17 +159,17 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
|
||||
poly1305_ctx,
|
||||
POLY1305_KEYLEN);
|
||||
#if 0
|
||||
ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
|
||||
ssh_log_hexdump("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
|
||||
#endif
|
||||
|
||||
poly1305_auth(tag, (uint8_t *)complete_packet, encrypted_size +
|
||||
sizeof(uint32_t), poly1305_ctx);
|
||||
#if 0
|
||||
ssh_print_hexa("poly1305 src",
|
||||
ssh_log_hexdump("poly1305 src",
|
||||
(uint8_t*)complete_packet,
|
||||
encrypted_size + 4);
|
||||
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN);
|
||||
ssh_print_hexa("received tag", mac, POLY1305_TAGLEN);
|
||||
ssh_log_hexdump("poly1305 tag", tag, POLY1305_TAGLEN);
|
||||
ssh_log_hexdump("received tag", mac, POLY1305_TAGLEN);
|
||||
#endif
|
||||
|
||||
cmp = memcmp(tag, mac, POLY1305_TAGLEN);
|
||||
|
||||
386
src/channels.c
386
src/channels.c
@@ -29,6 +29,9 @@
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif /* HAVE_SYS_TIME_H */
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -106,7 +109,7 @@ ssh_channel ssh_channel_new(ssh_session session)
|
||||
channel->stderr_buffer = ssh_buffer_new();
|
||||
if (channel->stderr_buffer == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(channel->stdout_buffer);
|
||||
SSH_BUFFER_FREE(channel->stdout_buffer);
|
||||
SAFE_FREE(channel);
|
||||
return NULL;
|
||||
}
|
||||
@@ -117,10 +120,21 @@ ssh_channel ssh_channel_new(ssh_session session)
|
||||
|
||||
if (session->channels == NULL) {
|
||||
session->channels = ssh_list_new();
|
||||
if (session->channels == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
SSH_BUFFER_FREE(channel->stdout_buffer);
|
||||
SSH_BUFFER_FREE(channel->stderr_buffer);
|
||||
SAFE_FREE(channel);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ssh_list_prepend(session->channels, channel);
|
||||
|
||||
/* Set states explicitly */
|
||||
channel->state = SSH_CHANNEL_STATE_NOT_OPEN;
|
||||
channel->request_state = SSH_CHANNEL_REQ_STATE_NONE;
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
@@ -277,74 +291,89 @@ static int ssh_channel_open_termination(void *c){
|
||||
*
|
||||
* @return SSH_OK if successful; SSH_ERROR otherwise.
|
||||
*/
|
||||
static int channel_open(ssh_channel channel, const char *type, int window,
|
||||
int maxpacket, ssh_buffer payload) {
|
||||
ssh_session session = channel->session;
|
||||
int err=SSH_ERROR;
|
||||
int rc;
|
||||
static int
|
||||
channel_open(ssh_channel channel,
|
||||
const char *type,
|
||||
uint32_t window,
|
||||
uint32_t maxpacket,
|
||||
ssh_buffer payload)
|
||||
{
|
||||
ssh_session session = channel->session;
|
||||
int err = SSH_ERROR;
|
||||
int rc;
|
||||
|
||||
switch(channel->state){
|
||||
case SSH_CHANNEL_STATE_NOT_OPEN:
|
||||
break;
|
||||
case SSH_CHANNEL_STATE_OPENING:
|
||||
goto pending;
|
||||
case SSH_CHANNEL_STATE_OPEN:
|
||||
case SSH_CHANNEL_STATE_CLOSED:
|
||||
case SSH_CHANNEL_STATE_OPEN_DENIED:
|
||||
goto end;
|
||||
default:
|
||||
ssh_set_error(session,SSH_FATAL,"Bad state in channel_open: %d",channel->state);
|
||||
}
|
||||
channel->local_channel = ssh_channel_new_id(session);
|
||||
channel->local_maxpacket = maxpacket;
|
||||
channel->local_window = window;
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Creating a channel %d with %d window and %d max packet",
|
||||
channel->local_channel, window, maxpacket);
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bsddd",
|
||||
SSH2_MSG_CHANNEL_OPEN,
|
||||
type,
|
||||
channel->local_channel,
|
||||
channel->local_window,
|
||||
channel->local_maxpacket);
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(session);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (payload != NULL) {
|
||||
if (ssh_buffer_add_buffer(session->out_buffer, payload) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
|
||||
return err;
|
||||
switch (channel->state) {
|
||||
case SSH_CHANNEL_STATE_NOT_OPEN:
|
||||
break;
|
||||
case SSH_CHANNEL_STATE_OPENING:
|
||||
goto pending;
|
||||
case SSH_CHANNEL_STATE_OPEN:
|
||||
case SSH_CHANNEL_STATE_CLOSED:
|
||||
case SSH_CHANNEL_STATE_OPEN_DENIED:
|
||||
goto end;
|
||||
default:
|
||||
ssh_set_error(session, SSH_FATAL, "Bad state in channel_open: %d",
|
||||
channel->state);
|
||||
}
|
||||
|
||||
channel->local_channel = ssh_channel_new_id(session);
|
||||
channel->local_maxpacket = maxpacket;
|
||||
channel->local_window = window;
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Creating a channel %d with %d window and %d max packet",
|
||||
channel->local_channel, window, maxpacket);
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bsddd",
|
||||
SSH2_MSG_CHANNEL_OPEN,
|
||||
type,
|
||||
channel->local_channel,
|
||||
channel->local_window,
|
||||
channel->local_maxpacket);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (payload != NULL) {
|
||||
if (ssh_buffer_add_buffer(session->out_buffer, payload) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
channel->state = SSH_CHANNEL_STATE_OPENING;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return err;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
|
||||
type, channel->local_channel);
|
||||
|
||||
pending:
|
||||
/* wait until channel is opened by server */
|
||||
err = ssh_handle_packets_termination(session,
|
||||
SSH_TIMEOUT_DEFAULT,
|
||||
ssh_channel_open_termination,
|
||||
channel);
|
||||
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
err = SSH_ERROR;
|
||||
}
|
||||
|
||||
end:
|
||||
/* This needs to pass the SSH_AGAIN from the above,
|
||||
* but needs to catch failed channel states */
|
||||
if (channel->state == SSH_CHANNEL_STATE_OPEN) {
|
||||
err = SSH_OK;
|
||||
} else if (err != SSH_AGAIN) {
|
||||
/* Messages were handled correctly, but he channel state is invalid */
|
||||
err = SSH_ERROR;
|
||||
}
|
||||
}
|
||||
channel->state = SSH_CHANNEL_STATE_OPENING;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
|
||||
type, channel->local_channel);
|
||||
pending:
|
||||
/* wait until channel is opened by server */
|
||||
err = ssh_handle_packets_termination(session,
|
||||
SSH_TIMEOUT_DEFAULT,
|
||||
ssh_channel_open_termination,
|
||||
channel);
|
||||
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR)
|
||||
err = SSH_ERROR;
|
||||
end:
|
||||
if(channel->state == SSH_CHANNEL_STATE_OPEN)
|
||||
err=SSH_OK;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* return channel with corresponding local id, or NULL if not found */
|
||||
@@ -373,7 +402,10 @@ ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) {
|
||||
* @param minimumsize The minimum acceptable size for the new window.
|
||||
* @return SSH_OK if successful; SSH_ERROR otherwise.
|
||||
*/
|
||||
static int grow_window(ssh_session session, ssh_channel channel, int minimumsize) {
|
||||
static int grow_window(ssh_session session,
|
||||
ssh_channel channel,
|
||||
uint32_t minimumsize)
|
||||
{
|
||||
uint32_t new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE;
|
||||
int rc;
|
||||
|
||||
@@ -538,7 +570,7 @@ SSH_PACKET_CALLBACK(channel_rcv_data){
|
||||
|
||||
if (channel_default_bufferize(channel, ssh_string_data(str), len,
|
||||
is_stderr) < 0) {
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
@@ -554,7 +586,7 @@ SSH_PACKET_CALLBACK(channel_rcv_data){
|
||||
channel->local_window,
|
||||
channel->remote_window);
|
||||
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
|
||||
if (is_stderr) {
|
||||
buf = channel->stderr_buffer;
|
||||
@@ -822,8 +854,10 @@ SSH_PACKET_CALLBACK(channel_rcv_request) {
|
||||
*
|
||||
* FIXME is the window changed?
|
||||
*/
|
||||
int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||
int is_stderr) {
|
||||
int channel_default_bufferize(ssh_channel channel,
|
||||
void *data, size_t len,
|
||||
bool is_stderr)
|
||||
{
|
||||
ssh_session session;
|
||||
|
||||
if(channel == NULL) {
|
||||
@@ -838,8 +872,10 @@ int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"placing %d bytes into channel buffer (stderr=%d)", len, is_stderr);
|
||||
if (is_stderr == 0) {
|
||||
"placing %zu bytes into channel buffer (%s)",
|
||||
len,
|
||||
is_stderr ? "stderr" : "stdout");
|
||||
if (!is_stderr) {
|
||||
/* stdout */
|
||||
if (channel->stdout_buffer == NULL) {
|
||||
channel->stdout_buffer = ssh_buffer_new();
|
||||
@@ -851,7 +887,7 @@ int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||
|
||||
if (ssh_buffer_add_data(channel->stdout_buffer, data, len) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(channel->stdout_buffer);
|
||||
SSH_BUFFER_FREE(channel->stdout_buffer);
|
||||
channel->stdout_buffer = NULL;
|
||||
return -1;
|
||||
}
|
||||
@@ -867,7 +903,7 @@ int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||
|
||||
if (ssh_buffer_add_data(channel->stderr_buffer, data, len) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(channel->stderr_buffer);
|
||||
SSH_BUFFER_FREE(channel->stderr_buffer);
|
||||
channel->stderr_buffer = NULL;
|
||||
return -1;
|
||||
}
|
||||
@@ -998,8 +1034,8 @@ int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
payload);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(payload);
|
||||
ssh_string_free(str);
|
||||
SSH_BUFFER_FREE(payload);
|
||||
SSH_STRING_FREE(str);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1081,8 +1117,8 @@ int ssh_channel_open_forward_unix(ssh_channel channel,
|
||||
payload);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(payload);
|
||||
ssh_string_free(str);
|
||||
SSH_BUFFER_FREE(payload);
|
||||
SSH_STRING_FREE(str);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1815,7 +1851,7 @@ int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal,
|
||||
pending:
|
||||
rc = channel_request(channel, "pty-req", buffer, 1);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1875,7 +1911,7 @@ int ssh_channel_change_pty_size(ssh_channel channel, int cols, int rows) {
|
||||
|
||||
rc = channel_request(channel, "window-change", buffer, 0);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1944,11 +1980,23 @@ int ssh_channel_request_subsystem(ssh_channel channel, const char *subsys) {
|
||||
pending:
|
||||
rc = channel_request(channel, "subsystem", buffer, 1);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Request sftp subsystem on the channel
|
||||
*
|
||||
* @param[in] channel The channel to request the sftp subsystem.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @note You should use sftp_new() which does this for you.
|
||||
*/
|
||||
int ssh_channel_request_sftp( ssh_channel channel){
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
@@ -2048,7 +2096,7 @@ pending:
|
||||
rc = channel_request(channel, "x11-req", buffer, 1);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2361,7 +2409,7 @@ pending:
|
||||
}
|
||||
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2433,7 +2481,7 @@ pending:
|
||||
rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2491,7 +2539,7 @@ int ssh_channel_request_env(ssh_channel channel, const char *name, const char *v
|
||||
pending:
|
||||
rc = channel_request(channel, "env", buffer,1);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -2513,12 +2561,12 @@ error:
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
rc = channel_request_exec(channel, "ps aux");
|
||||
rc = ssh_channel_request_exec(channel, "ps aux");
|
||||
if (rc > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((rc = channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||
while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||
if (fwrite(buffer, 1, rc, stdout) != (unsigned int) rc) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2560,7 +2608,7 @@ int ssh_channel_request_exec(ssh_channel channel, const char *cmd) {
|
||||
pending:
|
||||
rc = channel_request(channel, "exec", buffer, 1);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2623,7 +2671,7 @@ int ssh_channel_request_send_signal(ssh_channel channel, const char *sig) {
|
||||
|
||||
rc = channel_request(channel, "signal", buffer, 0);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2666,7 +2714,7 @@ int ssh_channel_request_send_break(ssh_channel channel, uint32_t length) {
|
||||
rc = channel_request(channel, "break", buffer, 0);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2894,15 +2942,16 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* If the server closed the channel properly, there is nothing to do */
|
||||
if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Remote channel is closed.");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
|
||||
return 0;
|
||||
}
|
||||
len = ssh_buffer_get_len(stdbuf);
|
||||
/* Read count bytes if len is greater, everything otherwise */
|
||||
len = (len > count ? count : len);
|
||||
@@ -2942,42 +2991,45 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
||||
*
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
int is_stderr) {
|
||||
ssh_session session;
|
||||
int to_read;
|
||||
int rc;
|
||||
int blocking;
|
||||
int ssh_channel_read_nonblocking(ssh_channel channel,
|
||||
void *dest,
|
||||
uint32_t count,
|
||||
int is_stderr)
|
||||
{
|
||||
ssh_session session;
|
||||
ssize_t to_read;
|
||||
int rc;
|
||||
int blocking;
|
||||
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if(dest == NULL) {
|
||||
ssh_set_error_invalid(channel->session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if(dest == NULL) {
|
||||
ssh_set_error_invalid(channel->session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
session = channel->session;
|
||||
|
||||
to_read = ssh_channel_poll(channel, is_stderr);
|
||||
to_read = ssh_channel_poll(channel, is_stderr);
|
||||
|
||||
if (to_read <= 0) {
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (to_read <= 0) {
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return to_read; /* may be an error code */
|
||||
}
|
||||
return to_read; /* may be an error code */
|
||||
}
|
||||
|
||||
if (to_read > (int)count) {
|
||||
to_read = (int)count;
|
||||
}
|
||||
blocking = ssh_is_blocking(session);
|
||||
ssh_set_blocking(session, 0);
|
||||
rc = ssh_channel_read(channel, dest, to_read, is_stderr);
|
||||
ssh_set_blocking(session,blocking);
|
||||
if ((size_t)to_read > count) {
|
||||
to_read = (ssize_t)count;
|
||||
}
|
||||
blocking = ssh_is_blocking(session);
|
||||
ssh_set_blocking(session, 0);
|
||||
rc = ssh_channel_read(channel, dest, (uint32_t)to_read, is_stderr);
|
||||
ssh_set_blocking(session,blocking);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3046,38 +3098,57 @@ int ssh_channel_poll(ssh_channel channel, int is_stderr){
|
||||
*
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr){
|
||||
ssh_session session;
|
||||
ssh_buffer stdbuf;
|
||||
struct ssh_channel_read_termination_struct ctx;
|
||||
int rc;
|
||||
int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr)
|
||||
{
|
||||
ssh_session session;
|
||||
ssh_buffer stdbuf;
|
||||
struct ssh_channel_read_termination_struct ctx;
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
stdbuf = channel->stdout_buffer;
|
||||
session = channel->session;
|
||||
stdbuf = channel->stdout_buffer;
|
||||
|
||||
if (is_stderr) {
|
||||
stdbuf = channel->stderr_buffer;
|
||||
}
|
||||
ctx.buffer = stdbuf;
|
||||
ctx.channel = channel;
|
||||
ctx.count = 1;
|
||||
rc = ssh_handle_packets_termination(channel->session, timeout,
|
||||
ssh_channel_read_termination, &ctx);
|
||||
if(rc ==SSH_ERROR || session->session_state == SSH_SESSION_STATE_ERROR){
|
||||
rc = SSH_ERROR;
|
||||
goto end;
|
||||
}
|
||||
rc = ssh_buffer_get_len(stdbuf);
|
||||
if(rc > 0)
|
||||
goto end;
|
||||
if (channel->remote_eof)
|
||||
rc = SSH_EOF;
|
||||
end:
|
||||
return rc;
|
||||
if (is_stderr) {
|
||||
stdbuf = channel->stderr_buffer;
|
||||
}
|
||||
ctx.buffer = stdbuf;
|
||||
ctx.channel = channel;
|
||||
ctx.count = 1;
|
||||
rc = ssh_handle_packets_termination(channel->session,
|
||||
timeout,
|
||||
ssh_channel_read_termination,
|
||||
&ctx);
|
||||
if (rc == SSH_ERROR ||
|
||||
session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
rc = SSH_ERROR;
|
||||
goto out;
|
||||
} else if (rc == SSH_AGAIN) {
|
||||
/* If the above timeout expired, it is ok and we do not need to
|
||||
* attempt to check the read buffer. The calling functions do not
|
||||
* expect us to return SSH_AGAIN either here. */
|
||||
rc = SSH_OK;
|
||||
goto out;
|
||||
}
|
||||
len = ssh_buffer_get_len(stdbuf);
|
||||
if (len > 0) {
|
||||
if (len > INT_MAX) {
|
||||
rc = SSH_ERROR;
|
||||
} else {
|
||||
rc = (int)len;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (channel->remote_eof) {
|
||||
rc = SSH_EOF;
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3196,8 +3267,9 @@ static int channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
|
||||
}
|
||||
|
||||
/* Just count number of pointers in the array */
|
||||
static int count_ptrs(ssh_channel *ptrs) {
|
||||
int c;
|
||||
static size_t count_ptrs(ssh_channel *ptrs)
|
||||
{
|
||||
size_t c;
|
||||
for (c = 0; ptrs[c] != NULL; c++)
|
||||
;
|
||||
|
||||
@@ -3451,7 +3523,7 @@ pending:
|
||||
payload);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(payload);
|
||||
SSH_BUFFER_FREE(payload);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -3513,7 +3585,7 @@ pending:
|
||||
payload);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(payload);
|
||||
SSH_BUFFER_FREE(payload);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -3554,7 +3626,7 @@ int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) {
|
||||
|
||||
rc = channel_request(channel, "exit-status", buffer, 0);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3609,7 +3681,7 @@ int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
|
||||
|
||||
rc = channel_request(channel, "exit-signal", buffer, 0);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
SSH_BUFFER_FREE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
227
src/client.c
227
src/client.c
@@ -252,6 +252,7 @@ static int dh_handshake(ssh_session session) {
|
||||
switch(session->next_crypto->kex_type){
|
||||
case SSH_KEX_DH_GROUP1_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA256:
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
case SSH_KEX_DH_GROUP18_SHA512:
|
||||
rc = ssh_client_dh_init(session);
|
||||
@@ -450,7 +451,7 @@ static void ssh_client_connection_callback(ssh_session session)
|
||||
if (dh_handshake(session) == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
FALL_THROUGH;
|
||||
case SSH_SESSION_STATE_DH:
|
||||
if(session->dh_handshake_state==DH_STATE_FINISHED){
|
||||
set_status(session,1.0f);
|
||||
@@ -504,119 +505,138 @@ static int ssh_connect_termination(void *user){
|
||||
* @see ssh_new()
|
||||
* @see ssh_disconnect()
|
||||
*/
|
||||
int ssh_connect(ssh_session session) {
|
||||
int ret;
|
||||
int ssh_connect(ssh_session session)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (session == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (!is_ssh_initialized()) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Library not initialized.");
|
||||
|
||||
switch(session->pending_call_state){
|
||||
case SSH_PENDING_CALL_NONE:
|
||||
break;
|
||||
case SSH_PENDING_CALL_CONNECT:
|
||||
goto pending;
|
||||
default:
|
||||
ssh_set_error(session,SSH_FATAL,"Bad call during pending SSH call in ssh_connect");
|
||||
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session->alive = 0;
|
||||
session->client = 1;
|
||||
|
||||
if (session->opts.fd == SSH_INVALID_SOCKET &&
|
||||
session->opts.host == NULL &&
|
||||
session->opts.ProxyCommand == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* If the system configuration files were not yet processed, do it now */
|
||||
if (!session->opts.config_processed) {
|
||||
ret = ssh_options_parse_config(session, NULL);
|
||||
if (ret != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to process system configuration files");
|
||||
return SSH_ERROR;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ssh_options_apply(session);
|
||||
if (ret < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (session == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"libssh %s, using threading %s",
|
||||
ssh_copyright(),
|
||||
ssh_threads_get_type());
|
||||
switch(session->pending_call_state) {
|
||||
case SSH_PENDING_CALL_NONE:
|
||||
break;
|
||||
case SSH_PENDING_CALL_CONNECT:
|
||||
goto pending;
|
||||
default:
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad call during pending SSH call in ssh_connect");
|
||||
|
||||
session->ssh_connection_callback = ssh_client_connection_callback;
|
||||
session->session_state=SSH_SESSION_STATE_CONNECTING;
|
||||
ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
|
||||
session->socket_callbacks.connected=socket_callback_connected;
|
||||
session->socket_callbacks.data=callback_receive_banner;
|
||||
session->socket_callbacks.exception=ssh_socket_exception_callback;
|
||||
session->socket_callbacks.userdata=session;
|
||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||
session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||
ret=SSH_OK;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session->alive = 0;
|
||||
session->client = 1;
|
||||
|
||||
if (session->opts.fd == SSH_INVALID_SOCKET &&
|
||||
session->opts.host == NULL &&
|
||||
session->opts.ProxyCommand == NULL)
|
||||
{
|
||||
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* If the system configuration files were not yet processed, do it now */
|
||||
if (!session->opts.config_processed) {
|
||||
ret = ssh_options_parse_config(session, NULL);
|
||||
if (ret != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to process system configuration files");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ssh_options_apply(session);
|
||||
if (ret < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"libssh %s, using threading %s",
|
||||
ssh_copyright(),
|
||||
ssh_threads_get_type());
|
||||
|
||||
session->ssh_connection_callback = ssh_client_connection_callback;
|
||||
session->session_state = SSH_SESSION_STATE_CONNECTING;
|
||||
ssh_socket_set_callbacks(session->socket, &session->socket_callbacks);
|
||||
session->socket_callbacks.connected = socket_callback_connected;
|
||||
session->socket_callbacks.data = callback_receive_banner;
|
||||
session->socket_callbacks.exception = ssh_socket_exception_callback;
|
||||
session->socket_callbacks.userdata = session;
|
||||
|
||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||
ret = SSH_OK;
|
||||
#ifndef _WIN32
|
||||
} else if (session->opts.ProxyCommand != NULL){
|
||||
ret = ssh_socket_connect_proxycommand(session->socket,
|
||||
session->opts.ProxyCommand);
|
||||
} else if (session->opts.ProxyCommand != NULL) {
|
||||
ret = ssh_socket_connect_proxycommand(session->socket,
|
||||
session->opts.ProxyCommand);
|
||||
#endif
|
||||
} else {
|
||||
ret=ssh_socket_connect(session->socket,
|
||||
session->opts.host,
|
||||
session->opts.port > 0 ? session->opts.port : 22,
|
||||
session->opts.bindaddr);
|
||||
}
|
||||
if (ret == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
} else {
|
||||
ret = ssh_socket_connect(session->socket,
|
||||
session->opts.host,
|
||||
session->opts.port > 0 ? session->opts.port : 22,
|
||||
session->opts.bindaddr);
|
||||
}
|
||||
if (ret == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
set_status(session, 0.2f);
|
||||
set_status(session, 0.2f);
|
||||
|
||||
session->alive = 1;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Socket connecting, now waiting for the callbacks to work");
|
||||
|
||||
session->alive = 1;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
|
||||
pending:
|
||||
session->pending_call_state=SSH_PENDING_CALL_CONNECT;
|
||||
if(ssh_is_blocking(session)) {
|
||||
int timeout = (session->opts.timeout * 1000) +
|
||||
(session->opts.timeout_usec / 1000);
|
||||
if (timeout == 0) {
|
||||
timeout = 10 * 1000;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET,"Actual timeout : %d", timeout);
|
||||
ret = ssh_handle_packets_termination(session, timeout, ssh_connect_termination, session);
|
||||
if (session->session_state != SSH_SESSION_STATE_ERROR &&
|
||||
(ret == SSH_ERROR || !ssh_connect_termination(session))) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Timeout connecting to %s", session->opts.host);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = ssh_handle_packets_termination(session,
|
||||
SSH_TIMEOUT_NONBLOCKING,
|
||||
ssh_connect_termination,
|
||||
session);
|
||||
if (ret == SSH_ERROR) {
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET,"current state : %d",session->session_state);
|
||||
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
|
||||
return SSH_AGAIN;
|
||||
}
|
||||
session->pending_call_state = SSH_PENDING_CALL_CONNECT;
|
||||
if(ssh_is_blocking(session)) {
|
||||
int timeout = (session->opts.timeout * 1000) +
|
||||
(session->opts.timeout_usec / 1000);
|
||||
if (timeout == 0) {
|
||||
timeout = 10 * 1000;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Actual timeout : %d", timeout);
|
||||
ret = ssh_handle_packets_termination(session, timeout,
|
||||
ssh_connect_termination, session);
|
||||
if (session->session_state != SSH_SESSION_STATE_ERROR &&
|
||||
(ret == SSH_ERROR || !ssh_connect_termination(session)))
|
||||
{
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Timeout connecting to %s", session->opts.host);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
} else {
|
||||
ret = ssh_handle_packets_termination(session,
|
||||
SSH_TIMEOUT_NONBLOCKING,
|
||||
ssh_connect_termination,
|
||||
session);
|
||||
if (ret == SSH_ERROR) {
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
session->pending_call_state=SSH_PENDING_CALL_NONE;
|
||||
if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED)
|
||||
return SSH_ERROR;
|
||||
return SSH_OK;
|
||||
SSH_LOG(SSH_LOG_PACKET, "current state : %d", session->session_state);
|
||||
if (!ssh_is_blocking(session) && !ssh_connect_termination(session)) {
|
||||
return SSH_AGAIN;
|
||||
}
|
||||
|
||||
session->pending_call_state = SSH_PENDING_CALL_NONE;
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR ||
|
||||
session->session_state == SSH_SESSION_STATE_DISCONNECTED)
|
||||
{
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -701,6 +721,7 @@ error:
|
||||
}
|
||||
session->opts.fd = SSH_INVALID_SOCKET;
|
||||
session->session_state=SSH_SESSION_STATE_DISCONNECTED;
|
||||
session->pending_call_state = SSH_PENDING_CALL_NONE;
|
||||
|
||||
while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
|
||||
ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
|
||||
@@ -750,7 +771,7 @@ error:
|
||||
}
|
||||
|
||||
const char *ssh_copyright(void) {
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2019 "
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2021 "
|
||||
"Aris Adamantiadis, Andreas Schneider "
|
||||
"and libssh contributors. "
|
||||
"Distributed under the LGPL, please refer to COPYING "
|
||||
|
||||
35
src/config.c
35
src/config.c
@@ -274,10 +274,8 @@ static int
|
||||
ssh_config_match(char *value, const char *pattern, bool negate)
|
||||
{
|
||||
int ok, result = 0;
|
||||
char *lowervalue;
|
||||
|
||||
lowervalue = (value) ? ssh_lowercase(value) : NULL;
|
||||
ok = match_pattern_list(lowervalue, pattern, strlen(pattern), 0);
|
||||
ok = match_pattern_list(value, pattern, strlen(pattern), 0);
|
||||
if (ok <= 0 && negate == true) {
|
||||
result = 1;
|
||||
} else if (ok > 0 && negate == false) {
|
||||
@@ -286,7 +284,6 @@ ssh_config_match(char *value, const char *pattern, bool negate)
|
||||
SSH_LOG(SSH_LOG_TRACE, "%s '%s' against pattern '%s'%s (ok=%d)",
|
||||
result == 1 ? "Matched" : "Not matched", value, pattern,
|
||||
negate == true ? " (negated)" : "", ok);
|
||||
SAFE_FREE(lowervalue);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -397,6 +394,11 @@ ssh_config_parse_line(ssh_session session,
|
||||
long l;
|
||||
int64_t ll;
|
||||
|
||||
/* Ignore empty lines */
|
||||
if (line == NULL || *line == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
x = s = strdup(line);
|
||||
if (s == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
@@ -423,6 +425,7 @@ ssh_config_parse_line(ssh_session session,
|
||||
opcode != SOC_HOST &&
|
||||
opcode != SOC_MATCH &&
|
||||
opcode != SOC_INCLUDE &&
|
||||
opcode != SOC_IDENTITY &&
|
||||
opcode > SOC_UNSUPPORTED) { /* Ignore all unknown types here */
|
||||
/* Skip all the options that were already applied */
|
||||
if (seen[opcode] != 0) {
|
||||
@@ -450,6 +453,7 @@ ssh_config_parse_line(ssh_session session,
|
||||
int result = 1;
|
||||
size_t args = 0;
|
||||
enum ssh_config_match_e opt;
|
||||
char *localuser = NULL;
|
||||
|
||||
*parsing = 0;
|
||||
do {
|
||||
@@ -515,8 +519,29 @@ ssh_config_parse_line(ssh_session session,
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case MATCH_ORIGINALHOST:
|
||||
case MATCH_LOCALUSER:
|
||||
/* Here we match only one argument */
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"line %d: ERROR - Match user keyword "
|
||||
"requires argument", count);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
localuser = ssh_get_local_username();
|
||||
if (localuser == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARN, "line %d: Can not get local username "
|
||||
"for conditional matching.", count);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
result &= ssh_config_match(localuser, p, negate);
|
||||
SAFE_FREE(localuser);
|
||||
args++;
|
||||
break;
|
||||
|
||||
case MATCH_ORIGINALHOST:
|
||||
/* Skip one argument */
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
|
||||
541
src/connect.c
541
src/connect.c
@@ -25,9 +25,13 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif /* HAVE_SYS_TIME_H */
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/misc.h"
|
||||
@@ -90,131 +94,55 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef gai_strerror
|
||||
char WSAAPI *gai_strerrorA(int code) {
|
||||
static char buf[256];
|
||||
char WSAAPI *gai_strerrorA(int code)
|
||||
{
|
||||
static char buf[256];
|
||||
|
||||
snprintf(buf, sizeof(buf), "Undetermined error code (%d)", code);
|
||||
snprintf(buf, sizeof(buf), "Undetermined error code (%d)", code);
|
||||
|
||||
return buf;
|
||||
return buf;
|
||||
}
|
||||
#endif /* gai_strerror */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
static int ssh_connect_socket_close(socket_t s){
|
||||
static int ssh_connect_socket_close(socket_t s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return closesocket(s);
|
||||
return closesocket(s);
|
||||
#else
|
||||
return close(s);
|
||||
return close(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int getai(const char *host, int port, struct addrinfo **ai)
|
||||
{
|
||||
const char *service = NULL;
|
||||
struct addrinfo hints;
|
||||
char s_port[10];
|
||||
|
||||
static int getai(const char *host, int port, struct addrinfo **ai) {
|
||||
const char *service = NULL;
|
||||
struct addrinfo hints;
|
||||
char s_port[10];
|
||||
ZERO_STRUCT(hints);
|
||||
|
||||
ZERO_STRUCT(hints);
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (port == 0) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
} else {
|
||||
snprintf(s_port, sizeof(s_port), "%hu", (unsigned short)port);
|
||||
service = s_port;
|
||||
if (port == 0) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
} else {
|
||||
snprintf(s_port, sizeof(s_port), "%hu", (unsigned short)port);
|
||||
service = s_port;
|
||||
#ifdef AI_NUMERICSERV
|
||||
hints.ai_flags=AI_NUMERICSERV;
|
||||
hints.ai_flags = AI_NUMERICSERV;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_is_ipaddr(host)) {
|
||||
/* this is an IP address */
|
||||
SSH_LOG(SSH_LOG_PACKET,"host %s matches an IP address",host);
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
if (ssh_is_ipaddr(host)) {
|
||||
/* this is an IP address */
|
||||
SSH_LOG(SSH_LOG_PACKET, "host %s matches an IP address", host);
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
|
||||
return getaddrinfo(host, service, &hints, ai);
|
||||
}
|
||||
|
||||
static int ssh_connect_ai_timeout(ssh_session session, const char *host,
|
||||
int port, struct addrinfo *ai, long timeout, long usec, socket_t s) {
|
||||
int timeout_ms;
|
||||
ssh_pollfd_t fds;
|
||||
int rc = 0;
|
||||
int ret;
|
||||
socklen_t len = sizeof(rc);
|
||||
|
||||
/* I know we're losing some precision. But it's not like poll-like family
|
||||
* type of mechanisms are precise up to the microsecond.
|
||||
*/
|
||||
timeout_ms=timeout * 1000 + usec / 1000;
|
||||
|
||||
rc = ssh_socket_set_nonblocking(s);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to set socket non-blocking for %s:%d", host, port);
|
||||
ssh_connect_socket_close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE, "Trying to connect to host: %s:%d with "
|
||||
"timeout %d ms", host, port, timeout_ms);
|
||||
|
||||
/* The return value is checked later */
|
||||
connect(s, ai->ai_addr, ai->ai_addrlen);
|
||||
freeaddrinfo(ai);
|
||||
|
||||
fds.fd=s;
|
||||
fds.revents=0;
|
||||
fds.events=POLLOUT;
|
||||
#ifdef _WIN32
|
||||
fds.events |= POLLWRNORM;
|
||||
#endif
|
||||
rc = ssh_poll(&fds,1,timeout_ms);
|
||||
|
||||
if (rc == 0) {
|
||||
/* timeout */
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Timeout while connecting to %s:%d", host, port);
|
||||
ssh_connect_socket_close(s);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"poll error: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
|
||||
return -1;
|
||||
}
|
||||
rc = -1;
|
||||
|
||||
/* Get connect(2) return code. Zero means no error */
|
||||
ret = getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len);
|
||||
if (ret < 0 || rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Connect to %s:%d failed: %s", host, port, strerror(rc));
|
||||
ssh_connect_socket_close(s);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* s is connected ? */
|
||||
SSH_LOG(SSH_LOG_PACKET, "Socket connected with timeout");
|
||||
ret = ssh_socket_set_blocking(s);
|
||||
if (ret < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to set socket as blocking connecting to %s:%d failed: %s",
|
||||
host, port, strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s;
|
||||
return getaddrinfo(host, service, &hints, ai);
|
||||
}
|
||||
|
||||
static int set_tcp_nodelay(socket_t socket)
|
||||
@@ -228,99 +156,6 @@ static int set_tcp_nodelay(socket_t socket)
|
||||
sizeof(opt));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Connect to an IPv4 or IPv6 host specified by its IP address or
|
||||
* hostname.
|
||||
*
|
||||
* @returns A file descriptor, < 0 on error.
|
||||
*/
|
||||
socket_t ssh_connect_host(ssh_session session, const char *host,
|
||||
const char *bind_addr, int port, long timeout, long usec) {
|
||||
socket_t s = -1;
|
||||
int rc;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *itr;
|
||||
|
||||
rc = getai(host, port, &ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (itr = ai; itr != NULL; itr = itr->ai_next){
|
||||
/* create socket */
|
||||
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
|
||||
if (s < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Socket create failed: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind_addr) {
|
||||
struct addrinfo *bind_ai;
|
||||
struct addrinfo *bind_itr;
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
|
||||
|
||||
rc = getai(bind_addr, 0, &bind_ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve bind address %s (%s)",
|
||||
bind_addr,
|
||||
gai_strerror(rc));
|
||||
freeaddrinfo(ai);
|
||||
close(s);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
|
||||
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Binding local address: %s", strerror(errno));
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(bind_ai);
|
||||
|
||||
/* Cannot bind to any local addresses */
|
||||
if (bind_itr == NULL) {
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeout || usec) {
|
||||
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
|
||||
timeout, usec, s);
|
||||
|
||||
freeaddrinfo(ai);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
} else {
|
||||
/* We are connected */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
@@ -331,102 +166,109 @@ socket_t ssh_connect_host(ssh_session session, const char *host,
|
||||
* @warning very ugly !!!
|
||||
*/
|
||||
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
||||
const char *bind_addr, int port) {
|
||||
socket_t s = -1;
|
||||
int rc;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *itr;
|
||||
const char *bind_addr, int port)
|
||||
{
|
||||
socket_t s = -1;
|
||||
int rc;
|
||||
struct addrinfo *ai = NULL;
|
||||
struct addrinfo *itr = NULL;
|
||||
|
||||
rc = getai(host, port, &ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
|
||||
rc = getai(host, port, &ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve hostname %s (%s)",
|
||||
host, gai_strerror(rc));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (itr = ai; itr != NULL; itr = itr->ai_next){
|
||||
/* create socket */
|
||||
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
|
||||
if (s < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Socket create failed: %s", strerror(errno));
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind_addr) {
|
||||
struct addrinfo *bind_ai;
|
||||
struct addrinfo *bind_itr;
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
|
||||
|
||||
rc = getai(bind_addr, 0, &bind_ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve bind address %s (%s)",
|
||||
bind_addr,
|
||||
gai_strerror(rc));
|
||||
ssh_connect_socket_close(s);
|
||||
s=-1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
|
||||
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Binding local address: %s", strerror(errno));
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
for (itr = ai; itr != NULL; itr = itr->ai_next) {
|
||||
/* create socket */
|
||||
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
|
||||
if (s < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Socket create failed: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(bind_ai);
|
||||
|
||||
/* Cannot bind to any local addresses */
|
||||
if (bind_itr == NULL) {
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (bind_addr) {
|
||||
struct addrinfo *bind_ai;
|
||||
struct addrinfo *bind_itr;
|
||||
|
||||
rc = ssh_socket_set_nonblocking(s);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to set socket non-blocking for %s:%d", host, port);
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
|
||||
|
||||
if (session->opts.nodelay) {
|
||||
/* For winsock, socket options are only effective before connect */
|
||||
rc = set_tcp_nodelay(s);
|
||||
rc = getai(bind_addr, 0, &bind_ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve bind address %s (%s)",
|
||||
bind_addr,
|
||||
gai_strerror(rc));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (bind_itr = bind_ai;
|
||||
bind_itr != NULL;
|
||||
bind_itr = bind_itr->ai_next)
|
||||
{
|
||||
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Binding local address: %s", strerror(errno));
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(bind_ai);
|
||||
|
||||
/* Cannot bind to any local addresses */
|
||||
if (bind_itr == NULL) {
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_socket_set_nonblocking(s);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to set TCP_NODELAY on socket: %s", strerror(errno));
|
||||
"Failed to set socket non-blocking for %s:%d",
|
||||
host, port);
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (session->opts.nodelay) {
|
||||
/* For winsock, socket options are only effective before connect */
|
||||
rc = set_tcp_nodelay(s);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to set TCP_NODELAY on socket: %s",
|
||||
strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to connect: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to connect: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,11 +277,13 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int ssh_select_cb (socket_t fd, int revents, void *userdata){
|
||||
fd_set *set = (fd_set *)userdata;
|
||||
if(revents & POLLIN)
|
||||
FD_SET(fd, set);
|
||||
return 0;
|
||||
static int ssh_select_cb (socket_t fd, int revents, void *userdata)
|
||||
{
|
||||
fd_set *set = (fd_set *)userdata;
|
||||
if (revents & POLLIN) {
|
||||
FD_SET(fd, set);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,73 +317,84 @@ static int ssh_select_cb (socket_t fd, int revents, void *userdata){
|
||||
* @see select(2)
|
||||
*/
|
||||
int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
fd_set *readfds, struct timeval *timeout) {
|
||||
fd_set origfds;
|
||||
socket_t fd;
|
||||
size_t i, j;
|
||||
int rc;
|
||||
int base_tm, tm;
|
||||
struct ssh_timestamp ts;
|
||||
ssh_event event = ssh_event_new();
|
||||
int firstround=1;
|
||||
fd_set *readfds, struct timeval *timeout)
|
||||
{
|
||||
fd_set origfds;
|
||||
socket_t fd;
|
||||
size_t i, j;
|
||||
int rc;
|
||||
int base_tm, tm;
|
||||
struct ssh_timestamp ts;
|
||||
ssh_event event = ssh_event_new();
|
||||
int firstround = 1;
|
||||
|
||||
base_tm = tm=timeout->tv_sec * 1000 + timeout->tv_usec/1000;
|
||||
for (i=0 ; channels[i] != NULL; ++i){
|
||||
ssh_event_add_session(event, channels[i]->session);
|
||||
}
|
||||
|
||||
ZERO_STRUCT(origfds);
|
||||
FD_ZERO(&origfds);
|
||||
for (fd = 0; fd < maxfd ; fd++) {
|
||||
if (FD_ISSET(fd, readfds)) {
|
||||
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
|
||||
FD_SET(fd, &origfds);
|
||||
}
|
||||
}
|
||||
outchannels[0] = NULL;
|
||||
FD_ZERO(readfds);
|
||||
ssh_timestamp_init(&ts);
|
||||
do {
|
||||
/* Poll every channel */
|
||||
j = 0;
|
||||
for (i = 0; channels[i]; i++) {
|
||||
if(ssh_channel_poll(channels[i], 0) != 0) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
} else if(ssh_channel_poll(channels[i], 1) != 0) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
}
|
||||
base_tm = tm = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
|
||||
for (i = 0 ; channels[i] != NULL; ++i) {
|
||||
ssh_event_add_session(event, channels[i]->session);
|
||||
}
|
||||
outchannels[j] = NULL;
|
||||
if(j != 0)
|
||||
break;
|
||||
/* watch if a user socket was triggered */
|
||||
for (fd = 0; fd < maxfd; fd++) {
|
||||
|
||||
ZERO_STRUCT(origfds);
|
||||
FD_ZERO(&origfds);
|
||||
for (fd = 0; fd < maxfd ; fd++) {
|
||||
if (FD_ISSET(fd, readfds)) {
|
||||
goto out;
|
||||
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
|
||||
FD_SET(fd, &origfds);
|
||||
}
|
||||
}
|
||||
outchannels[0] = NULL;
|
||||
FD_ZERO(readfds);
|
||||
ssh_timestamp_init(&ts);
|
||||
do {
|
||||
/* Poll every channel */
|
||||
j = 0;
|
||||
for (i = 0; channels[i]; i++) {
|
||||
rc = ssh_channel_poll(channels[i], 0);
|
||||
if (rc != 0) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
} else {
|
||||
rc = ssh_channel_poll(channels[i], 1);
|
||||
if (rc != 0) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the timeout is elapsed, we should go out */
|
||||
if(!firstround && ssh_timeout_elapsed(&ts, base_tm))
|
||||
goto out;
|
||||
/* since there's nothing, let's fire the polling */
|
||||
rc = ssh_event_dopoll(event,tm);
|
||||
if (rc == SSH_ERROR){
|
||||
goto out;
|
||||
}
|
||||
tm = ssh_timeout_update(&ts, base_tm);
|
||||
firstround=0;
|
||||
} while (1);
|
||||
outchannels[j] = NULL;
|
||||
if (j != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* watch if a user socket was triggered */
|
||||
for (fd = 0; fd < maxfd; fd++) {
|
||||
if (FD_ISSET(fd, readfds)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the timeout is elapsed, we should go out */
|
||||
if (!firstround && ssh_timeout_elapsed(&ts, base_tm)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* since there's nothing, let's fire the polling */
|
||||
rc = ssh_event_dopoll(event,tm);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
tm = ssh_timeout_update(&ts, base_tm);
|
||||
firstround = 0;
|
||||
} while (1);
|
||||
out:
|
||||
for (fd = 0; fd < maxfd; fd++) {
|
||||
if (FD_ISSET(fd, &origfds)) {
|
||||
ssh_event_remove_fd(event, fd);
|
||||
for (fd = 0; fd < maxfd; fd++) {
|
||||
if (FD_ISSET(fd, &origfds)) {
|
||||
ssh_event_remove_fd(event, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
ssh_event_free(event);
|
||||
return SSH_OK;
|
||||
ssh_event_free(event);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
289
src/curve25519.c
289
src/curve25519.c
@@ -39,6 +39,10 @@
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply);
|
||||
|
||||
static ssh_packet_callback dh_client_callbacks[] = {
|
||||
@@ -52,58 +56,216 @@ static struct ssh_packet_callbacks_struct ssh_curve25519_client_callbacks = {
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
static int ssh_curve25519_init(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
size_t pubkey_len = CURVE25519_PUBKEY_SIZE;
|
||||
size_t pkey_len = CURVE25519_PRIVKEY_SIZE;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
|
||||
if (pctx == NULL) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to initialize X25519 context: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = EVP_PKEY_keygen_init(pctx);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to initialize X25519 keygen: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = EVP_PKEY_keygen(pctx, &pkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to generate X25519 keys: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (session->server) {
|
||||
rc = EVP_PKEY_get_raw_public_key(pkey,
|
||||
session->next_crypto->curve25519_server_pubkey,
|
||||
&pubkey_len);
|
||||
} else {
|
||||
rc = EVP_PKEY_get_raw_public_key(pkey,
|
||||
session->next_crypto->curve25519_client_pubkey,
|
||||
&pubkey_len);
|
||||
}
|
||||
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to get X25519 raw public key: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
EVP_PKEY_free(pkey);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = EVP_PKEY_get_raw_private_key(pkey,
|
||||
session->next_crypto->curve25519_privkey,
|
||||
&pkey_len);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to get X25519 raw private key: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
EVP_PKEY_free(pkey);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
#else
|
||||
rc = ssh_get_random(session->next_crypto->curve25519_privkey,
|
||||
CURVE25519_PRIVKEY_SIZE, 1);
|
||||
if (rc != 1) {
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (session->server) {
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
} else {
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_X25519 */
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief Starts curve25519-sha256@libssh.org / curve25519-sha256 key exchange
|
||||
*/
|
||||
int ssh_client_curve25519_init(ssh_session session){
|
||||
int rc;
|
||||
int ok;
|
||||
int ssh_client_curve25519_init(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ok = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
|
||||
if (!ok) {
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = ssh_curve25519_init(session);
|
||||
if (rc != SSH_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_KEX_ECDH_INIT,
|
||||
CURVE25519_PUBKEY_SIZE,
|
||||
(size_t)CURVE25519_PUBKEY_SIZE,
|
||||
session->next_crypto->curve25519_client_pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_KEX_ECDH_INIT,
|
||||
CURVE25519_PUBKEY_SIZE,
|
||||
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_curve25519_client_callbacks);
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
rc = ssh_packet_send(session);
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_curve25519_client_callbacks);
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
rc = ssh_packet_send(session);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ssh_curve25519_build_k(ssh_session session) {
|
||||
ssh_curve25519_pubkey k;
|
||||
static int ssh_curve25519_build_k(ssh_session session)
|
||||
{
|
||||
ssh_curve25519_pubkey k;
|
||||
|
||||
if (session->server)
|
||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||
session->next_crypto->curve25519_client_pubkey);
|
||||
else
|
||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||
session->next_crypto->curve25519_server_pubkey);
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = NULL, *pubkey = NULL;
|
||||
size_t shared_key_len = sizeof(k);
|
||||
int rc, ret = SSH_ERROR;
|
||||
|
||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->shared_secret);
|
||||
if (session->next_crypto->shared_secret == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL,
|
||||
session->next_crypto->curve25519_privkey,
|
||||
CURVE25519_PRIVKEY_SIZE);
|
||||
if (pkey == NULL) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to create X25519 EVP_PKEY: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
if (pctx == NULL) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to initialize X25519 context: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = EVP_PKEY_derive_init(pctx);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to initialize X25519 key derivation: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (session->server) {
|
||||
pubkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL,
|
||||
session->next_crypto->curve25519_client_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
} else {
|
||||
pubkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL,
|
||||
session->next_crypto->curve25519_server_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
}
|
||||
if (pubkey == NULL) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to create X25519 public key EVP_PKEY: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = EVP_PKEY_derive_set_peer(pctx, pubkey);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to set peer X25519 public key: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = EVP_PKEY_derive(pctx, k, &shared_key_len);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE,
|
||||
"Failed to derive X25519 shared secret: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto out;
|
||||
}
|
||||
ret = SSH_OK;
|
||||
out:
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_free(pubkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
if (ret == SSH_ERROR) {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
if (session->server) {
|
||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||
session->next_crypto->curve25519_client_pubkey);
|
||||
} else {
|
||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||
session->next_crypto->curve25519_server_pubkey);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_X25519 */
|
||||
|
||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->shared_secret);
|
||||
if (session->next_crypto->shared_secret == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Session server cookie",
|
||||
ssh_log_hexdump("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_print_hexa("Session client cookie",
|
||||
ssh_log_hexdump("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||
#endif
|
||||
@@ -132,7 +294,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
|
||||
}
|
||||
|
||||
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
@@ -148,11 +310,11 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
|
||||
if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){
|
||||
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
||||
(int)ssh_string_len(q_s_string));
|
||||
ssh_string_free(q_s_string);
|
||||
SSH_STRING_FREE(q_s_string);
|
||||
goto error;
|
||||
}
|
||||
memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE);
|
||||
ssh_string_free(q_s_string);
|
||||
SSH_STRING_FREE(q_s_string);
|
||||
|
||||
signature = ssh_buffer_get_ssh_string(packet);
|
||||
if (signature == NULL) {
|
||||
@@ -215,14 +377,14 @@ void ssh_server_curve25519_init(ssh_session session){
|
||||
*/
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
/* ECDH keys */
|
||||
ssh_string q_c_string;
|
||||
ssh_string q_s_string;
|
||||
ssh_string q_c_string = NULL;
|
||||
ssh_string q_s_string = NULL;
|
||||
ssh_string server_pubkey_blob = NULL;
|
||||
|
||||
/* SSH host keys (rsa,dsa,ecdsa) */
|
||||
ssh_key privkey;
|
||||
ssh_key privkey = NULL;
|
||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||
ssh_string sig_blob = NULL;
|
||||
int ok;
|
||||
int rc;
|
||||
(void)type;
|
||||
(void)user;
|
||||
@@ -240,24 +402,20 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
SSH_FATAL,
|
||||
"Incorrect size for server Curve25519 public key: %zu",
|
||||
ssh_string_len(q_c_string));
|
||||
ssh_string_free(q_c_string);
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(session->next_crypto->curve25519_client_pubkey,
|
||||
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
|
||||
ssh_string_free(q_c_string);
|
||||
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
|
||||
SSH_STRING_FREE(q_c_string);
|
||||
/* Build server's keypair */
|
||||
|
||||
ok = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
|
||||
if (!ok) {
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
rc = ssh_curve25519_init(session);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Failed to generate curve25519 keys");
|
||||
goto error;
|
||||
}
|
||||
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
|
||||
rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
@@ -272,7 +430,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
@@ -292,7 +450,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
/* add host's public key */
|
||||
rc = ssh_buffer_add_ssh_string(session->out_buffer,
|
||||
server_pubkey_blob);
|
||||
ssh_string_free(server_pubkey_blob);
|
||||
SSH_STRING_FREE(server_pubkey_blob);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
@@ -301,28 +459,33 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
/* add ecdh public key */
|
||||
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||
if (q_s_string == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_string_fill(q_s_string,
|
||||
session->next_crypto->curve25519_server_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
rc = ssh_string_fill(q_s_string,
|
||||
session->next_crypto->curve25519_server_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not copy public key");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_add_ssh_string(session->out_buffer, q_s_string);
|
||||
ssh_string_free(q_s_string);
|
||||
SSH_STRING_FREE(q_s_string);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
/* add signature blob */
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_add_ssh_string(session->out_buffer, sig_blob);
|
||||
ssh_string_free(sig_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
@@ -349,6 +512,8 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
error:
|
||||
SSH_STRING_FREE(q_c_string);
|
||||
SSH_STRING_FREE(q_s_string);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
38
src/dh-gex.c
38
src/dh-gex.c
@@ -107,7 +107,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
|
||||
int blen;
|
||||
bignum pmin1 = NULL, one = NULL;
|
||||
bignum_CTX ctx = bignum_ctx_new();
|
||||
bignum modulus, generator;
|
||||
bignum modulus = NULL, generator = NULL;
|
||||
const_bignum pubkey;
|
||||
(void) type;
|
||||
(void) user;
|
||||
@@ -179,14 +179,18 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
|
||||
bignum_ctx_free(ctx);
|
||||
ctx = NULL;
|
||||
|
||||
/* all checks passed, set parameters */
|
||||
/* all checks passed, set parameters (the BNs are copied in openssl backend) */
|
||||
rc = ssh_dh_set_parameters(session->next_crypto->dh_ctx,
|
||||
modulus, generator);
|
||||
if (rc != SSH_OK) {
|
||||
bignum_safe_free(modulus);
|
||||
bignum_safe_free(generator);
|
||||
goto error;
|
||||
}
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
bignum_safe_free(modulus);
|
||||
bignum_safe_free(generator);
|
||||
#endif
|
||||
modulus = NULL;
|
||||
generator = NULL;
|
||||
|
||||
/* compute and send DH public parameter */
|
||||
rc = ssh_dh_keypair_gen_keys(session->next_crypto->dh_ctx,
|
||||
@@ -194,8 +198,13 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
|
||||
DH_CLIENT_KEYPAIR, NULL, &pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bB",
|
||||
SSH2_MSG_KEX_DH_GEX_INIT,
|
||||
@@ -216,6 +225,8 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
error:
|
||||
bignum_safe_free(modulus);
|
||||
bignum_safe_free(generator);
|
||||
bignum_safe_free(one);
|
||||
bignum_safe_free(pmin1);
|
||||
if(!bignum_ctx_invalid(ctx)) {
|
||||
@@ -252,9 +263,11 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
|
||||
bignum_safe_free(server_pubkey);
|
||||
goto error;
|
||||
}
|
||||
/* The ownership was passed to the crypto structure */
|
||||
server_pubkey = NULL;
|
||||
|
||||
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
@@ -262,6 +275,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
|
||||
rc = ssh_dh_compute_shared_secret(session->next_crypto->dh_ctx,
|
||||
DH_CLIENT_KEYPAIR, DH_SERVER_KEYPAIR,
|
||||
&session->next_crypto->shared_secret);
|
||||
ssh_dh_debug_crypto(session->next_crypto);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
|
||||
goto error;
|
||||
@@ -281,6 +295,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
error:
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
ssh_dh_cleanup(session->next_crypto);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
|
||||
@@ -354,8 +369,13 @@ static bool dhgroup_better_size(uint32_t pmin,
|
||||
*/
|
||||
static bool invn_chance(int n)
|
||||
{
|
||||
uint32_t nounce;
|
||||
ssh_get_random(&nounce, sizeof(nounce), 0);
|
||||
uint32_t nounce = 0;
|
||||
int ok;
|
||||
|
||||
ok = ssh_get_random(&nounce, sizeof(nounce), 0);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
return (nounce % n) == 0;
|
||||
}
|
||||
|
||||
@@ -636,8 +656,8 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
|
||||
generator);
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
bignum_safe_free(generator);
|
||||
bignum_safe_free(modulus);
|
||||
bignum_safe_free(generator);
|
||||
bignum_safe_free(modulus);
|
||||
#endif
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
|
||||
34
src/dh.c
34
src/dh.c
@@ -361,11 +361,12 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){
|
||||
rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
|
||||
NULL, server_pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
bignum_safe_free(server_pubkey);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
@@ -373,6 +374,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){
|
||||
rc = ssh_dh_compute_shared_secret(session->next_crypto->dh_ctx,
|
||||
DH_CLIENT_KEYPAIR, DH_SERVER_KEYPAIR,
|
||||
&session->next_crypto->shared_secret);
|
||||
ssh_dh_debug_crypto(session->next_crypto);
|
||||
if (rc == SSH_ERROR){
|
||||
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
|
||||
goto error;
|
||||
@@ -430,6 +432,7 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto = session->next_crypto;
|
||||
ssh_key privkey = NULL;
|
||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
bignum client_pubkey;
|
||||
@@ -455,13 +458,14 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_dh_compute_shared_secret(crypto->dh_ctx,
|
||||
DH_SERVER_KEYPAIR, DH_CLIENT_KEYPAIR,
|
||||
&crypto->shared_secret);
|
||||
ssh_dh_debug_crypto(crypto);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
|
||||
goto error;
|
||||
@@ -471,7 +475,7 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet)
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||
goto error;
|
||||
}
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
goto error;
|
||||
@@ -479,6 +483,7 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet)
|
||||
switch (crypto->kex_type){
|
||||
case SSH_KEX_DH_GROUP1_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA256:
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
case SSH_KEX_DH_GROUP18_SHA512:
|
||||
packet_type = SSH2_MSG_KEXDH_REPLY;
|
||||
@@ -693,13 +698,16 @@ static char *ssh_get_b64_unpadded(const unsigned char *hash, size_t len)
|
||||
/**
|
||||
* @brief Get a hash as a human-readable hex- or base64-string.
|
||||
*
|
||||
* This gets an allocated fingerprint hash. It is a hex strings if the given
|
||||
* hash is a md5 sum. If it is a SHA sum, it will return an unpadded base64
|
||||
* strings. Either way, the output is prepended by the hash-type.
|
||||
* This gets an allocated fingerprint hash. If it is a SHA sum, it will
|
||||
* return an unpadded base64 strings. If it is a MD5 sum, it will return hex
|
||||
* string. Either way, the output is prepended by the hash-type.
|
||||
*
|
||||
* @param type Which sort of hash is given.
|
||||
* @warning Do NOT use MD5 or SHA1! Those hash functions are being deprecated.
|
||||
*
|
||||
* @param hash What should be converted to a base64 string.
|
||||
* @param type Which sort of hash is given, use
|
||||
* SSH_PUBLICKEY_HASH_SHA256 or better.
|
||||
*
|
||||
* @param hash The hash to be converted to fingerprint.
|
||||
*
|
||||
* @param len Length of the buffer to convert.
|
||||
*
|
||||
@@ -766,13 +774,13 @@ char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
|
||||
/**
|
||||
* @brief Print a hash as a human-readable hex- or base64-string.
|
||||
*
|
||||
* This function prints hex strings if the given hash is a md5 sum.
|
||||
* But prints unpadded base64 strings for sha sums.
|
||||
* Either way, the output is prepended by the hash-type.
|
||||
* This prints an unpadded base64 strings for SHA sums and hex strings for MD5
|
||||
* sum. Either way, the output is prepended by the hash-type.
|
||||
*
|
||||
* @param type Which sort of hash is given.
|
||||
* @param type Which sort of hash is given. Use
|
||||
* SSH_PUBLICKEY_HASH_SHA256 or better.
|
||||
*
|
||||
* @param hash What should be converted to a base64 string.
|
||||
* @param hash The hash to be converted to fingerprint.
|
||||
*
|
||||
* @param len Length of the buffer to convert.
|
||||
*
|
||||
|
||||
@@ -41,6 +41,27 @@ struct dh_ctx {
|
||||
DH *keypair[2];
|
||||
};
|
||||
|
||||
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c)
|
||||
{
|
||||
#ifdef DEBUG_CRYPTO
|
||||
const_bignum x = NULL, y = NULL, e = NULL, f = NULL;
|
||||
|
||||
ssh_dh_keypair_get_keys(c->dh_ctx, DH_CLIENT_KEYPAIR, &x, &e);
|
||||
ssh_dh_keypair_get_keys(c->dh_ctx, DH_SERVER_KEYPAIR, &y, &f);
|
||||
ssh_print_bignum("x", x);
|
||||
ssh_print_bignum("y", y);
|
||||
ssh_print_bignum("e", e);
|
||||
ssh_print_bignum("f", f);
|
||||
|
||||
ssh_log_hexdump("Session server cookie", c->server_kex.cookie, 16);
|
||||
ssh_log_hexdump("Session client cookie", c->client_kex.cookie, 16);
|
||||
ssh_print_bignum("k", c->shared_secret);
|
||||
|
||||
#else
|
||||
(void)c; /* UNUSED_PARAM */
|
||||
#endif
|
||||
}
|
||||
|
||||
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
|
||||
const_bignum *priv, const_bignum *pub)
|
||||
{
|
||||
@@ -96,12 +117,14 @@ int ssh_dh_get_parameters(struct dh_ctx *ctx,
|
||||
int ssh_dh_set_parameters(struct dh_ctx *ctx,
|
||||
const bignum modulus, const bignum generator)
|
||||
{
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || (modulus == NULL) || (generator == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
bignum p = NULL;
|
||||
bignum g = NULL;
|
||||
|
||||
@@ -156,6 +179,7 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group1, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA256:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group14, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
|
||||
48
src/dh_key.c
48
src/dh_key.c
@@ -60,6 +60,28 @@ struct dh_ctx {
|
||||
bignum modulus;
|
||||
};
|
||||
|
||||
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c)
|
||||
{
|
||||
#ifdef DEBUG_CRYPTO
|
||||
const_bignum x = NULL, y = NULL, e = NULL, f = NULL;
|
||||
|
||||
ssh_dh_keypair_get_keys(c->dh_ctx, DH_CLIENT_KEYPAIR, &x, &e);
|
||||
ssh_dh_keypair_get_keys(c->dh_ctx, DH_SERVER_KEYPAIR, &y, &f);
|
||||
ssh_print_bignum("p", c->dh_ctx->modulus);
|
||||
ssh_print_bignum("g", c->dh_ctx->generator);
|
||||
ssh_print_bignum("x", x);
|
||||
ssh_print_bignum("y", y);
|
||||
ssh_print_bignum("e", e);
|
||||
ssh_print_bignum("f", f);
|
||||
|
||||
ssh_log_hexdump("Session server cookie", c->server_kex.cookie, 16);
|
||||
ssh_log_hexdump("Session client cookie", c->client_kex.cookie, 16);
|
||||
ssh_print_bignum("k", c->shared_secret);
|
||||
#else
|
||||
(void)c; /* UNUSED_PARAM */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ssh_dh_free_modulus(struct dh_ctx *ctx)
|
||||
{
|
||||
if ((ctx->modulus != ssh_dh_group1) &&
|
||||
@@ -225,6 +247,7 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group1, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA256:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group14, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
@@ -263,30 +286,6 @@ void ssh_dh_cleanup(struct ssh_crypto_struct *crypto)
|
||||
crypto->dh_ctx = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
static void ssh_dh_debug(ssh_session session)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto = session->next_crypto;
|
||||
const_bignum x, y, e, f;
|
||||
ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR, &x, &e);
|
||||
ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR, &y, &f);
|
||||
ssh_print_bignum("p", crypto->dh_ctx->modulus);
|
||||
ssh_print_bignum("g", crypto->dh_ctx->generator);
|
||||
ssh_print_bignum("x", x);
|
||||
ssh_print_bignum("y", y);
|
||||
ssh_print_bignum("e", e);
|
||||
ssh_print_bignum("f", f);
|
||||
|
||||
ssh_print_hexa("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_print_hexa("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("k", session->next_crypto->shared_secret);
|
||||
}
|
||||
#else
|
||||
#define ssh_dh_debug(session)
|
||||
#endif
|
||||
|
||||
/** @internal
|
||||
* @brief generates a secret DH parameter of at least DH_SECURITY_BITS
|
||||
* security as well as the corresponding public key.
|
||||
@@ -370,7 +369,6 @@ int ssh_dh_compute_shared_secret(struct dh_ctx *dh_ctx, int local, int remote,
|
||||
|
||||
done:
|
||||
bignum_ctx_free(ctx);
|
||||
ssh_dh_debug(session);
|
||||
if (rc != 1) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){
|
||||
}
|
||||
|
||||
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ int ssh_client_ecdh_init(ssh_session session){
|
||||
rc = ssh_buffer_add_ssh_string(session->out_buffer,client_pubkey);
|
||||
if (rc < 0) {
|
||||
EC_KEY_free(key);
|
||||
ssh_string_free(client_pubkey);
|
||||
SSH_STRING_FREE(client_pubkey);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -181,9 +181,9 @@ int ecdh_build_k(ssh_session session) {
|
||||
session->next_crypto->ecdh_privkey = NULL;
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Session server cookie",
|
||||
ssh_log_hexdump("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_print_hexa("Session client cookie",
|
||||
ssh_log_hexdump("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||
#endif
|
||||
@@ -206,6 +206,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
bignum_CTX ctx;
|
||||
/* SSH host keys (rsa,dsa,ecdsa) */
|
||||
ssh_key privkey;
|
||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
int curve;
|
||||
@@ -277,7 +278,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
@@ -288,7 +289,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
goto error;
|
||||
}
|
||||
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
goto error;
|
||||
@@ -297,7 +298,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not export server public key");
|
||||
ssh_string_free(sig_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -308,8 +309,8 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
q_s_string, /* ecdh public key */
|
||||
sig_blob); /* signature blob */
|
||||
|
||||
ssh_string_free(sig_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
|
||||
@@ -115,7 +115,7 @@ int ssh_client_ecdh_init(ssh_session session)
|
||||
out:
|
||||
gcry_sexp_release(param);
|
||||
gcry_sexp_release(key);
|
||||
ssh_string_free(client_pubkey);
|
||||
SSH_STRING_FREE(client_pubkey);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -215,13 +215,13 @@ int ecdh_build_k(ssh_session session)
|
||||
k_len = 133;
|
||||
} else {
|
||||
ssh_string_burn(s);
|
||||
ssh_string_free(s);
|
||||
SSH_STRING_FREE(s);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ssh_string_len(s) != k_len) {
|
||||
ssh_string_burn(s);
|
||||
ssh_string_free(s);
|
||||
SSH_STRING_FREE(s);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ int ecdh_build_k(ssh_session session)
|
||||
k_len / 2,
|
||||
NULL);
|
||||
ssh_string_burn(s);
|
||||
ssh_string_free(s);
|
||||
SSH_STRING_FREE(s);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
@@ -242,9 +242,9 @@ int ecdh_build_k(ssh_session session)
|
||||
session->next_crypto->ecdh_privkey = NULL;
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Session server cookie",
|
||||
ssh_log_hexdump("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_print_hexa("Session client cookie",
|
||||
ssh_log_hexdump("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||
#endif
|
||||
@@ -254,7 +254,7 @@ int ecdh_build_k(ssh_session session)
|
||||
gcry_sexp_release(data);
|
||||
gcry_sexp_release(result);
|
||||
ssh_string_burn(privkey);
|
||||
ssh_string_free(privkey);
|
||||
SSH_STRING_FREE(privkey);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -273,6 +273,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
gcry_sexp_t key = NULL;
|
||||
/* SSH host keys (rsa,dsa,ecdsa) */
|
||||
ssh_key privkey;
|
||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
@@ -325,7 +326,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
if (rc != SSH_OK) {
|
||||
goto out;
|
||||
}
|
||||
@@ -336,7 +337,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
goto out;
|
||||
}
|
||||
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
rc = SSH_ERROR;
|
||||
@@ -346,7 +347,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not export server public key");
|
||||
ssh_string_free(sig_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -357,8 +358,8 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
q_s_string, /* ecdh public key */
|
||||
sig_blob); /* signature blob */
|
||||
|
||||
ssh_string_free(sig_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
|
||||
@@ -113,7 +113,7 @@ int ssh_client_ecdh_init(ssh_session session)
|
||||
|
||||
out:
|
||||
mbedtls_ecp_group_free(&grp);
|
||||
ssh_string_free(client_pubkey);
|
||||
SSH_STRING_FREE(client_pubkey);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -188,6 +188,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
ssh_string q_s_string = NULL;
|
||||
mbedtls_ecp_group grp;
|
||||
ssh_key privkey = NULL;
|
||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
int rc;
|
||||
@@ -250,7 +251,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
if (rc == SSH_ERROR) {
|
||||
rc = SSH_ERROR;
|
||||
goto out;
|
||||
@@ -263,7 +264,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
goto out;
|
||||
}
|
||||
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
rc = SSH_ERROR;
|
||||
@@ -273,7 +274,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not export server public key");
|
||||
ssh_string_free(sig_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -283,8 +284,8 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
q_s_string, /* ecdh public key */
|
||||
sig_blob); /* signature blob */
|
||||
|
||||
ssh_string_free(sig_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
SSH_STRING_FREE(sig_blob);
|
||||
SSH_STRING_FREE(pubkey_blob);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
|
||||
2
src/external/bcrypt_pbkdf.c
vendored
2
src/external/bcrypt_pbkdf.c
vendored
@@ -87,7 +87,7 @@ bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
|
||||
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
|
||||
&j);
|
||||
for (i = 0; i < 64; i++)
|
||||
ssh_blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
|
||||
ssh_blf_enc(&state, cdata, BCRYPT_BLOCKS/2);
|
||||
|
||||
/* copy out */
|
||||
for (i = 0; i < BCRYPT_BLOCKS; i++) {
|
||||
|
||||
8
src/external/ed25519.c
vendored
8
src/external/ed25519.c
vendored
@@ -77,8 +77,8 @@ static void get_hram(unsigned char *hram,
|
||||
}
|
||||
|
||||
|
||||
int crypto_sign_ed25519_keypair(unsigned char *pk,
|
||||
unsigned char *sk)
|
||||
int crypto_sign_ed25519_keypair(ed25519_pubkey pk,
|
||||
ed25519_privkey sk)
|
||||
{
|
||||
sc25519 scsk;
|
||||
ge25519 gepk;
|
||||
@@ -114,7 +114,7 @@ int crypto_sign_ed25519(unsigned char *sm,
|
||||
uint64_t *smlen,
|
||||
const unsigned char *m,
|
||||
uint64_t mlen,
|
||||
const unsigned char *sk)
|
||||
const ed25519_privkey sk)
|
||||
{
|
||||
sc25519 sck, scs, scsk;
|
||||
ge25519 ger;
|
||||
@@ -177,7 +177,7 @@ int crypto_sign_ed25519_open(unsigned char *m,
|
||||
uint64_t *mlen,
|
||||
const unsigned char *sm,
|
||||
uint64_t smlen,
|
||||
const unsigned char *pk)
|
||||
const ed25519_pubkey pk)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
4
src/external/fe25519.c
vendored
4
src/external/fe25519.c
vendored
@@ -120,10 +120,10 @@ void fe25519_pack(unsigned char r[32], const fe25519 *x)
|
||||
}
|
||||
}
|
||||
|
||||
int fe25519_iszero(const fe25519 *x)
|
||||
uint32_t fe25519_iszero(const fe25519 *x)
|
||||
{
|
||||
int i;
|
||||
int r;
|
||||
uint32_t r;
|
||||
|
||||
fe25519 t = *x;
|
||||
fe25519_freeze(&t);
|
||||
|
||||
4
src/external/sc25519.c
vendored
4
src/external/sc25519.c
vendored
@@ -223,7 +223,7 @@ int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
|
||||
|
||||
void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
||||
{
|
||||
int i, carry;
|
||||
uint32_t i, carry;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
r->v[i] = x->v[i] + y->v[i];
|
||||
@@ -253,7 +253,7 @@ void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
||||
|
||||
void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
||||
{
|
||||
int i,j,carry;
|
||||
uint32_t i,j,carry;
|
||||
uint32_t t[64];
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
|
||||
@@ -255,7 +255,11 @@ int ssh_getpass(const char *prompt,
|
||||
|
||||
/* disable nonblocking I/O */
|
||||
if (fd & O_NDELAY) {
|
||||
fcntl(0, F_SETFL, fd & ~O_NDELAY);
|
||||
ok = fcntl(0, F_SETFL, fd & ~O_NDELAY);
|
||||
if (ok < 0) {
|
||||
perror("fcntl");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ok = ssh_gets(prompt, buf, len, verify);
|
||||
@@ -267,7 +271,11 @@ int ssh_getpass(const char *prompt,
|
||||
|
||||
/* close fd */
|
||||
if (fd & O_NDELAY) {
|
||||
fcntl(0, F_SETFL, fd);
|
||||
ok = fcntl(0, F_SETFL, fd);
|
||||
if (ok < 0) {
|
||||
perror("fcntl");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
|
||||
72
src/gssapi.c
72
src/gssapi.c
@@ -208,7 +208,7 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
||||
return SSH_ERROR;
|
||||
session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN;
|
||||
rc = ssh_gssapi_send_response(session, oid_s);
|
||||
ssh_string_free(oid_s);
|
||||
SSH_STRING_FREE(oid_s);
|
||||
return rc;
|
||||
} else {
|
||||
return ssh_auth_reply_default(session,0);
|
||||
@@ -235,6 +235,10 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
||||
for (i=0 ; i< n_oid ; ++i){
|
||||
unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]);
|
||||
size_t len = ssh_string_len(oids[i]);
|
||||
|
||||
if (oid_s == NULL) {
|
||||
continue;
|
||||
}
|
||||
if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){
|
||||
SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID");
|
||||
continue;
|
||||
@@ -293,6 +297,10 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
||||
for (i=0 ; i< n_oid ; ++i){
|
||||
unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]);
|
||||
size_t len = ssh_string_len(oids[i]);
|
||||
|
||||
if (oid_s == NULL) {
|
||||
continue;
|
||||
}
|
||||
if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){
|
||||
SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID");
|
||||
continue;
|
||||
@@ -384,7 +392,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
ssh_packet_send(session);
|
||||
ssh_string_free(out_token);
|
||||
SSH_STRING_FREE(out_token);
|
||||
} else {
|
||||
session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC;
|
||||
}
|
||||
@@ -403,7 +411,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
||||
"accepting token",
|
||||
maj_stat,
|
||||
min_stat);
|
||||
ssh_string_free(token);
|
||||
SSH_STRING_FREE(token);
|
||||
if (client_name != GSS_C_NO_NAME){
|
||||
session->gssapi->client_name = client_name;
|
||||
session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name);
|
||||
@@ -444,24 +452,28 @@ static ssh_buffer ssh_gssapi_build_mic(ssh_session session)
|
||||
ssh_buffer mic_buffer = NULL;
|
||||
int rc;
|
||||
|
||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
|
||||
if (crypto == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mic_buffer = ssh_buffer_new();
|
||||
if (mic_buffer == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
|
||||
rc = ssh_buffer_pack(mic_buffer,
|
||||
"dPbsss",
|
||||
crypto->digest_len,
|
||||
(size_t)crypto->digest_len, crypto->session_id,
|
||||
crypto->session_id_len,
|
||||
crypto->session_id_len, crypto->session_id,
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
session->gssapi->user,
|
||||
"ssh-connection",
|
||||
"gssapi-with-mic");
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(mic_buffer);
|
||||
SSH_BUFFER_FREE(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -545,10 +557,10 @@ error:
|
||||
end:
|
||||
ssh_gssapi_free(session);
|
||||
if (mic_buffer != NULL) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
SSH_BUFFER_FREE(mic_buffer);
|
||||
}
|
||||
if (mic_token != NULL) {
|
||||
ssh_string_free(mic_token);
|
||||
SSH_STRING_FREE(mic_token);
|
||||
}
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
@@ -700,13 +712,13 @@ end:
|
||||
* later.
|
||||
*/
|
||||
int ssh_gssapi_auth_mic(ssh_session session){
|
||||
int i;
|
||||
size_t i;
|
||||
gss_OID_set selected; /* oid selected for authentication */
|
||||
ssh_string *oids;
|
||||
ssh_string *oids = NULL;
|
||||
int rc;
|
||||
int n_oids = 0;
|
||||
size_t n_oids = 0;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
char name_buf[256];
|
||||
char name_buf[256] = {0};
|
||||
gss_buffer_desc hostname;
|
||||
const char *gss_host = session->opts.host;
|
||||
|
||||
@@ -750,7 +762,7 @@ int ssh_gssapi_auth_mic(ssh_session session){
|
||||
}
|
||||
|
||||
n_oids = selected->count;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Sending %d oids", n_oids);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Sending %zu oids", n_oids);
|
||||
|
||||
oids = calloc(n_oids, sizeof(ssh_string));
|
||||
if (oids == NULL) {
|
||||
@@ -760,6 +772,11 @@ int ssh_gssapi_auth_mic(ssh_session session){
|
||||
|
||||
for (i=0; i<n_oids; ++i){
|
||||
oids[i] = ssh_string_new(selected->elements[i].length + 2);
|
||||
if (oids[i] == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
rc = SSH_ERROR;
|
||||
goto out;
|
||||
}
|
||||
((unsigned char *)oids[i]->data)[0] = SSH_OID_TAG;
|
||||
((unsigned char *)oids[i]->data)[1] = selected->elements[i].length;
|
||||
memcpy((unsigned char *)oids[i]->data + 2, selected->elements[i].elements,
|
||||
@@ -767,8 +784,10 @@ int ssh_gssapi_auth_mic(ssh_session session){
|
||||
}
|
||||
|
||||
rc = ssh_gssapi_send_auth_mic(session, oids, n_oids);
|
||||
|
||||
out:
|
||||
for (i = 0; i < n_oids; i++) {
|
||||
ssh_string_free(oids[i]);
|
||||
SSH_STRING_FREE(oids[i]);
|
||||
}
|
||||
free(oids);
|
||||
if (rc != SSH_ERROR) {
|
||||
@@ -778,13 +797,13 @@ int ssh_gssapi_auth_mic(ssh_session session){
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s){
|
||||
gss_OID ret;
|
||||
static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s)
|
||||
{
|
||||
gss_OID ret = NULL;
|
||||
unsigned char *data = ssh_string_data(oid_s);
|
||||
size_t len = ssh_string_len(oid_s);
|
||||
|
||||
ret = malloc(sizeof(gss_OID_desc));
|
||||
if (ret == NULL) {
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -792,10 +811,17 @@ static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s){
|
||||
SAFE_FREE(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (data[0] != SSH_OID_TAG || data[1] != len - 2) {
|
||||
SAFE_FREE(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = malloc(sizeof(gss_OID_desc));
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->elements = malloc(len - 2);
|
||||
if (ret->elements == NULL) {
|
||||
SAFE_FREE(ret);
|
||||
@@ -828,7 +854,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
|
||||
goto error;
|
||||
}
|
||||
session->gssapi->client.oid = ssh_gssapi_oid_from_string(oid_s);
|
||||
ssh_string_free(oid_s);
|
||||
SSH_STRING_FREE(oid_s);
|
||||
if (!session->gssapi->client.oid) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid OID");
|
||||
goto error;
|
||||
@@ -896,7 +922,7 @@ static int ssh_gssapi_send_mic(ssh_session session){
|
||||
maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT,
|
||||
&mic_buf, &mic_token_buf);
|
||||
if (GSS_ERROR(maj_stat)){
|
||||
ssh_buffer_free(mic_buffer);
|
||||
SSH_BUFFER_FREE(mic_buffer);
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
|
||||
"generating MIC",
|
||||
maj_stat,
|
||||
@@ -910,7 +936,7 @@ static int ssh_gssapi_send_mic(ssh_session session){
|
||||
mic_token_buf.length,
|
||||
(size_t)mic_token_buf.length, mic_token_buf.value);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
SSH_BUFFER_FREE(mic_buffer);
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -958,7 +984,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
|
||||
"accepting token",
|
||||
maj_stat,
|
||||
min_stat);
|
||||
ssh_string_free(token);
|
||||
SSH_STRING_FREE(token);
|
||||
if (GSS_ERROR(maj_stat)){
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
|
||||
"Gssapi error",
|
||||
|
||||
26
src/gzip.c
26
src/gzip.c
@@ -90,14 +90,14 @@ static ssh_buffer gzip_compress(ssh_session session, ssh_buffer source, int leve
|
||||
zout->avail_out = BLOCKSIZE;
|
||||
status = deflate(zout, Z_PARTIAL_FLUSH);
|
||||
if (status != Z_OK) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"status %d deflating zlib packet", status);
|
||||
return NULL;
|
||||
}
|
||||
len = BLOCKSIZE - zout->avail_out;
|
||||
if (ssh_buffer_add_data(dest, out_buf, len) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return NULL;
|
||||
}
|
||||
zout->next_out = out_buf;
|
||||
@@ -115,16 +115,16 @@ int compress_buffer(ssh_session session, ssh_buffer buf) {
|
||||
}
|
||||
|
||||
if (ssh_buffer_reinit(buf) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_data(buf, ssh_buffer_get(dest), ssh_buffer_get_len(dest)) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,6 +162,10 @@ static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t
|
||||
int status;
|
||||
|
||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||
if (crypto == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zin = crypto->compress_in_ctx;
|
||||
if (zin == NULL) {
|
||||
zin = crypto->compress_in_ctx = initdecompress(session);
|
||||
@@ -185,18 +189,18 @@ static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t
|
||||
if (status != Z_OK && status != Z_BUF_ERROR) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"status %d inflating zlib packet", status);
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = BLOCKSIZE - zin->avail_out;
|
||||
if (ssh_buffer_add_data(dest,out_buf,len) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return NULL;
|
||||
}
|
||||
if (ssh_buffer_get_len(dest) > maxlen){
|
||||
/* Size of packet exceeded, avoid a denial of service attack */
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return NULL;
|
||||
}
|
||||
zin->next_out = out_buf;
|
||||
@@ -214,15 +218,15 @@ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen){
|
||||
}
|
||||
|
||||
if (ssh_buffer_reinit(buf) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_data(buf, ssh_buffer_get(dest), ssh_buffer_get_len(dest)) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_buffer_free(dest);
|
||||
SSH_BUFFER_FREE(dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
47
src/init.c
47
src/init.c
@@ -106,7 +106,6 @@ _ret:
|
||||
*
|
||||
* This functions is automatically called when the library is loaded.
|
||||
*
|
||||
* @returns 0 on success, -1 if an error occured.
|
||||
*/
|
||||
void libssh_constructor(void)
|
||||
{
|
||||
@@ -136,14 +135,20 @@ void libssh_constructor(void)
|
||||
/**
|
||||
* @brief Initialize global cryptographic data structures.
|
||||
*
|
||||
* Since version 0.8.0, it is not necessary to call this function on systems
|
||||
* which are fully supported with regards to threading (that is, system with
|
||||
* pthreads available).
|
||||
* Since version 0.8.0, when libssh is dynamically linked, it is not necessary
|
||||
* to call this function on systems which are fully supported with regards to
|
||||
* threading (that is, system with pthreads available).
|
||||
*
|
||||
* If libssh is statically linked, it is necessary to explicitly call ssh_init()
|
||||
* before calling any other provided API, and it is necessary to explicitly call
|
||||
* ssh_finalize() to free the allocated resources before exiting.
|
||||
*
|
||||
* If the library is already initialized, increments the _ssh_initialized
|
||||
* counter and return the error code cached in _ssh_init_ret.
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
*
|
||||
* @see ssh_finalize()
|
||||
*/
|
||||
int ssh_init(void) {
|
||||
return _ssh_init(0);
|
||||
@@ -188,8 +193,6 @@ _ret:
|
||||
*
|
||||
* This function is automatically called when the library is unloaded.
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
*
|
||||
*/
|
||||
void libssh_destructor(void)
|
||||
{
|
||||
@@ -205,8 +208,13 @@ void libssh_destructor(void)
|
||||
/**
|
||||
* @brief Finalize and cleanup all libssh and cryptographic data structures.
|
||||
*
|
||||
* Since version 0.8.0, it is not necessary to call this function, since it is
|
||||
* automatically called when the library is unloaded.
|
||||
* Since version 0.8.0, when libssh is dynamically linked, it is not necessary
|
||||
* to call this function, since it is automatically called when the library is
|
||||
* unloaded.
|
||||
*
|
||||
* If libssh is statically linked, it is necessary to explicitly call ssh_init()
|
||||
* before calling any other provided API, and it is necessary to explicitly call
|
||||
* ssh_finalize() to free the allocated resources before exiting.
|
||||
*
|
||||
* If ssh_init() is called explicitly, then ssh_finalize() must be called
|
||||
* explicitly.
|
||||
@@ -214,9 +222,9 @@ void libssh_destructor(void)
|
||||
* When called, decrements the counter _ssh_initialized. If the counter reaches
|
||||
* zero, then the libssh and cryptographic data structures are cleaned up.
|
||||
*
|
||||
* @returns 0 on succes, -1 if an error occured.
|
||||
* @returns 0 on success, -1 if an error occurred.
|
||||
*
|
||||
@returns 0 otherwise
|
||||
* @see ssh_init()
|
||||
*/
|
||||
int ssh_finalize(void) {
|
||||
return _ssh_finalize(0);
|
||||
@@ -253,4 +261,23 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Return whether the library is initialized
|
||||
*
|
||||
* @returns true if the library is initialized; false otherwise.
|
||||
*
|
||||
* @see ssh_init()
|
||||
*/
|
||||
bool is_ssh_initialized() {
|
||||
|
||||
bool is_initialized = false;
|
||||
|
||||
ssh_mutex_lock(&ssh_init_mutex);
|
||||
is_initialized = _ssh_initialized > 0;
|
||||
ssh_mutex_unlock(&ssh_init_mutex);
|
||||
|
||||
return is_initialized;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -138,7 +138,7 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
|
||||
ssh_mac_update(ctx, key, key_len);
|
||||
ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
|
||||
ssh_mac_update(ctx, &letter, 1);
|
||||
ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
|
||||
ssh_mac_update(ctx, crypto->session_id, crypto->session_id_len);
|
||||
ssh_mac_final(digest, ctx);
|
||||
|
||||
if (requested_len < output_len) {
|
||||
|
||||
311
src/kex.c
311
src/kex.c
@@ -154,13 +154,12 @@
|
||||
ECDH \
|
||||
"diffie-hellman-group18-sha512,diffie-hellman-group16-sha512," \
|
||||
GEX_SHA256 \
|
||||
"diffie-hellman-group14-sha256," \
|
||||
"diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
|
||||
#define KEY_EXCHANGE_SUPPORTED \
|
||||
GEX_SHA1 \
|
||||
KEY_EXCHANGE
|
||||
|
||||
#define KEX_METHODS_SIZE 10
|
||||
|
||||
/* RFC 8308 */
|
||||
#define KEX_EXTENSION_CLIENT "ext-info-c"
|
||||
|
||||
@@ -185,6 +184,7 @@
|
||||
"ecdh-sha2-nistp384,"\
|
||||
"ecdh-sha2-nistp521,"\
|
||||
"diffie-hellman-group-exchange-sha256,"\
|
||||
"diffie-hellman-group14-sha256,"\
|
||||
"diffie-hellman-group16-sha512,"\
|
||||
"diffie-hellman-group18-sha512"
|
||||
|
||||
@@ -257,7 +257,7 @@ static const char *ssh_kex_descriptions[] = {
|
||||
|
||||
const char *ssh_kex_get_default_methods(uint32_t algo)
|
||||
{
|
||||
if (algo >= KEX_METHODS_SIZE) {
|
||||
if (algo >= SSH_KEX_METHODS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ const char *ssh_kex_get_default_methods(uint32_t algo)
|
||||
|
||||
const char *ssh_kex_get_supported_method(uint32_t algo)
|
||||
{
|
||||
if (algo >= KEX_METHODS_SIZE) {
|
||||
if (algo >= SSH_KEX_METHODS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ const char *ssh_kex_get_supported_method(uint32_t algo)
|
||||
}
|
||||
|
||||
const char *ssh_kex_get_description(uint32_t algo) {
|
||||
if (algo >= KEX_METHODS_SIZE) {
|
||||
if (algo >= SSH_KEX_METHODS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ const char *ssh_kex_get_description(uint32_t algo) {
|
||||
}
|
||||
|
||||
const char *ssh_kex_get_fips_methods(uint32_t algo) {
|
||||
if (algo >= KEX_METHODS_SIZE) {
|
||||
if (algo >= SSH_KEX_METHODS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -333,9 +333,10 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit)
|
||||
int i, ok;
|
||||
int server_kex = session->server;
|
||||
ssh_string str = NULL;
|
||||
char *strings[KEX_METHODS_SIZE] = {0};
|
||||
char *strings[SSH_KEX_METHODS] = {0};
|
||||
char *rsa_sig_ext = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
size_t len;
|
||||
|
||||
uint8_t first_kex_packet_follows = 0;
|
||||
uint32_t kexinit_reserved = 0;
|
||||
@@ -351,32 +352,32 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit)
|
||||
}
|
||||
|
||||
if (server_kex) {
|
||||
rc = ssh_buffer_get_data(packet,session->next_crypto->client_kex.cookie, 16);
|
||||
if (rc != 16) {
|
||||
len = ssh_buffer_get_data(packet,session->next_crypto->client_kex.cookie, 16);
|
||||
if (len != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie);
|
||||
if (rc < 0) {
|
||||
ok = ssh_hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie);
|
||||
if (ok < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
rc = ssh_buffer_get_data(packet,session->next_crypto->server_kex.cookie, 16);
|
||||
if (rc != 16) {
|
||||
len = ssh_buffer_get_data(packet,session->next_crypto->server_kex.cookie, 16);
|
||||
if (len != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie);
|
||||
if (rc < 0) {
|
||||
ok = ssh_hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie);
|
||||
if (ok < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
str = ssh_buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
@@ -393,7 +394,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit)
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
@@ -528,7 +529,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit)
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
error:
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
if (server_kex) {
|
||||
session->next_crypto->client_kex.methods[i] = NULL;
|
||||
@@ -547,7 +548,7 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
|
||||
int i = 0;
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("session cookie", kex->cookie, 16);
|
||||
ssh_log_hexdump("session cookie", kex->cookie, 16);
|
||||
#endif
|
||||
|
||||
for(i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
@@ -561,103 +562,94 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief selects the hostkey mechanisms to be chosen for the key exchange,
|
||||
* as some hostkey mechanisms may be present in known_hosts file and preferred
|
||||
* as some hostkey mechanisms may be present in known_hosts files.
|
||||
*
|
||||
* @returns a cstring containing a comma-separated list of hostkey methods.
|
||||
* NULL if no method matches
|
||||
*/
|
||||
char *ssh_client_select_hostkeys(ssh_session session)
|
||||
{
|
||||
char methods_buffer[128]={0};
|
||||
char tail_buffer[128]={0};
|
||||
const char *wanted = NULL;
|
||||
char *wanted_without_certs = NULL;
|
||||
char *known_hosts_algorithms = NULL;
|
||||
char *known_hosts_ordered = NULL;
|
||||
char *new_hostkeys = NULL;
|
||||
static const char *preferred_hostkeys[] = {
|
||||
"ssh-ed25519",
|
||||
"ecdsa-sha2-nistp521",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256",
|
||||
"ssh-rsa",
|
||||
#ifdef HAVE_DSA
|
||||
"ssh-dss",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
struct ssh_list *algo_list = NULL;
|
||||
struct ssh_iterator *it = NULL;
|
||||
size_t algo_count;
|
||||
int needcomma = 0;
|
||||
size_t i, len;
|
||||
char *fips_hostkeys = NULL;
|
||||
|
||||
algo_list = ssh_known_hosts_get_algorithms(session);
|
||||
if (algo_list == NULL) {
|
||||
wanted = session->opts.wanted_methods[SSH_HOSTKEYS];
|
||||
if (wanted == NULL) {
|
||||
if (ssh_fips_mode()) {
|
||||
wanted = ssh_kex_get_fips_methods(SSH_HOSTKEYS);
|
||||
} else {
|
||||
wanted = ssh_kex_get_default_methods(SSH_HOSTKEYS);
|
||||
}
|
||||
}
|
||||
|
||||
/* This removes the certificate types, unsupported for now */
|
||||
wanted_without_certs = ssh_find_all_matching(HOSTKEYS, wanted);
|
||||
if (wanted_without_certs == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"List of allowed host key algorithms is empty or contains only "
|
||||
"unsupported algorithms");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
algo_count = ssh_list_count(algo_list);
|
||||
if (algo_count == 0) {
|
||||
ssh_list_free(algo_list);
|
||||
return NULL;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Order of wanted host keys: \"%s\"",
|
||||
wanted_without_certs);
|
||||
|
||||
for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
|
||||
bool found = false;
|
||||
/* This is a signature type: We list also the SHA2 extensions */
|
||||
enum ssh_keytypes_e base_preferred =
|
||||
ssh_key_type_from_signature_name(preferred_hostkeys[i]);
|
||||
|
||||
for (it = ssh_list_get_iterator(algo_list);
|
||||
it != NULL;
|
||||
it = it->next) {
|
||||
const char *algo = ssh_iterator_value(const char *, it);
|
||||
/* This is always key type so we do not have to care for the
|
||||
* SHA2 extension */
|
||||
enum ssh_keytypes_e base_algo = ssh_key_type_from_name(algo);
|
||||
|
||||
if (base_preferred == base_algo) {
|
||||
/* Matching the keys already verified it is a known type */
|
||||
if (needcomma) {
|
||||
strncat(methods_buffer,
|
||||
",",
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
}
|
||||
strncat(methods_buffer,
|
||||
preferred_hostkeys[i],
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
needcomma = 1;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
/* Collect the rest of the algorithms in other buffer, that will
|
||||
* follow the preferred buffer. This will signalize all the algorithms
|
||||
* we are willing to accept.
|
||||
*/
|
||||
if (!found) {
|
||||
snprintf(tail_buffer + strlen(tail_buffer),
|
||||
sizeof(tail_buffer) - strlen(tail_buffer),
|
||||
",%s", preferred_hostkeys[i]);
|
||||
}
|
||||
}
|
||||
ssh_list_free(algo_list);
|
||||
|
||||
if (strlen(methods_buffer) == 0) {
|
||||
known_hosts_algorithms = ssh_known_hosts_get_algorithms_names(session);
|
||||
if (known_hosts_algorithms == NULL) {
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"No supported kex method for existing key in known_hosts file");
|
||||
return NULL;
|
||||
"No key found in known_hosts; "
|
||||
"changing host key method to \"%s\"",
|
||||
wanted_without_certs);
|
||||
|
||||
return wanted_without_certs;
|
||||
}
|
||||
|
||||
/* Append the supported list to the preferred.
|
||||
* The length is maximum 128 + 128 + 1, which will not overflow
|
||||
*/
|
||||
len = strlen(methods_buffer) + strlen(tail_buffer) + 1;
|
||||
new_hostkeys = malloc(len);
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Algorithms found in known_hosts files: \"%s\"",
|
||||
known_hosts_algorithms);
|
||||
|
||||
/* Filter and order the keys from known_hosts according to wanted list */
|
||||
known_hosts_ordered = ssh_find_all_matching(known_hosts_algorithms,
|
||||
wanted_without_certs);
|
||||
SAFE_FREE(known_hosts_algorithms);
|
||||
if (known_hosts_ordered == NULL) {
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"No key found in known_hosts is allowed; "
|
||||
"changing host key method to \"%s\"",
|
||||
wanted_without_certs);
|
||||
|
||||
return wanted_without_certs;
|
||||
}
|
||||
|
||||
/* Append the other supported keys after the preferred ones
|
||||
* This function tolerates NULL pointers in parameters */
|
||||
new_hostkeys = ssh_append_without_duplicates(known_hosts_ordered,
|
||||
wanted_without_certs);
|
||||
SAFE_FREE(known_hosts_ordered);
|
||||
SAFE_FREE(wanted_without_certs);
|
||||
if (new_hostkeys == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(new_hostkeys, len,
|
||||
"%s%s", methods_buffer, tail_buffer);
|
||||
|
||||
if (ssh_fips_mode()) {
|
||||
/* Filter out algorithms not allowed in FIPS mode */
|
||||
fips_hostkeys = ssh_keep_fips_algos(SSH_HOSTKEYS, new_hostkeys);
|
||||
SAFE_FREE(new_hostkeys);
|
||||
if (fips_hostkeys == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"None of the wanted host keys or keys in known_hosts files "
|
||||
"is allowed in FIPS mode.");
|
||||
return NULL;
|
||||
}
|
||||
new_hostkeys = fips_hostkeys;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Changing host key method to \"%s\"",
|
||||
@@ -672,7 +664,7 @@ char *ssh_client_select_hostkeys(ssh_session session)
|
||||
*/
|
||||
int ssh_set_client_kex(ssh_session session)
|
||||
{
|
||||
struct ssh_kex_struct *client= &session->next_crypto->client_kex;
|
||||
struct ssh_kex_struct *client = &session->next_crypto->client_kex;
|
||||
const char *wanted;
|
||||
char *kex = NULL;
|
||||
char *kex_tmp = NULL;
|
||||
@@ -686,15 +678,23 @@ int ssh_set_client_kex(ssh_session session)
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
|
||||
/* first check if we have specific host key methods */
|
||||
if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) {
|
||||
/* Only if no override */
|
||||
session->opts.wanted_methods[SSH_HOSTKEYS] =
|
||||
ssh_client_select_hostkeys(session);
|
||||
}
|
||||
memset(client->methods, 0, SSH_KEX_METHODS * sizeof(char **));
|
||||
|
||||
/* Set the list of allowed algorithms in order of preference, if it hadn't
|
||||
* been set yet. */
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
if (i == SSH_HOSTKEYS) {
|
||||
/* Set the hostkeys in the following order:
|
||||
* - First: keys present in known_hosts files ordered by preference
|
||||
* - Next: other wanted algorithms ordered by preference */
|
||||
client->methods[i] = ssh_client_select_hostkeys(session);
|
||||
if (client->methods[i] == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
wanted = session->opts.wanted_methods[i];
|
||||
if (wanted == NULL) {
|
||||
if (ssh_fips_mode()) {
|
||||
@@ -735,13 +735,29 @@ int ssh_set_client_kex(ssh_session session)
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static const char *ssh_find_aead_hmac(const char *cipher)
|
||||
{
|
||||
if (cipher == NULL) {
|
||||
return NULL;
|
||||
} else if (strcmp(cipher, "chacha20-poly1305@openssh.com") == 0) {
|
||||
return "aead-poly1305";
|
||||
} else if (strcmp(cipher, "aes256-gcm@openssh.com") == 0) {
|
||||
return "aead-gcm";
|
||||
} else if (strcmp(cipher, "aes128-gcm@openssh.com") == 0) {
|
||||
return "aead-gcm";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @brief Select the different methods on basis of client's and
|
||||
* server's kex messages, and watches out if a match is possible.
|
||||
*/
|
||||
int ssh_kex_select_methods (ssh_session session){
|
||||
int ssh_kex_select_methods (ssh_session session)
|
||||
{
|
||||
struct ssh_kex_struct *server = &session->next_crypto->server_kex;
|
||||
struct ssh_kex_struct *client = &session->next_crypto->client_kex;
|
||||
char *ext_start = NULL;
|
||||
const char *aead_hmac = NULL;
|
||||
int i;
|
||||
|
||||
/* Here we should drop the ext-info-c from the list so we avoid matching.
|
||||
@@ -751,9 +767,17 @@ int ssh_kex_select_methods (ssh_session session){
|
||||
ext_start[0] = '\0';
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
session->next_crypto->kex_methods[i]=ssh_find_matching(server->methods[i],client->methods[i]);
|
||||
if(session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){
|
||||
|
||||
if (i == SSH_MAC_C_S || i == SSH_MAC_S_C) {
|
||||
aead_hmac = ssh_find_aead_hmac(session->next_crypto->kex_methods[i-2]);
|
||||
if (aead_hmac) {
|
||||
free(session->next_crypto->kex_methods[i]);
|
||||
session->next_crypto->kex_methods[i] = strdup(aead_hmac);
|
||||
}
|
||||
}
|
||||
if (session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){
|
||||
ssh_set_error(session,SSH_FATAL,"kex error : no match for method %s: server [%s], client [%s]",
|
||||
ssh_kex_descriptions[i],server->methods[i],client->methods[i]);
|
||||
return SSH_ERROR;
|
||||
@@ -762,29 +786,31 @@ int ssh_kex_select_methods (ssh_session session){
|
||||
session->next_crypto->kex_methods[i] = strdup("");
|
||||
}
|
||||
}
|
||||
if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){
|
||||
if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP1_SHA1;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA256;
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP16_SHA512;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP18_SHA512;
|
||||
#ifdef WITH_GEX
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA1;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA256;
|
||||
#endif /* WITH_GEX */
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP384;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP521;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
|
||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){
|
||||
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){
|
||||
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_INFO, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
|
||||
@@ -804,7 +830,8 @@ int ssh_kex_select_methods (ssh_session session){
|
||||
|
||||
|
||||
/* this function only sends the predefined set of kex methods */
|
||||
int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
int ssh_send_kex(ssh_session session, int server_kex)
|
||||
{
|
||||
struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex :
|
||||
&session->next_crypto->client_kex);
|
||||
ssh_string str = NULL;
|
||||
@@ -824,7 +851,7 @@ int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
|
||||
ssh_list_kex(kex);
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
str = ssh_string_from_char(kex->methods[i]);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
@@ -836,7 +863,7 @@ int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
if (ssh_buffer_add_ssh_string(session->out_buffer, str) < 0) {
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
@@ -857,7 +884,7 @@ int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_hashbuf);
|
||||
ssh_string_free(str);
|
||||
SSH_STRING_FREE(str);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1020,14 +1047,15 @@ int ssh_make_sessionid(ssh_session session)
|
||||
ssh_buffer_get_len(server_hash),
|
||||
ssh_buffer_get(server_hash),
|
||||
server_pubkey_blob);
|
||||
ssh_string_free(server_pubkey_blob);
|
||||
if(rc != SSH_OK){
|
||||
SSH_STRING_FREE(server_pubkey_blob);
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch(session->next_crypto->kex_type) {
|
||||
case SSH_KEX_DH_GROUP1_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA256:
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
case SSH_KEX_DH_GROUP18_SHA512:
|
||||
rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
|
||||
@@ -1120,7 +1148,7 @@ int ssh_make_sessionid(ssh_session session)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf));
|
||||
ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf));
|
||||
#endif
|
||||
|
||||
switch (session->next_crypto->kex_type) {
|
||||
@@ -1139,6 +1167,7 @@ int ssh_make_sessionid(ssh_session session)
|
||||
sha1(ssh_buffer_get(buf), ssh_buffer_get_len(buf),
|
||||
session->next_crypto->secret_hash);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP14_SHA256:
|
||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||
case SSH_KEX_CURVE25519_SHA256:
|
||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||
@@ -1193,23 +1222,25 @@ int ssh_make_sessionid(ssh_session session)
|
||||
}
|
||||
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
|
||||
session->next_crypto->digest_len);
|
||||
/* Initial length is the same as secret hash */
|
||||
session->next_crypto->session_id_len = session->next_crypto->digest_len;
|
||||
}
|
||||
#ifdef DEBUG_CRYPTO
|
||||
printf("Session hash: \n");
|
||||
ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
|
||||
ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
|
||||
ssh_log_hexdump("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
|
||||
ssh_log_hexdump("session id", session->next_crypto->session_id, session->next_crypto->session_id_len);
|
||||
#endif
|
||||
|
||||
rc = SSH_OK;
|
||||
error:
|
||||
ssh_buffer_free(buf);
|
||||
ssh_buffer_free(client_hash);
|
||||
ssh_buffer_free(server_hash);
|
||||
SSH_BUFFER_FREE(buf);
|
||||
SSH_BUFFER_FREE(client_hash);
|
||||
SSH_BUFFER_FREE(server_hash);
|
||||
|
||||
session->in_hashbuf = NULL;
|
||||
session->out_hashbuf = NULL;
|
||||
|
||||
ssh_string_free(num);
|
||||
SSH_STRING_FREE(num);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1384,22 +1415,22 @@ int ssh_generate_session_keys(ssh_session session)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Client to Server IV", IV_cli_to_srv, IV_len);
|
||||
ssh_print_hexa("Server to Client IV", IV_srv_to_cli, IV_len);
|
||||
ssh_print_hexa("Client to Server Encryption Key", enckey_cli_to_srv,
|
||||
ssh_log_hexdump("Client to Server IV", IV_cli_to_srv, IV_len);
|
||||
ssh_log_hexdump("Server to Client IV", IV_srv_to_cli, IV_len);
|
||||
ssh_log_hexdump("Client to Server Encryption Key", enckey_cli_to_srv,
|
||||
enckey_cli_to_srv_len);
|
||||
ssh_print_hexa("Server to Client Encryption Key", enckey_srv_to_cli,
|
||||
ssh_log_hexdump("Server to Client Encryption Key", enckey_srv_to_cli,
|
||||
enckey_srv_to_cli_len);
|
||||
ssh_print_hexa("Client to Server Integrity Key", intkey_cli_to_srv,
|
||||
ssh_log_hexdump("Client to Server Integrity Key", intkey_cli_to_srv,
|
||||
intkey_cli_to_srv_len);
|
||||
ssh_print_hexa("Server to Client Integrity Key", intkey_srv_to_cli,
|
||||
ssh_log_hexdump("Server to Client Integrity Key", intkey_srv_to_cli,
|
||||
intkey_srv_to_cli_len);
|
||||
#endif
|
||||
|
||||
rc = 0;
|
||||
error:
|
||||
ssh_string_burn(k_string);
|
||||
ssh_string_free(k_string);
|
||||
SSH_STRING_FREE(k_string);
|
||||
if (rc != 0) {
|
||||
free(IV_cli_to_srv);
|
||||
free(IV_srv_to_cli);
|
||||
|
||||
@@ -405,8 +405,12 @@ int ssh_is_server_known(ssh_session session)
|
||||
|
||||
if ((ret == SSH_SERVER_NOT_KNOWN) &&
|
||||
(session->opts.StrictHostKeyChecking == 0)) {
|
||||
ssh_write_knownhost(session);
|
||||
ret = SSH_SERVER_KNOWN_OK;
|
||||
int rv = ssh_session_update_known_hosts(session);
|
||||
if (rv != SSH_OK) {
|
||||
ret = SSH_SERVER_ERROR;
|
||||
} else {
|
||||
ret = SSH_SERVER_KNOWN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(host);
|
||||
@@ -492,10 +496,12 @@ char * ssh_dump_knownhost(ssh_session session) {
|
||||
* @deprecated Please use ssh_session_update_known_hosts()
|
||||
* @brief This function is deprecated
|
||||
*/
|
||||
int ssh_write_knownhost(ssh_session session) {
|
||||
int ssh_write_knownhost(ssh_session session)
|
||||
{
|
||||
FILE *file;
|
||||
char *buffer;
|
||||
char *buffer = NULL;
|
||||
char *dir;
|
||||
int rc;
|
||||
|
||||
if (session->opts.knownhosts == NULL) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
@@ -504,33 +510,45 @@ int ssh_write_knownhost(ssh_session session) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if directory exists and create it if not */
|
||||
dir = ssh_dirname(session->opts.knownhosts);
|
||||
if (dir == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
errno = 0;
|
||||
file = fopen(session->opts.knownhosts, "a");
|
||||
if (file == NULL) {
|
||||
if (errno == ENOENT) {
|
||||
dir = ssh_dirname(session->opts.knownhosts);
|
||||
if (dir == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (!ssh_file_readaccess_ok(dir)) {
|
||||
if (ssh_mkdir(dir, 0700) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Cannot create %s directory.", dir);
|
||||
rc = ssh_mkdirs(dir, 0700);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Cannot create %s directory: %s",
|
||||
dir, strerror(errno));
|
||||
SAFE_FREE(dir);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SAFE_FREE(dir);
|
||||
|
||||
errno = 0;
|
||||
file = fopen(session->opts.knownhosts, "a");
|
||||
if (file == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't open known_hosts file %s"
|
||||
" for appending: %s",
|
||||
session->opts.knownhosts, strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
} else {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't open known_hosts file %s for appending: %s",
|
||||
session->opts.knownhosts, strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
SAFE_FREE(dir);
|
||||
|
||||
file = fopen(session->opts.knownhosts, "a");
|
||||
if (file == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't open known_hosts file %s for appending: %s",
|
||||
session->opts.knownhosts, strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
buffer = ssh_dump_knownhost(session);
|
||||
if (buffer == NULL) {
|
||||
rc = ssh_session_export_known_hosts_entry(session, &buffer);
|
||||
if (rc != SSH_OK) {
|
||||
fclose(file);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
251
src/knownhosts.c
251
src/knownhosts.c
@@ -42,6 +42,7 @@
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/knownhosts.h"
|
||||
#include "libssh/token.h"
|
||||
|
||||
/**
|
||||
* @addtogroup libssh_session
|
||||
@@ -128,8 +129,8 @@ static int match_hashed_hostname(const char *host, const char *hashed_host)
|
||||
|
||||
error:
|
||||
free(hashed);
|
||||
ssh_buffer_free(salt);
|
||||
ssh_buffer_free(hash);
|
||||
SSH_BUFFER_FREE(salt);
|
||||
SSH_BUFFER_FREE(hash);
|
||||
|
||||
return match;
|
||||
}
|
||||
@@ -306,7 +307,7 @@ static char *ssh_session_get_host_port(ssh_session session)
|
||||
if (session->opts.host == NULL) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Can't verify server inn known hosts if the host we "
|
||||
"Can't verify server in known hosts if the host we "
|
||||
"should connect to has not been set");
|
||||
|
||||
return NULL;
|
||||
@@ -371,6 +372,7 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
|
||||
list = ssh_list_new();
|
||||
if (list == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
SAFE_FREE(host_port);
|
||||
return NULL;
|
||||
}
|
||||
@@ -451,6 +453,146 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Returns a static string containing a list of the signature types the
|
||||
* given key type can generate.
|
||||
*
|
||||
* @returns A static cstring containing the signature types the key is able to
|
||||
* generate separated by commas; NULL in case of error
|
||||
*/
|
||||
static const char *ssh_known_host_sigs_from_hostkey_type(enum ssh_keytypes_e type)
|
||||
{
|
||||
switch (type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
return "rsa-sha2-512,rsa-sha2-256,ssh-rsa";
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
return "ssh-ed25519";
|
||||
#ifdef HAVE_DSA
|
||||
case SSH_KEYTYPE_DSS:
|
||||
return "ssh-dss";
|
||||
#endif
|
||||
#ifdef HAVE_ECDH
|
||||
case SSH_KEYTYPE_ECDSA_P256:
|
||||
return "ecdsa-sha2-nistp256";
|
||||
case SSH_KEYTYPE_ECDSA_P384:
|
||||
return "ecdsa-sha2-nistp384";
|
||||
case SSH_KEYTYPE_ECDSA_P521:
|
||||
return "ecdsa-sha2-nistp521";
|
||||
#endif
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "The given type %d is not a base private key type "
|
||||
"or is unsupported", type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Get the host keys algorithms identifiers from the known_hosts files
|
||||
*
|
||||
* This expands the signatures types that can be generated from the keys types
|
||||
* present in the known_hosts files
|
||||
*
|
||||
* @param[in] session The ssh session to use.
|
||||
*
|
||||
* @return A newly allocated cstring containing a list of signature algorithms
|
||||
* that can be generated by the host using the keys listed in the known_hosts
|
||||
* files, NULL on error.
|
||||
*/
|
||||
char *ssh_known_hosts_get_algorithms_names(ssh_session session)
|
||||
{
|
||||
char methods_buffer[256 + 1] = {0};
|
||||
struct ssh_list *entry_list = NULL;
|
||||
struct ssh_iterator *it = NULL;
|
||||
char *host_port = NULL;
|
||||
size_t count;
|
||||
bool needcomma = false;
|
||||
char *names;
|
||||
|
||||
int rc;
|
||||
|
||||
if (session->opts.knownhosts == NULL ||
|
||||
session->opts.global_knownhosts == NULL) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"Can't find a known_hosts file");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
host_port = ssh_session_get_host_port(session);
|
||||
if (host_port == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.knownhosts,
|
||||
&entry_list);
|
||||
if (rc != 0) {
|
||||
SAFE_FREE(host_port);
|
||||
ssh_list_free(entry_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.global_knownhosts,
|
||||
&entry_list);
|
||||
SAFE_FREE(host_port);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (entry_list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = ssh_list_count(entry_list);
|
||||
if (count == 0) {
|
||||
ssh_list_free(entry_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (it = ssh_list_get_iterator(entry_list);
|
||||
it != NULL;
|
||||
it = ssh_list_get_iterator(entry_list))
|
||||
{
|
||||
struct ssh_knownhosts_entry *entry = NULL;
|
||||
const char *algo = NULL;
|
||||
|
||||
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
|
||||
algo = ssh_known_host_sigs_from_hostkey_type(entry->publickey->type);
|
||||
if (algo == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (needcomma) {
|
||||
strncat(methods_buffer,
|
||||
",",
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
}
|
||||
|
||||
strncat(methods_buffer,
|
||||
algo,
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
needcomma = true;
|
||||
|
||||
ssh_knownhosts_entry_free(entry);
|
||||
ssh_list_remove(entry_list, it);
|
||||
}
|
||||
|
||||
ssh_list_free(entry_list);
|
||||
|
||||
names = ssh_remove_duplicates(methods_buffer);
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse a line from a known_hosts entry into a structure
|
||||
*
|
||||
@@ -638,14 +780,15 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
|
||||
struct ssh_list *entry_list = NULL;
|
||||
struct ssh_iterator *it = NULL;
|
||||
char *host_port = NULL;
|
||||
bool ok;
|
||||
bool global_known_hosts_found = false;
|
||||
bool known_hosts_found = false;
|
||||
int rc;
|
||||
|
||||
if (session->opts.knownhosts == NULL) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"Can't find a known_hosts file");
|
||||
"Cannot find a known_hosts file");
|
||||
|
||||
return SSH_KNOWN_HOSTS_NOT_FOUND;
|
||||
}
|
||||
@@ -653,50 +796,67 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
|
||||
|
||||
if (session->opts.knownhosts == NULL &&
|
||||
session->opts.global_knownhosts == NULL) {
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"No path set for a known_hosts file");
|
||||
|
||||
return SSH_KNOWN_HOSTS_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (session->opts.knownhosts != NULL) {
|
||||
ok = ssh_file_readaccess_ok(session->opts.knownhosts);
|
||||
if (!ok) {
|
||||
return SSH_KNOWN_HOSTS_NOT_FOUND;
|
||||
known_hosts_found = ssh_file_readaccess_ok(session->opts.knownhosts);
|
||||
if (!known_hosts_found) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Cannot access file %s",
|
||||
session->opts.knownhosts);
|
||||
}
|
||||
}
|
||||
|
||||
if (session->opts.global_knownhosts != NULL) {
|
||||
ok = ssh_file_readaccess_ok(session->opts.global_knownhosts);
|
||||
if (!ok) {
|
||||
return SSH_KNOWN_HOSTS_NOT_FOUND;
|
||||
global_known_hosts_found =
|
||||
ssh_file_readaccess_ok(session->opts.global_knownhosts);
|
||||
if (!global_known_hosts_found) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Cannot access file %s",
|
||||
session->opts.global_knownhosts);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!known_hosts_found) && (!global_known_hosts_found)) {
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"Cannot find a known_hosts file");
|
||||
|
||||
return SSH_KNOWN_HOSTS_NOT_FOUND;
|
||||
}
|
||||
|
||||
host_port = ssh_session_get_host_port(session);
|
||||
if (host_port == NULL) {
|
||||
return SSH_KNOWN_HOSTS_ERROR;
|
||||
}
|
||||
|
||||
if (session->opts.knownhosts != NULL) {
|
||||
if (known_hosts_found) {
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.knownhosts,
|
||||
&entry_list);
|
||||
if (rc != 0) {
|
||||
SAFE_FREE(host_port);
|
||||
ssh_list_free(entry_list);
|
||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
return SSH_KNOWN_HOSTS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (session->opts.global_knownhosts != NULL) {
|
||||
if (global_known_hosts_found) {
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.global_knownhosts,
|
||||
&entry_list);
|
||||
SAFE_FREE(host_port);
|
||||
if (rc != 0) {
|
||||
SAFE_FREE(host_port);
|
||||
ssh_list_free(entry_list);
|
||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
return SSH_KNOWN_HOSTS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(host_port);
|
||||
|
||||
if (ssh_list_count(entry_list) == 0) {
|
||||
ssh_list_free(entry_list);
|
||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
@@ -820,34 +980,41 @@ int ssh_session_update_known_hosts(ssh_session session)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if directory exists and create it if not */
|
||||
dir = ssh_dirname(session->opts.knownhosts);
|
||||
if (dir == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_file_readaccess_ok(dir);
|
||||
if (rc == 0) {
|
||||
rc = ssh_mkdir(dir, 0700);
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Cannot create %s directory.", dir);
|
||||
SAFE_FREE(dir);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SAFE_FREE(dir);
|
||||
|
||||
errno = 0;
|
||||
fp = fopen(session->opts.knownhosts, "a");
|
||||
if (fp == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't open known_hosts file %s for appending: %s",
|
||||
session->opts.knownhosts, strerror(errno));
|
||||
return SSH_ERROR;
|
||||
if (errno == ENOENT) {
|
||||
dir = ssh_dirname(session->opts.knownhosts);
|
||||
if (dir == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "%s", strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_mkdirs(dir, 0700);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Cannot create %s directory: %s",
|
||||
dir, strerror(errno));
|
||||
SAFE_FREE(dir);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SAFE_FREE(dir);
|
||||
|
||||
errno = 0;
|
||||
fp = fopen(session->opts.knownhosts, "a");
|
||||
if (fp == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't open known_hosts file %s"
|
||||
" for appending: %s",
|
||||
session->opts.knownhosts, strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
} else {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Couldn't open known_hosts file %s for appending: %s",
|
||||
session->opts.knownhosts, strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_session_export_known_hosts_entry(session, &entry);
|
||||
|
||||
@@ -353,7 +353,7 @@ void publickey_free(ssh_public_key key) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_release(key->dsa_pub);
|
||||
#elif HAVE_LIBCRYPTO
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
DSA_free(key->dsa_pub);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -280,6 +280,12 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HMAC_CTX *HMAC_CTX_new(void)
|
||||
{
|
||||
HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
|
||||
@@ -394,3 +400,12 @@ int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *OpenSSL_version(int type)
|
||||
{
|
||||
return SSLeay_version(type);
|
||||
}
|
||||
unsigned long OpenSSL_version_num(void)
|
||||
{
|
||||
return SSLeay();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
|
||||
EVP_MD_CTX *EVP_MD_CTX_new(void);
|
||||
void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
|
||||
|
||||
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx);
|
||||
|
||||
HMAC_CTX *HMAC_CTX_new(void);
|
||||
int HMAC_CTX_reset(HMAC_CTX *ctx);
|
||||
void HMAC_CTX_free(HMAC_CTX *ctx);
|
||||
@@ -44,6 +46,10 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
|
||||
void DH_get0_key(const DH *dh,
|
||||
const BIGNUM **pub_key, const BIGNUM **priv_key);
|
||||
int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
|
||||
|
||||
const char *OpenSSL_version(int type);
|
||||
unsigned long OpenSSL_version_num(void);
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
|
||||
#endif /* LIBCRYPTO_COMPAT_H */
|
||||
|
||||
@@ -392,7 +392,7 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||
goto out;
|
||||
}
|
||||
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
|
||||
crypto->session_id, crypto->digest_len);
|
||||
crypto->session_id, crypto->session_id_len);
|
||||
if (rc != 1) {
|
||||
goto out;
|
||||
}
|
||||
@@ -536,7 +536,7 @@ static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher,
|
||||
int rc;
|
||||
|
||||
evp_cipher_init(cipher);
|
||||
EVP_CIPHER_CTX_init(cipher->ctx);
|
||||
EVP_CIPHER_CTX_reset(cipher->ctx);
|
||||
|
||||
rc = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV);
|
||||
if (rc != 1){
|
||||
@@ -569,7 +569,7 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
|
||||
int rc;
|
||||
|
||||
evp_cipher_init(cipher);
|
||||
EVP_CIPHER_CTX_init(cipher->ctx);
|
||||
EVP_CIPHER_CTX_reset(cipher->ctx);
|
||||
|
||||
rc = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV);
|
||||
if (rc != 1){
|
||||
@@ -652,7 +652,6 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
|
||||
|
||||
static void evp_cipher_cleanup(struct ssh_cipher_struct *cipher) {
|
||||
if (cipher->ctx != NULL) {
|
||||
EVP_CIPHER_CTX_cleanup(cipher->ctx);
|
||||
EVP_CIPHER_CTX_free(cipher->ctx);
|
||||
}
|
||||
}
|
||||
@@ -686,8 +685,12 @@ static int aes_ctr_set_key(struct ssh_cipher_struct *cipher, void *key,
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len) {
|
||||
static void
|
||||
aes_ctr_encrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
unsigned char tmp_buffer[AES_BLOCK_SIZE];
|
||||
unsigned int num=0;
|
||||
/* Some things are special with ctr128 :
|
||||
@@ -704,8 +707,12 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou
|
||||
}
|
||||
|
||||
static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
|
||||
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
|
||||
SAFE_FREE(cipher->aes_key);
|
||||
if (cipher != NULL) {
|
||||
if (cipher->aes_key != NULL) {
|
||||
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
|
||||
}
|
||||
SAFE_FREE(cipher->aes_key);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_CTR */
|
||||
@@ -1076,11 +1083,11 @@ int ssh_crypto_init(void)
|
||||
if (libcrypto_initialized) {
|
||||
return SSH_OK;
|
||||
}
|
||||
if (SSLeay() != OPENSSL_VERSION_NUMBER){
|
||||
if (OpenSSL_version_num() != OPENSSL_VERSION_NUMBER){
|
||||
SSH_LOG(SSH_LOG_WARNING, "libssh compiled with %s "
|
||||
"headers, currently running with %s.",
|
||||
OPENSSL_VERSION_TEXT,
|
||||
SSLeay_version(SSLeay())
|
||||
OpenSSL_version(OpenSSL_version_num())
|
||||
);
|
||||
}
|
||||
#ifdef CAN_DISABLE_AESNI
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user