mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-05 04:40:31 +09:00
Compare commits
348 Commits
libssh-0.9
...
libssh-0.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
273fb4cfc6 | ||
|
|
56f7c27852 | ||
|
|
1285b37b60 | ||
|
|
b7de358cdc | ||
|
|
bea6393de0 | ||
|
|
9158cc524c | ||
|
|
8ba10ef42b | ||
|
|
2ff8a09ee6 | ||
|
|
d52fa9a02c | ||
|
|
ec3fdb434c | ||
|
|
d877969db3 | ||
|
|
b1a7bd21ad | ||
|
|
0831b85002 | ||
|
|
34d1f5e097 | ||
|
|
fcf2cd0d9e | ||
|
|
4a4ca44b19 | ||
|
|
17a6c3f88f | ||
|
|
e24bb932ed | ||
|
|
5c2d444fa8 | ||
|
|
9763563c02 | ||
|
|
5f9d9f4a53 | ||
|
|
e8f3207a0d | ||
|
|
e5cee205c1 | ||
|
|
63056d1bb1 | ||
|
|
09e4f3d331 | ||
|
|
4b886ac656 | ||
|
|
789df0b7d0 | ||
|
|
66a222a73c | ||
|
|
09a7638575 | ||
|
|
203818608a | ||
|
|
f8c452cbef | ||
|
|
adeaa69cc5 | ||
|
|
72bce5ece7 | ||
|
|
7819621fc2 | ||
|
|
fcfba0d8aa | ||
|
|
b166ac4749 | ||
|
|
160a416ef6 | ||
|
|
59071bc4c5 | ||
|
|
2ae63251d3 | ||
|
|
eefae820b5 | ||
|
|
0792fb37b0 | ||
|
|
e23c28a82b | ||
|
|
7291b50420 | ||
|
|
c1d61617fb | ||
|
|
488fb47c32 | ||
|
|
721132696c | ||
|
|
ee034e0484 | ||
|
|
d56c8fdfc6 | ||
|
|
4269b62153 | ||
|
|
c6c63030c5 | ||
|
|
afa5dbb8b1 | ||
|
|
bd7e8295e2 | ||
|
|
933d9c6b07 | ||
|
|
0f0eb05e03 | ||
|
|
171a950a80 | ||
|
|
b1b1da0f97 | ||
|
|
7453038d74 | ||
|
|
29ef92a95e | ||
|
|
6650685758 | ||
|
|
bdca6b7efa | ||
|
|
97b2a61d74 | ||
|
|
781ce47dea | ||
|
|
277ee932d6 | ||
|
|
c91f530610 | ||
|
|
69740ea841 | ||
|
|
1bb7895cd9 | ||
|
|
a028b88aed | ||
|
|
8a25f6bb07 | ||
|
|
2db453db16 | ||
|
|
03134c2932 | ||
|
|
95d0c143b3 | ||
|
|
3dcdafa6d7 | ||
|
|
75c446c529 | ||
|
|
4a9c32fc81 | ||
|
|
1634c5a91a | ||
|
|
dfa7593c27 | ||
|
|
034af66338 | ||
|
|
55c7b93a0a | ||
|
|
4818cf5606 | ||
|
|
316a3a42a4 | ||
|
|
546d9da185 | ||
|
|
3b7d997b54 | ||
|
|
129744692c | ||
|
|
83f6ce0928 | ||
|
|
b5c7f07064 | ||
|
|
223ba36d54 | ||
|
|
9141e9d4fe | ||
|
|
ead42db7c8 | ||
|
|
d5a68bedfd | ||
|
|
4307489702 | ||
|
|
f0da1f2e03 | ||
|
|
50477cb80b | ||
|
|
ded4a81ffe | ||
|
|
c2bc4e62dd | ||
|
|
f7ab481b22 | ||
|
|
628b529a91 | ||
|
|
7e25963130 | ||
|
|
91d8f1a256 | ||
|
|
61dcc023b0 | ||
|
|
4468a78ee2 | ||
|
|
8f18063b6d | ||
|
|
a167faee3e | ||
|
|
0e8f6aaee5 | ||
|
|
f0a1b94d0d | ||
|
|
5d1ddf5920 | ||
|
|
152ae623c2 | ||
|
|
e7bd9d02bc | ||
|
|
9196639940 | ||
|
|
786d7e39a3 | ||
|
|
c33710d112 | ||
|
|
a14a80f35f | ||
|
|
0389ff6d9d | ||
|
|
8954fccfdb | ||
|
|
332df98fc9 | ||
|
|
d4cc3f69c6 | ||
|
|
534c58c475 | ||
|
|
84fd910423 | ||
|
|
d51f77c2b1 | ||
|
|
47376cbc77 | ||
|
|
85c3db3e89 | ||
|
|
3f8a522c7f | ||
|
|
eb08802b7c | ||
|
|
dc587045bf | ||
|
|
9b495b72c5 | ||
|
|
2ce6c56609 | ||
|
|
9caef95899 | ||
|
|
66c2630aaf | ||
|
|
b8f63ee2df | ||
|
|
68adb49996 | ||
|
|
12e94bfd18 | ||
|
|
4fc3d7a27f | ||
|
|
466bb332c1 | ||
|
|
ff25b45367 | ||
|
|
df83f4fb57 | ||
|
|
5bda3ab9f6 | ||
|
|
9a057159a2 | ||
|
|
9c0875dd5d | ||
|
|
1fa5a2a504 | ||
|
|
a08a2f52fb | ||
|
|
21d37f8605 | ||
|
|
e43586b4de | ||
|
|
dc7e1bdb39 | ||
|
|
03d559b066 | ||
|
|
3191c1f6be | ||
|
|
d46f01cb7c | ||
|
|
04e290a19b | ||
|
|
bad407f5e2 | ||
|
|
2787756efe | ||
|
|
7b35afdf6b | ||
|
|
dba2903e38 | ||
|
|
965014b035 | ||
|
|
c4ec92f375 | ||
|
|
54cf9d1364 | ||
|
|
23ce6d7156 | ||
|
|
07473976e1 | ||
|
|
51063fe07e | ||
|
|
9cc1af1d53 | ||
|
|
8a83bc0569 | ||
|
|
0181f5b5ed | ||
|
|
eaae8ce086 | ||
|
|
0b2072dd30 | ||
|
|
2e77cf6b34 | ||
|
|
ad3c052e1c | ||
|
|
57d9d97866 | ||
|
|
22747c862a | ||
|
|
fed755eee5 | ||
|
|
804410f8ad | ||
|
|
df57a9a81d | ||
|
|
97076780a5 | ||
|
|
899553f9f7 | ||
|
|
2edff5e69e | ||
|
|
37f451171b | ||
|
|
2efc1721d8 | ||
|
|
e9613e6b52 | ||
|
|
73fbe68ccd | ||
|
|
0cb282df99 | ||
|
|
fdb0c0a29b | ||
|
|
2e56db3b2f | ||
|
|
4eb759bf40 | ||
|
|
c3987a9796 | ||
|
|
a070c942e7 | ||
|
|
113b1872cf | ||
|
|
c7dc2937fc | ||
|
|
075895da40 | ||
|
|
7930086a37 | ||
|
|
3f376f848d | ||
|
|
3cee61a65b | ||
|
|
90321f732e | ||
|
|
c6140b1a4c | ||
|
|
9290d89570 | ||
|
|
da9ab71f88 | ||
|
|
53dfee98d2 | ||
|
|
bb14611f86 | ||
|
|
b1aca92268 | ||
|
|
2b524655ae | ||
|
|
b51594c34a | ||
|
|
b409b7d092 | ||
|
|
4256936fed | ||
|
|
fdb6dc7069 | ||
|
|
6291900234 | ||
|
|
216bd2abd8 | ||
|
|
574f279f00 | ||
|
|
d886870bbf | ||
|
|
f56c93cccd | ||
|
|
bbd17bc97a | ||
|
|
26fa923b55 | ||
|
|
177a082974 | ||
|
|
ce3ee332d4 | ||
|
|
eb95f8fa85 | ||
|
|
8d3db75724 | ||
|
|
e1fbc02209 | ||
|
|
766041d956 | ||
|
|
f880a7728f | ||
|
|
013203301f | ||
|
|
bfb60befa7 | ||
|
|
4d34890624 | ||
|
|
6751c0e2c3 | ||
|
|
a641b6ea79 | ||
|
|
fa3c73016d | ||
|
|
ffabd8c6ed | ||
|
|
219a311925 | ||
|
|
8e3af4d859 | ||
|
|
9fa614a36d | ||
|
|
3d207f72a0 | ||
|
|
f53d2f7511 | ||
|
|
b853d99546 | ||
|
|
a09976e3d6 | ||
|
|
1ba0432524 | ||
|
|
7dcd749ee1 | ||
|
|
30368fb06a | ||
|
|
fd6b7db1ce | ||
|
|
53514b2a40 | ||
|
|
0e20418296 | ||
|
|
92b59ace9e | ||
|
|
af7b5b78ee | ||
|
|
2b67e2d54c | ||
|
|
f44994f1e6 | ||
|
|
97d6eb84a4 | ||
|
|
33f2211cae | ||
|
|
03aff19b80 | ||
|
|
cf660fe27c | ||
|
|
f9d60e1360 | ||
|
|
1098280e43 | ||
|
|
62301834f4 | ||
|
|
3e0ac84001 | ||
|
|
4d26e08789 | ||
|
|
3c4403c400 | ||
|
|
8dcde7a74f | ||
|
|
bb7cd8e22b | ||
|
|
7458e95ee5 | ||
|
|
2f69c5f022 | ||
|
|
efdd567a1b | ||
|
|
cff8f7c0b5 | ||
|
|
fe4a4b1b79 | ||
|
|
8caf653e97 | ||
|
|
88c4d532ab | ||
|
|
e69d063252 | ||
|
|
a35218da74 | ||
|
|
4d8e2cdc8b | ||
|
|
3d0f2977bf | ||
|
|
230929a4b2 | ||
|
|
c847216ca4 | ||
|
|
cacd2fa999 | ||
|
|
0b688e4829 | ||
|
|
27cf0ea06b | ||
|
|
e473108e1b | ||
|
|
c74cc9a606 | ||
|
|
619e60cf0e | ||
|
|
37b3657481 | ||
|
|
c1211a4e1a | ||
|
|
95d34b5937 | ||
|
|
6dc3f666c5 | ||
|
|
8e4491a532 | ||
|
|
492095b2a7 | ||
|
|
d516642980 | ||
|
|
193845ecdd | ||
|
|
598d04d5d9 | ||
|
|
06c5dd9c84 | ||
|
|
6632659907 | ||
|
|
86bf835d50 | ||
|
|
c9d0362a6b | ||
|
|
d2989f28db | ||
|
|
0bab6013d0 | ||
|
|
361d93586c | ||
|
|
0db13661b4 | ||
|
|
c866592d7d | ||
|
|
eb90325bed | ||
|
|
c878545977 | ||
|
|
741021513b | ||
|
|
97e8aba080 | ||
|
|
802d46d040 | ||
|
|
96718df15e | ||
|
|
89bd779e78 | ||
|
|
b5af3e74d7 | ||
|
|
2d3932d988 | ||
|
|
d0c1583ad2 | ||
|
|
59ff4064ba | ||
|
|
00a68c985f | ||
|
|
e862ea556c | ||
|
|
a4704cba0b | ||
|
|
455b3a7865 | ||
|
|
fabaab1540 | ||
|
|
8ac49ff181 | ||
|
|
cdf55a18d2 | ||
|
|
d158ca7101 | ||
|
|
664b7ebfa1 | ||
|
|
163c488e30 | ||
|
|
4b5bfa7a9d | ||
|
|
decbadda45 | ||
|
|
f00d780c16 | ||
|
|
1daa2e4609 | ||
|
|
d84bc3ad8e | ||
|
|
a9350e3205 | ||
|
|
95e3a7e7a3 | ||
|
|
e4cecee7d3 | ||
|
|
8b867b41d3 | ||
|
|
c6bd2fe734 | ||
|
|
d7e52b99bd | ||
|
|
a640d9472a | ||
|
|
b15103ef4e | ||
|
|
95071cd1fe | ||
|
|
18a888f9fb | ||
|
|
bbfc41948a | ||
|
|
c29a8cc084 | ||
|
|
54e7af83e6 | ||
|
|
3483d6327d | ||
|
|
5869345899 | ||
|
|
0cad2778b4 | ||
|
|
24de1fbde8 | ||
|
|
131728a680 | ||
|
|
e949e135b6 | ||
|
|
1510b63d20 | ||
|
|
0db4d9bd46 | ||
|
|
1e17e084bf | ||
|
|
a2c14c5ec5 | ||
|
|
b99849c831 | ||
|
|
c7d4286ca1 | ||
|
|
434e2b7212 | ||
|
|
acf0f0fa6e | ||
|
|
220e6b66e8 | ||
|
|
c4d4731ddf | ||
|
|
139ccaa78c | ||
|
|
c42410b560 | ||
|
|
120f11812d | ||
|
|
500486d501 | ||
|
|
6708debd4c | ||
|
|
852a8b4875 | ||
|
|
9c6b4ecb48 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,8 +4,6 @@
|
||||
*.swp
|
||||
*~$
|
||||
cscope.*
|
||||
compile_commands.json
|
||||
/.clangd
|
||||
tags
|
||||
/build
|
||||
/obj*
|
||||
|
||||
394
.gitlab-ci.yml
394
.gitlab-ci.yml
@@ -4,17 +4,15 @@ variables:
|
||||
CENTOS7_BUILD: buildenv-centos7
|
||||
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
||||
MINGW_BUILD: buildenv-mingw
|
||||
DEBIAN_CROSS_BUILD: buildenv-debian-cross
|
||||
|
||||
# pkd tests fail on CentOS7 docker images, so we don't use -DSERVER_TESTING=ON
|
||||
centos7/openssl_1.0.x/x86_64:
|
||||
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
|
||||
centos7/openssl_1.0.x/x86-64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake3
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
- mkdir -p obj && cd obj && cmake3 -DUNIT_TESTING=ON -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
|
||||
-DWITH_PCAP=ON .. && make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
@@ -25,16 +23,12 @@ centos7/openssl_1.0.x/x86_64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/openssl_1.1.x/x86_64:
|
||||
fedora/openssl_1.1.x/x86-64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-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
|
||||
tags:
|
||||
@@ -47,37 +41,13 @@ fedora/openssl_1.1.x/x86_64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/openssl_1.1.x/x86_64/fips:
|
||||
fedora/openssl_1.1.x/x86-64/release:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- echo 1 > /etc/system-fips
|
||||
- update-crypto-policies --set FIPS
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Release
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-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) && OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/openssl_1.1.x/x86_64/minimal:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_ZLIB=OFF -DWITH_PCAP=OFF
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DWITH_GEX=OFF .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -97,8 +67,7 @@ fedora/address-sanitizer:
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=AddressSanitizer
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -111,35 +80,12 @@ fedora/address-sanitizer:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
# This is disabled as it report OpenSSL issues
|
||||
# It also has ethe same issues with cwrap as AddressSanitizer
|
||||
.fedora/memory-sanitizer:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=MemorySanitizer
|
||||
-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 ..
|
||||
&& make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/undefined-sanitizer:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
|
||||
&& make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -152,26 +98,16 @@ fedora/undefined-sanitizer:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/csbuild:
|
||||
fedora/static-analysis:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- |
|
||||
if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then
|
||||
export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
|
||||
fi
|
||||
|
||||
# Check if the commit exists in this branch
|
||||
# This is not the case for a force push
|
||||
git branch --contains $CI_COMMIT_BEFORE_SHA 2>/dev/null || export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
|
||||
|
||||
export CI_COMMIT_RANGE="$CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA"
|
||||
|
||||
- csbuild
|
||||
--build-dir=obj-csbuild
|
||||
--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
|
||||
- export CCC_CC=clang
|
||||
- export CCC_CXX=clang++
|
||||
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
|
||||
scan-build --status-bugs -o scan make -j$(nproc)
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
@@ -180,17 +116,16 @@ fedora/csbuild:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj-csbuild/
|
||||
- obj/scan
|
||||
|
||||
# That is a specific runner that we cannot enable universally.
|
||||
# We restrict it to builds under the $BUILD_IMAGES_PROJECT project.
|
||||
freebsd/x86_64:
|
||||
freebsd/x86-64:
|
||||
image:
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -206,15 +141,13 @@ freebsd/x86_64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/libgcrypt/x86_64:
|
||||
fedora/libgcrypt/x86-64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DWITH_GCRYPT=ON -DWITH_DEBUG_CRYPTO=ON .. &&
|
||||
-DWITH_GCRYPT=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -226,15 +159,14 @@ fedora/libgcrypt/x86_64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/mbedtls/x86_64:
|
||||
fedora/mbedtls/x86-64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON .. &&
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_MBEDTLS=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -246,63 +178,14 @@ fedora/mbedtls/x86_64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
fedora/mingw64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
script:
|
||||
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
||||
- export WINEDEBUG=-all
|
||||
- mkdir -p obj && cd obj && mingw64-cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) &&
|
||||
ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
fedora/mingw32:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
script:
|
||||
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
||||
- export WINEDEBUG=-all
|
||||
- mkdir -p obj && cd obj && mingw32-cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) &&
|
||||
ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86_64/gcc:
|
||||
tumbleweed/openssl_1.1.x/x86-64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -314,79 +197,14 @@ tumbleweed/openssl_1.1.x/x86_64/gcc:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86/gcc:
|
||||
tumbleweed/openssl_1.1.x/x86-64/release:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86_64/gcc7:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Release
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86/gcc7:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
||||
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86_64/clang:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
-DUNIT_TESTING=ON
|
||||
-DSERVER_TESTING=ON .. &&
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
@@ -412,15 +230,32 @@ tumbleweed/docs:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/undefined-sanitizer:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
|
||||
&& make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
@@ -436,12 +271,10 @@ tumbleweed/static-analysis:
|
||||
script:
|
||||
- export CCC_CC=clang
|
||||
- export CCC_CXX=clang++
|
||||
- mkdir -p obj && cd obj && scan-build cmake
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
|
||||
scan-build --status-bugs -o scan make -j$(nproc)
|
||||
tags:
|
||||
- shared
|
||||
@@ -453,57 +286,76 @@ tumbleweed/static-analysis:
|
||||
paths:
|
||||
- obj/scan
|
||||
|
||||
visualstudio/x86_64:
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
mingw64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
script:
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="x64-windows"
|
||||
- cd obj
|
||||
- cmake
|
||||
-A x64
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON ..
|
||||
- cmake --build .
|
||||
- Xvfb :1 -screen 0 1024x768x16 -ac +extension GLX +render -noreset -nolisten tcp &
|
||||
- export DISPLAY=:1
|
||||
- mkdir -p obj && cd obj && mingw64-cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc)
|
||||
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
||||
- ctest --output-on-failure
|
||||
tags:
|
||||
- vs2017
|
||||
- windows
|
||||
- shared
|
||||
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:
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
mingw32:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
script:
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="x86-windows"
|
||||
- cd obj
|
||||
- cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON ..
|
||||
- cmake --build .
|
||||
- Xvfb :1 -screen 0 1024x768x16 -ac +extension GLX +render -noreset -nolisten tcp &
|
||||
- export DISPLAY=:1
|
||||
- mkdir -p obj && cd obj && mingw32-cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc)
|
||||
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
||||
- ctest --output-on-failure
|
||||
tags:
|
||||
- vs2017
|
||||
- windows
|
||||
- shared
|
||||
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/
|
||||
|
||||
.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=Debug
|
||||
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
|
||||
-DWITH_PCAP=ON .. && make -j$(nproc)
|
||||
- ctest --output-on-failure -j$(nproc)
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
Debian.cross.mips-linux-gnu:
|
||||
<<: *Debian_cross_template
|
||||
|
||||
@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
|
||||
project(libssh VERSION 0.9.2 LANGUAGES C)
|
||||
project(libssh VERSION 0.8.5 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.3")
|
||||
set(LIBRARY_VERSION "4.7.2")
|
||||
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)
|
||||
|
||||
@@ -39,9 +39,6 @@ include(CompilerChecks.cmake)
|
||||
include(MacroEnsureOutOfSourceBuild)
|
||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
||||
|
||||
# Copy library files to a lib sub-directory
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||
|
||||
# search for libraries
|
||||
if (WITH_ZLIB)
|
||||
find_package(ZLIB REQUIRED)
|
||||
@@ -70,10 +67,6 @@ else (WITH_GCRYPT)
|
||||
endif (NOT OPENSSL_FOUND)
|
||||
endif(WITH_GCRYPT)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
find_package(CMocka REQUIRED)
|
||||
endif ()
|
||||
|
||||
# Find out if we have threading available
|
||||
set(CMAKE_THREAD_PREFER_PTHREADS ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
@@ -117,37 +110,39 @@ install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
${LIB_INSTALL_DIR}/pkgconfig
|
||||
COMPONENT
|
||||
pkgconfig
|
||||
)
|
||||
endif (UNIX)
|
||||
|
||||
# CMake config files
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# cmake config files
|
||||
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
|
||||
# libssh-config-version.cmake
|
||||
write_basic_package_version_file(libssh-config-version.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
|
||||
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
||||
${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||
COMPONENT
|
||||
devel)
|
||||
devel
|
||||
)
|
||||
|
||||
|
||||
# in tree build settings
|
||||
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
|
||||
|
||||
if (WITH_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif (WITH_EXAMPLES)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
include(AddCMockaTest)
|
||||
add_subdirectory(tests)
|
||||
find_package(CMocka REQUIRED)
|
||||
include(AddCMockaTest)
|
||||
add_subdirectory(tests)
|
||||
endif (UNIT_TESTING)
|
||||
|
||||
### SOURCE PACKAGE
|
||||
@@ -205,11 +200,6 @@ endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
|
||||
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET})
|
||||
|
||||
# Link compile database for clangd
|
||||
execute_process(COMMAND cmake -E create_symlink
|
||||
"${CMAKE_BINARY_DIR}/compile_commands.json"
|
||||
"${CMAKE_SOURCE_DIR}/compile_commands.json")
|
||||
|
||||
message(STATUS "********************************************")
|
||||
message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
||||
|
||||
@@ -220,12 +210,10 @@ message(STATUS "libnacl support: ${WITH_NACL}")
|
||||
message(STATUS "SFTP support: ${WITH_SFTP}")
|
||||
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 "Build shared library: ${BUILD_SHARED_LIBS}")
|
||||
message(STATUS "With static library: ${WITH_STATIC_LIB}")
|
||||
message(STATUS "Unit testing: ${UNIT_TESTING}")
|
||||
message(STATUS "Client code testing: ${CLIENT_TESTING}")
|
||||
message(STATUS "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
|
||||
set(_SERVER_TESTING OFF)
|
||||
if (WITH_SERVER)
|
||||
set(_SERVER_TESTING ${SERVER_TESTING})
|
||||
@@ -240,9 +228,5 @@ message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
|
||||
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
|
||||
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
|
||||
message(STATUS "Release is final: ${WITH_FINAL}")
|
||||
message(STATUS "Global client config: ${GLOBAL_CLIENT_CONFIG}")
|
||||
if (WITH_SERVER)
|
||||
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
|
||||
endif()
|
||||
message(STATUS "********************************************")
|
||||
|
||||
|
||||
13
COPYING
13
COPYING
@@ -455,15 +455,6 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
Linking with OpenSSL
|
||||
|
||||
17. In addition, as a special exception, we give permission to link the code
|
||||
of its release of libssh with the OpenSSL project's "OpenSSL" library (or with
|
||||
modified versions of it that use the same license as the "OpenSSL" library),
|
||||
and distribute the linked executables. You must obey the GNU Lesser General
|
||||
Public License in all respects for all of the code used other than "OpenSSL".
|
||||
If you modify this file, you may extend this exception to your version of the
|
||||
file, but you are not obligated to do so. If you do not wish to do so, delete
|
||||
this exception statement from your version.
|
||||
|
||||
Linking with OpenSSL
|
||||
17. In addition, as a special exception, we give permission to link the code of its release of libssh with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Lesser General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
# SOURCE GENERATOR
|
||||
set(CPACK_SOURCE_GENERATOR "TXZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;/[.]clangd/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
### NSIS INSTALLER
|
||||
|
||||
51
ChangeLog
51
ChangeLog
@@ -1,57 +1,6 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
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
|
||||
* Disabled blowfish support by default
|
||||
* Fixed several ssh config parsing issues
|
||||
* Added support for DH Group Exchange KEX
|
||||
* 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
|
||||
|
||||
@@ -41,7 +41,6 @@ if (UNIX)
|
||||
add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS)
|
||||
add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
|
||||
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
|
||||
add_c_compiler_flag("-Wmissing-field-initializers" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
|
||||
if (REQUIRED_FLAGS_WFORMAT)
|
||||
@@ -52,10 +51,7 @@ if (UNIX)
|
||||
add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
# Allow zero for a variadic macro argument
|
||||
string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID)
|
||||
if ("${_C_COMPILER_ID}" STREQUAL "clang")
|
||||
add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
|
||||
endif()
|
||||
add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
@@ -69,18 +65,10 @@ if (UNIX)
|
||||
check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG)
|
||||
if (WITH_STACK_PROTECTOR_STRONG)
|
||||
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong")
|
||||
# This is needed as Solaris has a seperate libssp
|
||||
if (SOLARIS)
|
||||
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong")
|
||||
endif()
|
||||
else (WITH_STACK_PROTECTOR_STRONG)
|
||||
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||
if (WITH_STACK_PROTECTOR)
|
||||
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector")
|
||||
# This is needed as Solaris has a seperate libssp
|
||||
if (SOLARIS)
|
||||
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector")
|
||||
endif()
|
||||
endif()
|
||||
endif (WITH_STACK_PROTECTOR_STRONG)
|
||||
|
||||
@@ -94,8 +82,6 @@ if (UNIX)
|
||||
add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS)
|
||||
endif()
|
||||
|
||||
add_c_compiler_flag("-Wno-deprecated-declarations" DEPRECATION_COMPILER_FLAGS)
|
||||
|
||||
# Unset CMAKE_REQUIRED_FLAGS
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
endif()
|
||||
@@ -114,8 +100,3 @@ if (OSX)
|
||||
endif()
|
||||
|
||||
set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE)
|
||||
set(DEFAULT_LINK_FLAGS ${SUPPORTED_LINKER_FLAGS} CACHE INTERNAL "Default C Linker Flags" FORCE)
|
||||
|
||||
if (DEPRECATION_COMPILER_FLAGS)
|
||||
set(DEFAULT_C_NO_DEPRECATION_FLAGS ${DEPRECATION_COMPILER_FLAGS} CACHE INTERNAL "Default no deprecation flags" FORCE)
|
||||
endif()
|
||||
|
||||
@@ -9,7 +9,10 @@ include(TestBigEndian)
|
||||
|
||||
set(PACKAGE ${PROJECT_NAME})
|
||||
set(VERSION ${PROJECT_VERSION})
|
||||
set(SYSCONFDIR ${CMAKE_INSTALL_SYSCONFDIR})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
set(LIBDIR ${LIB_INSTALL_DIR})
|
||||
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
|
||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
||||
@@ -61,7 +64,6 @@ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
|
||||
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
check_include_file(byteswap.h HAVE_BYTESWAP_H)
|
||||
check_include_file(glob.h HAVE_GLOB_H)
|
||||
check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H)
|
||||
|
||||
if (WIN32)
|
||||
check_include_file(io.h HAVE_IO_H)
|
||||
@@ -86,10 +88,8 @@ if (OPENSSL_FOUND)
|
||||
message(FATAL_ERROR "Could not detect openssl/aes.h")
|
||||
endif()
|
||||
|
||||
if (WITH_BLOWFISH_CIPHER)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
|
||||
@@ -108,10 +108,6 @@ if (OPENSSL_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(EVP_aes_128_gcm HAVE_OPENSSL_EVP_AES_GCM)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
|
||||
@@ -124,41 +120,10 @@ if (OPENSSL_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(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})
|
||||
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(EVP_DigestSign HAVE_OPENSSL_EVP_DIGESTSIGN)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
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_LIBRARY})
|
||||
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_LIBRARY})
|
||||
check_symbol_exists(EVP_PKEY_X25519 "openssl/evp.h" HAVE_OPENSSL_X25519)
|
||||
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
@@ -289,14 +254,6 @@ if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(HAVE_PTHREAD 1)
|
||||
endif (CMAKE_USE_PTHREADS_INIT)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
if (CMOCKA_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMOCKA_LIBRARIES})
|
||||
check_function_exists(cmocka_set_test_filter HAVE_CMOCKA_SET_TEST_FILTER)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# OPTIONS
|
||||
check_c_source_compiles("
|
||||
__thread int tls;
|
||||
@@ -315,19 +272,19 @@ int main(void) {
|
||||
###########################################################
|
||||
# For detecting attributes we need to treat warnings as
|
||||
# errors
|
||||
if (UNIX OR MINGW)
|
||||
if (UNIX)
|
||||
# Get warnings for attributs
|
||||
check_c_compiler_flag("-Wattributes" REQUIRED_FLAGS_WERROR)
|
||||
check_c_compiler_flag("-Wattributs" REQUIRED_FLAGS_WERROR)
|
||||
if (REQUIRED_FLAGS_WERROR)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Wattributes ")
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wattributes")
|
||||
endif()
|
||||
|
||||
# Turn warnings into errors
|
||||
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
|
||||
if (REQUIRED_FLAGS_WERROR)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Werror ")
|
||||
set(CMAKE_REQUIRED_FLAGS "-Werror")
|
||||
endif()
|
||||
endif ()
|
||||
endif (UNIX)
|
||||
|
||||
check_c_source_compiles("
|
||||
void test_constructor_attribute(void) __attribute__ ((constructor));
|
||||
@@ -371,28 +328,6 @@ int main(void) {
|
||||
return 0;
|
||||
}" HAVE_FALLTHROUGH_ATTRIBUTE)
|
||||
|
||||
if (NOT WIN32)
|
||||
check_c_source_compiles("
|
||||
#define __unused __attribute__((unused))
|
||||
|
||||
static int do_nothing(int i __unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = do_nothing(5);
|
||||
if (i > 5) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}" HAVE_UNUSED_ATTRIBUTE)
|
||||
endif()
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <string.h>
|
||||
|
||||
@@ -405,6 +340,18 @@ int main(void)
|
||||
return 0;
|
||||
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <stdio.h>
|
||||
#define __VA_NARG__(...) (__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
|
||||
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
|
||||
#define __VA_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,N,...) N
|
||||
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
#define myprintf(format, ...) printf((format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__)
|
||||
int main(void) {
|
||||
myprintf(\"%d %d %d %d\",1,2,3);
|
||||
return 0;
|
||||
}" HAVE_GCC_NARG_MACRO)
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <stdio.h>
|
||||
int main(void) {
|
||||
@@ -419,8 +366,6 @@ int main(void) {
|
||||
return 0;
|
||||
}" HAVE_COMPILER__FUNCTION__)
|
||||
|
||||
# This is only available with OpenBSD's gcc implementation */
|
||||
if (OPENBSD)
|
||||
check_c_source_compiles("
|
||||
#define ARRAY_LEN 16
|
||||
void test_attr(const unsigned char *k)
|
||||
@@ -429,7 +374,6 @@ void test_attr(const unsigned char *k)
|
||||
int main(void) {
|
||||
return 0;
|
||||
}" HAVE_GCC_BOUNDED_ATTRIBUTE)
|
||||
endif(OPENBSD)
|
||||
|
||||
# Stop treating warnings as errors
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
@@ -2,15 +2,14 @@ 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)
|
||||
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
||||
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)
|
||||
@@ -19,7 +18,6 @@ option(WITH_EXAMPLES "Build examples" ON)
|
||||
option(WITH_NACL "Build with libnacl (curve25519)" ON)
|
||||
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
|
||||
option(WITH_ABI_BREAK "Allow ABI break" OFF)
|
||||
option(WITH_GEX "Enable DH Group exchange mechanisms" ON)
|
||||
option(FUZZ_TESTING "Build with fuzzer for the server" OFF)
|
||||
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
|
||||
|
||||
@@ -34,9 +32,13 @@ if (WITH_BENCHMARKS)
|
||||
set(CLIENT_TESTING ON)
|
||||
endif()
|
||||
|
||||
if (UNIT_TESTING OR CLIENT_TESTING OR SERVER_TESTING)
|
||||
if (WITH_STATIC_LIB)
|
||||
set(BUILD_STATIC_LIB ON)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
set(BUILD_STATIC_LIB ON)
|
||||
endif()
|
||||
endif (UNIT_TESTING)
|
||||
|
||||
if (WITH_NACL)
|
||||
set(WITH_NACL ON)
|
||||
@@ -45,11 +47,3 @@ endif (WITH_NACL)
|
||||
if (WITH_ABI_BREAK)
|
||||
set(WITH_SYMBOL_VERSIONING ON)
|
||||
endif (WITH_ABI_BREAK)
|
||||
|
||||
if (NOT GLOBAL_BIND_CONFIG)
|
||||
set(GLOBAL_BIND_CONFIG "/etc/ssh/libssh_server_config")
|
||||
endif (NOT GLOBAL_BIND_CONFIG)
|
||||
|
||||
if (NOT GLOBAL_CLIENT_CONFIG)
|
||||
set(GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config")
|
||||
endif (NOT GLOBAL_CLIENT_CONFIG)
|
||||
|
||||
11
INSTALL
11
INSTALL
@@ -11,10 +11,9 @@ In order to build libssh, you need to install several components:
|
||||
- [openssl](http://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
|
||||
|
||||
optional:
|
||||
- [cmocka](https://cmocka.org/) >= 1.1.0
|
||||
- [libz](http://www.zlib.net) >= 1.2
|
||||
- [socket_wrapper](https://cwrap.org/) >= 1.1.5
|
||||
- [nss_wrapper](https://cwrap.org/) >= 1.1.2
|
||||
- [uid_wrapper](https://cwrap.org/) >= 1.2.0
|
||||
@@ -23,12 +22,12 @@ optional:
|
||||
Note that these version numbers are version we know works correctly. If you
|
||||
build and run libssh successfully with an older version, please let us know.
|
||||
|
||||
For Windows use vcpkg:
|
||||
Windows binaries known to be working:
|
||||
|
||||
https://github.com/Microsoft/vcpkg
|
||||
- http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
- http://zlib.net/ -> zlib compiled DLL
|
||||
|
||||
which you can use to install openssl and zlib. libssh itself is also part of
|
||||
vcpkg!
|
||||
We installed them in C:\Program Files
|
||||
|
||||
## Building
|
||||
First, you need to configure the compilation, using CMake. Go inside the
|
||||
|
||||
@@ -1,63 +1,11 @@
|
||||
#
|
||||
# - add_cmocka_test(test_name test_source linklib1 ... linklibN)
|
||||
|
||||
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
||||
# Copyright (c) 2007-2018 Andreas Schneider <asn@cryptomilk.org>
|
||||
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
#.rst:
|
||||
# AddCMockaTest
|
||||
# -------------
|
||||
#
|
||||
# This file provides a function to add a test
|
||||
#
|
||||
# Functions provided
|
||||
# ------------------
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# add_cmocka_test(target_name
|
||||
# SOURCES src1 src2 ... srcN
|
||||
# [COMPILE_OPTIONS opt1 opt2 ... optN]
|
||||
# [LINK_LIBRARIES lib1 lib2 ... libN]
|
||||
# [LINK_OPTIONS lopt1 lop2 .. loptN]
|
||||
# )
|
||||
#
|
||||
# ``target_name``:
|
||||
# Required, expects the name of the test which will be used to define a target
|
||||
#
|
||||
# ``SOURCES``:
|
||||
# Required, expects one or more source files names
|
||||
#
|
||||
# ``COMPILE_OPTIONS``:
|
||||
# Optional, expects one or more options to be passed to the compiler
|
||||
#
|
||||
# ``LINK_LIBRARIES``:
|
||||
# Optional, expects one or more libraries to be linked with the test
|
||||
# executable.
|
||||
#
|
||||
# ``LINK_OPTIONS``:
|
||||
# Optional, expects one or more options to be passed to the linker
|
||||
#
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# .. code-block:: cmake
|
||||
#
|
||||
# add_cmocka_test(my_test
|
||||
# SOURCES my_test.c other_source.c
|
||||
# COMPILE_OPTIONS -g -Wall
|
||||
# LINK_LIBRARIES mylib
|
||||
# LINK_OPTIONS -Wl,--enable-syscall-fixup
|
||||
# )
|
||||
#
|
||||
# Where ``my_test`` is the name of the test, ``my_test.c`` and
|
||||
# ``other_source.c`` are sources for the binary, ``-g -Wall`` are compiler
|
||||
# options to be used, ``mylib`` is a target of a library to be linked, and
|
||||
# ``-Wl,--enable-syscall-fixup`` is an option passed to the linker.
|
||||
#
|
||||
|
||||
enable_testing()
|
||||
include(CTest)
|
||||
|
||||
@@ -69,52 +17,10 @@ if (CMAKE_CROSSCOMPILING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
function(ADD_CMOCKA_TEST _TARGET_NAME)
|
||||
function(ADD_CMOCKA_TEST _testName _testSource)
|
||||
add_executable(${_testName} ${_testSource})
|
||||
|
||||
set(one_value_arguments
|
||||
)
|
||||
|
||||
set(multi_value_arguments
|
||||
SOURCES
|
||||
COMPILE_OPTIONS
|
||||
LINK_LIBRARIES
|
||||
LINK_OPTIONS
|
||||
)
|
||||
|
||||
cmake_parse_arguments(_add_cmocka_test
|
||||
""
|
||||
"${one_value_arguments}"
|
||||
"${multi_value_arguments}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if (NOT DEFINED _add_cmocka_test_SOURCES)
|
||||
message(FATAL_ERROR "No sources provided for target ${_TARGET_NAME}")
|
||||
endif()
|
||||
|
||||
add_executable(${_TARGET_NAME} ${_add_cmocka_test_SOURCES})
|
||||
|
||||
if (DEFINED _add_cmocka_test_COMPILE_OPTIONS)
|
||||
target_compile_options(${_TARGET_NAME}
|
||||
PRIVATE ${_add_cmocka_test_COMPILE_OPTIONS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DEFINED _add_cmocka_test_LINK_LIBRARIES)
|
||||
target_link_libraries(${_TARGET_NAME}
|
||||
PRIVATE ${_add_cmocka_test_LINK_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DEFINED _add_cmocka_test_LINK_OPTIONS)
|
||||
set_target_properties(${_TARGET_NAME}
|
||||
PROPERTIES LINK_FLAGS
|
||||
${_add_cmocka_test_LINK_OPTIONS}
|
||||
)
|
||||
endif()
|
||||
|
||||
add_test(${_TARGET_NAME}
|
||||
${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME}
|
||||
)
|
||||
target_link_libraries(${_testName} ${ARGN})
|
||||
|
||||
add_test(${_testName} ${TARGET_SYSTEM_EMULATOR} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}${CMAKE_EXECUTABLE_SUFFIX})
|
||||
endfunction (ADD_CMOCKA_TEST)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
if (UNIX AND NOT WIN32)
|
||||
# Activate with: -DCMAKE_BUILD_TYPE=Profiling
|
||||
set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
|
||||
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the C compiler during PROFILING builds.")
|
||||
set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
|
||||
set(CMAKE_CXX_FLAGS_PROFILING "-g -O0 -fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the CXX compiler during PROFILING builds.")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
|
||||
@@ -22,28 +22,4 @@ if (UNIX AND NOT WIN32)
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
|
||||
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
|
||||
CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")
|
||||
|
||||
# Activate with: -DCMAKE_BUILD_TYPE=MemorySanitizer
|
||||
set(CMAKE_C_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
|
||||
CACHE STRING "Flags used by the C compiler during MEMORYSANITIZER builds.")
|
||||
set(CMAKE_CXX_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
|
||||
CACHE STRING "Flags used by the CXX compiler during MEMORYSANITIZER builds.")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
|
||||
set(CMAKE_EXEC_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
|
||||
CACHE STRING "Flags used by the linker during MEMORYSANITIZER builds.")
|
||||
|
||||
# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer
|
||||
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
|
||||
CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.")
|
||||
set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
|
||||
CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
|
||||
set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
|
||||
CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.")
|
||||
endif()
|
||||
|
||||
109
cmake/Modules/DefineInstallationPaths.cmake
Normal file
109
cmake/Modules/DefineInstallationPaths.cmake
Normal file
@@ -0,0 +1,109 @@
|
||||
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 ()
|
||||
@@ -49,15 +49,7 @@ find_library(GCRYPT_LIBRARY
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
find_library(GCRYPT_ERROR_LIBRARY
|
||||
NAMES
|
||||
gpg-error
|
||||
libgpg-error-0
|
||||
libgpg-error6-0
|
||||
HINTS
|
||||
${_GCRYPT_ROOT_HINTS_AND_PATHS}
|
||||
)
|
||||
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} ${GCRYPT_ERROR_LIBRARY})
|
||||
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})
|
||||
|
||||
if (GCRYPT_INCLUDE_DIR)
|
||||
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")
|
||||
|
||||
@@ -4,16 +4,14 @@
|
||||
/* 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}"
|
||||
|
||||
/* Global bind configuration file path */
|
||||
#cmakedefine GLOBAL_BIND_CONFIG "${GLOBAL_BIND_CONFIG}"
|
||||
|
||||
/* Global client configuration file path */
|
||||
#cmakedefine GLOBAL_CLIENT_CONFIG "${GLOBAL_CLIENT_CONFIG}"
|
||||
|
||||
/************************** HEADER FILES *************************/
|
||||
|
||||
/* Define to 1 if you have the <argp.h> header file. */
|
||||
@@ -25,9 +23,6 @@
|
||||
/* Define to 1 if you have the <glob.h> header file. */
|
||||
#cmakedefine HAVE_GLOB_H 1
|
||||
|
||||
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
|
||||
#cmakedefine HAVE_VALGRIND_VALGRIND_H 1
|
||||
|
||||
/* Define to 1 if you have the <pty.h> header file. */
|
||||
#cmakedefine HAVE_PTY_H 1
|
||||
|
||||
@@ -97,12 +92,6 @@
|
||||
/* 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. */
|
||||
@@ -111,9 +100,6 @@
|
||||
/* Define to 1 if you have the `EVP_aes128_cbc' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_AES_CBC 1
|
||||
|
||||
/* Define to 1 if you have the `EVP_aes128_gcm' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_AES_GCM 1
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
|
||||
#cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1
|
||||
|
||||
@@ -123,21 +109,6 @@
|
||||
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1
|
||||
|
||||
/* Define to 1 if you have the `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
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
@@ -207,9 +178,6 @@
|
||||
/* Define to 1 if you have the `SecureZeroMemory' function. */
|
||||
#cmakedefine HAVE_SECURE_ZERO_MEMORY 1
|
||||
|
||||
/* Define to 1 if you have the `cmocka_set_test_filter' function. */
|
||||
#cmakedefine HAVE_CMOCKA_SET_TEST_FILTER 1
|
||||
|
||||
/*************************** LIBRARIES ***************************/
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
@@ -224,21 +192,18 @@
|
||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||
#cmakedefine HAVE_PTHREAD 1
|
||||
|
||||
/* Define to 1 if you have the `cmocka' library (-lcmocka). */
|
||||
#cmakedefine HAVE_CMOCKA 1
|
||||
|
||||
/**************************** OPTIONS ****************************/
|
||||
|
||||
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
|
||||
#cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1
|
||||
|
||||
#cmakedefine HAVE_FALLTHROUGH_ATTRIBUTE 1
|
||||
#cmakedefine HAVE_UNUSED_ATTRIBUTE 1
|
||||
|
||||
#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
|
||||
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
|
||||
|
||||
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
|
||||
#cmakedefine HAVE_GCC_NARG_MACRO 1
|
||||
|
||||
#cmakedefine HAVE_COMPILER__FUNC__ 1
|
||||
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
|
||||
@@ -257,12 +222,6 @@
|
||||
/* Define to 1 if you want to enable server support */
|
||||
#cmakedefine WITH_SERVER 1
|
||||
|
||||
/* Define to 1 if you want to enable DH group exchange algorithms */
|
||||
#cmakedefine WITH_GEX 1
|
||||
|
||||
/* Define to 1 if you want to enable blowfish cipher support */
|
||||
#cmakedefine WITH_BLOWFISH_CIPHER 1
|
||||
|
||||
/* Define to 1 if you want to enable debug output for crypto functions */
|
||||
#cmakedefine DEBUG_CRYPTO 1
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ int authenticate_pubkey(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||
rc = ssh_userauth_publickey_auto(session, NULL);
|
||||
|
||||
if (rc == SSH_AUTH_ERROR)
|
||||
{
|
||||
@@ -281,7 +281,7 @@ pass, ssh_userauth_none() might answer SSH_AUTH_SUCCESS.
|
||||
The following example shows how to perform "none" authentication:
|
||||
|
||||
@code
|
||||
int authenticate_none(ssh_session session)
|
||||
int authenticate_kbdint(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
||||
@@ -431,9 +431,6 @@ int show_remote_processes(ssh_session session)
|
||||
}
|
||||
@endcode
|
||||
|
||||
Each ssh_channel_request_exec() needs to be run on freshly created
|
||||
and connected (with ssh_channel_open_session()) channel.
|
||||
|
||||
@see @ref opening_shell
|
||||
@see @ref remote_command
|
||||
@see @ref sftp_subsystem
|
||||
|
||||
@@ -27,7 +27,4 @@ the dllimport attribute.
|
||||
#include <libssh/libssh.h>
|
||||
@endcode
|
||||
|
||||
If you're are statically linking with OpenSSL, read the "Linking your
|
||||
application" section in the NOTES.<OS> in the OpenSSL source tree!
|
||||
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,7 @@ The libssh library provides:
|
||||
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256,ssh-dss
|
||||
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
|
||||
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
||||
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5, none
|
||||
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512, hmac-md5, none
|
||||
- <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
|
||||
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
|
||||
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
|
||||
|
||||
@@ -61,7 +61,7 @@ int sftp_helloworld(ssh_session session)
|
||||
rc = sftp_init(sftp);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error initializing SFTP session: code %d.\n",
|
||||
fprintf(stderr, "Error initializing SFTP session: %s.\n",
|
||||
sftp_get_error(sftp));
|
||||
sftp_free(sftp);
|
||||
return rc;
|
||||
|
||||
@@ -6,7 +6,10 @@ set(examples_SRCS
|
||||
connect_ssh.c
|
||||
)
|
||||
|
||||
include_directories(${libssh_BINARY_DIR})
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
if (ARGP_INCLUDE_DIR)
|
||||
include_directories(${ARGP_INCLUDE_DIR})
|
||||
@@ -15,68 +18,60 @@ 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 ssh::ssh)
|
||||
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(scp_download scp_download.c ${examples_SRCS})
|
||||
target_compile_options(scp_download PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(scp_download ssh::ssh)
|
||||
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
||||
target_compile_options(sshnetcat PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(sshnetcat ssh::ssh)
|
||||
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
if (WITH_SFTP)
|
||||
add_executable(samplesftp samplesftp.c ${examples_SRCS})
|
||||
target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(samplesftp ssh::ssh)
|
||||
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
|
||||
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 ssh::ssh)
|
||||
target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
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 ssh::ssh ${ARGP_LIBRARY} util)
|
||||
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${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 ssh::ssh ${ARGP_LIBRARY})
|
||||
target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||
|
||||
add_executable(proxy proxy.c)
|
||||
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
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 ssh::ssh ${ARGP_LIBRARY})
|
||||
target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${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 ssh::ssh ${ARGP_LIBRARY})
|
||||
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${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 ssh::ssh)
|
||||
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(senddata senddata.c ${examples_SRCS})
|
||||
target_compile_options(senddata PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(senddata ssh::ssh)
|
||||
|
||||
add_executable(keygen keygen.c)
|
||||
target_compile_options(keygen PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(keygen ssh::ssh)
|
||||
target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(libsshpp libsshpp.cpp)
|
||||
target_link_libraries(libsshpp ssh::ssh)
|
||||
target_link_libraries(libsshpp ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
|
||||
target_link_libraries(libsshpp_noexcept ssh::ssh)
|
||||
target_link_libraries(libsshpp_noexcept ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
@@ -100,39 +100,6 @@ int authenticate_kbdint(ssh_session session, const char *password)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int auth_keyfile(ssh_session session, char* keyfile)
|
||||
{
|
||||
ssh_key key = NULL;
|
||||
char pubkey[132] = {0}; // +".pub"
|
||||
int rc;
|
||||
|
||||
snprintf(pubkey, sizeof(pubkey), "%s.pub", keyfile);
|
||||
|
||||
rc = ssh_pki_import_pubkey_file( pubkey, &key);
|
||||
|
||||
if (rc != SSH_OK)
|
||||
return SSH_AUTH_DENIED;
|
||||
|
||||
rc = ssh_userauth_try_publickey(session, NULL, key);
|
||||
|
||||
ssh_key_free(key);
|
||||
|
||||
if (rc!=SSH_AUTH_SUCCESS)
|
||||
return SSH_AUTH_DENIED;
|
||||
|
||||
rc = ssh_pki_import_privkey_file(keyfile, NULL, NULL, NULL, &key);
|
||||
|
||||
if (rc != SSH_OK)
|
||||
return SSH_AUTH_DENIED;
|
||||
|
||||
rc = ssh_userauth_publickey(session, NULL, key);
|
||||
|
||||
ssh_key_free(key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void error(ssh_session session)
|
||||
{
|
||||
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
|
||||
@@ -173,35 +140,6 @@ int authenticate_console(ssh_session session)
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
char buffer[128] = {0};
|
||||
char *p = NULL;
|
||||
|
||||
printf("Automatic pubkey failed. "
|
||||
"Do you want to try a specific key? (y/n)\n");
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
||||
break;
|
||||
}
|
||||
if ((buffer[0]=='Y') || (buffer[0]=='y')) {
|
||||
printf("private key filename: ");
|
||||
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
if ((p = strchr(buffer, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
rc = auth_keyfile(session, buffer);
|
||||
|
||||
if(rc == SSH_AUTH_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "failed with key\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Try to authenticate with keyboard interactive";
|
||||
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
|
||||
|
||||
@@ -14,10 +14,6 @@ clients must be made or how a client should react.
|
||||
#define EXAMPLES_COMMON_H_
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
|
||||
/** Zero a structure */
|
||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
|
||||
|
||||
int authenticate_console(ssh_session session);
|
||||
int authenticate_kbdint(ssh_session session, const char *password);
|
||||
int verify_knownhost(ssh_session session);
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/* keygen.c
|
||||
* Sample implementation of ssh-keygen using libssh
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2019 Red Hat, Inc.
|
||||
|
||||
Author: Jakub Jelen <jjelen@redhat.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ssh_key key = NULL;
|
||||
int rv;
|
||||
|
||||
/* Generate a new ED25519 private key file */
|
||||
rv = ssh_pki_generate(SSH_KEYTYPE_ED25519, 0, &key);
|
||||
if (rv != SSH_OK) {
|
||||
fprintf(stderr, "Failed to generate private key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write it to a file testkey in the current dirrectory */
|
||||
rv = ssh_pki_export_privkey_file(key, NULL, NULL, NULL, "testkey");
|
||||
if (rv != SSH_OK) {
|
||||
fprintf(stderr, "Failed to write private key file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -32,86 +32,82 @@ clients must be made or how a client should react.
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
int verify_knownhost(ssh_session session)
|
||||
{
|
||||
enum ssh_known_hosts_e state;
|
||||
char buf[10];
|
||||
unsigned char *hash = NULL;
|
||||
size_t hlen;
|
||||
ssh_key srv_pubkey;
|
||||
int rc;
|
||||
int verify_knownhost(ssh_session session){
|
||||
enum ssh_known_hosts_e state;
|
||||
char buf[10];
|
||||
unsigned char *hash = NULL;
|
||||
size_t hlen;
|
||||
ssh_key srv_pubkey;
|
||||
int rc;
|
||||
|
||||
rc = ssh_get_server_publickey(session, &srv_pubkey);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
rc = ssh_get_server_publickey(session, &srv_pubkey);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_get_publickey_hash(srv_pubkey,
|
||||
SSH_PUBLICKEY_HASH_SHA256,
|
||||
&hash,
|
||||
&hlen);
|
||||
ssh_key_free(srv_pubkey);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
rc = ssh_get_publickey_hash(srv_pubkey,
|
||||
SSH_PUBLICKEY_HASH_SHA256,
|
||||
&hash,
|
||||
&hlen);
|
||||
ssh_key_free(srv_pubkey);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
state = ssh_session_is_known_server(session);
|
||||
state = ssh_session_is_known_server(session);
|
||||
|
||||
switch(state) {
|
||||
case SSH_KNOWN_HOSTS_CHANGED:
|
||||
fprintf(stderr,"Host key for server changed : server's one is now :\n");
|
||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||
return -1;
|
||||
case SSH_KNOWN_HOSTS_OTHER:
|
||||
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
|
||||
fprintf(stderr,"An attacker might change the default server key to confuse your client"
|
||||
"into thinking the key does not exist\n"
|
||||
"We advise you to rerun the client with -d or -r for more safety.\n");
|
||||
return -1;
|
||||
case SSH_KNOWN_HOSTS_NOT_FOUND:
|
||||
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
|
||||
fprintf(stderr,"the file will be automatically created.\n");
|
||||
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
||||
FALL_THROUGH;
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
fprintf(stderr,
|
||||
"The server is unknown. Do you trust the host key (yes/no)?\n");
|
||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
if(strncasecmp(buf,"yes",3)!=0){
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
if(strncasecmp(buf,"yes",3)==0){
|
||||
rc = ssh_session_update_known_hosts(session);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr, "error %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case SSH_KNOWN_HOSTS_ERROR:
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"%s",ssh_get_error(session));
|
||||
return -1;
|
||||
switch(state){
|
||||
case SSH_KNOWN_HOSTS_OK:
|
||||
break; /* ok */
|
||||
}
|
||||
break; /* ok */
|
||||
case SSH_KNOWN_HOSTS_CHANGED:
|
||||
fprintf(stderr,"Host key for server changed : server's one is now :\n");
|
||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||
return -1;
|
||||
case SSH_KNOWN_HOSTS_OTHER:
|
||||
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
|
||||
fprintf(stderr,"An attacker might change the default server key to confuse your client"
|
||||
"into thinking the key does not exist\n"
|
||||
"We advise you to rerun the client with -d or -r for more safety.\n");
|
||||
return -1;
|
||||
case SSH_KNOWN_HOSTS_NOT_FOUND:
|
||||
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
|
||||
fprintf(stderr,"the file will be automatically created.\n");
|
||||
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
||||
FALL_THROUGH;
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
fprintf(stderr,
|
||||
"The server is unknown. Do you trust the host key (yes/no)?\n");
|
||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
if(strncasecmp(buf,"yes",3)!=0){
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
if(strncasecmp(buf,"yes",3)==0){
|
||||
if (ssh_write_knownhost(session) < 0) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr, "error %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
break;
|
||||
case SSH_KNOWN_HOSTS_ERROR:
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"%s",ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
/* ssh_client.c */
|
||||
|
||||
/* client.c */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
@@ -198,20 +197,19 @@ 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_STDINOUT);
|
||||
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDOUT);
|
||||
ssh_connector_set_in_fd(connector_in, 0);
|
||||
ssh_event_add_connector(event, connector_in);
|
||||
|
||||
/* stdout */
|
||||
connector_out = ssh_connector_new(session);
|
||||
ssh_connector_set_out_fd(connector_out, 1);
|
||||
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT);
|
||||
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDOUT);
|
||||
ssh_event_add_connector(event, connector_out);
|
||||
|
||||
/* stderr */
|
||||
@@ -224,11 +222,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
|
||||
if (signal_delayed) {
|
||||
sizechanged();
|
||||
}
|
||||
rc = ssh_event_dopoll(event, 60000);
|
||||
if (rc == SSH_ERROR) {
|
||||
fprintf(stderr, "Error in ssh_event_dopoll()\n");
|
||||
break;
|
||||
}
|
||||
ssh_event_dopoll(event, 60000);
|
||||
}
|
||||
ssh_event_remove_connector(event, connector_in);
|
||||
ssh_event_remove_connector(event, connector_out);
|
||||
@@ -239,6 +233,7 @@ 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)
|
||||
@@ -246,11 +241,7 @@ 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);
|
||||
@@ -259,7 +250,6 @@ 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;
|
||||
@@ -270,7 +260,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -284,7 +273,6 @@ static void shell(ssh_session session)
|
||||
if (interactive) {
|
||||
do_cleanup(0);
|
||||
}
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
static void batch_shell(ssh_session session)
|
||||
@@ -301,18 +289,12 @@ 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)
|
||||
|
||||
@@ -37,7 +37,6 @@ The goal is to show the API in action.
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
@@ -70,11 +69,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};
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
@@ -129,14 +125,6 @@ static struct argp_option options[] = {
|
||||
.doc = "Set the ecdsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "authorizedkeys",
|
||||
.key = 'a',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the authorized keys file.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "no-default-keys",
|
||||
.key = 'n',
|
||||
@@ -190,9 +178,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
|
||||
ecdsa_already_set = 1;
|
||||
break;
|
||||
case 'a':
|
||||
strncpy(authorizedkeys, arg, DEF_STR_SIZE-1);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
||||
"3");
|
||||
@@ -449,53 +434,6 @@ static int auth_password(ssh_session session, const char *user,
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
static int auth_publickey(ssh_session session,
|
||||
const char *user,
|
||||
struct ssh_key_struct *pubkey,
|
||||
char signature_state,
|
||||
void *userdata)
|
||||
{
|
||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
||||
|
||||
(void) user;
|
||||
(void) session;
|
||||
|
||||
if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
if (signature_state != SSH_PUBLICKEY_STATE_VALID) {
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
// valid so far. Now look through authorized keys for a match
|
||||
if (authorizedkeys[0]) {
|
||||
ssh_key key = NULL;
|
||||
int result;
|
||||
struct stat buf;
|
||||
|
||||
if (stat(authorizedkeys, &buf) == 0) {
|
||||
result = ssh_pki_import_pubkey_file( authorizedkeys, &key );
|
||||
if ((result != SSH_OK) || (key==NULL)) {
|
||||
fprintf(stderr,
|
||||
"Unable to import public key file %s\n",
|
||||
authorizedkeys);
|
||||
} else {
|
||||
result = ssh_key_cmp( key, pubkey, SSH_KEY_CMP_PUBLIC );
|
||||
ssh_key_free(key);
|
||||
if (result == 0) {
|
||||
sdata->authenticated = 1;
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no matches
|
||||
sdata->authenticated = 0;
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
static ssh_channel channel_open(ssh_session session, void *userdata) {
|
||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
||||
|
||||
@@ -534,8 +472,7 @@ static int process_stderr(socket_t fd, int revents, void *userdata) {
|
||||
}
|
||||
|
||||
static void handle_session(ssh_event event, ssh_session session) {
|
||||
int n;
|
||||
int rc = 0;
|
||||
int n, rc;
|
||||
|
||||
/* Structure for storing the pty size. */
|
||||
struct winsize wsize = {
|
||||
@@ -580,12 +517,6 @@ static void handle_session(ssh_event event, ssh_session session) {
|
||||
.channel_open_request_session_function = channel_open,
|
||||
};
|
||||
|
||||
if (authorizedkeys[0]) {
|
||||
server_cb.auth_pubkey_function = auth_publickey;
|
||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY);
|
||||
} else
|
||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
|
||||
|
||||
ssh_callbacks_init(&server_cb);
|
||||
ssh_callbacks_init(&channel_cb);
|
||||
|
||||
@@ -596,6 +527,7 @@ static void handle_session(ssh_event event, ssh_session session) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
|
||||
ssh_event_add_session(event, session);
|
||||
|
||||
n = 0;
|
||||
|
||||
@@ -1,654 +0,0 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
Copyright 2018 T. Wimmer
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Example:
|
||||
./sshd_direct-tcpip -v -p 2022 -d serverkey.dsa -r serverkey.rsa 127.0.0.1
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#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 <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define USER "user"
|
||||
#define PASSWORD "pwd"
|
||||
|
||||
struct event_fd_data_struct {
|
||||
int *p_fd;
|
||||
ssh_channel channel;
|
||||
struct ssh_channel_callbacks_struct *cb_chan;
|
||||
int stacked;
|
||||
};
|
||||
|
||||
struct cleanup_node_struct {
|
||||
struct event_fd_data_struct *data;
|
||||
struct cleanup_node_struct *next;
|
||||
};
|
||||
|
||||
static bool authenticated = false;
|
||||
static int tries = 0;
|
||||
static bool error_set = false;
|
||||
static int sockets_cnt = 0;
|
||||
static ssh_event mainloop = NULL;
|
||||
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) {
|
||||
// Allocate memory for node
|
||||
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
|
||||
|
||||
new_node->next = (*head_ref);
|
||||
|
||||
// Copy new_data
|
||||
new_node->data = new_data;
|
||||
|
||||
// Change head pointer as new node is added at the beginning
|
||||
(*head_ref) = new_node;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while (current != NULL) {
|
||||
if (ssh_channel_is_closed(current->data->channel)) {
|
||||
if (current == (*head_ref)) {
|
||||
(*head_ref) = current->next;
|
||||
}
|
||||
if (previous != NULL) {
|
||||
previous->next = current->next;
|
||||
}
|
||||
gone = current;
|
||||
current = current->next;
|
||||
|
||||
if (gone->data->channel) {
|
||||
_close_socket(*gone->data);
|
||||
ssh_remove_channel_callbacks(gone->data->channel, gone->data->cb_chan);
|
||||
ssh_channel_free(gone->data->channel);
|
||||
gone->data->channel = NULL;
|
||||
|
||||
SAFE_FREE(gone->data->p_fd);
|
||||
SAFE_FREE(gone->data->cb_chan);
|
||||
SAFE_FREE(gone->data);
|
||||
SAFE_FREE(gone);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "channel already freed!\n");
|
||||
}
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== do_cleanup", "Freed.");
|
||||
}
|
||||
else {
|
||||
ssh_channel_close(current->data->channel);
|
||||
previous = current;
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
authenticated = true;
|
||||
printf("Authenticated\n");
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
if (tries >= 3){
|
||||
printf("Too many authentication tries\n");
|
||||
ssh_disconnect(session);
|
||||
error_set = true;
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
tries++;
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, 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("Received some gssapi credentials\n");
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
_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)
|
||||
return NULL;
|
||||
printf("Session channel request\n");
|
||||
chan = ssh_channel_new(session);
|
||||
ssh_callbacks_init(&channel_cb);
|
||||
ssh_set_channel_callbacks(chan, &channel_cb);
|
||||
return chan;*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
ssh_event_remove_fd(mainloop, *event_fd_data.p_fd);
|
||||
sockets_cnt--;
|
||||
#ifdef _WIN32
|
||||
closesocket(*event_fd_data.p_fd);
|
||||
#else
|
||||
close(*event_fd_data.p_fd);
|
||||
#endif // _WIN32
|
||||
(*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;
|
||||
_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 my_channel_close_function(ssh_session session, 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);
|
||||
|
||||
stack_socket_close(session, event_fd_data);
|
||||
}
|
||||
|
||||
static void my_channel_eof_function(ssh_session session, 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);
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
static int my_channel_data_function(ssh_session session,
|
||||
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;
|
||||
|
||||
if (event_fd_data->channel == NULL) {
|
||||
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);
|
||||
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));
|
||||
stack_socket_close(session, event_fd_data);
|
||||
}
|
||||
else {
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_channel_data_function", "Sent %d bytes", i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
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;
|
||||
ssh_session session;
|
||||
int len, i, wr;
|
||||
char buf[16384];
|
||||
int blocking;
|
||||
|
||||
if (channel == NULL) {
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel == NULL!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
session = ssh_channel_get_session(channel);
|
||||
|
||||
if (ssh_channel_is_closed(channel)) {
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel is closed!");
|
||||
stack_socket_close(session, event_fd_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(revents & POLLIN)) {
|
||||
if (revents & POLLPRI) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLPRI");
|
||||
}
|
||||
if (revents & POLLOUT) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLOUT");
|
||||
}
|
||||
if (revents & POLLHUP) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLHUP");
|
||||
}
|
||||
if (revents & POLLNVAL) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLNVAL");
|
||||
}
|
||||
if (revents & POLLERR) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLERR");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
#ifdef _WIN32
|
||||
struct sockaddr from;
|
||||
int fromlen = sizeof(from);
|
||||
len = recvfrom(*event_fd_data->p_fd, buf, sizeof(buf), 0, &from, &fromlen);
|
||||
#else
|
||||
len = recv(*event_fd_data->p_fd, buf, sizeof(buf), 0);
|
||||
#endif // _WIN32
|
||||
if (len < 0) {
|
||||
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Reading from tcp socket: %s", strerror(errno));
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
}
|
||||
else if (len > 0) {
|
||||
if (ssh_channel_is_open(channel)) {
|
||||
wr = 0;
|
||||
do {
|
||||
i = ssh_channel_write(channel, buf, len);
|
||||
if (i < 0) {
|
||||
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Error writing on the direct-tcpip channel: %d", i);
|
||||
len = wr;
|
||||
break;
|
||||
}
|
||||
wr += i;
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel_write (%d from %d)", wr, len);
|
||||
} while (i > 0 && wr < len);
|
||||
}
|
||||
else {
|
||||
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Can't write on closed channel!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "The destination host has disconnected!");
|
||||
|
||||
ssh_channel_close(channel);
|
||||
#ifdef _WIN32
|
||||
shutdown(*event_fd_data->p_fd, SD_RECEIVE);
|
||||
#else
|
||||
shutdown(*event_fd_data->p_fd, SHUT_RD);
|
||||
#endif // _WIN32
|
||||
}
|
||||
ssh_set_blocking(session, blocking);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int open_tcp_socket(ssh_message msg) {
|
||||
struct sockaddr_in sin;
|
||||
int forwardsock = -1;
|
||||
struct hostent *host;
|
||||
const char *dest_hostname;
|
||||
int dest_port;
|
||||
|
||||
forwardsock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (forwardsock < 0) {
|
||||
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR opening socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest_hostname = ssh_message_channel_request_open_destination(msg);
|
||||
dest_port = ssh_message_channel_request_open_destination_port(msg);
|
||||
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== open_tcp_socket", "Connecting to %s on port %d", dest_hostname, dest_port);
|
||||
|
||||
host = gethostbyname(dest_hostname);
|
||||
if (host == NULL) {
|
||||
close(forwardsock);
|
||||
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR, no such host: %s", dest_hostname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset((char *)&sin, '\0', sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
memcpy((char *)&sin.sin_addr.s_addr, (char *)host->h_addr, host->h_length);
|
||||
sin.sin_port = htons(dest_port);
|
||||
|
||||
if (connect(forwardsock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
||||
close(forwardsock);
|
||||
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR connecting: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
sockets_cnt++;
|
||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== open_tcp_socket", "Connected. sockets_cnt = %d", sockets_cnt);
|
||||
return forwardsock;
|
||||
}
|
||||
|
||||
static int message_callback(ssh_session session, ssh_message message, 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));
|
||||
if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN) {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "channel_request_open");
|
||||
|
||||
if (ssh_message_subtype(message) == SSH_CHANNEL_DIRECT_TCPIP) {
|
||||
channel = ssh_message_channel_request_open_reply_accept(message);
|
||||
|
||||
if (channel == NULL) {
|
||||
_ssh_log(SSH_LOG_WARNING, "=== message_callback", "Accepting direct-tcpip channel failed!");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "Connected to channel!");
|
||||
|
||||
socket_fd = open_tcp_socket(message);
|
||||
if (-1 == socket_fd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pFd = malloc(sizeof *pFd);
|
||||
cb_chan = malloc(sizeof *cb_chan);
|
||||
event_fd_data = malloc(sizeof *event_fd_data);
|
||||
|
||||
(*pFd) = socket_fd;
|
||||
event_fd_data->channel = channel;
|
||||
event_fd_data->p_fd = pFd;
|
||||
event_fd_data->stacked = 0;
|
||||
event_fd_data->cb_chan = cb_chan;
|
||||
|
||||
cb_chan->userdata = event_fd_data;
|
||||
cb_chan->channel_eof_function = my_channel_eof_function;
|
||||
cb_chan->channel_close_function = my_channel_close_function;
|
||||
cb_chan->channel_data_function = my_channel_data_function;
|
||||
cb_chan->channel_exit_status_function = my_channel_exit_status_function;
|
||||
|
||||
ssh_callbacks_init(cb_chan);
|
||||
ssh_set_channel_callbacks(channel, cb_chan);
|
||||
|
||||
ssh_event_add_fd(mainloop, (socket_t)*pFd, POLLIN, my_fd_data_function, event_fd_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the host key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure.
|
||||
*/
|
||||
ssh_bind sshbind = state->input;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "1");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
struct ssh_server_callbacks_struct cb = {
|
||||
.userdata = NULL,
|
||||
.auth_password_function = auth_password,
|
||||
.auth_gssapi_mic_function = auth_gssapi_mic,
|
||||
.channel_open_request_session_function = new_session_channel,
|
||||
.service_request_function = service_request
|
||||
};
|
||||
struct ssh_callbacks_struct cb_gen = {
|
||||
.userdata = NULL,
|
||||
.global_request_function = global_request
|
||||
};
|
||||
|
||||
int ret = 1;
|
||||
|
||||
sshbind = ssh_bind_new();
|
||||
session = ssh_new();
|
||||
mainloop = ssh_event_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
/*
|
||||
* Parse our arguments; every option seen by parse_opt will
|
||||
* be reflected in arguments.
|
||||
*/
|
||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#endif
|
||||
|
||||
if (ssh_bind_listen(sshbind) < 0) {
|
||||
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ssh_bind_accept(sshbind, session) == SSH_ERROR) {
|
||||
printf("error accepting a connection : %s\n", ssh_get_error(sshbind));
|
||||
ret = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
ssh_callbacks_init(&cb);
|
||||
ssh_callbacks_init(&cb_gen);
|
||||
ssh_set_server_callbacks(session, &cb);
|
||||
ssh_set_callbacks(session, &cb_gen);
|
||||
ssh_set_message_callback(session, message_callback, (void *)NULL);
|
||||
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
ret = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC);
|
||||
ssh_event_add_session(mainloop, session);
|
||||
|
||||
while (!authenticated) {
|
||||
if (error_set) {
|
||||
break;
|
||||
}
|
||||
if (ssh_event_dopoll(mainloop, -1) == SSH_ERROR) {
|
||||
printf("Error : %s\n", ssh_get_error(session));
|
||||
ret = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
if (error_set) {
|
||||
printf("Error, exiting loop\n");
|
||||
} else {
|
||||
printf("Authenticated and got a channel\n");
|
||||
|
||||
while (!error_set) {
|
||||
if (ssh_event_dopoll(mainloop, 100) == SSH_ERROR) {
|
||||
printf("Error : %s\n", ssh_get_error(session));
|
||||
ret = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
do_cleanup(&cleanup_stack);
|
||||
}
|
||||
}
|
||||
|
||||
shutdown:
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
ssh_finalize();
|
||||
return ret;
|
||||
}
|
||||
@@ -90,7 +90,6 @@ static void select_loop(ssh_session session,ssh_channel channel){
|
||||
do{
|
||||
int fd;
|
||||
|
||||
ZERO_STRUCT(fds);
|
||||
FD_ZERO(&fds);
|
||||
if(!eof)
|
||||
FD_SET(0,&fds);
|
||||
|
||||
@@ -26,7 +26,7 @@ install(
|
||||
FILES
|
||||
${libssh_HDRS}
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}
|
||||
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||
COMPONENT
|
||||
headers
|
||||
)
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
#include "libssh/libmbedcrypto.h"
|
||||
|
||||
bignum ssh_make_string_bn(ssh_string string);
|
||||
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout);
|
||||
ssh_string ssh_make_bignum_string(bignum num);
|
||||
void ssh_print_bignum(const char *which, const_bignum num);
|
||||
void ssh_print_bignum(const char *which, const bignum num);
|
||||
|
||||
|
||||
#endif /* BIGNUM_H_ */
|
||||
|
||||
@@ -46,9 +46,6 @@ struct ssh_bind_struct {
|
||||
unsigned int bindport;
|
||||
int blocking;
|
||||
int toaccept;
|
||||
bool config_processed;
|
||||
char *config_dir;
|
||||
char *pubkey_accepted_key_types;
|
||||
};
|
||||
|
||||
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* bind_config.h - Parse the SSH server configuration file
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2019 by Red Hat, Inc.
|
||||
*
|
||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef BIND_CONFIG_H_
|
||||
#define BIND_CONFIG_H_
|
||||
|
||||
#include "libssh/server.h"
|
||||
|
||||
enum ssh_bind_config_opcode_e {
|
||||
/* Known but not allowed in Match block */
|
||||
BIND_CFG_NOT_ALLOWED_IN_MATCH = -4,
|
||||
/* Unknown opcode */
|
||||
BIND_CFG_UNKNOWN = -3,
|
||||
/* Known and not applicable to libssh */
|
||||
BIND_CFG_NA = -2,
|
||||
/* Known but not supported by current libssh version */
|
||||
BIND_CFG_UNSUPPORTED = -1,
|
||||
BIND_CFG_INCLUDE,
|
||||
BIND_CFG_HOSTKEY,
|
||||
BIND_CFG_LISTENADDRESS,
|
||||
BIND_CFG_PORT,
|
||||
BIND_CFG_LOGLEVEL,
|
||||
BIND_CFG_CIPHERS,
|
||||
BIND_CFG_MACS,
|
||||
BIND_CFG_KEXALGORITHMS,
|
||||
BIND_CFG_MATCH,
|
||||
BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES,
|
||||
BIND_CFG_HOSTKEY_ALGORITHMS,
|
||||
|
||||
BIND_CFG_MAX /* Keep this one last in the list */
|
||||
};
|
||||
|
||||
/* @brief Parse configuration file and set the options to the given ssh_bind
|
||||
*
|
||||
* @params[in] sshbind The ssh_bind context to be configured
|
||||
* @params[in] filename The path to the configuration file
|
||||
*
|
||||
* @returns 0 on successful parsing the configuration file, -1 on error
|
||||
*/
|
||||
int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename);
|
||||
|
||||
#endif /* BIND_CONFIG_H_ */
|
||||
@@ -40,21 +40,21 @@ void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len);
|
||||
int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len);
|
||||
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
va_list ap);
|
||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
...);
|
||||
#define ssh_buffer_pack(buffer, format, ...) \
|
||||
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||
|
||||
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
const char *format, size_t argc,
|
||||
const char *format, int argc,
|
||||
va_list ap);
|
||||
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
...);
|
||||
#define ssh_buffer_unpack(buffer, format, ...) \
|
||||
_ssh_buffer_unpack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2018 Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _BYTEARRAY_H
|
||||
#define _BYTEARRAY_H
|
||||
|
||||
#define _DATA_BYTE_CONST(data, pos) \
|
||||
((uint8_t)(((const uint8_t *)(data))[(pos)]))
|
||||
|
||||
#define _DATA_BYTE(data, pos) \
|
||||
(((uint8_t *)(data))[(pos)])
|
||||
|
||||
/*
|
||||
* These macros pull or push integer values from byte arrays stored in
|
||||
* little-endian byte order.
|
||||
*/
|
||||
#define PULL_LE_U8(data, pos) \
|
||||
(_DATA_BYTE_CONST(data, pos))
|
||||
|
||||
#define PULL_LE_U16(data, pos) \
|
||||
((uint16_t)PULL_LE_U8(data, pos) | ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8)
|
||||
|
||||
#define PULL_LE_U32(data, pos) \
|
||||
((uint32_t)(PULL_LE_U16(data, pos) | ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16))
|
||||
|
||||
#define PULL_LE_U64(data, pos) \
|
||||
((uint64_t)(PULL_LE_U32(data, pos) | ((uint64_t)PULL_LE_U32(data, (pos) + 4)) << 32))
|
||||
|
||||
|
||||
#define PUSH_LE_U8(data, pos, val) \
|
||||
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
|
||||
|
||||
#define PUSH_LE_U16(data, pos, val) \
|
||||
(PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)), PUSH_LE_U8((data), (pos) + 1, (uint8_t)((uint16_t)(val) >> 8)))
|
||||
|
||||
#define PUSH_LE_U32(data, pos, val) \
|
||||
(PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)), PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16)))
|
||||
|
||||
#define PUSH_LE_U64(data, pos, val) \
|
||||
(PUSH_LE_U32((data), (pos), (uint32_t)((uint64_t)(val) & 0xffffffff)), PUSH_LE_U32((data), (pos) + 4, (uint32_t)((uint64_t)(val) >> 32)))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* These macros pull or push integer values from byte arrays stored in
|
||||
* big-endian byte order (network byte order).
|
||||
*/
|
||||
#define PULL_BE_U8(data, pos) \
|
||||
(_DATA_BYTE_CONST(data, pos))
|
||||
|
||||
#define PULL_BE_U16(data, pos) \
|
||||
((((uint16_t)(PULL_BE_U8(data, pos))) << 8) | (uint16_t)PULL_BE_U8(data, (pos) + 1))
|
||||
|
||||
#define PULL_BE_U32(data, pos) \
|
||||
((((uint32_t)PULL_BE_U16(data, pos)) << 16) | (uint32_t)(PULL_BE_U16(data, (pos) + 2)))
|
||||
|
||||
#define PULL_BE_U64(data, pos) \
|
||||
((((uint64_t)PULL_BE_U32(data, pos)) << 32) | (uint64_t)(PULL_BE_U32(data, (pos) + 4)))
|
||||
|
||||
|
||||
|
||||
#define PUSH_BE_U8(data, pos, val) \
|
||||
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
|
||||
|
||||
#define PUSH_BE_U16(data, pos, val) \
|
||||
(PUSH_BE_U8((data), (pos), (uint8_t)(((uint16_t)(val)) >> 8)), PUSH_BE_U8((data), (pos) + 1, (uint8_t)((val) & 0xff)))
|
||||
|
||||
#define PUSH_BE_U32(data, pos, val) \
|
||||
(PUSH_BE_U16((data), (pos), (uint16_t)(((uint32_t)(val)) >> 16)), PUSH_BE_U16((data), (pos) + 2, (uint16_t)((val) & 0xffff)))
|
||||
|
||||
#define PUSH_BE_U64(data, pos, val) \
|
||||
(PUSH_BE_U32((data), (pos), (uint32_t)(((uint64_t)(val)) >> 32)), PUSH_BE_U32((data), (pos) + 4, (uint32_t)((val) & 0xffffffff)))
|
||||
|
||||
#endif /* _BYTEARRAY_H */
|
||||
@@ -854,7 +854,7 @@ typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
|
||||
* @code
|
||||
* struct ssh_channel_callbacks_struct cb = {
|
||||
* .userdata = data,
|
||||
* .channel_data_function = my_channel_data_function
|
||||
* .channel_data = my_channel_data_function
|
||||
* };
|
||||
* ssh_callbacks_init(&cb);
|
||||
* ssh_set_channel_callbacks(channel, &cb);
|
||||
@@ -944,20 +944,9 @@ LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
|
||||
*cb);
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to the appropriate callbacks structure for the
|
||||
* environment, to be used with ssh_threads_set_callbacks.
|
||||
*
|
||||
* @returns A pointer to a ssh_threads_callbacks_struct to be used with
|
||||
* @brief returns a pointer on the pthread threads callbacks, to be used with
|
||||
* ssh_threads_set_callbacks.
|
||||
*
|
||||
* @see ssh_threads_set_callbacks
|
||||
*/
|
||||
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_default(void);
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer on the pthread threads callbacks, to be used with
|
||||
* ssh_threads_set_callbacks.
|
||||
*
|
||||
* @warning you have to link with the library ssh_threads.
|
||||
* @see ssh_threads_set_callbacks
|
||||
*/
|
||||
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
|
||||
|
||||
@@ -48,16 +48,11 @@ enum ssh_channel_state_e {
|
||||
};
|
||||
|
||||
/* The channel has been closed by the remote side */
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x0001
|
||||
|
||||
/* The channel has been closed locally */
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_LOCAL 0x0002
|
||||
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x1
|
||||
/* The channel has been freed by the calling program */
|
||||
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x0004
|
||||
|
||||
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x2
|
||||
/* the channel has not yet been bound to a remote one */
|
||||
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x0008
|
||||
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x4
|
||||
|
||||
struct ssh_channel_struct {
|
||||
ssh_session session; /* SSH_SESSION pointer */
|
||||
@@ -103,9 +98,5 @@ 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);
|
||||
void ssh_channel_do_free(ssh_channel channel);
|
||||
int ssh_global_request(ssh_session session,
|
||||
const char *request,
|
||||
ssh_buffer buffer,
|
||||
int reply);
|
||||
|
||||
#endif /* CHANNELS_H_ */
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* config.h - parse the ssh config file
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009-2018 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LIBSSH_CONFIG_H_
|
||||
#define LIBSSH_CONFIG_H_
|
||||
|
||||
|
||||
enum ssh_config_opcode_e {
|
||||
/* Unknown opcode */
|
||||
SOC_UNKNOWN = -3,
|
||||
/* Known and not applicable to libssh */
|
||||
SOC_NA = -2,
|
||||
/* Known but not supported by current libssh version */
|
||||
SOC_UNSUPPORTED = -1,
|
||||
SOC_HOST,
|
||||
SOC_MATCH,
|
||||
SOC_HOSTNAME,
|
||||
SOC_PORT,
|
||||
SOC_USERNAME,
|
||||
SOC_IDENTITY,
|
||||
SOC_CIPHERS,
|
||||
SOC_MACS,
|
||||
SOC_COMPRESSION,
|
||||
SOC_TIMEOUT,
|
||||
SOC_PROTOCOL,
|
||||
SOC_STRICTHOSTKEYCHECK,
|
||||
SOC_KNOWNHOSTS,
|
||||
SOC_PROXYCOMMAND,
|
||||
SOC_PROXYJUMP,
|
||||
SOC_GSSAPISERVERIDENTITY,
|
||||
SOC_GSSAPICLIENTIDENTITY,
|
||||
SOC_GSSAPIDELEGATECREDENTIALS,
|
||||
SOC_INCLUDE,
|
||||
SOC_BINDADDRESS,
|
||||
SOC_GLOBALKNOWNHOSTSFILE,
|
||||
SOC_LOGLEVEL,
|
||||
SOC_HOSTKEYALGORITHMS,
|
||||
SOC_KEXALGORITHMS,
|
||||
SOC_GSSAPIAUTHENTICATION,
|
||||
SOC_KBDINTERACTIVEAUTHENTICATION,
|
||||
SOC_PASSWORDAUTHENTICATION,
|
||||
SOC_PUBKEYAUTHENTICATION,
|
||||
SOC_PUBKEYACCEPTEDTYPES,
|
||||
SOC_REKEYLIMIT,
|
||||
|
||||
SOC_MAX /* Keep this one last in the list */
|
||||
};
|
||||
#endif /* LIBSSH_CONFIG_H_ */
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* config_parser.h - Common configuration file parser functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2019 by Red Hat, Inc.
|
||||
*
|
||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_PARSER_H_
|
||||
#define CONFIG_PARSER_H_
|
||||
|
||||
char *ssh_config_get_cmd(char **str);
|
||||
|
||||
char *ssh_config_get_token(char **str);
|
||||
|
||||
long ssh_config_get_long(char **str, long notfound);
|
||||
|
||||
const char *ssh_config_get_str_tok(char **str, const char *def);
|
||||
|
||||
int ssh_config_get_yesno(char **str, int notfound);
|
||||
|
||||
/* @brief Parse SSH URI in format [user@]host[:port] from the given string
|
||||
*
|
||||
* @param[in] tok String to parse
|
||||
* @param[out] username Pointer to the location, where the new username will
|
||||
* be stored or NULL if we do not care about the result.
|
||||
* @param[out] hostname Pointer to the location, where the new hostname will
|
||||
* be stored or NULL if we do not care about the result.
|
||||
* @param[out] port Pointer to the location, where the new port will
|
||||
* be stored or NULL if we do not care about the result.
|
||||
*
|
||||
* @returns SSH_OK if the provided string is in format of SSH URI,
|
||||
* SSH_ERROR on failure
|
||||
*/
|
||||
int ssh_config_parse_uri(const char *tok,
|
||||
char **username,
|
||||
char **hostname,
|
||||
char **port);
|
||||
|
||||
#endif /* LIBSSH_CONFIG_H_ */
|
||||
28
include/libssh/crc32.h
Normal file
28
include/libssh/crc32.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* crc32.c - simple CRC32 code
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CRC32_H
|
||||
#define _CRC32_H
|
||||
|
||||
uint32_t ssh_crc32(const char *buf, uint32_t len);
|
||||
|
||||
#endif /* _CRC32_H */
|
||||
@@ -25,13 +25,10 @@
|
||||
#ifndef _CRYPTO_H_
|
||||
#define _CRYPTO_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#include <gcrypt.h>
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
#include <mbedtls/gcm.h>
|
||||
#endif
|
||||
#include "libssh/wrapper.h"
|
||||
|
||||
@@ -45,27 +42,17 @@
|
||||
#ifdef HAVE_OPENSSL_ECDH_H
|
||||
#include <openssl/ecdh.h>
|
||||
#endif
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/ecdh.h"
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/curve25519.h"
|
||||
|
||||
#define DIGEST_MAX_LEN 64
|
||||
|
||||
#define AES_GCM_TAGLEN 16
|
||||
#define AES_GCM_IVLEN 12
|
||||
|
||||
enum ssh_key_exchange_e {
|
||||
/* diffie-hellman-group1-sha1 */
|
||||
SSH_KEX_DH_GROUP1_SHA1=1,
|
||||
/* diffie-hellman-group14-sha1 */
|
||||
SSH_KEX_DH_GROUP14_SHA1,
|
||||
#ifdef WITH_GEX
|
||||
/* diffie-hellman-group-exchange-sha1 */
|
||||
SSH_KEX_DH_GEX_SHA1,
|
||||
/* diffie-hellman-group-exchange-sha256 */
|
||||
SSH_KEX_DH_GEX_SHA256,
|
||||
#endif /* WITH_GEX */
|
||||
/* ecdh-sha2-nistp256 */
|
||||
SSH_KEX_ECDH_SHA2_NISTP256,
|
||||
/* ecdh-sha2-nistp384 */
|
||||
@@ -84,29 +71,18 @@ enum ssh_key_exchange_e {
|
||||
|
||||
enum ssh_cipher_e {
|
||||
SSH_NO_CIPHER=0,
|
||||
#ifdef WITH_BLOWFISH_CIPHER
|
||||
SSH_BLOWFISH_CBC,
|
||||
#endif /* WITH_BLOWFISH_CIPHER */
|
||||
SSH_3DES_CBC,
|
||||
SSH_AES128_CBC,
|
||||
SSH_AES192_CBC,
|
||||
SSH_AES256_CBC,
|
||||
SSH_AES128_CTR,
|
||||
SSH_AES192_CTR,
|
||||
SSH_AES256_CTR,
|
||||
SSH_AEAD_AES128_GCM,
|
||||
SSH_AEAD_AES256_GCM,
|
||||
SSH_AEAD_CHACHA20_POLY1305
|
||||
SSH_AES256_CTR
|
||||
};
|
||||
|
||||
struct dh_ctx;
|
||||
|
||||
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 */
|
||||
#endif /* WITH_GEX */
|
||||
bignum e,f,x,k,y;
|
||||
#ifdef HAVE_ECDH
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
EC_KEY *ecdh_privkey;
|
||||
@@ -124,7 +100,7 @@ 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 digest_len; /* len of all the fields below */
|
||||
unsigned char *session_id;
|
||||
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
|
||||
unsigned char *encryptIV;
|
||||
@@ -136,7 +112,6 @@ struct ssh_crypto_struct {
|
||||
unsigned char hmacbuf[DIGEST_MAX_LEN];
|
||||
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
||||
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */
|
||||
bool in_hmac_etm, out_hmac_etm; /* Whether EtM mode is used or not */
|
||||
|
||||
ssh_key server_pubkey;
|
||||
int do_compress_out; /* idem */
|
||||
@@ -150,8 +125,7 @@ struct ssh_crypto_struct {
|
||||
struct ssh_kex_struct client_kex;
|
||||
char *kex_methods[SSH_KEX_METHODS];
|
||||
enum ssh_key_exchange_e kex_type;
|
||||
enum ssh_kdf_digest digest_type; /* Digest type for session keys derivation */
|
||||
enum ssh_crypto_direction_e used; /* Is this crypto still used for either of directions? */
|
||||
enum ssh_mac_e mac_type; /* Mac operations to use for key gen */
|
||||
};
|
||||
|
||||
struct ssh_cipher_struct {
|
||||
@@ -162,7 +136,6 @@ struct ssh_cipher_struct {
|
||||
size_t keylen; /* length of the key structure */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_cipher_hd_t *key;
|
||||
unsigned char last_iv[AES_GCM_IVLEN];
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
struct ssh_3des_key_schedule *des3_key;
|
||||
struct ssh_aes_key_schedule *aes_key;
|
||||
@@ -172,30 +145,17 @@ struct ssh_cipher_struct {
|
||||
mbedtls_cipher_context_t encrypt_ctx;
|
||||
mbedtls_cipher_context_t decrypt_ctx;
|
||||
mbedtls_cipher_type_t type;
|
||||
#ifdef MBEDTLS_GCM_C
|
||||
mbedtls_gcm_context gcm_ctx;
|
||||
unsigned char last_iv[AES_GCM_IVLEN];
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
#endif
|
||||
struct chacha20_poly1305_keysched *chacha20_schedule;
|
||||
unsigned int keysize; /* bytes of key used. != keylen */
|
||||
size_t tag_size; /* overhead required for tag */
|
||||
/* Counters for rekeying initialization */
|
||||
uint32_t packets;
|
||||
uint64_t blocks;
|
||||
/* Rekeying limit for the cipher or manually enforced */
|
||||
uint64_t max_blocks;
|
||||
/* sets the new key for immediate use */
|
||||
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||
void (*encrypt)(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len);
|
||||
void (*decrypt)(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len);
|
||||
void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
size_t len, uint8_t *mac, uint64_t seq);
|
||||
int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,
|
||||
@@ -206,9 +166,5 @@ struct ssh_cipher_struct {
|
||||
};
|
||||
|
||||
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void);
|
||||
int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
|
||||
unsigned char *key, size_t key_len,
|
||||
int key_type, unsigned char *output,
|
||||
size_t requested_len);
|
||||
|
||||
#endif /* _CRYPTO_H_ */
|
||||
|
||||
@@ -48,9 +48,10 @@ typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
|
||||
|
||||
|
||||
int ssh_client_curve25519_init(ssh_session session);
|
||||
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet);
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
void ssh_server_curve25519_init(ssh_session session);
|
||||
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet);
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
#endif /* CURVE25519_H_ */
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.be>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SRC_DH_GEX_H_
|
||||
#define SRC_DH_GEX_H_
|
||||
|
||||
int ssh_client_dhgex_init(ssh_session session);
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
void ssh_server_dhgex_init(ssh_session session);
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
#endif /* SRC_DH_GEX_H_ */
|
||||
@@ -25,37 +25,25 @@
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
struct dh_ctx;
|
||||
int ssh_dh_generate_e(ssh_session session);
|
||||
int ssh_dh_generate_f(ssh_session session);
|
||||
int ssh_dh_generate_x(ssh_session session);
|
||||
int ssh_dh_generate_y(ssh_session session);
|
||||
|
||||
#define DH_CLIENT_KEYPAIR 0
|
||||
#define DH_SERVER_KEYPAIR 1
|
||||
|
||||
/* functions implemented by crypto backends */
|
||||
int ssh_dh_init_common(struct ssh_crypto_struct *crypto);
|
||||
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto);
|
||||
|
||||
int ssh_dh_get_parameters(struct dh_ctx *ctx,
|
||||
const_bignum *modulus, const_bignum *generator);
|
||||
int ssh_dh_set_parameters(struct dh_ctx *ctx,
|
||||
const bignum modulus, const bignum generator);
|
||||
|
||||
int ssh_dh_keypair_gen_keys(struct dh_ctx *ctx, int peer);
|
||||
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
|
||||
const_bignum *priv, const_bignum *pub);
|
||||
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
|
||||
const bignum priv, const bignum pub);
|
||||
|
||||
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);
|
||||
|
||||
int ssh_dh_import_next_pubkey_blob(ssh_session session,
|
||||
ssh_string pubkey_blob);
|
||||
ssh_string ssh_dh_get_e(ssh_session session);
|
||||
ssh_string ssh_dh_get_f(ssh_session session);
|
||||
int ssh_dh_import_f(ssh_session session,ssh_string f_string);
|
||||
int ssh_dh_import_e(ssh_session session, ssh_string e_string);
|
||||
|
||||
int ssh_dh_import_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
|
||||
int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
|
||||
|
||||
int ssh_dh_build_k(ssh_session session);
|
||||
int ssh_client_dh_init(ssh_session session);
|
||||
int ssh_client_dh_reply(ssh_session session, ssh_buffer packet);
|
||||
|
||||
ssh_key ssh_dh_get_current_server_publickey(ssh_session session);
|
||||
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
|
||||
@@ -64,12 +52,10 @@ ssh_key ssh_dh_get_next_server_publickey(ssh_session session);
|
||||
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
|
||||
ssh_string *pubkey_blob);
|
||||
|
||||
int ssh_client_dh_init(ssh_session session);
|
||||
#ifdef WITH_SERVER
|
||||
void ssh_server_dh_init(ssh_session session);
|
||||
#endif /* WITH_SERVER */
|
||||
int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet);
|
||||
int ssh_fallback_group(uint32_t pmax, bignum *p, bignum *g);
|
||||
bool ssh_dh_is_known_group(bignum modulus, bignum generator);
|
||||
int ssh_make_sessionid(ssh_session session);
|
||||
/* add data for the final cookie */
|
||||
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||
int ssh_hashbufout_add_cookie(ssh_session session);
|
||||
int ssh_generate_session_keys(ssh_session session);
|
||||
|
||||
#endif /* DH_H_ */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define ECDH_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
#ifdef HAVE_OPENSSL_ECDH_H
|
||||
@@ -42,15 +41,15 @@
|
||||
#define HAVE_ECDH 1
|
||||
#endif
|
||||
|
||||
extern struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks;
|
||||
/* Common functions. */
|
||||
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
|
||||
|
||||
/* Backend-specific functions. */
|
||||
int ssh_client_ecdh_init(ssh_session session);
|
||||
int ecdh_build_k(ssh_session session);
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
extern struct ssh_packet_callbacks_struct ssh_ecdh_server_callbacks;
|
||||
void ssh_server_ecdh_init(ssh_session session);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init);
|
||||
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet);
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
#endif /* ECDH_H_ */
|
||||
|
||||
@@ -56,8 +56,8 @@ int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int crypto_sign_ed25519(
|
||||
unsigned char *sm, uint64_t *smlen,
|
||||
const unsigned char *m, uint64_t mlen,
|
||||
unsigned char *sm,unsigned long long *smlen,
|
||||
const unsigned char *m,unsigned long long mlen,
|
||||
const ed25519_privkey sk);
|
||||
|
||||
/** @internal
|
||||
@@ -71,8 +71,8 @@ int crypto_sign_ed25519(
|
||||
* @returns 0 on success (supposedly).
|
||||
*/
|
||||
int crypto_sign_ed25519_open(
|
||||
unsigned char *m, uint64_t *mlen,
|
||||
const unsigned char *sm, uint64_t smlen,
|
||||
unsigned char *m,unsigned long long *mlen,
|
||||
const unsigned char *sm,unsigned long long smlen,
|
||||
const ed25519_pubkey pk);
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -39,21 +39,12 @@ int ssh_set_client_kex(ssh_session session);
|
||||
int ssh_kex_select_methods(ssh_session session);
|
||||
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
|
||||
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
|
||||
char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list);
|
||||
char **ssh_space_tokenize(const char *chain);
|
||||
int ssh_get_kex1(ssh_session session);
|
||||
char *ssh_find_matching(const char *in_d, const char *what_d);
|
||||
const char *ssh_kex_get_supported_method(uint32_t algo);
|
||||
const char *ssh_kex_get_default_methods(uint32_t algo);
|
||||
const char *ssh_kex_get_fips_methods(uint32_t algo);
|
||||
const char *ssh_kex_get_description(uint32_t algo);
|
||||
char *ssh_client_select_hostkeys(ssh_session session);
|
||||
int ssh_send_rekex(ssh_session session);
|
||||
int server_set_kex(ssh_session session);
|
||||
int ssh_make_sessionid(ssh_session session);
|
||||
/* add data for the final cookie */
|
||||
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||
int ssh_hashbufout_add_cookie(ssh_session session);
|
||||
int ssh_generate_session_keys(ssh_session session);
|
||||
|
||||
#endif /* KEX_H_ */
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#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,
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
typedef EVP_MD_CTX* SHACTX;
|
||||
typedef EVP_MD_CTX* SHA256CTX;
|
||||
@@ -65,7 +64,6 @@ typedef void *EVPCTX;
|
||||
#define BROKEN_AES_CTR
|
||||
#endif
|
||||
typedef BIGNUM* bignum;
|
||||
typedef const BIGNUM* const_bignum;
|
||||
typedef BN_CTX* bignum_CTX;
|
||||
|
||||
#define bignum_new() BN_new()
|
||||
@@ -76,47 +74,19 @@ typedef BN_CTX* bignum_CTX;
|
||||
} \
|
||||
} while(0)
|
||||
#define bignum_set_word(bn,n) BN_set_word(bn,n)
|
||||
#define bignum_bin2bn(data, datalen, dest) \
|
||||
do { \
|
||||
(*dest) = BN_new(); \
|
||||
if ((*dest) != NULL) { \
|
||||
BN_bin2bn(data,datalen,(*dest)); \
|
||||
} \
|
||||
} while(0)
|
||||
#define bignum_bin2bn(bn,datalen,data) BN_bin2bn(bn,datalen,data)
|
||||
#define bignum_bn2dec(num) BN_bn2dec(num)
|
||||
#define bignum_dec2bn(data, bn) BN_dec2bn(bn, data)
|
||||
#define bignum_hex2bn(data, bn) BN_hex2bn(bn, data)
|
||||
#define bignum_bn2hex(num, dest) (*dest)=(unsigned char *)BN_bn2hex(num)
|
||||
#define bignum_dec2bn(bn,data) BN_dec2bn(data,bn)
|
||||
#define bignum_bn2hex(num) BN_bn2hex(num)
|
||||
#define bignum_rand(rnd, bits) BN_rand(rnd, bits, 0, 1)
|
||||
#define bignum_rand_range(rnd, max) BN_rand_range(rnd, max)
|
||||
#define bignum_ctx_new() BN_CTX_new()
|
||||
#define bignum_ctx_free(num) BN_CTX_free(num)
|
||||
#define bignum_ctx_invalid(ctx) ((ctx) == NULL)
|
||||
#define bignum_mod_exp(dest,generator,exp,modulo,ctx) BN_mod_exp(dest,generator,exp,modulo,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_bn2bin(num,len, ptr) BN_bn2bin(num, ptr)
|
||||
#define bignum_bn2bin(num,ptr) BN_bn2bin(num,ptr)
|
||||
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
|
||||
#define bignum_rshift1(dest, src) BN_rshift1(dest, src)
|
||||
#define bignum_dup(orig, dest) do { \
|
||||
if (*(dest) == NULL) { \
|
||||
*(dest) = BN_dup(orig); \
|
||||
} else { \
|
||||
BN_copy(*(dest), orig); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
||||
@@ -50,8 +50,6 @@ typedef gcry_md_hd_t EVPCTX;
|
||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||
|
||||
typedef gcry_mpi_t bignum;
|
||||
typedef const struct gcry_mpi *const_bignum;
|
||||
typedef void* bignum_CTX;
|
||||
|
||||
/* Constants for curves. */
|
||||
#define NID_gcrypt_nistp256 0
|
||||
@@ -61,7 +59,6 @@ typedef void* bignum_CTX;
|
||||
/* missing gcrypt functions */
|
||||
int ssh_gcry_dec2bn(bignum *bn, const char *data);
|
||||
char *ssh_gcry_bn2dec(bignum bn);
|
||||
int ssh_gcry_rand_range(bignum rnd, bignum max);
|
||||
|
||||
#define bignum_new() gcry_mpi_new(0)
|
||||
#define bignum_safe_free(num) do { \
|
||||
@@ -70,38 +67,20 @@ int ssh_gcry_rand_range(bignum rnd, bignum max);
|
||||
(num)=NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
#define bignum_free(num) gcry_mpi_release(num)
|
||||
#define bignum_ctx_new() NULL
|
||||
#define bignum_ctx_free(ctx) do {(ctx) = NULL;} while(0)
|
||||
#define bignum_ctx_invalid(ctx) (ctx != NULL)
|
||||
#define bignum_set_word(bn,n) (gcry_mpi_set_ui(bn,n)!=NULL ? 1 : 0)
|
||||
#define bignum_bin2bn(data,datalen,dest) gcry_mpi_scan(dest,GCRYMPI_FMT_USG,data,datalen,NULL)
|
||||
#define bignum_set_word(bn,n) gcry_mpi_set_ui(bn,n)
|
||||
#define bignum_bin2bn(bn,datalen,data) gcry_mpi_scan(data,GCRYMPI_FMT_USG,bn,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, (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)
|
||||
#define bignum_bn2hex(num,data) gcry_mpi_aprint(GCRYMPI_FMT_HEX,data,NULL,num)
|
||||
#define bignum_hex2bn(num,datalen,data) gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,datalen,NULL)
|
||||
#define bignum_rand(num,bits) 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) gcry_mpi_powm(dest,generator,exp,modulo)
|
||||
#define bignum_num_bits(num) gcry_mpi_get_nbits(num)
|
||||
#define bignum_num_bytes(num) ((gcry_mpi_get_nbits(num)+7)/8)
|
||||
#define bignum_is_bit_set(num,bit) gcry_mpi_test_bit(num,bit)
|
||||
#define bignum_bn2bin(num,datalen,data) gcry_mpi_print(GCRYMPI_FMT_USG,data,datalen,NULL,num)
|
||||
#define bignum_cmp(num1,num2) gcry_mpi_cmp(num1,num2)
|
||||
#define bignum_rshift1(dest, src) gcry_mpi_rshift (dest, src, 1)
|
||||
#define bignum_add(dst, a, b) gcry_mpi_add(dst, a, b)
|
||||
#define bignum_sub(dst, a, b) gcry_mpi_sub(dst, a, b)
|
||||
#define bignum_mod(dst, a, b, ctx) 1,gcry_mpi_mod(dst, a, b)
|
||||
#define bignum_rand_range(rnd, max) ssh_gcry_rand_range(rnd, max);
|
||||
#define bignum_dup(orig, dest) do { \
|
||||
if (*(dest) == NULL) { \
|
||||
*(dest) = gcry_mpi_copy(orig); \
|
||||
} else { \
|
||||
gcry_mpi_set(*(dest), orig); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Helper functions for data conversions. */
|
||||
|
||||
/* Extract an MPI from the given s-expression SEXP named NAME which is
|
||||
@@ -112,8 +91,6 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
|
||||
enum gcry_mpi_format informat,
|
||||
enum gcry_mpi_format outformat);
|
||||
|
||||
#define ssh_fips_mode() false
|
||||
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
|
||||
#endif /* LIBGCRYPT_H_ */
|
||||
|
||||
@@ -60,8 +60,6 @@ typedef mbedtls_md_context_t *EVPCTX;
|
||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||
|
||||
typedef mbedtls_mpi *bignum;
|
||||
typedef const mbedtls_mpi *const_bignum;
|
||||
typedef void* bignum_CTX;
|
||||
|
||||
/* Constants for curves */
|
||||
#define NID_mbedtls_nistp256 0
|
||||
@@ -75,11 +73,9 @@ struct mbedtls_ecdsa_sig {
|
||||
|
||||
bignum ssh_mbedcry_bn_new(void);
|
||||
void ssh_mbedcry_bn_free(bignum num);
|
||||
unsigned char *ssh_mbedcry_bn2num(const_bignum num, int radix);
|
||||
char *ssh_mbedcry_bn2num(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);
|
||||
int ssh_mbedcry_hex2bn(bignum *dest, char *data);
|
||||
|
||||
#define bignum_new() ssh_mbedcry_bn_new()
|
||||
#define bignum_safe_free(num) do { \
|
||||
@@ -88,44 +84,22 @@ int ssh_mbedcry_hex2bn(bignum *dest, char *data);
|
||||
(num)=NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
#define bignum_ctx_new() NULL
|
||||
#define bignum_ctx_free(num) do {(num) = NULL;} while(0)
|
||||
#define bignum_ctx_invalid(ctx) (ctx == NULL?0:1)
|
||||
#define bignum_set_word(bn, n) (mbedtls_mpi_lset(bn, n)==0?1:0) /* TODO fix
|
||||
#define bignum_set_word(bn, n) mbedtls_mpi_lset(bn, n) /* TODO fix
|
||||
overflow/underflow */
|
||||
#define bignum_bin2bn(data, datalen, bn) do { \
|
||||
*(bn) = bignum_new(); \
|
||||
if (*(bn) != NULL) { \
|
||||
mbedtls_mpi_read_binary(*(bn), data, datalen); \
|
||||
} \
|
||||
} while(0)
|
||||
#define bignum_bin2bn(data, datalen, bn) mbedtls_mpi_read_binary(bn, data, \
|
||||
datalen)
|
||||
#define bignum_bn2dec(num) ssh_mbedcry_bn2num(num, 10)
|
||||
#define bignum_dec2bn(data, bn) mbedtls_mpi_read_string(bn, 10, data)
|
||||
#define bignum_bn2hex(num, dest) (*dest)=ssh_mbedcry_bn2num(num, 16)
|
||||
#define bignum_hex2bn(data, dest) ssh_mbedcry_hex2bn(dest, data)
|
||||
#define bignum_bn2hex(num) ssh_mbedcry_bn2num(num, 16)
|
||||
#define bignum_rand(rnd, bits) ssh_mbedcry_rand((rnd), (bits), 0, 1)
|
||||
#define bignum_rand_range(rnd, max) ssh_mbedcry_rand_range(rnd, max)
|
||||
#define bignum_mod_exp(dest, generator, exp, modulo, ctx) \
|
||||
(mbedtls_mpi_exp_mod(dest, generator, exp, modulo, NULL)==0?1:0)
|
||||
#define bignum_add(dest, a, b) mbedtls_mpi_add_mpi(dest, a, b)
|
||||
#define bignum_sub(dest, a, b) mbedtls_mpi_sub_mpi(dest, a, b)
|
||||
#define bignum_mod(dest, a, b, ctx) \
|
||||
(mbedtls_mpi_mod_mpi(dest, a, b) == 0 ? 1 : 0)
|
||||
mbedtls_mpi_exp_mod(dest, generator, exp, modulo, NULL)
|
||||
#define bignum_num_bytes(num) mbedtls_mpi_size(num)
|
||||
#define bignum_num_bits(num) mbedtls_mpi_bitlen(num)
|
||||
#define bignum_is_bit_set(num, bit) ssh_mbedcry_is_bit_set(num, bit)
|
||||
#define bignum_bn2bin(num, len, ptr) mbedtls_mpi_write_binary(num, ptr, \
|
||||
#define bignum_bn2bin(num, ptr) mbedtls_mpi_write_binary(num, ptr, \
|
||||
mbedtls_mpi_size(num))
|
||||
#define bignum_cmp(num1, num2) mbedtls_mpi_cmp_mpi(num1, num2)
|
||||
#define bignum_rshift1(dest, src) mbedtls_mpi_copy(dest, src), mbedtls_mpi_shift_r(dest, 1)
|
||||
#define bignum_dup(orig, dest) do { \
|
||||
if (*(dest) == NULL) { \
|
||||
*(dest) = bignum_new(); \
|
||||
} \
|
||||
if (*(dest) != NULL) { \
|
||||
mbedtls_mpi_copy(orig, *(dest)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void);
|
||||
|
||||
@@ -134,7 +108,5 @@ int ssh_mbedtls_random(void *where, int len, int strong);
|
||||
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
|
||||
mbedtls_ecp_point *p);
|
||||
|
||||
#define ssh_fips_mode() false
|
||||
|
||||
#endif /* HAVE_LIBMBEDCRYPTO */
|
||||
#endif /* LIBMBEDCRYPTO_H_ */
|
||||
|
||||
@@ -78,8 +78,8 @@
|
||||
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 9
|
||||
#define LIBSSH_VERSION_MICRO 2
|
||||
#define LIBSSH_VERSION_MINOR 8
|
||||
#define LIBSSH_VERSION_MICRO 5
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
@@ -293,17 +293,10 @@ enum ssh_keytypes_e{
|
||||
SSH_KEYTYPE_DSS=1,
|
||||
SSH_KEYTYPE_RSA,
|
||||
SSH_KEYTYPE_RSA1,
|
||||
SSH_KEYTYPE_ECDSA, /* deprecated */
|
||||
SSH_KEYTYPE_ECDSA,
|
||||
SSH_KEYTYPE_ED25519,
|
||||
SSH_KEYTYPE_DSS_CERT01,
|
||||
SSH_KEYTYPE_RSA_CERT01,
|
||||
SSH_KEYTYPE_ECDSA_P256,
|
||||
SSH_KEYTYPE_ECDSA_P384,
|
||||
SSH_KEYTYPE_ECDSA_P521,
|
||||
SSH_KEYTYPE_ECDSA_P256_CERT01,
|
||||
SSH_KEYTYPE_ECDSA_P384_CERT01,
|
||||
SSH_KEYTYPE_ECDSA_P521_CERT01,
|
||||
SSH_KEYTYPE_ED25519_CERT01,
|
||||
SSH_KEYTYPE_RSA_CERT01
|
||||
};
|
||||
|
||||
enum ssh_keycmp_e {
|
||||
@@ -412,9 +405,6 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
||||
SSH_OPTIONS_NODELAY,
|
||||
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
SSH_OPTIONS_PROCESS_CONFIG,
|
||||
SSH_OPTIONS_REKEY_DATA,
|
||||
SSH_OPTIONS_REKEY_TIME,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -441,7 +431,6 @@ 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 */
|
||||
@@ -462,8 +451,6 @@ LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
|
||||
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport);
|
||||
LIBSSH_API int ssh_channel_open_forward_unix(ssh_channel channel, const char *remotepath,
|
||||
const char *sourcehost, int localport);
|
||||
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
|
||||
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
|
||||
@@ -556,11 +543,6 @@ SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, in
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_write_knownhost(ssh_session session);
|
||||
SSH_DEPRECATED LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_is_server_known(ssh_session session);
|
||||
SSH_DEPRECATED LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||
|
||||
|
||||
|
||||
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
||||
@@ -570,6 +552,7 @@ LIBSSH_API int ssh_get_poll_flags(ssh_session session);
|
||||
LIBSSH_API int ssh_init(void);
|
||||
LIBSSH_API int ssh_is_blocking(ssh_session session);
|
||||
LIBSSH_API int ssh_is_connected(ssh_session session);
|
||||
LIBSSH_API int ssh_is_server_known(ssh_session session);
|
||||
|
||||
/* KNOWN HOSTS */
|
||||
LIBSSH_API void ssh_knownhosts_entry_free(struct ssh_knownhosts_entry *entry);
|
||||
@@ -589,8 +572,9 @@ LIBSSH_API int ssh_session_export_known_hosts_entry(ssh_session session,
|
||||
char **pentry_string);
|
||||
LIBSSH_API int ssh_session_update_known_hosts(ssh_session session);
|
||||
|
||||
LIBSSH_API enum ssh_known_hosts_e ssh_session_get_known_hosts_entry(ssh_session session,
|
||||
struct ssh_knownhosts_entry **pentry);
|
||||
LIBSSH_API enum ssh_known_hosts_e
|
||||
ssh_session_get_known_hosts_entry(ssh_session session,
|
||||
struct ssh_knownhosts_entry **pentry);
|
||||
LIBSSH_API enum ssh_known_hosts_e ssh_session_is_known_server(ssh_session session);
|
||||
|
||||
/* LOGGING */
|
||||
@@ -608,10 +592,7 @@ SSH_DEPRECATED LIBSSH_API void ssh_log(ssh_session session,
|
||||
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||
|
||||
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
|
||||
LIBSSH_API int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);
|
||||
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
|
||||
#define SSH_MESSAGE_FREE(x) \
|
||||
do { if ((x) != NULL) { ssh_message_free(x); (x) = NULL; } } while(0)
|
||||
LIBSSH_API void ssh_message_free(ssh_message msg);
|
||||
LIBSSH_API ssh_message ssh_message_get(ssh_session session);
|
||||
LIBSSH_API int ssh_message_subtype(ssh_message msg);
|
||||
@@ -712,6 +693,7 @@ LIBSSH_API char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
|
||||
unsigned char *hash,
|
||||
size_t len);
|
||||
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
|
||||
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
|
||||
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
|
||||
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);
|
||||
@@ -778,6 +760,8 @@ LIBSSH_API int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i
|
||||
const char *answer);
|
||||
LIBSSH_API int ssh_userauth_gssapi(ssh_session session);
|
||||
LIBSSH_API const char *ssh_version(int req_version);
|
||||
LIBSSH_API int ssh_write_knownhost(ssh_session session);
|
||||
LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
|
||||
|
||||
LIBSSH_API void ssh_string_burn(ssh_string str);
|
||||
LIBSSH_API ssh_string ssh_string_copy(ssh_string str);
|
||||
|
||||
@@ -212,7 +212,7 @@ public:
|
||||
* @see ssh_userauth_kbdint
|
||||
*/
|
||||
int userauthKbdint(const char* username, const char* submethods){
|
||||
int ret = ssh_userauth_kbdint(c_session, username, submethods);
|
||||
int ret=ssh_userauth_kbdint(c_session,NULL,NULL);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -407,7 +407,7 @@ public:
|
||||
* @see ssh_write_knownhost
|
||||
*/
|
||||
int writeKnownhost(){
|
||||
int ret = ssh_session_update_known_hosts(c_session);
|
||||
int ret = ssh_write_knownhost(c_session);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request);
|
||||
|
||||
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
|
||||
const char *request, uint8_t want_reply);
|
||||
void ssh_message_queue(ssh_session session, ssh_message message);
|
||||
ssh_message ssh_message_pop_head(ssh_session session);
|
||||
int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);
|
||||
|
||||
#endif /* MESSAGES_H_ */
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
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);
|
||||
@@ -82,10 +81,4 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
||||
|
||||
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);
|
||||
|
||||
#endif /* MISC_H_ */
|
||||
|
||||
@@ -70,7 +70,6 @@ int ssh_packet_parse_type(ssh_session session);
|
||||
int ssh_packet_socket_callback(const void *data, size_t len, void *user);
|
||||
void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s);
|
||||
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
|
||||
void ssh_packet_remove_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
|
||||
void ssh_packet_set_default_callbacks(ssh_session session);
|
||||
void ssh_packet_process(ssh_session session, uint8_t type);
|
||||
|
||||
@@ -81,11 +80,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
|
||||
unsigned char *ssh_packet_encrypt(ssh_session session,
|
||||
void *packet,
|
||||
unsigned int len);
|
||||
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
|
||||
int ssh_packet_hmac_verify(ssh_session session,ssh_buffer buffer,
|
||||
unsigned char *mac, enum ssh_hmac_e type);
|
||||
int ssh_packet_set_newkeys(ssh_session session,
|
||||
enum ssh_crypto_direction_e direction);
|
||||
struct ssh_crypto_struct *ssh_packet_get_current_crypto(ssh_session session,
|
||||
enum ssh_crypto_direction_e direction);
|
||||
|
||||
#endif /* PACKET_H_ */
|
||||
|
||||
@@ -30,15 +30,7 @@
|
||||
#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 */
|
||||
@@ -52,30 +44,25 @@ struct ssh_key_struct {
|
||||
int flags;
|
||||
const char *type_c; /* Don't free it ! it is static */
|
||||
int ecdsa_nid;
|
||||
#if defined(HAVE_LIBGCRYPT)
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa;
|
||||
gcry_sexp_t rsa;
|
||||
gcry_sexp_t ecdsa;
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
mbedtls_pk_context *rsa;
|
||||
mbedtls_ecdsa_context *ecdsa;
|
||||
void *dsa;
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
#elif HAVE_LIBCRYPTO
|
||||
DSA *dsa;
|
||||
RSA *rsa;
|
||||
# if defined(HAVE_OPENSSL_ECC)
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
EC_KEY *ecdsa;
|
||||
# else
|
||||
void *ecdsa;
|
||||
# endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
#ifdef HAVE_OPENSSL_ED25519
|
||||
uint8_t *ed25519_pubkey;
|
||||
uint8_t *ed25519_privkey;
|
||||
#else
|
||||
void *ecdsa;
|
||||
#endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif
|
||||
ed25519_pubkey *ed25519_pubkey;
|
||||
ed25519_privkey *ed25519_privkey;
|
||||
#endif
|
||||
void *cert;
|
||||
enum ssh_keytypes_e cert_type;
|
||||
};
|
||||
@@ -84,18 +71,23 @@ struct ssh_signature_struct {
|
||||
enum ssh_keytypes_e type;
|
||||
enum ssh_digest_e hash_type;
|
||||
const char *type_c;
|
||||
#if defined(HAVE_LIBGCRYPT)
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa_sig;
|
||||
gcry_sexp_t rsa_sig;
|
||||
gcry_sexp_t ecdsa_sig;
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
DSA_SIG *dsa_sig;
|
||||
ssh_string rsa_sig;
|
||||
# ifdef HAVE_OPENSSL_ECC
|
||||
ECDSA_SIG *ecdsa_sig;
|
||||
# else
|
||||
void *ecdsa_sig;
|
||||
# endif
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
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;
|
||||
ed25519_signature *ed25519_sig;
|
||||
};
|
||||
|
||||
typedef struct ssh_signature_struct *ssh_signature;
|
||||
@@ -108,19 +100,6 @@ const char *
|
||||
ssh_key_get_signature_algorithm(ssh_session session,
|
||||
enum ssh_keytypes_e type);
|
||||
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
|
||||
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)
|
||||
|
||||
#define is_cert_type(kt)\
|
||||
((kt) == SSH_KEYTYPE_DSS_CERT01 ||\
|
||||
(kt) == SSH_KEYTYPE_RSA_CERT01 ||\
|
||||
((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
|
||||
(kt) <= SSH_KEYTYPE_ED25519_CERT01))
|
||||
|
||||
/* SSH Signature Functions */
|
||||
ssh_signature ssh_signature_new(void);
|
||||
@@ -131,11 +110,11 @@ int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
const ssh_key pubkey,
|
||||
ssh_signature *psig);
|
||||
int ssh_pki_signature_verify(ssh_session session,
|
||||
ssh_signature sig,
|
||||
const ssh_key key,
|
||||
const unsigned char *digest,
|
||||
size_t dlen);
|
||||
int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
ssh_string sig_blob,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
size_t dlen);
|
||||
|
||||
/* SSH Public Key Functions */
|
||||
int ssh_pki_export_pubkey_blob(const ssh_key key,
|
||||
@@ -149,13 +128,12 @@ int ssh_pki_import_cert_blob(const ssh_string cert_blob,
|
||||
|
||||
/* SSH Signing Functions */
|
||||
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
|
||||
const ssh_key privatekey, enum ssh_digest_e hash_type);
|
||||
const ssh_key privatekey);
|
||||
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 enum ssh_digest_e digest);
|
||||
const ssh_key privkey);
|
||||
|
||||
/* Temporary functions, to be removed after migration to ssh_key */
|
||||
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);
|
||||
|
||||
@@ -61,8 +61,6 @@ int pki_key_compare(const ssh_key k1,
|
||||
const ssh_key k2,
|
||||
enum ssh_keycmp_e what);
|
||||
|
||||
int pki_key_check_hash_compatible(ssh_key key,
|
||||
enum ssh_digest_e hash_type);
|
||||
/* SSH Private Key Functions */
|
||||
enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey);
|
||||
ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
@@ -111,29 +109,30 @@ int pki_privkey_build_ecdsa(ssh_key key,
|
||||
ssh_string pki_publickey_to_blob(const ssh_key key);
|
||||
|
||||
/* SSH Signature Functions */
|
||||
ssh_signature pki_sign_data(const ssh_key privkey,
|
||||
enum ssh_digest_e hash_type,
|
||||
const unsigned char *input,
|
||||
size_t input_len);
|
||||
int pki_verify_data_signature(ssh_signature signature,
|
||||
const ssh_key pubkey,
|
||||
const unsigned char *input,
|
||||
size_t input_len);
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
||||
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 *hash,
|
||||
size_t hlen);
|
||||
|
||||
/* SSH Signing Functions */
|
||||
ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
const unsigned char *input,
|
||||
size_t input_len,
|
||||
enum ssh_digest_e hash_type);
|
||||
#define pki_do_sign(key, hash, hlen) \
|
||||
pki_do_sign_hash(key, hash, hlen, SSH_DIGEST_AUTO)
|
||||
ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
||||
const unsigned char *hash,
|
||||
size_t hlen,
|
||||
enum ssh_digest_e hash_type);
|
||||
#define pki_do_sign_sessionid(key, hash, hlen) \
|
||||
pki_do_sign_sessionid_hash(key, hash, hlen, SSH_DIGEST_AUTO)
|
||||
ssh_signature pki_do_sign_sessionid_hash(const ssh_key key,
|
||||
const unsigned char *hash,
|
||||
size_t hlen,
|
||||
enum ssh_digest_e hash_type);
|
||||
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
|
||||
const unsigned char *hash, size_t hlen);
|
||||
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
|
||||
@@ -143,8 +142,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_signature_to_blob(ssh_signature sig);
|
||||
int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob);
|
||||
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
|
||||
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
|
||||
int pki_privkey_build_ed25519(ssh_key key,
|
||||
ssh_string pubkey,
|
||||
ssh_string privkey);
|
||||
|
||||
@@ -78,22 +78,6 @@ char *strndup(const char *s, size_t n);
|
||||
# endif /* __WORDSIZE */
|
||||
# endif /* PRIu64 */
|
||||
|
||||
# ifndef PRIu32
|
||||
# define PRIu32 "u"
|
||||
# endif /* PRIu32 */
|
||||
|
||||
# ifndef PRIx64
|
||||
# if __WORDSIZE == 64
|
||||
# define PRIx64 "lx"
|
||||
# else
|
||||
# define PRIx64 "llx"
|
||||
# endif /* __WORDSIZE */
|
||||
# endif /* PRIx64 */
|
||||
|
||||
# ifndef PRIx32
|
||||
# define PRIx32 "x"
|
||||
# endif /* PRIx32 */
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# include <stdio.h>
|
||||
# include <stdarg.h> /* va_copy define check */
|
||||
@@ -221,17 +205,7 @@ int gettimeofday(struct timeval *__p, void *__t);
|
||||
struct ssh_common_struct;
|
||||
struct ssh_kex_struct;
|
||||
|
||||
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);
|
||||
int ssh_get_key_params(ssh_session session, ssh_key *privkey);
|
||||
|
||||
/* LOGGING */
|
||||
void ssh_log_function(int verbosity,
|
||||
@@ -282,6 +256,8 @@ 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);
|
||||
|
||||
@@ -348,6 +324,7 @@ void explicit_bzero(void *s, size_t n);
|
||||
/**
|
||||
* Get the argument cound of variadic arguments
|
||||
*/
|
||||
#ifdef HAVE_GCC_NARG_MACRO
|
||||
/*
|
||||
* Since MSVC 2010 there is a bug in passing __VA_ARGS__ to subsequent
|
||||
* macros as a single token, which results in:
|
||||
@@ -357,7 +334,7 @@ void explicit_bzero(void *s, size_t n);
|
||||
#define VA_APPLY_VARIADIC_MACRO(macro, tuple) macro tuple
|
||||
|
||||
#define __VA_NARG__(...) \
|
||||
(__VA_NARG_(__VA_ARGS__, __RSEQ_N()))
|
||||
(__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
|
||||
#define __VA_NARG_(...) \
|
||||
VA_APPLY_VARIADIC_MACRO(__VA_ARG_N, (__VA_ARGS__))
|
||||
#define __VA_ARG_N( \
|
||||
@@ -376,6 +353,10 @@ void explicit_bzero(void *s, size_t n);
|
||||
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
|
||||
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
|
||||
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
#else
|
||||
/* clang does not support the above construction */
|
||||
#define __VA_NARG__(...) (-1)
|
||||
#endif
|
||||
|
||||
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
|
||||
|
||||
@@ -405,22 +386,6 @@ void explicit_bzero(void *s, size_t n);
|
||||
# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
|
||||
#endif /* FALL_THROUGH */
|
||||
|
||||
#ifndef __unused__
|
||||
# ifdef HAVE_UNUSED_ATTRIBUTE
|
||||
# define __unused__ __attribute__((unused))
|
||||
# else /* HAVE_UNUSED_ATTRIBUTE */
|
||||
# define __unused__
|
||||
# endif /* HAVE_UNUSED_ATTRIBUTE */
|
||||
#endif /* __unused__ */
|
||||
|
||||
#ifndef UNUSED_PARAM
|
||||
#define UNUSED_PARAM(param) param __unused__
|
||||
#endif /* UNUSED_PARAM */
|
||||
|
||||
#ifndef UNUSED_VAR
|
||||
#define UNUSED_VAR(var) __unused__ var
|
||||
#endif /* UNUSED_VAR */
|
||||
|
||||
void ssh_agent_state_free(void *data);
|
||||
|
||||
#endif /* _LIBSSH_PRIV_H */
|
||||
|
||||
@@ -46,16 +46,7 @@ enum ssh_bind_options_e {
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY,
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
||||
SSH_BIND_OPTIONS_ECDSAKEY,
|
||||
SSH_BIND_OPTIONS_IMPORT_KEY,
|
||||
SSH_BIND_OPTIONS_KEY_EXCHANGE,
|
||||
SSH_BIND_OPTIONS_CIPHERS_C_S,
|
||||
SSH_BIND_OPTIONS_CIPHERS_S_C,
|
||||
SSH_BIND_OPTIONS_HMAC_C_S,
|
||||
SSH_BIND_OPTIONS_HMAC_S_C,
|
||||
SSH_BIND_OPTIONS_CONFIG_DIR,
|
||||
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES,
|
||||
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS,
|
||||
SSH_BIND_OPTIONS_PROCESS_CONFIG,
|
||||
SSH_BIND_OPTIONS_IMPORT_KEY
|
||||
};
|
||||
|
||||
typedef struct ssh_bind_struct* ssh_bind;
|
||||
@@ -94,9 +85,6 @@ LIBSSH_API ssh_bind ssh_bind_new(void);
|
||||
LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind,
|
||||
enum ssh_bind_options_e type, const void *value);
|
||||
|
||||
LIBSSH_API int ssh_bind_options_parse_config(ssh_bind sshbind,
|
||||
const char *filename);
|
||||
|
||||
/**
|
||||
* @brief Start listening to the socket.
|
||||
*
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
|
||||
#ifndef SESSION_H_
|
||||
#define SESSION_H_
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/packet.h"
|
||||
@@ -29,8 +27,6 @@
|
||||
#include "libssh/auth.h"
|
||||
#include "libssh/channels.h"
|
||||
#include "libssh/poll.h"
|
||||
#include "libssh/config.h"
|
||||
#include "libssh/misc.h"
|
||||
|
||||
/* These are the different states a SSH session can be into its life */
|
||||
enum ssh_session_state_e {
|
||||
@@ -49,8 +45,6 @@ enum ssh_session_state_e {
|
||||
|
||||
enum ssh_dh_state_e {
|
||||
DH_STATE_INIT=0,
|
||||
DH_STATE_GROUP_SENT,
|
||||
DH_STATE_REQUEST_SENT,
|
||||
DH_STATE_INIT_SENT,
|
||||
DH_STATE_NEWKEYS_SENT,
|
||||
DH_STATE_FINISHED
|
||||
@@ -93,11 +87,10 @@ enum ssh_pending_call_e {
|
||||
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
|
||||
|
||||
/* extensions flags */
|
||||
/* negotiation enabled */
|
||||
#define SSH_EXT_NEGOTIATION 0x01
|
||||
/* server-sig-algs extension */
|
||||
#define SSH_EXT_SIG_RSA_SHA256 0x02
|
||||
#define SSH_EXT_SIG_RSA_SHA512 0x04
|
||||
#define SSH_EXT_SIG_RSA_SHA256 0x01
|
||||
#define SSH_EXT_SIG_RSA_SHA512 0x02
|
||||
#define SSH_EXT_ALL SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512
|
||||
|
||||
/* members that are common to ssh_session and ssh_bind */
|
||||
struct ssh_common_struct {
|
||||
@@ -117,7 +110,6 @@ struct ssh_session_struct {
|
||||
int openssh;
|
||||
uint32_t send_seq;
|
||||
uint32_t recv_seq;
|
||||
struct ssh_timestamp last_rekey_time;
|
||||
|
||||
int connected;
|
||||
/* !=0 when the user got a session handle */
|
||||
@@ -138,8 +130,6 @@ struct ssh_session_struct {
|
||||
ssh_buffer in_buffer;
|
||||
PACKET in_packet;
|
||||
ssh_buffer out_buffer;
|
||||
struct ssh_list *out_queue; /* This list is used for delaying packets
|
||||
when rekeying is required */
|
||||
|
||||
/* the states are used by the nonblocking stuff to remember */
|
||||
/* where it was before being interrupted */
|
||||
@@ -174,6 +164,8 @@ struct ssh_session_struct {
|
||||
|
||||
struct ssh_list *channels; /* linked list of channels */
|
||||
int maxchannel;
|
||||
int exec_channel_opened; /* version 1 only. more
|
||||
info in channels1.c */
|
||||
ssh_agent agent; /* ssh agent */
|
||||
|
||||
/* keyb interactive data */
|
||||
@@ -188,7 +180,6 @@ 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 */
|
||||
@@ -228,10 +219,6 @@ struct ssh_session_struct {
|
||||
int gss_delegate_creds;
|
||||
int flags;
|
||||
int nodelay;
|
||||
bool config_processed;
|
||||
uint8_t options_seen[SOC_MAX];
|
||||
uint64_t rekey_data;
|
||||
uint32_t rekey_time;
|
||||
} opts;
|
||||
/* counters */
|
||||
ssh_counter socket_counter;
|
||||
@@ -245,10 +232,8 @@ struct ssh_session_struct {
|
||||
*/
|
||||
typedef int (*ssh_termination_function)(void *user);
|
||||
int ssh_handle_packets(ssh_session session, int timeout);
|
||||
int ssh_handle_packets_termination(ssh_session session,
|
||||
long timeout,
|
||||
ssh_termination_function fct,
|
||||
void *user);
|
||||
int ssh_handle_packets_termination(ssh_session session, int timeout,
|
||||
ssh_termination_function fct, void *user);
|
||||
void ssh_socket_exception_callback(int code, int errno_code, void *user);
|
||||
|
||||
#endif /* SESSION_H_ */
|
||||
|
||||
@@ -201,18 +201,13 @@ struct sftp_statvfs_struct {
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @brief Start a new sftp session.
|
||||
*
|
||||
* @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);
|
||||
|
||||
@@ -237,10 +232,7 @@ 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 protocol with the server.
|
||||
*
|
||||
* This function involves the SFTP protocol initialization (as described
|
||||
* in the SFTP specification), including the version and extensions negotiation.
|
||||
* @brief Initialize the sftp session with the server.
|
||||
*
|
||||
* @param sftp The sftp session to initialize.
|
||||
*
|
||||
@@ -826,9 +818,7 @@ LIBSSH_API int sftp_fsync(sftp_file file);
|
||||
*
|
||||
* @param path The path to be canonicalized.
|
||||
*
|
||||
* @return A pointer to the newly allocated canonicalized path,
|
||||
* NULL on error. The caller needs to free the memory
|
||||
* using ssh_string_free_char().
|
||||
* @return The canonicalize path, NULL on error.
|
||||
*/
|
||||
LIBSSH_API char *sftp_canonicalize_path(sftp_session sftp, const char *path);
|
||||
|
||||
@@ -861,13 +851,6 @@ LIBSSH_API sftp_session sftp_server_new(ssh_session session, ssh_channel chan);
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
LIBSSH_API int sftp_server_init(sftp_session sftp);
|
||||
|
||||
/**
|
||||
* @brief Close and deallocate a sftp server session.
|
||||
*
|
||||
* @param sftp The sftp session handle to free.
|
||||
*/
|
||||
LIBSSH_API void sftp_server_free(sftp_session sftp);
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
/* this is not a public interface */
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* token.h - Tokens list handling
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2019 by Red Hat, Inc.
|
||||
*
|
||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TOKEN_H_
|
||||
#define TOKEN_H_
|
||||
|
||||
struct ssh_tokens_st {
|
||||
char *buffer;
|
||||
char **tokens;
|
||||
};
|
||||
|
||||
struct ssh_tokens_st *ssh_tokenize(const char *chain, char separator);
|
||||
|
||||
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_ */
|
||||
@@ -21,28 +21,33 @@
|
||||
#ifndef WRAPPER_H_
|
||||
#define WRAPPER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/libcrypto.h"
|
||||
#include "libssh/libgcrypt.h"
|
||||
#include "libssh/libmbedcrypto.h"
|
||||
|
||||
enum ssh_kdf_digest {
|
||||
SSH_KDF_SHA1=1,
|
||||
SSH_KDF_SHA256,
|
||||
SSH_KDF_SHA384,
|
||||
SSH_KDF_SHA512
|
||||
enum ssh_digest_e {
|
||||
SSH_DIGEST_AUTO=0,
|
||||
SSH_DIGEST_SHA1=1,
|
||||
SSH_DIGEST_SHA256,
|
||||
SSH_DIGEST_SHA512
|
||||
};
|
||||
|
||||
enum ssh_mac_e {
|
||||
SSH_MAC_SHA1=1,
|
||||
SSH_MAC_SHA256,
|
||||
SSH_MAC_SHA384,
|
||||
SSH_MAC_SHA512
|
||||
};
|
||||
|
||||
enum ssh_hmac_e {
|
||||
SSH_HMAC_SHA1 = 1,
|
||||
SSH_HMAC_SHA256,
|
||||
SSH_HMAC_SHA384,
|
||||
SSH_HMAC_SHA512,
|
||||
SSH_HMAC_MD5,
|
||||
SSH_HMAC_AEAD_POLY1305,
|
||||
SSH_HMAC_AEAD_GCM
|
||||
SSH_HMAC_AEAD_POLY1305
|
||||
};
|
||||
|
||||
enum ssh_des_e {
|
||||
@@ -53,17 +58,9 @@ enum ssh_des_e {
|
||||
struct ssh_hmac_struct {
|
||||
const char* name;
|
||||
enum ssh_hmac_e hmac_type;
|
||||
bool etm;
|
||||
};
|
||||
|
||||
enum ssh_crypto_direction_e {
|
||||
SSH_DIRECTION_IN = 1,
|
||||
SSH_DIRECTION_OUT = 2,
|
||||
SSH_DIRECTION_BOTH = 3,
|
||||
};
|
||||
|
||||
struct ssh_cipher_struct;
|
||||
struct ssh_crypto_struct;
|
||||
|
||||
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
|
||||
MD5CTX md5_init(void);
|
||||
@@ -73,38 +70,37 @@ void md5_final(unsigned char *md,MD5CTX c);
|
||||
SHACTX sha1_init(void);
|
||||
void sha1_update(SHACTX c, const void *data, unsigned long len);
|
||||
void sha1_final(unsigned char *md,SHACTX c);
|
||||
void sha1(const unsigned char *digest,int len,unsigned char *hash);
|
||||
void sha1(unsigned char *digest,int len,unsigned char *hash);
|
||||
|
||||
SHA256CTX sha256_init(void);
|
||||
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
|
||||
void sha256_final(unsigned char *md,SHA256CTX c);
|
||||
void sha256(const unsigned char *digest, int len, unsigned char *hash);
|
||||
void sha256(unsigned char *digest, int len, unsigned char *hash);
|
||||
|
||||
SHA384CTX sha384_init(void);
|
||||
void sha384_update(SHA384CTX c, const void *data, unsigned long len);
|
||||
void sha384_final(unsigned char *md,SHA384CTX c);
|
||||
void sha384(const unsigned char *digest, int len, unsigned char *hash);
|
||||
void sha384(unsigned char *digest, int len, unsigned char *hash);
|
||||
|
||||
SHA512CTX sha512_init(void);
|
||||
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
|
||||
void sha512_final(unsigned char *md,SHA512CTX c);
|
||||
void sha512(const unsigned char *digest, int len, unsigned char *hash);
|
||||
void sha512(unsigned char *digest, int len, unsigned char *hash);
|
||||
|
||||
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
|
||||
EVPCTX evp_init(int nid);
|
||||
void evp_update(EVPCTX ctx, const void *data, unsigned long len);
|
||||
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
|
||||
|
||||
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type);
|
||||
void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len);
|
||||
void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx);
|
||||
|
||||
HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
|
||||
void hmac_update(HMACCTX c, const void *data, unsigned long len);
|
||||
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
|
||||
size_t hmac_digest_len(enum ssh_hmac_e type);
|
||||
|
||||
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||
unsigned char *key, size_t key_len,
|
||||
int key_type, unsigned char *output,
|
||||
size_t requested_len);
|
||||
|
||||
int crypt_set_algorithms_client(ssh_session session);
|
||||
int crypt_set_algorithms_server(ssh_session session);
|
||||
struct ssh_crypto_struct *crypto_new(void);
|
||||
@@ -117,6 +113,6 @@ void ssh_crypto_finalize(void);
|
||||
void ssh_cipher_clear(struct ssh_cipher_struct *cipher);
|
||||
struct ssh_hmac_struct *ssh_get_hmactab(void);
|
||||
struct ssh_cipher_struct *ssh_get_ciphertab(void);
|
||||
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type, bool etm);
|
||||
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type);
|
||||
|
||||
#endif /* WRAPPER_H_ */
|
||||
|
||||
1
libssh-build-tree-settings.cmake.in
Normal file
1
libssh-build-tree-settings.cmake.in
Normal file
@@ -0,0 +1 @@
|
||||
set(LIBSSH_INLUDE_DIR @PROJECT_SOURCE_DIR@/include)
|
||||
11
libssh-config-version.cmake.in
Normal file
11
libssh-config-version.cmake.in
Normal file
@@ -0,0 +1,11 @@
|
||||
set(PACKAGE_VERSION @PROJECT_VERSION@)
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
15
libssh-config.cmake.in
Normal file
15
libssh-config.cmake.in
Normal file
@@ -0,0 +1,15 @@
|
||||
get_filename_component(LIBSSH_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
if (EXISTS "${LIBSSH_CMAKE_DIR}/CMakeCache.txt")
|
||||
# In build tree
|
||||
include(${LIBSSH_CMAKE_DIR}/libssh-build-tree-settings.cmake)
|
||||
else()
|
||||
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
|
||||
endif()
|
||||
|
||||
set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
|
||||
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@)
|
||||
|
||||
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_INCLUDE_DIR)
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: ${PROJECT_NAME}
|
||||
Description: The SSH Library
|
||||
Version: ${PROJECT_VERSION}
|
||||
Libs: -L${CMAKE_INSTALL_FULL_LIBDIR} -lssh
|
||||
Cflags: -I${CMAKE_INSTALL_FULL_INCLUDEDIR}
|
||||
Libs: -L${LIB_INSTALL_DIR} -lssh
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}
|
||||
|
||||
|
||||
200
obj/build_make.sh
Executable file
200
obj/build_make.sh
Executable file
@@ -0,0 +1,200 @@
|
||||
#!/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.3
|
||||
4.7.2
|
||||
@@ -1,415 +0,0 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
@@ -1,415 +0,0 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
@@ -1,419 +0,0 @@
|
||||
_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_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
@@ -1,421 +0,0 @@
|
||||
_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,421 +0,0 @@
|
||||
_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,421 +0,0 @@
|
||||
_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,4 +1,7 @@
|
||||
set(LIBSSH_PUBLIC_INCLUDE_DIRS ${libssh_SOURCE_DIR}/include)
|
||||
set(LIBSSH_PUBLIC_INCLUDE_DIRS
|
||||
${libssh_SOURCE_DIR}/include
|
||||
CACHE INTERNAL "libssh public include directories"
|
||||
)
|
||||
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${libssh_BINARY_DIR}
|
||||
@@ -15,6 +18,13 @@ if (WIN32)
|
||||
)
|
||||
endif (WIN32)
|
||||
|
||||
if (HAVE_LIBSOCKET)
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
socket
|
||||
)
|
||||
endif (HAVE_LIBSOCKET)
|
||||
|
||||
if (OPENSSL_CRYPTO_LIBRARY)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
@@ -38,7 +48,7 @@ if (MBEDTLS_CRYPTO_LIBRARY)
|
||||
)
|
||||
endif (MBEDTLS_CRYPTO_LIBRARY)
|
||||
|
||||
if (GCRYPT_LIBRARIES)
|
||||
if (GCRYPT_LIBRARY)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
${GCRYPT_INCLUDE_DIR}
|
||||
@@ -46,8 +56,9 @@ if (GCRYPT_LIBRARIES)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${GCRYPT_LIBRARIES})
|
||||
endif()
|
||||
${GCRYPT_LIBRARY}
|
||||
)
|
||||
endif (GCRYPT_LIBRARY)
|
||||
|
||||
if (WITH_ZLIB)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
@@ -85,6 +96,16 @@ 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 (BUILD_STATIC_LIB)
|
||||
set(LIBSSH_STATIC_LIBRARY
|
||||
ssh_static
|
||||
@@ -110,7 +131,6 @@ set(libssh_SRCS
|
||||
error.c
|
||||
getpass.c
|
||||
init.c
|
||||
kdf.c
|
||||
kex.c
|
||||
known_hosts.c
|
||||
knownhosts.c
|
||||
@@ -126,6 +146,7 @@ set(libssh_SRCS
|
||||
pcap.c
|
||||
pki.c
|
||||
pki_container_openssh.c
|
||||
pki_ed25519.c
|
||||
poll.c
|
||||
session.c
|
||||
scp.c
|
||||
@@ -136,19 +157,14 @@ 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)
|
||||
set_source_files_properties(known_hosts.c
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS ${DEFAULT_C_NO_DEPRECATION_FLAGS})
|
||||
endif()
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
@@ -176,12 +192,6 @@ if (WITH_GCRYPT)
|
||||
gcrypt_missing.c
|
||||
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
|
||||
@@ -191,12 +201,6 @@ elseif (WITH_MBEDTLS)
|
||||
mbedcrypto_missing.c
|
||||
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
|
||||
@@ -205,18 +209,7 @@ else (WITH_GCRYPT)
|
||||
pki_crypto.c
|
||||
ecdh_crypto.c
|
||||
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()
|
||||
@@ -241,17 +234,9 @@ if (WITH_SERVER)
|
||||
${libssh_SRCS}
|
||||
server.c
|
||||
bind.c
|
||||
bind_config.c
|
||||
)
|
||||
endif (WITH_SERVER)
|
||||
|
||||
if (WITH_GEX)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
dh-gex.c
|
||||
)
|
||||
endif (WITH_GEX)
|
||||
|
||||
if (WITH_ZLIB)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
@@ -267,14 +252,17 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
|
||||
if (NOT WITH_NACL)
|
||||
if (NOT HAVE_OPENSSL_ED25519)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
external/curve25519_ref.c
|
||||
)
|
||||
endif (NOT HAVE_OPENSSL_ED25519)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
external/curve25519_ref.c
|
||||
)
|
||||
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")
|
||||
|
||||
@@ -306,23 +294,10 @@ if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
|
||||
)
|
||||
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
|
||||
|
||||
# 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})
|
||||
add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS})
|
||||
target_compile_options(${LIBSSH_SHARED_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
target_link_libraries(ssh
|
||||
PRIVATE ${LIBSSH_LINK_LIBRARIES})
|
||||
|
||||
add_library(ssh::ssh ALIAS ssh)
|
||||
target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
|
||||
|
||||
if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
|
||||
if (ABIMAP_FOUND)
|
||||
@@ -330,55 +305,45 @@ 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(ssh
|
||||
set_target_properties(${LIBSSH_SHARED_LIBRARY}
|
||||
PROPERTIES LINK_FLAGS
|
||||
"-Wl,--version-script,\"${MAP_PATH}\"")
|
||||
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
|
||||
|
||||
set_target_properties(ssh
|
||||
set_target_properties(
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh
|
||||
DEFINE_SYMBOL
|
||||
LIBSSH_EXPORTS
|
||||
)
|
||||
|
||||
if (WITH_VISIBILITY_HIDDEN)
|
||||
set_target_properties(ssh PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
endif (WITH_VISIBILITY_HIDDEN)
|
||||
|
||||
if (MINGW)
|
||||
set_target_properties(ssh PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
|
||||
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
|
||||
endif ()
|
||||
|
||||
|
||||
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})
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
COMPONENT libraries
|
||||
)
|
||||
|
||||
if (BUILD_STATIC_LIB)
|
||||
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)
|
||||
add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS})
|
||||
target_compile_options(${LIBSSH_STATIC_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
if (MSVC)
|
||||
set(OUTPUT_SUFFIX static)
|
||||
@@ -386,7 +351,7 @@ if (BUILD_STATIC_LIB)
|
||||
set(OUTPUT_SUFFIX )
|
||||
endif (MSVC)
|
||||
set_target_properties(
|
||||
ssh-static
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
@@ -400,12 +365,21 @@ if (BUILD_STATIC_LIB)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(
|
||||
ssh-static
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"-DLIBSSH_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}")
|
||||
|
||||
41
src/agent.c
41
src/agent.c
@@ -56,13 +56,33 @@
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/poll.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bytearray.h"
|
||||
|
||||
/* macro to check for "agent failure" message */
|
||||
#define agent_failed(x) \
|
||||
(((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
|
||||
((x) == SSH2_AGENT_FAILURE))
|
||||
|
||||
static uint32_t agent_get_u32(const void *vp) {
|
||||
const uint8_t *p = (const uint8_t *)vp;
|
||||
uint32_t v;
|
||||
|
||||
v = (uint32_t)p[0] << 24;
|
||||
v |= (uint32_t)p[1] << 16;
|
||||
v |= (uint32_t)p[2] << 8;
|
||||
v |= (uint32_t)p[3];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void agent_put_u32(void *vp, uint32_t v) {
|
||||
uint8_t *p = (uint8_t *)vp;
|
||||
|
||||
p[0] = (uint8_t)(v >> 24) & 0xff;
|
||||
p[1] = (uint8_t)(v >> 16) & 0xff;
|
||||
p[2] = (uint8_t)(v >> 8) & 0xff;
|
||||
p[3] = (uint8_t)v & 0xff;
|
||||
}
|
||||
|
||||
static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int do_read) {
|
||||
char *b = buf;
|
||||
size_t pos = 0;
|
||||
@@ -255,7 +275,7 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
|
||||
len = ssh_buffer_get_len(request);
|
||||
SSH_LOG(SSH_LOG_TRACE, "Request length: %u", len);
|
||||
PUSH_BE_U32(payload, 0, len);
|
||||
agent_put_u32(payload, len);
|
||||
|
||||
/* send length and then the request packet */
|
||||
if (atomicio(session->agent, payload, 4, 0) == 4) {
|
||||
@@ -279,7 +299,7 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = PULL_BE_U32(payload, 0);
|
||||
len = agent_get_u32(payload);
|
||||
if (len > 256 * 1024) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Authentication response too long: %u", len);
|
||||
@@ -311,7 +331,7 @@ 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;
|
||||
uint32_t buf[1] = {0};
|
||||
int rc;
|
||||
|
||||
/* send message to the agent requesting the list of identities */
|
||||
@@ -366,15 +386,8 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
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 -1;
|
||||
}
|
||||
session->agent->count = ntohl(count);
|
||||
ssh_buffer_get_u32(reply, (uint32_t *) buf);
|
||||
session->agent->count = agent_get_u32(buf);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
|
||||
session->agent->count);
|
||||
if (session->agent->count > 1024) {
|
||||
@@ -536,7 +549,7 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
}
|
||||
|
||||
/* Add Flags: SHA2 extension (RFC 8332) if negotiated */
|
||||
if (ssh_key_type_plain(pubkey->type) == SSH_KEYTYPE_RSA) {
|
||||
if (pubkey->type == SSH_KEYTYPE_RSA) {
|
||||
if (session->extensions & SSH_EXT_SIG_RSA_SHA512) {
|
||||
flags |= SSH_AGENT_RSA_SHA2_512;
|
||||
} else if (session->extensions & SSH_EXT_SIG_RSA_SHA256) {
|
||||
|
||||
78
src/auth.c
78
src/auth.c
@@ -25,7 +25,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -70,7 +69,7 @@ static int ssh_userauth_request_service(ssh_session session) {
|
||||
int rc;
|
||||
|
||||
rc = ssh_service_request(session, "ssh-userauth");
|
||||
if ((rc != SSH_OK) && (rc != SSH_AGAIN)) {
|
||||
if (rc != SSH_OK) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Failed to request \"ssh-userauth\" service");
|
||||
}
|
||||
@@ -283,10 +282,7 @@ end:
|
||||
*
|
||||
* It is also used to communicate the new to the upper levels.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_success)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto = NULL;
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
|
||||
(void)packet;
|
||||
(void)type;
|
||||
(void)user;
|
||||
@@ -298,16 +294,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success)
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
|
||||
|
||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
|
||||
if (crypto != NULL && crypto->delayed_compress_out) {
|
||||
if (session->current_crypto && session->current_crypto->delayed_compress_out) {
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression OUT");
|
||||
crypto->do_compress_out = 1;
|
||||
session->current_crypto->do_compress_out = 1;
|
||||
}
|
||||
|
||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||
if (crypto != NULL && crypto->delayed_compress_in) {
|
||||
if (session->current_crypto && session->current_crypto->delayed_compress_in) {
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression IN");
|
||||
crypto->do_compress_in = 1;
|
||||
session->current_crypto->do_compress_in = 1;
|
||||
}
|
||||
|
||||
/* Reset errors by previous authentication methods. */
|
||||
@@ -516,13 +509,26 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Check if the given public key algorithm is allowed */
|
||||
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
|
||||
if (sig_type_c == NULL) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
switch (pubkey->type) {
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"Invalid key type (unknown)");
|
||||
return SSH_AUTH_DENIED;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
sig_type_c = ssh_pki_key_ecdsa_name(pubkey);
|
||||
break;
|
||||
case SSH_KEYTYPE_DSS:
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if the given public key algorithm is allowed */
|
||||
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The key algorithm '%s' is not allowed to be used by"
|
||||
@@ -614,7 +620,6 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
int rc;
|
||||
const char *sig_type_c = NULL;
|
||||
enum ssh_keytypes_e key_type;
|
||||
enum ssh_digest_e hash_type;
|
||||
|
||||
if (session == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
@@ -640,13 +645,26 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
|
||||
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
|
||||
|
||||
/* Check if the given public key algorithm is allowed */
|
||||
sig_type_c = ssh_key_get_signature_algorithm(session, key_type);
|
||||
if (sig_type_c == NULL) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
switch (key_type) {
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"Invalid key type (unknown)");
|
||||
return SSH_AUTH_DENIED;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
sig_type_c = ssh_pki_key_ecdsa_name(privkey);
|
||||
break;
|
||||
case SSH_KEYTYPE_DSS:
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
sig_type_c = ssh_key_get_signature_algorithm(session, key_type);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if the given public key algorithm is allowed */
|
||||
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The key algorithm '%s' is not allowed to be used by"
|
||||
@@ -683,11 +701,8 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
}
|
||||
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);
|
||||
|
||||
/* sign the buffer with the private key */
|
||||
str = ssh_pki_do_sign(session, session->out_buffer, privkey, hash_type);
|
||||
str = ssh_pki_do_sign(session, session->out_buffer, privkey);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -756,15 +771,9 @@ static int ssh_userauth_agent_publickey(ssh_session session,
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
|
||||
|
||||
/* Check if the given public key algorithm is allowed */
|
||||
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
|
||||
if (sig_type_c == NULL) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Invalid key type (unknown)");
|
||||
SSH_STRING_FREE(pubkey_s);
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"The key algorithm '%s' is not allowed to be used by"
|
||||
@@ -1262,9 +1271,6 @@ int ssh_userauth_password(ssh_session session,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set the buffer as secure to be explicitly zeroed when freed */
|
||||
ssh_buffer_set_secure(session->out_buffer);
|
||||
|
||||
session->auth.current_method = SSH_AUTH_METHOD_PASSWORD;
|
||||
session->auth.state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT;
|
||||
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
|
||||
|
||||
67
src/bignum.c
67
src/bignum.c
@@ -56,39 +56,70 @@ ssh_string ssh_make_bignum_string(bignum num) {
|
||||
ptr->data[0] = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bn2bin(num, len, ptr->data + pad);
|
||||
#elif HAVE_LIBCRYPTO
|
||||
bignum_bn2bin(num, ptr->data + pad);
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
bignum_bn2bin(num, ptr->data + pad);
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bignum ssh_make_string_bn(ssh_string string)
|
||||
{
|
||||
bignum bn = NULL;
|
||||
size_t len = ssh_string_len(string);
|
||||
bignum ssh_make_string_bn(ssh_string string){
|
||||
bignum bn = NULL;
|
||||
unsigned int len = ssh_string_len(string);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "Importing a %zu bits, %zu bytes object ...\n",
|
||||
len * 8, len);
|
||||
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
|
||||
len * 8, len);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
bignum_bin2bn(string->data, len, &bn);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bin2bn(string->data, len, &bn);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bn = bignum_bin2bn(string->data, len, NULL);
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
bn = bignum_new();
|
||||
bignum_bin2bn(string->data, len, bn);
|
||||
#endif
|
||||
|
||||
return bn;
|
||||
return bn;
|
||||
}
|
||||
|
||||
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout) {
|
||||
unsigned int len = ssh_string_len(string);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
/* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */
|
||||
(void) len;
|
||||
(void) bnout;
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bignum_bin2bn(string->data, len, bnout);
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
bignum_bin2bn(string->data, len, bnout);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* prints the bignum on stderr */
|
||||
void ssh_print_bignum(const char *name, const_bignum num)
|
||||
{
|
||||
unsigned char *hex = NULL;
|
||||
if (num != NULL) {
|
||||
bignum_bn2hex(num, &hex);
|
||||
}
|
||||
fprintf(stderr, "%s value: %s\n", name, (hex == NULL) ? "(null)" : (char *) hex);
|
||||
void ssh_print_bignum(const char *which, const bignum num) {
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
SAFE_FREE(hex);
|
||||
unsigned char *hex = NULL;
|
||||
bignum_bn2hex(num, &hex);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
OPENSSL_free(hex);
|
||||
char *hex = NULL;
|
||||
hex = bignum_bn2hex(num);
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
SAFE_FREE(hex);
|
||||
char *hex = NULL;
|
||||
hex = bignum_bn2hex(num);
|
||||
#endif
|
||||
fprintf(stderr, "%s value: ", which);
|
||||
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
SAFE_FREE(hex);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
OPENSSL_free(hex);
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
SAFE_FREE(hex);
|
||||
#endif
|
||||
}
|
||||
|
||||
82
src/bind.c
82
src/bind.c
@@ -38,7 +38,6 @@
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/socket.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/token.h"
|
||||
|
||||
/**
|
||||
* @addtogroup libssh_server
|
||||
@@ -131,17 +130,18 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
|
||||
}
|
||||
|
||||
ssh_bind ssh_bind_new(void) {
|
||||
ssh_bind ptr;
|
||||
ssh_bind ptr;
|
||||
|
||||
ptr = calloc(1, sizeof(struct ssh_bind_struct));
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr->bindfd = SSH_INVALID_SOCKET;
|
||||
ptr->bindport = 22;
|
||||
ptr->common.log_verbosity = 0;
|
||||
ptr = malloc(sizeof(struct ssh_bind_struct));
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(ptr);
|
||||
ptr->bindfd = SSH_INVALID_SOCKET;
|
||||
ptr->bindport= 22;
|
||||
ptr->common.log_verbosity = 0;
|
||||
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int ssh_bind_import_keys(ssh_bind sshbind) {
|
||||
@@ -169,7 +169,7 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (!is_ecdsa_key_type(ssh_key_type(sshbind->ecdsa))) {
|
||||
if (ssh_key_type(sshbind->ecdsa) != SSH_KEYTYPE_ECDSA) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"The ECDSA host key has the wrong type");
|
||||
ssh_key_free(sshbind->ecdsa);
|
||||
@@ -343,24 +343,12 @@ static int ssh_bind_poll_callback(ssh_poll_handle sshpoll,
|
||||
* @param sshbind the ssh_bind object
|
||||
* @returns a ssh_poll handle suitable for operation
|
||||
*/
|
||||
ssh_poll_handle ssh_bind_get_poll(ssh_bind sshbind)
|
||||
{
|
||||
short events = POLLIN;
|
||||
|
||||
if (sshbind->poll) {
|
||||
return sshbind->poll;
|
||||
}
|
||||
|
||||
#ifdef POLLRDHUP
|
||||
events |= POLLRDHUP;
|
||||
#endif /* POLLRDHUP */
|
||||
|
||||
sshbind->poll = ssh_poll_new(sshbind->bindfd,
|
||||
events,
|
||||
ssh_bind_poll_callback,
|
||||
sshbind);
|
||||
|
||||
ssh_poll_handle ssh_bind_get_poll(ssh_bind sshbind){
|
||||
if(sshbind->poll)
|
||||
return sshbind->poll;
|
||||
sshbind->poll=ssh_poll_new(sshbind->bindfd,POLLIN,
|
||||
ssh_bind_poll_callback,sshbind);
|
||||
return sshbind->poll;
|
||||
}
|
||||
|
||||
void ssh_bind_set_blocking(ssh_bind sshbind, int blocking) {
|
||||
@@ -394,8 +382,6 @@ void ssh_bind_free(ssh_bind sshbind){
|
||||
/* options */
|
||||
SAFE_FREE(sshbind->banner);
|
||||
SAFE_FREE(sshbind->bindaddr);
|
||||
SAFE_FREE(sshbind->config_dir);
|
||||
SAFE_FREE(sshbind->pubkey_accepted_key_types);
|
||||
|
||||
SAFE_FREE(sshbind->dsakey);
|
||||
SAFE_FREE(sshbind->rsakey);
|
||||
@@ -423,25 +409,14 @@ void ssh_bind_free(ssh_bind sshbind){
|
||||
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
int i, rc;
|
||||
|
||||
if (sshbind == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (session == NULL){
|
||||
ssh_set_error(sshbind, SSH_FATAL,"session is null");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Apply global bind configurations, if it hasn't been applied before */
|
||||
rc = ssh_bind_options_parse_config(sshbind, NULL);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,"Could not parse global config");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session->server = 1;
|
||||
|
||||
/* Copy options from bind to session */
|
||||
/* copy options */
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (sshbind->wanted_methods[i]) {
|
||||
session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
|
||||
@@ -461,29 +436,6 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
}
|
||||
}
|
||||
|
||||
if (sshbind->pubkey_accepted_key_types != NULL) {
|
||||
if (session->opts.pubkey_accepted_types == NULL) {
|
||||
session->opts.pubkey_accepted_types = strdup(sshbind->pubkey_accepted_key_types);
|
||||
if (session->opts.pubkey_accepted_types == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
} else {
|
||||
char *p;
|
||||
/* If something was set to the session prior to calling this
|
||||
* function, keep only what is allowed by the options set in
|
||||
* sshbind */
|
||||
p = ssh_find_all_matching(sshbind->pubkey_accepted_key_types,
|
||||
session->opts.pubkey_accepted_types);
|
||||
if (p == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SAFE_FREE(session->opts.pubkey_accepted_types);
|
||||
session->opts.pubkey_accepted_types = p;
|
||||
}
|
||||
}
|
||||
|
||||
session->common.log_verbosity = sshbind->common.log_verbosity;
|
||||
if(sshbind->banner != NULL)
|
||||
session->opts.custombanner = strdup(sshbind->banner);
|
||||
|
||||
@@ -1,638 +0,0 @@
|
||||
/*
|
||||
* bind_config.c - Parse the SSH server configuration file
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2019 by Red Hat, Inc.
|
||||
*
|
||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_GLOB_H
|
||||
# include <glob.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/bind.h"
|
||||
#include "libssh/bind_config.h"
|
||||
#include "libssh/config_parser.h"
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/server.h"
|
||||
#include "libssh/options.h"
|
||||
|
||||
#define MAX_LINE_SIZE 1024
|
||||
|
||||
/* Flags used for the parser state */
|
||||
#define PARSING 1
|
||||
#define IN_MATCH (1<<1)
|
||||
|
||||
struct ssh_bind_config_keyword_table_s {
|
||||
const char *name;
|
||||
enum ssh_bind_config_opcode_e opcode;
|
||||
bool allowed_in_match;
|
||||
};
|
||||
|
||||
static struct ssh_bind_config_keyword_table_s
|
||||
ssh_bind_config_keyword_table[] = {
|
||||
{
|
||||
.name = "include",
|
||||
.opcode = BIND_CFG_INCLUDE
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.opcode = BIND_CFG_HOSTKEY
|
||||
},
|
||||
{
|
||||
.name = "listenaddress",
|
||||
.opcode = BIND_CFG_LISTENADDRESS
|
||||
},
|
||||
{
|
||||
.name = "port",
|
||||
.opcode = BIND_CFG_PORT
|
||||
},
|
||||
{
|
||||
.name = "loglevel",
|
||||
.opcode = BIND_CFG_LOGLEVEL,
|
||||
.allowed_in_match = true,
|
||||
},
|
||||
{
|
||||
.name = "ciphers",
|
||||
.opcode = BIND_CFG_CIPHERS
|
||||
},
|
||||
{
|
||||
.name = "macs",
|
||||
.opcode = BIND_CFG_MACS
|
||||
},
|
||||
{
|
||||
.name = "kexalgorithms",
|
||||
.opcode = BIND_CFG_KEXALGORITHMS
|
||||
},
|
||||
{
|
||||
.name = "match",
|
||||
.opcode = BIND_CFG_MATCH,
|
||||
.allowed_in_match = true
|
||||
},
|
||||
{
|
||||
.name = "pubkeyacceptedkeytypes",
|
||||
.opcode = BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES,
|
||||
.allowed_in_match = true
|
||||
},
|
||||
{
|
||||
.name = "hostkeyalgorithms",
|
||||
.opcode = BIND_CFG_HOSTKEY_ALGORITHMS,
|
||||
.allowed_in_match = true
|
||||
},
|
||||
{
|
||||
.opcode = BIND_CFG_UNKNOWN,
|
||||
}
|
||||
};
|
||||
|
||||
enum ssh_bind_config_match_e {
|
||||
BIND_MATCH_UNKNOWN = -1,
|
||||
BIND_MATCH_ALL,
|
||||
BIND_MATCH_USER,
|
||||
BIND_MATCH_GROUP,
|
||||
BIND_MATCH_HOST,
|
||||
BIND_MATCH_LOCALADDRESS,
|
||||
BIND_MATCH_LOCALPORT,
|
||||
BIND_MATCH_RDOMAIN,
|
||||
BIND_MATCH_ADDRESS,
|
||||
};
|
||||
|
||||
struct ssh_bind_config_match_keyword_table_s {
|
||||
const char *name;
|
||||
enum ssh_bind_config_match_e opcode;
|
||||
};
|
||||
|
||||
static struct ssh_bind_config_match_keyword_table_s
|
||||
ssh_bind_config_match_keyword_table[] = {
|
||||
{
|
||||
.name = "all",
|
||||
.opcode = BIND_MATCH_ALL
|
||||
},
|
||||
{
|
||||
.name = "user",
|
||||
.opcode = BIND_MATCH_USER
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.opcode = BIND_MATCH_GROUP
|
||||
},
|
||||
{
|
||||
.name = "host",
|
||||
.opcode = BIND_MATCH_HOST
|
||||
},
|
||||
{
|
||||
.name = "localaddress",
|
||||
.opcode = BIND_MATCH_LOCALADDRESS
|
||||
},
|
||||
{
|
||||
.name = "localport",
|
||||
.opcode = BIND_MATCH_LOCALPORT
|
||||
},
|
||||
{
|
||||
.name = "rdomain",
|
||||
.opcode = BIND_MATCH_RDOMAIN
|
||||
},
|
||||
{
|
||||
.name = "address",
|
||||
.opcode = BIND_MATCH_ADDRESS
|
||||
},
|
||||
{
|
||||
.opcode = BIND_MATCH_UNKNOWN
|
||||
},
|
||||
};
|
||||
|
||||
static enum ssh_bind_config_opcode_e
|
||||
ssh_bind_config_get_opcode(char *keyword, uint32_t *parser_flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ssh_bind_config_keyword_table[i].name != NULL; i++) {
|
||||
if (strcasecmp(keyword, ssh_bind_config_keyword_table[i].name) == 0) {
|
||||
if ((*parser_flags & IN_MATCH) &&
|
||||
!(ssh_bind_config_keyword_table[i].allowed_in_match))
|
||||
{
|
||||
return BIND_CFG_NOT_ALLOWED_IN_MATCH;
|
||||
}
|
||||
return ssh_bind_config_keyword_table[i].opcode;
|
||||
}
|
||||
}
|
||||
|
||||
return BIND_CFG_UNKNOWN;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_bind_config_parse_line(ssh_bind bind,
|
||||
const char *line,
|
||||
unsigned int count,
|
||||
uint32_t *parser_flags,
|
||||
uint8_t *seen);
|
||||
|
||||
static void local_parse_file(ssh_bind bind,
|
||||
const char *filename,
|
||||
uint32_t *parser_flags,
|
||||
uint8_t *seen)
|
||||
{
|
||||
FILE *f;
|
||||
char line[MAX_LINE_SIZE] = {0};
|
||||
unsigned int count = 0;
|
||||
int rv;
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading additional configuration data from %s",
|
||||
filename);
|
||||
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
count++;
|
||||
rv = ssh_bind_config_parse_line(bind, line, count, parser_flags, seen);
|
||||
if (rv < 0) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||
static void local_parse_glob(ssh_bind bind,
|
||||
const char *fileglob,
|
||||
uint32_t *parser_flags,
|
||||
uint8_t *seen)
|
||||
{
|
||||
glob_t globbuf = {
|
||||
.gl_flags = 0,
|
||||
};
|
||||
int rt;
|
||||
u_int i;
|
||||
|
||||
rt = glob(fileglob, GLOB_TILDE, NULL, &globbuf);
|
||||
if (rt == GLOB_NOMATCH) {
|
||||
globfree(&globbuf);
|
||||
return;
|
||||
} else if (rt != 0) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Glob error: %s",
|
||||
fileglob);
|
||||
globfree(&globbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < globbuf.gl_pathc; i++) {
|
||||
local_parse_file(bind, globbuf.gl_pathv[i], parser_flags, seen);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
}
|
||||
#endif /* HAVE_GLOB HAVE_GLOB_GL_FLAGS_MEMBER */
|
||||
|
||||
static enum ssh_bind_config_match_e
|
||||
ssh_bind_config_get_match_opcode(const char *keyword)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; ssh_bind_config_match_keyword_table[i].name != NULL; i++) {
|
||||
if (strcasecmp(keyword, ssh_bind_config_match_keyword_table[i].name) == 0) {
|
||||
return ssh_bind_config_match_keyword_table[i].opcode;
|
||||
}
|
||||
}
|
||||
|
||||
return BIND_MATCH_UNKNOWN;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_bind_config_parse_line(ssh_bind bind,
|
||||
const char *line,
|
||||
unsigned int count,
|
||||
uint32_t *parser_flags,
|
||||
uint8_t *seen)
|
||||
{
|
||||
enum ssh_bind_config_opcode_e opcode;
|
||||
const char *p = NULL;
|
||||
char *s = NULL, *x = NULL;
|
||||
char *keyword = NULL;
|
||||
size_t len;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
if (bind == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((line == NULL) || (parser_flags == NULL)) {
|
||||
ssh_set_error_invalid(bind);
|
||||
return -1;
|
||||
}
|
||||
|
||||
x = s = strdup(line);
|
||||
if (s == NULL) {
|
||||
ssh_set_error_oom(bind);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Remove trailing spaces */
|
||||
for (len = strlen(s) - 1; len > 0; len--) {
|
||||
if (! isspace(s[len])) {
|
||||
break;
|
||||
}
|
||||
s[len] = '\0';
|
||||
}
|
||||
|
||||
keyword = ssh_config_get_token(&s);
|
||||
if (keyword == NULL || *keyword == '#' ||
|
||||
*keyword == '\0' || *keyword == '\n') {
|
||||
SAFE_FREE(x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
opcode = ssh_bind_config_get_opcode(keyword, parser_flags);
|
||||
if ((*parser_flags & PARSING) &&
|
||||
opcode != BIND_CFG_HOSTKEY &&
|
||||
opcode != BIND_CFG_INCLUDE &&
|
||||
opcode != BIND_CFG_MATCH &&
|
||||
opcode > BIND_CFG_UNSUPPORTED) { /* Ignore all unknown types here */
|
||||
/* Skip all the options that were already applied */
|
||||
if (seen[opcode] != 0) {
|
||||
SAFE_FREE(x);
|
||||
return 0;
|
||||
}
|
||||
seen[opcode] = 1;
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case BIND_CFG_INCLUDE:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||
local_parse_glob(bind, p, parser_flags, seen);
|
||||
#else
|
||||
local_parse_file(bind, p, parser_flags, seen);
|
||||
#endif /* HAVE_GLOB */
|
||||
}
|
||||
break;
|
||||
|
||||
case BIND_CFG_HOSTKEY:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HOSTKEY, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set Hostkey value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_LISTENADDRESS:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDADDR, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set ListenAddress value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_PORT:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDPORT_STR, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set Port value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_CIPHERS:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_C_S, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set C->S Ciphers value '%s'",
|
||||
count, p);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_S_C, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set S->C Ciphers value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_MACS:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_C_S, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set C->S MAC value '%s'",
|
||||
count, p);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_S_C, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set S->C MAC value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_LOGLEVEL:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
int value = -1;
|
||||
|
||||
if (strcasecmp(p, "quiet") == 0) {
|
||||
value = SSH_LOG_NONE;
|
||||
} else if (strcasecmp(p, "fatal") == 0 ||
|
||||
strcasecmp(p, "error")== 0 ||
|
||||
strcasecmp(p, "info") == 0) {
|
||||
value = SSH_LOG_WARN;
|
||||
} else if (strcasecmp(p, "verbose") == 0) {
|
||||
value = SSH_LOG_INFO;
|
||||
} else if (strcasecmp(p, "DEBUG") == 0 ||
|
||||
strcasecmp(p, "DEBUG1") == 0) {
|
||||
value = SSH_LOG_DEBUG;
|
||||
} else if (strcasecmp(p, "DEBUG2") == 0 ||
|
||||
strcasecmp(p, "DEBUG3") == 0) {
|
||||
value = SSH_LOG_TRACE;
|
||||
}
|
||||
if (value != -1) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY,
|
||||
&value);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set LogLevel value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_KEXALGORITHMS:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_KEY_EXCHANGE, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set KexAlgorithms value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_MATCH: {
|
||||
bool negate;
|
||||
int result = PARSING;
|
||||
size_t args = 0;
|
||||
enum ssh_bind_config_match_e opt;
|
||||
const char *p2 = NULL;
|
||||
|
||||
/* The options set in Match blocks should be applied when a connection
|
||||
* is accepted, and not right away when parsing the file (as it is
|
||||
* currently done). This means the configuration files should be parsed
|
||||
* again or the options set in the Match blocks should be stored and
|
||||
* applied as necessary. */
|
||||
|
||||
/* If this is the first Match block, erase the seen table to allow
|
||||
* options to be overridden. Erasing the seen table was the easiest way
|
||||
* to allow overriding an option, but only for the first occurrence of
|
||||
* an option in a Match block. This is sufficient for the current
|
||||
* implementation which supports only the 'All' criterion, meaning the
|
||||
* options can be applied right away. */
|
||||
if (!(*parser_flags & IN_MATCH)) {
|
||||
memset(seen, 0x00, BIND_CFG_MAX * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
/* In this line the PARSING bit is cleared from the flags */
|
||||
*parser_flags = IN_MATCH;
|
||||
do {
|
||||
p = p2 = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
break;
|
||||
}
|
||||
args++;
|
||||
SSH_LOG(SSH_LOG_TRACE, "line %d: Processing Match keyword '%s'",
|
||||
count, p);
|
||||
|
||||
/* If the option is prefixed with ! the result should be negated */
|
||||
negate = false;
|
||||
if (p[0] == '!') {
|
||||
negate = true;
|
||||
p++;
|
||||
}
|
||||
|
||||
opt = ssh_bind_config_get_match_opcode(p);
|
||||
switch (opt) {
|
||||
case BIND_MATCH_ALL:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if ((args == 1) && (p == NULL || p[0] == '\0')) {
|
||||
/* The "all" keyword does not accept arguments or modifiers
|
||||
*/
|
||||
if (negate == true) {
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ssh_set_error(bind, SSH_FATAL,
|
||||
"line %d: ERROR - Match all cannot be combined with "
|
||||
"other Match attributes", count);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
case BIND_MATCH_USER:
|
||||
case BIND_MATCH_GROUP:
|
||||
case BIND_MATCH_HOST:
|
||||
case BIND_MATCH_LOCALADDRESS:
|
||||
case BIND_MATCH_LOCALPORT:
|
||||
case BIND_MATCH_RDOMAIN:
|
||||
case BIND_MATCH_ADDRESS:
|
||||
/* Only "All" is supported for now */
|
||||
/* Skip one argument */
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
|
||||
"'%s' requires argument\n", count, p2);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
args++;
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Unsupported Match keyword '%s', ignoring\n",
|
||||
count,
|
||||
p2);
|
||||
result = 0;
|
||||
break;
|
||||
case BIND_MATCH_UNKNOWN:
|
||||
default:
|
||||
ssh_set_error(bind, SSH_FATAL,
|
||||
"ERROR - Unknown argument '%s' for Match keyword", p);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
} while (p != NULL && p[0] != '\0');
|
||||
if (args == 0) {
|
||||
ssh_set_error(bind, SSH_FATAL,
|
||||
"ERROR - Match keyword requires an argument");
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
/* This line only sets the PARSING flag if all checks passed */
|
||||
*parser_flags |= result;
|
||||
break;
|
||||
}
|
||||
case BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind,
|
||||
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set PubKeyAcceptedKeyTypes value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_HOSTKEY_ALGORITHMS:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && (*parser_flags & PARSING)) {
|
||||
rc = ssh_bind_options_set(bind,
|
||||
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS, p);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Failed to set HostkeyAlgorithms value '%s'",
|
||||
count, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIND_CFG_NOT_ALLOWED_IN_MATCH:
|
||||
SSH_LOG(SSH_LOG_WARN, "Option not allowed in Match block: %s, line: %d",
|
||||
keyword, count);
|
||||
break;
|
||||
case BIND_CFG_UNKNOWN:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d",
|
||||
keyword, count);
|
||||
break;
|
||||
case BIND_CFG_UNSUPPORTED:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unsupported option: %s, line: %d",
|
||||
keyword, count);
|
||||
break;
|
||||
case BIND_CFG_NA:
|
||||
SSH_LOG(SSH_LOG_WARN, "Option not applicable: %s, line: %d",
|
||||
keyword, count);
|
||||
break;
|
||||
default:
|
||||
ssh_set_error(bind, SSH_FATAL, "ERROR - unimplemented opcode: %d",
|
||||
opcode);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
SAFE_FREE(x);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ssh_bind_config_parse_file(ssh_bind bind, const char *filename)
|
||||
{
|
||||
char line[MAX_LINE_SIZE] = {0};
|
||||
unsigned int count = 0;
|
||||
FILE *f;
|
||||
uint32_t parser_flags;
|
||||
int rv;
|
||||
|
||||
/* This local table is used during the parsing of the current file (and
|
||||
* files included recursively in this file) to prevent an option to be
|
||||
* redefined, i.e. the first value set is kept. But this DO NOT prevent the
|
||||
* option to be redefined later by another file. */
|
||||
uint8_t seen[BIND_CFG_MAX] = {0};
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
|
||||
|
||||
parser_flags = PARSING;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
count++;
|
||||
rv = ssh_bind_config_parse_line(bind, line, count, &parser_flags, seen);
|
||||
if (rv) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
110
src/buffer.c
110
src/buffer.c
@@ -809,20 +809,20 @@ ssh_buffer_get_ssh_string(struct ssh_buffer_struct *buffer)
|
||||
*/
|
||||
static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
va_list ap)
|
||||
{
|
||||
const char *p = NULL;
|
||||
ssh_string string = NULL;
|
||||
char *cstring = NULL;
|
||||
size_t needed_size = 0;
|
||||
size_t len;
|
||||
size_t count;
|
||||
size_t len;
|
||||
int rc = SSH_OK;
|
||||
|
||||
for (p = format, count = 0; *p != '\0'; p++, count++) {
|
||||
/* Invalid number of arguments passed */
|
||||
if (count > argc) {
|
||||
if (argc != -1 && count > argc) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -881,7 +881,7 @@ static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != count) {
|
||||
if (argc != -1 && argc != count) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -891,7 +891,11 @@ static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
|
||||
*/
|
||||
uint32_t canary = va_arg(ap, uint32_t);
|
||||
if (canary != SSH_BUFFER_PACK_END) {
|
||||
abort();
|
||||
if (argc == -1){
|
||||
return SSH_ERROR;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -914,7 +918,7 @@ static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
|
||||
*/
|
||||
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
va_list ap)
|
||||
{
|
||||
int rc = SSH_ERROR;
|
||||
@@ -930,15 +934,11 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
char *cstring;
|
||||
bignum b;
|
||||
size_t len;
|
||||
size_t count;
|
||||
|
||||
if (argc > 256) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
int count;
|
||||
|
||||
for (p = format, count = 0; *p != '\0'; p++, count++) {
|
||||
/* Invalid number of arguments passed */
|
||||
if (count > argc) {
|
||||
if (argc != -1 && count > argc) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -1010,15 +1010,19 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != count) {
|
||||
if (argc != -1 && argc != count) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (rc != SSH_ERROR){
|
||||
/* Check if our canary is intact, if not something really bad happened */
|
||||
/* Check if our canary is intact, if not somthing really bad happened */
|
||||
uint32_t canary = va_arg(ap, uint32_t);
|
||||
if (canary != SSH_BUFFER_PACK_END) {
|
||||
abort();
|
||||
if (argc == -1){
|
||||
return SSH_ERROR;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
@@ -1046,16 +1050,12 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
*/
|
||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
int rc;
|
||||
|
||||
if (argc > 256) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
va_start(ap, argc);
|
||||
rc = ssh_buffer_pack_allocate_va(buffer, format, argc, ap);
|
||||
va_end(ap);
|
||||
@@ -1082,11 +1082,11 @@ int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
||||
*/
|
||||
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
va_list ap)
|
||||
{
|
||||
int rc = SSH_ERROR;
|
||||
const char *p = format, *last;
|
||||
const char *p, *last;
|
||||
union {
|
||||
uint8_t *byte;
|
||||
uint16_t *word;
|
||||
@@ -1094,32 +1094,24 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
uint64_t *qword;
|
||||
ssh_string *string;
|
||||
char **cstring;
|
||||
bignum *bignum;
|
||||
void **data;
|
||||
} o;
|
||||
size_t len, rlen, max_len;
|
||||
ssh_string tmp_string = NULL;
|
||||
va_list ap_copy;
|
||||
size_t count;
|
||||
int count;
|
||||
|
||||
max_len = ssh_buffer_get_len(buffer);
|
||||
|
||||
/* copy the argument list in case a rollback is needed */
|
||||
va_copy(ap_copy, ap);
|
||||
|
||||
if (argc > 256) {
|
||||
rc = SSH_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (count = 0; *p != '\0'; p++, count++) {
|
||||
for (p = format, count = 0; *p != '\0'; p++, count++) {
|
||||
/* Invalid number of arguments passed */
|
||||
if (count > argc) {
|
||||
if (argc != -1 && count > argc) {
|
||||
rc = SSH_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = SSH_ERROR;
|
||||
switch (*p) {
|
||||
case 'b':
|
||||
o.byte = va_arg(ap, uint8_t *);
|
||||
@@ -1129,38 +1121,20 @@ 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));
|
||||
if (rlen == 2) {
|
||||
*o.word = ntohs(*o.word);
|
||||
rc = SSH_OK;
|
||||
}
|
||||
*o.word = ntohs(*o.word);
|
||||
rc = rlen==2 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'd':
|
||||
o.dword = va_arg(ap, uint32_t *);
|
||||
rlen = ssh_buffer_get_u32(buffer, o.dword);
|
||||
if (rlen == 4) {
|
||||
*o.dword = ntohl(*o.dword);
|
||||
rc = SSH_OK;
|
||||
}
|
||||
*o.dword = ntohl(*o.dword);
|
||||
rc = rlen==4 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'q':
|
||||
o.qword = va_arg(ap, uint64_t*);
|
||||
rlen = ssh_buffer_get_u64(buffer, o.qword);
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
*o.bignum = ssh_make_string_bn(tmp_string);
|
||||
ssh_string_burn(tmp_string);
|
||||
SSH_STRING_FREE(tmp_string);
|
||||
rc = (*o.bignum != NULL) ? SSH_OK : SSH_ERROR;
|
||||
*o.qword = ntohll(*o.qword);
|
||||
rc = rlen==8 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'S':
|
||||
o.string = va_arg(ap, ssh_string *);
|
||||
@@ -1173,12 +1147,14 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
|
||||
o.cstring = va_arg(ap, char **);
|
||||
*o.cstring = NULL;
|
||||
rlen = ssh_buffer_get_u32(buffer, &u32len);
|
||||
if (rlen != 4){
|
||||
rc = ssh_buffer_get_u32(buffer, &u32len);
|
||||
if (rc != 4){
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
len = ntohl(u32len);
|
||||
if (len > max_len - 1) {
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1234,13 +1210,14 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != count) {
|
||||
if (argc != -1 && argc != count) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -1249,7 +1226,11 @@ cleanup:
|
||||
/* Check if our canary is intact, if not something really bad happened */
|
||||
uint32_t canary = va_arg(ap, uint32_t);
|
||||
if (canary != SSH_BUFFER_PACK_END){
|
||||
abort();
|
||||
if (argc == -1){
|
||||
rc = SSH_ERROR;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1286,10 +1267,6 @@ cleanup:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
o.bignum = va_arg(ap_copy, bignum *);
|
||||
bignum_safe_free(*o.bignum);
|
||||
break;
|
||||
case 'S':
|
||||
o.string = va_arg(ap_copy, ssh_string *);
|
||||
if (buffer->secure) {
|
||||
@@ -1336,7 +1313,6 @@ cleanup:
|
||||
* 's': char ** (C string, pulled as SSH string)
|
||||
* 'P': size_t, void ** (len of data, pointer to data)
|
||||
* only pulls data.
|
||||
* 'B': bignum * (pulled as SSH string)
|
||||
* @returns SSH_OK on success
|
||||
* SSH_ERROR on error
|
||||
* @warning when using 'P' with a constant size (e.g. 8), do not
|
||||
@@ -1344,7 +1320,7 @@ cleanup:
|
||||
*/
|
||||
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
size_t argc,
|
||||
int argc,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -109,11 +109,11 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
|
||||
out_packet->payload,
|
||||
len - sizeof(uint32_t));
|
||||
|
||||
/* ssh_log_hexdump("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
|
||||
/* ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
|
||||
/* step 4, compute the MAC */
|
||||
poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx);
|
||||
/* ssh_log_hexdump("poly1305 src", (uint8_t *)out_packet, len);
|
||||
ssh_log_hexdump("poly1305 tag", tag, POLY1305_TAGLEN); */
|
||||
/* ssh_print_hexa("poly1305 src", (uint8_t *)out_packet, len);
|
||||
ssh_print_hexa("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_log_hexdump("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
|
||||
ssh_print_hexa("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_log_hexdump("poly1305 src",
|
||||
ssh_print_hexa("poly1305 src",
|
||||
(uint8_t*)complete_packet,
|
||||
encrypted_size + 4);
|
||||
ssh_log_hexdump("poly1305 tag", tag, POLY1305_TAGLEN);
|
||||
ssh_log_hexdump("received tag", mac, POLY1305_TAGLEN);
|
||||
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN);
|
||||
ssh_print_hexa("received tag", mac, POLY1305_TAGLEN);
|
||||
#endif
|
||||
|
||||
cmp = memcmp(tag, mac, POLY1305_TAGLEN);
|
||||
@@ -192,7 +192,6 @@ static void chacha20_cleanup(struct ssh_cipher_struct *cipher) {
|
||||
}
|
||||
|
||||
const struct ssh_cipher_struct chacha20poly1305_cipher = {
|
||||
.ciphertype = SSH_AEAD_CHACHA20_POLY1305,
|
||||
.name = "chacha20-poly1305@openssh.com",
|
||||
.blocksize = 8,
|
||||
.lenfield_blocksize = 4,
|
||||
|
||||
520
src/channels.c
520
src/channels.c
@@ -28,7 +28,6 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -85,11 +84,6 @@ ssh_channel ssh_channel_new(ssh_session session)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if we have an authenticated session */
|
||||
if (!(session->flags & SSH_SESSION_FLAG_AUTHENTICATED)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
channel = calloc(1, sizeof(struct ssh_channel_struct));
|
||||
if (channel == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
@@ -159,8 +153,8 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
|
||||
channel=ssh_channel_from_local(session,channelid);
|
||||
if(channel==NULL){
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Unknown channel id %"PRIu32,
|
||||
(uint32_t) channelid);
|
||||
"Unknown channel id %lu",
|
||||
(long unsigned int) channelid);
|
||||
/* TODO: Set error marking in channel object */
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
@@ -187,9 +181,9 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Remote window : %"PRIu32", maxpacket : %"PRIu32,
|
||||
(uint32_t) channel->remote_window,
|
||||
(uint32_t) channel->remote_maxpacket);
|
||||
"Remote window : %lu, maxpacket : %lu",
|
||||
(long unsigned int) channel->remote_window,
|
||||
(long unsigned int) channel->remote_maxpacket);
|
||||
|
||||
channel->state = SSH_CHANNEL_STATE_OPEN;
|
||||
channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND;
|
||||
@@ -235,9 +229,9 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Channel opening failure: channel %u error (%"PRIu32") %s",
|
||||
"Channel opening failure: channel %u error (%lu) %s",
|
||||
channel->local_channel,
|
||||
(uint32_t) code,
|
||||
(long unsigned int) code,
|
||||
error);
|
||||
SAFE_FREE(error);
|
||||
channel->state=SSH_CHANNEL_STATE_OPEN_DENIED;
|
||||
@@ -274,92 +268,75 @@ static int ssh_channel_open_termination(void *c){
|
||||
* @param[in] maxpacket The maximum packet size allowed (like MTU).
|
||||
*
|
||||
* @param[in] payload The buffer containing additional payload for the query.
|
||||
*
|
||||
* @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, int window,
|
||||
int 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
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:
|
||||
if(channel->state == SSH_CHANNEL_STATE_OPEN)
|
||||
err=SSH_OK;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* return channel with corresponding local id, or NULL if not found */
|
||||
@@ -386,7 +363,6 @@ ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) {
|
||||
* @param session SSH session
|
||||
* @param channel SSH channel
|
||||
* @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) {
|
||||
uint32_t new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE;
|
||||
@@ -442,7 +418,7 @@ error:
|
||||
* @param[in] packet The buffer to parse packet from. The read pointer will
|
||||
* be moved after the call.
|
||||
*
|
||||
* @return The related ssh_channel, or NULL if the channel is
|
||||
* @returns The related ssh_channel, or NULL if the channel is
|
||||
* unknown or the packet is invalid.
|
||||
*/
|
||||
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
|
||||
@@ -460,8 +436,8 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
|
||||
channel = ssh_channel_from_local(session, chan);
|
||||
if (channel == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Server specified invalid channel %"PRIu32,
|
||||
(uint32_t) chan);
|
||||
"Server specified invalid channel %lu",
|
||||
(long unsigned int) chan);
|
||||
}
|
||||
|
||||
return channel;
|
||||
@@ -707,10 +683,6 @@ SSH_PACKET_CALLBACK(channel_rcv_request) {
|
||||
if (strcmp(request,"exit-status") == 0) {
|
||||
SAFE_FREE(request);
|
||||
rc = ssh_buffer_unpack(packet, "d", &channel->exit_status);
|
||||
if (rc != SSH_OK) {
|
||||
SSH_LOG(SSH_LOG_PACKET, "Invalid exit-status packet");
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "received exit-status %d", channel->exit_status);
|
||||
|
||||
ssh_callbacks_execute_list(channel->callbacks,
|
||||
@@ -1019,88 +991,6 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a TCP/IP - UNIX domain socket forwarding channel.
|
||||
*
|
||||
* @param[in] channel An allocated channel.
|
||||
*
|
||||
* @param[in] remotepath The UNIX socket path on the remote machine
|
||||
*
|
||||
* @param[in] sourcehost The numeric IP address of the machine from where the
|
||||
* connection request originates. This is mostly for
|
||||
* logging purposes.
|
||||
*
|
||||
* @param[in] localport The port on the host from where the connection
|
||||
* originated. This is mostly for logging purposes.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @warning This function does not bind the local port and does not
|
||||
* automatically forward the content of a socket to the channel.
|
||||
* You still have to use channel_read and channel_write for this.
|
||||
* @warning Requires support of OpenSSH for UNIX domain socket forwarding.
|
||||
*/
|
||||
int ssh_channel_open_forward_unix(ssh_channel channel,
|
||||
const char *remotepath,
|
||||
const char *sourcehost,
|
||||
int localport)
|
||||
{
|
||||
ssh_session session = NULL;
|
||||
ssh_buffer payload = NULL;
|
||||
ssh_string str = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
int version;
|
||||
|
||||
if (channel == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
|
||||
version = ssh_get_openssh_version(session);
|
||||
if (version == 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"We're not connected to an OpenSSH server!");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (remotepath == NULL || sourcehost == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return rc;
|
||||
}
|
||||
|
||||
payload = ssh_buffer_new();
|
||||
if (payload == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(payload,
|
||||
"ssd",
|
||||
remotepath,
|
||||
sourcehost,
|
||||
localport);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = channel_open(channel,
|
||||
"direct-streamlocal@openssh.com",
|
||||
CHANNEL_INITIAL_WINDOW,
|
||||
CHANNEL_MAX_PACKET,
|
||||
payload);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(payload);
|
||||
ssh_string_free(str);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close and free a channel.
|
||||
@@ -1109,50 +999,28 @@ error:
|
||||
*
|
||||
* @warning Any data unread on this channel will be lost.
|
||||
*/
|
||||
void ssh_channel_free(ssh_channel channel)
|
||||
{
|
||||
ssh_session session;
|
||||
void ssh_channel_free(ssh_channel channel) {
|
||||
ssh_session session;
|
||||
|
||||
if (channel == NULL) {
|
||||
return;
|
||||
}
|
||||
if (channel == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
if (session->alive) {
|
||||
bool send_close = false;
|
||||
session = channel->session;
|
||||
if (session->alive && channel->state == SSH_CHANNEL_STATE_OPEN) {
|
||||
ssh_channel_close(channel);
|
||||
}
|
||||
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
|
||||
|
||||
switch (channel->state) {
|
||||
case SSH_CHANNEL_STATE_OPEN:
|
||||
send_close = true;
|
||||
break;
|
||||
case SSH_CHANNEL_STATE_CLOSED:
|
||||
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) {
|
||||
send_close = true;
|
||||
}
|
||||
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
|
||||
send_close = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
send_close = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (send_close) {
|
||||
ssh_channel_close(channel);
|
||||
}
|
||||
}
|
||||
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
|
||||
|
||||
/* The idea behind the flags is the following : it is well possible
|
||||
* that a client closes a channel that stills exists on the server side.
|
||||
* We definitively close the channel when we receive a close message *and*
|
||||
* the user closed it.
|
||||
*/
|
||||
if ((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) ||
|
||||
(channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)) {
|
||||
ssh_channel_do_free(channel);
|
||||
}
|
||||
/* The idea behind the flags is the following : it is well possible
|
||||
* that a client closes a channel that stills exists on the server side.
|
||||
* We definitively close the channel when we receive a close message *and*
|
||||
* the user closed it.
|
||||
*/
|
||||
if((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE)
|
||||
|| (channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)){
|
||||
ssh_channel_do_free(channel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1170,15 +1038,13 @@ void ssh_channel_do_free(ssh_channel channel)
|
||||
ssh_list_remove(session->channels, it);
|
||||
}
|
||||
|
||||
SSH_BUFFER_FREE(channel->stdout_buffer);
|
||||
SSH_BUFFER_FREE(channel->stderr_buffer);
|
||||
ssh_buffer_free(channel->stdout_buffer);
|
||||
ssh_buffer_free(channel->stderr_buffer);
|
||||
|
||||
if (channel->callbacks != NULL) {
|
||||
ssh_list_free(channel->callbacks);
|
||||
channel->callbacks = NULL;
|
||||
}
|
||||
|
||||
channel->session = NULL;
|
||||
SAFE_FREE(channel);
|
||||
}
|
||||
|
||||
@@ -1210,52 +1076,43 @@ void ssh_channel_do_free(ssh_channel channel)
|
||||
* @see ssh_channel_free()
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
int ssh_channel_send_eof(ssh_channel channel)
|
||||
{
|
||||
ssh_session session;
|
||||
int rc = SSH_ERROR;
|
||||
int err;
|
||||
int ssh_channel_send_eof(ssh_channel channel){
|
||||
ssh_session session;
|
||||
int rc = SSH_ERROR;
|
||||
int err;
|
||||
|
||||
if (channel == NULL || channel->session == NULL) {
|
||||
return rc;
|
||||
}
|
||||
if(channel == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* If the EOF has already been sent we're done here. */
|
||||
if (channel->local_eof != 0) {
|
||||
return SSH_OK;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
session = channel->session;
|
||||
err = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_EOF,
|
||||
channel->remote_channel);
|
||||
if (err != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_EOF,
|
||||
channel->remote_channel);
|
||||
if (err != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a EOF on client channel (%d:%d)",
|
||||
channel->local_channel,
|
||||
channel->remote_channel);
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a EOF on client channel (%d:%d)",
|
||||
channel->local_channel,
|
||||
channel->remote_channel);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_channel_flush(channel);
|
||||
if(rc == SSH_ERROR)
|
||||
goto error;
|
||||
|
||||
rc = ssh_channel_flush(channel);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
channel->local_eof = 1;
|
||||
channel->local_eof = 1;
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1271,57 +1128,52 @@ error:
|
||||
* @see ssh_channel_free()
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
int ssh_channel_close(ssh_channel channel)
|
||||
{
|
||||
ssh_session session;
|
||||
int rc = 0;
|
||||
int ssh_channel_close(ssh_channel channel){
|
||||
ssh_session session;
|
||||
int rc = 0;
|
||||
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* If the channel close has already been sent we're done here. */
|
||||
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
session = channel->session;
|
||||
|
||||
if (channel->local_eof == 0) {
|
||||
rc = ssh_channel_send_eof(channel);
|
||||
if (rc != SSH_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_CLOSE,
|
||||
channel->remote_channel);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a close on client channel (%d:%d)",
|
||||
channel->local_channel,
|
||||
channel->remote_channel);
|
||||
|
||||
if (rc == SSH_OK) {
|
||||
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
||||
channel->flags |= SSH_CHANNEL_FLAG_CLOSED_LOCAL;
|
||||
}
|
||||
|
||||
rc = ssh_channel_flush(channel);
|
||||
if(rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_CLOSE,
|
||||
channel->remote_channel);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a close on client channel (%d:%d)",
|
||||
channel->local_channel,
|
||||
channel->remote_channel);
|
||||
|
||||
if(rc == SSH_OK) {
|
||||
channel->state=SSH_CHANNEL_STATE_CLOSED;
|
||||
}
|
||||
|
||||
rc = ssh_channel_flush(channel);
|
||||
if(rc == SSH_ERROR)
|
||||
goto error;
|
||||
|
||||
return rc;
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* this termination function waits for a window growing condition */
|
||||
@@ -1354,9 +1206,9 @@ static int ssh_waitsession_unblocked(void *s){
|
||||
* @brief Flushes a channel (and its session) until the output buffer
|
||||
* is empty, or timeout elapsed.
|
||||
* @param channel SSH channel
|
||||
* @return SSH_OK On success,
|
||||
* SSH_ERROR On error.
|
||||
* SSH_AGAIN Timeout elapsed (or in nonblocking mode).
|
||||
* @returns SSH_OK On success,
|
||||
* SSH_ERROR on error
|
||||
* SSH_AGAIN Timeout elapsed (or in nonblocking mode)
|
||||
*/
|
||||
int ssh_channel_flush(ssh_channel channel){
|
||||
return ssh_blocking_flush(channel->session, SSH_TIMEOUT_DEFAULT);
|
||||
@@ -1964,18 +1816,6 @@ error:
|
||||
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;
|
||||
@@ -2242,11 +2082,8 @@ static int ssh_global_request_termination(void *s){
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
int ssh_global_request(ssh_session session,
|
||||
const char *request,
|
||||
ssh_buffer buffer,
|
||||
int reply)
|
||||
{
|
||||
static int global_request(ssh_session session, const char *request,
|
||||
ssh_buffer buffer, int reply) {
|
||||
int rc;
|
||||
|
||||
switch (session->global_req_state) {
|
||||
@@ -2377,7 +2214,7 @@ int ssh_channel_listen_forward(ssh_session session,
|
||||
goto error;
|
||||
}
|
||||
pending:
|
||||
rc = ssh_global_request(session, "tcpip-forward", buffer, 1);
|
||||
rc = global_request(session, "tcpip-forward", buffer, 1);
|
||||
|
||||
/* TODO: FIXME no guarantee the last packet we received contains
|
||||
* that info */
|
||||
@@ -2457,7 +2294,7 @@ int ssh_channel_cancel_forward(ssh_session session,
|
||||
goto error;
|
||||
}
|
||||
pending:
|
||||
rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
|
||||
rc = global_request(session, "cancel-tcpip-forward", buffer, 1);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
@@ -2540,12 +2377,12 @@ error:
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
rc = ssh_channel_request_exec(channel, "ps aux");
|
||||
rc = channel_request_exec(channel, "ps aux");
|
||||
if (rc > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||
while ((rc = channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||
if (fwrite(buffer, 1, rc, stdout) != (unsigned int) rc) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2903,7 +2740,7 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
||||
ctx.buffer = stdbuf;
|
||||
ctx.count = 1;
|
||||
|
||||
if (timeout_ms < SSH_TIMEOUT_DEFAULT) {
|
||||
if (timeout_ms < 0) {
|
||||
timeout_ms = SSH_TIMEOUT_INFINITE;
|
||||
}
|
||||
|
||||
@@ -2918,13 +2755,8 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
||||
/*
|
||||
* If the channel is closed or in an error state, reading from it is an error
|
||||
*/
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Remote channel is closed.");
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR ||
|
||||
channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
|
||||
@@ -3140,8 +2972,8 @@ static int ssh_channel_exit_status_termination(void *c){
|
||||
*
|
||||
* @param[in] channel The channel to get the status from.
|
||||
*
|
||||
* @return The exit status, -1 if no exit status has been returned
|
||||
* (yet), or SSH_ERROR on error.
|
||||
* @returns The exit status, -1 if no exit status has been returned
|
||||
* (yet).
|
||||
* @warning This function may block until a timeout (or never)
|
||||
* if the other side is not willing to close the channel.
|
||||
*
|
||||
@@ -3251,7 +3083,7 @@ static int count_ptrs(ssh_channel *ptrs) {
|
||||
*
|
||||
* @return SSH_OK on a successful operation, SSH_EINTR if the
|
||||
* select(2) syscall was interrupted, then relaunch the
|
||||
* function, or SSH_ERROR on error.
|
||||
* function.
|
||||
*/
|
||||
int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
||||
ssh_channel *exceptchans, struct timeval * timeout) {
|
||||
|
||||
34
src/client.c
34
src/client.c
@@ -38,9 +38,6 @@
|
||||
#include "libssh/socket.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/dh.h"
|
||||
#ifdef WITH_GEX
|
||||
#include "libssh/dh-gex.h"
|
||||
#endif /* WITH_GEX */
|
||||
#include "libssh/ecdh.h"
|
||||
#include "libssh/threads.h"
|
||||
#include "libssh/misc.h"
|
||||
@@ -183,6 +180,7 @@ int ssh_send_banner(ssh_session session, int server)
|
||||
|
||||
if (server == 1) {
|
||||
if (session->opts.custombanner == NULL){
|
||||
len = strlen(banner);
|
||||
session->serverbanner = strdup(banner);
|
||||
if (session->serverbanner == NULL) {
|
||||
goto end;
|
||||
@@ -256,12 +254,6 @@ static int dh_handshake(ssh_session session) {
|
||||
case SSH_KEX_DH_GROUP18_SHA512:
|
||||
rc = ssh_client_dh_init(session);
|
||||
break;
|
||||
#ifdef WITH_GEX
|
||||
case SSH_KEX_DH_GEX_SHA1:
|
||||
case SSH_KEX_DH_GEX_SHA256:
|
||||
rc = ssh_client_dhgex_init(session);
|
||||
break;
|
||||
#endif /* WITH_GEX */
|
||||
#ifdef HAVE_ECDH
|
||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||
case SSH_KEX_ECDH_SHA2_NISTP384:
|
||||
@@ -279,7 +271,11 @@ static int dh_handshake(ssh_session session) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
if (rc == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
case DH_STATE_INIT_SENT:
|
||||
/* wait until ssh_packet_dh_reply is called */
|
||||
break;
|
||||
@@ -399,7 +395,7 @@ static void ssh_client_connection_callback(ssh_session session)
|
||||
goto error;
|
||||
}
|
||||
set_status(session, 0.4f);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"SSH server banner: %s", session->serverbanner);
|
||||
|
||||
/* Here we analyze the different protocols the server allows. */
|
||||
@@ -498,8 +494,8 @@ static int ssh_connect_termination(void *user){
|
||||
* @param[in] session The ssh session to connect.
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR on error.
|
||||
* @returns SSH_AGAIN, if the session is in nonblocking mode,
|
||||
* and call must be done again.
|
||||
* @returns SSH_AGAIN, if the session is in nonblocking mode,
|
||||
* and call must be done again.
|
||||
*
|
||||
* @see ssh_new()
|
||||
* @see ssh_disconnect()
|
||||
@@ -531,16 +527,6 @@ int ssh_connect(ssh_session session) {
|
||||
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");
|
||||
@@ -750,7 +736,7 @@ error:
|
||||
}
|
||||
|
||||
const char *ssh_copyright(void) {
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2019 "
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2018 "
|
||||
"Aris Adamantiadis, Andreas Schneider "
|
||||
"and libssh contributors. "
|
||||
"Distributed under the LGPL, please refer to COPYING "
|
||||
|
||||
598
src/config.c
598
src/config.c
@@ -31,10 +31,7 @@
|
||||
# include <glob.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "libssh/config_parser.h"
|
||||
#include "libssh/config.h"
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/misc.h"
|
||||
@@ -42,6 +39,45 @@
|
||||
|
||||
#define MAX_LINE_SIZE 1024
|
||||
|
||||
enum ssh_config_opcode_e {
|
||||
/* Unknown opcode */
|
||||
SOC_UNKNOWN = -3,
|
||||
/* Known and not applicable to libssh */
|
||||
SOC_NA = -2,
|
||||
/* Known but not supported by current libssh version */
|
||||
SOC_UNSUPPORTED = -1,
|
||||
SOC_HOST,
|
||||
SOC_MATCH,
|
||||
SOC_HOSTNAME,
|
||||
SOC_PORT,
|
||||
SOC_USERNAME,
|
||||
SOC_IDENTITY,
|
||||
SOC_CIPHERS,
|
||||
SOC_MACS,
|
||||
SOC_COMPRESSION,
|
||||
SOC_TIMEOUT,
|
||||
SOC_PROTOCOL,
|
||||
SOC_STRICTHOSTKEYCHECK,
|
||||
SOC_KNOWNHOSTS,
|
||||
SOC_PROXYCOMMAND,
|
||||
SOC_GSSAPISERVERIDENTITY,
|
||||
SOC_GSSAPICLIENTIDENTITY,
|
||||
SOC_GSSAPIDELEGATECREDENTIALS,
|
||||
SOC_INCLUDE,
|
||||
SOC_BINDADDRESS,
|
||||
SOC_GLOBALKNOWNHOSTSFILE,
|
||||
SOC_LOGLEVEL,
|
||||
SOC_HOSTKEYALGORITHMS,
|
||||
SOC_KEXALGORITHMS,
|
||||
SOC_GSSAPIAUTHENTICATION,
|
||||
SOC_KBDINTERACTIVEAUTHENTICATION,
|
||||
SOC_PASSWORDAUTHENTICATION,
|
||||
SOC_PUBKEYAUTHENTICATION,
|
||||
SOC_PUBKEYACCEPTEDTYPES,
|
||||
|
||||
SOC_END /* Keep this one last in the list */
|
||||
};
|
||||
|
||||
struct ssh_config_keyword_table_s {
|
||||
const char *name;
|
||||
enum ssh_config_opcode_e opcode;
|
||||
@@ -108,10 +144,10 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = {
|
||||
{ "numberofpasswordprompts", SOC_UNSUPPORTED},
|
||||
{ "pkcs11provider", SOC_UNSUPPORTED},
|
||||
{ "preferredauthentications", SOC_UNSUPPORTED},
|
||||
{ "proxyjump", SOC_PROXYJUMP},
|
||||
{ "proxyjump", SOC_UNSUPPORTED},
|
||||
{ "proxyusefdpass", SOC_UNSUPPORTED},
|
||||
{ "pubkeyacceptedtypes", SOC_PUBKEYACCEPTEDTYPES},
|
||||
{ "rekeylimit", SOC_REKEYLIMIT},
|
||||
{ "rekeylimit", SOC_UNSUPPORTED},
|
||||
{ "remotecommand", SOC_UNSUPPORTED},
|
||||
{ "revokedhostkeys", SOC_UNSUPPORTED},
|
||||
{ "rhostsrsaauthentication", SOC_UNSUPPORTED},
|
||||
@@ -147,14 +183,12 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = {
|
||||
{ "tunnel", SOC_NA},
|
||||
{ "tunneldevice", SOC_NA},
|
||||
{ "xauthlocation", SOC_NA},
|
||||
{ "pubkeyacceptedkeytypes", SOC_PUBKEYACCEPTEDTYPES},
|
||||
{ NULL, SOC_UNKNOWN }
|
||||
};
|
||||
|
||||
enum ssh_config_match_e {
|
||||
MATCH_UNKNOWN = -1,
|
||||
MATCH_ALL,
|
||||
MATCH_FINAL,
|
||||
MATCH_CANONICAL,
|
||||
MATCH_EXEC,
|
||||
MATCH_HOST,
|
||||
@@ -171,17 +205,15 @@ struct ssh_config_match_keyword_table_s {
|
||||
static struct ssh_config_match_keyword_table_s ssh_config_match_keyword_table[] = {
|
||||
{ "all", MATCH_ALL },
|
||||
{ "canonical", MATCH_CANONICAL },
|
||||
{ "final", MATCH_FINAL },
|
||||
{ "exec", MATCH_EXEC },
|
||||
{ "host", MATCH_HOST },
|
||||
{ "originalhost", MATCH_ORIGINALHOST },
|
||||
{ "user", MATCH_USER },
|
||||
{ "localuser", MATCH_LOCALUSER },
|
||||
{ NULL, MATCH_UNKNOWN },
|
||||
};
|
||||
|
||||
static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
unsigned int count, int *parsing);
|
||||
unsigned int count, int *parsing, int seen[]);
|
||||
|
||||
static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
|
||||
int i;
|
||||
@@ -195,47 +227,137 @@ static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
|
||||
return SOC_UNKNOWN;
|
||||
}
|
||||
|
||||
static void
|
||||
local_parse_file(ssh_session session,
|
||||
const char *filename,
|
||||
int *parsing)
|
||||
{
|
||||
FILE *f;
|
||||
char line[MAX_LINE_SIZE] = {0};
|
||||
unsigned int count = 0;
|
||||
int rv;
|
||||
static char *ssh_config_get_cmd(char **str) {
|
||||
register char *c;
|
||||
char *r;
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
||||
filename);
|
||||
return;
|
||||
/* Ignore leading spaces */
|
||||
for (c = *str; *c; c++) {
|
||||
if (! isblank(*c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading additional configuration data from %s", filename);
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
count++;
|
||||
rv = ssh_config_parse_line(session, line, count, parsing);
|
||||
if (rv < 0) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
if (*c == '\"') {
|
||||
for (r = ++c; *c; c++) {
|
||||
if (*c == '\"') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
for (r = c; *c; c++) {
|
||||
if (*c == '\n') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*str = c + 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static char *ssh_config_get_token(char **str) {
|
||||
register char *c;
|
||||
char *r;
|
||||
|
||||
c = ssh_config_get_cmd(str);
|
||||
|
||||
for (r = c; *c; c++) {
|
||||
if (isblank(*c) || *c == '=') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*str = c + 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static long ssh_config_get_long(char **str, long notfound) {
|
||||
char *p, *endp;
|
||||
long i;
|
||||
|
||||
p = ssh_config_get_token(str);
|
||||
if (p && *p) {
|
||||
i = strtol(p, &endp, 10);
|
||||
if (p == endp) {
|
||||
return notfound;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
return notfound;
|
||||
}
|
||||
|
||||
static const char *ssh_config_get_str_tok(char **str, const char *def) {
|
||||
char *p;
|
||||
|
||||
p = ssh_config_get_token(str);
|
||||
if (p && *p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
static int ssh_config_get_yesno(char **str, int notfound) {
|
||||
const char *p;
|
||||
|
||||
p = ssh_config_get_str_tok(str, NULL);
|
||||
if (p == NULL) {
|
||||
return notfound;
|
||||
}
|
||||
|
||||
if (strncasecmp(p, "yes", 3) == 0) {
|
||||
return 1;
|
||||
} else if (strncasecmp(p, "no", 2) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return notfound;
|
||||
}
|
||||
|
||||
static void local_parse_file(ssh_session session, const char *filename, int *parsing, int seen[]) {
|
||||
FILE *f;
|
||||
char line[MAX_LINE_SIZE] = {0};
|
||||
unsigned int count = 0;
|
||||
|
||||
if ((f = fopen(filename, "r")) == NULL) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading additional configuration data from %s", filename);
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
count++;
|
||||
if (ssh_config_parse_line(session, line, count, parsing, seen) < 0) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||
static void local_parse_glob(ssh_session session,
|
||||
const char *fileglob,
|
||||
int *parsing)
|
||||
int *parsing,
|
||||
int seen[])
|
||||
{
|
||||
glob_t globbuf = {
|
||||
.gl_flags = 0,
|
||||
};
|
||||
int rt;
|
||||
size_t i;
|
||||
u_int i;
|
||||
|
||||
rt = glob(fileglob, GLOB_TILDE, NULL, &globbuf);
|
||||
if (rt == GLOB_NOMATCH) {
|
||||
@@ -249,7 +371,7 @@ static void local_parse_glob(ssh_session session,
|
||||
}
|
||||
|
||||
for (i = 0; i < globbuf.gl_pathc; i++) {
|
||||
local_parse_file(session, globbuf.gl_pathv[i], parsing);
|
||||
local_parse_file(session, globbuf.gl_pathv[i], parsing, seen);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
@@ -274,8 +396,10 @@ static int
|
||||
ssh_config_match(char *value, const char *pattern, bool negate)
|
||||
{
|
||||
int ok, result = 0;
|
||||
char *lowervalue;
|
||||
|
||||
ok = match_pattern_list(value, pattern, strlen(pattern), 0);
|
||||
lowervalue = (value) ? ssh_lowercase(value) : NULL;
|
||||
ok = match_pattern_list(lowervalue, pattern, strlen(pattern), 0);
|
||||
if (ok <= 0 && negate == true) {
|
||||
result = 1;
|
||||
} else if (ok > 0 && negate == false) {
|
||||
@@ -284,115 +408,20 @@ 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;
|
||||
}
|
||||
|
||||
/* @brief: Parse the ProxyJump configuration line and if parsing,
|
||||
* stores the result in the configuration option
|
||||
*/
|
||||
static int
|
||||
ssh_config_parse_proxy_jump(ssh_session session, const char *s, bool do_parsing)
|
||||
{
|
||||
char *c = NULL, *cp = NULL, *endp = NULL;
|
||||
char *username = NULL;
|
||||
char *hostname = NULL;
|
||||
char *port = NULL;
|
||||
char *next = NULL;
|
||||
int cmp, rv = SSH_ERROR;
|
||||
bool parse_entry = do_parsing;
|
||||
|
||||
/* Special value none disables the proxy */
|
||||
cmp = strcasecmp(s, "none");
|
||||
if (cmp == 0 && do_parsing) {
|
||||
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, s);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/* This is comma-separated list of [user@]host[:port] entries */
|
||||
c = strdup(s);
|
||||
if (c == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
cp = c;
|
||||
do {
|
||||
endp = strchr(cp, ',');
|
||||
if (endp != NULL) {
|
||||
/* Split out the token */
|
||||
*endp = '\0';
|
||||
}
|
||||
if (parse_entry) {
|
||||
/* We actually care only about the first item */
|
||||
rv = ssh_config_parse_uri(cp, &username, &hostname, &port);
|
||||
/* The rest of the list needs to be passed on */
|
||||
if (endp != NULL) {
|
||||
next = strdup(endp + 1);
|
||||
if (next == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
rv = SSH_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* The rest is just sanity-checked to avoid failures later */
|
||||
rv = ssh_config_parse_uri(cp, NULL, NULL, NULL);
|
||||
}
|
||||
if (rv != SSH_OK) {
|
||||
goto out;
|
||||
}
|
||||
parse_entry = 0;
|
||||
if (endp != NULL) {
|
||||
cp = endp + 1;
|
||||
} else {
|
||||
cp = NULL; /* end */
|
||||
}
|
||||
} while (cp != NULL);
|
||||
|
||||
if (hostname != NULL && do_parsing) {
|
||||
char com[512] = {0};
|
||||
|
||||
rv = snprintf(com, sizeof(com), "ssh%s%s%s%s%s%s -W [%%h]:%%p %s",
|
||||
username ? " -l " : "",
|
||||
username ? username : "",
|
||||
port ? " -p " : "",
|
||||
port ? port : "",
|
||||
next ? " -J " : "",
|
||||
next ? next : "",
|
||||
hostname);
|
||||
if (rv < 0 || rv >= (int)sizeof(com)) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Too long ProxyJump configuration line");
|
||||
rv = SSH_ERROR;
|
||||
goto out;
|
||||
}
|
||||
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, com);
|
||||
}
|
||||
rv = SSH_OK;
|
||||
|
||||
out:
|
||||
SAFE_FREE(username);
|
||||
SAFE_FREE(hostname);
|
||||
SAFE_FREE(port);
|
||||
SAFE_FREE(next);
|
||||
SAFE_FREE(c);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_config_parse_line(ssh_session session,
|
||||
const char *line,
|
||||
unsigned int count,
|
||||
int *parsing)
|
||||
{
|
||||
static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
unsigned int count, int *parsing, int seen[]) {
|
||||
enum ssh_config_opcode_e opcode;
|
||||
const char *p = NULL, *p2 = NULL;
|
||||
char *s = NULL, *x = NULL;
|
||||
char *keyword = NULL;
|
||||
char *lowerhost = NULL;
|
||||
const char *p;
|
||||
char *s, *x;
|
||||
char *keyword;
|
||||
char *lowerhost;
|
||||
size_t len;
|
||||
int i, rv;
|
||||
uint8_t *seen = session->opts.options_seen;
|
||||
int i;
|
||||
long l;
|
||||
int64_t ll;
|
||||
|
||||
x = s = strdup(line);
|
||||
if (s == NULL) {
|
||||
@@ -421,7 +450,6 @@ ssh_config_parse_line(ssh_session session,
|
||||
opcode != SOC_MATCH &&
|
||||
opcode != SOC_INCLUDE &&
|
||||
opcode > SOC_UNSUPPORTED) { /* Ignore all unknown types here */
|
||||
/* Skip all the options that were already applied */
|
||||
if (seen[opcode] != 0) {
|
||||
SAFE_FREE(x);
|
||||
return 0;
|
||||
@@ -435,9 +463,9 @@ ssh_config_parse_line(ssh_session session,
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
|
||||
local_parse_glob(session, p, parsing);
|
||||
local_parse_glob(session, p, parsing, seen);
|
||||
#else
|
||||
local_parse_file(session, p, parsing);
|
||||
local_parse_file(session, p, parsing, seen);
|
||||
#endif /* HAVE_GLOB */
|
||||
}
|
||||
break;
|
||||
@@ -447,11 +475,10 @@ 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 {
|
||||
p = p2 = ssh_config_get_str_tok(&s, NULL);
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
break;
|
||||
}
|
||||
@@ -470,10 +497,8 @@ ssh_config_parse_line(ssh_session session,
|
||||
switch (opt) {
|
||||
case MATCH_ALL:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (args <= 2 && (p == NULL || p[0] == '\0')) {
|
||||
/* The first or second, but last argument. The "all" keyword
|
||||
* can be prefixed with either "final" or "canonical"
|
||||
* keywords which do not have any effect here. */
|
||||
if (args == 1 && (p == NULL || p[0] == '\0')) {
|
||||
/* The first argument and end of line */
|
||||
if (negate == true) {
|
||||
result = 0;
|
||||
}
|
||||
@@ -481,74 +506,21 @@ ssh_config_parse_line(ssh_session session,
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"line %d: ERROR - Match all cannot be combined with "
|
||||
"line %d: ERROR - Match all can not be combined with "
|
||||
"other Match attributes", count);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
|
||||
case MATCH_FINAL:
|
||||
case MATCH_CANONICAL:
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Unsupported Match keyword '%s', skipping",
|
||||
count,
|
||||
p);
|
||||
/* Not set any result here -- the result is dependent on the
|
||||
* following matches after this keyword */
|
||||
break;
|
||||
|
||||
case MATCH_EXEC:
|
||||
/* Skip to the end of line as unsupported */
|
||||
p = ssh_config_get_cmd(&s);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
|
||||
"'%s' requires argument", count, p2);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
args++;
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Unsupported Match keyword '%s', ignoring",
|
||||
count,
|
||||
p2);
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
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:
|
||||
case MATCH_LOCALUSER:
|
||||
/* Skip one argument */
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL || p[0] == '\0') {
|
||||
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
|
||||
"'%s' requires argument", count, p2);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
args++;
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"line %d: Unsupported Match keyword '%s', ignoring",
|
||||
count,
|
||||
p2);
|
||||
FALL_THROUGH;
|
||||
case MATCH_CANONICAL:
|
||||
SSH_LOG(SSH_LOG_WARN, "line: %d: Unsupported Match keyword "
|
||||
"'%s', Ignoring\n", count, p);
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
@@ -723,25 +695,10 @@ ssh_config_parse_line(ssh_session session,
|
||||
break;
|
||||
case SOC_PROXYCOMMAND:
|
||||
p = ssh_config_get_cmd(&s);
|
||||
/* We share the seen value with the ProxyJump */
|
||||
if (p && *parsing && !seen[SOC_PROXYJUMP]) {
|
||||
if (p && *parsing) {
|
||||
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, p);
|
||||
}
|
||||
break;
|
||||
case SOC_PROXYJUMP:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL) {
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
/* We share the seen value with the ProxyCommand */
|
||||
rv = ssh_config_parse_proxy_jump(session, p,
|
||||
(*parsing && !seen[SOC_PROXYCOMMAND]));
|
||||
if (rv != SSH_OK) {
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SOC_GSSAPISERVERIDENTITY:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
@@ -815,141 +772,6 @@ ssh_config_parse_line(ssh_session session,
|
||||
ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, p);
|
||||
}
|
||||
break;
|
||||
case SOC_REKEYLIMIT:
|
||||
/* Parse the data limit */
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
} else if (strcmp(p, "default") == 0) {
|
||||
/* Default rekey limits enforced automaticaly */
|
||||
ll = 0;
|
||||
} else {
|
||||
char *endp = NULL;
|
||||
ll = strtoll(p, &endp, 10);
|
||||
if (p == endp || ll < 0) {
|
||||
/* No number or negative */
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit");
|
||||
break;
|
||||
}
|
||||
switch (*endp) {
|
||||
case 'G':
|
||||
if (ll > LLONG_MAX / 1024) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 1024;
|
||||
FALL_THROUGH;
|
||||
case 'M':
|
||||
if (ll > LLONG_MAX / 1024) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 1024;
|
||||
FALL_THROUGH;
|
||||
case 'K':
|
||||
if (ll > LLONG_MAX / 1024) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 1024;
|
||||
endp++;
|
||||
FALL_THROUGH;
|
||||
case '\0':
|
||||
/* just the number */
|
||||
break;
|
||||
default:
|
||||
/* Invalid suffix */
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
if (*endp != ' ' && *endp != '\0') {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Invalid trailing characters after the rekey limit: %s",
|
||||
endp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ll > -1 && *parsing) {
|
||||
uint64_t v = (uint64_t)ll;
|
||||
ssh_options_set(session, SSH_OPTIONS_REKEY_DATA, &v);
|
||||
}
|
||||
/* Parse the time limit */
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
} else if (strcmp(p, "none") == 0) {
|
||||
ll = 0;
|
||||
} else {
|
||||
char *endp = NULL;
|
||||
ll = strtoll(p, &endp, 10);
|
||||
if (p == endp || ll < 0) {
|
||||
/* No number or negative */
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit");
|
||||
break;
|
||||
}
|
||||
switch (*endp) {
|
||||
case 'w':
|
||||
case 'W':
|
||||
if (ll > LLONG_MAX / 7) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 7;
|
||||
FALL_THROUGH;
|
||||
case 'd':
|
||||
case 'D':
|
||||
if (ll > LLONG_MAX / 24) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 24;
|
||||
FALL_THROUGH;
|
||||
case 'h':
|
||||
case 'H':
|
||||
if (ll > LLONG_MAX / 60) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 60;
|
||||
FALL_THROUGH;
|
||||
case 'm':
|
||||
case 'M':
|
||||
if (ll > LLONG_MAX / 60) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
ll = ll * 60;
|
||||
FALL_THROUGH;
|
||||
case 's':
|
||||
case 'S':
|
||||
endp++;
|
||||
FALL_THROUGH;
|
||||
case '\0':
|
||||
/* just the number */
|
||||
break;
|
||||
default:
|
||||
/* Invalid suffix */
|
||||
ll = -1;
|
||||
break;
|
||||
}
|
||||
if (*endp != '\0') {
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid trailing characters after the"
|
||||
" rekey limit: %s", endp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ll > -1 && *parsing) {
|
||||
uint32_t v = (uint32_t)ll;
|
||||
ssh_options_set(session, SSH_OPTIONS_REKEY_TIME, &v);
|
||||
}
|
||||
break;
|
||||
case SOC_GSSAPIAUTHENTICATION:
|
||||
case SOC_KBDINTERACTIVEAUTHENTICATION:
|
||||
case SOC_PASSWORDAUTHENTICATION:
|
||||
@@ -976,7 +798,7 @@ ssh_config_parse_line(ssh_session session,
|
||||
}
|
||||
break;
|
||||
case SOC_NA:
|
||||
SSH_LOG(SSH_LOG_INFO, "Unapplicable option: %s, line: %d",
|
||||
SSH_LOG(SSH_LOG_INFO, "Unapplicable option: %s, line: %d\n",
|
||||
keyword, count);
|
||||
break;
|
||||
case SOC_UNSUPPORTED:
|
||||
@@ -984,7 +806,7 @@ ssh_config_parse_line(ssh_session session,
|
||||
keyword, count);
|
||||
break;
|
||||
case SOC_UNKNOWN:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d",
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d\n",
|
||||
keyword, count);
|
||||
break;
|
||||
default:
|
||||
@@ -999,37 +821,29 @@ ssh_config_parse_line(ssh_session session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* @brief Parse configuration file and set the options to the given session
|
||||
*
|
||||
* @params[in] session The ssh session
|
||||
* @params[in] filename The path to the ssh configuration file
|
||||
*
|
||||
* @returns 0 on successful parsing the configuration file, -1 on error
|
||||
*/
|
||||
int ssh_config_parse_file(ssh_session session, const char *filename)
|
||||
{
|
||||
char line[MAX_LINE_SIZE] = {0};
|
||||
unsigned int count = 0;
|
||||
FILE *f;
|
||||
int parsing, rv;
|
||||
/* ssh_config_parse_file */
|
||||
int ssh_config_parse_file(ssh_session session, const char *filename) {
|
||||
char line[MAX_LINE_SIZE] = {0};
|
||||
unsigned int count = 0;
|
||||
FILE *f;
|
||||
int parsing;
|
||||
int seen[SOC_END - SOC_UNSUPPORTED] = {0};
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
|
||||
|
||||
parsing = 1;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
count++;
|
||||
rv = ssh_config_parse_line(session, line, count, &parsing);
|
||||
if (rv < 0) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
if ((f = fopen(filename, "r")) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
|
||||
|
||||
parsing = 1;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
count++;
|
||||
if (ssh_config_parse_line(session, line, count, &parsing, seen) < 0) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* config_parser.c - Common configuration file parser functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libssh/config_parser.h"
|
||||
#include "libssh/priv.h"
|
||||
|
||||
char *ssh_config_get_cmd(char **str)
|
||||
{
|
||||
register char *c;
|
||||
char *r;
|
||||
|
||||
/* Ignore leading spaces */
|
||||
for (c = *str; *c; c++) {
|
||||
if (! isblank(*c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*c == '\"') {
|
||||
for (r = ++c; *c; c++) {
|
||||
if (*c == '\"') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (r = c; *c; c++) {
|
||||
if (*c == '\n') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*str = c + 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
char *ssh_config_get_token(char **str)
|
||||
{
|
||||
register char *c;
|
||||
char *r;
|
||||
|
||||
c = ssh_config_get_cmd(str);
|
||||
|
||||
for (r = c; *c; c++) {
|
||||
if (isblank(*c) || *c == '=') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*str = c + 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
long ssh_config_get_long(char **str, long notfound)
|
||||
{
|
||||
char *p, *endp;
|
||||
long i;
|
||||
|
||||
p = ssh_config_get_token(str);
|
||||
if (p && *p) {
|
||||
i = strtol(p, &endp, 10);
|
||||
if (p == endp) {
|
||||
return notfound;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
return notfound;
|
||||
}
|
||||
|
||||
const char *ssh_config_get_str_tok(char **str, const char *def)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = ssh_config_get_token(str);
|
||||
if (p && *p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
int ssh_config_get_yesno(char **str, int notfound)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = ssh_config_get_str_tok(str, NULL);
|
||||
if (p == NULL) {
|
||||
return notfound;
|
||||
}
|
||||
|
||||
if (strncasecmp(p, "yes", 3) == 0) {
|
||||
return 1;
|
||||
} else if (strncasecmp(p, "no", 2) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return notfound;
|
||||
}
|
||||
|
||||
int ssh_config_parse_uri(const char *tok,
|
||||
char **username,
|
||||
char **hostname,
|
||||
char **port)
|
||||
{
|
||||
char *endp = NULL;
|
||||
long port_n;
|
||||
|
||||
/* Sanitize inputs */
|
||||
if (username != NULL) {
|
||||
*username = NULL;
|
||||
}
|
||||
if (hostname != NULL) {
|
||||
*hostname = NULL;
|
||||
}
|
||||
if (port != NULL) {
|
||||
*port = NULL;
|
||||
}
|
||||
|
||||
/* Username part (optional) */
|
||||
endp = strchr(tok, '@');
|
||||
if (endp != NULL) {
|
||||
/* Zero-length username is not valid */
|
||||
if (tok == endp) {
|
||||
goto error;
|
||||
}
|
||||
if (username != NULL) {
|
||||
*username = strndup(tok, endp - tok);
|
||||
if (*username == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
tok = endp + 1;
|
||||
/* If there is second @ character, this does not look like our URI */
|
||||
endp = strchr(tok, '@');
|
||||
if (endp != NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hostname */
|
||||
if (*tok == '[') {
|
||||
/* IPv6 address is enclosed with square brackets */
|
||||
tok++;
|
||||
endp = strchr(tok, ']');
|
||||
if (endp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
/* Hostnames or aliases expand to the last colon or to the end */
|
||||
endp = strrchr(tok, ':');
|
||||
if (endp == NULL) {
|
||||
endp = strchr(tok, '\0');
|
||||
}
|
||||
}
|
||||
if (tok == endp) {
|
||||
/* Zero-length hostnames are not valid */
|
||||
goto error;
|
||||
}
|
||||
if (hostname != NULL) {
|
||||
*hostname = strndup(tok, endp - tok);
|
||||
if (*hostname == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* Skip also the closing bracket */
|
||||
if (*endp == ']') {
|
||||
endp++;
|
||||
}
|
||||
|
||||
/* Port (optional) */
|
||||
if (*endp != '\0') {
|
||||
char *port_end = NULL;
|
||||
|
||||
/* Verify the port is valid positive number */
|
||||
port_n = strtol(endp + 1, &port_end, 10);
|
||||
if (port_n < 1 || *port_end != '\0') {
|
||||
SSH_LOG(SSH_LOG_WARN, "Failed to parse port number."
|
||||
" The value '%ld' is invalid or there are some"
|
||||
" trailing characters: '%s'", port_n, port_end);
|
||||
goto error;
|
||||
}
|
||||
if (port != NULL) {
|
||||
*port = strdup(endp + 1);
|
||||
if (*port == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
|
||||
error:
|
||||
if (username != NULL) {
|
||||
SAFE_FREE(*username);
|
||||
}
|
||||
if (hostname != NULL) {
|
||||
SAFE_FREE(*hostname);
|
||||
}
|
||||
if (port != NULL) {
|
||||
SAFE_FREE(*port);
|
||||
}
|
||||
return SSH_ERROR;
|
||||
}
|
||||
542
src/connect.c
542
src/connect.c
@@ -90,55 +90,131 @@
|
||||
|
||||
#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];
|
||||
|
||||
ZERO_STRUCT(hints);
|
||||
static int getai(const char *host, int port, struct addrinfo **ai) {
|
||||
const char *service = NULL;
|
||||
struct addrinfo hints;
|
||||
char s_port[10];
|
||||
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
ZERO_STRUCT(hints);
|
||||
|
||||
if (port == 0) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
} else {
|
||||
snprintf(s_port, sizeof(s_port), "%hu", (unsigned short)port);
|
||||
service = s_port;
|
||||
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;
|
||||
#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);
|
||||
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;
|
||||
}
|
||||
|
||||
static int set_tcp_nodelay(socket_t socket)
|
||||
@@ -152,6 +228,99 @@ 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
|
||||
*
|
||||
@@ -162,109 +331,102 @@ static int set_tcp_nodelay(socket_t socket)
|
||||
* @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 = NULL;
|
||||
struct addrinfo *itr = NULL;
|
||||
const char *bind_addr, int port) {
|
||||
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));
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
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);
|
||||
|
||||
if (bind_addr) {
|
||||
struct addrinfo *bind_ai;
|
||||
struct addrinfo *bind_itr;
|
||||
/* Cannot bind to any local addresses */
|
||||
if (bind_itr == NULL) {
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
|
||||
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;
|
||||
}
|
||||
|
||||
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 (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 socket non-blocking for %s:%d",
|
||||
host, port);
|
||||
"Failed to set TCP_NODELAY on socket: %s", strerror(errno));
|
||||
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;
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
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;
|
||||
}
|
||||
|
||||
return s;
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,13 +435,11 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,84 +473,72 @@ 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;
|
||||
int 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);
|
||||
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);
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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++) {
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
outchannels[j] = NULL;
|
||||
if(j != 0)
|
||||
break;
|
||||
/* watch if a user socket was triggered */
|
||||
for (fd = 0; fd < maxfd; fd++) {
|
||||
if (FD_ISSET(fd, &origfds)) {
|
||||
ssh_event_remove_fd(event, fd);
|
||||
if (FD_ISSET(fd, readfds)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ssh_event_free(event);
|
||||
return SSH_OK;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
ssh_event_free(event);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -267,13 +267,8 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
|
||||
|
||||
if (connector->out_channel != NULL) {
|
||||
if (r == 0) {
|
||||
SSH_LOG(SSH_LOG_TRACE, "input fd %d is EOF", connector->in_fd);
|
||||
if (connector->out_channel->local_eof == 0) {
|
||||
rc = ssh_channel_send_eof(connector->out_channel);
|
||||
(void)rc; /* TODO Handle rc? */
|
||||
}
|
||||
connector->in_available = 1; /* Don't poll on it */
|
||||
return;
|
||||
rc = ssh_channel_send_eof(connector->out_channel);
|
||||
(void)rc; /* TODO Handle rc? */
|
||||
} else if (r> 0) {
|
||||
/* loop around ssh_channel_write in case our window reduced due to a race */
|
||||
while (total != r){
|
||||
@@ -294,7 +289,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
|
||||
}
|
||||
} else if (connector->out_fd != SSH_INVALID_SOCKET) {
|
||||
if (r == 0){
|
||||
close(connector->out_fd);
|
||||
close (connector->out_fd);
|
||||
connector->out_fd = SSH_INVALID_SOCKET;
|
||||
} else {
|
||||
/*
|
||||
@@ -646,12 +641,14 @@ int ssh_connector_remove_event(ssh_connector connector) {
|
||||
session = ssh_channel_get_session(connector->in_channel);
|
||||
|
||||
ssh_event_remove_session(connector->event, session);
|
||||
connector->in_channel = NULL;
|
||||
}
|
||||
|
||||
if (connector->out_channel != NULL) {
|
||||
session = ssh_channel_get_session(connector->out_channel);
|
||||
|
||||
ssh_event_remove_session(connector->event, session);
|
||||
connector->out_channel = NULL;
|
||||
}
|
||||
connector->event = NULL;
|
||||
|
||||
|
||||
351
src/curve25519.c
351
src/curve25519.c
@@ -39,240 +39,75 @@
|
||||
#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[] = {
|
||||
ssh_packet_client_curve25519_reply
|
||||
};
|
||||
|
||||
static struct ssh_packet_callbacks_struct ssh_curve25519_client_callbacks = {
|
||||
.start = SSH2_MSG_KEX_ECDH_REPLY,
|
||||
.n_callbacks = 1,
|
||||
.callbacks = dh_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 ssh_client_curve25519_init(ssh_session session){
|
||||
int rc;
|
||||
int ok;
|
||||
|
||||
rc = ssh_curve25519_init(session);
|
||||
if (rc != SSH_OK) {
|
||||
return 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_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;
|
||||
}
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
|
||||
return rc;
|
||||
rc = ssh_packet_send(session);
|
||||
|
||||
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;
|
||||
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = NULL, *pubkey = NULL;
|
||||
size_t shared_key_len;
|
||||
int rc;
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
session->next_crypto->k = bignum_new();
|
||||
|
||||
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;
|
||||
}
|
||||
if (session->next_crypto->k == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
session->next_crypto->k = bignum_new();
|
||||
|
||||
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));
|
||||
EVP_PKEY_free(pkey);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (session->next_crypto->k == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
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));
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
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);
|
||||
|
||||
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));
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
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));
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_free(pubkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
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));
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_free(pubkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#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 HAVE_LIBGCRYPT
|
||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->k);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_log_hexdump("Session server cookie",
|
||||
ssh_print_hexa("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_log_hexdump("Session client cookie",
|
||||
ssh_print_hexa("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->k);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -282,15 +117,11 @@ static int ssh_curve25519_build_k(ssh_session session)
|
||||
* @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
|
||||
* a SSH_MSG_NEWKEYS
|
||||
*/
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
|
||||
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){
|
||||
ssh_string q_s_string = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
ssh_string signature = NULL;
|
||||
int rc;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_curve25519_client_callbacks);
|
||||
|
||||
pubkey_blob = ssh_buffer_get_ssh_string(packet);
|
||||
if (pubkey_blob == NULL) {
|
||||
@@ -340,47 +171,18 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
|
||||
}
|
||||
|
||||
rc=ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
return rc;
|
||||
error:
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init);
|
||||
|
||||
static ssh_packet_callback dh_server_callbacks[]= {
|
||||
ssh_packet_server_curve25519_init
|
||||
};
|
||||
|
||||
static struct ssh_packet_callbacks_struct ssh_curve25519_server_callbacks = {
|
||||
.start = SSH2_MSG_KEX_ECDH_INIT,
|
||||
.n_callbacks = 1,
|
||||
.callbacks = dh_server_callbacks,
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief sets up the curve25519-sha256@libssh.org kex callbacks
|
||||
*/
|
||||
void ssh_server_curve25519_init(ssh_session session){
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_curve25519_server_callbacks);
|
||||
}
|
||||
|
||||
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||
* SSH_MSG_KEXDH_REPLY
|
||||
*/
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
||||
/* ECDH keys */
|
||||
ssh_string q_c_string;
|
||||
ssh_string q_s_string;
|
||||
@@ -388,40 +190,37 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
|
||||
/* SSH host keys (rsa,dsa,ecdsa) */
|
||||
ssh_key privkey;
|
||||
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
|
||||
ssh_string sig_blob = NULL;
|
||||
int ok;
|
||||
int rc;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_curve25519_server_callbacks);
|
||||
|
||||
/* Extract the client pubkey from the init packet */
|
||||
q_c_string = ssh_buffer_get_ssh_string(packet);
|
||||
if (q_c_string == NULL) {
|
||||
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Incorrect size for server Curve25519 public key: %zu",
|
||||
ssh_string_len(q_c_string));
|
||||
ssh_string_free(q_c_string);
|
||||
goto error;
|
||||
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
||||
(int)ssh_string_len(q_c_string));
|
||||
ssh_string_free(q_c_string);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
memcpy(session->next_crypto->curve25519_client_pubkey,
|
||||
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
|
||||
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
|
||||
ssh_string_free(q_c_string);
|
||||
/* Build server's keypair */
|
||||
|
||||
rc = ssh_curve25519_init(session);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Failed to generate curve25519 keys");
|
||||
goto error;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -436,7 +235,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
@@ -479,7 +278,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
goto error;
|
||||
}
|
||||
/* add signature blob */
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
goto error;
|
||||
@@ -506,16 +305,12 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
|
||||
|
||||
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
return rc;
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
684
src/dh-gex.c
684
src/dh-gex.c
@@ -1,684 +0,0 @@
|
||||
/*
|
||||
* dh-gex.c - diffie-hellman group exchange
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.be>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/dh-gex.h"
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/callbacks.h"
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/session.h"
|
||||
|
||||
/* Minimum, recommanded and maximum size of DH group */
|
||||
#define DH_PMIN 2048
|
||||
#define DH_PREQ 2048
|
||||
#define DH_PMAX 8192
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group);
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply);
|
||||
|
||||
static ssh_packet_callback dhgex_client_callbacks[] = {
|
||||
ssh_packet_client_dhgex_group, /* SSH_MSG_KEX_DH_GEX_GROUP */
|
||||
NULL, /* SSH_MSG_KEX_DH_GEX_INIT */
|
||||
ssh_packet_client_dhgex_reply /* SSH_MSG_KEX_DH_GEX_REPLY */
|
||||
};
|
||||
|
||||
static struct ssh_packet_callbacks_struct ssh_dhgex_client_callbacks = {
|
||||
.start = SSH2_MSG_KEX_DH_GEX_GROUP,
|
||||
.n_callbacks = 3,
|
||||
.callbacks = dhgex_client_callbacks,
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief initiates a diffie-hellman-group-exchange kex
|
||||
*/
|
||||
int ssh_client_dhgex_init(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_dh_init_common(session->next_crypto);
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->next_crypto->dh_pmin = DH_PMIN;
|
||||
session->next_crypto->dh_pn = DH_PREQ;
|
||||
session->next_crypto->dh_pmax = DH_PMAX;
|
||||
/* Minimum group size, preferred group size, maximum group size */
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bddd",
|
||||
SSH2_MSG_KEX_DH_GEX_REQUEST,
|
||||
session->next_crypto->dh_pmin,
|
||||
session->next_crypto->dh_pn,
|
||||
session->next_crypto->dh_pmax);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_dhgex_client_callbacks);
|
||||
session->dh_handshake_state = DH_STATE_REQUEST_SENT;
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
return rc;
|
||||
error:
|
||||
ssh_dh_cleanup(session->next_crypto);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief handle a DH_GEX_GROUP packet, client side. This packet contains
|
||||
* the group parameters.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
|
||||
{
|
||||
int rc;
|
||||
int blen;
|
||||
bignum pmin1 = NULL, one = NULL;
|
||||
bignum_CTX ctx = bignum_ctx_new();
|
||||
bignum modulus = NULL, generator = NULL;
|
||||
const_bignum pubkey;
|
||||
(void) type;
|
||||
(void) user;
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_GROUP received");
|
||||
|
||||
if (bignum_ctx_invalid(ctx)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (session->dh_handshake_state != DH_STATE_REQUEST_SENT) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Received DH_GEX_GROUP in invalid state");
|
||||
goto error;
|
||||
}
|
||||
one = bignum_new();
|
||||
pmin1 = bignum_new();
|
||||
if (one == NULL || pmin1 == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_buffer_unpack(packet,
|
||||
"BB",
|
||||
&modulus,
|
||||
&generator);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_GROUP packet");
|
||||
goto error;
|
||||
}
|
||||
/* basic checks */
|
||||
if (ssh_fips_mode() &&
|
||||
!ssh_dh_is_known_group(modulus, generator)) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"The received DH group is not FIPS approved");
|
||||
goto error;
|
||||
}
|
||||
rc = bignum_set_word(one, 1);
|
||||
if (rc != 1) {
|
||||
goto error;
|
||||
}
|
||||
blen = bignum_num_bits(modulus);
|
||||
if (blen < DH_PMIN || blen > DH_PMAX) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Invalid dh group parameter p: %d not in [%d:%d]",
|
||||
blen,
|
||||
DH_PMIN,
|
||||
DH_PMAX);
|
||||
goto error;
|
||||
}
|
||||
if (bignum_cmp(modulus, one) <= 0) {
|
||||
/* p must be positive and preferably bigger than one */
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
|
||||
}
|
||||
if (!bignum_is_bit_set(modulus, 0)) {
|
||||
/* p must be a prime and therefore not divisible by 2 */
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
|
||||
goto error;
|
||||
}
|
||||
bignum_sub(pmin1, modulus, one);
|
||||
if (bignum_cmp(generator, one) <= 0 ||
|
||||
bignum_cmp(generator, pmin1) > 0) {
|
||||
/* generator must be at least 2 and smaller than p-1*/
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter g");
|
||||
goto error;
|
||||
}
|
||||
bignum_ctx_free(ctx);
|
||||
ctx = NULL;
|
||||
|
||||
/* 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) {
|
||||
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,
|
||||
DH_CLIENT_KEYPAIR);
|
||||
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,
|
||||
pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
bignum_safe_free(one);
|
||||
bignum_safe_free(pmin1);
|
||||
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)) {
|
||||
bignum_ctx_free(ctx);
|
||||
}
|
||||
ssh_dh_cleanup(session->next_crypto);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto=session->next_crypto;
|
||||
int rc;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
bignum server_pubkey = NULL;
|
||||
(void)type;
|
||||
(void)user;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_REPLY received");
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_dhgex_client_callbacks);
|
||||
rc = ssh_buffer_unpack(packet,
|
||||
"SBS",
|
||||
&pubkey_blob, &server_pubkey,
|
||||
&crypto->dh_server_signature);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_REPLY packet");
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
|
||||
NULL, server_pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
bignum_safe_free(server_pubkey);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||
ssh_string_free(pubkey_blob);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Send the MSG_NEWKEYS */
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
error:
|
||||
ssh_dh_cleanup(session->next_crypto);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
#define MODULI_FILE "/etc/ssh/moduli"
|
||||
/* 2 "Safe" prime; (p-1)/2 is also prime. */
|
||||
#define SAFE_PRIME 2
|
||||
/* 0x04 Probabilistic Miller-Rabin primality tests. */
|
||||
#define PRIM_TEST_REQUIRED 0x04
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Determines if the proposed modulus size is more appropriate than the
|
||||
* current one.
|
||||
*
|
||||
* @returns 1 if it's more appropriate. Returns 0 if same or less appropriate
|
||||
*/
|
||||
static bool dhgroup_better_size(uint32_t pmin,
|
||||
uint32_t pn,
|
||||
uint32_t pmax,
|
||||
size_t current_size,
|
||||
size_t proposed_size)
|
||||
{
|
||||
if (current_size == proposed_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current_size == pn) {
|
||||
/* can't do better */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current_size == 0 && proposed_size >= pmin && proposed_size <= pmax) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (proposed_size < pmin || proposed_size > pmax) {
|
||||
/* out of bounds */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current_size == 0) {
|
||||
/* not in the allowed window */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (proposed_size >= pn && proposed_size < current_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (proposed_size <= pn && proposed_size > current_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (proposed_size >= pn && current_size < pn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We're in the allowed window but a better match already exists. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief returns 1 with 1/n probability
|
||||
* @returns 1 on with P(1/n), 0 with P(n-1/n).
|
||||
*/
|
||||
static bool invn_chance(int n)
|
||||
{
|
||||
uint32_t nounce;
|
||||
ssh_get_random(&nounce, sizeof(nounce), 0);
|
||||
return (nounce % n) == 0;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief retrieves a DH group from an open moduli file.
|
||||
*/
|
||||
static int ssh_retrieve_dhgroup_file(FILE *moduli,
|
||||
uint32_t pmin,
|
||||
uint32_t pn,
|
||||
uint32_t pmax,
|
||||
size_t *best_size,
|
||||
char **best_generator,
|
||||
char **best_modulus)
|
||||
{
|
||||
char timestamp[32] = {0};
|
||||
char generator[32] = {0};
|
||||
char modulus[4096] = {0};
|
||||
size_t type, tests, tries, size, proposed_size;
|
||||
int firstbyte;
|
||||
int rc;
|
||||
size_t line = 0;
|
||||
size_t best_nlines = 0;
|
||||
|
||||
for(;;) {
|
||||
line++;
|
||||
firstbyte = getc(moduli);
|
||||
if (firstbyte == '#'){
|
||||
do {
|
||||
firstbyte = getc(moduli);
|
||||
} while(firstbyte != '\n' && firstbyte != EOF);
|
||||
continue;
|
||||
}
|
||||
if (firstbyte == EOF) {
|
||||
break;
|
||||
}
|
||||
ungetc(firstbyte, moduli);
|
||||
rc = fscanf(moduli,
|
||||
"%31s %zu %zu %zu %zu %31s %4095s\n",
|
||||
timestamp,
|
||||
&type,
|
||||
&tests,
|
||||
&tries,
|
||||
&size,
|
||||
generator,
|
||||
modulus);
|
||||
if (rc != 7){
|
||||
if (rc == EOF) {
|
||||
break;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_INFO, "Invalid moduli entry line %zu", line);
|
||||
do {
|
||||
firstbyte = getc(moduli);
|
||||
} while(firstbyte != '\n' && firstbyte != EOF);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we only want safe primes that were tested */
|
||||
if (type != SAFE_PRIME || !(tests & PRIM_TEST_REQUIRED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
proposed_size = size + 1;
|
||||
if (proposed_size != *best_size &&
|
||||
dhgroup_better_size(pmin, pn, pmax, *best_size, proposed_size)) {
|
||||
best_nlines = 0;
|
||||
*best_size = proposed_size;
|
||||
}
|
||||
if (proposed_size == *best_size) {
|
||||
best_nlines++;
|
||||
}
|
||||
|
||||
/* Use reservoir sampling algorithm */
|
||||
if (proposed_size == *best_size && invn_chance(best_nlines)) {
|
||||
SAFE_FREE(*best_generator);
|
||||
SAFE_FREE(*best_modulus);
|
||||
*best_generator = strdup(generator);
|
||||
if (*best_generator == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
*best_modulus = strdup(modulus);
|
||||
if (*best_modulus == NULL) {
|
||||
SAFE_FREE(*best_generator);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*best_size != 0) {
|
||||
SSH_LOG(SSH_LOG_INFO,
|
||||
"Selected %zu bits modulus out of %zu candidates in %zu lines",
|
||||
*best_size,
|
||||
best_nlines - 1,
|
||||
line);
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"No moduli found for [%u:%u:%u]",
|
||||
pmin,
|
||||
pn,
|
||||
pmax);
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief retrieves a DH group from the moduli file based on bits len parameters
|
||||
* @param[in] pmin minimum group size in bits
|
||||
* @param[in] pn preferred group size
|
||||
* @param[in] pmax maximum group size
|
||||
* @param[out] size size of the chosen modulus
|
||||
* @param[out] p modulus
|
||||
* @param[out] g generator
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
*/
|
||||
static int ssh_retrieve_dhgroup(uint32_t pmin,
|
||||
uint32_t pn,
|
||||
uint32_t pmax,
|
||||
size_t *size,
|
||||
bignum *p,
|
||||
bignum *g)
|
||||
{
|
||||
FILE *moduli = NULL;
|
||||
char *generator = NULL;
|
||||
char *modulus = NULL;
|
||||
int rc;
|
||||
|
||||
/* In FIPS mode, we can not negotiate arbitrary primes,
|
||||
* but just the approved ones */
|
||||
if (ssh_fips_mode()) {
|
||||
SSH_LOG(SSH_LOG_TRACE, "In FIPS mode, using built-in primes");
|
||||
return ssh_fallback_group(pmax, p, g);
|
||||
}
|
||||
|
||||
moduli = fopen(MODULI_FILE, "r");
|
||||
if (moduli == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"Unable to open moduli file: %s",
|
||||
strerror(errno));
|
||||
return ssh_fallback_group(pmax, p, g);
|
||||
}
|
||||
|
||||
*size = 0;
|
||||
*p = NULL;
|
||||
*g = NULL;
|
||||
|
||||
rc = ssh_retrieve_dhgroup_file(moduli,
|
||||
pmin,
|
||||
pn,
|
||||
pmax,
|
||||
size,
|
||||
&generator,
|
||||
&modulus);
|
||||
fclose(moduli);
|
||||
if (rc == SSH_ERROR || *size == 0) {
|
||||
goto error;
|
||||
}
|
||||
rc = bignum_hex2bn(generator, g);
|
||||
if (rc == 0) {
|
||||
goto error;
|
||||
}
|
||||
rc = bignum_hex2bn(modulus, p);
|
||||
if (rc == 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(generator);
|
||||
SAFE_FREE(modulus);
|
||||
|
||||
return SSH_OK;
|
||||
|
||||
error:
|
||||
bignum_safe_free(*g);
|
||||
bignum_safe_free(*p);
|
||||
SAFE_FREE(generator);
|
||||
SAFE_FREE(modulus);
|
||||
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request);
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_init);
|
||||
|
||||
static ssh_packet_callback dhgex_server_callbacks[]= {
|
||||
NULL, /* SSH_MSG_KEX_DH_GEX_REQUEST_OLD */
|
||||
NULL, /* SSH_MSG_KEX_DH_GEX_GROUP */
|
||||
ssh_packet_server_dhgex_init, /* SSH_MSG_KEX_DH_GEX_INIT */
|
||||
NULL, /* SSH_MSG_KEX_DH_GEX_REPLY */
|
||||
ssh_packet_server_dhgex_request /* SSH_MSG_GEX_DH_GEX_REQUEST */
|
||||
|
||||
};
|
||||
|
||||
static struct ssh_packet_callbacks_struct ssh_dhgex_server_callbacks = {
|
||||
.start = SSH2_MSG_KEX_DH_GEX_REQUEST_OLD,
|
||||
.n_callbacks = 5,
|
||||
.callbacks = dhgex_server_callbacks,
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief sets up the diffie-hellman-groupx kex callbacks
|
||||
*/
|
||||
void ssh_server_dhgex_init(ssh_session session){
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_dhgex_server_callbacks);
|
||||
ssh_dh_init_common(session->next_crypto);
|
||||
session->dh_handshake_state = DH_STATE_INIT;
|
||||
}
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
|
||||
{
|
||||
bignum modulus = NULL, generator = NULL;
|
||||
uint32_t pmin, pn, pmax;
|
||||
size_t size = 0;
|
||||
int rc;
|
||||
|
||||
(void) type;
|
||||
(void) user;
|
||||
|
||||
if (session->dh_handshake_state != DH_STATE_INIT) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Received DH_GEX_REQUEST in invalid state");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Minimum group size, preferred group size, maximum group size */
|
||||
rc = ssh_buffer_unpack(packet, "ddd", &pmin, &pn, &pmax);
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_invalid(session);
|
||||
goto error;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_INFO, "dh-gex: DHGEX_REQUEST[%u:%u:%u]", pmin, pn, pmax);
|
||||
|
||||
if (pmin > pn || pn > pmax || pn > DH_PMAX || pmax < DH_PMIN) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Invalid dh-gex arguments [%u:%u:%u]",
|
||||
pmin,
|
||||
pn,
|
||||
pmax);
|
||||
goto error;
|
||||
}
|
||||
session->next_crypto->dh_pmin = pmin;
|
||||
session->next_crypto->dh_pn = pn;
|
||||
session->next_crypto->dh_pmax = pmax;
|
||||
|
||||
/* ensure safe parameters */
|
||||
if (pmin < DH_PMIN) {
|
||||
pmin = DH_PMIN;
|
||||
if (pn < pmin) {
|
||||
pn = pmin;
|
||||
}
|
||||
}
|
||||
rc = ssh_retrieve_dhgroup(pmin,
|
||||
pn,
|
||||
pmax,
|
||||
&size,
|
||||
&modulus,
|
||||
&generator);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Couldn't find DH group for [%u:%u:%u]",
|
||||
pmin,
|
||||
pn,
|
||||
pmax);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_dh_set_parameters(session->next_crypto->dh_ctx,
|
||||
modulus, generator);
|
||||
if (rc != SSH_OK) {
|
||||
bignum_safe_free(generator);
|
||||
bignum_safe_free(modulus);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bBB",
|
||||
SSH2_MSG_KEX_DH_GEX_GROUP,
|
||||
modulus,
|
||||
generator);
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
bignum_safe_free(generator);
|
||||
bignum_safe_free(modulus);
|
||||
#endif
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_invalid(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->dh_handshake_state = DH_STATE_GROUP_SENT;
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief parse an incoming SSH_MSG_KEX_DH_GEX_INIT packet and complete
|
||||
* Diffie-Hellman key exchange
|
||||
**/
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_init){
|
||||
(void) type;
|
||||
(void) user;
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_KEX_DHGEX_INIT");
|
||||
ssh_packet_remove_callbacks(session, &ssh_dhgex_server_callbacks);
|
||||
ssh_server_dh_process_init(session, packet);
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
286
src/dh_crypto.c
286
src/dh_crypto.c
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2019 by Simo Sorce - Red Hat, Inc.
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
#include "openssl/crypto.h"
|
||||
#include "openssl/dh.h"
|
||||
#include "libcrypto-compat.h"
|
||||
|
||||
extern bignum ssh_dh_generator;
|
||||
extern bignum ssh_dh_group1;
|
||||
extern bignum ssh_dh_group14;
|
||||
extern bignum ssh_dh_group16;
|
||||
extern bignum ssh_dh_group18;
|
||||
|
||||
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)
|
||||
{
|
||||
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
|
||||
((priv == NULL) && (pub == NULL)) || (ctx == NULL) ||
|
||||
(ctx->keypair[peer] == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
DH_get0_key(ctx->keypair[peer], pub, priv);
|
||||
if (priv && (*priv == NULL || bignum_num_bits(*priv) == 0)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (pub && (*pub == NULL || bignum_num_bits(*pub) == 0)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
|
||||
const bignum priv, const bignum pub)
|
||||
{
|
||||
bignum priv_key = NULL;
|
||||
bignum pub_key = NULL;
|
||||
|
||||
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
|
||||
((priv == NULL) && (pub == NULL)) || (ctx == NULL) ||
|
||||
(ctx->keypair[peer] == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (priv) {
|
||||
priv_key = priv;
|
||||
}
|
||||
if (pub) {
|
||||
pub_key = pub;
|
||||
}
|
||||
(void)DH_set0_key(ctx->keypair[peer], pub_key, priv_key);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_dh_get_parameters(struct dh_ctx *ctx,
|
||||
const_bignum *modulus, const_bignum *generator)
|
||||
{
|
||||
if (ctx == NULL || ctx->keypair[0] == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
DH_get0_pqg(ctx->keypair[0], modulus, NULL, generator);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
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 (i = 0; i < 2; i++) {
|
||||
bignum p = NULL;
|
||||
bignum g = NULL;
|
||||
|
||||
/* when setting modulus or generator,
|
||||
* make sure to invalidate existing keys */
|
||||
DH_free(ctx->keypair[i]);
|
||||
ctx->keypair[i] = DH_new();
|
||||
if (ctx->keypair[i] == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = BN_dup(modulus);
|
||||
g = BN_dup(generator);
|
||||
rc = DH_set0_pqg(ctx->keypair[i], p, NULL, g);
|
||||
if (rc != 1) {
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rc = SSH_OK;
|
||||
done:
|
||||
if (rc != SSH_OK) {
|
||||
DH_free(ctx->keypair[0]);
|
||||
DH_free(ctx->keypair[1]);
|
||||
ctx->keypair[0] = NULL;
|
||||
ctx->keypair[1] = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief allocate and initialize ephemeral values used in dh kex
|
||||
*/
|
||||
int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
|
||||
{
|
||||
struct dh_ctx *ctx;
|
||||
int rc;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
crypto->dh_ctx = ctx;
|
||||
|
||||
switch (crypto->kex_type) {
|
||||
case SSH_KEX_DH_GROUP1_SHA1:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group1, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group14, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group16, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP18_SHA512:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group18, ssh_dh_generator);
|
||||
break;
|
||||
default:
|
||||
rc = SSH_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_dh_cleanup(crypto);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto)
|
||||
{
|
||||
if (crypto->dh_ctx != NULL) {
|
||||
DH_free(crypto->dh_ctx->keypair[0]);
|
||||
DH_free(crypto->dh_ctx->keypair[1]);
|
||||
free(crypto->dh_ctx);
|
||||
crypto->dh_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief generates a secret DH parameter of at least DH_SECURITY_BITS
|
||||
* security as well as the corresponding public key.
|
||||
* @param[out] parms a dh_ctx that will hold the new keys.
|
||||
* @param peer Select either client or server key storage. Valid values are:
|
||||
* DH_CLIENT_KEYPAIR or DH_SERVER_KEYPAIR
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error
|
||||
*/
|
||||
int ssh_dh_keypair_gen_keys(struct dh_ctx *dh_ctx, int peer)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((dh_ctx == NULL) || (dh_ctx->keypair[peer] == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = DH_generate_key(dh_ctx->keypair[peer]);
|
||||
if (rc != 1) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief generates a shared secret between the local peer and the remote
|
||||
* peer. The local peer must have been initialized using either the
|
||||
* ssh_dh_keypair_gen_keys() function or by seetting manually both
|
||||
* the private and public keys. The remote peer only needs to have
|
||||
* the remote's peer public key set.
|
||||
* @param[in] local peer identifier (DH_CLIENT_KEYPAIR or DH_SERVER_KEYPAIR)
|
||||
* @param[in] remote peer identifier (DH_CLIENT_KEYPAIR or DH_SERVER_KEYPAIR)
|
||||
* @param[out] dest a new bignum with the shared secret value is returned.
|
||||
* @return SSH_OK on success, SSH_ERROR on error
|
||||
*/
|
||||
int ssh_dh_compute_shared_secret(struct dh_ctx *dh_ctx, int local, int remote,
|
||||
bignum *dest)
|
||||
{
|
||||
unsigned char *kstring = NULL;
|
||||
const_bignum pub_key = NULL;
|
||||
int klen, rc;
|
||||
|
||||
if ((dh_ctx == NULL) ||
|
||||
(dh_ctx->keypair[local] == NULL) ||
|
||||
(dh_ctx->keypair[remote] == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
kstring = malloc(DH_size(dh_ctx->keypair[local]));
|
||||
if (kstring == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ssh_dh_keypair_get_keys(dh_ctx, remote, NULL, &pub_key);
|
||||
if (rc != SSH_OK) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
klen = DH_compute_key(kstring, pub_key, dh_ctx->keypair[local]);
|
||||
if (klen == -1) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*dest = BN_bin2bn(kstring, klen, NULL);
|
||||
if (*dest == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = SSH_OK;
|
||||
done:
|
||||
free(kstring);
|
||||
return rc;
|
||||
}
|
||||
375
src/dh_key.c
375
src/dh_key.c
@@ -1,375 +0,0 @@
|
||||
/*
|
||||
* dh-int.c - Diffie-Helman algorithm code against SSH 2
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2018 by Aris Adamantiadis
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 by Dmitriy Kuznetsov <dk@yandex.ru>
|
||||
* Copyright (c) 2019 by Simo Sorce <simo@redhat.com>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
extern bignum ssh_dh_generator;
|
||||
extern bignum ssh_dh_group1;
|
||||
extern bignum ssh_dh_group14;
|
||||
extern bignum ssh_dh_group16;
|
||||
extern bignum ssh_dh_group18;
|
||||
|
||||
/*
|
||||
* How many bits of security we want for fast DH. DH private key size must be
|
||||
* twice that size.
|
||||
*/
|
||||
#define DH_SECURITY_BITS 512
|
||||
|
||||
struct dh_keypair {
|
||||
bignum priv_key;
|
||||
bignum pub_key;
|
||||
};
|
||||
|
||||
struct dh_ctx {
|
||||
/* 0 is client, 1 is server */
|
||||
struct dh_keypair keypair[2];
|
||||
bignum generator;
|
||||
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) &&
|
||||
(ctx->modulus != ssh_dh_group14) &&
|
||||
(ctx->modulus != ssh_dh_group16) &&
|
||||
(ctx->modulus != ssh_dh_group18)) {
|
||||
bignum_safe_free(ctx->modulus);
|
||||
}
|
||||
ctx->modulus = NULL;
|
||||
}
|
||||
|
||||
static void ssh_dh_free_generator(struct dh_ctx *ctx)
|
||||
{
|
||||
if (ctx->generator != ssh_dh_generator) {
|
||||
bignum_safe_free(ctx->generator);
|
||||
}
|
||||
}
|
||||
|
||||
static void ssh_dh_free_dh_keypair(struct dh_keypair *keypair)
|
||||
{
|
||||
bignum_safe_free(keypair->priv_key);
|
||||
bignum_safe_free(keypair->pub_key);
|
||||
}
|
||||
|
||||
static int ssh_dh_init_dh_keypair(struct dh_keypair *keypair)
|
||||
{
|
||||
int rc;
|
||||
|
||||
keypair->priv_key = bignum_new();
|
||||
if (keypair->priv_key == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
keypair->pub_key = bignum_new();
|
||||
if (keypair->pub_key == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = SSH_OK;
|
||||
done:
|
||||
if (rc != SSH_OK) {
|
||||
ssh_dh_free_dh_keypair(keypair);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
|
||||
const_bignum *priv, const_bignum *pub)
|
||||
{
|
||||
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
|
||||
((priv == NULL) && (pub == NULL)) || (ctx == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (priv) {
|
||||
/* check that we have something in it */
|
||||
if (bignum_num_bits(ctx->keypair[peer].priv_key)) {
|
||||
*priv = ctx->keypair[peer].priv_key;
|
||||
} else {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (pub) {
|
||||
/* check that we have something in it */
|
||||
if (bignum_num_bits(ctx->keypair[peer].pub_key)) {
|
||||
*pub = ctx->keypair[peer].pub_key;
|
||||
} else {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
|
||||
bignum priv, bignum pub)
|
||||
{
|
||||
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
|
||||
((priv == NULL) && (pub == NULL)) || (ctx == NULL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (priv) {
|
||||
bignum_safe_free(ctx->keypair[peer].priv_key);
|
||||
ctx->keypair[peer].priv_key = priv;
|
||||
}
|
||||
if (pub) {
|
||||
bignum_safe_free(ctx->keypair[peer].pub_key);
|
||||
ctx->keypair[peer].pub_key = pub;
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_dh_get_parameters(struct dh_ctx *ctx,
|
||||
const_bignum *modulus, const_bignum *generator)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (modulus) {
|
||||
*modulus = ctx->modulus;
|
||||
}
|
||||
if (generator) {
|
||||
*generator = ctx->generator;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_dh_set_parameters(struct dh_ctx *ctx,
|
||||
bignum modulus, bignum generator)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((ctx == NULL) || ((modulus == NULL) && (generator == NULL))) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* when setting modulus or generator,
|
||||
* make sure to invalidate existing keys */
|
||||
ssh_dh_free_dh_keypair(&ctx->keypair[DH_CLIENT_KEYPAIR]);
|
||||
ssh_dh_free_dh_keypair(&ctx->keypair[DH_SERVER_KEYPAIR]);
|
||||
|
||||
rc = ssh_dh_init_dh_keypair(&ctx->keypair[DH_CLIENT_KEYPAIR]);
|
||||
if (rc != SSH_OK) {
|
||||
goto done;
|
||||
}
|
||||
rc = ssh_dh_init_dh_keypair(&ctx->keypair[DH_SERVER_KEYPAIR]);
|
||||
if (rc != SSH_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (modulus) {
|
||||
ssh_dh_free_modulus(ctx);
|
||||
ctx->modulus = modulus;
|
||||
}
|
||||
if (generator) {
|
||||
ssh_dh_free_generator(ctx);
|
||||
ctx->generator = generator;
|
||||
}
|
||||
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief allocate and initialize ephemeral values used in dh kex
|
||||
*/
|
||||
int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
|
||||
{
|
||||
struct dh_ctx *ctx = NULL;
|
||||
int rc;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
switch (crypto->kex_type) {
|
||||
case SSH_KEX_DH_GROUP1_SHA1:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group1, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group14, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP16_SHA512:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group16, ssh_dh_generator);
|
||||
break;
|
||||
case SSH_KEX_DH_GROUP18_SHA512:
|
||||
rc = ssh_dh_set_parameters(ctx, ssh_dh_group18, ssh_dh_generator);
|
||||
break;
|
||||
default:
|
||||
rc = SSH_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
crypto->dh_ctx = ctx;
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_dh_cleanup(crypto);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto)
|
||||
{
|
||||
struct dh_ctx *ctx = crypto->dh_ctx;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_dh_free_dh_keypair(&ctx->keypair[DH_CLIENT_KEYPAIR]);
|
||||
ssh_dh_free_dh_keypair(&ctx->keypair[DH_SERVER_KEYPAIR]);
|
||||
|
||||
ssh_dh_free_modulus(ctx);
|
||||
ssh_dh_free_generator(ctx);
|
||||
free(ctx);
|
||||
crypto->dh_ctx = NULL;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief generates a secret DH parameter of at least DH_SECURITY_BITS
|
||||
* security as well as the corresponding public key.
|
||||
* @param[out] parms a dh_kex paramters structure with preallocated bignum
|
||||
* where to store the parameters
|
||||
* @return SSH_OK on success, SSH_ERROR on error
|
||||
*/
|
||||
int ssh_dh_keypair_gen_keys(struct dh_ctx *dh_ctx, int peer)
|
||||
{
|
||||
bignum tmp = NULL;
|
||||
bignum_CTX ctx = NULL;
|
||||
int rc = 0;
|
||||
int bits = 0;
|
||||
int p_bits = 0;
|
||||
|
||||
ctx = bignum_ctx_new();
|
||||
if (bignum_ctx_invalid(ctx)){
|
||||
goto error;
|
||||
}
|
||||
tmp = bignum_new();
|
||||
if (tmp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
p_bits = bignum_num_bits(dh_ctx->modulus);
|
||||
/* we need at most DH_SECURITY_BITS */
|
||||
bits = MIN(DH_SECURITY_BITS * 2, p_bits);
|
||||
/* ensure we're not too close of p so rnd()%p stays uniform */
|
||||
if (bits <= p_bits && bits + 64 > p_bits) {
|
||||
bits += 64;
|
||||
}
|
||||
rc = bignum_rand(tmp, bits);
|
||||
if (rc != 1) {
|
||||
goto error;
|
||||
}
|
||||
rc = bignum_mod(dh_ctx->keypair[peer].priv_key, tmp, dh_ctx->modulus, ctx);
|
||||
if (rc != 1) {
|
||||
goto error;
|
||||
}
|
||||
/* Now compute the corresponding public key */
|
||||
rc = bignum_mod_exp(dh_ctx->keypair[peer].pub_key, dh_ctx->generator,
|
||||
dh_ctx->keypair[peer].priv_key, dh_ctx->modulus, ctx);
|
||||
if (rc != 1) {
|
||||
goto error;
|
||||
}
|
||||
bignum_safe_free(tmp);
|
||||
bignum_ctx_free(ctx);
|
||||
return SSH_OK;
|
||||
error:
|
||||
bignum_safe_free(tmp);
|
||||
bignum_ctx_free(ctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief generates a shared secret between the local peer and the remote peer
|
||||
* @param[in] local peer identifier
|
||||
* @param[in] remote peer identifier
|
||||
* @param[out] dest a preallocated bignum where to store parameter
|
||||
* @return SSH_OK on success, SSH_ERROR on error
|
||||
*/
|
||||
int ssh_dh_compute_shared_secret(struct dh_ctx *dh_ctx, int local, int remote,
|
||||
bignum *dest)
|
||||
{
|
||||
int rc;
|
||||
bignum_CTX ctx = bignum_ctx_new();
|
||||
if (bignum_ctx_invalid(ctx)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*dest == NULL) {
|
||||
*dest = bignum_new();
|
||||
if (*dest == NULL) {
|
||||
rc = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rc = bignum_mod_exp(*dest, dh_ctx->keypair[remote].pub_key,
|
||||
dh_ctx->keypair[local].priv_key,
|
||||
dh_ctx->modulus, ctx);
|
||||
|
||||
done:
|
||||
bignum_ctx_free(ctx);
|
||||
if (rc != 1) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
51
src/ecdh.c
51
src/ecdh.c
@@ -30,32 +30,16 @@
|
||||
|
||||
#ifdef HAVE_ECDH
|
||||
|
||||
static SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply);
|
||||
|
||||
static ssh_packet_callback ecdh_client_callbacks[]= {
|
||||
ssh_packet_client_ecdh_reply
|
||||
};
|
||||
|
||||
struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks = {
|
||||
.start = SSH2_MSG_KEX_ECDH_REPLY,
|
||||
.n_callbacks = 1,
|
||||
.callbacks = ecdh_client_callbacks,
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
|
||||
* a SSH_MSG_NEWKEYS
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){
|
||||
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet){
|
||||
ssh_string q_s_string = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
ssh_string signature = NULL;
|
||||
int rc;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_ecdh_client_callbacks);
|
||||
pubkey_blob = ssh_buffer_get_ssh_string(packet);
|
||||
if (pubkey_blob == NULL) {
|
||||
ssh_set_error(session,SSH_FATAL, "No public key in packet");
|
||||
@@ -93,39 +77,10 @@ SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){
|
||||
}
|
||||
|
||||
rc=ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
return rc;
|
||||
error:
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
static ssh_packet_callback ecdh_server_callbacks[] = {
|
||||
ssh_packet_server_ecdh_init
|
||||
};
|
||||
|
||||
struct ssh_packet_callbacks_struct ssh_ecdh_server_callbacks = {
|
||||
.start = SSH2_MSG_KEX_ECDH_INIT,
|
||||
.n_callbacks = 1,
|
||||
.callbacks = ecdh_server_callbacks,
|
||||
.user = NULL
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief sets up the ecdh kex callbacks
|
||||
*/
|
||||
void ssh_server_ecdh_init(ssh_session session){
|
||||
ssh_packet_set_callbacks(session, &ssh_ecdh_server_callbacks);
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
#endif /* HAVE_ECDH */
|
||||
|
||||
@@ -108,10 +108,6 @@ int ssh_client_ecdh_init(ssh_session session){
|
||||
session->next_crypto->ecdh_privkey = key;
|
||||
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||||
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
|
||||
return rc;
|
||||
@@ -128,6 +124,12 @@ int ecdh_build_k(ssh_session session) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->next_crypto->k = bignum_new();
|
||||
if (session->next_crypto->k == NULL) {
|
||||
bignum_ctx_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pubkey = EC_POINT_new(group);
|
||||
if (pubkey == NULL) {
|
||||
bignum_ctx_free(ctx);
|
||||
@@ -170,22 +172,18 @@ int ecdh_build_k(ssh_session session) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bignum_bin2bn(buffer, len, &session->next_crypto->shared_secret);
|
||||
bignum_bin2bn(buffer, len, session->next_crypto->k);
|
||||
free(buffer);
|
||||
if (session->next_crypto->shared_secret == NULL) {
|
||||
EC_KEY_free(session->next_crypto->ecdh_privkey);
|
||||
session->next_crypto->ecdh_privkey = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
EC_KEY_free(session->next_crypto->ecdh_privkey);
|
||||
session->next_crypto->ecdh_privkey = NULL;
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_log_hexdump("Session server cookie",
|
||||
ssh_print_hexa("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_log_hexdump("Session client cookie",
|
||||
ssh_print_hexa("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->k);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -193,10 +191,11 @@ int ecdh_build_k(ssh_session session) {
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
/** @brief Handle a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||
* SSH_MSG_KEXDH_REPLY
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
|
||||
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
|
||||
/* ECDH keys */
|
||||
ssh_string q_c_string;
|
||||
ssh_string q_s_string;
|
||||
@@ -206,21 +205,17 @@ 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;
|
||||
int len;
|
||||
int rc;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_ecdh_server_callbacks);
|
||||
/* Extract the client pubkey from the init packet */
|
||||
q_c_string = ssh_buffer_get_ssh_string(packet);
|
||||
if (q_c_string == NULL) {
|
||||
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session->next_crypto->ecdh_client_pubkey = q_c_string;
|
||||
|
||||
@@ -238,7 +233,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
if (ecdh_key == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
BN_CTX_free(ctx);
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
group = EC_KEY_get0_group(ecdh_key);
|
||||
@@ -256,7 +251,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
if (q_s_string == NULL) {
|
||||
EC_KEY_free(ecdh_key);
|
||||
BN_CTX_free(ctx);
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
EC_POINT_point2oct(group,
|
||||
@@ -274,25 +269,25 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
rc = ecdh_build_k(session);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_make_sessionid(session);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
|
||||
@@ -314,33 +309,26 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent");
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Send the MSG_NEWKEYS */
|
||||
rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
return SSH_ERROR;;
|
||||
}
|
||||
|
||||
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||
rc = ssh_packet_send(session);
|
||||
if (rc == SSH_ERROR){
|
||||
goto error;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
@@ -106,10 +106,6 @@ int ssh_client_ecdh_init(ssh_session session)
|
||||
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||||
client_pubkey = NULL;
|
||||
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
|
||||
out:
|
||||
@@ -198,9 +194,8 @@ int ecdh_build_k(ssh_session session)
|
||||
goto out;
|
||||
}
|
||||
|
||||
session->next_crypto->shared_secret = gcry_mpi_new(0);
|
||||
gcry_mpi_point_snatch_get(session->next_crypto->shared_secret,
|
||||
NULL, NULL, point);
|
||||
session->next_crypto->k = gcry_mpi_new(0);
|
||||
gcry_mpi_point_snatch_get(session->next_crypto->k, NULL, NULL, point);
|
||||
#else
|
||||
s = ssh_sexp_extract_mpi(result, "s", GCRYMPI_FMT_USG, GCRYMPI_FMT_USG);
|
||||
if (s == NULL) {
|
||||
@@ -225,7 +220,7 @@ int ecdh_build_k(ssh_session session)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = gcry_mpi_scan(&session->next_crypto->shared_secret,
|
||||
err = gcry_mpi_scan(&session->next_crypto->k,
|
||||
GCRYMPI_FMT_USG,
|
||||
(const char *)ssh_string_data(s) + 1,
|
||||
k_len / 2,
|
||||
@@ -242,11 +237,11 @@ int ecdh_build_k(ssh_session session)
|
||||
session->next_crypto->ecdh_privkey = NULL;
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_log_hexdump("Session server cookie",
|
||||
ssh_print_hexa("Session server cookie",
|
||||
session->next_crypto->server_kex.cookie, 16);
|
||||
ssh_log_hexdump("Session client cookie",
|
||||
ssh_print_hexa("Session client cookie",
|
||||
session->next_crypto->client_kex.cookie, 16);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
|
||||
ssh_print_bignum("Shared secret key", session->next_crypto->k);
|
||||
#endif
|
||||
|
||||
out:
|
||||
@@ -260,11 +255,10 @@ int ecdh_build_k(ssh_session session)
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
|
||||
/** @brief Handle a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||
* SSH_MSG_KEXDH_REPLY
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet) {
|
||||
gpg_error_t err;
|
||||
/* ECDH keys */
|
||||
ssh_string q_c_string;
|
||||
@@ -273,15 +267,11 @@ 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;
|
||||
const char *curve = NULL;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_ecdh_server_callbacks);
|
||||
curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||||
if (curve == NULL) {
|
||||
goto out;
|
||||
@@ -296,7 +286,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
session->next_crypto->ecdh_client_pubkey = q_c_string;
|
||||
|
||||
/* Build server's keypair */
|
||||
err = gcry_sexp_build(¶m, NULL, "(genkey(ecdh(curve %s) (flags transient-key)))",
|
||||
err = gcry_sexp_build(¶m, NULL, "(genkey(ecdh(curve %s)))",
|
||||
curve);
|
||||
if (err) {
|
||||
goto out;
|
||||
@@ -326,7 +316,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
if (rc != SSH_OK) {
|
||||
goto out;
|
||||
}
|
||||
@@ -337,7 +327,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
goto out;
|
||||
}
|
||||
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
rc = SSH_ERROR;
|
||||
@@ -386,11 +376,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
out:
|
||||
gcry_sexp_release(param);
|
||||
gcry_sexp_release(key);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
return SSH_PACKET_USED;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
@@ -106,9 +106,6 @@ int ssh_client_ecdh_init(ssh_session session)
|
||||
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||||
client_pubkey = NULL;
|
||||
|
||||
/* register the packet callbacks */
|
||||
ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
|
||||
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||
rc = ssh_packet_send(session);
|
||||
|
||||
out:
|
||||
@@ -154,16 +151,16 @@ int ecdh_build_k(ssh_session session)
|
||||
goto out;
|
||||
}
|
||||
|
||||
session->next_crypto->shared_secret = malloc(sizeof(mbedtls_mpi));
|
||||
if (session->next_crypto->shared_secret == NULL) {
|
||||
session->next_crypto->k = malloc(sizeof(mbedtls_mpi));
|
||||
if (session->next_crypto->k == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(session->next_crypto->shared_secret);
|
||||
mbedtls_mpi_init(session->next_crypto->k);
|
||||
|
||||
rc = mbedtls_ecdh_compute_shared(&grp,
|
||||
session->next_crypto->shared_secret,
|
||||
session->next_crypto->k,
|
||||
&pubkey,
|
||||
&session->next_crypto->ecdh_privkey->d,
|
||||
mbedtls_ctr_drbg_random,
|
||||
@@ -182,21 +179,17 @@ out:
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet)
|
||||
{
|
||||
ssh_string q_c_string = NULL;
|
||||
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;
|
||||
mbedtls_ecp_group_id curve;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
ssh_packet_remove_callbacks(session, &ssh_ecdh_server_callbacks);
|
||||
curve = ecdh_kex_type_to_curve(session->next_crypto->kex_type);
|
||||
if (curve == MBEDTLS_ECP_DP_NONE) {
|
||||
return SSH_ERROR;
|
||||
@@ -251,7 +244,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey, &digest);
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
if (rc == SSH_ERROR) {
|
||||
rc = SSH_ERROR;
|
||||
goto out;
|
||||
@@ -264,7 +257,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
goto out;
|
||||
}
|
||||
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
rc = SSH_ERROR;
|
||||
@@ -312,11 +305,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
|
||||
|
||||
out:
|
||||
mbedtls_ecp_group_free(&grp);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
return SSH_PACKET_USED;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
16
src/external/ed25519.c
vendored
16
src/external/ed25519.c
vendored
@@ -63,9 +63,9 @@ static void get_hram(unsigned char *hram,
|
||||
const unsigned char *sm,
|
||||
const unsigned char *pk,
|
||||
unsigned char *playground,
|
||||
uint64_t smlen)
|
||||
unsigned long long smlen)
|
||||
{
|
||||
uint64_t i;
|
||||
unsigned long long i;
|
||||
SHA512CTX ctx;
|
||||
for (i = 0;i < 32;++i) playground[i] = sm[i];
|
||||
for (i = 32;i < 64;++i) playground[i] = pk[i-32];
|
||||
@@ -111,9 +111,9 @@ int crypto_sign_ed25519_keypair(unsigned char *pk,
|
||||
}
|
||||
|
||||
int crypto_sign_ed25519(unsigned char *sm,
|
||||
uint64_t *smlen,
|
||||
unsigned long long *smlen,
|
||||
const unsigned char *m,
|
||||
uint64_t mlen,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *sk)
|
||||
{
|
||||
sc25519 sck, scs, scsk;
|
||||
@@ -122,7 +122,7 @@ int crypto_sign_ed25519(unsigned char *sm,
|
||||
unsigned char r[32];
|
||||
unsigned char s[32];
|
||||
unsigned char extsk[64];
|
||||
uint64_t i;
|
||||
unsigned long long i;
|
||||
unsigned char hmg[SHA512_DIGEST_LEN];
|
||||
unsigned char hram[SHA512_DIGEST_LEN];
|
||||
|
||||
@@ -174,9 +174,9 @@ int crypto_sign_ed25519(unsigned char *sm,
|
||||
}
|
||||
|
||||
int crypto_sign_ed25519_open(unsigned char *m,
|
||||
uint64_t *mlen,
|
||||
unsigned long long *mlen,
|
||||
const unsigned char *sm,
|
||||
uint64_t smlen,
|
||||
unsigned long long smlen,
|
||||
const unsigned char *pk)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -186,7 +186,7 @@ int crypto_sign_ed25519_open(unsigned char *m,
|
||||
sc25519 schram, scs;
|
||||
unsigned char hram[SHA512_DIGEST_LEN];
|
||||
|
||||
*mlen = (uint64_t) -1;
|
||||
*mlen = (unsigned long long) -1;
|
||||
if (smlen < 64) return -1;
|
||||
|
||||
if (ge25519_unpackneg_vartime(&get1, pk)) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user