mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-03-24 20:40:09 +09:00
Compare commits
526 Commits
libssh-0.8
...
master-fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8daf03c564 | ||
|
|
8ece2abfab | ||
|
|
f05717d23e | ||
|
|
eaa97d2062 | ||
|
|
bda2cc69af | ||
|
|
83d827d7dd | ||
|
|
0f95295966 | ||
|
|
8e69d435ef | ||
|
|
d78a29eb79 | ||
|
|
58113d489e | ||
|
|
c306a693f3 | ||
|
|
21e2522360 | ||
|
|
8f887e82c7 | ||
|
|
993e24a361 | ||
|
|
cf6f1e7a64 | ||
|
|
31bc83f366 | ||
|
|
42ce989488 | ||
|
|
4282f3c664 | ||
|
|
3784226fd8 | ||
|
|
cf24048f02 | ||
|
|
f427a975b8 | ||
|
|
c413834764 | ||
|
|
41b0d263d6 | ||
|
|
a08a97f9c7 | ||
|
|
c0ae59e102 | ||
|
|
109a203453 | ||
|
|
ac8b954019 | ||
|
|
c6ca62d7e1 | ||
|
|
6d3672911b | ||
|
|
95f83c2391 | ||
|
|
130256c348 | ||
|
|
b72c9eead6 | ||
|
|
c7628fbfea | ||
|
|
783e5fd206 | ||
|
|
c79c33e224 | ||
|
|
968fdf4e18 | ||
|
|
bc91fa98ea | ||
|
|
d2434c69c0 | ||
|
|
7f83a1efae | ||
|
|
7b725e6bc7 | ||
|
|
46d8840f7e | ||
|
|
c1fdb56d23 | ||
|
|
57bdc9cb20 | ||
|
|
312084731e | ||
|
|
500bf54a34 | ||
|
|
a56fa14fda | ||
|
|
ac1377148f | ||
|
|
f38c6fcc6e | ||
|
|
0dd2b375c7 | ||
|
|
77be4ce905 | ||
|
|
78b1f0ead3 | ||
|
|
31527d4105 | ||
|
|
65e16b8d9e | ||
|
|
1f6b929735 | ||
|
|
74285d3aca | ||
|
|
7960fbaabb | ||
|
|
a2baf6e97b | ||
|
|
f9ff53b494 | ||
|
|
98487f464b | ||
|
|
b214f84538 | ||
|
|
05417665b9 | ||
|
|
e639c9d0d8 | ||
|
|
bf2c7128ab | ||
|
|
83f2ac4abb | ||
|
|
0b4c2a8e62 | ||
|
|
8418a1131e | ||
|
|
c18ed4eafa | ||
|
|
daabb084fe | ||
|
|
6709f2edf9 | ||
|
|
5bdb7a5079 | ||
|
|
824c56067b | ||
|
|
db5721d041 | ||
|
|
3da5fcbb56 | ||
|
|
9d8c943c68 | ||
|
|
21881cde34 | ||
|
|
55252e4d70 | ||
|
|
8e002b9415 | ||
|
|
f4339df577 | ||
|
|
0197e5e1e5 | ||
|
|
9546b20dec | ||
|
|
b227c12ad2 | ||
|
|
f369d02932 | ||
|
|
0b9e07fbdc | ||
|
|
c47cdc0f97 | ||
|
|
4b6eb05023 | ||
|
|
59ada799d7 | ||
|
|
bb5d46c190 | ||
|
|
aa56b8ca53 | ||
|
|
67f418218b | ||
|
|
03c30e9c8a | ||
|
|
61cac32288 | ||
|
|
aa899f8ec0 | ||
|
|
c88fb4c55b | ||
|
|
a8ed5e31dc | ||
|
|
86dabfe7e4 | ||
|
|
1650d8178e | ||
|
|
6eb43fcbf3 | ||
|
|
9aa47fef99 | ||
|
|
de7405f1c7 | ||
|
|
4a95a35bc6 | ||
|
|
f6b390084e | ||
|
|
b7fefb0500 | ||
|
|
89a8a6fcf0 | ||
|
|
7e44ce1556 | ||
|
|
5fc4d5b22a | ||
|
|
5159cd96e8 | ||
|
|
35c417312c | ||
|
|
e1a8b359c1 | ||
|
|
c8519c435e | ||
|
|
d85bc347d3 | ||
|
|
9c4baa7fd5 | ||
|
|
a4342b97d6 | ||
|
|
963c3077a4 | ||
|
|
a280747462 | ||
|
|
bce8d56705 | ||
|
|
ced05eb6db | ||
|
|
b796924fea | ||
|
|
2af4e3970e | ||
|
|
cf3c2ee5b3 | ||
|
|
57eb6a400a | ||
|
|
8c77a49729 | ||
|
|
8c8026b892 | ||
|
|
80be1d0ee9 | ||
|
|
9c3ba94960 | ||
|
|
194c34ebe3 | ||
|
|
00cd5b1c83 | ||
|
|
9fbbdcc154 | ||
|
|
b9ac61d5a3 | ||
|
|
ca425ebe67 | ||
|
|
7e6b540277 | ||
|
|
12ec1fed2f | ||
|
|
fb70d0fb41 | ||
|
|
f8b70d6a73 | ||
|
|
74888a6fa4 | ||
|
|
729384f346 | ||
|
|
7e5291668c | ||
|
|
bb081f6681 | ||
|
|
8a3ea3bdd5 | ||
|
|
a190ff9302 | ||
|
|
2e7e0ad6c9 | ||
|
|
39b08af2e8 | ||
|
|
60a3796041 | ||
|
|
cc4f220fd3 | ||
|
|
bc72ec5821 | ||
|
|
54ec81db2d | ||
|
|
1ec2ca4202 | ||
|
|
2fad391456 | ||
|
|
cde13b0f00 | ||
|
|
8f31623947 | ||
|
|
253bda4bac | ||
|
|
480915c07d | ||
|
|
e27c6b21b5 | ||
|
|
f65c00f39d | ||
|
|
1d33a4424d | ||
|
|
0386e088eb | ||
|
|
e91bb29e9d | ||
|
|
f622c4309b | ||
|
|
ae6b0e0f49 | ||
|
|
bdb3bb9ccd | ||
|
|
32e502a79d | ||
|
|
6ec5a08639 | ||
|
|
35a6455489 | ||
|
|
c1a8c41c5d | ||
|
|
893b69d82b | ||
|
|
9285e8516b | ||
|
|
91f35eca4d | ||
|
|
49e287006f | ||
|
|
85fc0d5b83 | ||
|
|
0ff566b6dd | ||
|
|
9c200d3ef4 | ||
|
|
4ea46eecce | ||
|
|
009ca5c9dd | ||
|
|
fe618a35dc | ||
|
|
795389ae1b | ||
|
|
60037f3275 | ||
|
|
e1548a71bd | ||
|
|
75be012b4a | ||
|
|
68b0c7a934 | ||
|
|
459868c4a5 | ||
|
|
5d7414467d | ||
|
|
20981bf229 | ||
|
|
825f4ba964 | ||
|
|
2bddafeb70 | ||
|
|
16b876d07f | ||
|
|
a80caec19b | ||
|
|
d6b6fff7f7 | ||
|
|
259d7de153 | ||
|
|
d13517e922 | ||
|
|
45058285fc | ||
|
|
42bd7cdf6c | ||
|
|
72bd2fe197 | ||
|
|
a2120e168b | ||
|
|
5790036a23 | ||
|
|
032f486f27 | ||
|
|
46090facba | ||
|
|
777786d76c | ||
|
|
101df98e54 | ||
|
|
f747e46f33 | ||
|
|
275f73125d | ||
|
|
422376efd4 | ||
|
|
3245b50795 | ||
|
|
508dfc5251 | ||
|
|
43a40999da | ||
|
|
e701913fc8 | ||
|
|
aec9fa4442 | ||
|
|
85a274ff3c | ||
|
|
e210b61148 | ||
|
|
f09ca85ebf | ||
|
|
096d966e43 | ||
|
|
cc513c4c9a | ||
|
|
31202822a7 | ||
|
|
6118628424 | ||
|
|
00e5ef1b3c | ||
|
|
6eef4b4a3c | ||
|
|
79e907402e | ||
|
|
ca7da823c3 | ||
|
|
2eaa23a20e | ||
|
|
143b5e2e50 | ||
|
|
11d480134c | ||
|
|
3786db4cdf | ||
|
|
9cf341bad3 | ||
|
|
e57f0273a6 | ||
|
|
3d74c3802e | ||
|
|
667fb5f9a9 | ||
|
|
14f5624ff5 | ||
|
|
9adc2d36eb | ||
|
|
1e5e09563a | ||
|
|
35bf5334b8 | ||
|
|
a7604c7d6e | ||
|
|
c5cadaa982 | ||
|
|
caf50270c6 | ||
|
|
b7a29c7ffd | ||
|
|
491a42d046 | ||
|
|
642a1b1aa4 | ||
|
|
f709c3ac58 | ||
|
|
ae2b9a3bde | ||
|
|
1d7520b68a | ||
|
|
9c37c8c5a5 | ||
|
|
6c56c1e0d7 | ||
|
|
e4711c469f | ||
|
|
8410f43d8b | ||
|
|
d0ce2d1ecd | ||
|
|
5a198732a5 | ||
|
|
92aa2cf496 | ||
|
|
bbed139eca | ||
|
|
0eab270754 | ||
|
|
71594f9d6c | ||
|
|
2ae2baf9ca | ||
|
|
4c47719d98 | ||
|
|
a30d542207 | ||
|
|
d9d3b65df2 | ||
|
|
97cb302c0e | ||
|
|
90373d8394 | ||
|
|
07f7fa7806 | ||
|
|
5123f7955b | ||
|
|
c15ad753a7 | ||
|
|
63aa274f4b | ||
|
|
8170e30073 | ||
|
|
77f58a225f | ||
|
|
48459c37f6 | ||
|
|
31f24ed23e | ||
|
|
82c3faa44d | ||
|
|
7c75e76d10 | ||
|
|
f246e31ca0 | ||
|
|
7390db6bbb | ||
|
|
cc83b463ce | ||
|
|
39975fdd6d | ||
|
|
1226de875b | ||
|
|
2307be32cf | ||
|
|
eaaa4131de | ||
|
|
39102224b2 | ||
|
|
e365aed6d2 | ||
|
|
d23bda8181 | ||
|
|
86d521cbe7 | ||
|
|
856dc698a9 | ||
|
|
4d09c6dc31 | ||
|
|
03a66b8599 | ||
|
|
c04eac40f3 | ||
|
|
8cc0672c0c | ||
|
|
8f7214a584 | ||
|
|
9d2de880ec | ||
|
|
039c066da5 | ||
|
|
6efbf7a30e | ||
|
|
e5170107c9 | ||
|
|
30df04a8a5 | ||
|
|
aaca395bd3 | ||
|
|
0762057eb9 | ||
|
|
57153f6481 | ||
|
|
4c32befd93 | ||
|
|
be8302e2f3 | ||
|
|
97d2e1f4cb | ||
|
|
12fc0ea1bf | ||
|
|
573eab0d51 | ||
|
|
0e317e612f | ||
|
|
01135703a3 | ||
|
|
c070414309 | ||
|
|
d2cc4eccc7 | ||
|
|
38781f69b0 | ||
|
|
dc4faf9952 | ||
|
|
cbbc6ddcb6 | ||
|
|
a7456bf4d5 | ||
|
|
afc14fe003 | ||
|
|
79a3fcac72 | ||
|
|
945afaa6b4 | ||
|
|
d840a05be3 | ||
|
|
662c30eb72 | ||
|
|
29b5477849 | ||
|
|
2e8f2f03e7 | ||
|
|
983d1189d0 | ||
|
|
7b2e1c7fb7 | ||
|
|
ceecd3fd6f | ||
|
|
bfd33ecf29 | ||
|
|
56317caafc | ||
|
|
ca4fb9c6f8 | ||
|
|
91800eb243 | ||
|
|
2923ad59f9 | ||
|
|
556ad59a5a | ||
|
|
fcb203cb2d | ||
|
|
6dbcc21921 | ||
|
|
2eccd04ff6 | ||
|
|
e9b44d26b1 | ||
|
|
9f5f10552b | ||
|
|
458bda8877 | ||
|
|
3d35250c07 | ||
|
|
ef06ef2c1b | ||
|
|
ba1ff992ce | ||
|
|
e558827c4e | ||
|
|
1e195a232a | ||
|
|
d1cd914012 | ||
|
|
c3980d433a | ||
|
|
78498ee289 | ||
|
|
76f5a60a82 | ||
|
|
07986731c6 | ||
|
|
f1608778be | ||
|
|
72e91d5131 | ||
|
|
4af4b59e21 | ||
|
|
ca464ca2ba | ||
|
|
9ac6ac6c26 | ||
|
|
b6b5a61c97 | ||
|
|
1acb82e38a | ||
|
|
a6d59811bb | ||
|
|
d4a443d56c | ||
|
|
62bff4aff1 | ||
|
|
f8e68b92b8 | ||
|
|
9c5d2d4543 | ||
|
|
7867126aa6 | ||
|
|
4774d2b9f7 | ||
|
|
f48dcb26e3 | ||
|
|
d1f23cd6d8 | ||
|
|
e601dbd8e3 | ||
|
|
f3ffd8aa41 | ||
|
|
4d98b1cd7e | ||
|
|
b00a0578f9 | ||
|
|
336c097ae7 | ||
|
|
1dd8466f66 | ||
|
|
8b19ef05f3 | ||
|
|
7e11e41a9f | ||
|
|
5914ea7c75 | ||
|
|
f1e84d5e67 | ||
|
|
8e3dd09e11 | ||
|
|
ae0afec98d | ||
|
|
0be43c333e | ||
|
|
83a5d3b258 | ||
|
|
bb4bdec184 | ||
|
|
e0449ba21f | ||
|
|
8a56b90c3e | ||
|
|
218c67a51d | ||
|
|
89c525bbf1 | ||
|
|
2c0baef7d4 | ||
|
|
bfb6718b50 | ||
|
|
d99c066a0b | ||
|
|
2844942c1b | ||
|
|
3a729829fd | ||
|
|
576fdbe1e8 | ||
|
|
87df9cfc5d | ||
|
|
ea375d1605 | ||
|
|
c15bd2831f | ||
|
|
efef877356 | ||
|
|
254a0f7132 | ||
|
|
d2131b286f | ||
|
|
c1c32bda14 | ||
|
|
a1b57d3b94 | ||
|
|
be703974e9 | ||
|
|
29f36791c9 | ||
|
|
492e3d5c77 | ||
|
|
9a3f43f4ee | ||
|
|
baa434ebed | ||
|
|
f99e6766d6 | ||
|
|
3efc64112a | ||
|
|
bc19f892eb | ||
|
|
f8fc0b9dfb | ||
|
|
1b12a2415d | ||
|
|
1c0ac0b12e | ||
|
|
ea2b403ab2 | ||
|
|
8323cd791f | ||
|
|
461ebd1e2f | ||
|
|
be147e897d | ||
|
|
1d329236b3 | ||
|
|
0c6544adcb | ||
|
|
09a1d95b69 | ||
|
|
6b10bbea2f | ||
|
|
b4c8bd9fe4 | ||
|
|
5d13006650 | ||
|
|
6fa5e8adb0 | ||
|
|
60ad7ee15d | ||
|
|
5fe81e89fb | ||
|
|
09cf301eee | ||
|
|
594c62d718 | ||
|
|
4169be45eb | ||
|
|
5d53f519bc | ||
|
|
37864b6575 | ||
|
|
4521ab73b6 | ||
|
|
9ca6127b91 | ||
|
|
ebb01549d0 | ||
|
|
945469c9e0 | ||
|
|
82da0c3361 | ||
|
|
1f08aabe43 | ||
|
|
3ca7e1eea9 | ||
|
|
fa60827840 | ||
|
|
761225712a | ||
|
|
df13d8c61f | ||
|
|
cbccae795d | ||
|
|
100c9c98ce | ||
|
|
d7a64b9519 | ||
|
|
fc212d73ed | ||
|
|
2b05e46b62 | ||
|
|
8d8b64cc3f | ||
|
|
11d87238b8 | ||
|
|
8243030c55 | ||
|
|
111d06eac5 | ||
|
|
20ca6e09dd | ||
|
|
66a0f14a0c | ||
|
|
aba6e34b63 | ||
|
|
4fcc0bd407 | ||
|
|
7960b8ed1b | ||
|
|
2aeee5194c | ||
|
|
ca925588b0 | ||
|
|
5b07c1aa2c | ||
|
|
9510a538c2 | ||
|
|
f32cb70675 | ||
|
|
1499b38aef | ||
|
|
509331ec81 | ||
|
|
247983e982 | ||
|
|
f0e99961b6 | ||
|
|
2291c75ab0 | ||
|
|
77b4801e11 | ||
|
|
a3c8dac6b6 | ||
|
|
5334cb9d55 | ||
|
|
9a73fa885a | ||
|
|
23f60a56f3 | ||
|
|
648f5cf400 | ||
|
|
f49bb1b6a3 | ||
|
|
f0a4c1e888 | ||
|
|
a0fec81221 | ||
|
|
0aad4de5f4 | ||
|
|
280519af29 | ||
|
|
0ae376f133 | ||
|
|
73c9d60e5a | ||
|
|
ae3825dfb2 | ||
|
|
8f1e995cec | ||
|
|
4de8ed684b | ||
|
|
d0f3cdfa10 | ||
|
|
a97e227a9d | ||
|
|
119a457357 | ||
|
|
4ae7e35d9c | ||
|
|
47bf099c36 | ||
|
|
9a43298b3a | ||
|
|
3f17154367 | ||
|
|
f8435e261c | ||
|
|
6162b63d5e | ||
|
|
19e081aedb | ||
|
|
a154bd9f22 | ||
|
|
e618298bda | ||
|
|
7e1b67754c | ||
|
|
868623f9a8 | ||
|
|
49f92cf5cd | ||
|
|
c2fc9ac956 | ||
|
|
15473426c8 | ||
|
|
9820a35a9e | ||
|
|
5e9435924c | ||
|
|
64a354159f | ||
|
|
0a46690eca | ||
|
|
26263aabd4 | ||
|
|
6867a35004 | ||
|
|
7946104566 | ||
|
|
140ddf5109 | ||
|
|
887908107a | ||
|
|
8855a140cf | ||
|
|
a9a99fb31f | ||
|
|
26a4097742 | ||
|
|
99a9cf0fcb | ||
|
|
fd157befae | ||
|
|
6f6840a88a | ||
|
|
562e579675 | ||
|
|
1e89896d05 | ||
|
|
3b896750b8 | ||
|
|
f433949dcd | ||
|
|
8e418ea020 | ||
|
|
6766b0a860 | ||
|
|
ce45de9ea2 | ||
|
|
85d2c0371a | ||
|
|
1d9f548204 | ||
|
|
dad456a1ee | ||
|
|
a0214dfc9a | ||
|
|
c004b43fde | ||
|
|
6848c23d84 | ||
|
|
4104d2fb91 | ||
|
|
86d00f438c | ||
|
|
f65882cca6 | ||
|
|
a3475c2e4b | ||
|
|
4d87256ca7 | ||
|
|
6aa9392699 | ||
|
|
0656f8a43d | ||
|
|
66a3bc0332 | ||
|
|
dbce0e5228 | ||
|
|
8ef35a005c | ||
|
|
8425dce7b2 | ||
|
|
0be1ae0e3b | ||
|
|
83898f3f6c | ||
|
|
a33e71ae88 | ||
|
|
f2b6899298 | ||
|
|
4c058aefd9 | ||
|
|
8c2ad7bdd3 | ||
|
|
e04a8b3abd | ||
|
|
15ab612592 | ||
|
|
4f0f1a9160 |
341
.gitlab-ci.yml
341
.gitlab-ci.yml
@@ -4,31 +4,17 @@ variables:
|
||||
CENTOS7_BUILD: buildenv-centos7
|
||||
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
||||
MINGW_BUILD: buildenv-mingw
|
||||
DEBIAN_CROSS_BUILD: buildenv-debian-cross
|
||||
|
||||
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
|
||||
centos7/openssl_1.0.x/x86-64:
|
||||
centos7/openssl_1.0.x/x86_64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
|
||||
script:
|
||||
- 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:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/openssl_1.1.x/x86-64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake3
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=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
|
||||
@@ -40,12 +26,13 @@ fedora/openssl_1.1.x/x86-64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/openssl_1.1.x/x86-64/release:
|
||||
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=Release
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -66,7 +53,8 @@ fedora/address-sanitizer:
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=AddressSanitizer
|
||||
-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 -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -84,7 +72,7 @@ fedora/undefined-sanitizer:
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-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:
|
||||
@@ -97,16 +85,27 @@ fedora/undefined-sanitizer:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
fedora/static-analysis:
|
||||
fedora/csbuild:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||
script:
|
||||
- export CCC_CC=clang
|
||||
- export CCC_CXX=clang++
|
||||
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
|
||||
scan-build --status-bugs -o scan make -j$(nproc)
|
||||
- |
|
||||
if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then
|
||||
export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
|
||||
fi
|
||||
|
||||
# Check if the commit exists in this branch
|
||||
# This is not the case for a force push
|
||||
git branch --contains $CI_COMMIT_BEFORE_SHA 2>/dev/null || export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
|
||||
|
||||
export CI_COMMIT_RANGE="$CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA"
|
||||
|
||||
- csbuild
|
||||
--build-dir=obj-csbuild
|
||||
--prep-cmd="cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON @SRCDIR@"
|
||||
--build-cmd "make clean && make -j$(nproc)"
|
||||
--git-commit-range $CI_COMMIT_RANGE
|
||||
--color
|
||||
--print-current --print-fixed
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
@@ -115,16 +114,17 @@ fedora/static-analysis:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/scan
|
||||
- obj-csbuild/
|
||||
|
||||
# That is a specific runner that we cannot enable universally.
|
||||
# We restrict it to builds under the $BUILD_IMAGES_PROJECT project.
|
||||
freebsd/x86-64:
|
||||
freebsd/x86_64:
|
||||
image:
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -140,11 +140,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=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DWITH_GCRYPT=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
@@ -158,13 +160,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=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DWITH_MBEDTLS=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -177,13 +180,89 @@ fedora/mbedtls/x86-64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86-64:
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
fedora/mingw64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
script:
|
||||
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
||||
- export WINEDEBUG=-all
|
||||
- mkdir -p obj && cd obj && mingw64-cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) &&
|
||||
ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
fedora/mingw32:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
script:
|
||||
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
||||
- export WINEDEBUG=-all
|
||||
- mkdir -p obj && cd obj && mingw32-cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) &&
|
||||
ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
.Debian.cross.template: &Debian_cross_template
|
||||
stage: test
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_CROSS_BUILD
|
||||
script:
|
||||
- build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
- host="${CI_JOB_NAME#*.cross.}"
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_C_COMPILER="$(which $host-gcc)"
|
||||
-DCMAKE_CXX_COMPILER="$(which $host-g++)"
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
|
||||
-DWITH_PCAP=ON .. &&
|
||||
make -j$(nproc) &&
|
||||
ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
Debian.cross.mips-linux-gnu:
|
||||
<<: *Debian_cross_template
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86_64/gcc:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -196,13 +275,77 @@ tumbleweed/openssl_1.1.x/x86-64:
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86-64/release:
|
||||
tumbleweed/openssl_1.1.x/x86/gcc:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- 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
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86_64/gcc7:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86/gcc7:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
||||
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
tumbleweed/openssl_1.1.x/x86_64/clang:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
script:
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
@@ -229,32 +372,15 @@ 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_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
|
||||
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
make -j$(nproc) && ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
@@ -270,10 +396,12 @@ tumbleweed/static-analysis:
|
||||
script:
|
||||
- export CCC_CC=clang
|
||||
- export CCC_CXX=clang++
|
||||
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
|
||||
- mkdir -p obj && cd obj && scan-build cmake
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||
scan-build --status-bugs -o scan make -j$(nproc)
|
||||
tags:
|
||||
- shared
|
||||
@@ -285,48 +413,53 @@ tumbleweed/static-analysis:
|
||||
paths:
|
||||
- obj/scan
|
||||
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
mingw64:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
visualstudio/x86_64:
|
||||
script:
|
||||
- Xvfb :1 -screen 0 1024x768x16 -ac +extension GLX +render -noreset -nolisten tcp &
|
||||
- export DISPLAY=:1
|
||||
- mkdir -p obj && cd obj && mingw64-cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc)
|
||||
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="x64-windows"
|
||||
- cd obj
|
||||
- cmake
|
||||
-A x64
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON ..
|
||||
- cmake --build .
|
||||
- ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
- vs2017
|
||||
- windows
|
||||
except:
|
||||
- tags
|
||||
only:
|
||||
- branches@libssh/libssh-mirror
|
||||
- branches@ansasaki/libssh-mirror
|
||||
- branches@cryptomilk/libssh-mirror
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||
# for MinGW
|
||||
mingw32:
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||
visualstudio/x86:
|
||||
script:
|
||||
- Xvfb :1 -screen 0 1024x768x16 -ac +extension GLX +render -noreset -nolisten tcp &
|
||||
- export DISPLAY=:1
|
||||
- mkdir -p obj && cd obj && mingw32-cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DUNIT_TESTING=ON .. &&
|
||||
make -j$(nproc)
|
||||
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
||||
- $env:VCPKG_DEFAULT_TRIPLET="x86-windows"
|
||||
- cd obj
|
||||
- cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
|
||||
-DPICKY_DEVELOPER=ON
|
||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
||||
-DUNIT_TESTING=ON ..
|
||||
- cmake --build .
|
||||
- ctest --output-on-failure
|
||||
tags:
|
||||
- shared
|
||||
- vs2017
|
||||
- windows
|
||||
except:
|
||||
- tags
|
||||
only:
|
||||
- branches@libssh/libssh-mirror
|
||||
- branches@ansasaki/libssh-mirror
|
||||
- branches@cryptomilk/libssh-mirror
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
|
||||
@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
|
||||
project(libssh VERSION 0.8.9 LANGUAGES C)
|
||||
project(libssh VERSION 0.8.90 LANGUAGES C)
|
||||
|
||||
# global needed variable
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
@@ -22,7 +22,7 @@ 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.7.6")
|
||||
set(LIBRARY_VERSION "4.7.2")
|
||||
set(LIBRARY_SOVERSION "4")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
@@ -70,6 +70,10 @@ 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)
|
||||
@@ -150,9 +154,8 @@ if (WITH_EXAMPLES)
|
||||
endif (WITH_EXAMPLES)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
find_package(CMocka REQUIRED)
|
||||
include(AddCMockaTest)
|
||||
add_subdirectory(tests)
|
||||
include(AddCMockaTest)
|
||||
add_subdirectory(tests)
|
||||
endif (UNIT_TESTING)
|
||||
|
||||
### SOURCE PACKAGE
|
||||
|
||||
@@ -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;.*\.patch")
|
||||
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
|
||||
|
||||
72
ChangeLog
72
ChangeLog
@@ -1,78 +1,6 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
version 0.8.9 (released 2020-04-09)
|
||||
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
|
||||
AES-CTR keys with OpenSSL
|
||||
|
||||
version 0.8.8 (released 2019-12-10)
|
||||
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
|
||||
|
||||
version 0.8.7 (released 2019-02-25)
|
||||
* Fixed handling extension flags in the server implementation
|
||||
* Fixed exporting ed25519 private keys
|
||||
* Fixed corner cases for rsa-sha2 signatures
|
||||
* Fixed some issues with connector
|
||||
|
||||
version 0.8.6 (released 2018-12-24)
|
||||
* Fixed compilation issues with different OpenSSL versions
|
||||
* Fixed StrictHostKeyChecking in new knownhosts API
|
||||
* Fixed ssh_send_keepalive() with packet filter
|
||||
* Fixed possible crash with knownhosts options
|
||||
* Fixed issus with rekeying
|
||||
* Fixed strong ECDSA keys
|
||||
* Fixed some issues with rsa-sha2 extentions
|
||||
* Fixed access violation in ssh_init() (static linking)
|
||||
* Fixed ssh_channel_close() handling
|
||||
|
||||
version 0.8.5 (released 2018-10-29)
|
||||
* Added support to get known_hosts locations with ssh_options_get()
|
||||
* Fixed preferred algorithm for known hosts negotiations
|
||||
* Fixed KEX with some server implementations (e.g. Cisco)
|
||||
* Fixed issues with MSVC
|
||||
* Fixed keyboard-interactive auth in server mode
|
||||
(regression from CVE-2018-10933)
|
||||
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
|
||||
* Fixed socket fd handling with proxy command
|
||||
* Fixed a memory leak with OpenSSL
|
||||
|
||||
version 0.8.4 (released 2018-10-16)
|
||||
* Fixed CVE-2018-10933
|
||||
* Fixed building without globbing support
|
||||
* Fixed possible memory leaks
|
||||
* Avoid SIGPIPE on sockets
|
||||
|
||||
version 0.8.3 (released 2018-09-21)
|
||||
* Added support for rsa-sha2
|
||||
* Added support to parse private keys in openssh container format
|
||||
(other than ed25519)
|
||||
* Added support for diffie-hellman-group18-sha512 and
|
||||
diffie-hellman-group16-sha512
|
||||
* Added ssh_get_fingerprint_hash()
|
||||
* Added ssh_pki_export_privkey_base64()
|
||||
* Added support for Match keyword in config file
|
||||
* Improved performance and reduced memory footprint for sftp
|
||||
* Fixed ecdsa publickey auth
|
||||
* Fixed reading a closed channel
|
||||
* Added support to announce posix-rename@openssh.com and
|
||||
hardlink@openssh.com in the sftp server
|
||||
|
||||
version 0.8.2 (released 2018-08-30)
|
||||
* Added sha256 fingerprints for pubkeys
|
||||
* Improved compiler flag detection
|
||||
* Fixed race condition in reading sftp messages
|
||||
* Fixed doxygen generation and added modern style
|
||||
* Fixed library initialization on Windows
|
||||
* Fixed __bounded__ attribute detection
|
||||
* Fixed a bug in the options parser
|
||||
* Fixed documentation for new knwon_hosts API
|
||||
|
||||
version 0.8.1 (released 2018-08-13)
|
||||
* Fixed version number in the header
|
||||
* Fixed version number in pkg-config and cmake config
|
||||
* Fixed library initialization
|
||||
* Fixed attribute detection
|
||||
|
||||
version 0.8.0 (released 2018-08-10)
|
||||
* Removed support for deprecated SSHv1 protocol
|
||||
* Added new connector API for clients
|
||||
|
||||
@@ -51,7 +51,10 @@ if (UNIX)
|
||||
add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
# Allow zero for a variadic macro argument
|
||||
add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
|
||||
string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID)
|
||||
if ("${_C_COMPILER_ID}" STREQUAL "clang")
|
||||
add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
|
||||
endif()
|
||||
|
||||
add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS)
|
||||
|
||||
@@ -65,10 +68,18 @@ 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)
|
||||
|
||||
@@ -82,6 +93,8 @@ 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()
|
||||
@@ -100,3 +113,8 @@ 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()
|
||||
|
||||
@@ -64,6 +64,7 @@ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
|
||||
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
check_include_file(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)
|
||||
@@ -108,6 +109,10 @@ 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,6 +129,8 @@ if (OPENSSL_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
|
||||
|
||||
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
|
||||
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
@@ -254,6 +261,14 @@ 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;
|
||||
@@ -272,19 +287,19 @@ int main(void) {
|
||||
###########################################################
|
||||
# For detecting attributes we need to treat warnings as
|
||||
# errors
|
||||
if (UNIX)
|
||||
if (UNIX OR MINGW)
|
||||
# Get warnings for attributs
|
||||
check_c_compiler_flag("-Wattributs" REQUIRED_FLAGS_WERROR)
|
||||
check_c_compiler_flag("-Wattributes" REQUIRED_FLAGS_WERROR)
|
||||
if (REQUIRED_FLAGS_WERROR)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wattributes")
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Wattributes ")
|
||||
endif()
|
||||
|
||||
# Turn warnings into errors
|
||||
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
|
||||
if (REQUIRED_FLAGS_WERROR)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Werror")
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Werror ")
|
||||
endif()
|
||||
endif (UNIX)
|
||||
endif ()
|
||||
|
||||
check_c_source_compiles("
|
||||
void test_constructor_attribute(void) __attribute__ ((constructor));
|
||||
@@ -328,6 +343,28 @@ 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>
|
||||
|
||||
@@ -366,6 +403,8 @@ 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)
|
||||
@@ -374,6 +413,7 @@ 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)
|
||||
|
||||
8
INSTALL
8
INSTALL
@@ -22,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.
|
||||
|
||||
Windows binaries known to be working:
|
||||
For Windows use vcpkg:
|
||||
|
||||
- http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
- http://zlib.net/ -> zlib compiled DLL
|
||||
https://github.com/Microsoft/vcpkg
|
||||
|
||||
We installed them in C:\Program Files
|
||||
which you can use to install openssl and zilib. libssh itself is also part of
|
||||
vcpkg!
|
||||
|
||||
## Building
|
||||
First, you need to configure the compilation, using CMake. Go inside the
|
||||
|
||||
@@ -1,11 +1,63 @@
|
||||
# - 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)
|
||||
|
||||
@@ -17,10 +69,52 @@ if (CMAKE_CROSSCOMPILING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
function(ADD_CMOCKA_TEST _testName _testSource)
|
||||
add_executable(${_testName} ${_testSource})
|
||||
function(ADD_CMOCKA_TEST _TARGET_NAME)
|
||||
|
||||
target_link_libraries(${_testName} ${ARGN})
|
||||
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}
|
||||
)
|
||||
|
||||
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 "-g -O0 -fprofile-arcs -ftest-coverage"
|
||||
set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the C compiler during PROFILING builds.")
|
||||
set(CMAKE_CXX_FLAGS_PROFILING "-g -O0 -fprofile-arcs -ftest-coverage"
|
||||
set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the CXX compiler during PROFILING builds.")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
|
||||
@@ -22,4 +22,16 @@ 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=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()
|
||||
|
||||
@@ -49,7 +49,15 @@ find_library(GCRYPT_LIBRARY
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})
|
||||
find_library(GCRYPT_ERROR_LIBRARY
|
||||
NAMES
|
||||
gpg-error
|
||||
libgpg-error-0
|
||||
libgpg-error6-0
|
||||
HINTS
|
||||
${_GCRYPT_ROOT_HINTS_AND_PATHS}
|
||||
)
|
||||
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} ${GCRYPT_ERROR_LIBRARY})
|
||||
|
||||
if (GCRYPT_INCLUDE_DIR)
|
||||
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -100,6 +103,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -109,6 +115,9 @@
|
||||
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_ia32cap_loc' function. */
|
||||
#cmakedefine HAVE_OPENSSL_IA32CAP_LOC 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
@@ -178,6 +187,9 @@
|
||||
/* 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). */
|
||||
@@ -192,12 +204,16 @@
|
||||
/* 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,6 +14,10 @@ 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);
|
||||
|
||||
@@ -32,82 +32,86 @@ 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_OK:
|
||||
break; /* ok */
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
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){
|
||||
if (ssh_write_knownhost(session) < 0) {
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr, "error %s\n", strerror(errno));
|
||||
return -1;
|
||||
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;
|
||||
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;
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
fprintf(stderr,"%s",ssh_get_error(session));
|
||||
return -1;
|
||||
case SSH_KNOWN_HOSTS_OK:
|
||||
break; /* ok */
|
||||
}
|
||||
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,8 @@ static int process_stderr(socket_t fd, int revents, void *userdata) {
|
||||
}
|
||||
|
||||
static void handle_session(ssh_event event, ssh_session session) {
|
||||
int n, rc;
|
||||
int n;
|
||||
int rc = 0;
|
||||
|
||||
/* Structure for storing the pty size. */
|
||||
struct winsize wsize = {
|
||||
|
||||
@@ -90,6 +90,7 @@ 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);
|
||||
|
||||
@@ -40,11 +40,11 @@ void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len);
|
||||
int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len);
|
||||
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
int argc,
|
||||
size_t argc,
|
||||
va_list ap);
|
||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
int argc,
|
||||
size_t argc,
|
||||
...);
|
||||
#define ssh_buffer_pack(buffer, format, ...) \
|
||||
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||
|
||||
90
include/libssh/bytearray.h
Normal file
90
include/libssh/bytearray.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2018 Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _BYTEARRAY_H
|
||||
#define _BYTEARRAY_H
|
||||
|
||||
#define _DATA_BYTE_CONST(data, pos) \
|
||||
((uint8_t)(((const uint8_t *)(data))[(pos)]))
|
||||
|
||||
#define _DATA_BYTE(data, pos) \
|
||||
(((uint8_t *)(data))[(pos)])
|
||||
|
||||
/*
|
||||
* These macros pull or push integer values from byte arrays stored in
|
||||
* little-endian byte order.
|
||||
*/
|
||||
#define PULL_LE_U8(data, pos) \
|
||||
(_DATA_BYTE_CONST(data, pos))
|
||||
|
||||
#define PULL_LE_U16(data, pos) \
|
||||
((uint16_t)PULL_LE_U8(data, pos) | ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8)
|
||||
|
||||
#define PULL_LE_U32(data, pos) \
|
||||
((uint32_t)(PULL_LE_U16(data, pos) | ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16))
|
||||
|
||||
#define PULL_LE_U64(data, pos) \
|
||||
((uint64_t)(PULL_LE_U32(data, pos) | ((uint64_t)PULL_LE_U32(data, (pos) + 4)) << 32))
|
||||
|
||||
|
||||
#define PUSH_LE_U8(data, pos, val) \
|
||||
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
|
||||
|
||||
#define PUSH_LE_U16(data, pos, val) \
|
||||
(PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)), PUSH_LE_U8((data), (pos) + 1, (uint8_t)((uint16_t)(val) >> 8)))
|
||||
|
||||
#define PUSH_LE_U32(data, pos, val) \
|
||||
(PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)), PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16)))
|
||||
|
||||
#define PUSH_LE_U64(data, pos, val) \
|
||||
(PUSH_LE_U32((data), (pos), (uint32_t)((uint64_t)(val) & 0xffffffff)), PUSH_LE_U32((data), (pos) + 4, (uint32_t)((uint64_t)(val) >> 32)))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* These macros pull or push integer values from byte arrays stored in
|
||||
* big-endian byte order (network byte order).
|
||||
*/
|
||||
#define PULL_BE_U8(data, pos) \
|
||||
(_DATA_BYTE_CONST(data, pos))
|
||||
|
||||
#define PULL_BE_U16(data, pos) \
|
||||
((((uint16_t)(PULL_BE_U8(data, pos))) << 8) | (uint16_t)PULL_BE_U8(data, (pos) + 1))
|
||||
|
||||
#define PULL_BE_U32(data, pos) \
|
||||
((((uint32_t)PULL_BE_U16(data, pos)) << 16) | (uint32_t)(PULL_BE_U16(data, (pos) + 2)))
|
||||
|
||||
#define PULL_BE_U64(data, pos) \
|
||||
((((uint64_t)PULL_BE_U32(data, pos)) << 32) | (uint64_t)(PULL_BE_U32(data, (pos) + 4)))
|
||||
|
||||
|
||||
|
||||
#define PUSH_BE_U8(data, pos, val) \
|
||||
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
|
||||
|
||||
#define PUSH_BE_U16(data, pos, val) \
|
||||
(PUSH_BE_U8((data), (pos), (uint8_t)(((uint16_t)(val)) >> 8)), PUSH_BE_U8((data), (pos) + 1, (uint8_t)((val) & 0xff)))
|
||||
|
||||
#define PUSH_BE_U32(data, pos, val) \
|
||||
(PUSH_BE_U16((data), (pos), (uint16_t)(((uint32_t)(val)) >> 16)), PUSH_BE_U16((data), (pos) + 2, (uint16_t)((val) & 0xffff)))
|
||||
|
||||
#define PUSH_BE_U64(data, pos, val) \
|
||||
(PUSH_BE_U32((data), (pos), (uint32_t)(((uint64_t)(val)) >> 32)), PUSH_BE_U32((data), (pos) + 4, (uint32_t)((val) & 0xffffffff)))
|
||||
|
||||
#endif /* _BYTEARRAY_H */
|
||||
@@ -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 */
|
||||
|
||||
66
include/libssh/config.h
Normal file
66
include/libssh/config.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* config.h - parse the ssh config file
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009-2018 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LIBSSH_CONFIG_H_
|
||||
#define LIBSSH_CONFIG_H_
|
||||
|
||||
|
||||
enum ssh_config_opcode_e {
|
||||
/* Unknown opcode */
|
||||
SOC_UNKNOWN = -3,
|
||||
/* Known and not applicable to libssh */
|
||||
SOC_NA = -2,
|
||||
/* Known but not supported by current libssh version */
|
||||
SOC_UNSUPPORTED = -1,
|
||||
SOC_HOST,
|
||||
SOC_MATCH,
|
||||
SOC_HOSTNAME,
|
||||
SOC_PORT,
|
||||
SOC_USERNAME,
|
||||
SOC_IDENTITY,
|
||||
SOC_CIPHERS,
|
||||
SOC_MACS,
|
||||
SOC_COMPRESSION,
|
||||
SOC_TIMEOUT,
|
||||
SOC_PROTOCOL,
|
||||
SOC_STRICTHOSTKEYCHECK,
|
||||
SOC_KNOWNHOSTS,
|
||||
SOC_PROXYCOMMAND,
|
||||
SOC_GSSAPISERVERIDENTITY,
|
||||
SOC_GSSAPICLIENTIDENTITY,
|
||||
SOC_GSSAPIDELEGATECREDENTIALS,
|
||||
SOC_INCLUDE,
|
||||
SOC_BINDADDRESS,
|
||||
SOC_GLOBALKNOWNHOSTSFILE,
|
||||
SOC_LOGLEVEL,
|
||||
SOC_HOSTKEYALGORITHMS,
|
||||
SOC_KEXALGORITHMS,
|
||||
SOC_GSSAPIAUTHENTICATION,
|
||||
SOC_KBDINTERACTIVEAUTHENTICATION,
|
||||
SOC_PASSWORDAUTHENTICATION,
|
||||
SOC_PUBKEYAUTHENTICATION,
|
||||
SOC_PUBKEYACCEPTEDTYPES,
|
||||
|
||||
SOC_MAX /* Keep this one last in the list */
|
||||
};
|
||||
#endif /* LIBSSH_CONFIG_H_ */
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* crc32.c - simple CRC32 code
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CRC32_H
|
||||
#define _CRC32_H
|
||||
|
||||
uint32_t ssh_crc32(const char *buf, uint32_t len);
|
||||
|
||||
#endif /* _CRC32_H */
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#include <gcrypt.h>
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
#include <mbedtls/gcm.h>
|
||||
#endif
|
||||
#include "libssh/wrapper.h"
|
||||
|
||||
@@ -48,6 +50,9 @@
|
||||
|
||||
#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,
|
||||
@@ -78,7 +83,10 @@ enum ssh_cipher_e {
|
||||
SSH_AES256_CBC,
|
||||
SSH_AES128_CTR,
|
||||
SSH_AES192_CTR,
|
||||
SSH_AES256_CTR
|
||||
SSH_AES256_CTR,
|
||||
SSH_AEAD_AES128_GCM,
|
||||
SSH_AEAD_AES256_GCM,
|
||||
SSH_AEAD_CHACHA20_POLY1305
|
||||
};
|
||||
|
||||
struct ssh_crypto_struct {
|
||||
@@ -136,6 +144,7 @@ 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;
|
||||
@@ -145,6 +154,10 @@ 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 */
|
||||
@@ -152,10 +165,14 @@ struct ssh_cipher_struct {
|
||||
/* 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,
|
||||
unsigned long len);
|
||||
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
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 (*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,
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 8
|
||||
#define LIBSSH_VERSION_MICRO 8
|
||||
#define LIBSSH_VERSION_MICRO 90
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
@@ -405,6 +405,7 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
||||
SSH_OPTIONS_NODELAY,
|
||||
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
SSH_OPTIONS_PROCESS_CONFIG,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -543,6 +544,10 @@ SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, in
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_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);
|
||||
|
||||
|
||||
|
||||
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
||||
@@ -552,7 +557,6 @@ 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);
|
||||
@@ -593,6 +597,8 @@ SSH_DEPRECATED LIBSSH_API void ssh_log(ssh_session session,
|
||||
|
||||
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
|
||||
LIBSSH_API 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);
|
||||
@@ -760,8 +766,6 @@ 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,NULL,NULL);
|
||||
int ret = ssh_userauth_kbdint(c_session, username, submethods);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -407,7 +407,7 @@ public:
|
||||
* @see ssh_write_knownhost
|
||||
*/
|
||||
int writeKnownhost(){
|
||||
int ret = ssh_write_knownhost(c_session);
|
||||
int ret = ssh_session_update_known_hosts(c_session);
|
||||
ssh_throw(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request);
|
||||
|
||||
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
|
||||
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);
|
||||
|
||||
|
||||
@@ -50,12 +50,6 @@ struct ssh_timestamp {
|
||||
long useconds;
|
||||
};
|
||||
|
||||
enum ssh_quote_state_e {
|
||||
NO_QUOTE,
|
||||
SINGLE_QUOTE,
|
||||
DOUBLE_QUOTE
|
||||
};
|
||||
|
||||
struct ssh_list *ssh_list_new(void);
|
||||
void ssh_list_free(struct ssh_list *list);
|
||||
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
||||
@@ -87,6 +81,6 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
||||
|
||||
int ssh_match_group(const char *group, const char *object);
|
||||
|
||||
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
|
||||
void uint64_inc(unsigned char *counter);
|
||||
|
||||
#endif /* MISC_H_ */
|
||||
|
||||
@@ -70,6 +70,7 @@ 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);
|
||||
|
||||
|
||||
@@ -44,23 +44,23 @@ struct ssh_key_struct {
|
||||
int flags;
|
||||
const char *type_c; /* Don't free it ! it is static */
|
||||
int ecdsa_nid;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#if defined(HAVE_LIBGCRYPT)
|
||||
gcry_sexp_t dsa;
|
||||
gcry_sexp_t rsa;
|
||||
gcry_sexp_t ecdsa;
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
mbedtls_pk_context *rsa;
|
||||
mbedtls_ecdsa_context *ecdsa;
|
||||
void *dsa;
|
||||
#elif HAVE_LIBCRYPTO
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
DSA *dsa;
|
||||
RSA *rsa;
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
# if defined(HAVE_OPENSSL_ECC)
|
||||
EC_KEY *ecdsa;
|
||||
#else
|
||||
# else
|
||||
void *ecdsa;
|
||||
#endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif
|
||||
# endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
ed25519_pubkey *ed25519_pubkey;
|
||||
ed25519_privkey *ed25519_privkey;
|
||||
void *cert;
|
||||
@@ -71,11 +71,11 @@ struct ssh_signature_struct {
|
||||
enum ssh_keytypes_e type;
|
||||
enum ssh_digest_e hash_type;
|
||||
const char *type_c;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#if defined(HAVE_LIBGCRYPT)
|
||||
gcry_sexp_t dsa_sig;
|
||||
gcry_sexp_t rsa_sig;
|
||||
gcry_sexp_t ecdsa_sig;
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
DSA_SIG *dsa_sig;
|
||||
ssh_string rsa_sig;
|
||||
# ifdef HAVE_OPENSSL_ECC
|
||||
@@ -83,10 +83,10 @@ struct ssh_signature_struct {
|
||||
# else
|
||||
void *ecdsa_sig;
|
||||
# endif
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
||||
ssh_string rsa_sig;
|
||||
struct mbedtls_ecdsa_sig ecdsa_sig;
|
||||
#endif
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
ed25519_signature *ed25519_sig;
|
||||
};
|
||||
|
||||
|
||||
@@ -386,6 +386,22 @@ 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 */
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#ifndef SESSION_H_
|
||||
#define SESSION_H_
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/packet.h"
|
||||
@@ -27,6 +29,7 @@
|
||||
#include "libssh/auth.h"
|
||||
#include "libssh/channels.h"
|
||||
#include "libssh/poll.h"
|
||||
#include "libssh/config.h"
|
||||
|
||||
/* These are the different states a SSH session can be into its life */
|
||||
enum ssh_session_state_e {
|
||||
@@ -87,11 +90,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 {
|
||||
@@ -218,6 +220,8 @@ struct ssh_session_struct {
|
||||
int gss_delegate_creds;
|
||||
int flags;
|
||||
int nodelay;
|
||||
bool config_processed;
|
||||
uint8_t options_seen[SOC_MAX];
|
||||
} opts;
|
||||
/* counters */
|
||||
ssh_counter socket_counter;
|
||||
@@ -231,8 +235,10 @@ 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, int timeout,
|
||||
ssh_termination_function fct, void *user);
|
||||
int ssh_handle_packets_termination(ssh_session session,
|
||||
long timeout,
|
||||
ssh_termination_function fct,
|
||||
void *user);
|
||||
void ssh_socket_exception_callback(int code, int errno_code, void *user);
|
||||
|
||||
#endif /* SESSION_H_ */
|
||||
|
||||
@@ -818,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);
|
||||
|
||||
|
||||
@@ -44,9 +44,11 @@ enum ssh_mac_e {
|
||||
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_POLY1305,
|
||||
SSH_HMAC_AEAD_GCM
|
||||
};
|
||||
|
||||
enum ssh_des_e {
|
||||
|
||||
@@ -1 +1 @@
|
||||
4.7.6
|
||||
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,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
|
||||
@@ -48,7 +48,7 @@ if (MBEDTLS_CRYPTO_LIBRARY)
|
||||
)
|
||||
endif (MBEDTLS_CRYPTO_LIBRARY)
|
||||
|
||||
if (GCRYPT_LIBRARY)
|
||||
if (GCRYPT_LIBRARIES)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
${GCRYPT_INCLUDE_DIR}
|
||||
@@ -56,9 +56,8 @@ if (GCRYPT_LIBRARY)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${GCRYPT_LIBRARY}
|
||||
)
|
||||
endif (GCRYPT_LIBRARY)
|
||||
${GCRYPT_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (WITH_ZLIB)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
@@ -165,6 +164,12 @@ set(libssh_SRCS
|
||||
chachapoly.c
|
||||
)
|
||||
|
||||
if (DEFAULT_C_NO_DEPRECATION_FLAGS)
|
||||
set_source_files_properties(known_hosts.c
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS ${DEFAULT_C_NO_DEPRECATION_FLAGS})
|
||||
endif()
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
|
||||
39
src/agent.c
39
src/agent.c
@@ -56,33 +56,13 @@
|
||||
#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;
|
||||
@@ -275,7 +255,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);
|
||||
agent_put_u32(payload, len);
|
||||
PUSH_BE_U32(payload, 0, len);
|
||||
|
||||
/* send length and then the request packet */
|
||||
if (atomicio(session->agent, payload, 4, 0) == 4) {
|
||||
@@ -299,7 +279,7 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = agent_get_u32(payload);
|
||||
len = PULL_BE_U32(payload, 0);
|
||||
if (len > 256 * 1024) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Authentication response too long: %u", len);
|
||||
@@ -331,7 +311,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
ssh_buffer request = NULL;
|
||||
ssh_buffer reply = NULL;
|
||||
unsigned int type = 0;
|
||||
uint32_t buf[1] = {0};
|
||||
uint32_t count = 0;
|
||||
int rc;
|
||||
|
||||
/* send message to the agent requesting the list of identities */
|
||||
@@ -386,8 +366,15 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_buffer_get_u32(reply, (uint32_t *) buf);
|
||||
session->agent->count = agent_get_u32(buf);
|
||||
rc = ssh_buffer_get_u32(reply, &count);
|
||||
if (rc != 4) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Failed to read count");
|
||||
ssh_buffer_free(reply);
|
||||
return -1;
|
||||
}
|
||||
session->agent->count = ntohl(count);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
|
||||
session->agent->count);
|
||||
if (session->agent->count > 1024) {
|
||||
|
||||
10
src/bignum.c
10
src/bignum.c
@@ -69,7 +69,7 @@ ssh_string ssh_make_bignum_string(bignum num) {
|
||||
|
||||
bignum ssh_make_string_bn(ssh_string string){
|
||||
bignum bn = NULL;
|
||||
unsigned int len = ssh_string_len(string);
|
||||
size_t len = ssh_string_len(string);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
|
||||
@@ -88,12 +88,12 @@ bignum ssh_make_string_bn(ssh_string string){
|
||||
return bn;
|
||||
}
|
||||
|
||||
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout) {
|
||||
unsigned int len = ssh_string_len(string);
|
||||
void ssh_make_string_bn_inplace(ssh_string string,
|
||||
UNUSED_PARAM(bignum bnout))
|
||||
{
|
||||
UNUSED_VAR(size_t 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
|
||||
|
||||
40
src/buffer.c
40
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,
|
||||
int argc,
|
||||
size_t argc,
|
||||
va_list ap)
|
||||
{
|
||||
const char *p = NULL;
|
||||
ssh_string string = NULL;
|
||||
char *cstring = NULL;
|
||||
size_t needed_size = 0;
|
||||
size_t count;
|
||||
size_t len;
|
||||
size_t count;
|
||||
int rc = SSH_OK;
|
||||
|
||||
for (p = format, count = 0; *p != '\0'; p++, count++) {
|
||||
/* Invalid number of arguments passed */
|
||||
if (argc != -1 && count > argc) {
|
||||
if (count > argc) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -881,7 +881,7 @@ static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != -1 && argc != count) {
|
||||
if (argc != count) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -891,11 +891,7 @@ 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) {
|
||||
if (argc == -1){
|
||||
return SSH_ERROR;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,7 +914,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,
|
||||
int argc,
|
||||
size_t argc,
|
||||
va_list ap)
|
||||
{
|
||||
int rc = SSH_ERROR;
|
||||
@@ -934,11 +930,15 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
char *cstring;
|
||||
bignum b;
|
||||
size_t len;
|
||||
int count;
|
||||
size_t count;
|
||||
|
||||
if (argc > 256) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
for (p = format, count = 0; *p != '\0'; p++, count++) {
|
||||
/* Invalid number of arguments passed */
|
||||
if (argc != -1 && count > argc) {
|
||||
if (count > argc) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -1010,7 +1010,7 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != -1 && argc != count) {
|
||||
if (argc != count) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -1018,11 +1018,7 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
/* Check if our canary is intact, if not somthing really bad happened */
|
||||
uint32_t canary = va_arg(ap, uint32_t);
|
||||
if (canary != SSH_BUFFER_PACK_END) {
|
||||
if (argc == -1){
|
||||
return SSH_ERROR;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
@@ -1050,12 +1046,16 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||
*/
|
||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
||||
const char *format,
|
||||
int argc,
|
||||
size_t 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);
|
||||
@@ -1098,7 +1098,7 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||
} o;
|
||||
size_t len, rlen, max_len;
|
||||
va_list ap_copy;
|
||||
int count;
|
||||
int count; /* int for size comparison with argc */
|
||||
|
||||
max_len = ssh_buffer_get_len(buffer);
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ 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,
|
||||
|
||||
224
src/channels.c
224
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>
|
||||
@@ -684,6 +683,10 @@ 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,
|
||||
@@ -1000,50 +1003,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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1099,43 +1080,47 @@ 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) {
|
||||
return rc;
|
||||
}
|
||||
if(channel == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1151,60 +1136,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 (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;
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -2774,7 +2751,7 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
||||
ctx.buffer = stdbuf;
|
||||
ctx.count = 1;
|
||||
|
||||
if (timeout_ms < 0) {
|
||||
if (timeout_ms < SSH_TIMEOUT_DEFAULT) {
|
||||
timeout_ms = SSH_TIMEOUT_INFINITE;
|
||||
}
|
||||
|
||||
@@ -2789,8 +2766,13 @@ 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 ||
|
||||
channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Remote channel is closed.");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
|
||||
|
||||
11
src/client.c
11
src/client.c
@@ -180,7 +180,6 @@ 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;
|
||||
@@ -527,6 +526,16 @@ 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");
|
||||
|
||||
165
src/config.c
165
src/config.c
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libssh/config.h"
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/misc.h"
|
||||
@@ -39,45 +40,6 @@
|
||||
|
||||
#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;
|
||||
@@ -210,11 +172,10 @@ static struct ssh_config_match_keyword_table_s ssh_config_match_keyword_table[]
|
||||
{ "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, int seen[]);
|
||||
unsigned int count, int *parsing);
|
||||
|
||||
static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
|
||||
int i;
|
||||
@@ -324,35 +285,41 @@ static int ssh_config_get_yesno(char **str, int notfound) {
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 seen[])
|
||||
int *parsing)
|
||||
{
|
||||
glob_t globbuf = {
|
||||
.gl_flags = 0,
|
||||
@@ -372,7 +339,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, seen);
|
||||
local_parse_file(session, globbuf.gl_pathv[i], parsing);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
@@ -413,8 +380,12 @@ ssh_config_match(char *value, const char *pattern, bool negate)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
unsigned int count, int *parsing, int seen[]) {
|
||||
static int
|
||||
ssh_config_parse_line(ssh_session session,
|
||||
const char *line,
|
||||
unsigned int count,
|
||||
int *parsing)
|
||||
{
|
||||
enum ssh_config_opcode_e opcode;
|
||||
const char *p;
|
||||
char *s, *x;
|
||||
@@ -422,6 +393,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
char *lowerhost;
|
||||
size_t len;
|
||||
int i;
|
||||
uint8_t *seen = session->opts.options_seen;
|
||||
long l;
|
||||
|
||||
x = s = strdup(line);
|
||||
@@ -451,6 +423,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
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;
|
||||
@@ -464,9 +437,9 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
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, seen);
|
||||
local_parse_glob(session, p, parsing);
|
||||
#else
|
||||
local_parse_file(session, p, parsing, seen);
|
||||
local_parse_file(session, p, parsing);
|
||||
#endif /* HAVE_GLOB */
|
||||
}
|
||||
break;
|
||||
@@ -507,7 +480,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"line %d: ERROR - Match all can not be combined with "
|
||||
"line %d: ERROR - Match all cannot be combined with "
|
||||
"other Match attributes", count);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
@@ -799,7 +772,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
}
|
||||
break;
|
||||
case SOC_NA:
|
||||
SSH_LOG(SSH_LOG_INFO, "Unapplicable option: %s, line: %d\n",
|
||||
SSH_LOG(SSH_LOG_INFO, "Unapplicable option: %s, line: %d",
|
||||
keyword, count);
|
||||
break;
|
||||
case SOC_UNSUPPORTED:
|
||||
@@ -807,7 +780,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
keyword, count);
|
||||
break;
|
||||
case SOC_UNKNOWN:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d\n",
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d",
|
||||
keyword, count);
|
||||
break;
|
||||
default:
|
||||
@@ -822,29 +795,37 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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};
|
||||
/* @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;
|
||||
|
||||
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;
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -488,6 +488,7 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
ssh_event_add_session(event, channels[i]->session);
|
||||
}
|
||||
|
||||
ZERO_STRUCT(origfds);
|
||||
FD_ZERO(&origfds);
|
||||
for (fd = 0; fd < maxfd ; fd++) {
|
||||
if (FD_ISSET(fd, readfds)) {
|
||||
|
||||
@@ -641,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;
|
||||
|
||||
|
||||
4
src/dh.c
4
src/dh.c
@@ -1274,10 +1274,6 @@ int ssh_get_server_publickey(ssh_session session, ssh_key *key)
|
||||
|
||||
ssh_key ssh_dh_get_current_server_publickey(ssh_session session)
|
||||
{
|
||||
if (session->current_crypto == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session->current_crypto->server_pubkey;
|
||||
}
|
||||
|
||||
|
||||
13
src/gssapi.c
13
src/gssapi.c
@@ -172,10 +172,10 @@ static void ssh_gssapi_log_error(int verb,
|
||||
|
||||
out:
|
||||
if (msg_maj.value) {
|
||||
dummy_maj = gss_release_buffer(&dummy_min, &msg_maj);
|
||||
gss_release_buffer(&dummy_min, &msg_maj);
|
||||
}
|
||||
if (msg_min.value) {
|
||||
dummy_maj = gss_release_buffer(&dummy_min, &msg_min);
|
||||
gss_release_buffer(&dummy_min, &msg_min);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +217,15 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
||||
gss_create_empty_oid_set(&min_stat, &both_supported);
|
||||
|
||||
maj_stat = gss_indicate_mechs(&min_stat, &supported);
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "indicate mecks %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING,
|
||||
"indicate mechs",
|
||||
maj_stat,
|
||||
min_stat);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
for (i=0; i < supported->count; ++i){
|
||||
ptr = ssh_get_hexa(supported->elements[i].elements, supported->elements[i].length);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Supported mech %zu: %s", i, ptr);
|
||||
|
||||
@@ -143,7 +143,7 @@ void libssh_constructor(void)
|
||||
* If the library is already initialized, increments the _ssh_initialized
|
||||
* counter and return the error code cached in _ssh_init_ret.
|
||||
*
|
||||
* @returns 0 on success, -1 if an error occured.
|
||||
* @returns SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
*/
|
||||
int ssh_init(void) {
|
||||
return _ssh_init(0);
|
||||
@@ -188,7 +188,7 @@ _ret:
|
||||
*
|
||||
* This function is automatically called when the library is unloaded.
|
||||
*
|
||||
* @returns 0 on succes, -1 if an error occured.
|
||||
* @returns SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
*
|
||||
*/
|
||||
void libssh_destructor(void)
|
||||
|
||||
114
src/kex.c
114
src/kex.c
@@ -38,17 +38,24 @@
|
||||
#include "libssh/curve25519.h"
|
||||
#include "libssh/knownhosts.h"
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/pki.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
# define BLOWFISH "blowfish-cbc,"
|
||||
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define AES "aes256-gcm@openssh.com,aes128-gcm@openssh.com," \
|
||||
"aes256-ctr,aes192-ctr,aes128-ctr," \
|
||||
"aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define DES "3des-cbc"
|
||||
# define DES_SUPPORTED "3des-cbc"
|
||||
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
# define BLOWFISH "blowfish-cbc,"
|
||||
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# ifdef MBEDTLS_GCM_C
|
||||
# define GCM "aes256-gcm@openssh.com,aes128-gcm@openssh.com,"
|
||||
# else
|
||||
# define GCM ""
|
||||
# endif /* MBEDTLS_GCM_C */
|
||||
# define AES GCM "aes256-ctr,aes192-ctr,aes128-ctr," \
|
||||
"aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define DES "3des-cbc"
|
||||
# define DES_SUPPORTED "3des-cbc"
|
||||
|
||||
@@ -61,10 +68,15 @@
|
||||
# endif /* HAVE_OPENSSL_BLOWFISH_H */
|
||||
|
||||
# ifdef HAVE_OPENSSL_AES_H
|
||||
# ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||
# define GCM "aes256-gcm@openssh.com,aes128-gcm@openssh.com,"
|
||||
# else
|
||||
# define GCM ""
|
||||
# endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||
# ifdef BROKEN_AES_CTR
|
||||
# define AES "aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define AES GCM "aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# else /* BROKEN_AES_CTR */
|
||||
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define AES GCM "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# endif /* BROKEN_AES_CTR */
|
||||
# else /* HAVE_OPENSSL_AES_H */
|
||||
# define AES ""
|
||||
@@ -416,12 +428,12 @@ out:
|
||||
return is_wrong;
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit)
|
||||
{
|
||||
int i, ok;
|
||||
int server_kex=session->server;
|
||||
int server_kex = session->server;
|
||||
ssh_string str = NULL;
|
||||
char *strings[KEX_METHODS_SIZE] = {0};
|
||||
char *rsa_sig_ext = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
uint8_t first_kex_packet_follows = 0;
|
||||
@@ -430,9 +442,9 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
|
||||
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange");
|
||||
} else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
|
||||
} else if (session->session_state != SSH_SESSION_STATE_INITIAL_KEX) {
|
||||
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
|
||||
goto error;
|
||||
}
|
||||
@@ -528,52 +540,13 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
ok = ssh_match_group(session->next_crypto->client_kex.methods[SSH_KEX],
|
||||
KEX_EXTENSION_CLIENT);
|
||||
if (ok) {
|
||||
const char *hostkeys = NULL;
|
||||
|
||||
/* The client supports extension negotiation */
|
||||
session->extensions |= SSH_EXT_NEGOTIATION;
|
||||
/*
|
||||
* RFC 8332 Section 3.1: Use for Server Authentication
|
||||
* Check what algorithms were provided in the SSH_HOSTKEYS list
|
||||
* by the client and enable the respective extensions to provide
|
||||
* correct signature in the next packet if RSA is negotiated
|
||||
* Enable all the supported extensions and when the time comes
|
||||
* (after NEWKEYS) send them to the client.
|
||||
*/
|
||||
hostkeys = session->next_crypto->client_kex.methods[SSH_HOSTKEYS];
|
||||
ok = ssh_match_group(hostkeys, "rsa-sha2-512");
|
||||
if (ok) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA512;
|
||||
}
|
||||
ok = ssh_match_group(hostkeys, "rsa-sha2-256");
|
||||
if (ok) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA256;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the client preference is honored for the case
|
||||
* both signature types are enabled.
|
||||
*/
|
||||
if ((session->extensions & SSH_EXT_SIG_RSA_SHA256) &&
|
||||
(session->extensions & SSH_EXT_SIG_RSA_SHA512)) {
|
||||
session->extensions &= ~(SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512);
|
||||
rsa_sig_ext = ssh_find_matching("rsa-sha2-512,rsa-sha2-256",
|
||||
session->next_crypto->client_kex.methods[SSH_HOSTKEYS]);
|
||||
if (rsa_sig_ext == NULL) {
|
||||
goto error; /* should never happen */
|
||||
} else if (strcmp(rsa_sig_ext, "rsa-sha2-512") == 0) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA512;
|
||||
} else if (strcmp(rsa_sig_ext, "rsa-sha2-256") == 0) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA256;
|
||||
} else {
|
||||
SAFE_FREE(rsa_sig_ext);
|
||||
goto error; /* should never happen */
|
||||
}
|
||||
SAFE_FREE(rsa_sig_ext);
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_DEBUG, "The client supports extension "
|
||||
"negotiation. Enabled signature algorithms: %s%s",
|
||||
session->extensions & SSH_EXT_SIG_RSA_SHA256 ? "SHA256" : "",
|
||||
session->extensions & SSH_EXT_SIG_RSA_SHA512 ? " SHA512" : "");
|
||||
"negotiation: enabling all extensions");
|
||||
session->extensions = SSH_EXT_ALL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -644,8 +617,6 @@ char *ssh_client_select_hostkeys(ssh_session session)
|
||||
"ecdsa-sha2-nistp521",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256",
|
||||
"ssh-rsa",
|
||||
#ifdef HAVE_DSA
|
||||
"ssh-dss",
|
||||
@@ -671,30 +642,29 @@ char *ssh_client_select_hostkeys(ssh_session session)
|
||||
|
||||
for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
|
||||
bool found = false;
|
||||
/* This is a signature type: We list also the SHA2 extensions */
|
||||
enum ssh_keytypes_e base_preferred =
|
||||
ssh_key_type_from_signature_name(preferred_hostkeys[i]);
|
||||
|
||||
for (it = ssh_list_get_iterator(algo_list);
|
||||
it != NULL;
|
||||
it = it->next) {
|
||||
const char *algo = ssh_iterator_value(const char *, it);
|
||||
/* This is always key type so we do not have to care for the
|
||||
* SHA2 extension */
|
||||
enum ssh_keytypes_e base_algo = ssh_key_type_from_name(algo);
|
||||
int cmp;
|
||||
int ok;
|
||||
|
||||
if (base_preferred == base_algo) {
|
||||
/* Matching the keys already verified it is a known type */
|
||||
if (needcomma) {
|
||||
cmp = strcmp(preferred_hostkeys[i], algo);
|
||||
if (cmp == 0) {
|
||||
ok = ssh_verify_existing_algo(SSH_HOSTKEYS, algo);
|
||||
if (ok) {
|
||||
if (needcomma) {
|
||||
strncat(methods_buffer,
|
||||
",",
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
}
|
||||
strncat(methods_buffer,
|
||||
",",
|
||||
algo,
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
needcomma = 1;
|
||||
found = true;
|
||||
}
|
||||
strncat(methods_buffer,
|
||||
preferred_hostkeys[i],
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
needcomma = 1;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
/* Collect the rest of the algorithms in other buffer, that will
|
||||
@@ -756,10 +726,10 @@ int ssh_set_client_kex(ssh_session session)
|
||||
|
||||
memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
|
||||
/* first check if we have specific host key methods */
|
||||
if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) {
|
||||
if(session->opts.wanted_methods[SSH_HOSTKEYS] == NULL){
|
||||
/* Only if no override */
|
||||
session->opts.wanted_methods[SSH_HOSTKEYS] =
|
||||
ssh_client_select_hostkeys(session);
|
||||
ssh_client_select_hostkeys(session);
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
|
||||
@@ -545,6 +545,10 @@ ssh_string publickey_to_string(ssh_public_key pubkey) {
|
||||
ssh_string key_blob;
|
||||
int rc;
|
||||
|
||||
if (pubkey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key = ssh_key_new();
|
||||
if (key == NULL) {
|
||||
return NULL;
|
||||
|
||||
337
src/libcrypto.c
337
src/libcrypto.c
@@ -43,7 +43,6 @@
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "libcrypto-compat.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL_AES_H
|
||||
@@ -55,14 +54,15 @@
|
||||
#include <openssl/des.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT
|
||||
#include <openssl/modes.h>
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER<0x00907000L)
|
||||
#define OLD_CRYPTO
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_VALGRIND_VALGRIND_H) && defined(HAVE_OPENSSL_IA32CAP_LOC))
|
||||
#include <valgrind/valgrind.h>
|
||||
#define CAN_DISABLE_AESNI
|
||||
#endif
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
struct ssh_mac_ctx_struct {
|
||||
@@ -432,6 +432,9 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
case SSH_HMAC_SHA256:
|
||||
HMAC_Init_ex(ctx, key, len, EVP_sha256(), NULL);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
HMAC_Init_ex(ctx, key, len, EVP_sha384(), NULL);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
|
||||
break;
|
||||
@@ -440,7 +443,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
break;
|
||||
default:
|
||||
HMAC_CTX_free(ctx);
|
||||
SAFE_FREE(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
@@ -496,6 +498,19 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "This cipher is not available in evp_cipher_init");
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||
case SSH_AEAD_AES128_GCM:
|
||||
cipher->cipher = EVP_aes_128_gcm();
|
||||
break;
|
||||
case SSH_AEAD_AES256_GCM:
|
||||
cipher->cipher = EVP_aes_256_gcm();
|
||||
break;
|
||||
#else
|
||||
case SSH_AEAD_AES128_GCM:
|
||||
case SSH_AEAD_AES256_GCM:
|
||||
SSH_LOG(SSH_LOG_WARNING, "This cipher is not available in evp_cipher_init");
|
||||
break;
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||
case SSH_3DES_CBC:
|
||||
cipher->cipher = EVP_des_ede3_cbc();
|
||||
break;
|
||||
@@ -503,6 +518,9 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher) {
|
||||
cipher->cipher = EVP_bf_cbc();
|
||||
break;
|
||||
/* ciphers not using EVP */
|
||||
case SSH_AEAD_CHACHA20_POLY1305:
|
||||
SSH_LOG(SSH_LOG_WARNING, "The ChaCha cipher cannot be handled here");
|
||||
break;
|
||||
case SSH_NO_CIPHER:
|
||||
SSH_LOG(SSH_LOG_WARNING, "No valid ciphertype found");
|
||||
break;
|
||||
@@ -522,6 +540,22 @@ static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher,
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptInit_ex failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||
/* For AES-GCM we need to set IV in specific way */
|
||||
if (cipher->ciphertype == SSH_AEAD_AES128_GCM ||
|
||||
cipher->ciphertype == SSH_AEAD_AES256_GCM) {
|
||||
rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||
EVP_CTRL_GCM_SET_IV_FIXED,
|
||||
-1,
|
||||
(u_char *)IV);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_IV_FIXED failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||
|
||||
EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
|
||||
|
||||
return SSH_OK;
|
||||
@@ -539,6 +573,22 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptInit_ex failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||
/* For AES-GCM we need to set IV in specific way */
|
||||
if (cipher->ciphertype == SSH_AEAD_AES128_GCM ||
|
||||
cipher->ciphertype == SSH_AEAD_AES256_GCM) {
|
||||
rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||
EVP_CTRL_GCM_SET_IV_FIXED,
|
||||
-1,
|
||||
(u_char *)IV);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_IV_FIXED failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||
|
||||
EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
|
||||
|
||||
return SSH_OK;
|
||||
@@ -546,20 +596,25 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
|
||||
|
||||
/* EVP wrapper function for encrypt/decrypt */
|
||||
static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
unsigned long len) {
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
int outlen = 0;
|
||||
int rc = 0;
|
||||
|
||||
rc = EVP_EncryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
|
||||
rc = EVP_EncryptUpdate(cipher->ctx,
|
||||
(unsigned char *)out,
|
||||
&outlen,
|
||||
(unsigned char *)in,
|
||||
(int)len);
|
||||
if (rc != 1){
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed");
|
||||
return;
|
||||
}
|
||||
if (outlen != (int)len){
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"EVP_EncryptUpdate: output size %d for %lu in",
|
||||
"EVP_EncryptUpdate: output size %d for %zu in",
|
||||
outlen,
|
||||
len);
|
||||
return;
|
||||
@@ -567,20 +622,25 @@ static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher,
|
||||
}
|
||||
|
||||
static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
unsigned long len) {
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
int outlen = 0;
|
||||
int rc = 0;
|
||||
|
||||
rc = EVP_DecryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
|
||||
rc = EVP_DecryptUpdate(cipher->ctx,
|
||||
(unsigned char *)out,
|
||||
&outlen,
|
||||
(unsigned char *)in,
|
||||
(int)len);
|
||||
if (rc != 1){
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed");
|
||||
return;
|
||||
}
|
||||
if (outlen != (int)len){
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"EVP_DecryptUpdate: output size %d for %lu in",
|
||||
"EVP_DecryptUpdate: output size %d for %zu in",
|
||||
outlen,
|
||||
len);
|
||||
return;
|
||||
@@ -641,16 +701,182 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou
|
||||
}
|
||||
|
||||
static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
|
||||
if (cipher != NULL) {
|
||||
if (cipher->aes_key != NULL) {
|
||||
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
|
||||
}
|
||||
SAFE_FREE(cipher->aes_key);
|
||||
}
|
||||
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
|
||||
SAFE_FREE(cipher->aes_key);
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_CTR */
|
||||
|
||||
#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||
static int
|
||||
evp_cipher_aead_get_length(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
uint8_t *out,
|
||||
size_t len,
|
||||
uint64_t seq)
|
||||
{
|
||||
(void)cipher;
|
||||
(void)seq;
|
||||
|
||||
/* The length is not encrypted: Copy it to the result buffer */
|
||||
memcpy(out, in, len);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len,
|
||||
uint8_t *tag,
|
||||
uint64_t seq)
|
||||
{
|
||||
size_t authlen, aadlen;
|
||||
u_char lastiv[1];
|
||||
int outlen = 0;
|
||||
int rc;
|
||||
|
||||
(void) seq;
|
||||
|
||||
aadlen = cipher->lenfield_blocksize;
|
||||
authlen = cipher->tag_size;
|
||||
|
||||
/* increment IV */
|
||||
rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||
EVP_CTRL_GCM_IV_GEN,
|
||||
1,
|
||||
lastiv);
|
||||
if (rc == 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_IV_GEN failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pass over the authenticated data (not encrypted) */
|
||||
rc = EVP_EncryptUpdate(cipher->ctx,
|
||||
NULL,
|
||||
&outlen,
|
||||
(unsigned char *)in,
|
||||
(int)aadlen);
|
||||
if (rc == 0 || outlen != (int)aadlen) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Failed to pass authenticated data");
|
||||
return;
|
||||
}
|
||||
memcpy(out, in, aadlen);
|
||||
|
||||
/* Encrypt the rest of the data */
|
||||
rc = EVP_EncryptUpdate(cipher->ctx,
|
||||
(unsigned char *)out + aadlen,
|
||||
&outlen,
|
||||
(unsigned char *)in + aadlen,
|
||||
(int)len - aadlen);
|
||||
if (rc != 1 || outlen != (int)len - aadlen) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute tag */
|
||||
rc = EVP_EncryptFinal(cipher->ctx,
|
||||
NULL,
|
||||
&outlen);
|
||||
if (rc < 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptFinal failed: Failed to create a tag");
|
||||
return;
|
||||
}
|
||||
|
||||
rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||
EVP_CTRL_GCM_GET_TAG,
|
||||
authlen,
|
||||
(unsigned char *)tag);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_GET_TAG failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher,
|
||||
void *complete_packet,
|
||||
uint8_t *out,
|
||||
size_t encrypted_size,
|
||||
uint64_t seq)
|
||||
{
|
||||
size_t authlen, aadlen;
|
||||
u_char lastiv[1];
|
||||
int outlen = 0;
|
||||
int rc = 0;
|
||||
|
||||
(void)seq;
|
||||
|
||||
aadlen = cipher->lenfield_blocksize;
|
||||
authlen = cipher->tag_size;
|
||||
|
||||
/* increment IV */
|
||||
rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||
EVP_CTRL_GCM_IV_GEN,
|
||||
1,
|
||||
lastiv);
|
||||
if (rc == 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_IV_GEN failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* set tag for authentication */
|
||||
rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||
EVP_CTRL_GCM_SET_TAG,
|
||||
authlen,
|
||||
(unsigned char *)complete_packet + aadlen + encrypted_size);
|
||||
if (rc == 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_TAG failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Pass over the authenticated data (not encrypted) */
|
||||
rc = EVP_DecryptUpdate(cipher->ctx,
|
||||
NULL,
|
||||
&outlen,
|
||||
(unsigned char *)complete_packet,
|
||||
(int)aadlen);
|
||||
if (rc == 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Failed to pass authenticated data");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* Do not copy the length to the target buffer, because it is already processed */
|
||||
//memcpy(out, complete_packet, aadlen);
|
||||
|
||||
/* Decrypt the rest of the data */
|
||||
rc = EVP_DecryptUpdate(cipher->ctx,
|
||||
(unsigned char *)out,
|
||||
&outlen,
|
||||
(unsigned char *)complete_packet + aadlen,
|
||||
encrypted_size /* already substracted aadlen*/);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (outlen != (int)encrypted_size) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"EVP_DecryptUpdate: output size %d for %zd in",
|
||||
outlen,
|
||||
encrypted_size);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* verify tag */
|
||||
rc = EVP_DecryptFinal(cipher->ctx,
|
||||
NULL,
|
||||
&outlen);
|
||||
if (rc < 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptFinal failed: Failed authentication");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||
|
||||
/*
|
||||
* The table of supported ciphers
|
||||
*/
|
||||
@@ -674,7 +900,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
#ifdef HAVE_OPENSSL_EVP_AES_CTR
|
||||
{
|
||||
.name = "aes128-ctr",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES128_CTR,
|
||||
.keysize = 128,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
@@ -685,7 +911,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
},
|
||||
{
|
||||
.name = "aes192-ctr",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES192_CTR,
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
@@ -696,7 +922,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
},
|
||||
{
|
||||
.name = "aes256-ctr",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES256_CTR,
|
||||
.keysize = 256,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
@@ -708,7 +934,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
#else /* HAVE_OPENSSL_EVP_AES_CTR */
|
||||
{
|
||||
.name = "aes128-ctr",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES128_CTR,
|
||||
.keysize = 128,
|
||||
.set_encrypt_key = aes_ctr_set_key,
|
||||
@@ -719,7 +945,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
},
|
||||
{
|
||||
.name = "aes192-ctr",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES192_CTR,
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = aes_ctr_set_key,
|
||||
@@ -730,7 +956,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
},
|
||||
{
|
||||
.name = "aes256-ctr",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES256_CTR,
|
||||
.keysize = 256,
|
||||
.set_encrypt_key = aes_ctr_set_key,
|
||||
@@ -743,7 +969,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
#endif /* BROKEN_AES_CTR */
|
||||
{
|
||||
.name = "aes128-cbc",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES128_CBC,
|
||||
.keysize = 128,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
@@ -754,7 +980,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
},
|
||||
{
|
||||
.name = "aes192-cbc",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES192_CBC,
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
@@ -765,7 +991,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
},
|
||||
{
|
||||
.name = "aes256-cbc",
|
||||
.blocksize = 16,
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.ciphertype = SSH_AES256_CBC,
|
||||
.keysize = 256,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
@@ -774,6 +1000,36 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.decrypt = evp_cipher_decrypt,
|
||||
.cleanup = evp_cipher_cleanup
|
||||
},
|
||||
#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||
{
|
||||
.name = "aes128-gcm@openssh.com",
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||
.ciphertype = SSH_AEAD_AES128_GCM,
|
||||
.keysize = 128,
|
||||
.tag_size = AES_GCM_TAGLEN,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
.set_decrypt_key = evp_cipher_set_decrypt_key,
|
||||
.aead_encrypt = evp_cipher_aead_encrypt,
|
||||
.aead_decrypt_length = evp_cipher_aead_get_length,
|
||||
.aead_decrypt = evp_cipher_aead_decrypt,
|
||||
.cleanup = evp_cipher_cleanup
|
||||
},
|
||||
{
|
||||
.name = "aes256-gcm@openssh.com",
|
||||
.blocksize = AES_BLOCK_SIZE,
|
||||
.lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||
.ciphertype = SSH_AEAD_AES256_GCM,
|
||||
.keysize = 256,
|
||||
.tag_size = AES_GCM_TAGLEN,
|
||||
.set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||
.set_decrypt_key = evp_cipher_set_decrypt_key,
|
||||
.aead_encrypt = evp_cipher_aead_encrypt,
|
||||
.aead_decrypt_length = evp_cipher_aead_get_length,
|
||||
.aead_decrypt = evp_cipher_aead_decrypt,
|
||||
.cleanup = evp_cipher_cleanup
|
||||
},
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||
#endif /* HAS_AES */
|
||||
#ifdef HAS_DES
|
||||
{
|
||||
@@ -812,7 +1068,24 @@ int ssh_crypto_init(void)
|
||||
if (libcrypto_initialized) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
if (SSLeay() != OPENSSL_VERSION_NUMBER){
|
||||
SSH_LOG(SSH_LOG_WARNING, "libssh compiled with %s "
|
||||
"headers, currently running with %s.",
|
||||
OPENSSL_VERSION_TEXT,
|
||||
SSLeay_version(SSLeay())
|
||||
);
|
||||
}
|
||||
#ifdef CAN_DISABLE_AESNI
|
||||
/*
|
||||
* disable AES-NI when running within Valgrind, because they generate
|
||||
* too many "uninitialized memory access" false positives
|
||||
*/
|
||||
if (RUNNING_ON_VALGRIND){
|
||||
SSH_LOG(SSH_LOG_INFO, "Running within Valgrind, disabling AES-NI");
|
||||
/* Bit #57 denotes AES-NI instruction set extension */
|
||||
OPENSSL_ia32cap &= ~(1LL << 57);
|
||||
}
|
||||
#endif
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
|
||||
|
||||
211
src/libgcrypt.c
211
src/libgcrypt.c
@@ -31,6 +31,7 @@
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/wrapper.h"
|
||||
#include "libssh/string.h"
|
||||
#include "libssh/misc.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#include <gcrypt.h>
|
||||
@@ -282,6 +283,9 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
case SSH_HMAC_SHA256:
|
||||
gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
@@ -350,6 +354,8 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
}
|
||||
if(strstr(cipher->name,"-ctr"))
|
||||
mode=GCRY_CIPHER_MODE_CTR;
|
||||
if (strstr(cipher->name, "-gcm"))
|
||||
mode = GCRY_CIPHER_MODE_GCM;
|
||||
switch (cipher->keysize) {
|
||||
case 128:
|
||||
if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES128,
|
||||
@@ -383,6 +389,11 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
} else if (mode == GCRY_CIPHER_MODE_GCM) {
|
||||
/* Store the IV so we can handle the packet counter increments later
|
||||
* The IV is passed to the cipher context later.
|
||||
*/
|
||||
memcpy(cipher->last_iv, IV, AES_GCM_IVLEN);
|
||||
} else {
|
||||
if(gcry_cipher_setctr(cipher->key[0],IV,16)){
|
||||
SAFE_FREE(cipher->key);
|
||||
@@ -394,14 +405,174 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aes_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len) {
|
||||
gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
|
||||
static void aes_encrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len) {
|
||||
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||
static void aes_decrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
static int
|
||||
aes_aead_get_length(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
uint8_t *out,
|
||||
size_t len,
|
||||
uint64_t seq)
|
||||
{
|
||||
(void)cipher;
|
||||
(void)seq;
|
||||
|
||||
/* The length is not encrypted: Copy it to the result buffer */
|
||||
memcpy(out, in, len);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
aes_gcm_encrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len,
|
||||
uint8_t *tag,
|
||||
uint64_t seq)
|
||||
{
|
||||
gpg_error_t err;
|
||||
size_t aadlen, authlen;
|
||||
|
||||
(void)seq;
|
||||
|
||||
aadlen = cipher->lenfield_blocksize;
|
||||
authlen = cipher->tag_size;
|
||||
|
||||
/* increment IV */
|
||||
err = gcry_cipher_setiv(cipher->key[0],
|
||||
cipher->last_iv,
|
||||
AES_GCM_IVLEN);
|
||||
/* This actualy does not increment the packet counter for the
|
||||
* current encryption operation, but for the next one. The first
|
||||
* operation needs to be completed with the derived IV.
|
||||
*
|
||||
* The IV buffer has the following structure:
|
||||
* [ 4B static IV ][ 8B packet counter ][ 4B block counter ]
|
||||
*/
|
||||
uint64_inc(cipher->last_iv + 4);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s",
|
||||
gpg_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pass the authenticated data (packet_length) */
|
||||
err = gcry_cipher_authenticate(cipher->key[0], in, aadlen);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_authenticate failed: %s",
|
||||
gpg_strerror(err));
|
||||
return;
|
||||
}
|
||||
memcpy(out, in, aadlen);
|
||||
|
||||
/* Encrypt the rest of the data */
|
||||
err = gcry_cipher_encrypt(cipher->key[0],
|
||||
(unsigned char *)out + aadlen,
|
||||
len - aadlen,
|
||||
(unsigned char *)in + aadlen,
|
||||
len - aadlen);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s",
|
||||
gpg_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the tag */
|
||||
err = gcry_cipher_gettag(cipher->key[0],
|
||||
(void *)tag,
|
||||
authlen);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_gettag failed: %s",
|
||||
gpg_strerror(err));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
aes_gcm_decrypt(struct ssh_cipher_struct *cipher,
|
||||
void *complete_packet,
|
||||
uint8_t *out,
|
||||
size_t encrypted_size,
|
||||
uint64_t seq)
|
||||
{
|
||||
gpg_error_t err;
|
||||
size_t aadlen, authlen;
|
||||
|
||||
(void)seq;
|
||||
|
||||
aadlen = cipher->lenfield_blocksize;
|
||||
authlen = cipher->tag_size;
|
||||
|
||||
/* increment IV */
|
||||
err = gcry_cipher_setiv(cipher->key[0],
|
||||
cipher->last_iv,
|
||||
AES_GCM_IVLEN);
|
||||
/* This actualy does not increment the packet counter for the
|
||||
* current encryption operation, but for the next one. The first
|
||||
* operation needs to be completed with the derived IV.
|
||||
*
|
||||
* The IV buffer has the following structure:
|
||||
* [ 4B static IV ][ 8B packet counter ][ 4B block counter ]
|
||||
*/
|
||||
uint64_inc(cipher->last_iv + 4);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s",
|
||||
gpg_strerror(err));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Pass the authenticated data (packet_length) */
|
||||
err = gcry_cipher_authenticate(cipher->key[0],
|
||||
complete_packet,
|
||||
aadlen);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_authenticate failed: %s",
|
||||
gpg_strerror(err));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* Do not copy the length to the target buffer, because it is already processed */
|
||||
//memcpy(out, complete_packet, aadlen);
|
||||
|
||||
/* Encrypt the rest of the data */
|
||||
err = gcry_cipher_decrypt(cipher->key[0],
|
||||
out,
|
||||
encrypted_size,
|
||||
(unsigned char *)complete_packet + aadlen,
|
||||
encrypted_size);
|
||||
if (err) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_decrypt failed: %s",
|
||||
gpg_strerror(err));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Check the tag */
|
||||
err = gcry_cipher_checktag(cipher->key[0],
|
||||
(unsigned char *)complete_packet + aadlen + encrypted_size,
|
||||
authlen);
|
||||
if (gpg_err_code(err) == GPG_ERR_CHECKSUM) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "The authentication tag does not match");
|
||||
return SSH_ERROR;
|
||||
} else if (err != GPG_ERR_NO_ERROR) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "General error while decryption: %s",
|
||||
gpg_strerror(err));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
@@ -516,6 +687,34 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_decrypt
|
||||
},
|
||||
{
|
||||
.name = "aes128-gcm@openssh.com",
|
||||
.blocksize = 16,
|
||||
.lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||
.keylen = sizeof(gcry_cipher_hd_t),
|
||||
.key = NULL,
|
||||
.keysize = 128,
|
||||
.tag_size = AES_GCM_TAGLEN,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.aead_encrypt = aes_gcm_encrypt,
|
||||
.aead_decrypt_length = aes_aead_get_length,
|
||||
.aead_decrypt = aes_gcm_decrypt,
|
||||
},
|
||||
{
|
||||
.name = "aes256-gcm@openssh.com",
|
||||
.blocksize = 16,
|
||||
.lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||
.keylen = sizeof(gcry_cipher_hd_t),
|
||||
.key = NULL,
|
||||
.keysize = 256,
|
||||
.tag_size = AES_GCM_TAGLEN,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.aead_encrypt = aes_gcm_encrypt,
|
||||
.aead_decrypt_length = aes_aead_get_length,
|
||||
.aead_decrypt = aes_gcm_decrypt,
|
||||
},
|
||||
{
|
||||
.name = "3des-cbc",
|
||||
.blocksize = 8,
|
||||
|
||||
@@ -26,9 +26,13 @@
|
||||
#include "libssh/wrapper.h"
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/misc.h"
|
||||
|
||||
#ifdef HAVE_LIBMBEDCRYPTO
|
||||
#include <mbedtls/md.h>
|
||||
#ifdef MBEDTLS_GCM_C
|
||||
#include <mbedtls/gcm.h>
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
static mbedtls_entropy_context ssh_mbedtls_entropy;
|
||||
static mbedtls_ctr_drbg_context ssh_mbedtls_ctr_drbg;
|
||||
@@ -462,6 +466,9 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type)
|
||||
case SSH_HMAC_SHA256:
|
||||
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
||||
break;
|
||||
@@ -506,39 +513,68 @@ void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len)
|
||||
SAFE_FREE(c);
|
||||
}
|
||||
|
||||
static int cipher_set_encrypt_key(struct ssh_cipher_struct *cipher, void *key,
|
||||
void *IV)
|
||||
static int
|
||||
cipher_init(struct ssh_cipher_struct *cipher,
|
||||
mbedtls_operation_t operation,
|
||||
void *key,
|
||||
void *IV)
|
||||
{
|
||||
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
mbedtls_cipher_context_t *ctx;
|
||||
int rc;
|
||||
|
||||
mbedtls_cipher_init(&cipher->encrypt_ctx);
|
||||
if (operation == MBEDTLS_ENCRYPT) {
|
||||
ctx = &cipher->encrypt_ctx;
|
||||
} else if (operation == MBEDTLS_DECRYPT) {
|
||||
ctx = &cipher->decrypt_ctx;
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_WARNING, "unknown operation");
|
||||
return 1;
|
||||
}
|
||||
|
||||
mbedtls_cipher_init(ctx);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||
|
||||
rc = mbedtls_cipher_setup(&cipher->encrypt_ctx, cipher_info);
|
||||
rc = mbedtls_cipher_setup(ctx, cipher_info);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setup failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_setkey(&cipher->encrypt_ctx, key,
|
||||
rc = mbedtls_cipher_setkey(ctx, key,
|
||||
cipher_info->key_bitlen,
|
||||
MBEDTLS_ENCRYPT);
|
||||
operation);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_set_iv(&cipher->encrypt_ctx, IV, cipher_info->iv_size);
|
||||
|
||||
rc = mbedtls_cipher_set_iv(ctx, IV, cipher_info->iv_size);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_reset(&cipher->encrypt_ctx);
|
||||
return 0;
|
||||
error:
|
||||
mbedtls_cipher_free(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
cipher_set_encrypt_key(struct ssh_cipher_struct *cipher,
|
||||
void *key,
|
||||
void *IV)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = cipher_init(cipher, MBEDTLS_ENCRYPT, key, IV);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "cipher_init failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_reset(&cipher->encrypt_ctx);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed");
|
||||
goto error;
|
||||
@@ -546,38 +582,19 @@ static int cipher_set_encrypt_key(struct ssh_cipher_struct *cipher, void *key,
|
||||
|
||||
return SSH_OK;
|
||||
error:
|
||||
mbedtls_cipher_free(&cipher->encrypt_ctx);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int cipher_set_encrypt_key_cbc(struct ssh_cipher_struct *cipher, void *key,
|
||||
void *IV)
|
||||
static int
|
||||
cipher_set_encrypt_key_cbc(struct ssh_cipher_struct *cipher,
|
||||
void *key,
|
||||
void *IV)
|
||||
{
|
||||
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
int rc;
|
||||
|
||||
mbedtls_cipher_init(&cipher->encrypt_ctx);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||
|
||||
rc = mbedtls_cipher_setup(&cipher->encrypt_ctx, cipher_info);
|
||||
rc = cipher_init(cipher, MBEDTLS_ENCRYPT, key, IV);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setup failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_setkey(&cipher->encrypt_ctx, key,
|
||||
cipher_info->key_bitlen,
|
||||
MBEDTLS_ENCRYPT);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_set_iv(&cipher->encrypt_ctx, IV, cipher_info->iv_size);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||
SSH_LOG(SSH_LOG_WARNING, "cipher_init failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -592,7 +609,6 @@ static int cipher_set_encrypt_key_cbc(struct ssh_cipher_struct *cipher, void *ke
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_reset(&cipher->encrypt_ctx);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed");
|
||||
goto error;
|
||||
@@ -604,37 +620,51 @@ error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int cipher_set_decrypt_key(struct ssh_cipher_struct *cipher, void *key,
|
||||
void *IV)
|
||||
#ifdef MBEDTLS_GCM_C
|
||||
static int
|
||||
cipher_set_key_gcm(struct ssh_cipher_struct *cipher,
|
||||
void *key,
|
||||
void *IV)
|
||||
{
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
int rc;
|
||||
|
||||
mbedtls_cipher_init(&cipher->decrypt_ctx);
|
||||
mbedtls_gcm_init(&cipher->gcm_ctx);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||
|
||||
rc = mbedtls_cipher_setup(&cipher->decrypt_ctx, cipher_info);
|
||||
rc = mbedtls_gcm_setkey(&cipher->gcm_ctx,
|
||||
MBEDTLS_CIPHER_ID_AES,
|
||||
key,
|
||||
cipher_info->key_bitlen);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_setkey(&cipher->decrypt_ctx, key,
|
||||
cipher_info->key_bitlen,
|
||||
MBEDTLS_DECRYPT);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
/* Store the IV so we can increment the packet counter later */
|
||||
memcpy(cipher->last_iv, IV, AES_GCM_IVLEN);
|
||||
|
||||
rc = mbedtls_cipher_set_iv(&cipher->decrypt_ctx, IV, cipher_info->iv_size);
|
||||
return 0;
|
||||
error:
|
||||
mbedtls_gcm_free(&cipher->gcm_ctx);
|
||||
return 1;
|
||||
}
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
static int
|
||||
cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
|
||||
void *key,
|
||||
void *IV)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = cipher_init(cipher, MBEDTLS_DECRYPT, key, IV);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||
SSH_LOG(SSH_LOG_WARNING, "cipher_init failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
mbedtls_cipher_reset(&cipher->decrypt_ctx);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed");
|
||||
goto error;
|
||||
@@ -646,45 +676,27 @@ error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int cipher_set_decrypt_key_cbc(struct ssh_cipher_struct *cipher, void *key,
|
||||
void *IV)
|
||||
static int
|
||||
cipher_set_decrypt_key_cbc(struct ssh_cipher_struct *cipher,
|
||||
void *key,
|
||||
void *IV)
|
||||
{
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
int rc;
|
||||
|
||||
mbedtls_cipher_init(&cipher->decrypt_ctx);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||
|
||||
rc = mbedtls_cipher_setup(&cipher->decrypt_ctx, cipher_info);
|
||||
rc = cipher_init(cipher, MBEDTLS_DECRYPT, key, IV);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_setkey(&cipher->decrypt_ctx, key,
|
||||
cipher_info->key_bitlen,
|
||||
MBEDTLS_DECRYPT);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_set_iv(&cipher->decrypt_ctx, IV, cipher_info->iv_size);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||
SSH_LOG(SSH_LOG_WARNING, "cipher_init failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_set_padding_mode(&cipher->decrypt_ctx,
|
||||
MBEDTLS_PADDING_NONE);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_padding_mode failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
mbedtls_cipher_reset(&cipher->decrypt_ctx);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed");
|
||||
goto error;
|
||||
@@ -696,8 +708,10 @@ error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static void cipher_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len)
|
||||
static void cipher_encrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
size_t outlen = 0;
|
||||
size_t total_len = 0;
|
||||
@@ -751,8 +765,10 @@ static void cipher_encrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void
|
||||
|
||||
}
|
||||
|
||||
static void cipher_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len)
|
||||
static void cipher_decrypt(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len)
|
||||
{
|
||||
size_t outlen = 0;
|
||||
int rc = 0;
|
||||
@@ -833,10 +849,105 @@ static void cipher_decrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void
|
||||
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_GCM_C
|
||||
static int
|
||||
cipher_gcm_get_length(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
uint8_t *out,
|
||||
size_t len,
|
||||
uint64_t seq)
|
||||
{
|
||||
(void)cipher;
|
||||
(void)seq;
|
||||
|
||||
/* The length is not encrypted: Copy it to the result buffer */
|
||||
memcpy(out, in, len);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
cipher_encrypt_gcm(struct ssh_cipher_struct *cipher,
|
||||
void *in,
|
||||
void *out,
|
||||
size_t len,
|
||||
uint8_t *tag,
|
||||
uint64_t seq)
|
||||
{
|
||||
size_t authlen, aadlen;
|
||||
int rc;
|
||||
|
||||
(void) seq;
|
||||
|
||||
aadlen = cipher->lenfield_blocksize;
|
||||
authlen = cipher->tag_size;
|
||||
|
||||
/* The length is not encrypted */
|
||||
memcpy(out, in, aadlen);
|
||||
rc = mbedtls_gcm_crypt_and_tag(&cipher->gcm_ctx,
|
||||
MBEDTLS_GCM_ENCRYPT,
|
||||
len - aadlen, /* encrypted data len */
|
||||
cipher->last_iv, /* IV */
|
||||
AES_GCM_IVLEN,
|
||||
in, /* aad */
|
||||
aadlen,
|
||||
(const unsigned char *)in + aadlen, /* input */
|
||||
(unsigned char *)out + aadlen, /* output */
|
||||
authlen,
|
||||
tag); /* tag */
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_crypt_and_tag failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Increment the IV for the next invocation */
|
||||
uint64_inc(cipher->last_iv + 4);
|
||||
}
|
||||
|
||||
static int
|
||||
cipher_decrypt_gcm(struct ssh_cipher_struct *cipher,
|
||||
void *complete_packet,
|
||||
uint8_t *out,
|
||||
size_t encrypted_size,
|
||||
uint64_t seq)
|
||||
{
|
||||
size_t authlen, aadlen;
|
||||
int rc;
|
||||
|
||||
(void) seq;
|
||||
|
||||
aadlen = cipher->lenfield_blocksize;
|
||||
authlen = cipher->tag_size;
|
||||
|
||||
rc = mbedtls_gcm_auth_decrypt(&cipher->gcm_ctx,
|
||||
encrypted_size, /* encrypted data len */
|
||||
cipher->last_iv, /* IV */
|
||||
AES_GCM_IVLEN,
|
||||
complete_packet, /* aad */
|
||||
aadlen,
|
||||
(const u_char *)complete_packet + aadlen + encrypted_size, /* tag */
|
||||
authlen,
|
||||
(const u_char *)complete_packet + aadlen, /* input */
|
||||
(unsigned char *)out); /* output */
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_gcm_auth_decrypt failed");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Increment the IV for the next invocation */
|
||||
uint64_inc(cipher->last_iv + 4);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
static void cipher_cleanup(struct ssh_cipher_struct *cipher)
|
||||
{
|
||||
mbedtls_cipher_free(&cipher->encrypt_ctx);
|
||||
mbedtls_cipher_free(&cipher->decrypt_ctx);
|
||||
#ifdef MBEDTLS_GCM_C
|
||||
mbedtls_gcm_free(&cipher->gcm_ctx);
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
}
|
||||
|
||||
static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
@@ -917,6 +1028,36 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.decrypt = cipher_decrypt_cbc,
|
||||
.cleanup = cipher_cleanup
|
||||
},
|
||||
#ifdef MBEDTLS_GCM_C
|
||||
{
|
||||
.name = "aes128-gcm@openssh.com",
|
||||
.blocksize = 16,
|
||||
.lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||
.keysize = 128,
|
||||
.tag_size = AES_GCM_TAGLEN,
|
||||
.type = MBEDTLS_CIPHER_AES_128_GCM,
|
||||
.set_encrypt_key = cipher_set_key_gcm,
|
||||
.set_decrypt_key = cipher_set_key_gcm,
|
||||
.aead_encrypt = cipher_encrypt_gcm,
|
||||
.aead_decrypt_length = cipher_gcm_get_length,
|
||||
.aead_decrypt = cipher_decrypt_gcm,
|
||||
.cleanup = cipher_cleanup
|
||||
},
|
||||
{
|
||||
.name = "aes256-gcm@openssh.com",
|
||||
.blocksize = 16,
|
||||
.lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||
.keysize = 256,
|
||||
.tag_size = AES_GCM_TAGLEN,
|
||||
.type = MBEDTLS_CIPHER_AES_256_GCM,
|
||||
.set_encrypt_key = cipher_set_key_gcm,
|
||||
.set_decrypt_key = cipher_set_key_gcm,
|
||||
.aead_encrypt = cipher_encrypt_gcm,
|
||||
.aead_decrypt_length = cipher_gcm_get_length,
|
||||
.aead_decrypt = cipher_decrypt_gcm,
|
||||
.cleanup = cipher_cleanup
|
||||
},
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
{
|
||||
.name = "3des-cbc",
|
||||
.blocksize = 8,
|
||||
|
||||
183
src/messages.c
183
src/messages.c
@@ -63,14 +63,15 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
static ssh_message ssh_message_new(ssh_session session){
|
||||
ssh_message msg = malloc(sizeof(struct ssh_message_struct));
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(msg);
|
||||
msg->session = session;
|
||||
return msg;
|
||||
static ssh_message ssh_message_new(ssh_session session)
|
||||
{
|
||||
ssh_message msg = calloc(1, sizeof(struct ssh_message_struct));
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
msg->session = session;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
#ifndef WITH_SERVER
|
||||
@@ -155,6 +156,11 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg)
|
||||
session->server_callbacks->userdata);
|
||||
if (channel != NULL) {
|
||||
rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel);
|
||||
if (rc != SSH_OK) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"Failed to send reply for accepting a channel "
|
||||
"open");
|
||||
}
|
||||
return SSH_OK;
|
||||
} else {
|
||||
ssh_message_reply_default(msg);
|
||||
@@ -227,6 +233,10 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg)
|
||||
msg->channel_request.height,
|
||||
msg->channel_request.pxwidth,
|
||||
msg->channel_request.pxheight);
|
||||
if (rc != SSH_OK) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"Failed to iterate callbacks for window change");
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
ssh_callbacks_iterate_end();
|
||||
@@ -372,16 +382,16 @@ static int ssh_execute_message_callback(ssh_session session, ssh_message msg) {
|
||||
session->ssh_message_callback_data);
|
||||
if(ret == 1) {
|
||||
ret = ssh_message_reply_default(msg);
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
if(ret != SSH_OK) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
}
|
||||
} else {
|
||||
ret = ssh_message_reply_default(msg);
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
if(ret != SSH_OK) {
|
||||
return ret;
|
||||
}
|
||||
@@ -399,46 +409,60 @@ static int ssh_execute_message_callback(ssh_session session, ssh_message msg) {
|
||||
*
|
||||
* @param[in] message The message to add to the queue.
|
||||
*/
|
||||
void ssh_message_queue(ssh_session session, ssh_message message){
|
||||
if (message != NULL) {
|
||||
static void ssh_message_queue(ssh_session session, ssh_message message)
|
||||
{
|
||||
#ifdef WITH_SERVER
|
||||
int ret;
|
||||
/* probably not the best place to execute server callbacks, but still better
|
||||
* than nothing.
|
||||
*/
|
||||
ret = ssh_execute_server_callbacks(session, message);
|
||||
if (ret == SSH_OK){
|
||||
ssh_message_free(message);
|
||||
return;
|
||||
}
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
if (message == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
/* probably not the best place to execute server callbacks, but still better
|
||||
* than nothing.
|
||||
*/
|
||||
ret = ssh_execute_server_callbacks(session, message);
|
||||
if (ret == SSH_OK) {
|
||||
SSH_MESSAGE_FREE(message);
|
||||
return;
|
||||
}
|
||||
#endif /* WITH_SERVER */
|
||||
if(session->ssh_message_callback != NULL) {
|
||||
ssh_execute_message_callback(session, message);
|
||||
return;
|
||||
}
|
||||
if (session->server_callbacks != NULL){
|
||||
/* if we have server callbacks, but nothing was executed, it means we are
|
||||
* in non-synchronous mode, and we just don't care about the message we
|
||||
* received. Just send a default response. Do not queue it.
|
||||
|
||||
if (session->ssh_message_callback != NULL) {
|
||||
/* This will transfer the message, do not free. */
|
||||
ssh_execute_message_callback(session, message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (session->server_callbacks != NULL) {
|
||||
/* if we have server callbacks, but nothing was executed, it means we are
|
||||
* in non-synchronous mode, and we just don't care about the message we
|
||||
* received. Just send a default response. Do not queue it.
|
||||
*/
|
||||
ssh_message_reply_default(message);
|
||||
SSH_MESSAGE_FREE(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (session->ssh_message_list == NULL) {
|
||||
session->ssh_message_list = ssh_list_new();
|
||||
if (session->ssh_message_list != NULL) {
|
||||
/*
|
||||
* If the message list couldn't be allocated, the message can't be
|
||||
* enqueued
|
||||
*/
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
return;
|
||||
}
|
||||
if(session->ssh_message_list == NULL) {
|
||||
session->ssh_message_list = ssh_list_new();
|
||||
}
|
||||
if (session->ssh_message_list != NULL) {
|
||||
ssh_list_append(session->ssh_message_list, message);
|
||||
} else {
|
||||
/* If the message list couldn't be allocated, the message can't be
|
||||
* enqueued */
|
||||
ssh_message_reply_default(message);
|
||||
ssh_set_error_oom(session);
|
||||
ssh_message_free(message);
|
||||
SSH_MESSAGE_FREE(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* This will transfer the message, do not free. */
|
||||
ssh_list_append(session->ssh_message_list, message);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,38 +635,42 @@ void ssh_message_free(ssh_message msg){
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_service_request){
|
||||
ssh_string service = NULL;
|
||||
char *service_c = NULL;
|
||||
ssh_message msg=NULL;
|
||||
SSH_PACKET_CALLBACK(ssh_packet_service_request)
|
||||
{
|
||||
char *service_c = NULL;
|
||||
ssh_message msg = NULL;
|
||||
int rc;
|
||||
|
||||
(void)type;
|
||||
(void)user;
|
||||
service = ssh_buffer_get_ssh_string(packet);
|
||||
if (service == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid SSH_MSG_SERVICE_REQUEST packet");
|
||||
goto error;
|
||||
}
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
service_c = ssh_string_to_char(service);
|
||||
if (service_c == NULL) {
|
||||
goto error;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Received a SERVICE_REQUEST for service %s", service_c);
|
||||
msg=ssh_message_new(session);
|
||||
if(!msg){
|
||||
SAFE_FREE(service_c);
|
||||
goto error;
|
||||
}
|
||||
msg->type=SSH_REQUEST_SERVICE;
|
||||
msg->service_request.service=service_c;
|
||||
rc = ssh_buffer_unpack(packet,
|
||||
"s",
|
||||
&service_c);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Invalid SSH_MSG_SERVICE_REQUEST packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Received a SERVICE_REQUEST for service %s",
|
||||
service_c);
|
||||
|
||||
msg = ssh_message_new(session);
|
||||
if (msg == NULL) {
|
||||
SAFE_FREE(service_c);
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg->type = SSH_REQUEST_SERVICE;
|
||||
msg->service_request.service = service_c;
|
||||
|
||||
ssh_message_queue(session, msg);
|
||||
error:
|
||||
ssh_string_free(service);
|
||||
if(msg != NULL)
|
||||
ssh_message_queue(session,msg);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
|
||||
@@ -852,7 +880,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
if (rc < 0) {
|
||||
SSH_LOG(
|
||||
SSH_LOG_PACKET,
|
||||
"Received an invalid signature from peer");
|
||||
"Received an invalid signature from peer");
|
||||
msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG;
|
||||
goto error;
|
||||
}
|
||||
@@ -909,7 +937,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
/* bypass the message queue thing */
|
||||
SAFE_FREE(service);
|
||||
SAFE_FREE(method);
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
@@ -922,7 +950,7 @@ error:
|
||||
SAFE_FREE(service);
|
||||
SAFE_FREE(method);
|
||||
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
end:
|
||||
@@ -1065,7 +1093,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
error:
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
@@ -1164,8 +1192,7 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
|
||||
goto end;
|
||||
|
||||
error:
|
||||
ssh_message_free(msg);
|
||||
msg=NULL;
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
end:
|
||||
SAFE_FREE(type_c);
|
||||
if(msg != NULL)
|
||||
@@ -1362,7 +1389,7 @@ end:
|
||||
|
||||
return SSH_OK;
|
||||
error:
|
||||
ssh_message_free(msg);
|
||||
SSH_MESSAGE_FREE(msg);
|
||||
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
187
src/misc.c
187
src/misc.c
@@ -1108,188 +1108,17 @@ char *strndup(const char *s, size_t n)
|
||||
}
|
||||
#endif /* ! HAVE_STRNDUP */
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Quote file name to be used on shell.
|
||||
*
|
||||
* Try to put the given file name between single quotes. There are special
|
||||
* cases:
|
||||
*
|
||||
* - When the '\'' char is found in the file name, it is double quoted
|
||||
* - example:
|
||||
* input: a'b
|
||||
* output: 'a'"'"'b'
|
||||
* - When the '!' char is found in the file name, it is replaced by an unquoted
|
||||
* verbatim char "\!"
|
||||
* - example:
|
||||
* input: a!b
|
||||
* output 'a'\!'b'
|
||||
*
|
||||
* @param[in] file_name File name string to be quoted before used on shell
|
||||
* @param[out] buf Buffer to receive the final quoted file name. Must
|
||||
* have room for the final quoted string. The maximum
|
||||
* output length would be (3 * strlen(file_name) + 1)
|
||||
* since in the worst case each character would be
|
||||
* replaced by 3 characters, plus the terminating '\0'.
|
||||
* @param[in] buf_len The size of the provided output buffer
|
||||
*
|
||||
* @returns SSH_ERROR on error; length of the resulting string not counting the
|
||||
* string terminator '\0'
|
||||
* */
|
||||
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len)
|
||||
/* Increment 64b integer in network byte order */
|
||||
void
|
||||
uint64_inc(unsigned char *counter)
|
||||
{
|
||||
const char *src = NULL;
|
||||
char *dst = NULL;
|
||||
size_t required_buf_len;
|
||||
int i;
|
||||
|
||||
enum ssh_quote_state_e state = NO_QUOTE;
|
||||
|
||||
if (file_name == NULL || buf == NULL || buf_len == 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Invalid parameter");
|
||||
return SSH_ERROR;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
counter[i]++;
|
||||
if (counter[i])
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only allow file names smaller than 32kb. */
|
||||
if (strlen(file_name) > 32 * 1024) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "File name too long");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Paranoia check */
|
||||
required_buf_len = (size_t)3 * strlen(file_name) + 1;
|
||||
if (required_buf_len > buf_len) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Buffer too small");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
src = file_name;
|
||||
dst = buf;
|
||||
|
||||
while ((*src != '\0')) {
|
||||
switch (*src) {
|
||||
|
||||
/* The '\'' char is double quoted */
|
||||
|
||||
case '\'':
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* Start a new double quoted string. The '\'' char will be
|
||||
* copied to the beginning of it at the end of the loop. */
|
||||
*dst++ = '"';
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* Close the current single quoted string and start a new double
|
||||
* quoted string. The '\'' char will be copied to the beginning
|
||||
* of it at the end of the loop. */
|
||||
*dst++ = '\'';
|
||||
*dst++ = '"';
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* If already in the double quoted string, keep copying the
|
||||
* sequence of chars. */
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* When the '\'' char is found, the resulting state will be
|
||||
* DOUBLE_QUOTE in any case*/
|
||||
state = DOUBLE_QUOTE;
|
||||
break;
|
||||
|
||||
/* The '!' char is replaced by unquoted "\!" */
|
||||
|
||||
case '!':
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* The '!' char is interpreted in some shells (e.g. CSH) even
|
||||
* when is quoted with single quotes. Replace it with unquoted
|
||||
* "\!" which is correctly interpreted as the '!' character. */
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* Close the current quoted string and replace '!' for unquoted
|
||||
* "\!" */
|
||||
*dst++ = '\'';
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* Close current quoted string and replace "!" for unquoted
|
||||
* "\!" */
|
||||
*dst++ = '"';
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* When the '!' char is found, the resulting state will be NO_QUOTE
|
||||
* in any case*/
|
||||
state = NO_QUOTE;
|
||||
break;
|
||||
|
||||
/* Ordinary chars are single quoted */
|
||||
|
||||
default:
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* Start a new single quoted string */
|
||||
*dst++ = '\'';
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* If already in the single quoted string, keep copying the
|
||||
* sequence of chars. */
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* Close current double quoted string and start a new single
|
||||
* quoted string. */
|
||||
*dst++ = '"';
|
||||
*dst++ = '\'';
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* When an ordinary char is found, the resulting state will be
|
||||
* SINGLE_QUOTE in any case*/
|
||||
state = SINGLE_QUOTE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy the current char to output */
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
/* Close the quoted string when necessary */
|
||||
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* No open string */
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* Close current single quoted string */
|
||||
*dst++ = '\'';
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* Close current double quoted string */
|
||||
*dst++ = '"';
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Put the string terminator */
|
||||
*dst = '\0';
|
||||
|
||||
return dst - buf;
|
||||
|
||||
error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -302,6 +302,37 @@ int ssh_options_set_algo(ssh_session session,
|
||||
* \n
|
||||
* See the corresponding numbers in libssh.h.
|
||||
*
|
||||
* - SSH_OPTIONS_AUTH_CALLBACK:
|
||||
* Set a callback to use your own authentication function
|
||||
* (function pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_AUTH_USERDATA:
|
||||
* Set the user data passed to the authentication
|
||||
* function (generic pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_LOG_CALLBACK:
|
||||
* Set a callback to use your own logging function
|
||||
* (function pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_LOG_USERDATA:
|
||||
* Set the user data passed to the logging function
|
||||
* (generic pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_STATUS_CALLBACK:
|
||||
* Set a callback to show connection status in realtime
|
||||
* (function pointer).\n
|
||||
* \n
|
||||
* @code
|
||||
* fn(void *arg, float status)
|
||||
* @endcode
|
||||
* \n
|
||||
* During ssh_connect(), libssh will call the callback
|
||||
* with status from 0.0 to 1.0.
|
||||
*
|
||||
* - SSH_OPTIONS_STATUS_ARG:
|
||||
* Set the status argument which should be passed to the
|
||||
* status callback (generic pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_CIPHERS_C_S:
|
||||
* Set the symmetric cipher client to server (const char *,
|
||||
* comma-separated list).
|
||||
@@ -390,6 +421,12 @@ int ssh_options_set_algo(ssh_session session,
|
||||
* Set it to disable Nagle's Algorithm (TCP_NODELAY) on the
|
||||
* session socket. (int, 0=false)
|
||||
*
|
||||
* - SSH_OPTIONS_PROCESS_CONFIG
|
||||
* Set it to false to disable automatic processing of per-user
|
||||
* and system-wide OpenSSH configuration files. LibSSH
|
||||
* automatically uses these configuration files unless
|
||||
* you provide it with this option or with different file (bool).
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
@@ -918,6 +955,15 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
session->opts.nodelay = (*x & 0xff) > 0 ? 1 : 0;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_PROCESS_CONFIG:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
bool *x = (bool *)value;
|
||||
session->opts.config_processed = !(*x);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||
return -1;
|
||||
@@ -1299,6 +1345,8 @@ int ssh_options_parse_config(ssh_session session, const char *filename) {
|
||||
r = ssh_config_parse_file(session, "/etc/ssh/ssh_config");
|
||||
}
|
||||
|
||||
/* Do not process the default configuration as part of connection again */
|
||||
session->opts.config_processed = true;
|
||||
out:
|
||||
free(expanded_filename);
|
||||
return r;
|
||||
|
||||
269
src/packet.c
269
src/packet.c
@@ -47,6 +47,7 @@
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/auth.h"
|
||||
#include "libssh/gssapi.h"
|
||||
#include "libssh/bytearray.h"
|
||||
|
||||
static ssh_packet_callback default_packet_handlers[]= {
|
||||
ssh_packet_disconnect_callback, // SSH2_MSG_DISCONNECT 1
|
||||
@@ -263,17 +264,13 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
||||
/*
|
||||
* States required:
|
||||
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
|
||||
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
|
||||
* (re-exchange)
|
||||
* - dh_handshake_state == DH_STATE_FINISHED
|
||||
*
|
||||
* Transitions:
|
||||
* - None
|
||||
* */
|
||||
|
||||
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
|
||||
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
|
||||
{
|
||||
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
|
||||
rc = SSH_PACKET_DENIED;
|
||||
break;
|
||||
}
|
||||
@@ -956,8 +953,8 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
||||
size_t processed = 0; /* number of byte processed from the callback */
|
||||
enum ssh_packet_filter_result_e filter_result;
|
||||
|
||||
if(session->current_crypto != NULL) {
|
||||
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
|
||||
if (session->current_crypto != NULL) {
|
||||
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
|
||||
}
|
||||
if (lenfield_blocksize == 0) {
|
||||
lenfield_blocksize = blocksize;
|
||||
@@ -1065,32 +1062,45 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
||||
packet_len - (lenfield_blocksize - sizeof(uint32_t));
|
||||
cleartext_packet = ssh_buffer_allocate(session->in_buffer,
|
||||
packet_remaining);
|
||||
if (session->current_crypto) {
|
||||
/*
|
||||
* Decrypt the rest of the packet (lenfield_blocksize bytes already
|
||||
* have been decrypted)
|
||||
*/
|
||||
if (packet_remaining > 0) {
|
||||
rc = ssh_packet_decrypt(session,
|
||||
cleartext_packet,
|
||||
(uint8_t *)data,
|
||||
lenfield_blocksize,
|
||||
processed - lenfield_blocksize);
|
||||
if (cleartext_packet == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (packet_second_block != NULL) {
|
||||
if (session->current_crypto != NULL) {
|
||||
/*
|
||||
* Decrypt the rest of the packet (lenfield_blocksize bytes
|
||||
* already have been decrypted)
|
||||
*/
|
||||
if (packet_remaining > 0) {
|
||||
rc = ssh_packet_decrypt(session,
|
||||
cleartext_packet,
|
||||
(uint8_t *)data,
|
||||
lenfield_blocksize,
|
||||
processed - lenfield_blocksize);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Decryption error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
mac = packet_second_block + packet_remaining;
|
||||
|
||||
rc = ssh_packet_hmac_verify(session,
|
||||
session->in_buffer,
|
||||
mac,
|
||||
session->current_crypto->in_hmac);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Decryption error");
|
||||
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
||||
goto error;
|
||||
}
|
||||
processed += current_macsize;
|
||||
} else {
|
||||
memcpy(cleartext_packet,
|
||||
packet_second_block,
|
||||
packet_remaining);
|
||||
}
|
||||
mac = packet_second_block + packet_remaining;
|
||||
|
||||
rc = ssh_packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
||||
goto error;
|
||||
}
|
||||
processed += current_macsize;
|
||||
} else {
|
||||
memcpy(cleartext_packet, packet_second_block, packet_remaining);
|
||||
}
|
||||
|
||||
/* skip the size field which has been processed before */
|
||||
@@ -1231,6 +1241,17 @@ void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callback
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief remove the callbacks from the packet layer
|
||||
*/
|
||||
void ssh_packet_remove_callbacks(ssh_session session, ssh_packet_callbacks callbacks){
|
||||
struct ssh_iterator *it = NULL;
|
||||
it = ssh_list_find(session->packet_callbacks, callbacks);
|
||||
if (it != NULL) {
|
||||
ssh_list_remove(session->packet_callbacks, it);
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief sets the default packet handlers
|
||||
*/
|
||||
@@ -1361,106 +1382,112 @@ static int ssh_packet_write(ssh_session session) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int packet_send2(ssh_session session) {
|
||||
unsigned int blocksize = (session->current_crypto ?
|
||||
session->current_crypto->out_cipher->blocksize : 8);
|
||||
unsigned int lenfield_blocksize = (session->current_crypto ?
|
||||
session->current_crypto->out_cipher->lenfield_blocksize : 0);
|
||||
enum ssh_hmac_e hmac_type = (session->current_crypto ?
|
||||
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
|
||||
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
|
||||
unsigned char *hmac = NULL;
|
||||
char padstring[32] = { 0 };
|
||||
int rc = SSH_ERROR;
|
||||
uint32_t finallen,payloadsize,compsize;
|
||||
uint8_t padding;
|
||||
ssh_buffer header_buffer = ssh_buffer_new();
|
||||
static int packet_send2(ssh_session session)
|
||||
{
|
||||
unsigned int blocksize =
|
||||
(session->current_crypto ?
|
||||
session->current_crypto->out_cipher->blocksize : 8);
|
||||
unsigned int lenfield_blocksize =
|
||||
(session->current_crypto ?
|
||||
session->current_crypto->out_cipher->lenfield_blocksize : 0);
|
||||
enum ssh_hmac_e hmac_type =
|
||||
(session->current_crypto ?
|
||||
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
|
||||
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
|
||||
unsigned char *hmac = NULL;
|
||||
uint8_t padding_data[32] = { 0 };
|
||||
uint8_t padding_size;
|
||||
uint32_t finallen, payloadsize, compsize;
|
||||
uint8_t header[5] = {0};
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
payloadsize = currentlen;
|
||||
payloadsize = currentlen;
|
||||
#ifdef WITH_ZLIB
|
||||
if (session->current_crypto
|
||||
&& session->current_crypto->do_compress_out
|
||||
&& ssh_buffer_get_len(session->out_buffer)) {
|
||||
if (compress_buffer(session,session->out_buffer) < 0) {
|
||||
goto error;
|
||||
if (session->current_crypto != NULL &&
|
||||
session->current_crypto->do_compress_out &&
|
||||
ssh_buffer_get_len(session->out_buffer) > 0) {
|
||||
rc = compress_buffer(session,session->out_buffer);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
currentlen = ssh_buffer_get_len(session->out_buffer);
|
||||
}
|
||||
currentlen = ssh_buffer_get_len(session->out_buffer);
|
||||
}
|
||||
#endif /* WITH_ZLIB */
|
||||
compsize = currentlen;
|
||||
/* compressed payload + packet len (4) + padding len (1) */
|
||||
/* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */
|
||||
padding = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize));
|
||||
if(padding < 4) {
|
||||
padding += blocksize;
|
||||
}
|
||||
|
||||
if (session->current_crypto != NULL) {
|
||||
int ok;
|
||||
|
||||
ok = ssh_get_random(padstring, padding, 0);
|
||||
if (!ok) {
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (header_buffer == NULL){
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
finallen = currentlen + padding + 1;
|
||||
rc = ssh_buffer_pack(header_buffer, "db", finallen, padding);
|
||||
if (rc == SSH_ERROR){
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_prepend_data(session->out_buffer,
|
||||
ssh_buffer_get(header_buffer),
|
||||
ssh_buffer_get_len(header_buffer));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
#ifdef WITH_PCAP
|
||||
if (session->pcap_ctx) {
|
||||
ssh_pcap_context_write(session->pcap_ctx,
|
||||
SSH_PCAP_DIR_OUT,
|
||||
ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
}
|
||||
#endif
|
||||
hmac = ssh_packet_encrypt(session, ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
if (hmac) {
|
||||
rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
compsize = currentlen;
|
||||
/* compressed payload + packet len (4) + padding_size len (1) */
|
||||
/* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */
|
||||
padding_size = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize));
|
||||
if (padding_size < 4) {
|
||||
padding_size += blocksize;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_packet_write(session);
|
||||
session->send_seq++;
|
||||
if (session->raw_counter != NULL) {
|
||||
session->raw_counter->out_bytes += payloadsize;
|
||||
session->raw_counter->out_packets++;
|
||||
}
|
||||
if (session->current_crypto != NULL) {
|
||||
int ok;
|
||||
|
||||
ok = ssh_get_random(padding_data, padding_size, 0);
|
||||
if (!ok) {
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
finallen = currentlen + padding_size + 1;
|
||||
|
||||
PUSH_BE_U32(header, 0, finallen);
|
||||
PUSH_BE_U8(header, 4, padding_size);
|
||||
|
||||
rc = ssh_buffer_prepend_data(session->out_buffer,
|
||||
header,
|
||||
sizeof(header));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_add_data(session->out_buffer, padding_data, padding_size);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
if (session->pcap_ctx != NULL) {
|
||||
ssh_pcap_context_write(session->pcap_ctx,
|
||||
SSH_PCAP_DIR_OUT,
|
||||
ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
hmac = ssh_packet_encrypt(session,
|
||||
ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
if (hmac != NULL) {
|
||||
rc = ssh_buffer_add_data(session->out_buffer,
|
||||
hmac,
|
||||
hmac_digest_len(hmac_type));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_packet_write(session);
|
||||
session->send_seq++;
|
||||
if (session->raw_counter != NULL) {
|
||||
session->raw_counter->out_bytes += payloadsize;
|
||||
session->raw_counter->out_packets++;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"packet: wrote [len=%d,padding_size=%hhd,comp=%d,payload=%d]",
|
||||
finallen, padding_size, compsize, payloadsize);
|
||||
|
||||
rc = ssh_buffer_reinit(session->out_buffer);
|
||||
if (rc < 0) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
|
||||
finallen, padding, compsize, payloadsize);
|
||||
if (ssh_buffer_reinit(session->out_buffer) < 0) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
error:
|
||||
if (header_buffer != NULL) {
|
||||
ssh_buffer_free(header_buffer);
|
||||
}
|
||||
return rc; /* SSH_OK, AGAIN or ERROR */
|
||||
return rc; /* SSH_OK, AGAIN or ERROR */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -257,10 +257,10 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
|
||||
}
|
||||
session->dh_handshake_state = DH_STATE_FINISHED;
|
||||
session->ssh_connection_callback(session);
|
||||
return SSH_PACKET_USED;
|
||||
return SSH_PACKET_USED;
|
||||
error:
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -176,17 +176,6 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
||||
return session->current_crypto->hmacbuf;
|
||||
}
|
||||
|
||||
static int secure_memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
int rc = 0;
|
||||
const unsigned char *p1 = s1;
|
||||
const unsigned char *p2 = s2;
|
||||
for (; n > 0; --n) {
|
||||
rc |= *p1++ ^ *p2++;
|
||||
}
|
||||
return (rc != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
@@ -209,8 +198,9 @@ int ssh_packet_hmac_verify(ssh_session session,
|
||||
unsigned int len;
|
||||
uint32_t seq;
|
||||
|
||||
/* AEAD type have no mac checking */
|
||||
if (type == SSH_HMAC_AEAD_POLY1305) {
|
||||
/* AEAD types have no mac checking */
|
||||
if (type == SSH_HMAC_AEAD_POLY1305 ||
|
||||
type == SSH_HMAC_AEAD_GCM) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
@@ -230,7 +220,7 @@ int ssh_packet_hmac_verify(ssh_session session,
|
||||
ssh_print_hexa("Computed mac",hmacbuf,len);
|
||||
ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t));
|
||||
#endif
|
||||
if (secure_memcmp(mac, hmacbuf, len) == 0) {
|
||||
if (memcmp(mac, hmacbuf, len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,10 +91,13 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) {
|
||||
*/
|
||||
const char *ssh_pki_key_ecdsa_name(const ssh_key key)
|
||||
{
|
||||
if (key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC /* FIXME Better ECC check needed */
|
||||
return pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
|
||||
#else
|
||||
(void) key; /* unused */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
@@ -2202,8 +2205,9 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
crypto = session->next_crypto ? session->next_crypto :
|
||||
session->current_crypto;
|
||||
session->current_crypto;
|
||||
|
||||
if (crypto->secret_hash == NULL){
|
||||
ssh_set_error(session,SSH_FATAL,"Missing secret_hash");
|
||||
|
||||
@@ -313,6 +313,9 @@ ssh_pki_openssh_import(const char *text_key,
|
||||
*/
|
||||
if (!private) {
|
||||
rc = ssh_pki_import_pubkey_blob(pubkey0, &key);
|
||||
if (rc != SSH_OK) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Failed to import public key blob");
|
||||
}
|
||||
/* in either case we clean up here */
|
||||
goto out;
|
||||
}
|
||||
@@ -330,7 +333,6 @@ ssh_pki_openssh_import(const char *text_key,
|
||||
|
||||
privkey_buffer = ssh_buffer_new();
|
||||
if (privkey_buffer == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -409,7 +411,7 @@ static int pki_openssh_export_privkey_blob(const ssh_key privkey,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (privkey->ed25519_privkey == NULL ||
|
||||
privkey->ed25519_pubkey == NULL) {
|
||||
privkey->ed25519_pubkey == NULL){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = ssh_buffer_pack(buffer,
|
||||
@@ -442,6 +444,7 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
|
||||
char passphrase_buffer[128];
|
||||
int rc;
|
||||
int i;
|
||||
uint8_t padding = 1;
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp(ciphername, "none");
|
||||
@@ -468,6 +471,14 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
|
||||
SSH_LOG(SSH_LOG_WARN, "Unsupported KDF %s", kdfname);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
while (ssh_buffer_get_len(privkey_buffer) % cipher.blocksize != 0) {
|
||||
rc = ssh_buffer_add_u8(privkey_buffer, padding);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
padding++;
|
||||
}
|
||||
|
||||
/* We need material for key (keysize bits / 8) and IV (blocksize) */
|
||||
key_material_len = cipher.keysize/8 + cipher.blocksize;
|
||||
if (key_material_len > sizeof(key_material)){
|
||||
@@ -544,7 +555,6 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
|
||||
int to_encrypt=0;
|
||||
unsigned char *b64;
|
||||
uint32_t str_len, len;
|
||||
uint8_t padding = 1;
|
||||
int ok;
|
||||
int rc;
|
||||
|
||||
@@ -595,18 +605,6 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Add padding regardless encryption because it is expected
|
||||
* by OpenSSH tools.
|
||||
* XXX Using 16 B as we use only AES cipher below anyway.
|
||||
*/
|
||||
while (ssh_buffer_get_len(privkey_buffer) % 16 != 0) {
|
||||
rc = ssh_buffer_add_u8(privkey_buffer, padding);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
padding++;
|
||||
}
|
||||
|
||||
if (to_encrypt){
|
||||
ssh_buffer kdf_buf;
|
||||
|
||||
|
||||
@@ -1038,7 +1038,7 @@ int pki_privkey_build_rsa(ssh_key key,
|
||||
ssh_string n,
|
||||
ssh_string e,
|
||||
ssh_string d,
|
||||
ssh_string iqmp,
|
||||
UNUSED_PARAM(ssh_string iqmp),
|
||||
ssh_string p,
|
||||
ssh_string q)
|
||||
{
|
||||
@@ -1657,7 +1657,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
|
||||
s = ssh_string_new(20);
|
||||
if (s == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1666,7 +1665,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ps = ssh_make_string_bn(s);
|
||||
ssh_string_free(s);
|
||||
if (ps == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1675,8 +1673,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
* object */
|
||||
rc = DSA_SIG_set0(sig->dsa_sig, pr, ps);
|
||||
if (rc == 0) {
|
||||
bignum_safe_free(ps);
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1685,9 +1681,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
@@ -1741,7 +1734,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
rlen = ssh_buffer_get_len(b);
|
||||
ssh_buffer_free(b);
|
||||
if (s == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1754,7 +1746,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_string_burn(s);
|
||||
ssh_string_free(s);
|
||||
if (ps == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1763,8 +1754,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
* ECDSA signature object */
|
||||
rc = ECDSA_SIG_set0(sig->ecdsa_sig, pr, ps);
|
||||
if (rc == 0) {
|
||||
bignum_safe_free(ps);
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gcrypt.h>
|
||||
@@ -390,7 +389,7 @@ static int privatekey_dek_header(const char *header, unsigned int header_len,
|
||||
while(p[len] == '\n' || p[len] == '\r') /* skip empty lines */ \
|
||||
len++; \
|
||||
if(p[len] == '\0') /* EOL */ \
|
||||
eol = true; \
|
||||
len = -1; \
|
||||
else /* calculate length */ \
|
||||
for(p += len, len = 0; p[len] && p[len] != '\n' \
|
||||
&& p[len] != '\r'; len++); \
|
||||
@@ -410,8 +409,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
unsigned int iv_len = 0;
|
||||
int algo = 0;
|
||||
int mode = 0;
|
||||
bool eol = false;
|
||||
size_t len;
|
||||
int len;
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
@@ -443,38 +441,25 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
len = 0;
|
||||
get_next_line(p, len);
|
||||
|
||||
while(!eol && strncmp(p, header_begin, header_begin_size)) {
|
||||
while(len > 0 && strncmp(p, header_begin, header_begin_size)) {
|
||||
/* skip line */
|
||||
get_next_line(p, len);
|
||||
}
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
if(len < 0) {
|
||||
/* no header found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* skip header line */
|
||||
get_next_line(p, len);
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len > 11 && strncmp("Proc-Type: 4,ENCRYPTED", p, 11) == 0) {
|
||||
/* skip line */
|
||||
get_next_line(p, len);
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len > 10 && strncmp("DEK-Info: ", p, 10) == 0) {
|
||||
p += 10;
|
||||
len = 0;
|
||||
get_next_line(p, len);
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
if (privatekey_dek_header(p, len, &algo, &mode, &key_len,
|
||||
&iv, &iv_len) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
@@ -497,7 +482,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
}
|
||||
|
||||
get_next_line(p, len);
|
||||
while(!eol && strncmp(p, header_end, header_end_size) != 0) {
|
||||
while(len > 0 && strncmp(p, header_end, header_end_size) != 0) {
|
||||
if (ssh_buffer_add_data(buffer, p, len) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
@@ -506,7 +491,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
get_next_line(p, len);
|
||||
}
|
||||
|
||||
if (eol || strncmp(p, header_end, header_end_size) != 0) {
|
||||
if (len == -1 || strncmp(p, header_end, header_end_size) != 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
return NULL;
|
||||
|
||||
@@ -917,9 +917,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
switch(type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA: {
|
||||
|
||||
@@ -453,7 +453,6 @@ static void ssh_server_connection_callback(ssh_session session){
|
||||
|
||||
/* from now, the packet layer is handling incoming packets */
|
||||
session->socket_callbacks.data=ssh_packet_socket_callback;
|
||||
ssh_packet_register_socket_callback(session, session->socket);
|
||||
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
set_status(session, 0.5f);
|
||||
@@ -524,7 +523,7 @@ static void ssh_server_connection_callback(ssh_session session){
|
||||
* our supported extensions now. This is the first message after
|
||||
* sending NEWKEYS message and after turning on crypto.
|
||||
*/
|
||||
if (session->extensions & SSH_EXT_NEGOTIATION &&
|
||||
if (session->extensions &&
|
||||
session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
|
||||
ssh_server_send_extensions(session);
|
||||
}
|
||||
|
||||
@@ -449,12 +449,13 @@ void ssh_silent_disconnect(ssh_session session) {
|
||||
*
|
||||
* @param[in] blocking Zero for nonblocking mode.
|
||||
*/
|
||||
void ssh_set_blocking(ssh_session session, int blocking) {
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
session->flags &= ~SSH_SESSION_FLAG_BLOCKING;
|
||||
session->flags |= blocking ? SSH_SESSION_FLAG_BLOCKING : 0;
|
||||
void ssh_set_blocking(ssh_session session, int blocking)
|
||||
{
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
session->flags &= ~SSH_SESSION_FLAG_BLOCKING;
|
||||
session->flags |= blocking ? SSH_SESSION_FLAG_BLOCKING : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,8 +464,9 @@ void ssh_set_blocking(ssh_session session, int blocking) {
|
||||
* @returns 0 if the session is nonblocking,
|
||||
* @returns 1 if the functions may block.
|
||||
*/
|
||||
int ssh_is_blocking(ssh_session session){
|
||||
return (session->flags&SSH_SESSION_FLAG_BLOCKING) ? 1 : 0;
|
||||
int ssh_is_blocking(ssh_session session)
|
||||
{
|
||||
return (session->flags & SSH_SESSION_FLAG_BLOCKING) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Waits until the output socket is empty */
|
||||
@@ -643,11 +645,13 @@ int ssh_handle_packets(ssh_session session, int timeout) {
|
||||
* @param[in] session The session handle to use.
|
||||
*
|
||||
* @param[in] timeout Set an upper limit on the time for which this function
|
||||
* will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE
|
||||
* (-1) means an infinite timeout.
|
||||
* will block, in milliseconds. Specifying
|
||||
* SSH_TIMEOUT_INFINITE (-1) means an infinite timeout.
|
||||
* Specifying SSH_TIMEOUT_USER means to use the timeout
|
||||
* specified in options. 0 means poll will return immediately.
|
||||
* SSH_TIMEOUT_DEFAULT uses blocking parameters of the session.
|
||||
* specified in options. 0 means poll will return
|
||||
* immediately.
|
||||
* SSH_TIMEOUT_DEFAULT uses the session timeout if set or
|
||||
* uses blocking parameters of the session.
|
||||
* This parameter is passed to the poll() function.
|
||||
*
|
||||
* @param[in] fct Termination function to be used to determine if it is
|
||||
@@ -656,46 +660,50 @@ int ssh_handle_packets(ssh_session session, int timeout) {
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
*/
|
||||
int ssh_handle_packets_termination(ssh_session session,
|
||||
int timeout,
|
||||
long timeout,
|
||||
ssh_termination_function fct,
|
||||
void *user)
|
||||
{
|
||||
struct ssh_timestamp ts;
|
||||
long timeout_ms = SSH_TIMEOUT_INFINITE; /* default timeout */
|
||||
long tm;
|
||||
int ret = SSH_OK;
|
||||
int tm;
|
||||
|
||||
if (timeout == SSH_TIMEOUT_USER) {
|
||||
/* If a timeout has been provided, use it */
|
||||
if (timeout > 0) {
|
||||
timeout_ms = timeout;
|
||||
} else {
|
||||
if (ssh_is_blocking(session)) {
|
||||
timeout = ssh_make_milliseconds(session->opts.timeout,
|
||||
session->opts.timeout_usec);
|
||||
if (timeout == SSH_TIMEOUT_USER || timeout == SSH_TIMEOUT_DEFAULT) {
|
||||
if (session->opts.timeout > 0 ||
|
||||
session->opts.timeout_usec > 0) {
|
||||
timeout_ms =
|
||||
ssh_make_milliseconds(session->opts.timeout,
|
||||
session->opts.timeout_usec);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
timeout = SSH_TIMEOUT_NONBLOCKING;
|
||||
}
|
||||
} else if (timeout == SSH_TIMEOUT_DEFAULT) {
|
||||
if (ssh_is_blocking(session)) {
|
||||
timeout = SSH_TIMEOUT_INFINITE;
|
||||
} else {
|
||||
timeout = SSH_TIMEOUT_NONBLOCKING;
|
||||
timeout_ms = SSH_TIMEOUT_NONBLOCKING;
|
||||
}
|
||||
}
|
||||
|
||||
/* avoid unnecessary syscall for the SSH_TIMEOUT_NONBLOCKING case */
|
||||
if (timeout != SSH_TIMEOUT_NONBLOCKING) {
|
||||
if (timeout_ms != SSH_TIMEOUT_NONBLOCKING) {
|
||||
ssh_timestamp_init(&ts);
|
||||
}
|
||||
|
||||
tm = timeout;
|
||||
tm = timeout_ms;
|
||||
while(!fct(user)) {
|
||||
ret = ssh_handle_packets(session, tm);
|
||||
if (ret == SSH_ERROR) {
|
||||
break;
|
||||
}
|
||||
if (ssh_timeout_elapsed(&ts,timeout)) {
|
||||
if (ssh_timeout_elapsed(&ts, timeout_ms)) {
|
||||
ret = fct(user) ? SSH_OK : SSH_AGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
tm = ssh_timeout_update(&ts, timeout);
|
||||
tm = ssh_timeout_update(&ts, timeout_ms);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
194
src/sftp.c
194
src/sftp.c
@@ -48,6 +48,7 @@
|
||||
#include "libssh/channels.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/bytearray.h"
|
||||
|
||||
#ifdef WITH_SFTP
|
||||
|
||||
@@ -67,19 +68,6 @@ static void sftp_message_free(sftp_message msg);
|
||||
static void sftp_set_error(sftp_session sftp, int errnum);
|
||||
static void status_msg_free(sftp_status_message status);
|
||||
|
||||
static uint32_t sftp_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 sftp_ext sftp_ext_new(void) {
|
||||
sftp_ext ext;
|
||||
|
||||
@@ -333,32 +321,41 @@ void sftp_free(sftp_session sftp)
|
||||
SAFE_FREE(sftp);
|
||||
}
|
||||
|
||||
int sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload){
|
||||
int size;
|
||||
int sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload)
|
||||
{
|
||||
uint8_t header[5] = {0};
|
||||
uint32_t payload_size;
|
||||
int size;
|
||||
int rc;
|
||||
|
||||
if (ssh_buffer_prepend_data(payload, &type, sizeof(uint8_t)) < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
return -1;
|
||||
}
|
||||
/* Add size of type */
|
||||
payload_size = ssh_buffer_get_len(payload) + sizeof(uint8_t);
|
||||
PUSH_BE_U32(header, 0, payload_size);
|
||||
PUSH_BE_U8(header, 4, type);
|
||||
|
||||
size = htonl(ssh_buffer_get_len(payload));
|
||||
if (ssh_buffer_prepend_data(payload, &size, sizeof(uint32_t)) < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
return -1;
|
||||
}
|
||||
rc = ssh_buffer_prepend_data(payload, header, sizeof(header));
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size = ssh_channel_write(sftp->channel, ssh_buffer_get(payload),
|
||||
ssh_buffer_get_len(payload));
|
||||
if (size < 0) {
|
||||
return -1;
|
||||
} else if((uint32_t) size != ssh_buffer_get_len(payload)) {
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Had to write %d bytes, wrote only %d",
|
||||
ssh_buffer_get_len(payload),
|
||||
size);
|
||||
}
|
||||
size = ssh_channel_write(sftp->channel,
|
||||
ssh_buffer_get(payload),
|
||||
ssh_buffer_get_len(payload));
|
||||
if (size < 0) {
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
if ((uint32_t)size != ssh_buffer_get_len(payload)) {
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Had to write %d bytes, wrote only %d",
|
||||
ssh_buffer_get_len(payload),
|
||||
size);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
@@ -380,12 +377,14 @@ sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
rc = ssh_buffer_reinit(packet->payload);
|
||||
if (rc != 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
packet->payload = ssh_buffer_new();
|
||||
if (packet->payload == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -401,6 +400,10 @@ sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
} else if (s == 0) {
|
||||
is_eof = ssh_channel_is_eof(sftp->channel);
|
||||
if (is_eof) {
|
||||
ssh_set_error(sftp->session,
|
||||
SSH_FATAL,
|
||||
"Received EOF while reading sftp packet size");
|
||||
sftp_set_error(sftp, SSH_FX_EOF);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
@@ -408,9 +411,10 @@ sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
}
|
||||
} while (nread < 4);
|
||||
|
||||
size = sftp_get_u32(buffer);
|
||||
size = PULL_BE_U32(buffer, 0);
|
||||
if (size == 0 || size > SFTP_PACKET_SIZE_MAX) {
|
||||
ssh_set_error(sftp->session, SSH_FATAL, "Invalid sftp packet size!");
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -421,6 +425,10 @@ sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
} else if (nread == 0) {
|
||||
is_eof = ssh_channel_is_eof(sftp->channel);
|
||||
if (is_eof) {
|
||||
ssh_set_error(sftp->session,
|
||||
SSH_FATAL,
|
||||
"Received EOF while reading sftp packet type");
|
||||
sftp_set_error(sftp, SSH_FX_EOF);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -434,6 +442,7 @@ sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
nread = ssh_buffer_allocate_size(packet->payload, size);
|
||||
if (nread < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
goto error;
|
||||
}
|
||||
while (size > 0 && size < SFTP_PACKET_SIZE_MAX) {
|
||||
@@ -450,12 +459,17 @@ sftp_packet sftp_packet_read(sftp_session sftp)
|
||||
rc = ssh_buffer_add_data(packet->payload, buffer, nread);
|
||||
if (rc != 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
goto error;
|
||||
}
|
||||
} else { /* nread == 0 */
|
||||
/* Retry the reading unless the remote was closed */
|
||||
is_eof = ssh_channel_is_eof(sftp->channel);
|
||||
if (is_eof) {
|
||||
ssh_set_error(sftp->session,
|
||||
SSH_REQUEST_DENIED,
|
||||
"Received EOF while reading sftp packet");
|
||||
sftp_set_error(sftp, SSH_FX_EOF);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -513,12 +527,14 @@ static sftp_message sftp_get_message(sftp_packet packet)
|
||||
SSH_FATAL,
|
||||
"Unknown packet type %d",
|
||||
packet->type);
|
||||
sftp_set_error(packet->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg = calloc(1, sizeof(struct sftp_message_struct));
|
||||
if (msg == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(packet->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -534,6 +550,7 @@ static sftp_message sftp_get_message(sftp_packet packet)
|
||||
ssh_set_error(packet->sftp->session, SSH_FATAL,
|
||||
"Invalid packet %d: no ID", packet->type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(packet->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -590,6 +607,7 @@ int sftp_init(sftp_session sftp) {
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -597,6 +615,7 @@ int sftp_init(sftp_session sftp) {
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
if (sftp_packet_write(sftp, SSH_FXP_INIT, buffer) < 0) {
|
||||
@@ -619,6 +638,7 @@ int sftp_init(sftp_session sftp) {
|
||||
/* TODO: are we sure there are 4 bytes ready? */
|
||||
rc = ssh_buffer_unpack(packet->payload, "d", &version);
|
||||
if (rc != SSH_OK){
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
@@ -644,6 +664,7 @@ int sftp_init(sftp_session sftp) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
SAFE_FREE(ext_name);
|
||||
SAFE_FREE(ext_data);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
tmp[count - 1] = ext_name;
|
||||
@@ -654,6 +675,7 @@ int sftp_init(sftp_session sftp) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
SAFE_FREE(ext_name);
|
||||
SAFE_FREE(ext_data);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
tmp[count - 1] = ext_data;
|
||||
@@ -739,6 +761,7 @@ static sftp_request_queue request_queue_new(sftp_message msg) {
|
||||
queue = calloc(1, sizeof(struct sftp_request_queue_struct));
|
||||
if (queue == NULL) {
|
||||
ssh_set_error_oom(msg->sftp->session);
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -835,12 +858,14 @@ static sftp_status_message parse_status_msg(sftp_message msg){
|
||||
if (msg->packet_type != SSH_FXP_STATUS) {
|
||||
ssh_set_error(msg->sftp->session, SSH_FATAL,
|
||||
"Not a ssh_fxp_status message passed in!");
|
||||
sftp_set_error(msg->sftp, SSH_FX_BAD_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = calloc(1, sizeof(struct sftp_status_message_struct));
|
||||
if (status == NULL) {
|
||||
ssh_set_error_oom(msg->sftp->session);
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -851,6 +876,7 @@ static sftp_status_message parse_status_msg(sftp_message msg){
|
||||
SAFE_FREE(status);
|
||||
ssh_set_error(msg->sftp->session, SSH_FATAL,
|
||||
"Invalid SSH_FXP_STATUS message");
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
rc = ssh_buffer_unpack(msg->payload, "ss",
|
||||
@@ -862,6 +888,7 @@ static sftp_status_message parse_status_msg(sftp_message msg){
|
||||
SAFE_FREE(status);
|
||||
ssh_set_error(msg->sftp->session, SSH_FATAL,
|
||||
"Invalid SSH_FXP_STATUS message");
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (status->errormsg == NULL)
|
||||
@@ -870,6 +897,7 @@ static sftp_status_message parse_status_msg(sftp_message msg){
|
||||
status->langmsg = strdup("");
|
||||
if (status->errormsg == NULL || status->langmsg == NULL) {
|
||||
ssh_set_error_oom(msg->sftp->session);
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
status_msg_free(status);
|
||||
return NULL;
|
||||
}
|
||||
@@ -899,6 +927,7 @@ static sftp_file parse_handle_msg(sftp_message msg){
|
||||
file = calloc(1, sizeof(struct sftp_file_struct));
|
||||
if (file == NULL) {
|
||||
ssh_set_error_oom(msg->sftp->session);
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -907,6 +936,7 @@ static sftp_file parse_handle_msg(sftp_message msg){
|
||||
ssh_set_error(msg->sftp->session, SSH_FATAL,
|
||||
"Invalid SSH_FXP_HANDLE message");
|
||||
SAFE_FREE(file);
|
||||
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -928,9 +958,14 @@ sftp_dir sftp_opendir(sftp_session sftp, const char *path)
|
||||
uint32_t id;
|
||||
int rc;
|
||||
|
||||
if (sftp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
payload = ssh_buffer_new();
|
||||
if (payload == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -943,6 +978,7 @@ sftp_dir sftp_opendir(sftp_session sftp, const char *path)
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(payload);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1022,6 +1058,7 @@ static sftp_attributes sftp_parse_attr_4(sftp_session sftp, ssh_buffer buf,
|
||||
attr = calloc(1, sizeof(struct sftp_attributes_struct));
|
||||
if (attr == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1239,6 +1276,7 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf,
|
||||
attr = calloc(1, sizeof(struct sftp_attributes_struct));
|
||||
if (attr == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1368,6 +1406,7 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf,
|
||||
SAFE_FREE(attr->group);
|
||||
SAFE_FREE(attr);
|
||||
ssh_set_error(sftp->session, SSH_FATAL, "Invalid ATTR structure");
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1456,6 +1495,7 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir)
|
||||
payload = ssh_buffer_new();
|
||||
if (payload == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1467,6 +1507,7 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir)
|
||||
dir->handle);
|
||||
if (rc != 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
ssh_buffer_free(payload);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1521,6 +1562,7 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Unsupported message back %d", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1586,6 +1628,7 @@ static int sftp_handle_close(sftp_session sftp, ssh_string handle)
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1598,6 +1641,7 @@ static int sftp_handle_close(sftp_session sftp, ssh_string handle)
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1639,6 +1683,7 @@ static int sftp_handle_close(sftp_session sftp, ssh_string handle)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d during sftp_handle_close!", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -1728,6 +1773,7 @@ sftp_file sftp_open(sftp_session sftp,
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1735,6 +1781,7 @@ sftp_file sftp_open(sftp_session sftp,
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1779,6 +1826,7 @@ sftp_file sftp_open(sftp_session sftp,
|
||||
SSH_FATAL,
|
||||
"Cannot open in append mode. Unknown file size.");
|
||||
sftp_close(handle);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1789,6 +1837,7 @@ sftp_file sftp_open(sftp_session sftp,
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d during open!", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1833,6 +1882,7 @@ ssize_t sftp_read(sftp_file handle, void *buf, size_t count) {
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
if (sftp_packet_write(handle->sftp, SSH_FXP_READ, buffer) < 0) {
|
||||
@@ -1901,6 +1951,7 @@ ssize_t sftp_read(sftp_file handle, void *buf, size_t count) {
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d during read!", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1917,6 +1968,7 @@ int sftp_async_read_begin(sftp_file file, uint32_t len){
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1931,6 +1983,7 @@ int sftp_async_read_begin(sftp_file file, uint32_t len){
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
if (sftp_packet_write(sftp, SSH_FXP_READ, buffer) < 0) {
|
||||
@@ -2021,6 +2074,7 @@ int sftp_async_read(sftp_file file, void *data, uint32_t size, uint32_t id){
|
||||
default:
|
||||
ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during read!",msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@@ -2040,6 +2094,7 @@ ssize_t sftp_write(sftp_file file, const void *buf, size_t count) {
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2055,6 +2110,7 @@ ssize_t sftp_write(sftp_file file, const void *buf, size_t count) {
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
packetlen=ssh_buffer_get_len(buffer);
|
||||
@@ -2100,6 +2156,7 @@ ssize_t sftp_write(sftp_file file, const void *buf, size_t count) {
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d during write!", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2155,6 +2212,7 @@ int sftp_unlink(sftp_session sftp, const char *file) {
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2167,6 +2225,7 @@ int sftp_unlink(sftp_session sftp, const char *file) {
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2211,6 +2270,7 @@ int sftp_unlink(sftp_session sftp, const char *file) {
|
||||
ssh_set_error(sftp->session,SSH_FATAL,
|
||||
"Received message %d when attempting to remove file", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -2227,6 +2287,7 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2239,6 +2300,7 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
if (sftp_packet_write(sftp, SSH_FXP_RMDIR, buffer) < 0) {
|
||||
@@ -2279,6 +2341,7 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
|
||||
"Received message %d when attempting to remove directory",
|
||||
msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -2298,6 +2361,7 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode)
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2314,6 +2378,7 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode)
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2321,6 +2386,7 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode)
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2378,6 +2444,7 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode)
|
||||
"Received message %d when attempting to make directory",
|
||||
msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -2394,6 +2461,7 @@ int sftp_rename(sftp_session sftp, const char *original, const char *newname) {
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2407,6 +2475,7 @@ int sftp_rename(sftp_session sftp, const char *original, const char *newname) {
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2457,6 +2526,7 @@ int sftp_rename(sftp_session sftp, const char *original, const char *newname) {
|
||||
"Received message %d when attempting to rename",
|
||||
msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -2475,6 +2545,7 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2487,6 +2558,7 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2494,6 +2566,7 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
|
||||
if (rc != 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2537,6 +2610,7 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d when attempting to set stats", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -2594,12 +2668,14 @@ int sftp_symlink(sftp_session sftp, const char *target, const char *dest) {
|
||||
return -1;
|
||||
if (target == NULL || dest == NULL) {
|
||||
ssh_set_error_invalid(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2622,6 +2698,7 @@ int sftp_symlink(sftp_session sftp, const char *target, const char *dest) {
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2665,6 +2742,7 @@ int sftp_symlink(sftp_session sftp, const char *target, const char *dest) {
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d when attempting to set stats", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -2684,15 +2762,18 @@ char *sftp_readlink(sftp_session sftp, const char *path)
|
||||
|
||||
if (path == NULL) {
|
||||
ssh_set_error_invalid(sftp);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (sftp->version < 3){
|
||||
ssh_set_error(sftp,SSH_REQUEST_DENIED,"sftp version %d does not support sftp_readlink",sftp->version);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2705,6 +2786,7 @@ char *sftp_readlink(sftp_session sftp, const char *path)
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2734,6 +2816,7 @@ char *sftp_readlink(sftp_session sftp, const char *path)
|
||||
ssh_set_error(sftp->session,
|
||||
SSH_ERROR,
|
||||
"Failed to retrieve link");
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2744,6 +2827,7 @@ char *sftp_readlink(sftp_session sftp, const char *path)
|
||||
if (status == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sftp_set_error(sftp, status->status);
|
||||
ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
|
||||
"SFTP server: %s", status->errormsg);
|
||||
status_msg_free(status);
|
||||
@@ -2751,6 +2835,7 @@ char *sftp_readlink(sftp_session sftp, const char *path)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d when attempting to set stats", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -2763,6 +2848,7 @@ static sftp_statvfs_t sftp_parse_statvfs(sftp_session sftp, ssh_buffer buf) {
|
||||
statvfs = calloc(1, sizeof(struct sftp_statvfs_struct));
|
||||
if (statvfs == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2782,6 +2868,7 @@ static sftp_statvfs_t sftp_parse_statvfs(sftp_session sftp, ssh_buffer buf) {
|
||||
if (rc != SSH_OK) {
|
||||
SAFE_FREE(statvfs);
|
||||
ssh_set_error(sftp->session, SSH_FATAL, "Invalid statvfs structure");
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2800,16 +2887,19 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path)
|
||||
return NULL;
|
||||
if (path == NULL) {
|
||||
ssh_set_error_invalid(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (sftp->version < 3){
|
||||
ssh_set_error(sftp,SSH_REQUEST_DENIED,"sftp version %d does not support sftp_statvfs",sftp->version);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2823,6 +2913,7 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path)
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2853,6 +2944,7 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path)
|
||||
if (status == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sftp_set_error(sftp, status->status);
|
||||
ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
|
||||
"SFTP server: %s", status->errormsg);
|
||||
status_msg_free(status);
|
||||
@@ -2860,6 +2952,7 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d when attempting to get statvfs", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -2881,6 +2974,7 @@ int sftp_fsync(sftp_file file)
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2893,6 +2987,7 @@ int sftp_fsync(sftp_file file)
|
||||
file->handle);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2952,6 +3047,7 @@ int sftp_fsync(sftp_file file)
|
||||
"Received message %d when attempting to set stats",
|
||||
msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
rc = -1;
|
||||
@@ -2978,6 +3074,7 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file)
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2991,6 +3088,7 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file)
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3021,6 +3119,7 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file)
|
||||
if (status == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sftp_set_error(sftp, status->status);
|
||||
ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
|
||||
"SFTP server: %s", status->errormsg);
|
||||
status_msg_free(status);
|
||||
@@ -3028,6 +3127,7 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d when attempting to set stats", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -3054,12 +3154,14 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
|
||||
return NULL;
|
||||
if (path == NULL) {
|
||||
ssh_set_error_invalid(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3072,6 +3174,7 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3101,6 +3204,7 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
|
||||
ssh_set_error(sftp->session,
|
||||
SSH_ERROR,
|
||||
"Failed to parse canonicalized path");
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3111,6 +3215,7 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
|
||||
if (status == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sftp_set_error(sftp, status->status);
|
||||
ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
|
||||
"SFTP server: %s", status->errormsg);
|
||||
status_msg_free(status);
|
||||
@@ -3118,6 +3223,7 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path)
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received message %d when attempting to set stats", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -3133,14 +3239,20 @@ static sftp_attributes sftp_xstat(sftp_session sftp,
|
||||
uint32_t id;
|
||||
int rc;
|
||||
|
||||
if (sftp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (path == NULL) {
|
||||
ssh_set_error_invalid(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3153,6 +3265,7 @@ static sftp_attributes sftp_xstat(sftp_session sftp,
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3189,6 +3302,7 @@ static sftp_attributes sftp_xstat(sftp_session sftp,
|
||||
ssh_set_error(sftp->session, SSH_FATAL,
|
||||
"Received mesg %d during stat()", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(sftp, SSH_FX_BAD_MESSAGE);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -3209,9 +3323,14 @@ sftp_attributes sftp_fstat(sftp_file file)
|
||||
uint32_t id;
|
||||
int rc;
|
||||
|
||||
if (file == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(file->sftp->session);
|
||||
sftp_set_error(file->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3224,6 +3343,7 @@ sftp_attributes sftp_fstat(sftp_file file)
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(file->sftp->session);
|
||||
ssh_buffer_free(buffer);
|
||||
sftp_set_error(file->sftp, SSH_FX_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3251,6 +3371,7 @@ sftp_attributes sftp_fstat(sftp_file file)
|
||||
if (status == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sftp_set_error(file->sftp, status->status);
|
||||
ssh_set_error(file->sftp->session, SSH_REQUEST_DENIED,
|
||||
"SFTP server: %s", status->errormsg);
|
||||
status_msg_free(status);
|
||||
@@ -3260,6 +3381,7 @@ sftp_attributes sftp_fstat(sftp_file file)
|
||||
ssh_set_error(file->sftp->session, SSH_FATAL,
|
||||
"Received msg %d during fstat()", msg->packet_type);
|
||||
sftp_message_free(msg);
|
||||
sftp_set_error(file->sftp, SSH_FX_BAD_MESSAGE);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
288
src/wrapper.c
288
src/wrapper.c
@@ -52,9 +52,11 @@
|
||||
static struct ssh_hmac_struct ssh_hmac_tab[] = {
|
||||
{ "hmac-sha1", SSH_HMAC_SHA1 },
|
||||
{ "hmac-sha2-256", SSH_HMAC_SHA256 },
|
||||
{ "hmac-sha2-384", SSH_HMAC_SHA384 },
|
||||
{ "hmac-sha2-512", SSH_HMAC_SHA512 },
|
||||
{ "hmac-md5", SSH_HMAC_MD5 },
|
||||
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305 },
|
||||
{ "aead-gcm", SSH_HMAC_AEAD_GCM },
|
||||
{ NULL, 0}
|
||||
};
|
||||
|
||||
@@ -68,12 +70,16 @@ size_t hmac_digest_len(enum ssh_hmac_e type) {
|
||||
return SHA_DIGEST_LEN;
|
||||
case SSH_HMAC_SHA256:
|
||||
return SHA256_DIGEST_LEN;
|
||||
case SSH_HMAC_SHA384:
|
||||
return SHA384_DIGEST_LEN;
|
||||
case SSH_HMAC_SHA512:
|
||||
return SHA512_DIGEST_LEN;
|
||||
case SSH_HMAC_MD5:
|
||||
return MD5_DIGEST_LEN;
|
||||
case SSH_HMAC_AEAD_POLY1305:
|
||||
return POLY1305_TAGLEN;
|
||||
case SSH_HMAC_AEAD_GCM:
|
||||
return AES_GCM_TAGLEN;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -218,134 +224,148 @@ void crypto_free(struct ssh_crypto_struct *crypto)
|
||||
SAFE_FREE(crypto);
|
||||
}
|
||||
|
||||
static int crypt_set_algorithms2(ssh_session session){
|
||||
const char *wanted;
|
||||
int i = 0;
|
||||
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
|
||||
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
|
||||
int cmp;
|
||||
static int crypt_set_algorithms2(ssh_session session)
|
||||
{
|
||||
const char *wanted = NULL;
|
||||
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
|
||||
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
|
||||
size_t i = 0;
|
||||
int cmp;
|
||||
|
||||
/*
|
||||
* We must scan the kex entries to find crypto algorithms and set their
|
||||
* appropriate structure.
|
||||
*/
|
||||
/*
|
||||
* We must scan the kex entries to find crypto algorithms and set their
|
||||
* appropriate structure.
|
||||
*/
|
||||
|
||||
/* out */
|
||||
wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
|
||||
while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
|
||||
i++;
|
||||
}
|
||||
/* out */
|
||||
wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
|
||||
for (i = 0; i < 64 && ssh_ciphertab[i].name != NULL; ++i) {
|
||||
cmp = strcmp(wanted, ssh_ciphertab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_ciphertab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"crypt_set_algorithms2: no crypto algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set output algorithm to %s", wanted);
|
||||
if (ssh_ciphertab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"crypt_set_algorithms2: no crypto algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set output algorithm to %s", wanted);
|
||||
|
||||
session->next_crypto->out_cipher = cipher_new(i);
|
||||
if (session->next_crypto->out_cipher == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
i = 0;
|
||||
session->next_crypto->out_cipher = cipher_new(i);
|
||||
if (session->next_crypto->out_cipher == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (session->next_crypto->out_cipher->aead_encrypt != NULL){
|
||||
/* this cipher has integrated MAC */
|
||||
wanted = "aead-poly1305";
|
||||
} else {
|
||||
/*
|
||||
* We must scan the kex entries to find hmac algorithms and set their
|
||||
* appropriate structure.
|
||||
*/
|
||||
if (session->next_crypto->out_cipher->aead_encrypt != NULL) {
|
||||
/* this cipher has integrated MAC */
|
||||
if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||
wanted = "aead-poly1305";
|
||||
} else {
|
||||
wanted = "aead-gcm";
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We must scan the kex entries to find hmac algorithms and set their
|
||||
* appropriate structure.
|
||||
*/
|
||||
|
||||
/* out */
|
||||
wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
|
||||
}
|
||||
/* out */
|
||||
wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
|
||||
}
|
||||
|
||||
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
||||
cmp = strcmp(wanted, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
||||
cmp = strcmp(wanted, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_hmactab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"crypt_set_algorithms2: no hmac algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
|
||||
if (ssh_hmactab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"crypt_set_algorithms2: no hmac algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
|
||||
|
||||
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
|
||||
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
|
||||
|
||||
/* in */
|
||||
wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
|
||||
/* in */
|
||||
wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
|
||||
|
||||
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
|
||||
cmp = strcmp(wanted, ssh_ciphertab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
|
||||
cmp = strcmp(wanted, ssh_ciphertab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_ciphertab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Crypt_set_algorithms: no crypto algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set input algorithm to %s", wanted);
|
||||
if (ssh_ciphertab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Crypt_set_algorithms: no crypto algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set input algorithm to %s", wanted);
|
||||
|
||||
session->next_crypto->in_cipher = cipher_new(i);
|
||||
if (session->next_crypto->in_cipher == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session->next_crypto->in_cipher = cipher_new(i);
|
||||
if (session->next_crypto->in_cipher == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
||||
/* this cipher has integrated MAC */
|
||||
wanted = "aead-poly1305";
|
||||
} else {
|
||||
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
||||
wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
|
||||
}
|
||||
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
||||
/* this cipher has integrated MAC */
|
||||
if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||
wanted = "aead-poly1305";
|
||||
} else {
|
||||
wanted = "aead-gcm";
|
||||
}
|
||||
} else {
|
||||
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
||||
wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
|
||||
}
|
||||
|
||||
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
||||
cmp = strcmp(wanted, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
||||
cmp = strcmp(wanted, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_hmactab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"crypt_set_algorithms2: no hmac algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", wanted);
|
||||
if (ssh_hmactab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"crypt_set_algorithms2: no hmac algorithm function found for %s",
|
||||
wanted);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", wanted);
|
||||
|
||||
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
|
||||
i = 0;
|
||||
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
|
||||
|
||||
/* compression */
|
||||
if (strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib") == 0) {
|
||||
session->next_crypto->do_compress_out = 1;
|
||||
}
|
||||
if (strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib") == 0) {
|
||||
session->next_crypto->do_compress_in = 1;
|
||||
}
|
||||
if (strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib@openssh.com") == 0) {
|
||||
session->next_crypto->delayed_compress_out = 1;
|
||||
}
|
||||
if (strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib@openssh.com") == 0) {
|
||||
session->next_crypto->delayed_compress_in = 1;
|
||||
}
|
||||
/* compression */
|
||||
cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib");
|
||||
if (cmp == 0) {
|
||||
session->next_crypto->do_compress_out = 1;
|
||||
}
|
||||
cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib");
|
||||
if (cmp == 0) {
|
||||
session->next_crypto->do_compress_in = 1;
|
||||
}
|
||||
cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib@openssh.com");
|
||||
if (cmp == 0) {
|
||||
session->next_crypto->delayed_compress_out = 1;
|
||||
}
|
||||
cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib@openssh.com");
|
||||
if (cmp == 0) {
|
||||
session->next_crypto->delayed_compress_in = 1;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int crypt_set_algorithms_client(ssh_session session)
|
||||
@@ -356,9 +376,11 @@ int crypt_set_algorithms_client(ssh_session session)
|
||||
#ifdef WITH_SERVER
|
||||
int crypt_set_algorithms_server(ssh_session session){
|
||||
const char *method = NULL;
|
||||
int i = 0;
|
||||
size_t i = 0;
|
||||
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
|
||||
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
|
||||
int cmp;
|
||||
|
||||
|
||||
if (session == NULL) {
|
||||
return SSH_ERROR;
|
||||
@@ -372,8 +394,6 @@ int crypt_set_algorithms_server(ssh_session session){
|
||||
method = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
|
||||
|
||||
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp(method, ssh_ciphertab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
@@ -392,10 +412,14 @@ int crypt_set_algorithms_server(ssh_session session){
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
i=0;
|
||||
|
||||
if (session->next_crypto->out_cipher->aead_encrypt != NULL){
|
||||
/* this cipher has integrated MAC */
|
||||
method = "aead-poly1305";
|
||||
if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||
method = "aead-poly1305";
|
||||
} else {
|
||||
method = "aead-gcm";
|
||||
}
|
||||
} else {
|
||||
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
||||
/* out */
|
||||
@@ -403,8 +427,11 @@ int crypt_set_algorithms_server(ssh_session session){
|
||||
}
|
||||
/* HMAC algorithm selection */
|
||||
|
||||
while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) {
|
||||
i++;
|
||||
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
||||
cmp = strcmp(method, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_hmactab[i].name == NULL) {
|
||||
@@ -418,16 +445,13 @@ int crypt_set_algorithms_server(ssh_session session){
|
||||
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
|
||||
|
||||
/* in */
|
||||
i=0;
|
||||
method = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
|
||||
|
||||
for (i = 0; ssh_ciphertab[i].name; i++) {
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp(method, ssh_ciphertab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
cmp = strcmp(method, ssh_ciphertab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_ciphertab[i].name == NULL) {
|
||||
@@ -442,23 +466,24 @@ int crypt_set_algorithms_server(ssh_session session){
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
i=0;
|
||||
|
||||
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
||||
/* this cipher has integrated MAC */
|
||||
method = "aead-poly1305";
|
||||
if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||
method = "aead-poly1305";
|
||||
} else {
|
||||
method = "aead-gcm";
|
||||
}
|
||||
} else {
|
||||
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
||||
method = session->next_crypto->kex_methods[SSH_MAC_C_S];
|
||||
}
|
||||
|
||||
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp(method, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
cmp = strcmp(method, ssh_hmactab[i].name);
|
||||
if (cmp == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_hmactab[i].name == NULL) {
|
||||
@@ -470,7 +495,6 @@ int crypt_set_algorithms_server(ssh_session session){
|
||||
SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", method);
|
||||
|
||||
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
|
||||
i=0;
|
||||
|
||||
/* compression */
|
||||
method = session->next_crypto->kex_methods[SSH_COMP_C_S];
|
||||
|
||||
@@ -9,8 +9,6 @@ set(TORTURE_LIBRARY torture)
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${CMOCKA_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${GCRYPT_INCLUDE_DIR}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
|
||||
@@ -4,6 +4,7 @@ find_package(socket_wrapper)
|
||||
|
||||
set(LIBSSH_CLIENT_TESTS
|
||||
torture_algorithms
|
||||
torture_client_config
|
||||
torture_connect
|
||||
torture_hostkey
|
||||
torture_auth
|
||||
@@ -14,6 +15,11 @@ set(LIBSSH_CLIENT_TESTS
|
||||
torture_session
|
||||
torture_request_env)
|
||||
|
||||
if (DEFAULT_C_NO_DEPRECATION_FLAGS)
|
||||
set_source_files_properties(torture_knownhosts.c
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS ${DEFAULT_C_NO_DEPRECATION_FLAGS})
|
||||
endif()
|
||||
if (WITH_SFTP)
|
||||
if (WITH_BENCHMARKS)
|
||||
set(SFTP_BENCHMARK_TESTS
|
||||
@@ -30,8 +36,11 @@ if (WITH_SFTP)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
foreach(_CLI_TEST ${LIBSSH_CLIENT_TESTS})
|
||||
add_cmocka_test(${_CLI_TEST} ${_CLI_TEST}.c ${TORTURE_LIBRARY})
|
||||
target_compile_options(${_CLI_TEST} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
add_cmocka_test(${_CLI_TEST}
|
||||
SOURCES ${_CLI_TEST}.c
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
||||
LINK_LIBRARIES ${TORTURE_LIBRARY}
|
||||
)
|
||||
|
||||
if (OSX)
|
||||
set_property(
|
||||
|
||||
@@ -90,9 +90,6 @@ static void test_algorithm(ssh_session session,
|
||||
};
|
||||
unsigned int i;
|
||||
|
||||
int verbosity = torture_libssh_verbosity();
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
|
||||
if (kex != NULL) {
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, kex);
|
||||
assert_ssh_return_code(session, rc);
|
||||
@@ -240,6 +237,20 @@ static void torture_algorithms_aes256_ctr_hmac_sha2_512(void **state) {
|
||||
test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-ctr", "hmac-sha2-512");
|
||||
}
|
||||
|
||||
static void torture_algorithms_aes128_gcm(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
|
||||
test_algorithm(s->ssh.session, NULL/*kex*/, "aes128-gcm@openssh.com", NULL);
|
||||
}
|
||||
|
||||
static void torture_algorithms_aes256_gcm(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
|
||||
test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-gcm@openssh.com", NULL);
|
||||
}
|
||||
|
||||
static void torture_algorithms_3des_cbc_hmac_sha1(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
|
||||
@@ -407,6 +418,24 @@ static void torture_algorithms_dh_group1(void **state) {
|
||||
test_algorithm(s->ssh.session, "diffie-hellman-group1-sha1", NULL/*cipher*/, NULL/*hmac*/);
|
||||
}
|
||||
|
||||
static void torture_algorithms_dh_group14(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
|
||||
test_algorithm(s->ssh.session, "diffie-hellman-group14-sha1", NULL/*cipher*/, NULL/*hmac*/);
|
||||
}
|
||||
|
||||
static void torture_algorithms_dh_group16(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
|
||||
test_algorithm(s->ssh.session, "diffie-hellman-group16-sha512", NULL/*cipher*/, NULL/*hmac*/);
|
||||
}
|
||||
|
||||
static void torture_algorithms_dh_group18(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
|
||||
test_algorithm(s->ssh.session, "diffie-hellman-group18-sha512", NULL/*cipher*/, NULL/*hmac*/);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
@@ -464,6 +493,12 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_aes256_ctr_hmac_sha2_512,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_aes128_gcm,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_aes256_gcm,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_3des_cbc_hmac_sha1,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
@@ -496,6 +531,15 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_dh_group1,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_dh_group14,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_dh_group16,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_dh_group18,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
#if ((OPENSSH_VERSION_MAJOR == 7 && OPENSSH_VERSION_MINOR >= 3) || OPENSSH_VERSION_MAJOR > 7)
|
||||
cmocka_unit_test_setup_teardown(torture_algorithms_ecdh_curve25519_sha256,
|
||||
session_setup,
|
||||
|
||||
@@ -52,12 +52,24 @@ static int session_setup(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
int verbosity = torture_libssh_verbosity();
|
||||
struct passwd *pwd;
|
||||
bool b = false;
|
||||
int rc;
|
||||
|
||||
pwd = getpwnam("bob");
|
||||
assert_non_null(pwd);
|
||||
|
||||
rc = setuid(pwd->pw_uid);
|
||||
assert_return_code(rc, errno);
|
||||
|
||||
s->ssh.session = ssh_new();
|
||||
assert_non_null(s->ssh.session);
|
||||
|
||||
ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
|
||||
/* Make sure no other configuration options from system will get used */
|
||||
rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_PROCESS_CONFIG, &b);
|
||||
assert_ssh_return_code(s->ssh.session, rc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -75,19 +87,12 @@ static int session_teardown(void **state)
|
||||
static int pubkey_setup(void **state)
|
||||
{
|
||||
int rc;
|
||||
struct passwd *pwd;
|
||||
|
||||
rc = session_setup(state);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pwd = getpwnam("bob");
|
||||
assert_non_null(pwd);
|
||||
|
||||
rc = setuid(pwd->pw_uid);
|
||||
assert_return_code(rc, errno);
|
||||
|
||||
/* Make sure we do not interfere with another ssh-agent */
|
||||
unsetenv("SSH_AUTH_SOCK");
|
||||
unsetenv("SSH_AGENT_PID");
|
||||
|
||||
200
tests/client/torture_client_config.c
Normal file
200
tests/client/torture_client_config.c
Normal file
@@ -0,0 +1,200 @@
|
||||
#include "config.h"
|
||||
|
||||
#define LIBSSH_STATIC
|
||||
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
#include "torture.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/misc.h"
|
||||
|
||||
#define LIBSSH_SSH_CONFIG "libssh_config"
|
||||
|
||||
#define TORTURE_CONFIG_USER "test-user"
|
||||
|
||||
#define CIPHERS "aes256-gcm@openssh.com,chacha20-poly1305@openssh.com"
|
||||
#define CIPHERS2 "aes256-cbc,aes128-ctr"
|
||||
|
||||
static int sshd_setup(void **state)
|
||||
{
|
||||
torture_setup_sshd_server(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sshd_teardown(void **state) {
|
||||
torture_teardown_sshd_server(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_config_files(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
int verbosity;
|
||||
struct passwd *pwd;
|
||||
char *filename = NULL;
|
||||
int rc;
|
||||
|
||||
/* Work under the bob's UID to be able to load his configuration file */
|
||||
pwd = getpwnam("bob");
|
||||
assert_non_null(pwd);
|
||||
|
||||
rc = setuid(pwd->pw_uid);
|
||||
assert_return_code(rc, errno);
|
||||
|
||||
s->ssh.session = ssh_new();
|
||||
assert_non_null(s->ssh.session);
|
||||
|
||||
filename = ssh_path_expand_tilde("~/.ssh/config");
|
||||
torture_write_file(filename, "Ciphers "CIPHERS"\nTestBogus1\nUser "TORTURE_CONFIG_USER);
|
||||
free(filename);
|
||||
|
||||
torture_write_file(LIBSSH_SSH_CONFIG, "Ciphers "CIPHERS2"\nTestBogus2\n");
|
||||
|
||||
verbosity = torture_libssh_verbosity();
|
||||
ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
char *filename;
|
||||
|
||||
filename = ssh_path_expand_tilde("~/.ssh/config");
|
||||
if (filename != NULL) {
|
||||
if (strlen(filename) > 0) {
|
||||
unlink(filename);
|
||||
}
|
||||
SAFE_FREE(filename);
|
||||
}
|
||||
|
||||
unlink(LIBSSH_SSH_CONFIG);
|
||||
|
||||
ssh_disconnect(s->ssh.session);
|
||||
ssh_free(s->ssh.session);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This tests makes sure that parsing both system-wide and per-user
|
||||
* configuration files retains OpenSSH semantics (the per-user overrides
|
||||
* the system-wide values).
|
||||
* This function ssh_options_parse_config() has hardcoded path to the
|
||||
* system-wide configuration file so this might not test anything at all
|
||||
* if this system-wide file does not overwrite this option.
|
||||
*/
|
||||
static void torture_client_config_system(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
int ret = 0;
|
||||
|
||||
/* The first tests assumes there is system-wide configuration file
|
||||
* setting Ciphers to some non-default value. We do not have any control
|
||||
* of that in this test case.
|
||||
*/
|
||||
ret = ssh_options_parse_config(s->ssh.session, NULL);
|
||||
assert_ssh_return_code(s->ssh.session, ret);
|
||||
|
||||
assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_C_S], CIPHERS);
|
||||
assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_S_C], CIPHERS);
|
||||
|
||||
/* Make sure the configuration was processed and user modified */
|
||||
assert_string_equal(s->ssh.session->opts.username, TORTURE_CONFIG_USER);
|
||||
}
|
||||
|
||||
/* This tests makes sure that parsing both system-wide and per-user
|
||||
* configuration files retains OpenSSH semantics (the per-user overrides
|
||||
* the system-wide values).
|
||||
* The function ssh_options_parse_config() has hardcoded path to the
|
||||
* system-wide configuraion file so we try to emmulate the behavior by parsing
|
||||
* the files separately in the same order.
|
||||
*/
|
||||
static void torture_client_config_emulate(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
char *filename = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* The first tests assumes there is system-wide configuration file
|
||||
* setting Ciphers to some non-default value. We do not have any control
|
||||
* of that in this test case
|
||||
*/
|
||||
filename = ssh_path_expand_tilde("~/.ssh/config");
|
||||
ret = ssh_options_parse_config(s->ssh.session, filename);
|
||||
free(filename);
|
||||
assert_ssh_return_code(s->ssh.session, ret);
|
||||
|
||||
ret = ssh_options_parse_config(s->ssh.session, LIBSSH_SSH_CONFIG);
|
||||
assert_ssh_return_code(s->ssh.session, ret);
|
||||
|
||||
assert_non_null(s->ssh.session->opts.wanted_methods[SSH_CRYPT_C_S]);
|
||||
assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_C_S], CIPHERS);
|
||||
assert_non_null(s->ssh.session->opts.wanted_methods[SSH_CRYPT_S_C]);
|
||||
assert_string_equal(s->ssh.session->opts.wanted_methods[SSH_CRYPT_S_C], CIPHERS);
|
||||
|
||||
/* Make sure the configuration was processed and user modified */
|
||||
assert_string_equal(s->ssh.session->opts.username, TORTURE_CONFIG_USER);
|
||||
}
|
||||
|
||||
/* This verifies that configuration files are parsed by default.
|
||||
*/
|
||||
static void torture_client_config_autoparse(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
int ret = 0;
|
||||
|
||||
ret = ssh_connect(s->ssh.session);
|
||||
assert_ssh_return_code(s->ssh.session, ret);
|
||||
|
||||
/* Make sure the configuration was processed and user modified */
|
||||
assert_string_equal(s->ssh.session->opts.username, TORTURE_CONFIG_USER);
|
||||
}
|
||||
|
||||
/* This verifies that we are able to suppress parsing of the configuration files
|
||||
* on connect using an option.
|
||||
*/
|
||||
static void torture_client_config_suppress(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
bool b = false;
|
||||
int ret = 0;
|
||||
|
||||
ret = ssh_options_set(s->ssh.session, SSH_OPTIONS_PROCESS_CONFIG, &b);
|
||||
assert_ssh_return_code(s->ssh.session, ret);
|
||||
|
||||
ret = ssh_connect(s->ssh.session);
|
||||
assert_ssh_return_code(s->ssh.session, ret);
|
||||
|
||||
/* Make sure the configuration was not processed and user modified */
|
||||
assert_string_equal(s->ssh.session->opts.username, "bob");
|
||||
}
|
||||
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(torture_client_config_system,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_client_config_emulate,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_client_config_autoparse,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_client_config_suppress,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
};
|
||||
|
||||
|
||||
ssh_init();
|
||||
torture_filter_tests(tests);
|
||||
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
|
||||
ssh_finalize();
|
||||
return rc;
|
||||
}
|
||||
@@ -68,6 +68,7 @@ static int session_setup(void **state)
|
||||
assert_non_null(s->ssh.session);
|
||||
|
||||
ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, BLACKHOLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ static void torture_ssh_forward(void **state)
|
||||
int dport;
|
||||
int bound_port;
|
||||
int rc;
|
||||
int verbosity = SSH_LOG_TRACE;
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
|
||||
rc = ssh_channel_listen_forward(session, "127.0.0.21", 8080, &bound_port);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
@@ -5,8 +5,6 @@ if (WITH_SERVER AND UNIX AND NOT WIN32)
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${CMOCKA_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${GCRYPT_INCLUDE_DIR}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
|
||||
@@ -46,12 +46,12 @@
|
||||
OPENSSH_PKACCEPTED_ECDSA \
|
||||
OPENSSH_PKACCEPTED_DSA
|
||||
|
||||
#define OPENSSH_CMD_START(hostkey_algos) \
|
||||
#define OPENSSH_CMD_START \
|
||||
OPENSSH_BINARY " " \
|
||||
"-o UserKnownHostsFile=/dev/null " \
|
||||
"-o StrictHostKeyChecking=no " \
|
||||
"-F /dev/null " \
|
||||
hostkey_algos " " \
|
||||
OPENSSH_HOSTKEY_ALGOS " " \
|
||||
OPENSSH_PKACCEPTED_TYPES " " \
|
||||
"-i " CLIENT_ID_FILE " " \
|
||||
"1> %s.out " \
|
||||
@@ -61,19 +61,16 @@
|
||||
#define OPENSSH_CMD_END "-p 1234 localhost ls"
|
||||
|
||||
#define OPENSSH_CMD \
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_KEX_CMD(kexalgo) \
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_CIPHER_CMD(ciphers) \
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-c " ciphers " " OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START "-c " ciphers " " OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_MAC_CMD(macs) \
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-o MACs=" macs " " OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_HOSTKEY_CMD(hostkeyalgo) \
|
||||
OPENSSH_CMD_START("-o HostKeyAlgorithms=" hostkeyalgo " ") OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START "-o MACs=" macs " " OPENSSH_CMD_END
|
||||
|
||||
|
||||
/* Dropbear */
|
||||
|
||||
@@ -383,6 +383,8 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||
#endif
|
||||
|
||||
#define CHACHA20 "chacha20-poly1305@openssh.com"
|
||||
#define AES128_GCM "aes128-gcm@openssh.com"
|
||||
#define AES256_GCM "aes256-gcm@openssh.com"
|
||||
|
||||
#ifdef HAVE_DSA
|
||||
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
|
||||
@@ -390,9 +392,13 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
|
||||
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
|
||||
f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
|
||||
f(client, rsa_aes128_gcm, ciphercmd(AES128_GCM), setup_rsa, teardown) \
|
||||
f(client, rsa_aes256_gcm, ciphercmd(AES256_GCM), setup_rsa, teardown) \
|
||||
f(client, dsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_dsa, teardown) \
|
||||
f(client, dsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_dsa, teardown) \
|
||||
f(client, dsa_chacha20, ciphercmd(CHACHA20), setup_dsa, teardown) \
|
||||
f(client, dsa_aes128_gcm, ciphercmd(AES128_GCM), setup_dsa, teardown) \
|
||||
f(client, dsa_aes256_gcm, ciphercmd(AES256_GCM), setup_dsa, teardown) \
|
||||
f(client, ed25519_3des_cbc, ciphercmd("3des-cbc"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes128_cbc, ciphercmd("aes128-cbc"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes128_ctr, ciphercmd("aes128-ctr"), setup_ed25519, teardown) \
|
||||
@@ -401,21 +407,31 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||
f(client, ed25519_aes192_cbc, ciphercmd("aes192-cbc"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes192_ctr, ciphercmd("aes192-ctr"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes128_gcm, ciphercmd(AES128_GCM), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes256_gcm, ciphercmd(AES256_GCM), setup_ed25519, teardown) \
|
||||
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
|
||||
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_521, teardown)
|
||||
#else
|
||||
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
|
||||
/* Ciphers. */ \
|
||||
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
|
||||
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
|
||||
f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
|
||||
f(client, rsa_aes128_gcm, ciphercmd(AES128_GCM), setup_rsa, teardown) \
|
||||
f(client, rsa_aes256_gcm, ciphercmd(AES256_GCM), setup_rsa, teardown) \
|
||||
f(client, ed25519_3des_cbc, ciphercmd("3des-cbc"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes128_cbc, ciphercmd("aes128-cbc"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes128_ctr, ciphercmd("aes128-ctr"), setup_ed25519, teardown) \
|
||||
@@ -424,17 +440,26 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||
f(client, ed25519_aes192_cbc, ciphercmd("aes192-cbc"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes192_ctr, ciphercmd("aes192-ctr"), setup_ed25519, teardown) \
|
||||
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes128_gcm, ciphercmd(AES128_GCM), setup_ed25519, teardown) \
|
||||
f(client, ed25519_aes256_gcm, ciphercmd(AES256_GCM), setup_ed25519, teardown) \
|
||||
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_256_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_256, teardown) \
|
||||
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_384_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_384, teardown) \
|
||||
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
|
||||
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_521, teardown) \
|
||||
f(client, ecdsa_521_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_521, teardown)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_DSA
|
||||
#define PKDTESTS_MAC(f, client, maccmd) \
|
||||
/* MACs. */ \
|
||||
@@ -478,12 +503,6 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||
f(client, ecdsa_521_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_ecdsa_521, teardown)
|
||||
#endif
|
||||
|
||||
#define PKDTESTS_HOSTKEY_OPENSSHONLY(f, client, hkcmd) \
|
||||
f(client, rsa_sha2_256, hkcmd("rsa-sha2-256"), setup_rsa, teardown) \
|
||||
f(client, rsa_sha2_512, hkcmd("rsa-sha2-512"), setup_rsa, teardown) \
|
||||
f(client, rsa_sha2_256_512, hkcmd("rsa-sha2-256,rsa-sha2-512"), setup_rsa, teardown) \
|
||||
f(client, rsa_sha2_512_256, hkcmd("rsa-sha2-512,rsa-sha2-256"), setup_rsa, teardown)
|
||||
|
||||
static void torture_pkd_client_noop(void **state) {
|
||||
struct pkd_state *pstate = (struct pkd_state *) (*state);
|
||||
(void) pstate;
|
||||
@@ -551,7 +570,6 @@ PKDTESTS_CIPHER(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD)
|
||||
PKDTESTS_CIPHER_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD)
|
||||
PKDTESTS_MAC(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_MAC_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_HOSTKEY_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_HOSTKEY_CMD)
|
||||
#undef CLIENT_ID_FILE
|
||||
|
||||
#define CLIENT_ID_FILE OPENSSH_ECDSA256_TESTKEY
|
||||
@@ -628,7 +646,6 @@ struct {
|
||||
PKDTESTS_CIPHER_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_CIPHER_CMD)
|
||||
PKDTESTS_MAC(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_MAC_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_HOSTKEY_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_HOSTKEY_CMD)
|
||||
|
||||
PKDTESTS_DEFAULT(emit_testmap, openssh_e256, OPENSSH_CMD)
|
||||
PKDTESTS_DEFAULT_OPENSSHONLY(emit_testmap, openssh_e256, OPENSSH_CMD)
|
||||
|
||||
422
tests/torture.c
422
tests/torture.c
@@ -38,15 +38,20 @@
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#elif (defined _WIN32) || (defined _WIN64)
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#define read _read
|
||||
#define open _open
|
||||
#define write _write
|
||||
#define close _close
|
||||
#define chdir _chdir
|
||||
#endif
|
||||
|
||||
#include "torture.h"
|
||||
#include "torture_key.h"
|
||||
#include "libssh/misc.h"
|
||||
|
||||
/* for pattern matching */
|
||||
#include "match.c"
|
||||
|
||||
#define TORTURE_SSHD_SRV_IPV4 "127.0.0.10"
|
||||
/* socket wrapper IPv6 prefix fd00::5357:5fxx */
|
||||
#define TORTURE_SSHD_SRV_IPV6 "fd00::5357:5f0a"
|
||||
@@ -425,7 +430,7 @@ failed:
|
||||
}
|
||||
ssh_disconnect(t->ssh);
|
||||
ssh_free(t->ssh);
|
||||
free(t);
|
||||
free(t);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -497,11 +502,10 @@ void torture_setup_socket_dir(void **state)
|
||||
s = malloc(sizeof(struct torture_state));
|
||||
assert_non_null(s);
|
||||
|
||||
s->socket_dir = strdup(TORTURE_SOCKET_DIR);
|
||||
s->socket_dir = torture_make_temp_dir(TORTURE_SOCKET_DIR);
|
||||
assert_non_null(s->socket_dir);
|
||||
|
||||
p = mkdtemp(s->socket_dir);
|
||||
assert_non_null(p);
|
||||
p = s->socket_dir;
|
||||
|
||||
/* pcap file */
|
||||
len = strlen(p) + 1 + strlen(TORTURE_PCAP_FILE) + 1;
|
||||
@@ -785,37 +789,361 @@ void torture_teardown_sshd_server(void **state)
|
||||
torture_teardown_socket_dir(state);
|
||||
}
|
||||
|
||||
char *torture_make_temp_dir(const char *template)
|
||||
{
|
||||
char *new_dir = NULL;
|
||||
char *template_copy = NULL;
|
||||
|
||||
if (template == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
template_copy = strdup(template);
|
||||
if (template_copy == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
new_dir = mkdtemp(template_copy);
|
||||
if (new_dir == NULL) {
|
||||
SAFE_FREE(template_copy);
|
||||
}
|
||||
|
||||
end:
|
||||
return template_copy;
|
||||
}
|
||||
|
||||
char *torture_create_temp_file(const char *template)
|
||||
{
|
||||
char *new_file = NULL;
|
||||
FILE *fp = NULL;
|
||||
mode_t mask;
|
||||
int fd;
|
||||
|
||||
new_file = strdup(template);
|
||||
if (new_file == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
mask = umask(S_IRWXO | S_IRWXG);
|
||||
fd = mkstemp(new_file);
|
||||
umask(mask);
|
||||
if (fd == -1) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
fp = fdopen(fd, "w");
|
||||
if (fp == NULL) {
|
||||
SAFE_FREE(new_file);
|
||||
close(fd);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
end:
|
||||
return new_file;
|
||||
}
|
||||
|
||||
char *torture_get_current_working_dir(void)
|
||||
{
|
||||
|
||||
char *cwd = NULL;
|
||||
char *result = NULL;
|
||||
|
||||
cwd = (char *)malloc(PATH_MAX + 1);
|
||||
if (cwd == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = getcwd(cwd, PATH_MAX);
|
||||
|
||||
if (result == NULL) {
|
||||
SAFE_FREE(cwd);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
return cwd;
|
||||
}
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
char *torture_make_temp_dir(const char *template)
|
||||
{
|
||||
DWORD rc = 0;
|
||||
char tmp_dir_path[MAX_PATH];
|
||||
char tmp_file_name[MAX_PATH];
|
||||
char *prefix = NULL;
|
||||
char *path = NULL;
|
||||
char *prefix_end = NULL;
|
||||
char *slash = NULL;
|
||||
|
||||
BOOL created;
|
||||
|
||||
if (template == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
prefix = strdup(template);
|
||||
if (prefix == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Replace slashes with backslashes */
|
||||
slash = strchr(prefix, '/');
|
||||
for (; slash != NULL; slash = strchr(prefix, '/')) {
|
||||
*slash = '\\';
|
||||
}
|
||||
|
||||
prefix_end = strstr(prefix, "XXXXXX");
|
||||
if (prefix_end != NULL) {
|
||||
*prefix_end = '\0';
|
||||
}
|
||||
|
||||
rc = GetTempPathA(MAX_PATH, tmp_dir_path);
|
||||
if ((rc > MAX_PATH) || (rc == 0)) {
|
||||
goto free_prefix;
|
||||
}
|
||||
|
||||
rc = GetTempFileNameA(tmp_dir_path, TEXT(prefix), 0, tmp_file_name);
|
||||
if (rc == 0) {
|
||||
goto free_prefix;
|
||||
}
|
||||
|
||||
path = strdup(tmp_file_name);
|
||||
if (path == NULL) {
|
||||
goto free_prefix;
|
||||
}
|
||||
|
||||
/* GetTempFileNameA() creates a temporary file; we need to remove it */
|
||||
rc = DeleteFileA(path);
|
||||
if (rc == 0) {
|
||||
rc = -1;
|
||||
SAFE_FREE(path);
|
||||
goto free_prefix;
|
||||
}
|
||||
|
||||
created = CreateDirectoryA(path, NULL);
|
||||
if (!created) {
|
||||
SAFE_FREE(path);
|
||||
}
|
||||
|
||||
free_prefix:
|
||||
SAFE_FREE(prefix);
|
||||
end:
|
||||
return path;
|
||||
}
|
||||
|
||||
static int recursive_rm_dir_content(const char *path)
|
||||
{
|
||||
WIN32_FIND_DATA file_data;
|
||||
HANDLE file_handle;
|
||||
DWORD attributes;
|
||||
|
||||
DWORD last_error = 0;
|
||||
|
||||
char file_path[MAX_PATH];
|
||||
|
||||
int rc = 0;
|
||||
BOOL removed;
|
||||
|
||||
strcpy(file_path, path);
|
||||
strcat(file_path, "\\*");
|
||||
|
||||
file_handle = FindFirstFile(file_path, &file_data);
|
||||
|
||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||
last_error = GetLastError();
|
||||
|
||||
/* Empty directory */
|
||||
if (last_error == ERROR_FILE_NOT_FOUND) {
|
||||
rc = 0;
|
||||
}
|
||||
else {
|
||||
/*TODO print error message?*/
|
||||
rc = last_error;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
else {
|
||||
do {
|
||||
rc = strcmp(file_data.cFileName, ".");
|
||||
if (rc == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = strcmp(file_data.cFileName, "..");
|
||||
if (rc == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create full file path */
|
||||
strcpy(file_path, path);
|
||||
strcat(file_path, "\\");
|
||||
strcat(file_path, file_data.cFileName);
|
||||
|
||||
attributes = GetFileAttributes(file_path);
|
||||
if (attributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
rc = recursive_rm_dir_content((const char *)file_path);
|
||||
if (rc != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
removed = RemoveDirectoryA(file_path);
|
||||
|
||||
if (!removed) {
|
||||
last_error = GetLastError();
|
||||
|
||||
/*TODO print error message?*/
|
||||
|
||||
rc = last_error;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rc = remove(file_path);
|
||||
if (rc) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
} while(FindNextFile(file_handle, &file_data));
|
||||
|
||||
FindClose(file_handle);
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int torture_rmdirs(const char *path)
|
||||
{
|
||||
int rc = 0;
|
||||
BOOL removed;
|
||||
|
||||
rc = recursive_rm_dir_content(path);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
removed = RemoveDirectoryA(path);
|
||||
if (!removed) {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int torture_isdir(const char *path)
|
||||
{
|
||||
|
||||
DWORD attributes = 0;
|
||||
|
||||
attributes = GetFileAttributes(path);
|
||||
if (attributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *torture_create_temp_file(const char *template)
|
||||
{
|
||||
DWORD rc = 0;
|
||||
char tmp_dir_path[MAX_PATH];
|
||||
char tmp_file_name[MAX_PATH];
|
||||
char *prefix = NULL;
|
||||
char *path = NULL;
|
||||
char *prefix_end = NULL;
|
||||
char *slash = NULL;
|
||||
|
||||
if (template == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
prefix = strdup(template);
|
||||
if (prefix == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Replace slashes with backslashes */
|
||||
slash = strchr(prefix, '/');
|
||||
for (; slash != NULL; slash = strchr(prefix, '/')) {
|
||||
*slash = '\\';
|
||||
}
|
||||
|
||||
prefix_end = strstr(prefix, "XXXXXX");
|
||||
if (prefix_end != NULL) {
|
||||
*prefix_end = '\0';
|
||||
}
|
||||
|
||||
rc = GetTempPathA(MAX_PATH, tmp_dir_path);
|
||||
if ((rc > MAX_PATH) || (rc == 0)) {
|
||||
goto free_prefix;
|
||||
}
|
||||
|
||||
/* Remark: this function creates the file */
|
||||
rc = GetTempFileNameA(tmp_dir_path, TEXT(prefix), 0, tmp_file_name);
|
||||
if (rc == 0) {
|
||||
goto free_prefix;
|
||||
}
|
||||
|
||||
path = strdup(tmp_file_name);
|
||||
|
||||
free_prefix:
|
||||
SAFE_FREE(prefix);
|
||||
end:
|
||||
return path;
|
||||
}
|
||||
|
||||
char *torture_get_current_working_dir(void)
|
||||
{
|
||||
char *cwd = NULL;
|
||||
char *result = NULL;
|
||||
|
||||
cwd = (char *)malloc(_MAX_PATH + 1);
|
||||
if (cwd == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = _getcwd(cwd, _MAX_PATH);
|
||||
|
||||
if (result == NULL) {
|
||||
SAFE_FREE(cwd);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
return cwd;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
int torture_change_dir(char *path)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (path == NULL) {
|
||||
rc = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = chdir(path);
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int torture_libssh_verbosity(void){
|
||||
return verbosity;
|
||||
}
|
||||
|
||||
void _torture_filter_tests(struct CMUnitTest *tests, size_t ntests)
|
||||
{
|
||||
size_t i,j;
|
||||
const char *name;
|
||||
if (pattern == NULL){
|
||||
return;
|
||||
}
|
||||
for (i=0; i < ntests; ++i){
|
||||
name = tests[i].name;
|
||||
/*printf("match(%s,%s)\n",name,pattern);*/
|
||||
if (!match_pattern(name, pattern)){
|
||||
for (j = i; j < ntests-1;++j){
|
||||
tests[j]=tests[j+1];
|
||||
}
|
||||
tests[ntests-1].name = NULL;
|
||||
tests[ntests-1].test_func = NULL;
|
||||
ntests--;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
if (ntests != 0){
|
||||
printf("%d tests left\n",(int)ntests);
|
||||
} else {
|
||||
printf("No matching test left\n");
|
||||
}
|
||||
(void) tests;
|
||||
(void) ntests;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void torture_write_file(const char *filename, const char *data){
|
||||
@@ -835,22 +1163,30 @@ void torture_write_file(const char *filename, const char *data){
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void torture_reset_config(ssh_session session)
|
||||
{
|
||||
memset(session->opts.options_seen, 0, sizeof(session->opts.options_seen));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct argument_s arguments;
|
||||
char *env = getenv("LIBSSH_VERBOSITY");
|
||||
struct argument_s arguments;
|
||||
char *env = getenv("LIBSSH_VERBOSITY");
|
||||
|
||||
arguments.verbose=0;
|
||||
arguments.pattern=NULL;
|
||||
torture_cmdline_parse(argc, argv, &arguments);
|
||||
verbosity=arguments.verbose;
|
||||
pattern=arguments.pattern;
|
||||
arguments.verbose=0;
|
||||
arguments.pattern=NULL;
|
||||
torture_cmdline_parse(argc, argv, &arguments);
|
||||
verbosity=arguments.verbose;
|
||||
pattern=arguments.pattern;
|
||||
|
||||
if (verbosity == 0 && env != NULL && env[0] != '\0') {
|
||||
if (env[0] > '0' && env[0] < '9') {
|
||||
verbosity = atoi(env);
|
||||
}
|
||||
}
|
||||
if (verbosity == 0 && env != NULL && env[0] != '\0') {
|
||||
if (env[0] > '0' && env[0] < '9') {
|
||||
verbosity = atoi(env);
|
||||
}
|
||||
}
|
||||
|
||||
return torture_run_tests();
|
||||
#if defined HAVE_CMOCKA_SET_TEST_FILTER
|
||||
cmocka_set_test_filter(pattern);
|
||||
#endif
|
||||
|
||||
return torture_run_tests();
|
||||
}
|
||||
|
||||
@@ -120,9 +120,17 @@ void torture_setup_sshd_server(void **state);
|
||||
void torture_teardown_socket_dir(void **state);
|
||||
void torture_teardown_sshd_server(void **state);
|
||||
|
||||
void torture_reset_config(ssh_session session);
|
||||
|
||||
/*
|
||||
* This function must be defined in every unit test file.
|
||||
*/
|
||||
int torture_run_tests(void);
|
||||
|
||||
char *torture_make_temp_dir(const char *template);
|
||||
char *torture_create_temp_file(const char *template);
|
||||
|
||||
char *torture_get_current_working_dir(void);
|
||||
int torture_change_dir(char *path);
|
||||
|
||||
#endif /* _TORTURE_H */
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#elif (defined _WIN32) || (defined _WIN64)
|
||||
#include <io.h>
|
||||
#define read _read
|
||||
#define open _open
|
||||
#define write _write
|
||||
#define close _close
|
||||
#endif
|
||||
|
||||
#include "torture_pki.h"
|
||||
|
||||
|
||||
@@ -2,98 +2,86 @@ project(unittests C)
|
||||
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
add_cmocka_test(torture_buffer torture_buffer.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_buffer PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
set(LIBSSH_UNIT_TESTS
|
||||
torture_buffer
|
||||
torture_bytearray
|
||||
torture_callbacks
|
||||
torture_crypto
|
||||
torture_init
|
||||
torture_list
|
||||
torture_misc
|
||||
torture_config
|
||||
torture_options
|
||||
torture_isipaddr
|
||||
torture_knownhosts_parsing
|
||||
torture_hashes
|
||||
torture_packet_filter
|
||||
torture_temp_dir
|
||||
torture_temp_file
|
||||
torture_push_pop_dir
|
||||
)
|
||||
|
||||
add_cmocka_test(torture_callbacks torture_callbacks.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_callbacks PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_crypto torture_crypto.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_crypto PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_init torture_init.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_init PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_list torture_list.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_list PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_misc torture_misc.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_misc PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_config torture_config.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_config PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_options torture_options.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_options PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_isipaddr torture_isipaddr.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_isipaddr PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_knownhosts_parsing torture_knownhosts_parsing.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_knownhosts_parsing PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_hashes torture_hashes.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_hashes PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_packet_filter torture_packet_filter.c ${TORTURE_LIBRARY})
|
||||
target_compile_options(torture_packet_filter PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
add_cmocka_test(torture_rand torture_rand.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_rand PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(torture_rand Threads::Threads)
|
||||
|
||||
add_cmocka_test(torture_threads_init torture_threads_init.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_threads_init PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(torture_threads_init Threads::Threads)
|
||||
|
||||
add_cmocka_test(torture_threads_buffer torture_threads_buffer.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_threads_buffer PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(torture_threads_buffer Threads::Threads)
|
||||
|
||||
add_cmocka_test(torture_threads_crypto torture_threads_crypto.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_threads_crypto PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(torture_threads_crypto Threads::Threads)
|
||||
endif ()
|
||||
set(LIBSSH_THREAD_UNIT_TESTS
|
||||
torture_rand
|
||||
torture_threads_init
|
||||
torture_threads_buffer
|
||||
torture_threads_crypto
|
||||
)
|
||||
|
||||
if (UNIX AND NOT WIN32)
|
||||
# this uses a socketpair
|
||||
add_cmocka_test(torture_packet torture_packet.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_packet PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
# requires ssh-keygen
|
||||
add_cmocka_test(torture_keyfiles torture_keyfiles.c ${TEST_TARGET_LIBRARIES})
|
||||
|
||||
add_cmocka_test(torture_pki torture_pki.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_pki PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_pki_rsa torture_pki_rsa.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_pki_rsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
|
||||
add_cmocka_test(torture_pki_ed25519 torture_pki_ed25519.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_pki_ed25519 PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
set(LIBSSH_UNIT_TESTS
|
||||
${LIBSSH_UNIT_TESTS}
|
||||
# this uses a socketpair
|
||||
torture_packet
|
||||
# requires ssh-keygen
|
||||
torture_keyfiles
|
||||
torture_pki
|
||||
torture_pki_rsa
|
||||
torture_pki_ed25519
|
||||
# requires /dev/null
|
||||
torture_channel
|
||||
)
|
||||
|
||||
if (HAVE_DSA)
|
||||
add_cmocka_test(torture_pki_dsa torture_pki_dsa.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_pki_dsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
set(LIBSSH_UNIT_TESTS
|
||||
${LIBSSH_UNIT_TESTS}
|
||||
torture_pki_dsa
|
||||
)
|
||||
endif()
|
||||
|
||||
if (HAVE_ECC)
|
||||
add_cmocka_test(torture_pki_ecdsa torture_pki_ecdsa.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_pki_ecdsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
set(LIBSSH_UNIT_TESTS
|
||||
${LIBSSH_UNIT_TESTS}
|
||||
torture_pki_ecdsa
|
||||
)
|
||||
endif()
|
||||
|
||||
# requires /dev/null
|
||||
add_cmocka_test(torture_channel torture_channel.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_channel PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
# requires pthread
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
add_cmocka_test(torture_threads_pki_rsa torture_threads_pki_rsa.c ${TEST_TARGET_LIBRARIES})
|
||||
target_compile_options(torture_threads_pki_rsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||
target_link_libraries(torture_threads_pki_rsa Threads::Threads)
|
||||
|
||||
# Not working correctly
|
||||
#if (WITH_SERVER)
|
||||
# add_cmocka_test(torture_server_x11 torture_server_x11.c ${TEST_TARGET_LIBRARIES})
|
||||
#endif (WITH_SERVER)
|
||||
endif ()
|
||||
set(LIBSSH_THREAD_UNIT_TESTS
|
||||
${LIBSSH_THREAD_UNIT_TESTS}
|
||||
# requires pthread
|
||||
torture_threads_pki_rsa
|
||||
)
|
||||
# Not working correctly
|
||||
#if (WITH_SERVER)
|
||||
# add_cmocka_test(torture_server_x11 torture_server_x11.c ${TEST_TARGET_LIBRARIES})
|
||||
#endif (WITH_SERVER)
|
||||
endif (UNIX AND NOT WIN32)
|
||||
|
||||
foreach(_UNIT_TEST ${LIBSSH_UNIT_TESTS})
|
||||
add_cmocka_test(${_UNIT_TEST}
|
||||
SOURCES ${_UNIT_TEST}.c
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
||||
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
foreach(_UNIT_TEST ${LIBSSH_THREAD_UNIT_TESTS})
|
||||
add_cmocka_test(${_UNIT_TEST}
|
||||
SOURCES ${_UNIT_TEST}.c
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
||||
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES} Threads::Threads
|
||||
)
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
|
||||
410
tests/unittests/torture_bytearray.c
Normal file
410
tests/unittests/torture_bytearray.c
Normal file
@@ -0,0 +1,410 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "torture.h"
|
||||
#include "libssh/bytearray.h"
|
||||
|
||||
static void torture_pull_le_u8(void **state)
|
||||
{
|
||||
uint8_t data[2] = {0};
|
||||
uint8_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
result = PULL_LE_U8(data, 0);
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
data[0] = 0x2a;
|
||||
result = PULL_LE_U8(data, 0);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
|
||||
data[0] = 0xf;
|
||||
result = PULL_LE_U8(data, 0);
|
||||
assert_int_equal(result, 0xf);
|
||||
|
||||
data[0] = 0xff;
|
||||
result = PULL_LE_U8(data, 0);
|
||||
assert_int_equal(result, 0xff);
|
||||
|
||||
data[1] = 0x2a;
|
||||
result = PULL_LE_U8(data, 1);
|
||||
assert_int_equal(result, 42);
|
||||
}
|
||||
|
||||
static void torture_pull_le_u16(void **state)
|
||||
{
|
||||
uint8_t data[2] = {0, 0};
|
||||
uint16_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
result = PULL_LE_U16(data, 0);
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
data[0] = 0x2a;
|
||||
data[1] = 0x00;
|
||||
result = PULL_LE_U16(data, 0);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0x00;
|
||||
result = PULL_LE_U16(data, 0);
|
||||
assert_int_equal(result, 0x00ff);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0xff;
|
||||
result = PULL_LE_U16(data, 0);
|
||||
assert_int_equal(result, 0xff00);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0xff;
|
||||
result = PULL_LE_U16(data, 0);
|
||||
assert_int_equal(result, 0xffff);
|
||||
}
|
||||
|
||||
static void torture_pull_le_u32(void **state)
|
||||
{
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
uint32_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
data[0] = 0x2a;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x00;
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x00;
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0x00ff);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0xff;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x00;
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0xff00);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0xff;
|
||||
data[3] = 0x00;
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0xff0000);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0xff;
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0xff000000);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0xff;
|
||||
data[2] = 0xff;
|
||||
data[3] = 0xff;
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0xffffffff);
|
||||
}
|
||||
|
||||
static void torture_push_le_u8(void **state)
|
||||
{
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
uint8_t data2[4] = {42, 42, 42, 42};
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_LE_U8(data, 0, 42);
|
||||
PUSH_LE_U8(data, 1, 42);
|
||||
PUSH_LE_U8(data, 2, 42);
|
||||
PUSH_LE_U8(data, 3, 42);
|
||||
assert_memory_equal(data, data2, sizeof(data));
|
||||
}
|
||||
|
||||
static void torture_push_le_u16(void **state)
|
||||
{
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
uint8_t data2[4] = {0xa6, 0x7f, 0x2a, 0x00};
|
||||
uint16_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_LE_U16(data, 0, 32678);
|
||||
PUSH_LE_U16(data, 2, 42);
|
||||
assert_memory_equal(data, data2, sizeof(data));
|
||||
|
||||
result = PULL_LE_U16(data, 2);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
result = PULL_LE_U16(data, 0);
|
||||
assert_int_equal(result, 32678);
|
||||
}
|
||||
|
||||
static void torture_push_le_u32(void **state)
|
||||
{
|
||||
uint8_t data[8] = {0};
|
||||
uint8_t data2[8] = {0xa6, 0x7f, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00};
|
||||
uint32_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_LE_U32(data, 0, 32678);
|
||||
PUSH_LE_U32(data, 4, 42);
|
||||
assert_memory_equal(data, data2, sizeof(data));
|
||||
|
||||
result = PULL_LE_U32(data, 4);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 32678);
|
||||
|
||||
PUSH_LE_U32(data, 0, 0xfffefffe);
|
||||
result = PULL_LE_U32(data, 0);
|
||||
assert_int_equal(result, 0xfffefffe);
|
||||
}
|
||||
|
||||
static void torture_push_le_u64(void **state)
|
||||
{
|
||||
uint8_t data[16] = {0};
|
||||
uint64_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_LE_U64(data, 0, 32678);
|
||||
|
||||
result = PULL_LE_U64(data, 0);
|
||||
assert_int_equal(result, 32678);
|
||||
|
||||
PUSH_LE_U64(data, 0, 0xfffefffefffefffeUL);
|
||||
|
||||
result = PULL_LE_U64(data, 0);
|
||||
assert_int_equal(result, 0xfffefffefffefffeUL);
|
||||
}
|
||||
|
||||
/****************** BIG ENDIAN ********************/
|
||||
|
||||
static void torture_pull_be_u8(void **state)
|
||||
{
|
||||
uint8_t data[2] = {0};
|
||||
uint8_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
result = PULL_BE_U8(data, 0);
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
data[0] = 0x2a;
|
||||
result = PULL_BE_U8(data, 0);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
|
||||
data[0] = 0xf;
|
||||
result = PULL_BE_U8(data, 0);
|
||||
assert_int_equal(result, 0xf);
|
||||
|
||||
data[0] = 0xff;
|
||||
result = PULL_BE_U8(data, 0);
|
||||
assert_int_equal(result, 0xff);
|
||||
|
||||
data[1] = 0x2a;
|
||||
result = PULL_BE_U8(data, 1);
|
||||
assert_int_equal(result, 42);
|
||||
}
|
||||
|
||||
static void torture_pull_be_u16(void **state)
|
||||
{
|
||||
uint8_t data[2] = {0, 0};
|
||||
uint16_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
result = PULL_BE_U16(data, 0);
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x2a;
|
||||
result = PULL_BE_U16(data, 0);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0xff;
|
||||
result = PULL_BE_U16(data, 0);
|
||||
assert_int_equal(result, 0x00ff);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0x00;
|
||||
result = PULL_BE_U16(data, 0);
|
||||
assert_int_equal(result, 0xff00);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0xff;
|
||||
result = PULL_BE_U16(data, 0);
|
||||
assert_int_equal(result, 0xffff);
|
||||
}
|
||||
|
||||
static void torture_pull_be_u32(void **state)
|
||||
{
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
uint32_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x2a;
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0xff;
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0x00ff);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0xff;
|
||||
data[3] = 0x00;
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0xff00);
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0xff;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x00;
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0xff0000);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x00;
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0xff000000);
|
||||
|
||||
data[0] = 0xff;
|
||||
data[1] = 0xff;
|
||||
data[2] = 0xff;
|
||||
data[3] = 0xff;
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0xffffffff);
|
||||
}
|
||||
|
||||
static void torture_push_be_u8(void **state)
|
||||
{
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
uint8_t data2[4] = {42, 42, 42, 42};
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_BE_U8(data, 0, 42);
|
||||
PUSH_BE_U8(data, 1, 42);
|
||||
PUSH_BE_U8(data, 2, 42);
|
||||
PUSH_BE_U8(data, 3, 42);
|
||||
assert_memory_equal(data, data2, sizeof(data));
|
||||
}
|
||||
|
||||
static void torture_push_be_u16(void **state)
|
||||
{
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
uint8_t data2[4] = {0x7f, 0xa6, 0x00, 0x2a};
|
||||
uint16_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_BE_U16(data, 0, 32678);
|
||||
PUSH_BE_U16(data, 2, 42);
|
||||
assert_memory_equal(data, data2, sizeof(data));
|
||||
|
||||
result = PULL_BE_U16(data, 2);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
result = PULL_BE_U16(data, 0);
|
||||
assert_int_equal(result, 32678);
|
||||
}
|
||||
|
||||
static void torture_push_be_u32(void **state)
|
||||
{
|
||||
uint8_t data[8] = {0};
|
||||
uint8_t data2[8] = {0x00, 0x00, 0x7f, 0xa6, 0x00, 0x00, 0x00, 0x2a};
|
||||
uint32_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_BE_U32(data, 0, 32678);
|
||||
PUSH_BE_U32(data, 4, 42);
|
||||
assert_memory_equal(data, data2, sizeof(data));
|
||||
|
||||
result = PULL_BE_U32(data, 4);
|
||||
assert_int_equal(result, 42);
|
||||
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 32678);
|
||||
|
||||
PUSH_BE_U32(data, 0, 0xfffefffe);
|
||||
result = PULL_BE_U32(data, 0);
|
||||
assert_int_equal(result, 0xfffefffe);
|
||||
}
|
||||
|
||||
static void torture_push_be_u64(void **state)
|
||||
{
|
||||
uint8_t data[16] = {0};
|
||||
uint64_t result;
|
||||
|
||||
(void)state;
|
||||
|
||||
PUSH_BE_U64(data, 0, 32678);
|
||||
|
||||
result = PULL_BE_U64(data, 0);
|
||||
assert_int_equal(result, 32678);
|
||||
|
||||
PUSH_LE_U64(data, 8, 0xfffefffe);
|
||||
|
||||
result = PULL_LE_U64(data, 8);
|
||||
assert_int_equal(result, 0xfffefffe);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(torture_pull_le_u8),
|
||||
cmocka_unit_test(torture_pull_le_u16),
|
||||
cmocka_unit_test(torture_pull_le_u32),
|
||||
|
||||
cmocka_unit_test(torture_push_le_u8),
|
||||
cmocka_unit_test(torture_push_le_u16),
|
||||
cmocka_unit_test(torture_push_le_u32),
|
||||
cmocka_unit_test(torture_push_le_u64),
|
||||
|
||||
/* BIG ENDIAN */
|
||||
cmocka_unit_test(torture_pull_be_u8),
|
||||
cmocka_unit_test(torture_pull_be_u16),
|
||||
cmocka_unit_test(torture_pull_be_u32),
|
||||
|
||||
cmocka_unit_test(torture_push_be_u8),
|
||||
cmocka_unit_test(torture_push_be_u16),
|
||||
cmocka_unit_test(torture_push_be_u32),
|
||||
cmocka_unit_test(torture_push_be_u64),
|
||||
};
|
||||
|
||||
torture_filter_tests(tests);
|
||||
|
||||
rc = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -75,6 +75,11 @@ static int setup_config_files(void **state)
|
||||
"\tConnectTimeout 30\n"
|
||||
"\tLogLevel DEBUG3\n"
|
||||
"\tGlobalKnownHostsFile "GLOBAL_KNOWN_HOSTS"\n"
|
||||
"\tCompression yes\n"
|
||||
"\tStrictHostkeyChecking no\n"
|
||||
"\tGSSAPIDelegateCredentials yes\n"
|
||||
"\tGSSAPIServerIdentity example.com\n"
|
||||
"\tGSSAPIClientIdentity home.sweet\n"
|
||||
"\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n");
|
||||
|
||||
/* authentication methods */
|
||||
@@ -151,7 +156,6 @@ static int teardown(void **state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief tests ssh_config_parse_file with Include directives
|
||||
*/
|
||||
@@ -249,6 +253,14 @@ static void torture_config_new(void **state)
|
||||
assert_string_equal(session->opts.global_knownhosts, GLOBAL_KNOWN_HOSTS);
|
||||
assert_int_equal(session->opts.timeout, 30);
|
||||
assert_string_equal(session->opts.bindaddr, BIND_ADDRESS);
|
||||
assert_string_equal(session->opts.wanted_methods[SSH_COMP_C_S],
|
||||
"zlib@openssh.com,zlib");
|
||||
assert_string_equal(session->opts.wanted_methods[SSH_COMP_S_C],
|
||||
"zlib@openssh.com,zlib");
|
||||
assert_int_equal(session->opts.StrictHostKeyChecking, 0);
|
||||
assert_int_equal(session->opts.gss_delegate_creds, 1);
|
||||
assert_string_equal(session->opts.gss_server_identity, "example.com");
|
||||
assert_string_equal(session->opts.gss_client_identity, "home.sweet");
|
||||
|
||||
assert_int_equal(ssh_get_log_level(), SSH_LOG_TRACE);
|
||||
assert_int_equal(session->common.log_verbosity, SSH_LOG_TRACE);
|
||||
@@ -287,6 +299,7 @@ static void torture_config_auth_methods(void **state) {
|
||||
assert_int_equal(session->opts.flags, 0);
|
||||
|
||||
/* gradually enable them again */
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "gss");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
|
||||
assert_true(ret == 0);
|
||||
@@ -341,29 +354,34 @@ static void torture_config_match(void **state)
|
||||
assert_string_equal(session->opts.host, "all-matched.com");
|
||||
|
||||
/* Hostname example does simple hostname matching */
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "example");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
|
||||
assert_true(ret == 0);
|
||||
assert_string_equal(session->opts.host, "example.com");
|
||||
|
||||
/* We can match also both hosts from a comma separated list */
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "example1");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
|
||||
assert_true(ret == 0);
|
||||
assert_string_equal(session->opts.host, "exampleN");
|
||||
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "example2");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
|
||||
assert_true(ret == 0);
|
||||
assert_string_equal(session->opts.host, "exampleN");
|
||||
|
||||
/* We can match by user */
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_USER, "guest");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
|
||||
assert_true(ret == 0);
|
||||
assert_string_equal(session->opts.host, "guest.com");
|
||||
|
||||
/* We can combine two options on a single line to match both of them */
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_USER, "tester");
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
|
||||
@@ -371,6 +389,7 @@ static void torture_config_match(void **state)
|
||||
assert_string_equal(session->opts.host, "testhost.com");
|
||||
|
||||
/* We can also negate conditions */
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_USER, "not-tester");
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost");
|
||||
ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
|
||||
@@ -382,33 +401,19 @@ static void torture_config_match(void **state)
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(torture_config_from_file,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_double_ports,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_glob,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_new,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_auth_methods,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_unknown,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_match,
|
||||
setup_config_files,
|
||||
teardown),
|
||||
cmocka_unit_test(torture_config_from_file),
|
||||
cmocka_unit_test(torture_config_double_ports),
|
||||
cmocka_unit_test(torture_config_glob),
|
||||
cmocka_unit_test(torture_config_new),
|
||||
cmocka_unit_test(torture_config_auth_methods),
|
||||
cmocka_unit_test(torture_config_unknown),
|
||||
cmocka_unit_test(torture_config_match),
|
||||
};
|
||||
|
||||
|
||||
ssh_init();
|
||||
torture_filter_tests(tests);
|
||||
rc = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
rc = cmocka_run_group_tests(tests, setup_config_files, teardown);
|
||||
ssh_finalize();
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -20,15 +20,19 @@ static int setup_rsa_key(void **state)
|
||||
assert_true(b64_key != NULL);
|
||||
|
||||
q = p = b64_key;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
type = ssh_key_type_from_name(q);
|
||||
assert_true(type == SSH_KEYTYPE_RSA);
|
||||
|
||||
q = ++p;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
rc = ssh_pki_import_pubkey_base64(q, type, &key);
|
||||
assert_true(rc == 0);
|
||||
|
||||
@@ -104,7 +104,7 @@ static int teardown(void **state)
|
||||
|
||||
static void torture_pubkey_from_file(void **state) {
|
||||
ssh_session session = *state;
|
||||
ssh_string pubkey;
|
||||
ssh_string pubkey = NULL;
|
||||
int type, rc;
|
||||
|
||||
rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
|
||||
#include "knownhosts.c"
|
||||
|
||||
#if (defined _WIN32) || (defined _WIN64)
|
||||
#ifndef S_IRWXO
|
||||
#define S_IRWXO 0
|
||||
#endif
|
||||
#ifndef S_IRWXG
|
||||
#define S_IRWXG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LOCALHOST_RSA_LINE "localhost,127.0.0.1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDD7g+vV5cvxxGN0Ldmda4WZCPgRaxV1tV+1KRZoGUNUI61h0X4bmmGaAPRQBCz4G1d9bawqDqEqnpFWazrxBU5cQtISSjzuDJKovLGliky/ShTszee1Thszg3qVNk9gGOWj7jn/HDaOxRlp003Bp47MOdnMnK/oftllFDfY2fF5IRpE6sSIGtg2ZDtF95TV5/9W2oMOIAy8u/83tuibYlNPa1X/von5LgdaPLn6Bk16bQKIhAhlMtFZH8MBYEWe4ZtOGaSWKOsK9MM/RTMlwPi6PkfoHNl4MCMupjx+CdLXwbQEt9Ww+bBIaCui2VWBEiruVbIgJh0W2Tal0e2BzYZ What a Wurst!"
|
||||
#define LOCALHOST_ECDSA_SHA1_NISTP256_LINE "localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFWmI0n0Tn5+zR7pPGcKYszRbJ/T0T3QfzRBSMMiyebGKRY8tjkU5h2l/UMugzOrOyWqMGQDgQn+a0aMunhKMg0="
|
||||
#define LOCALHOST_DEFAULT_ED25519 "localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA7M22fXD7OiS7kGMXP+OoIjCa+J+5sq8SgAZfIOmDgM"
|
||||
@@ -22,37 +31,29 @@ static int setup_knownhosts_file(void **state)
|
||||
char *tmp_file = NULL;
|
||||
size_t nwritten;
|
||||
FILE *fp = NULL;
|
||||
mode_t mask;
|
||||
int fd;
|
||||
int rc = 0;
|
||||
|
||||
tmp_file = strdup(TMP_FILE_NAME);
|
||||
tmp_file = torture_create_temp_file(TMP_FILE_NAME);
|
||||
assert_non_null(tmp_file);
|
||||
|
||||
*state = tmp_file;
|
||||
|
||||
mask = umask(S_IRWXO | S_IRWXG);
|
||||
fd = mkstemp(tmp_file);
|
||||
umask(mask);
|
||||
assert_return_code(fd, errno);
|
||||
|
||||
fp = fdopen(fd, "w");
|
||||
if (fp == NULL) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
fp = fopen(tmp_file, "w");
|
||||
assert_non_null(fp);
|
||||
|
||||
nwritten = fwrite(LOCALHOST_PATTERN_ED25519,
|
||||
sizeof(char),
|
||||
strlen(LOCALHOST_PATTERN_ED25519),
|
||||
fp);
|
||||
if (nwritten != strlen(LOCALHOST_PATTERN_ED25519)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
rc = -1;
|
||||
goto close_fp;
|
||||
}
|
||||
|
||||
nwritten = fwrite("\n", sizeof(char), 1, fp);
|
||||
if (nwritten != 1) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
rc = -1;
|
||||
goto close_fp;
|
||||
}
|
||||
|
||||
nwritten = fwrite(LOCALHOST_RSA_LINE,
|
||||
@@ -60,13 +61,14 @@ static int setup_knownhosts_file(void **state)
|
||||
strlen(LOCALHOST_RSA_LINE),
|
||||
fp);
|
||||
if (nwritten != strlen(LOCALHOST_RSA_LINE)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
rc = -1;
|
||||
goto close_fp;
|
||||
}
|
||||
|
||||
close_fp:
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int teardown_knownhosts_file(void **state)
|
||||
@@ -310,9 +312,8 @@ torture_knownhosts_algorithms(void **state)
|
||||
const char *knownhosts_file = *state;
|
||||
char *algo_list = NULL;
|
||||
ssh_session session;
|
||||
const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,"
|
||||
"ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"
|
||||
"ecdsa-sha2-nistp256"
|
||||
const char *expect = "ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521,"
|
||||
"ecdsa-sha2-nistp384,ecdsa-sha2-nistp256"
|
||||
#ifdef HAVE_DSA
|
||||
",ssh-dss"
|
||||
#endif
|
||||
@@ -340,9 +341,8 @@ torture_knownhosts_algorithms_global(void **state)
|
||||
const char *knownhosts_file = *state;
|
||||
char *algo_list = NULL;
|
||||
ssh_session session;
|
||||
const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,"
|
||||
"ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"
|
||||
"ecdsa-sha2-nistp256"
|
||||
const char *expect = "ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521,"
|
||||
"ecdsa-sha2-nistp384,ecdsa-sha2-nistp256"
|
||||
#ifdef HAVE_DSA
|
||||
",ssh-dss"
|
||||
#endif
|
||||
|
||||
@@ -462,22 +462,26 @@ static void torture_options_config_host(void **state) {
|
||||
|
||||
assert_int_equal(session->opts.port, 42);
|
||||
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost2");
|
||||
ssh_options_parse_config(session, "test_config");
|
||||
assert_int_equal(session->opts.port, 43);
|
||||
|
||||
session->opts.port = 0;
|
||||
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost3");
|
||||
ssh_options_parse_config(session, "test_config");
|
||||
assert_int_equal(session->opts.port, 43);
|
||||
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost4");
|
||||
ssh_options_parse_config(session, "test_config");
|
||||
assert_int_equal(session->opts.port, 44);
|
||||
|
||||
session->opts.port = 0;
|
||||
|
||||
torture_reset_config(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost5");
|
||||
ssh_options_parse_config(session, "test_config");
|
||||
assert_int_equal(session->opts.port, 44);
|
||||
@@ -505,6 +509,7 @@ static void torture_options_config_match(void **state)
|
||||
assert_ssh_return_code_equal(session, rv, SSH_ERROR);
|
||||
|
||||
/* The Match all keyword needs to be the only one (start) */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match all host local\n",
|
||||
@@ -515,6 +520,7 @@ static void torture_options_config_match(void **state)
|
||||
assert_ssh_return_code_equal(session, rv, SSH_ERROR);
|
||||
|
||||
/* The Match all keyword needs to be the only one (end) */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match host local all\n",
|
||||
@@ -525,6 +531,7 @@ static void torture_options_config_match(void **state)
|
||||
assert_ssh_return_code_equal(session, rv, SSH_ERROR);
|
||||
|
||||
/* The Match host keyword requires an argument */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match host\n",
|
||||
@@ -535,6 +542,7 @@ static void torture_options_config_match(void **state)
|
||||
assert_ssh_return_code_equal(session, rv, SSH_ERROR);
|
||||
|
||||
/* The Match user keyword requires an argument */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match user\n",
|
||||
@@ -545,6 +553,7 @@ static void torture_options_config_match(void **state)
|
||||
assert_ssh_return_code_equal(session, rv, SSH_ERROR);
|
||||
|
||||
/* The Match canonical keyword is ignored */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match canonical\n"
|
||||
@@ -561,6 +570,7 @@ static void torture_options_config_match(void **state)
|
||||
session->opts.port = 0;
|
||||
|
||||
/* The Match originalhost keyword is ignored */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match originalhost origin\n"
|
||||
@@ -577,6 +587,7 @@ static void torture_options_config_match(void **state)
|
||||
session->opts.port = 0;
|
||||
|
||||
/* The Match localuser keyword is ignored */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match originalhost origin\n"
|
||||
@@ -593,6 +604,7 @@ static void torture_options_config_match(void **state)
|
||||
session->opts.port = 0;
|
||||
|
||||
/* The Match exec keyword is ignored */
|
||||
torture_reset_config(session);
|
||||
config = fopen("test_config", "w");
|
||||
assert_non_null(config);
|
||||
fputs("Match exec /bin/true\n"
|
||||
|
||||
@@ -41,9 +41,10 @@ static SSH_PACKET_CALLBACK(copy_packet_data){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void torture_packet(const char *cipher,
|
||||
const char *mac_type, size_t payload_len) {
|
||||
|
||||
static void
|
||||
torture_packet(const char *cipher, const char *mac_type,
|
||||
const char *comp_type, size_t payload_len)
|
||||
{
|
||||
ssh_session session = ssh_new();
|
||||
int verbosity = torture_libssh_verbosity();
|
||||
struct ssh_crypto_struct *crypto;
|
||||
@@ -61,6 +62,7 @@ static void torture_packet(const char *cipher,
|
||||
.callbacks=callbacks,
|
||||
.user=response
|
||||
};
|
||||
int cmp;
|
||||
|
||||
assert_non_null(session);
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
@@ -75,8 +77,8 @@ static void torture_packet(const char *cipher,
|
||||
crypto->kex_methods[SSH_CRYPT_S_C] = strdup(cipher);
|
||||
crypto->kex_methods[SSH_MAC_C_S] = strdup(mac_type);
|
||||
crypto->kex_methods[SSH_MAC_S_C] = strdup(mac_type);
|
||||
crypto->kex_methods[SSH_COMP_C_S] = strdup("none");
|
||||
crypto->kex_methods[SSH_COMP_S_C] = strdup("none");
|
||||
crypto->kex_methods[SSH_COMP_C_S] = strdup(comp_type);
|
||||
crypto->kex_methods[SSH_COMP_S_C] = strdup(comp_type);
|
||||
crypto->kex_methods[SSH_LANG_C_S] = strdup("none");
|
||||
crypto->kex_methods[SSH_LANG_S_C] = strdup("none");
|
||||
rc = crypt_set_algorithms_client(session);
|
||||
@@ -112,7 +114,12 @@ static void torture_packet(const char *cipher,
|
||||
rc = recv(sockets[1], buffer, sizeof(buffer), 0);
|
||||
assert_true(rc > 0);
|
||||
encrypted_packet_len = rc;
|
||||
assert_in_range(encrypted_packet_len, payload_len + 4, payload_len + (32 * 3));
|
||||
cmp = strcmp(comp_type, "none");
|
||||
if (cmp == 0) {
|
||||
assert_in_range(encrypted_packet_len,
|
||||
payload_len + 4,
|
||||
payload_len + (32 * 3));
|
||||
}
|
||||
rc = send(sockets[0], buffer, encrypted_packet_len, 0);
|
||||
assert_int_equal(rc, encrypted_packet_len);
|
||||
|
||||
@@ -134,7 +141,7 @@ static void torture_packet_aes128_ctr(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes128-ctr","hmac-sha1",i);
|
||||
torture_packet("aes128-ctr", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +150,7 @@ static void torture_packet_aes192_ctr(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes192-ctr","hmac-sha1",i);
|
||||
torture_packet("aes192-ctr", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +159,7 @@ static void torture_packet_aes256_ctr(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes256-ctr","hmac-sha1",i);
|
||||
torture_packet("aes256-ctr", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +168,7 @@ static void torture_packet_aes128_cbc(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes128-cbc","hmac-sha1",i);
|
||||
torture_packet("aes128-cbc", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +177,7 @@ static void torture_packet_aes192_cbc(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes192-cbc","hmac-sha1",i);
|
||||
torture_packet("aes192-cbc", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +186,7 @@ static void torture_packet_aes256_cbc(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes256-cbc","hmac-sha1",i);
|
||||
torture_packet("aes256-cbc", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +195,7 @@ static void torture_packet_3des_cbc(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("3des-cbc","hmac-sha1",i);
|
||||
torture_packet("3des-cbc", "hmac-sha1", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +204,43 @@ static void torture_packet_chacha20(void **state)
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("chacha20-poly1305@openssh.com","none",i);
|
||||
torture_packet("chacha20-poly1305@openssh.com", "none", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void torture_packet_aes128_gcm(void **state)
|
||||
{
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes128-gcm@openssh.com", "none", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void torture_packet_aes256_gcm(void **state)
|
||||
{
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes256-gcm@openssh.com", "none", "none", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void torture_packet_compress_zlib(void **state)
|
||||
{
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes256-ctr", "hmac-sha1", "zlib", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void torture_packet_compress_zlib_openssh(void **state)
|
||||
{
|
||||
int i;
|
||||
(void)state; /* unused */
|
||||
for (i=1;i<256;++i){
|
||||
torture_packet("aes256-ctr", "hmac-sha1", "zlib@openssh.com", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +254,11 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test(torture_packet_aes192_cbc),
|
||||
cmocka_unit_test(torture_packet_aes256_cbc),
|
||||
cmocka_unit_test(torture_packet_3des_cbc),
|
||||
cmocka_unit_test(torture_packet_chacha20)
|
||||
cmocka_unit_test(torture_packet_chacha20),
|
||||
cmocka_unit_test(torture_packet_aes128_gcm),
|
||||
cmocka_unit_test(torture_packet_aes256_gcm),
|
||||
cmocka_unit_test(torture_packet_compress_zlib),
|
||||
cmocka_unit_test(torture_packet_compress_zlib_openssh),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -263,6 +263,8 @@ static void torture_packet_filter_check_unfiltered(void **state)
|
||||
enum ssh_packet_filter_result_e rc;
|
||||
int in_unfiltered;
|
||||
|
||||
(void)state;
|
||||
|
||||
session = ssh_new();
|
||||
|
||||
for (msg_type = 1; msg_type <= MESSAGE_COUNT; msg_type++) {
|
||||
@@ -462,36 +464,6 @@ static void torture_packet_filter_check_auth_success(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void torture_packet_filter_check_msg_ext_info(void **state)
|
||||
{
|
||||
int rc;
|
||||
|
||||
global_state accepted[] = {
|
||||
{
|
||||
.flags = (COMPARE_SESSION_STATE |
|
||||
COMPARE_DH_STATE),
|
||||
.session = SSH_SESSION_STATE_AUTHENTICATING,
|
||||
.dh = DH_STATE_FINISHED,
|
||||
},
|
||||
{
|
||||
.flags = (COMPARE_SESSION_STATE |
|
||||
COMPARE_DH_STATE),
|
||||
.session = SSH_SESSION_STATE_AUTHENTICATED,
|
||||
.dh = DH_STATE_FINISHED,
|
||||
},
|
||||
};
|
||||
|
||||
int accepted_count = 2;
|
||||
|
||||
/* Unused */
|
||||
(void) state;
|
||||
|
||||
rc = check_message_in_all_states(accepted, accepted_count,
|
||||
SSH2_MSG_EXT_INFO);
|
||||
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void torture_packet_filter_check_channel_open(void **state)
|
||||
{
|
||||
int rc;
|
||||
@@ -522,7 +494,6 @@ int torture_run_tests(void)
|
||||
cmocka_unit_test(torture_packet_filter_check_auth_success),
|
||||
cmocka_unit_test(torture_packet_filter_check_channel_open),
|
||||
cmocka_unit_test(torture_packet_filter_check_unfiltered),
|
||||
cmocka_unit_test(torture_packet_filter_check_msg_ext_info)
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -210,7 +210,7 @@ static void torture_pki_verify_mismatch(void **state)
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(verify_key != NULL);
|
||||
|
||||
/* Should gradefully fail, but not crash */
|
||||
/* Should gracefully fail, but not crash */
|
||||
rc = pki_signature_verify(session,
|
||||
sign,
|
||||
verify_key,
|
||||
@@ -240,7 +240,7 @@ static void torture_pki_verify_mismatch(void **state)
|
||||
assert_string_equal(new_sig->type_c, key->type_c);
|
||||
assert_string_equal(new_sig->type_c, signature_types[sig_type]);
|
||||
|
||||
/* The verificaiton should not work */
|
||||
/* The verification should not work */
|
||||
rc = pki_signature_verify(session,
|
||||
new_sig,
|
||||
verify_key,
|
||||
|
||||
@@ -14,16 +14,39 @@
|
||||
#define LIBSSH_DSA_TESTKEY "libssh_testkey.id_dsa"
|
||||
#define LIBSSH_DSA_TESTKEY_PASSPHRASE "libssh_testkey_passphrase.id_dsa"
|
||||
|
||||
const char template[] = "temp_dir_XXXXXX";
|
||||
const unsigned char DSA_HASH[] = "12345678901234567890";
|
||||
|
||||
struct pki_st {
|
||||
char *cwd;
|
||||
char *temp_dir;
|
||||
};
|
||||
|
||||
static int setup_dsa_key(void **state)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
int rc = 0;
|
||||
|
||||
unlink(LIBSSH_DSA_TESTKEY);
|
||||
unlink(LIBSSH_DSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_DSA_TESTKEY ".pub");
|
||||
unlink(LIBSSH_DSA_TESTKEY "-cert.pub");
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
printf("Changed directory to: %s\n", tmp_dir);
|
||||
|
||||
torture_write_file(LIBSSH_DSA_TESTKEY,
|
||||
torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0));
|
||||
@@ -39,12 +62,27 @@ static int setup_dsa_key(void **state)
|
||||
|
||||
static int setup_openssh_dsa_key(void **state)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
int rc = 0;
|
||||
|
||||
unlink(LIBSSH_DSA_TESTKEY);
|
||||
unlink(LIBSSH_DSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_DSA_TESTKEY ".pub");
|
||||
unlink(LIBSSH_DSA_TESTKEY "-cert.pub");
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
torture_write_file(LIBSSH_DSA_TESTKEY,
|
||||
torture_get_openssh_testkey(SSH_KEYTYPE_DSS, 0, 0));
|
||||
@@ -58,14 +96,26 @@ static int setup_openssh_dsa_key(void **state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown_dsa_key(void **state)
|
||||
{
|
||||
(void)state;
|
||||
static int teardown(void **state) {
|
||||
|
||||
unlink(LIBSSH_DSA_TESTKEY);
|
||||
unlink(LIBSSH_DSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_DSA_TESTKEY ".pub");
|
||||
unlink(LIBSSH_DSA_TESTKEY "-cert.pub");
|
||||
struct pki_st *test_state = NULL;
|
||||
int rc = 0;
|
||||
|
||||
test_state = *((struct pki_st **)state);
|
||||
|
||||
assert_non_null(test_state);
|
||||
assert_non_null(test_state->cwd);
|
||||
assert_non_null(test_state->temp_dir);
|
||||
|
||||
rc = torture_change_dir(test_state->cwd);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = torture_rmdirs(test_state->temp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
SAFE_FREE(test_state->temp_dir);
|
||||
SAFE_FREE(test_state->cwd);
|
||||
SAFE_FREE(test_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -586,26 +636,26 @@ int torture_run_tests(void)
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_import_pubkey_file,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_import_pubkey_from_openssh_privkey,
|
||||
setup_openssh_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_import_privkey_base64,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_import_privkey_base64,
|
||||
setup_openssh_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_publickey_from_privatekey,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_import_cert_file,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_write_privkey,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
#endif
|
||||
cmocka_unit_test(torture_pki_dsa_import_privkey_base64_passphrase),
|
||||
cmocka_unit_test(torture_pki_dsa_import_openssh_privkey_base64_passphrase),
|
||||
@@ -613,16 +663,16 @@ int torture_run_tests(void)
|
||||
/* public key */
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_publickey_base64,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_generate_pubkey_from_privkey,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_duplicate_key,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_dsa_duplicate_key,
|
||||
setup_dsa_key,
|
||||
teardown_dsa_key),
|
||||
teardown),
|
||||
cmocka_unit_test(torture_pki_dsa_generate_key),
|
||||
};
|
||||
|
||||
|
||||
@@ -13,15 +13,39 @@
|
||||
#define LIBSSH_ECDSA_TESTKEY "libssh_testkey.id_ecdsa"
|
||||
#define LIBSSH_ECDSA_TESTKEY_PASSPHRASE "libssh_testkey_passphrase.id_ecdsa"
|
||||
|
||||
const char template[] = "temp_dir_XXXXXX";
|
||||
const unsigned char ECDSA_HASH[] = "12345678901234567890";
|
||||
|
||||
struct pki_st {
|
||||
char *cwd;
|
||||
char *temp_dir;
|
||||
};
|
||||
|
||||
static int setup_ecdsa_key(void **state, int ecdsa_bits)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
int rc = 0;
|
||||
|
||||
unlink(LIBSSH_ECDSA_TESTKEY);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY ".pub");
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
printf("Changed directory to: %s\n", tmp_dir);
|
||||
|
||||
torture_write_file(LIBSSH_ECDSA_TESTKEY,
|
||||
torture_get_testkey(SSH_KEYTYPE_ECDSA, ecdsa_bits, 0));
|
||||
@@ -35,13 +59,30 @@ static int setup_ecdsa_key(void **state, int ecdsa_bits)
|
||||
|
||||
static int setup_openssh_ecdsa_key(void **state, int ecdsa_bits)
|
||||
{
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
const char *keystring = NULL;
|
||||
int rc = 0;
|
||||
|
||||
(void) state; /* unused */
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
unlink(LIBSSH_ECDSA_TESTKEY);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY ".pub");
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
printf("Changed directory to: %s\n", tmp_dir);
|
||||
|
||||
keystring = torture_get_openssh_testkey(SSH_KEYTYPE_ECDSA, ecdsa_bits, 0);
|
||||
torture_write_file(LIBSSH_ECDSA_TESTKEY,
|
||||
@@ -98,13 +139,26 @@ static int setup_openssh_ecdsa_key_256(void **state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void **state)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
static int teardown(void **state) {
|
||||
|
||||
unlink(LIBSSH_ECDSA_TESTKEY);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY ".pub");
|
||||
struct pki_st *test_state = NULL;
|
||||
int rc = 0;
|
||||
|
||||
test_state = *((struct pki_st **)state);
|
||||
|
||||
assert_non_null(test_state);
|
||||
assert_non_null(test_state->cwd);
|
||||
assert_non_null(test_state->temp_dir);
|
||||
|
||||
rc = torture_change_dir(test_state->cwd);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = torture_rmdirs(test_state->temp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
SAFE_FREE(test_state->temp_dir);
|
||||
SAFE_FREE(test_state->cwd);
|
||||
SAFE_FREE(test_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -199,15 +253,19 @@ static void torture_pki_ecdsa_publickey_base64(void **state)
|
||||
assert_true(key_buf != NULL);
|
||||
|
||||
q = p = key_buf;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
type = ssh_key_type_from_name(q);
|
||||
assert_true(type == SSH_KEYTYPE_ECDSA);
|
||||
|
||||
q = ++p;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
rc = ssh_pki_import_pubkey_base64(q, type, &key);
|
||||
assert_true(rc == 0);
|
||||
@@ -332,14 +390,15 @@ static void torture_pki_ecdsa_duplicate_then_demote(void **state)
|
||||
NULL,
|
||||
NULL,
|
||||
&privkey);
|
||||
assert_true(rc == 0);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
privkey_dup = ssh_key_dup(privkey);
|
||||
assert_true(privkey_dup != NULL);
|
||||
assert_non_null(privkey_dup);
|
||||
assert_int_equal(privkey->ecdsa_nid, privkey_dup->ecdsa_nid);
|
||||
|
||||
rc = ssh_pki_export_privkey_to_pubkey(privkey_dup, &pubkey);
|
||||
assert_true(rc == 0);
|
||||
assert_int_equal(rc, 0);
|
||||
assert_non_null(pubkey);
|
||||
assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid);
|
||||
|
||||
SSH_KEY_FREE(pubkey);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define LIBSSH_ED25519_TESTKEY "libssh_testkey.id_ed25519"
|
||||
#define LIBSSH_ED25519_TESTKEY_PASSPHRASE "libssh_testkey_passphrase.id_ed25519"
|
||||
|
||||
const char template[] = "temp_dir_XXXXXX";
|
||||
const unsigned char HASH[] = "12345678901234567890";
|
||||
const uint8_t ref_signature[ED25519_SIG_LEN]=
|
||||
"\xbb\x8d\x55\x9f\x06\x14\x39\x24\xb4\xe1\x5a\x57\x3d\x9d\xbe\x22"
|
||||
@@ -19,15 +20,37 @@ const uint8_t ref_signature[ED25519_SIG_LEN]=
|
||||
"\x10\xa3\x18\x93\xdf\xa4\x96\x81\x11\x8e\x1e\x26\x14\x8a\x08\x1b"
|
||||
"\x01\x6a\x60\x59\x9c\x4a\x55\xa3\x16\x56\xf6\xc4\x50\x42\x7f\x03";
|
||||
|
||||
struct pki_st {
|
||||
char *cwd;
|
||||
char *temp_dir;
|
||||
};
|
||||
|
||||
static int setup_ed25519_key(void **state)
|
||||
{
|
||||
const char *keystring = NULL;
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
int rc = 0;
|
||||
|
||||
(void) state; /* unused */
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
unlink(LIBSSH_ED25519_TESTKEY);
|
||||
unlink(LIBSSH_ED25519_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_ED25519_TESTKEY ".pub");
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
printf("Changed directory to: %s\n", tmp_dir);
|
||||
|
||||
keystring = torture_get_openssh_testkey(SSH_KEYTYPE_ED25519, 0, 0);
|
||||
torture_write_file(LIBSSH_ED25519_TESTKEY, keystring);
|
||||
@@ -41,11 +64,24 @@ static int setup_ed25519_key(void **state)
|
||||
}
|
||||
|
||||
static int teardown(void **state) {
|
||||
(void) state; /* unused */
|
||||
struct pki_st *test_state = NULL;
|
||||
int rc = 0;
|
||||
|
||||
unlink(LIBSSH_ED25519_TESTKEY);
|
||||
unlink(LIBSSH_ED25519_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_ED25519_TESTKEY ".pub");
|
||||
test_state = *((struct pki_st **)state);
|
||||
|
||||
assert_non_null(test_state);
|
||||
assert_non_null(test_state->cwd);
|
||||
assert_non_null(test_state->temp_dir);
|
||||
|
||||
rc = torture_change_dir(test_state->cwd);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = torture_rmdirs(test_state->temp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
SAFE_FREE(test_state->temp_dir);
|
||||
SAFE_FREE(test_state->cwd);
|
||||
SAFE_FREE(test_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -202,15 +238,19 @@ static void torture_pki_ed25519_publickey_base64(void **state)
|
||||
assert_true(key_buf != NULL);
|
||||
|
||||
q = p = key_buf;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
type = ssh_key_type_from_name(q);
|
||||
assert_true(type == SSH_KEYTYPE_ED25519);
|
||||
|
||||
q = ++p;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
rc = ssh_pki_import_pubkey_base64(q, type, &key);
|
||||
assert_true(rc == 0);
|
||||
|
||||
@@ -14,19 +14,42 @@
|
||||
#define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa"
|
||||
#define LIBSSH_RSA_TESTKEY_PASSPHRASE "libssh_testkey_passphrase.id_rsa"
|
||||
|
||||
const char template[] = "temp_dir_XXXXXX";
|
||||
const unsigned char RSA_HASH[] = "12345678901234567890";
|
||||
const unsigned char SHA256_HASH[] = "12345678901234567890123456789012";
|
||||
const unsigned char SHA512_HASH[] = "1234567890123456789012345678901234567890"
|
||||
"123456789012345678901234";
|
||||
|
||||
struct pki_st {
|
||||
char *cwd;
|
||||
char *temp_dir;
|
||||
};
|
||||
|
||||
static int setup_rsa_key(void **state)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
int rc = 0;
|
||||
|
||||
unlink(LIBSSH_RSA_TESTKEY);
|
||||
unlink(LIBSSH_RSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_RSA_TESTKEY ".pub");
|
||||
unlink(LIBSSH_RSA_TESTKEY "-cert.pub");
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
printf("Changed directory to: %s\n", tmp_dir);
|
||||
|
||||
torture_write_file(LIBSSH_RSA_TESTKEY,
|
||||
torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0));
|
||||
@@ -40,14 +63,29 @@ static int setup_rsa_key(void **state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_rsa_openssh_key(void **state)
|
||||
static int setup_openssh_rsa_key(void **state)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
struct pki_st *test_state = NULL;
|
||||
char *cwd = NULL;
|
||||
char *tmp_dir = NULL;
|
||||
int rc = 0;
|
||||
|
||||
unlink(LIBSSH_RSA_TESTKEY);
|
||||
unlink(LIBSSH_RSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_RSA_TESTKEY ".pub");
|
||||
unlink(LIBSSH_RSA_TESTKEY "-cert.pub");
|
||||
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
|
||||
assert_non_null(test_state);
|
||||
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
tmp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(tmp_dir);
|
||||
|
||||
test_state->cwd = cwd;
|
||||
test_state->temp_dir = tmp_dir;
|
||||
|
||||
*state = test_state;
|
||||
|
||||
rc = torture_change_dir(tmp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
torture_write_file(LIBSSH_RSA_TESTKEY,
|
||||
torture_get_openssh_testkey(SSH_KEYTYPE_RSA, 0, 0));
|
||||
@@ -62,12 +100,25 @@ static int setup_rsa_openssh_key(void **state)
|
||||
}
|
||||
|
||||
static int teardown(void **state) {
|
||||
(void) state; /* unused */
|
||||
|
||||
unlink(LIBSSH_RSA_TESTKEY);
|
||||
unlink(LIBSSH_RSA_TESTKEY_PASSPHRASE);
|
||||
unlink(LIBSSH_RSA_TESTKEY ".pub");
|
||||
unlink(LIBSSH_RSA_TESTKEY "-cert.pub");
|
||||
struct pki_st *test_state = NULL;
|
||||
int rc = 0;
|
||||
|
||||
test_state = *((struct pki_st **)state);
|
||||
|
||||
assert_non_null(test_state);
|
||||
assert_non_null(test_state->cwd);
|
||||
assert_non_null(test_state->temp_dir);
|
||||
|
||||
rc = torture_change_dir(test_state->cwd);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = torture_rmdirs(test_state->temp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
SAFE_FREE(test_state->temp_dir);
|
||||
SAFE_FREE(test_state->cwd);
|
||||
SAFE_FREE(test_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -277,15 +328,19 @@ static void torture_pki_rsa_publickey_base64(void **state)
|
||||
assert_true(key_buf != NULL);
|
||||
|
||||
q = p = key_buf;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
type = ssh_key_type_from_name(q);
|
||||
assert_true(type == SSH_KEYTYPE_RSA);
|
||||
|
||||
q = ++p;
|
||||
while (*p != ' ') p++;
|
||||
*p = '\0';
|
||||
while (p != NULL && *p != '\0' && *p != ' ') p++;
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
rc = ssh_pki_import_pubkey_base64(q, type, &key);
|
||||
assert_true(rc == 0);
|
||||
@@ -657,7 +712,7 @@ int torture_run_tests(void) {
|
||||
setup_rsa_key,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_rsa_import_pubkey_from_openssh_privkey,
|
||||
setup_rsa_openssh_key,
|
||||
setup_openssh_rsa_key,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_rsa_import_privkey_base64_NULL_key,
|
||||
setup_rsa_key,
|
||||
@@ -669,7 +724,7 @@ int torture_run_tests(void) {
|
||||
setup_rsa_key,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_rsa_import_privkey_base64,
|
||||
setup_rsa_openssh_key,
|
||||
setup_openssh_rsa_key,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_pki_rsa_publickey_from_privatekey,
|
||||
setup_rsa_key,
|
||||
|
||||
78
tests/unittests/torture_push_pop_dir.c
Normal file
78
tests/unittests/torture_push_pop_dir.c
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "torture.h"
|
||||
#define LIBSSH_STATIC
|
||||
|
||||
const char template[] = "temp_dir_XXXXXX";
|
||||
|
||||
static int setup(void **state)
|
||||
{
|
||||
char *temp_dir = NULL;
|
||||
|
||||
temp_dir = torture_make_temp_dir(template);
|
||||
assert_non_null(temp_dir);
|
||||
|
||||
*state = (void *)temp_dir;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void **state)
|
||||
{
|
||||
char *temp_dir = *((char **)state);
|
||||
|
||||
torture_rmdirs((const char *)temp_dir);
|
||||
|
||||
free(temp_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void torture_back_and_forth(void **state)
|
||||
{
|
||||
char *temp_dir = *((char **)state);
|
||||
char *cwd = NULL;
|
||||
char *after_change = NULL;
|
||||
char *after_changing_back = NULL;
|
||||
int rc = 0;
|
||||
|
||||
cwd = torture_get_current_working_dir();
|
||||
assert_non_null(cwd);
|
||||
|
||||
printf("Current dir: %s\n", cwd);
|
||||
|
||||
rc = torture_change_dir(temp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
after_change = torture_get_current_working_dir();
|
||||
assert_non_null(after_change);
|
||||
|
||||
printf("Current dir after change: %s\n", after_change);
|
||||
|
||||
rc = torture_change_dir(cwd);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
after_changing_back = torture_get_current_working_dir();
|
||||
assert_non_null(after_changing_back);
|
||||
|
||||
printf("Back to dir: %s\n", after_changing_back);
|
||||
|
||||
SAFE_FREE(cwd);
|
||||
SAFE_FREE(after_change);
|
||||
SAFE_FREE(after_changing_back);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(torture_back_and_forth,
|
||||
setup, teardown),
|
||||
};
|
||||
|
||||
torture_filter_tests(tests);
|
||||
rc = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user