mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 20:30:38 +09:00
Compare commits
285 Commits
libssh-0.1
...
libssh-0.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c91f530610 | ||
|
|
69740ea841 | ||
|
|
1bb7895cd9 | ||
|
|
a028b88aed | ||
|
|
8a25f6bb07 | ||
|
|
2db453db16 | ||
|
|
03134c2932 | ||
|
|
95d0c143b3 | ||
|
|
3dcdafa6d7 | ||
|
|
75c446c529 | ||
|
|
4a9c32fc81 | ||
|
|
1634c5a91a | ||
|
|
dfa7593c27 | ||
|
|
034af66338 | ||
|
|
55c7b93a0a | ||
|
|
4818cf5606 | ||
|
|
316a3a42a4 | ||
|
|
546d9da185 | ||
|
|
3b7d997b54 | ||
|
|
129744692c | ||
|
|
83f6ce0928 | ||
|
|
b5c7f07064 | ||
|
|
223ba36d54 | ||
|
|
9141e9d4fe | ||
|
|
ead42db7c8 | ||
|
|
d5a68bedfd | ||
|
|
4307489702 | ||
|
|
f0da1f2e03 | ||
|
|
50477cb80b | ||
|
|
ded4a81ffe | ||
|
|
c2bc4e62dd | ||
|
|
f7ab481b22 | ||
|
|
628b529a91 | ||
|
|
7e25963130 | ||
|
|
91d8f1a256 | ||
|
|
61dcc023b0 | ||
|
|
4468a78ee2 | ||
|
|
8f18063b6d | ||
|
|
a167faee3e | ||
|
|
0e8f6aaee5 | ||
|
|
f0a1b94d0d | ||
|
|
5d1ddf5920 | ||
|
|
152ae623c2 | ||
|
|
e7bd9d02bc | ||
|
|
9196639940 | ||
|
|
786d7e39a3 | ||
|
|
c33710d112 | ||
|
|
a14a80f35f | ||
|
|
0389ff6d9d | ||
|
|
8954fccfdb | ||
|
|
332df98fc9 | ||
|
|
d4cc3f69c6 | ||
|
|
534c58c475 | ||
|
|
84fd910423 | ||
|
|
d51f77c2b1 | ||
|
|
47376cbc77 | ||
|
|
85c3db3e89 | ||
|
|
3f8a522c7f | ||
|
|
eb08802b7c | ||
|
|
dc587045bf | ||
|
|
9b495b72c5 | ||
|
|
2ce6c56609 | ||
|
|
9caef95899 | ||
|
|
66c2630aaf | ||
|
|
b8f63ee2df | ||
|
|
68adb49996 | ||
|
|
12e94bfd18 | ||
|
|
4fc3d7a27f | ||
|
|
466bb332c1 | ||
|
|
ff25b45367 | ||
|
|
df83f4fb57 | ||
|
|
5bda3ab9f6 | ||
|
|
9a057159a2 | ||
|
|
9c0875dd5d | ||
|
|
1fa5a2a504 | ||
|
|
a08a2f52fb | ||
|
|
21d37f8605 | ||
|
|
e43586b4de | ||
|
|
dc7e1bdb39 | ||
|
|
03d559b066 | ||
|
|
3191c1f6be | ||
|
|
d46f01cb7c | ||
|
|
04e290a19b | ||
|
|
bad407f5e2 | ||
|
|
2787756efe | ||
|
|
7b35afdf6b | ||
|
|
dba2903e38 | ||
|
|
965014b035 | ||
|
|
c4ec92f375 | ||
|
|
54cf9d1364 | ||
|
|
23ce6d7156 | ||
|
|
07473976e1 | ||
|
|
51063fe07e | ||
|
|
9cc1af1d53 | ||
|
|
8a83bc0569 | ||
|
|
0181f5b5ed | ||
|
|
eaae8ce086 | ||
|
|
0b2072dd30 | ||
|
|
2e77cf6b34 | ||
|
|
ad3c052e1c | ||
|
|
57d9d97866 | ||
|
|
22747c862a | ||
|
|
fed755eee5 | ||
|
|
804410f8ad | ||
|
|
df57a9a81d | ||
|
|
97076780a5 | ||
|
|
899553f9f7 | ||
|
|
2edff5e69e | ||
|
|
37f451171b | ||
|
|
2efc1721d8 | ||
|
|
e9613e6b52 | ||
|
|
73fbe68ccd | ||
|
|
0cb282df99 | ||
|
|
fdb0c0a29b | ||
|
|
2e56db3b2f | ||
|
|
4eb759bf40 | ||
|
|
c3987a9796 | ||
|
|
a070c942e7 | ||
|
|
113b1872cf | ||
|
|
c7dc2937fc | ||
|
|
075895da40 | ||
|
|
7930086a37 | ||
|
|
3f376f848d | ||
|
|
3cee61a65b | ||
|
|
90321f732e | ||
|
|
c6140b1a4c | ||
|
|
9290d89570 | ||
|
|
da9ab71f88 | ||
|
|
53dfee98d2 | ||
|
|
bb14611f86 | ||
|
|
b1aca92268 | ||
|
|
2b524655ae | ||
|
|
b51594c34a | ||
|
|
b409b7d092 | ||
|
|
4256936fed | ||
|
|
fdb6dc7069 | ||
|
|
6291900234 | ||
|
|
216bd2abd8 | ||
|
|
574f279f00 | ||
|
|
d886870bbf | ||
|
|
f56c93cccd | ||
|
|
bbd17bc97a | ||
|
|
26fa923b55 | ||
|
|
177a082974 | ||
|
|
ce3ee332d4 | ||
|
|
eb95f8fa85 | ||
|
|
8d3db75724 | ||
|
|
e1fbc02209 | ||
|
|
766041d956 | ||
|
|
f880a7728f | ||
|
|
013203301f | ||
|
|
bfb60befa7 | ||
|
|
4d34890624 | ||
|
|
6751c0e2c3 | ||
|
|
a641b6ea79 | ||
|
|
fa3c73016d | ||
|
|
ffabd8c6ed | ||
|
|
219a311925 | ||
|
|
8e3af4d859 | ||
|
|
9fa614a36d | ||
|
|
3d207f72a0 | ||
|
|
f53d2f7511 | ||
|
|
b853d99546 | ||
|
|
a09976e3d6 | ||
|
|
1ba0432524 | ||
|
|
7dcd749ee1 | ||
|
|
30368fb06a | ||
|
|
fd6b7db1ce | ||
|
|
53514b2a40 | ||
|
|
0e20418296 | ||
|
|
92b59ace9e | ||
|
|
af7b5b78ee | ||
|
|
2b67e2d54c | ||
|
|
f44994f1e6 | ||
|
|
97d6eb84a4 | ||
|
|
33f2211cae | ||
|
|
03aff19b80 | ||
|
|
cf660fe27c | ||
|
|
f9d60e1360 | ||
|
|
1098280e43 | ||
|
|
62301834f4 | ||
|
|
3e0ac84001 | ||
|
|
4d26e08789 | ||
|
|
3c4403c400 | ||
|
|
8dcde7a74f | ||
|
|
bb7cd8e22b | ||
|
|
7458e95ee5 | ||
|
|
2f69c5f022 | ||
|
|
efdd567a1b | ||
|
|
cff8f7c0b5 | ||
|
|
fe4a4b1b79 | ||
|
|
8caf653e97 | ||
|
|
88c4d532ab | ||
|
|
e69d063252 | ||
|
|
a35218da74 | ||
|
|
4d8e2cdc8b | ||
|
|
3d0f2977bf | ||
|
|
230929a4b2 | ||
|
|
c847216ca4 | ||
|
|
cacd2fa999 | ||
|
|
0b688e4829 | ||
|
|
27cf0ea06b | ||
|
|
e473108e1b | ||
|
|
c74cc9a606 | ||
|
|
619e60cf0e | ||
|
|
37b3657481 | ||
|
|
c1211a4e1a | ||
|
|
95d34b5937 | ||
|
|
6dc3f666c5 | ||
|
|
8e4491a532 | ||
|
|
492095b2a7 | ||
|
|
d516642980 | ||
|
|
193845ecdd | ||
|
|
598d04d5d9 | ||
|
|
06c5dd9c84 | ||
|
|
6632659907 | ||
|
|
86bf835d50 | ||
|
|
c9d0362a6b | ||
|
|
d2989f28db | ||
|
|
0bab6013d0 | ||
|
|
361d93586c | ||
|
|
0db13661b4 | ||
|
|
c866592d7d | ||
|
|
eb90325bed | ||
|
|
c878545977 | ||
|
|
741021513b | ||
|
|
97e8aba080 | ||
|
|
802d46d040 | ||
|
|
96718df15e | ||
|
|
89bd779e78 | ||
|
|
b5af3e74d7 | ||
|
|
2d3932d988 | ||
|
|
d0c1583ad2 | ||
|
|
59ff4064ba | ||
|
|
00a68c985f | ||
|
|
e862ea556c | ||
|
|
a4704cba0b | ||
|
|
455b3a7865 | ||
|
|
fabaab1540 | ||
|
|
8ac49ff181 | ||
|
|
cdf55a18d2 | ||
|
|
d158ca7101 | ||
|
|
664b7ebfa1 | ||
|
|
163c488e30 | ||
|
|
4b5bfa7a9d | ||
|
|
decbadda45 | ||
|
|
f00d780c16 | ||
|
|
1daa2e4609 | ||
|
|
d84bc3ad8e | ||
|
|
a9350e3205 | ||
|
|
95e3a7e7a3 | ||
|
|
e4cecee7d3 | ||
|
|
8b867b41d3 | ||
|
|
c6bd2fe734 | ||
|
|
d7e52b99bd | ||
|
|
a640d9472a | ||
|
|
b15103ef4e | ||
|
|
95071cd1fe | ||
|
|
18a888f9fb | ||
|
|
bbfc41948a | ||
|
|
c29a8cc084 | ||
|
|
54e7af83e6 | ||
|
|
3483d6327d | ||
|
|
5869345899 | ||
|
|
0cad2778b4 | ||
|
|
24de1fbde8 | ||
|
|
131728a680 | ||
|
|
e949e135b6 | ||
|
|
1510b63d20 | ||
|
|
0db4d9bd46 | ||
|
|
1e17e084bf | ||
|
|
a2c14c5ec5 | ||
|
|
b99849c831 | ||
|
|
c7d4286ca1 | ||
|
|
434e2b7212 | ||
|
|
acf0f0fa6e | ||
|
|
220e6b66e8 | ||
|
|
c4d4731ddf | ||
|
|
139ccaa78c | ||
|
|
c42410b560 | ||
|
|
120f11812d | ||
|
|
500486d501 | ||
|
|
6708debd4c | ||
|
|
852a8b4875 | ||
|
|
9c6b4ecb48 |
@@ -1,18 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
max_line_length = 80
|
|
||||||
end_of_line = lf
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.{c,h}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
tab_width = 4
|
|
||||||
|
|
||||||
[{CMakeLists.txt,*.cmake}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
tab_width = 4
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,9 +4,6 @@
|
|||||||
*.swp
|
*.swp
|
||||||
*~$
|
*~$
|
||||||
cscope.*
|
cscope.*
|
||||||
compile_commands.json
|
|
||||||
/.cache
|
|
||||||
/.clangd
|
|
||||||
tags
|
tags
|
||||||
/build
|
/build
|
||||||
/obj*
|
/obj*
|
||||||
|
|||||||
794
.gitlab-ci.yml
794
.gitlab-ci.yml
@@ -1,559 +1,361 @@
|
|||||||
---
|
|
||||||
variables:
|
variables:
|
||||||
BUILD_IMAGES_PROJECT: libssh/build-images
|
BUILD_IMAGES_PROJECT: libssh/build-images
|
||||||
CENTOS7_BUILD: buildenv-centos7
|
|
||||||
CENTOS8_BUILD: buildenv-c8s
|
|
||||||
CENTOS9_BUILD: buildenv-c9s
|
|
||||||
FEDORA_BUILD: buildenv-fedora
|
FEDORA_BUILD: buildenv-fedora
|
||||||
MINGW_BUILD: buildenv-mingw
|
CENTOS7_BUILD: buildenv-centos7
|
||||||
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
||||||
UBUNTU_BUILD: buildenv-ubuntu
|
MINGW_BUILD: buildenv-mingw
|
||||||
ALPINE_BUILD: buildenv-alpine
|
DEBIAN_CROSS_BUILD: buildenv-debian-cross
|
||||||
|
|
||||||
stages:
|
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
|
||||||
- review
|
centos7/openssl_1.0.x/x86-64:
|
||||||
- build
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
|
||||||
- test
|
|
||||||
- analysis
|
|
||||||
|
|
||||||
.build:
|
|
||||||
stage: build
|
|
||||||
variables:
|
|
||||||
CMAKE_DEFAULT_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON"
|
|
||||||
CMAKE_BUILD_OPTIONS: "-DWITH_BLOWFISH_CIPHER=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON -DWITH_DSA=ON"
|
|
||||||
CMAKE_TEST_OPTIONS: "-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DWITH_BENCHMARKS=ON"
|
|
||||||
CMAKE_OPTIONS: $CMAKE_DEFAULT_OPTIONS $CMAKE_BUILD_OPTIONS $CMAKE_TEST_OPTIONS
|
|
||||||
before_script: &build
|
|
||||||
- uname -a
|
|
||||||
- cat /etc/os-release
|
|
||||||
- mount
|
|
||||||
- df -h
|
|
||||||
- cat /proc/swaps
|
|
||||||
- free -h
|
|
||||||
- mkdir -p obj && cd obj
|
|
||||||
script:
|
script:
|
||||||
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
|
- mkdir -p obj && cd obj && cmake3 -DUNIT_TESTING=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
make -j$(nproc) &&
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
|
||||||
make -j$(nproc) install
|
-DWITH_PCAP=ON .. && make -j$(nproc) && ctest --output-on-failure
|
||||||
# Do not use after_script as it does not make the targets fail
|
|
||||||
tags:
|
tags:
|
||||||
- shared
|
- shared
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- obj/
|
- obj/
|
||||||
|
|
||||||
.tests:
|
fedora/openssl_1.1.x/x86-64:
|
||||||
extends: .build
|
|
||||||
stage: test
|
|
||||||
# This is needed to prevent passing artifacts from previous stages
|
|
||||||
dependencies: []
|
|
||||||
script:
|
|
||||||
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
# Do not use after_script as it does not make the targets fail
|
|
||||||
|
|
||||||
.fedora:
|
|
||||||
extends: .tests
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
|
|
||||||
|
|
||||||
.tumbleweed:
|
|
||||||
extends: .tests
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
|
||||||
|
|
||||||
.fips:
|
|
||||||
extends: .tests
|
|
||||||
variables:
|
|
||||||
# DSA is turned off in fips mode
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_DSA=OFF
|
|
||||||
before_script:
|
|
||||||
- *build
|
|
||||||
- echo "# userspace fips" > /etc/system-fips
|
|
||||||
# We do not need the kernel part, but in case we ever do:
|
|
||||||
# mkdir -p /var/tmp/userspace-fips
|
|
||||||
# echo 1 > /var/tmp/userspace-fips/fips_enabled
|
|
||||||
# mount --bind /var/tmp/userspace-fips/fips_enabled \
|
|
||||||
# /proc/sys/crypto/fips_enabled
|
|
||||||
- update-crypto-policies --show
|
|
||||||
- update-crypto-policies --set FIPS
|
|
||||||
- update-crypto-policies --show
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# CentOS builds #
|
|
||||||
###############################################################################
|
|
||||||
# pkd tests fail on CentOS7 docker images, so we don't use -DSERVER_TESTING=ON
|
|
||||||
centos7/openssl_1.0.x/x86_64:
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
|
|
||||||
extends: .tests
|
|
||||||
script:
|
|
||||||
- cmake3 $CMAKE_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
centos9s/openssl_3.0.x/x86_64:
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
|
|
||||||
extends: .tests
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
|
|
||||||
script:
|
|
||||||
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
|
|
||||||
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
centos9s/openssl_3.0.x/x86_64/fips:
|
|
||||||
extends: .fips
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
|
|
||||||
script:
|
|
||||||
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
|
|
||||||
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
|
|
||||||
|
|
||||||
centos8s/openssl_1.1.1/x86_64:
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS8_BUILD
|
|
||||||
extends: .tests
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
|
|
||||||
script:
|
|
||||||
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
centos8s/openssl_1.1.1/x86_64/fips:
|
|
||||||
extends: .fips
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS8_BUILD
|
|
||||||
script:
|
|
||||||
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Fedora builds #
|
|
||||||
###############################################################################
|
|
||||||
fedora/build:
|
|
||||||
extends: .build
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
|
||||||
|
|
||||||
fedora/docs:
|
|
||||||
extends: .build
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
script:
|
script:
|
||||||
- cmake .. && make docs
|
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
|
-DPICKY_DEVELOPER=ON
|
||||||
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||||
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
fedora/ninja:
|
fedora/openssl_1.1.x/x86-64/release:
|
||||||
extends: .fedora
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
script:
|
script:
|
||||||
- cmake -G Ninja $CMAKE_OPTIONS ../ && ninja && CTEST_OUTPUT_ON_FAILURE=1 ninja test
|
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Release
|
||||||
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
fedora/openssl_3.0.x/x86_64:
|
-DPICKY_DEVELOPER=ON
|
||||||
extends: .fedora
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||||
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
fedora/openssl_3.0.x/x86_64/minimal:
|
tags:
|
||||||
extends: .fedora
|
- shared
|
||||||
variables:
|
except:
|
||||||
script:
|
- tags
|
||||||
- cmake $CMAKE_DEFAULT_OPTIONS
|
artifacts:
|
||||||
-DWITH_SFTP=OFF
|
expire_in: 1 week
|
||||||
-DWITH_SERVER=OFF
|
when: on_failure
|
||||||
-DWITH_ZLIB=OFF
|
paths:
|
||||||
-DWITH_PCAP=OFF
|
- obj/
|
||||||
-DWITH_DSA=OFF
|
|
||||||
-DUNIT_TESTING=ON
|
|
||||||
-DCLIENT_TESTING=ON
|
|
||||||
-DWITH_GEX=OFF .. &&
|
|
||||||
make -j$(nproc)
|
|
||||||
|
|
||||||
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
|
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
|
||||||
# so, this is only enabled for unit tests right now.
|
# so, this is only enabled for unit tests right now.
|
||||||
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||||
fedora/address-sanitizer:
|
fedora/address-sanitizer:
|
||||||
extends: .fedora
|
|
||||||
stage: analysis
|
|
||||||
script:
|
|
||||||
- cmake
|
|
||||||
-DCMAKE_BUILD_TYPE=AddressSanitizer
|
|
||||||
-DCMAKE_C_COMPILER=clang
|
|
||||||
-DCMAKE_CXX_COMPILER=clang++
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
$CMAKE_BUILD_OPTIONS
|
|
||||||
-DUNIT_TESTING=ON
|
|
||||||
-DFUZZ_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
# This is disabled as it report OpenSSL issues
|
|
||||||
# It also has the same issues with cwrap as AddressSanitizer
|
|
||||||
.fedora/memory-sanitizer:
|
|
||||||
extends: .fedora
|
|
||||||
stage: analysis
|
|
||||||
script:
|
|
||||||
- cmake
|
|
||||||
-DCMAKE_BUILD_TYPE=MemorySanitizer
|
|
||||||
-DCMAKE_C_COMPILER=clang
|
|
||||||
-DCMAKE_CXX_COMPILER=clang++
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
$CMAKE_BUILD_OPTIONS
|
|
||||||
-DUNIT_TESTING=ON
|
|
||||||
-DFUZZ_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
fedora/undefined-sanitizer:
|
|
||||||
extends: .fedora
|
|
||||||
stage: analysis
|
|
||||||
script:
|
|
||||||
- cmake
|
|
||||||
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
|
|
||||||
-DCMAKE_C_COMPILER=clang
|
|
||||||
-DCMAKE_CXX_COMPILER=clang++
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
$CMAKE_BUILD_OPTIONS
|
|
||||||
-DUNIT_TESTING=ON
|
|
||||||
-DFUZZ_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
fedora/libgcrypt/x86_64:
|
|
||||||
extends: .fedora
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_GCRYPT=ON -DWITH_DEBUG_CRYPTO=ON"
|
|
||||||
|
|
||||||
fedora/mbedtls/x86_64:
|
|
||||||
extends: .fedora
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_DSA=OFF"
|
|
||||||
|
|
||||||
# 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
|
|
||||||
extends: .tests
|
|
||||||
script:
|
|
||||||
- export WINEPATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
|
||||||
- export WINEDEBUG=-all
|
|
||||||
- mingw64-cmake $CMAKE_DEFAULT_OPTIONS
|
|
||||||
-DWITH_SFTP=ON
|
|
||||||
-DWITH_SERVER=ON
|
|
||||||
-DWITH_ZLIB=ON
|
|
||||||
-DWITH_PCAP=ON
|
|
||||||
-DUNIT_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
# 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
|
|
||||||
extends: .tests
|
|
||||||
script:
|
|
||||||
- export WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
|
||||||
- export WINEDEBUG=-all
|
|
||||||
- mingw32-cmake $CMAKE_DEFAULT_OPTIONS
|
|
||||||
-DWITH_SFTP=ON
|
|
||||||
-DWITH_SERVER=ON
|
|
||||||
-DWITH_ZLIB=ON
|
|
||||||
-DWITH_PCAP=ON
|
|
||||||
-DUNIT_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Fedora csbuild #
|
|
||||||
###############################################################################
|
|
||||||
.csbuild:
|
|
||||||
stage: analysis
|
|
||||||
variables:
|
|
||||||
GIT_DEPTH: "100"
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
before_script:
|
script:
|
||||||
- |
|
- mkdir -p obj && cd obj && cmake
|
||||||
if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then
|
-DCMAKE_BUILD_TYPE=AddressSanitizer
|
||||||
export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
fi
|
-DUNIT_TESTING=ON .. &&
|
||||||
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
# 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"
|
|
||||||
tags:
|
tags:
|
||||||
- shared
|
- shared
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- obj-csbuild/
|
- obj/
|
||||||
|
|
||||||
fedora/csbuild/openssl_3.0.x:
|
fedora/undefined-sanitizer:
|
||||||
extends: .csbuild
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
script:
|
script:
|
||||||
- csbuild
|
- mkdir -p obj && cd obj && cmake
|
||||||
--build-dir=obj-csbuild
|
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
|
||||||
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_DSA=ON @SRCDIR@ && make clean && make -j$(nproc)"
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
--git-commit-range $CI_COMMIT_RANGE
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
|
||||||
--color
|
&& make -j$(nproc) && ctest --output-on-failure
|
||||||
--print-current --print-fixed
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
fedora/csbuild/libgcrypt:
|
fedora/static-analysis:
|
||||||
extends: .csbuild
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
script:
|
script:
|
||||||
- csbuild
|
- export CCC_CC=clang
|
||||||
--build-dir=obj-csbuild
|
- export CCC_CXX=clang++
|
||||||
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_GCRYPT=ON -DWITH_DSA=ON @SRCDIR@ && make clean && make -j$(nproc)"
|
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
|
||||||
--git-commit-range $CI_COMMIT_RANGE
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
--color
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||||
--print-current --print-fixed
|
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
|
||||||
|
scan-build --status-bugs -o scan make -j$(nproc)
|
||||||
fedora/csbuild/mbedtls:
|
tags:
|
||||||
extends: .csbuild
|
- shared
|
||||||
script:
|
except:
|
||||||
- csbuild
|
- tags
|
||||||
--build-dir=obj-csbuild
|
|
||||||
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_MBEDTLS=ON @SRCDIR@ && make clean && make -j$(nproc)"
|
|
||||||
--git-commit-range $CI_COMMIT_RANGE
|
|
||||||
--color
|
|
||||||
--print-current --print-fixed
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Ubuntu builds #
|
|
||||||
###############################################################################
|
|
||||||
ubuntu/openssl_3.0.x/x86_64:
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$UBUNTU_BUILD
|
|
||||||
extends: .tests
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Alpine builds #
|
|
||||||
###############################################################################
|
|
||||||
alpine/openssl_3.0.x/musl:
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$ALPINE_BUILD
|
|
||||||
extends: .tests
|
|
||||||
script:
|
|
||||||
- cmake $CMAKE_DEFAULT_OPTIONS
|
|
||||||
-DWITH_SFTP=ON
|
|
||||||
-DWITH_SERVER=ON
|
|
||||||
-DWITH_ZLIB=ON
|
|
||||||
-DWITH_PCAP=ON
|
|
||||||
-DUNIT_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Tumbleweed builds #
|
|
||||||
###############################################################################
|
|
||||||
tumbleweed/openssl_3.0.x/x86_64/gcc:
|
|
||||||
extends: .tumbleweed
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: "-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config"
|
|
||||||
|
|
||||||
tumbleweed/openssl_3.0.x/x86/gcc:
|
|
||||||
extends: .tumbleweed
|
|
||||||
script:
|
|
||||||
- cmake
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
|
||||||
$CMAKE_DEFAULT_OPTIONS
|
|
||||||
-DWITH_SFTP=ON
|
|
||||||
-DWITH_SERVER=ON
|
|
||||||
-DWITH_ZLIB=ON
|
|
||||||
-DWITH_PCAP=ON
|
|
||||||
-DWITH_DSA=ON
|
|
||||||
-DUNIT_TESTING=ON .. &&
|
|
||||||
make -j$(nproc)
|
|
||||||
|
|
||||||
tumbleweed/openssl_3.0.x/x86_64/gcc7:
|
|
||||||
extends: .tumbleweed
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7 -DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config"
|
|
||||||
|
|
||||||
tumbleweed/openssl_3.0.x/x86/gcc7:
|
|
||||||
extends: .tumbleweed
|
|
||||||
script:
|
|
||||||
- cmake
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-cross-m32.cmake
|
|
||||||
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
|
|
||||||
$CMAKE_DEFAULT_OPTIONS
|
|
||||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
|
||||||
-DWITH_DSA=ON
|
|
||||||
-DUNIT_TESTING=ON .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
tumbleweed/openssl_3.0.x/x86_64/clang:
|
|
||||||
extends: .tumbleweed
|
|
||||||
variables:
|
|
||||||
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config"
|
|
||||||
|
|
||||||
tumbleweed/static-analysis:
|
|
||||||
extends: .tests
|
|
||||||
stage: analysis
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
|
||||||
script:
|
|
||||||
- export CCC_CC=clang
|
|
||||||
- export CCC_CXX=clang++
|
|
||||||
- scan-build cmake
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug
|
|
||||||
-DCMAKE_C_COMPILER=clang
|
|
||||||
-DCMAKE_CXX_COMPILER=clang++
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
$CMAKE_BUILD_OPTIONS
|
|
||||||
$CMAKE_TEST_OPTIONS .. &&
|
|
||||||
scan-build --status-bugs -o scan make -j$(nproc)
|
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- obj/scan
|
- obj/scan
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# FreeBSD builds #
|
|
||||||
###############################################################################
|
|
||||||
# That is a specific runner that we cannot enable universally.
|
# That is a specific runner that we cannot enable universally.
|
||||||
# We restrict it to builds under the $BUILD_IMAGES_PROJECT project.
|
# We restrict it to builds under the $BUILD_IMAGES_PROJECT project.
|
||||||
freebsd/openssl_1.1.1/x86_64:
|
freebsd/x86-64:
|
||||||
image:
|
image:
|
||||||
extends: .tests
|
|
||||||
before_script:
|
|
||||||
- mkdir -p obj && cd obj && cmake
|
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
|
||||||
-DUNIT_TESTING=ON ..
|
|
||||||
script:
|
script:
|
||||||
- cmake $CMAKE_DEFAULT_OPTIONS
|
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||||
-DWITH_SFTP=ON
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
-DWITH_SERVER=ON
|
-DPICKY_DEVELOPER=ON
|
||||||
-DWITH_ZLIB=ON
|
-DUNIT_TESTING=ON .. &&
|
||||||
-DWITH_PCAP=ON
|
make && ctest --output-on-failure
|
||||||
-DUNIT_TESTING=ON .. &&
|
|
||||||
make &&
|
|
||||||
ctest --output-on-failure
|
|
||||||
tags:
|
tags:
|
||||||
- private
|
- freebsd
|
||||||
- freebsd
|
|
||||||
only:
|
|
||||||
- branches@libssh/libssh-mirror
|
|
||||||
- branches@cryptomilk/libssh-mirror
|
|
||||||
- branches@jjelen/libssh-mirror
|
|
||||||
- branches@marco.fortina/libssh-mirror
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Visual Studio builds #
|
|
||||||
###############################################################################
|
|
||||||
.vs:
|
|
||||||
stage: test
|
|
||||||
cache:
|
|
||||||
key: vcpkg.${CI_JOB_NAME}
|
|
||||||
paths:
|
|
||||||
- .vcpkg
|
|
||||||
variables:
|
|
||||||
ErrorActionPreference: STOP
|
|
||||||
script:
|
|
||||||
- cmake --build .
|
|
||||||
- ctest --output-on-failure
|
|
||||||
tags:
|
|
||||||
- windows
|
|
||||||
- shared-windows
|
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
|
only:
|
||||||
|
- branches@libssh/libssh-mirror
|
||||||
|
- branches@cryptomilk/libssh-mirror
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- obj/
|
- obj/
|
||||||
before_script:
|
|
||||||
- If (!(test-path .vcpkg\archives)) { mkdir -p .vcpkg\archives }
|
|
||||||
- $env:VCPKG_DEFAULT_BINARY_CACHE="$PWD\.vcpkg\archives"
|
|
||||||
- echo $env:VCPKG_DEFAULT_BINARY_CACHE
|
|
||||||
- $env:VCPKG_DEFAULT_TRIPLET="$TRIPLET-windows"
|
|
||||||
- vcpkg install cmocka
|
|
||||||
- vcpkg install openssl
|
|
||||||
- vcpkg install zlib
|
|
||||||
- vcpkg integrate install
|
|
||||||
- mkdir -p obj; if ($?) {cd obj}; if (! $?) {exit 1}
|
|
||||||
- cmake
|
|
||||||
-A $PLATFORM
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
|
||||||
-DUNIT_TESTING=ON ..
|
|
||||||
|
|
||||||
visualstudio/x86_64:
|
fedora/libgcrypt/x86-64:
|
||||||
extends: .vs
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
variables:
|
|
||||||
PLATFORM: "x64"
|
|
||||||
TRIPLET: "x64"
|
|
||||||
|
|
||||||
visualstudio/x86:
|
|
||||||
extends: .vs
|
|
||||||
variables:
|
|
||||||
PLATFORM: "win32"
|
|
||||||
TRIPLET: "x86"
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Coverity #
|
|
||||||
###############################################################################
|
|
||||||
#
|
|
||||||
# git push -o ci.variable="COVERITY_SCAN_TOKEN=XXXXXX" \
|
|
||||||
# -o ci.variable="COVERITY_SCAN_PROJECT_NAME=XXXXXX" \
|
|
||||||
# -o ci.variable="COVERITY_SCAN_EMAIL=XXXXXX" \
|
|
||||||
# -f gitlab
|
|
||||||
|
|
||||||
coverity:
|
|
||||||
stage: analysis
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
|
|
||||||
script:
|
script:
|
||||||
- mkdir obj && cd obj
|
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||||
- wget https://scan.coverity.com/download/linux64 --post-data "token=$COVERITY_SCAN_TOKEN&project=$COVERITY_SCAN_PROJECT_NAME" -O /tmp/coverity_tool.tgz
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
- tar xf /tmp/coverity_tool.tgz
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||||
- cmake -DCMAKE_BUILD_TYPE=Debug $CMAKE_BUILD_OPTIONS $CMAKE_TEST_OPTIONS ..
|
-DWITH_GCRYPT=ON .. &&
|
||||||
- cov-analysis-linux64-*/bin/cov-build --dir cov-int make -j$(nproc)
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
- tar czf cov-int.tar.gz cov-int
|
|
||||||
- curl
|
|
||||||
--form token=$COVERITY_SCAN_TOKEN
|
|
||||||
--form email=$COVERITY_SCAN_EMAIL
|
|
||||||
--form file=@cov-int.tar.gz
|
|
||||||
--form version="`git describe --tags`"
|
|
||||||
--form description="CI build"
|
|
||||||
https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
|
|
||||||
tags:
|
tags:
|
||||||
- shared
|
- shared
|
||||||
only:
|
except:
|
||||||
refs:
|
- tags
|
||||||
- master
|
|
||||||
- schedules
|
|
||||||
variables:
|
|
||||||
- $COVERITY_SCAN_TOKEN != null
|
|
||||||
- $COVERITY_SCAN_PROJECT_NAME != null
|
|
||||||
- $COVERITY_SCAN_EMAIL != null
|
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- obj/cov-int/*.txt
|
- obj/
|
||||||
|
|
||||||
###############################################################################
|
fedora/mbedtls/x86-64:
|
||||||
# Codespell #
|
|
||||||
###############################################################################
|
|
||||||
codespell:
|
|
||||||
stage: review
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
|
||||||
script:
|
script:
|
||||||
- codespell --ignore-words-list=keypair,sorce,ned,nd,ue
|
- 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
|
||||||
|
-DPICKY_DEVELOPER=ON
|
||||||
|
-DWITH_MBEDTLS=ON .. &&
|
||||||
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
tags:
|
tags:
|
||||||
- shared
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
|
tumbleweed/openssl_1.1.x/x86-64:
|
||||||
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||||
|
script:
|
||||||
|
- mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
|
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
|
||||||
|
-DPICKY_DEVELOPER=ON
|
||||||
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||||
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
|
tumbleweed/openssl_1.1.x/x86-64/release:
|
||||||
|
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
|
||||||
|
-DPICKY_DEVELOPER=ON
|
||||||
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
|
||||||
|
make -j$(nproc) && ctest --output-on-failure
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
|
tumbleweed/docs:
|
||||||
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||||
|
script:
|
||||||
|
- mkdir -p obj && cd obj && cmake .. && make docs
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
|
tumbleweed/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
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
|
tumbleweed/static-analysis:
|
||||||
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||||
|
script:
|
||||||
|
- export CCC_CC=clang
|
||||||
|
- export CCC_CXX=clang++
|
||||||
|
- mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON --DWITH_PCAP=ON
|
||||||
|
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||||
|
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang .. &&
|
||||||
|
scan-build --status-bugs -o scan make -j$(nproc)
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/scan
|
||||||
|
|
||||||
|
# Unit testing only, no client and pkd testing, because cwrap is not available
|
||||||
|
# for MinGW
|
||||||
|
mingw64:
|
||||||
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||||
|
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
|
||||||
|
- 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
|
||||||
|
mingw32:
|
||||||
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
|
||||||
|
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
|
||||||
|
- 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=Debug
|
||||||
|
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
|
||||||
|
-DWITH_PCAP=ON .. && make -j$(nproc)
|
||||||
|
- ctest --output-on-failure -j$(nproc)
|
||||||
|
tags:
|
||||||
|
- shared
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
artifacts:
|
||||||
|
expire_in: 1 week
|
||||||
|
when: on_failure
|
||||||
|
paths:
|
||||||
|
- obj/
|
||||||
|
|
||||||
|
Debian.cross.mips-linux-gnu:
|
||||||
|
<<: *Debian_cross_template
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.3.0)
|
cmake_minimum_required(VERSION 3.3.0)
|
||||||
cmake_policy(SET CMP0048 NEW)
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
|
||||||
# Specify search path for CMake modules to be loaded by include()
|
# Specify search path for CMake modules to be loaded by include()
|
||||||
# and find_package()
|
# and find_package()
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
|||||||
include(DefineCMakeDefaults)
|
include(DefineCMakeDefaults)
|
||||||
include(DefineCompilerFlags)
|
include(DefineCompilerFlags)
|
||||||
|
|
||||||
project(libssh VERSION 0.10.6 LANGUAGES C)
|
project(libssh VERSION 0.8.3 LANGUAGES C)
|
||||||
|
|
||||||
# global needed variable
|
# global needed variable
|
||||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
@@ -22,16 +22,16 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
|||||||
# Increment AGE. Set REVISION to 0
|
# Increment AGE. Set REVISION to 0
|
||||||
# If the source code was changed, but there were no interface changes:
|
# If the source code was changed, but there were no interface changes:
|
||||||
# Increment REVISION.
|
# Increment REVISION.
|
||||||
set(LIBRARY_VERSION "4.9.6")
|
set(LIBRARY_VERSION "4.7.0")
|
||||||
set(LIBRARY_SOVERSION "4")
|
set(LIBRARY_SOVERSION "4")
|
||||||
|
|
||||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||||
|
|
||||||
# add definitions
|
# add definitions
|
||||||
include(DefinePlatformDefaults)
|
include(DefinePlatformDefaults)
|
||||||
|
include(DefineInstallationPaths)
|
||||||
include(DefineOptions.cmake)
|
include(DefineOptions.cmake)
|
||||||
include(CPackConfig.cmake)
|
include(CPackConfig.cmake)
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
include(CompilerChecks.cmake)
|
include(CompilerChecks.cmake)
|
||||||
|
|
||||||
@@ -39,9 +39,6 @@ include(CompilerChecks.cmake)
|
|||||||
include(MacroEnsureOutOfSourceBuild)
|
include(MacroEnsureOutOfSourceBuild)
|
||||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
||||||
|
|
||||||
# Copy library files to a lib sub-directory
|
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
||||||
|
|
||||||
# search for libraries
|
# search for libraries
|
||||||
if (WITH_ZLIB)
|
if (WITH_ZLIB)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
@@ -58,14 +55,8 @@ elseif(WITH_MBEDTLS)
|
|||||||
message(FATAL_ERROR "Could not find mbedTLS")
|
message(FATAL_ERROR "Could not find mbedTLS")
|
||||||
endif (NOT MBEDTLS_FOUND)
|
endif (NOT MBEDTLS_FOUND)
|
||||||
else (WITH_GCRYPT)
|
else (WITH_GCRYPT)
|
||||||
find_package(OpenSSL 1.0.1)
|
find_package(OpenSSL)
|
||||||
if (OPENSSL_FOUND)
|
if (NOT OPENSSL_FOUND)
|
||||||
# On CMake < 3.16, OPENSSL_CRYPTO_LIBRARIES is usually a synonym for OPENSSL_CRYPTO_LIBRARY, but is not defined
|
|
||||||
# when building on Windows outside of Cygwin. We provide the synonym here, if FindOpenSSL didn't define it already.
|
|
||||||
if (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
|
|
||||||
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
|
||||||
endif (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
|
|
||||||
else (OPENSSL_FOUND)
|
|
||||||
find_package(GCrypt)
|
find_package(GCrypt)
|
||||||
if (NOT GCRYPT_FOUND)
|
if (NOT GCRYPT_FOUND)
|
||||||
find_package(MbedTLS)
|
find_package(MbedTLS)
|
||||||
@@ -73,13 +64,9 @@ else (WITH_GCRYPT)
|
|||||||
message(FATAL_ERROR "Could not find OpenSSL, GCrypt or mbedTLS")
|
message(FATAL_ERROR "Could not find OpenSSL, GCrypt or mbedTLS")
|
||||||
endif (NOT MBEDTLS_FOUND)
|
endif (NOT MBEDTLS_FOUND)
|
||||||
endif (NOT GCRYPT_FOUND)
|
endif (NOT GCRYPT_FOUND)
|
||||||
endif (OPENSSL_FOUND)
|
endif (NOT OPENSSL_FOUND)
|
||||||
endif(WITH_GCRYPT)
|
endif(WITH_GCRYPT)
|
||||||
|
|
||||||
if (UNIT_TESTING)
|
|
||||||
find_package(CMocka REQUIRED)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# Find out if we have threading available
|
# Find out if we have threading available
|
||||||
set(CMAKE_THREAD_PREFER_PTHREADS ON)
|
set(CMAKE_THREAD_PREFER_PTHREADS ON)
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
@@ -89,13 +76,6 @@ if (WITH_GSSAPI)
|
|||||||
find_package(GSSAPI)
|
find_package(GSSAPI)
|
||||||
endif (WITH_GSSAPI)
|
endif (WITH_GSSAPI)
|
||||||
|
|
||||||
if (WITH_PKCS11_URI)
|
|
||||||
find_package(softhsm)
|
|
||||||
if (NOT SOFTHSM_FOUND)
|
|
||||||
message(SEND_ERROR "Could not find softhsm module!")
|
|
||||||
endif (NOT SOFTHSM_FOUND)
|
|
||||||
endif (WITH_PKCS11_URI)
|
|
||||||
|
|
||||||
if (WITH_NACL)
|
if (WITH_NACL)
|
||||||
find_package(NaCl)
|
find_package(NaCl)
|
||||||
if (NOT NACL_FOUND)
|
if (NOT NACL_FOUND)
|
||||||
@@ -103,7 +83,9 @@ if (WITH_NACL)
|
|||||||
endif (NOT NACL_FOUND)
|
endif (NOT NACL_FOUND)
|
||||||
endif (WITH_NACL)
|
endif (WITH_NACL)
|
||||||
|
|
||||||
find_package(Argp)
|
if (BSD OR SOLARIS OR OSX)
|
||||||
|
find_package(Argp)
|
||||||
|
endif (BSD OR SOLARIS OR OSX)
|
||||||
|
|
||||||
# Disable symbol versioning in non UNIX platforms
|
# Disable symbol versioning in non UNIX platforms
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
@@ -122,43 +104,45 @@ add_subdirectory(include)
|
|||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
# pkg-config file
|
# pkg-config file
|
||||||
if (UNIX OR MINGW)
|
if (UNIX)
|
||||||
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc @ONLY)
|
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||||
DESTINATION
|
DESTINATION
|
||||||
${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
${LIB_INSTALL_DIR}/pkgconfig
|
||||||
COMPONENT
|
COMPONENT
|
||||||
pkgconfig
|
pkgconfig
|
||||||
)
|
)
|
||||||
endif (UNIX OR MINGW)
|
endif (UNIX)
|
||||||
|
|
||||||
# CMake config files
|
|
||||||
include(CMakePackageConfigHelpers)
|
|
||||||
|
|
||||||
|
# cmake config files
|
||||||
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||||
|
|
||||||
# libssh-config-version.cmake
|
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
|
||||||
write_basic_package_version_file(libssh-config-version.cmake
|
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
|
||||||
VERSION ${PROJECT_VERSION}
|
|
||||||
COMPATIBILITY SameMajorVersion)
|
|
||||||
|
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
|
||||||
DESTINATION
|
DESTINATION
|
||||||
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||||
COMPONENT
|
COMPONENT
|
||||||
devel)
|
devel
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# in tree build settings
|
||||||
|
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
|
||||||
|
|
||||||
if (WITH_EXAMPLES)
|
if (WITH_EXAMPLES)
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
endif (WITH_EXAMPLES)
|
endif (WITH_EXAMPLES)
|
||||||
|
|
||||||
if (UNIT_TESTING)
|
if (UNIT_TESTING)
|
||||||
include(AddCMockaTest)
|
find_package(CMocka REQUIRED)
|
||||||
add_subdirectory(tests)
|
include(AddCMockaTest)
|
||||||
|
add_subdirectory(tests)
|
||||||
endif (UNIT_TESTING)
|
endif (UNIT_TESTING)
|
||||||
|
|
||||||
### SOURCE PACKAGE
|
### SOURCE PACKAGE
|
||||||
@@ -214,12 +198,7 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
|
|||||||
endif(UPDATE_ABI)
|
endif(UPDATE_ABI)
|
||||||
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
|
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
|
||||||
|
|
||||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET} VERBATIM)
|
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET})
|
||||||
|
|
||||||
# Link compile database for clangd
|
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
|
|
||||||
"${CMAKE_BINARY_DIR}/compile_commands.json"
|
|
||||||
"${CMAKE_SOURCE_DIR}/compile_commands.json")
|
|
||||||
|
|
||||||
message(STATUS "********************************************")
|
message(STATUS "********************************************")
|
||||||
message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
||||||
@@ -231,15 +210,10 @@ message(STATUS "libnacl support: ${WITH_NACL}")
|
|||||||
message(STATUS "SFTP support: ${WITH_SFTP}")
|
message(STATUS "SFTP support: ${WITH_SFTP}")
|
||||||
message(STATUS "Server support : ${WITH_SERVER}")
|
message(STATUS "Server support : ${WITH_SERVER}")
|
||||||
message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
|
message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
|
||||||
message(STATUS "GEX support : ${WITH_GEX}")
|
|
||||||
message(STATUS "Support insecure none cipher and MAC : ${WITH_INSECURE_NONE}")
|
|
||||||
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
|
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
|
||||||
message(STATUS "Build shared library: ${BUILD_SHARED_LIBS}")
|
message(STATUS "With static library: ${WITH_STATIC_LIB}")
|
||||||
message(STATUS "Unit testing: ${UNIT_TESTING}")
|
message(STATUS "Unit testing: ${UNIT_TESTING}")
|
||||||
message(STATUS "Client code testing: ${CLIENT_TESTING}")
|
message(STATUS "Client code testing: ${CLIENT_TESTING}")
|
||||||
message(STATUS "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
|
|
||||||
message(STATUS "PKCS #11 URI support: ${WITH_PKCS11_URI}")
|
|
||||||
message(STATUS "DSA support: ${WITH_DSA}")
|
|
||||||
set(_SERVER_TESTING OFF)
|
set(_SERVER_TESTING OFF)
|
||||||
if (WITH_SERVER)
|
if (WITH_SERVER)
|
||||||
set(_SERVER_TESTING ${SERVER_TESTING})
|
set(_SERVER_TESTING ${SERVER_TESTING})
|
||||||
@@ -254,9 +228,5 @@ message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
|
|||||||
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
|
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
|
||||||
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
|
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
|
||||||
message(STATUS "Release is final: ${WITH_FINAL}")
|
message(STATUS "Release is final: ${WITH_FINAL}")
|
||||||
message(STATUS "Global client config: ${GLOBAL_CLIENT_CONFIG}")
|
|
||||||
if (WITH_SERVER)
|
|
||||||
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
|
|
||||||
endif()
|
|
||||||
message(STATUS "********************************************")
|
message(STATUS "********************************************")
|
||||||
|
|
||||||
|
|||||||
13
COPYING
13
COPYING
@@ -455,15 +455,6 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
DAMAGES.
|
DAMAGES.
|
||||||
|
|
||||||
Linking with OpenSSL
|
Linking with OpenSSL
|
||||||
|
17. In addition, as a special exception, we give permission to link the code of its release of libssh with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Lesser General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
|
||||||
17. In addition, as a special exception, we give permission to link the code
|
|
||||||
of its release of libssh with the OpenSSL project's "OpenSSL" library (or with
|
|
||||||
modified versions of it that use the same license as the "OpenSSL" library),
|
|
||||||
and distribute the linked executables. You must obey the GNU Lesser General
|
|
||||||
Public License in all respects for all of the code used other than "OpenSSL".
|
|
||||||
If you modify this file, you may extend this exception to your version of the
|
|
||||||
file, but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
this exception statement from your version.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
|||||||
|
|
||||||
# SOURCE GENERATOR
|
# SOURCE GENERATOR
|
||||||
set(CPACK_SOURCE_GENERATOR "TXZ")
|
set(CPACK_SOURCE_GENERATOR "TXZ")
|
||||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git;/[.]clangd/;/[.]cache/;.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}")
|
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||||
|
|
||||||
### NSIS INSTALLER
|
### NSIS INSTALLER
|
||||||
@@ -23,7 +23,7 @@ if (WIN32)
|
|||||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
|
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
|
||||||
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||||
set(CPACK_NSIS_MENU_LINKS "https://www.libssh.org/" "libssh homepage")
|
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||||
endif (NSIS_MAKE)
|
endif (NSIS_MAKE)
|
||||||
endif (WIN32)
|
endif (WIN32)
|
||||||
|
|
||||||
|
|||||||
@@ -1,165 +1,36 @@
|
|||||||
CHANGELOG
|
ChangeLog
|
||||||
=========
|
==========
|
||||||
version 0.10.6 (released 2023-12-18)
|
|
||||||
* Fix CVE-2023-6004: Command injection using proxycommand
|
|
||||||
* Fix CVE-2023-48795: Potential downgrade attack using strict kex
|
|
||||||
* Fix CVE-2023-6918: Missing checks for return values of MD functions
|
|
||||||
* Fix ssh_send_issue_banner() for CMD(PowerShell)
|
|
||||||
* Avoid passing other events to callbacks when poll is called recursively (#202)
|
|
||||||
* Allow @ in usernames when parsing from URI composes
|
|
||||||
|
|
||||||
version 0.10.5 (released 2023-05-04)
|
version 0.8.3 (released 2018-09-21)
|
||||||
* Fix CVE-2023-1667: a NULL dereference during rekeying with algorithm guessing
|
* Added support for rsa-sha2
|
||||||
* Fix CVE-2023-2283: a possible authorization bypass in
|
* Added support to parse private keys in openssh container format
|
||||||
pki_verify_data_signature under low-memory conditions.
|
(other than ed25519)
|
||||||
* Fix several memory leaks in GSSAPI handling code
|
* Added support for diffie-hellman-group18-sha512 and
|
||||||
* Escape braces in ProxyCommand created from ProxyJump options for zsh
|
diffie-hellman-group16-sha512
|
||||||
compatibility.
|
* Added ssh_get_fingerprint_hash()
|
||||||
* Fix pkg-config path relocation for MinGW
|
* Added ssh_pki_export_privkey_base64()
|
||||||
* Improve doxygen documentation
|
* Added support for Match keyword in config file
|
||||||
* Fix build with cygwin due to the glob support
|
* Improved performance and reduced memory footprint for sftp
|
||||||
* Do not enqueue outgoing packets after sending SSH2_MSG_NEWKEYS
|
* Fixed ecdsa publickey auth
|
||||||
* Add support for SSH_SUPPRESS_DEPRECATED
|
* Fixed reading a closed channel
|
||||||
* Avoid functions declarations without prototype to build with clang 15
|
* Added support to announce posix-rename@openssh.com and
|
||||||
* Fix spelling issues
|
hardlink@openssh.com in the sftp server
|
||||||
* Avoid expanding KnownHosts, ProxyCommands and IdentityFiles repetitively
|
|
||||||
* Add support sk-* keys through configuration
|
|
||||||
* Improve checking for Argp library
|
|
||||||
* Log information about received extensions
|
|
||||||
* Correctly handle rekey with delayed compression
|
|
||||||
* Move the EC keys handling to OpenSSL 3.0 API
|
|
||||||
* Record peer disconnect message
|
|
||||||
* Avoid deadlock when write buffering occurs and we call poll recursively to
|
|
||||||
flush the output buffer
|
|
||||||
* Disable preauthentication compression by default
|
|
||||||
* Add CentOS 8 Stream / OpenSSL 1.1.1 to CI
|
|
||||||
* Add accidentally removed default compile flags
|
|
||||||
* Solve incorrect parsing of ProxyCommand option
|
|
||||||
|
|
||||||
version 0.10.4 (released 2022-09-07)
|
version 0.8.2 (released 2018-08-30)
|
||||||
* Fixed issues with KDF on big endian
|
* 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.10.3 (released 2022-09-05)
|
version 0.8.1 (released 2018-08-13)
|
||||||
* Fixed possible infinite loop in known hosts checking
|
* Fixed version number in the header
|
||||||
|
* Fixed version number in pkg-config and cmake config
|
||||||
version 0.10.2 (released 2022-09-02)
|
* Fixed library initialization
|
||||||
* Fixed tilde expansion when handling include directives
|
* Fixed attribute detection
|
||||||
* Fixed building the shared torture library
|
|
||||||
* Made rekey test more robust (fixes running on i586 build systems e.g koji)
|
|
||||||
|
|
||||||
version 0.10.1 (released 2022-08-30)
|
|
||||||
* Fixed proxycommand support
|
|
||||||
* Fixed musl libc support
|
|
||||||
|
|
||||||
version 0.10.0 (released 2022-08-26)
|
|
||||||
* Added support for OpenSSL 3.0
|
|
||||||
* Added support for mbedTLS 3
|
|
||||||
* Added support for Smart Cards (through openssl pkcs11 engine)
|
|
||||||
* Added support for chacha20-poly1305@openssh.com with libgcrypt
|
|
||||||
* Added support ed25519 keys in PEM files
|
|
||||||
* Added support for sk-ecdsa and sk-ed25519 (server side)
|
|
||||||
* Added support for limiting RSA key sizes and not accepting small one by
|
|
||||||
default
|
|
||||||
* Added support for ssh-agent on Windows
|
|
||||||
* Added ssh_userauth_publickey_auto_get_current_identity() API
|
|
||||||
* Added ssh_vlog() API
|
|
||||||
* Added ssh_send_issue_banner() API
|
|
||||||
* Added ssh_session_set_disconnect_message() API
|
|
||||||
* Added new configuration options:
|
|
||||||
+ IdentityAgent
|
|
||||||
+ ModuliFile
|
|
||||||
* Provided X11 client example
|
|
||||||
* Disabled DSA support at build time by default (will be removed in the next
|
|
||||||
release)
|
|
||||||
* Deprecated the SCP API!
|
|
||||||
* Deprecated old pubkey, privatekey API
|
|
||||||
* Avoided some needless large stack buffers to minimize memory footprint
|
|
||||||
* Removed support for OpenSSL < 1.0.1
|
|
||||||
* Fixed parsing username@host in login name
|
|
||||||
* Free global init mutex in the destructor on Windows
|
|
||||||
* Fixed PEM parsing in mbedtls to support both legacy and new PKCS8 formats
|
|
||||||
|
|
||||||
version 0.9.6 (released 2021-08-26)
|
|
||||||
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with
|
|
||||||
different key exchange mechanism
|
|
||||||
* Fix several memory leaks on error paths
|
|
||||||
* Reset pending_call_state on disconnect
|
|
||||||
* Fix handshake bug with AEAD ciphers and no HMAC overlap
|
|
||||||
* Use OPENSSL_CRYPTO_LIBRARIES in CMake
|
|
||||||
* Ignore request success and failure message if they are not expected
|
|
||||||
* Support more identity files in configuration
|
|
||||||
* Avoid setting compiler flags directly in CMake
|
|
||||||
* Support build directories with special characters
|
|
||||||
* Include stdlib.h to avoid crash in Windows
|
|
||||||
* Fix sftp_new_channel constructs an invalid object
|
|
||||||
* Fix Ninja multiple rules error
|
|
||||||
* Several tests fixes
|
|
||||||
|
|
||||||
version 0.9.5 (released 2020-09-10)
|
|
||||||
* CVE-2020-16135: Avoid null pointer dereference in sftpserver (T232)
|
|
||||||
* Improve handling of library initialization (T222)
|
|
||||||
* Fix parsing of subsecond times in SFTP (T219)
|
|
||||||
* Make the documentation reproducible
|
|
||||||
* Remove deprecated API usage in OpenSSL
|
|
||||||
* Fix regression of ssh_channel_poll_timeout() returning SSH_AGAIN
|
|
||||||
* Define version in one place (T226)
|
|
||||||
* Prevent invalid free when using different C runtimes than OpenSSL (T229)
|
|
||||||
* Compatibility improvements to testsuite
|
|
||||||
|
|
||||||
version 0.9.4 (released 2020-04-09)
|
|
||||||
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
|
|
||||||
AES-CTR keys with OpenSSL
|
|
||||||
* Added diffie-hellman-group14-sha256
|
|
||||||
* Fixed several possible memory leaks
|
|
||||||
|
|
||||||
version 0.9.3 (released 2019-12-10)
|
|
||||||
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
|
|
||||||
* SSH-01-003 Client: Missing NULL check leads to crash in erroneous state
|
|
||||||
* SSH-01-006 General: Various unchecked Null-derefs cause DOS
|
|
||||||
* SSH-01-007 PKI Gcrypt: Potential UAF/double free with RSA pubkeys
|
|
||||||
* SSH-01-010 SSH: Deprecated hash function in fingerprinting
|
|
||||||
* SSH-01-013 Conf-Parsing: Recursive wildcards in hostnames lead to DOS
|
|
||||||
* SSH-01-014 Conf-Parsing: Integer underflow leads to OOB array access
|
|
||||||
* SSH-01-001 State Machine: Initial machine states should be set explicitly
|
|
||||||
* SSH-01-002 Kex: Differently bound macros used to iterate same array
|
|
||||||
* SSH-01-005 Code-Quality: Integer sign confusion during assignments
|
|
||||||
* SSH-01-008 SCP: Protocol Injection via unescaped File Names
|
|
||||||
* SSH-01-009 SSH: Update documentation which RFCs are implemented
|
|
||||||
* SSH-01-012 PKI: Information leak via uninitialized stack buffer
|
|
||||||
|
|
||||||
version 0.9.2 (released 2019-11-07)
|
|
||||||
* Fixed libssh-config.cmake
|
|
||||||
* Fixed issues with rsa algorithm negotiation (T191)
|
|
||||||
* Fixed detection of OpenSSL ed25519 support (T197)
|
|
||||||
|
|
||||||
version 0.9.1 (released 2019-10-25)
|
|
||||||
* Added support for Ed25519 via OpenSSL
|
|
||||||
* Added support for X25519 via OpenSSL
|
|
||||||
* Added support for localuser in Match keyword
|
|
||||||
* Fixed Match keyword to be case sensitive
|
|
||||||
* Fixed compilation with LibreSSL
|
|
||||||
* Fixed error report of channel open (T75)
|
|
||||||
* Fixed sftp documentation (T137)
|
|
||||||
* Fixed known_hosts parsing (T156)
|
|
||||||
* Fixed build issue with MinGW (T157)
|
|
||||||
* Fixed build with gcc 9 (T164)
|
|
||||||
* Fixed deprecation issues (T165)
|
|
||||||
* Fixed known_hosts directory creation (T166)
|
|
||||||
|
|
||||||
version 0.9.0 (released 2019-02-xx)
|
|
||||||
* Added support for AES-GCM
|
|
||||||
* Added improved rekeying support
|
|
||||||
* Added performance improvements
|
|
||||||
* Disabled blowfish support by default
|
|
||||||
* Fixed several ssh config parsing issues
|
|
||||||
* Added support for DH Group Exchange KEX
|
|
||||||
* Added support for Encrypt-then-MAC mode
|
|
||||||
* Added support for parsing server side configuration file
|
|
||||||
* Added support for ECDSA/Ed25519 certificates
|
|
||||||
* Added FIPS 140-2 compatibility
|
|
||||||
* Improved known_hosts parsing
|
|
||||||
* Improved documentation
|
|
||||||
* Improved OpenSSL API usage for KEX, DH, and signatures
|
|
||||||
|
|
||||||
version 0.8.0 (released 2018-08-10)
|
version 0.8.0 (released 2018-08-10)
|
||||||
* Removed support for deprecated SSHv1 protocol
|
* Removed support for deprecated SSHv1 protocol
|
||||||
@@ -261,7 +132,7 @@ version 0.6.1 (released 2014-02-08)
|
|||||||
* Fixed DSA signature extraction.
|
* Fixed DSA signature extraction.
|
||||||
* Fixed some memory leaks.
|
* Fixed some memory leaks.
|
||||||
* Fixed read of non-connected socket.
|
* Fixed read of non-connected socket.
|
||||||
* Fixed thread detection.
|
* Fixed thread dectection.
|
||||||
|
|
||||||
version 0.6.0 (released 2014-01-08)
|
version 0.6.0 (released 2014-01-08)
|
||||||
* Added new publicy key API.
|
* Added new publicy key API.
|
||||||
@@ -286,7 +157,7 @@ version 0.6.0 (released 2014-01-08)
|
|||||||
version 0.5.5 (released 2013-07-26)
|
version 0.5.5 (released 2013-07-26)
|
||||||
* BUG 103: Fix ProxyCommand parsing.
|
* BUG 103: Fix ProxyCommand parsing.
|
||||||
* Fix setting -D_FORTIFY_SOURCE=2.
|
* Fix setting -D_FORTIFY_SOURCE=2.
|
||||||
* Fix pollset error return if empty.
|
* Fix pollset error return if emtpy.
|
||||||
* Fix NULL pointer checks in channel functions.
|
* Fix NULL pointer checks in channel functions.
|
||||||
* Several bugfixes.
|
* Several bugfixes.
|
||||||
|
|
||||||
@@ -302,7 +173,7 @@ version 0.5.3 (released 2012-11-20)
|
|||||||
* BUG #84 - Fix bug in sftp_mkdir not returning on error.
|
* BUG #84 - Fix bug in sftp_mkdir not returning on error.
|
||||||
* BUG #85 - Fixed a possible channel infinite loop if the connection dropped.
|
* BUG #85 - Fixed a possible channel infinite loop if the connection dropped.
|
||||||
* BUG #88 - Added missing channel request_state and set it to accepted.
|
* BUG #88 - Added missing channel request_state and set it to accepted.
|
||||||
* BUG #89 - Reset error state to no error on successful SSHv1 authentication.
|
* BUG #89 - Reset error state to no error on successful SSHv1 authentiction.
|
||||||
* Fixed a possible use after free in ssh_free().
|
* Fixed a possible use after free in ssh_free().
|
||||||
* Fixed multiple possible NULL pointer dereferences.
|
* Fixed multiple possible NULL pointer dereferences.
|
||||||
* Fixed multiple memory leaks in error paths.
|
* Fixed multiple memory leaks in error paths.
|
||||||
@@ -363,7 +234,7 @@ version 0.4.7 (released 2010-12-28)
|
|||||||
* Fixed a possible memory leak in ssh_get_user_home().
|
* Fixed a possible memory leak in ssh_get_user_home().
|
||||||
* Fixed a memory leak in sftp_xstat.
|
* Fixed a memory leak in sftp_xstat.
|
||||||
* Fixed uninitialized fd->revents member.
|
* Fixed uninitialized fd->revents member.
|
||||||
* Fixed timeout value in ssh_channel_accept().
|
* Fixed timout value in ssh_channel_accept().
|
||||||
* Fixed length checks in ssh_analyze_banner().
|
* Fixed length checks in ssh_analyze_banner().
|
||||||
* Fixed a possible data overread and crash bug.
|
* Fixed a possible data overread and crash bug.
|
||||||
* Fixed setting max_fd which breaks ssh_select().
|
* Fixed setting max_fd which breaks ssh_select().
|
||||||
@@ -386,7 +257,7 @@ version 0.4.5 (released 2010-07-13)
|
|||||||
* Added option to bind a client to an ip address.
|
* Added option to bind a client to an ip address.
|
||||||
* Fixed the ssh socket polling function.
|
* Fixed the ssh socket polling function.
|
||||||
* Fixed Windows related bugs in bsd_poll().
|
* Fixed Windows related bugs in bsd_poll().
|
||||||
* Fixed several build warnings.
|
* Fixed serveral build warnings.
|
||||||
|
|
||||||
version 0.4.4 (released 2010-06-01)
|
version 0.4.4 (released 2010-06-01)
|
||||||
* Fixed a bug in the expand function for escape sequences.
|
* Fixed a bug in the expand function for escape sequences.
|
||||||
@@ -405,17 +276,17 @@ version 0.4.3 (released 2010-05-18)
|
|||||||
* Fixed sftp_chown.
|
* Fixed sftp_chown.
|
||||||
* Fixed sftp_rename on protocol version 3.
|
* Fixed sftp_rename on protocol version 3.
|
||||||
* Fixed a blocking bug in channel_poll.
|
* Fixed a blocking bug in channel_poll.
|
||||||
* Fixed config parsing which has overwritten user specified values.
|
* Fixed config parsing wich has overwritten user specified values.
|
||||||
* Fixed hashed [host]:port format in knownhosts
|
* Fixed hashed [host]:port format in knownhosts
|
||||||
* Fixed Windows build.
|
* Fixed Windows build.
|
||||||
* Fixed doublefree happening after a negotiation error.
|
* Fixed doublefree happening after a negociation error.
|
||||||
* Fixed aes*-ctr with <= OpenSSL 0.9.7b.
|
* Fixed aes*-ctr with <= OpenSSL 0.9.7b.
|
||||||
* Fixed some documentation.
|
* Fixed some documentation.
|
||||||
* Fixed exec example which has broken read usage.
|
* Fixed exec example which has broken read usage.
|
||||||
* Fixed broken algorithm choice for server.
|
* Fixed broken algorithm choice for server.
|
||||||
* Fixed a typo that we don't export all symbols.
|
* Fixed a typo that we don't export all symbols.
|
||||||
* Removed the unneeded dependency to doxygen.
|
* Removed the unneeded dependency to doxygen.
|
||||||
* Build examples only on the Linux platform.
|
* Build examples only on the Linux plattform.
|
||||||
|
|
||||||
version 0.4.2 (released 2010-03-15)
|
version 0.4.2 (released 2010-03-15)
|
||||||
* Added owner and group information in sftp attributes.
|
* Added owner and group information in sftp attributes.
|
||||||
@@ -437,7 +308,7 @@ version 0.4.1 (released 2010-02-13)
|
|||||||
* Added an example for exec.
|
* Added an example for exec.
|
||||||
* Added private key type detection feature in privatekey_from_file().
|
* Added private key type detection feature in privatekey_from_file().
|
||||||
* Fixed zlib compression fallback.
|
* Fixed zlib compression fallback.
|
||||||
* Fixed kex bug that client preference should be priority
|
* Fixed kex bug that client preference should be prioritary
|
||||||
* Fixed known_hosts file set by the user.
|
* Fixed known_hosts file set by the user.
|
||||||
* Fixed a memleak in channel_accept().
|
* Fixed a memleak in channel_accept().
|
||||||
* Fixed underflow when leave_function() are unbalanced
|
* Fixed underflow when leave_function() are unbalanced
|
||||||
@@ -495,6 +366,14 @@ version 0.3.2 (released 2009-08-05)
|
|||||||
* Fixed compilation on Solaris.
|
* Fixed compilation on Solaris.
|
||||||
* Fixed SSHv1 compilation.
|
* Fixed SSHv1 compilation.
|
||||||
|
|
||||||
|
version 0.3.1 (released 2009-07-14)
|
||||||
|
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||||
|
* Fixed compilation of SSHv1.
|
||||||
|
* Fixed several memory leaks.
|
||||||
|
* Fixed possible infinite loops.
|
||||||
|
* Fixed a possible crash bug.
|
||||||
|
* Fixed build warnings.
|
||||||
|
* Fixed cmake on BSD.
|
||||||
version 0.3.1 (released 2009-07-14)
|
version 0.3.1 (released 2009-07-14)
|
||||||
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||||
* Fixed compilation of SSHv1.
|
* Fixed compilation of SSHv1.
|
||||||
@@ -544,7 +423,7 @@ version 0.2 (released 2007-11-29)
|
|||||||
version 0.11-dev
|
version 0.11-dev
|
||||||
* Server implementation development.
|
* Server implementation development.
|
||||||
* Small bug corrected when connecting to sun ssh servers.
|
* Small bug corrected when connecting to sun ssh servers.
|
||||||
* Channel weirdness corrected (writing huge data packets)
|
* Channel wierdness corrected (writing huge data packets)
|
||||||
* Channel_read_nonblocking added
|
* Channel_read_nonblocking added
|
||||||
* Channel bug where stderr wasn't correctly read fixed.
|
* Channel bug where stderr wasn't correctly read fixed.
|
||||||
* Added sftp_file_set_nonblocking(), which is nonblocking SFTP IO
|
* Added sftp_file_set_nonblocking(), which is nonblocking SFTP IO
|
||||||
@@ -575,7 +454,7 @@ version 0.11-dev
|
|||||||
* Keyboard-interactive authentication working.
|
* Keyboard-interactive authentication working.
|
||||||
|
|
||||||
version 0.1 (released 2004-03-05)
|
version 0.1 (released 2004-03-05)
|
||||||
* Beginning of sftp subsystem implementation.
|
* Begining of sftp subsystem implementation.
|
||||||
* Some cleanup into channels implementation
|
* Some cleanup into channels implementation
|
||||||
* Now every channel functions is called by its CHANNEL handler.
|
* Now every channel functions is called by its CHANNEL handler.
|
||||||
* Added channel_poll() and channel_read().
|
* Added channel_poll() and channel_read().
|
||||||
@@ -596,7 +475,7 @@ version 0.0.4 (released 2003-10-10)
|
|||||||
* Added a wrapper.c file. The goal is to provide a similar API to every
|
* Added a wrapper.c file. The goal is to provide a similar API to every
|
||||||
cryptographic functions. bignums and sha/md5 are wrapped now.
|
cryptographic functions. bignums and sha/md5 are wrapped now.
|
||||||
* More work than it first looks.
|
* More work than it first looks.
|
||||||
* Support for other crypto libs planned (lighter libs)
|
* Support for other crypto libs planed (lighter libs)
|
||||||
* Fixed stupid select() bug.
|
* Fixed stupid select() bug.
|
||||||
* Libssh now compiles and links with openssl 0.9.6
|
* Libssh now compiles and links with openssl 0.9.6
|
||||||
* RSA pubkey authentication code now works !
|
* RSA pubkey authentication code now works !
|
||||||
@@ -41,8 +41,6 @@ if (UNIX)
|
|||||||
add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS)
|
add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS)
|
||||||
add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
|
add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
|
||||||
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
|
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
|
||||||
add_c_compiler_flag("-Wmissing-field-initializers" SUPPORTED_COMPILER_FLAGS)
|
|
||||||
add_c_compiler_flag("-Wsign-compare" SUPPORTED_COMPILER_FLAGS)
|
|
||||||
|
|
||||||
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
|
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
|
||||||
if (REQUIRED_FLAGS_WFORMAT)
|
if (REQUIRED_FLAGS_WFORMAT)
|
||||||
@@ -53,10 +51,7 @@ if (UNIX)
|
|||||||
add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS)
|
add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS)
|
||||||
|
|
||||||
# Allow zero for a variadic macro argument
|
# Allow zero for a variadic macro argument
|
||||||
string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID)
|
add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
|
||||||
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)
|
add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS)
|
||||||
|
|
||||||
@@ -70,26 +65,16 @@ if (UNIX)
|
|||||||
check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG)
|
check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG)
|
||||||
if (WITH_STACK_PROTECTOR_STRONG)
|
if (WITH_STACK_PROTECTOR_STRONG)
|
||||||
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong")
|
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong")
|
||||||
# This is needed as Solaris has a separate libssp
|
|
||||||
if (SOLARIS)
|
|
||||||
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong")
|
|
||||||
endif()
|
|
||||||
else (WITH_STACK_PROTECTOR_STRONG)
|
else (WITH_STACK_PROTECTOR_STRONG)
|
||||||
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
|
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||||
if (WITH_STACK_PROTECTOR)
|
if (WITH_STACK_PROTECTOR)
|
||||||
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector")
|
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector")
|
||||||
# This is needed as Solaris has a separate libssp
|
|
||||||
if (SOLARIS)
|
|
||||||
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
endif (WITH_STACK_PROTECTOR_STRONG)
|
endif (WITH_STACK_PROTECTOR_STRONG)
|
||||||
|
|
||||||
if (NOT WINDOWS AND NOT CYGWIN)
|
check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION)
|
||||||
check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION)
|
if (WITH_STACK_CLASH_PROTECTION)
|
||||||
if (WITH_STACK_CLASH_PROTECTION)
|
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection")
|
||||||
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (PICKY_DEVELOPER)
|
if (PICKY_DEVELOPER)
|
||||||
@@ -97,8 +82,6 @@ if (UNIX)
|
|||||||
add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS)
|
add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_c_compiler_flag("-Wno-deprecated-declarations" DEPRECATION_COMPILER_FLAGS)
|
|
||||||
|
|
||||||
# Unset CMAKE_REQUIRED_FLAGS
|
# Unset CMAKE_REQUIRED_FLAGS
|
||||||
unset(CMAKE_REQUIRED_FLAGS)
|
unset(CMAKE_REQUIRED_FLAGS)
|
||||||
endif()
|
endif()
|
||||||
@@ -117,8 +100,3 @@ if (OSX)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE)
|
set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE)
|
||||||
set(DEFAULT_LINK_FLAGS ${SUPPORTED_LINKER_FLAGS} CACHE INTERNAL "Default C Linker Flags" FORCE)
|
|
||||||
|
|
||||||
if (DEPRECATION_COMPILER_FLAGS)
|
|
||||||
set(DEFAULT_C_NO_DEPRECATION_FLAGS ${DEPRECATION_COMPILER_FLAGS} CACHE INTERNAL "Default no deprecation flags" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ include(TestBigEndian)
|
|||||||
|
|
||||||
set(PACKAGE ${PROJECT_NAME})
|
set(PACKAGE ${PROJECT_NAME})
|
||||||
set(VERSION ${PROJECT_VERSION})
|
set(VERSION ${PROJECT_VERSION})
|
||||||
set(SYSCONFDIR ${CMAKE_INSTALL_SYSCONFDIR})
|
set(DATADIR ${DATA_INSTALL_DIR})
|
||||||
|
set(LIBDIR ${LIB_INSTALL_DIR})
|
||||||
|
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||||
|
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||||
|
|
||||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
||||||
@@ -61,7 +64,6 @@ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
|
|||||||
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
|
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
|
||||||
check_include_file(byteswap.h HAVE_BYTESWAP_H)
|
check_include_file(byteswap.h HAVE_BYTESWAP_H)
|
||||||
check_include_file(glob.h HAVE_GLOB_H)
|
check_include_file(glob.h HAVE_GLOB_H)
|
||||||
check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H)
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
check_include_file(io.h HAVE_IO_H)
|
check_include_file(io.h HAVE_IO_H)
|
||||||
@@ -86,10 +88,8 @@ if (OPENSSL_FOUND)
|
|||||||
message(FATAL_ERROR "Could not detect openssl/aes.h")
|
message(FATAL_ERROR "Could not detect openssl/aes.h")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WITH_BLOWFISH_CIPHER)
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
||||||
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
|
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
|
||||||
@@ -101,52 +101,29 @@ if (OPENSSL_FOUND)
|
|||||||
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
|
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
|
check_function_exists(EVP_aes_128_ctr HAVE_OPENSSL_EVP_AES_CTR)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
check_function_exists(EVP_KDF_CTX_new HAVE_OPENSSL_EVP_KDF_CTX_NEW)
|
check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
|
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
|
check_function_exists(CRYPTO_ctr128_encrypt HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
|
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
|
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
check_function_exists(EVP_DigestSign HAVE_OPENSSL_EVP_DIGESTSIGN)
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
check_function_exists(EVP_DigestVerify HAVE_OPENSSL_EVP_DIGESTVERIFY)
|
|
||||||
|
|
||||||
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
check_symbol_exists(EVP_PKEY_ED25519 "openssl/evp.h" FOUND_OPENSSL_ED25519)
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
check_function_exists(EVP_chacha20 HAVE_OPENSSL_EVP_CHACHA20)
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
check_symbol_exists(EVP_PKEY_POLY1305 "openssl/evp.h" HAVE_OPENSSL_EVP_POLY1305)
|
|
||||||
|
|
||||||
if (HAVE_OPENSSL_EVP_DIGESTSIGN AND HAVE_OPENSSL_EVP_DIGESTVERIFY AND
|
|
||||||
FOUND_OPENSSL_ED25519)
|
|
||||||
set(HAVE_OPENSSL_ED25519 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
check_symbol_exists(EVP_PKEY_X25519 "openssl/evp.h" HAVE_OPENSSL_X25519)
|
|
||||||
|
|
||||||
unset(CMAKE_REQUIRED_INCLUDES)
|
unset(CMAKE_REQUIRED_INCLUDES)
|
||||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||||
endif()
|
endif()
|
||||||
@@ -163,18 +140,11 @@ if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS)
|
|||||||
if (HAVE_OPENSSL_ECC)
|
if (HAVE_OPENSSL_ECC)
|
||||||
set(HAVE_ECC 1)
|
set(HAVE_ECC 1)
|
||||||
endif (HAVE_OPENSSL_ECC)
|
endif (HAVE_OPENSSL_ECC)
|
||||||
|
|
||||||
if (HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID OR HAVE_OPENSSL_EVP_KDF_CTX_NEW)
|
|
||||||
set(HAVE_OPENSSL_EVP_KDF_CTX 1)
|
|
||||||
endif (HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID OR HAVE_OPENSSL_EVP_KDF_CTX_NEW)
|
|
||||||
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (WITH_DSA)
|
if (NOT WITH_MBEDTLS)
|
||||||
if (NOT WITH_MBEDTLS)
|
set(HAVE_DSA 1)
|
||||||
set(HAVE_DSA 1)
|
endif (NOT WITH_MBEDTLS)
|
||||||
endif (NOT WITH_MBEDTLS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# FUNCTIONS
|
# FUNCTIONS
|
||||||
|
|
||||||
@@ -273,34 +243,17 @@ if (GCRYPT_FOUND)
|
|||||||
set(HAVE_GCRYPT_ECC 1)
|
set(HAVE_GCRYPT_ECC 1)
|
||||||
set(HAVE_ECC 1)
|
set(HAVE_ECC 1)
|
||||||
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
|
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
|
||||||
if (NOT GCRYPT_VERSION VERSION_LESS "1.7.0")
|
|
||||||
set(HAVE_GCRYPT_CHACHA_POLY 1)
|
|
||||||
endif (NOT GCRYPT_VERSION VERSION_LESS "1.7.0")
|
|
||||||
endif (GCRYPT_FOUND)
|
endif (GCRYPT_FOUND)
|
||||||
|
|
||||||
if (MBEDTLS_FOUND)
|
if (MBEDTLS_FOUND)
|
||||||
set(HAVE_LIBMBEDCRYPTO 1)
|
set(HAVE_LIBMBEDCRYPTO 1)
|
||||||
set(HAVE_ECC 1)
|
set(HAVE_ECC 1)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIR}/mbedtls")
|
|
||||||
check_include_file(chacha20.h HAVE_MBEDTLS_CHACHA20_H)
|
|
||||||
check_include_file(poly1305.h HAVE_MBEDTLS_POLY1305_H)
|
|
||||||
unset(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
|
|
||||||
endif (MBEDTLS_FOUND)
|
endif (MBEDTLS_FOUND)
|
||||||
|
|
||||||
if (CMAKE_USE_PTHREADS_INIT)
|
if (CMAKE_USE_PTHREADS_INIT)
|
||||||
set(HAVE_PTHREAD 1)
|
set(HAVE_PTHREAD 1)
|
||||||
endif (CMAKE_USE_PTHREADS_INIT)
|
endif (CMAKE_USE_PTHREADS_INIT)
|
||||||
|
|
||||||
if (UNIT_TESTING)
|
|
||||||
if (CMOCKA_FOUND)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${CMOCKA_LIBRARIES})
|
|
||||||
check_function_exists(cmocka_set_test_filter HAVE_CMOCKA_SET_TEST_FILTER)
|
|
||||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
__thread int tls;
|
__thread int tls;
|
||||||
@@ -319,19 +272,12 @@ int main(void) {
|
|||||||
###########################################################
|
###########################################################
|
||||||
# For detecting attributes we need to treat warnings as
|
# For detecting attributes we need to treat warnings as
|
||||||
# errors
|
# errors
|
||||||
if (UNIX OR MINGW)
|
if (UNIX)
|
||||||
# Get warnings for attributes
|
|
||||||
check_c_compiler_flag("-Wattributes" REQUIRED_FLAGS_WERROR)
|
|
||||||
if (REQUIRED_FLAGS_WERROR)
|
|
||||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Wattributes ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Turn warnings into errors
|
|
||||||
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
|
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
|
||||||
if (REQUIRED_FLAGS_WERROR)
|
if (REQUIRED_FLAGS_WERROR)
|
||||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Werror ")
|
set(CMAKE_REQUIRED_FLAGS "-Werror")
|
||||||
endif()
|
endif()
|
||||||
endif ()
|
endif (UNIX)
|
||||||
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
void test_constructor_attribute(void) __attribute__ ((constructor));
|
void test_constructor_attribute(void) __attribute__ ((constructor));
|
||||||
@@ -375,45 +321,6 @@ int main(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}" HAVE_FALLTHROUGH_ATTRIBUTE)
|
}" HAVE_FALLTHROUGH_ATTRIBUTE)
|
||||||
|
|
||||||
check_c_source_compiles("
|
|
||||||
#define WEAK __attribute__((weak))
|
|
||||||
|
|
||||||
WEAK int sum(int a, int b)
|
|
||||||
{
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int i = sum(2, 2);
|
|
||||||
|
|
||||||
(void)i;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}" HAVE_WEAK_ATTRIBUTE)
|
|
||||||
|
|
||||||
if (NOT WIN32)
|
|
||||||
check_c_source_compiles("
|
|
||||||
#define __unused __attribute__((unused))
|
|
||||||
|
|
||||||
static int do_nothing(int i __unused)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = do_nothing(5);
|
|
||||||
if (i > 5) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}" HAVE_UNUSED_ATTRIBUTE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -426,6 +333,18 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
|
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
|
||||||
|
|
||||||
|
check_c_source_compiles("
|
||||||
|
#include <stdio.h>
|
||||||
|
#define __VA_NARG__(...) (__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
|
||||||
|
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
|
||||||
|
#define __VA_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,N,...) N
|
||||||
|
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||||
|
#define myprintf(format, ...) printf((format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__)
|
||||||
|
int main(void) {
|
||||||
|
myprintf(\"%d %d %d %d\",1,2,3);
|
||||||
|
return 0;
|
||||||
|
}" HAVE_GCC_NARG_MACRO)
|
||||||
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main(void) {
|
int main(void) {
|
||||||
@@ -440,8 +359,6 @@ int main(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}" HAVE_COMPILER__FUNCTION__)
|
}" HAVE_COMPILER__FUNCTION__)
|
||||||
|
|
||||||
# This is only available with OpenBSD's gcc implementation */
|
|
||||||
if (OPENBSD)
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
#define ARRAY_LEN 16
|
#define ARRAY_LEN 16
|
||||||
void test_attr(const unsigned char *k)
|
void test_attr(const unsigned char *k)
|
||||||
@@ -450,7 +367,6 @@ void test_attr(const unsigned char *k)
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}" HAVE_GCC_BOUNDED_ATTRIBUTE)
|
}" HAVE_GCC_BOUNDED_ATTRIBUTE)
|
||||||
endif(OPENBSD)
|
|
||||||
|
|
||||||
# Stop treating warnings as errors
|
# Stop treating warnings as errors
|
||||||
unset(CMAKE_REQUIRED_FLAGS)
|
unset(CMAKE_REQUIRED_FLAGS)
|
||||||
@@ -485,28 +401,6 @@ if (WITH_GSSAPI AND NOT GSSAPI_FOUND)
|
|||||||
set(WITH_GSSAPI 0)
|
set(WITH_GSSAPI 0)
|
||||||
endif (WITH_GSSAPI AND NOT GSSAPI_FOUND)
|
endif (WITH_GSSAPI AND NOT GSSAPI_FOUND)
|
||||||
|
|
||||||
if (WITH_PKCS11_URI)
|
|
||||||
if (WITH_GCRYPT)
|
|
||||||
message(FATAL_ERROR "PKCS #11 is not supported for gcrypt.")
|
|
||||||
set(WITH_PKCS11_URI 0)
|
|
||||||
endif()
|
|
||||||
if (WITH_MBEDTLS)
|
|
||||||
message(FATAL_ERROR "PKCS #11 is not supported for mbedcrypto")
|
|
||||||
set(WITH_PKCS11_URI 0)
|
|
||||||
endif()
|
|
||||||
if (HAVE_OPENSSL AND NOT OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.1")
|
|
||||||
message(FATAL_ERROR "PKCS #11 requires at least OpenSSL 1.1.1")
|
|
||||||
set(WITH_PKCS11_URI 0)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WITH_MBEDTLS)
|
|
||||||
if (WITH_DSA)
|
|
||||||
message(FATAL_ERROR "DSA is not supported with mbedTLS crypto")
|
|
||||||
set(HAVE_DSA 0)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ENDIAN
|
# ENDIAN
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
test_big_endian(WORDS_BIGENDIAN)
|
test_big_endian(WORDS_BIGENDIAN)
|
||||||
|
|||||||
@@ -2,28 +2,23 @@ option(WITH_GSSAPI "Build with GSSAPI support" ON)
|
|||||||
option(WITH_ZLIB "Build with ZLIB support" ON)
|
option(WITH_ZLIB "Build with ZLIB support" ON)
|
||||||
option(WITH_SFTP "Build with SFTP support" ON)
|
option(WITH_SFTP "Build with SFTP support" ON)
|
||||||
option(WITH_SERVER "Build with SSH server support" ON)
|
option(WITH_SERVER "Build with SSH server support" ON)
|
||||||
option(WITH_DEBUG_CRYPTO "Build with crypto debug output" OFF)
|
option(WITH_STATIC_LIB "Build with a static library" OFF)
|
||||||
|
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
|
||||||
option(WITH_DEBUG_PACKET "Build with packet debug output" OFF)
|
option(WITH_DEBUG_PACKET "Build with packet debug output" OFF)
|
||||||
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
||||||
option(WITH_DSA "Build with DSA" OFF)
|
|
||||||
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
||||||
option(WITH_MBEDTLS "Compile against libmbedtls" OFF)
|
option(WITH_MBEDTLS "Compile against libmbedtls" OFF)
|
||||||
option(WITH_BLOWFISH_CIPHER "Compile with blowfish support" OFF)
|
|
||||||
option(WITH_PCAP "Compile with Pcap generation support" ON)
|
option(WITH_PCAP "Compile with Pcap generation support" ON)
|
||||||
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
|
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
|
||||||
option(WITH_PKCS11_URI "Build with PKCS#11 URI support" OFF)
|
|
||||||
option(UNIT_TESTING "Build with unit tests" OFF)
|
option(UNIT_TESTING "Build with unit tests" OFF)
|
||||||
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF)
|
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF)
|
||||||
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
|
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
|
||||||
option(WITH_BENCHMARKS "Build benchmarks tools; enables unit testing and client tests" OFF)
|
option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
|
||||||
option(WITH_EXAMPLES "Build examples" ON)
|
option(WITH_EXAMPLES "Build examples" ON)
|
||||||
option(WITH_NACL "Build with libnacl (curve25519)" ON)
|
option(WITH_NACL "Build with libnacl (curve25519)" ON)
|
||||||
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
|
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
|
||||||
option(WITH_ABI_BREAK "Allow ABI break" OFF)
|
option(WITH_ABI_BREAK "Allow ABI break" OFF)
|
||||||
option(WITH_GEX "Enable DH Group exchange mechanisms" ON)
|
option(FUZZ_TESTING "Build with fuzzer for the server" OFF)
|
||||||
option(WITH_INSECURE_NONE "Enable insecure none cipher and MAC algorithms (not suitable for production!)" OFF)
|
|
||||||
option(FUZZ_TESTING "Build with fuzzer for the server and client (automatically enables none cipher!)" OFF)
|
|
||||||
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
|
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
|
||||||
|
|
||||||
if (WITH_ZLIB)
|
if (WITH_ZLIB)
|
||||||
@@ -37,9 +32,13 @@ if (WITH_BENCHMARKS)
|
|||||||
set(CLIENT_TESTING ON)
|
set(CLIENT_TESTING ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIT_TESTING OR CLIENT_TESTING OR SERVER_TESTING)
|
if (WITH_STATIC_LIB)
|
||||||
|
set(BUILD_STATIC_LIB ON)
|
||||||
|
endif (WITH_STATIC_LIB)
|
||||||
|
|
||||||
|
if (UNIT_TESTING)
|
||||||
set(BUILD_STATIC_LIB ON)
|
set(BUILD_STATIC_LIB ON)
|
||||||
endif()
|
endif (UNIT_TESTING)
|
||||||
|
|
||||||
if (WITH_NACL)
|
if (WITH_NACL)
|
||||||
set(WITH_NACL ON)
|
set(WITH_NACL ON)
|
||||||
@@ -48,15 +47,3 @@ endif (WITH_NACL)
|
|||||||
if (WITH_ABI_BREAK)
|
if (WITH_ABI_BREAK)
|
||||||
set(WITH_SYMBOL_VERSIONING ON)
|
set(WITH_SYMBOL_VERSIONING ON)
|
||||||
endif (WITH_ABI_BREAK)
|
endif (WITH_ABI_BREAK)
|
||||||
|
|
||||||
if (NOT GLOBAL_BIND_CONFIG)
|
|
||||||
set(GLOBAL_BIND_CONFIG "/etc/ssh/libssh_server_config")
|
|
||||||
endif (NOT GLOBAL_BIND_CONFIG)
|
|
||||||
|
|
||||||
if (NOT GLOBAL_CLIENT_CONFIG)
|
|
||||||
set(GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config")
|
|
||||||
endif (NOT GLOBAL_CLIENT_CONFIG)
|
|
||||||
|
|
||||||
if (FUZZ_TESTING)
|
|
||||||
set(WITH_INSECURE_NONE ON)
|
|
||||||
endif (FUZZ_TESTING)
|
|
||||||
|
|||||||
22
INSTALL
22
INSTALL
@@ -7,29 +7,27 @@
|
|||||||
In order to build libssh, you need to install several components:
|
In order to build libssh, you need to install several components:
|
||||||
|
|
||||||
- A C compiler
|
- A C compiler
|
||||||
- [CMake](https://www.cmake.org) >= 3.3.0
|
- [CMake](http://www.cmake.org) >= 2.6.0.
|
||||||
- [openssl](https://www.openssl.org) >= 1.0.1
|
- [openssl](http://www.openssl.org) >= 0.9.8
|
||||||
or
|
or
|
||||||
- [gcrypt](https://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
|
- [gcrypt](http://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
|
||||||
- [libz](https://www.zlib.net) >= 1.2
|
|
||||||
|
|
||||||
optional:
|
optional:
|
||||||
- [cmocka](https://cmocka.org/) >= 1.1.0
|
- [libz](http://www.zlib.net) >= 1.2
|
||||||
- [socket_wrapper](https://cwrap.org/) >= 1.1.5
|
- [socket_wrapper](https://cwrap.org/) >= 1.1.5
|
||||||
- [nss_wrapper](https://cwrap.org/) >= 1.1.2
|
- [nss_wrapper](https://cwrap.org/) >= 1.1.2
|
||||||
- [uid_wrapper](https://cwrap.org/) >= 1.2.0
|
- [uid_wrapper](https://cwrap.org/) >= 1.2.0
|
||||||
- [pam_wrapper](https://cwrap.org/) >= 1.0.1
|
- [pam_wrapper](https://cwrap.org/) >= 1.0.1
|
||||||
- [priv_wrapper](https://cwrap.org/) >= 1.0.0
|
|
||||||
|
|
||||||
Note that these version numbers are version we know works correctly. If you
|
Note that these version numbers are version we know works correctly. If you
|
||||||
build and run libssh successfully with an older version, please let us know.
|
build and run libssh successfully with an older version, please let us know.
|
||||||
|
|
||||||
For Windows use vcpkg:
|
Windows binaries known to be working:
|
||||||
|
|
||||||
https://github.com/Microsoft/vcpkg
|
- http://www.slproweb.com/products/Win32OpenSSL.html
|
||||||
|
- http://zlib.net/ -> zlib compiled DLL
|
||||||
|
|
||||||
which you can use to install openssl and zlib. libssh itself is also part of
|
We installed them in C:\Program Files
|
||||||
vcpkg!
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
First, you need to configure the compilation, using CMake. Go inside the
|
First, you need to configure the compilation, using CMake. Go inside the
|
||||||
@@ -40,7 +38,7 @@ GNU/Linux, MacOS X, MSYS/MinGW:
|
|||||||
cmake -DUNIT_TESTING=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
|
cmake -DUNIT_TESTING=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
make
|
make
|
||||||
|
|
||||||
On Windows you should choose a makefile generator with -G or use
|
On Windows you should choose a makefile gernerator with -G or use
|
||||||
|
|
||||||
cmake-gui.exe ..
|
cmake-gui.exe ..
|
||||||
|
|
||||||
@@ -118,4 +116,4 @@ This document is written using [Markdown][] syntax, making it possible to
|
|||||||
provide usable information in both plain text and HTML format. Whenever
|
provide usable information in both plain text and HTML format. Whenever
|
||||||
modifying this document please use [Markdown][] syntax.
|
modifying this document please use [Markdown][] syntax.
|
||||||
|
|
||||||
[markdown]: https://www.daringfireball.net/projects/markdown
|
[markdown]: http://www.daringfireball.net/projects/markdown
|
||||||
|
|||||||
4
README
4
README
@@ -31,12 +31,12 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
|
|||||||
3* Where ?
|
3* Where ?
|
||||||
-_-_-_-_-_-_
|
-_-_-_-_-_-_
|
||||||
|
|
||||||
https://www.libssh.org
|
http://www.libssh.org
|
||||||
|
|
||||||
4* Contributing
|
4* Contributing
|
||||||
-_-_-_-_-_-_-_-_-_
|
-_-_-_-_-_-_-_-_-_
|
||||||
|
|
||||||
Please read the file 'CONTRIBUTING.md' next to this README file. It explains
|
Please read the file 'SubmittingPatches' next to this README file. It explains
|
||||||
our copyright policy and how you should send patches for upstream inclusion.
|
our copyright policy and how you should send patches for upstream inclusion.
|
||||||
|
|
||||||
Have fun and happy libssh hacking!
|
Have fun and happy libssh hacking!
|
||||||
|
|||||||
@@ -1,126 +1,9 @@
|
|||||||
# How to contribute a patch to libssh
|
Coding conventions in the libssh tree
|
||||||
|
======================================
|
||||||
|
|
||||||
Please checkout the libssh source code using git.
|
===========
|
||||||
|
Quick Start
|
||||||
For contributions we prefer Merge Requests on Gitlab:
|
===========
|
||||||
|
|
||||||
https://gitlab.com/libssh/libssh-mirror/
|
|
||||||
|
|
||||||
This way you get continuous integration which runs the complete libssh
|
|
||||||
testsuite for you.
|
|
||||||
|
|
||||||
For larger code changes, breaking the changes up into a set of simple
|
|
||||||
patches, each of which does a single thing, are much easier to review.
|
|
||||||
Patch sets like that will most likely have an easier time being merged
|
|
||||||
into the libssh code than large single patches that make lots of
|
|
||||||
changes in one large diff.
|
|
||||||
|
|
||||||
Also bugfixes and new features should be covered by tests. We use the cmocka
|
|
||||||
and cwrap framework for our testing and you can simply run it locally by
|
|
||||||
calling `make test`.
|
|
||||||
|
|
||||||
## Ownership of the contributed code
|
|
||||||
|
|
||||||
libssh is a project with distributed copyright ownership, which means
|
|
||||||
we prefer the copyright on parts of libssh to be held by individuals
|
|
||||||
rather than corporations if possible. There are historical legal
|
|
||||||
reasons for this, but one of the best ways to explain it is that it's
|
|
||||||
much easier to work with individuals who have ownership than corporate
|
|
||||||
legal departments if we ever need to make reasonable compromises with
|
|
||||||
people using and working with libssh.
|
|
||||||
|
|
||||||
We track the ownership of every part of libssh via https://git.libssh.org,
|
|
||||||
our source code control system, so we know the provenance of every piece
|
|
||||||
of code that is committed to libssh.
|
|
||||||
|
|
||||||
So if possible, if you're doing libssh changes on behalf of a company
|
|
||||||
who normally owns all the work you do please get them to assign
|
|
||||||
personal copyright ownership of your changes to you as an individual,
|
|
||||||
that makes things very easy for us to work with and avoids bringing
|
|
||||||
corporate legal departments into the picture.
|
|
||||||
|
|
||||||
If you can't do this we can still accept patches from you owned by
|
|
||||||
your employer under a standard employment contract with corporate
|
|
||||||
copyright ownership. It just requires a simple set-up process first.
|
|
||||||
|
|
||||||
We use a process very similar to the way things are done in the Linux
|
|
||||||
Kernel community, so it should be very easy to get a sign off from
|
|
||||||
your corporate legal department. The only changes we've made are to
|
|
||||||
accommodate the license we use, which is LGPLv2 (or later) whereas the
|
|
||||||
Linux kernel uses GPLv2.
|
|
||||||
|
|
||||||
The process is called signing.
|
|
||||||
|
|
||||||
## How to sign your work
|
|
||||||
|
|
||||||
Once you have permission to contribute to libssh from your employer, simply
|
|
||||||
email a copy of the following text from your corporate email address to:
|
|
||||||
|
|
||||||
contributing@libssh.org
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
libssh Developer's Certificate of Origin. Version 1.0
|
|
||||||
|
|
||||||
|
|
||||||
By making a contribution to this project, I certify that:
|
|
||||||
|
|
||||||
(a) The contribution was created in whole or in part by me and I
|
|
||||||
have the right to submit it under the appropriate
|
|
||||||
version of the GNU General Public License; or
|
|
||||||
|
|
||||||
(b) The contribution is based upon previous work that, to the best of
|
|
||||||
my knowledge, is covered under an appropriate open source license
|
|
||||||
and I have the right under that license to submit that work with
|
|
||||||
modifications, whether created in whole or in part by me, under
|
|
||||||
the GNU General Public License, in the appropriate version; or
|
|
||||||
|
|
||||||
(c) The contribution was provided directly to me by some other
|
|
||||||
person who certified (a) or (b) and I have not modified it.
|
|
||||||
|
|
||||||
(d) I understand and agree that this project and the contribution are
|
|
||||||
public and that a record of the contribution (including all
|
|
||||||
metadata and personal information I submit with it, including my
|
|
||||||
sign-off) is maintained indefinitely and may be redistributed
|
|
||||||
consistent with the libssh Team's policies and the requirements of
|
|
||||||
the GNU GPL where they are relevant.
|
|
||||||
|
|
||||||
(e) I am granting this work to this project under the terms of the
|
|
||||||
GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2.1 of
|
|
||||||
the License, or (at the option of the project) any later version.
|
|
||||||
|
|
||||||
https://www.gnu.org/licenses/lgpl-2.1.html
|
|
||||||
```
|
|
||||||
|
|
||||||
We will maintain a copy of that email as a record that you have the
|
|
||||||
rights to contribute code to libssh under the required licenses whilst
|
|
||||||
working for the company where the email came from.
|
|
||||||
|
|
||||||
Then when sending in a patch via the normal mechanisms described
|
|
||||||
above, add a line that states:
|
|
||||||
|
|
||||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
|
||||||
|
|
||||||
using your real name and the email address you sent the original email
|
|
||||||
you used to send the libssh Developer's Certificate of Origin to us
|
|
||||||
(sorry, no pseudonyms or anonymous contributions.)
|
|
||||||
|
|
||||||
That's it! Such code can then quite happily contain changes that have
|
|
||||||
copyright messages such as:
|
|
||||||
|
|
||||||
(c) Example Corporation.
|
|
||||||
|
|
||||||
and can be merged into the libssh codebase in the same way as patches
|
|
||||||
from any other individual. You don't need to send in a copy of the
|
|
||||||
libssh Developer's Certificate of Origin for each patch, or inside each
|
|
||||||
patch. Just the sign-off message is all that is required once we've
|
|
||||||
received the initial email.
|
|
||||||
|
|
||||||
|
|
||||||
# Coding conventions in the libssh tree
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
Coding style guidelines are about reducing the number of unnecessary
|
Coding style guidelines are about reducing the number of unnecessary
|
||||||
reformatting patches and making things easier for developers to work together.
|
reformatting patches and making things easier for developers to work together.
|
||||||
@@ -153,28 +36,31 @@ are the highlights.
|
|||||||
have a copy of "The C Programming Language" anyways right?
|
have a copy of "The C Programming Language" anyways right?
|
||||||
|
|
||||||
|
|
||||||
## Editor Hints
|
=============
|
||||||
|
Editor Hints
|
||||||
### Emacs
|
=============
|
||||||
|
|
||||||
|
Emacs
|
||||||
|
------
|
||||||
Add the follow to your $HOME/.emacs file:
|
Add the follow to your $HOME/.emacs file:
|
||||||
|
|
||||||
(add-hook 'c-mode-hook
|
(add-hook 'c-mode-hook
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(c-set-style "linux")
|
(c-set-style "linux")
|
||||||
(c-toggle-auto-state)))
|
(c-toggle-auto-state)))
|
||||||
|
|
||||||
|
|
||||||
## Neovim/VIM
|
Vim
|
||||||
|
----
|
||||||
|
|
||||||
For the basic vi editor included with all variants of \*nix, add the
|
For the basic vi editor included with all variants of \*nix, add the
|
||||||
following to ~/.config/nvim/init.rc or ~/.vimrc:
|
following to $HOME/.vimrc:
|
||||||
|
|
||||||
set ts=4 sw=4 et cindent
|
set ts=4 sw=4 et cindent
|
||||||
|
|
||||||
You can use the Vim gitmodline plugin to store this in the git config:
|
You can use the Vim gitmodline plugin to store this in the git config:
|
||||||
|
|
||||||
https://git.cryptomilk.org/projects/vim-gitmodeline.git/
|
http://git.cryptomilk.org/projects/vim-gitmodeline.git/
|
||||||
|
|
||||||
For Vim, the following settings in $HOME/.vimrc will also deal with
|
For Vim, the following settings in $HOME/.vimrc will also deal with
|
||||||
displaying trailing whitespace:
|
displaying trailing whitespace:
|
||||||
@@ -195,9 +81,12 @@ displaying trailing whitespace:
|
|||||||
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
|
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
|
||||||
|
|
||||||
|
|
||||||
## FAQ & Statement Reference
|
==========================
|
||||||
|
FAQ & Statement Reference
|
||||||
|
==========================
|
||||||
|
|
||||||
### Comments
|
Comments
|
||||||
|
---------
|
||||||
|
|
||||||
Comments should always use the standard C syntax. C++ style comments are not
|
Comments should always use the standard C syntax. C++ style comments are not
|
||||||
currently allowed.
|
currently allowed.
|
||||||
@@ -274,7 +163,8 @@ This is bad:
|
|||||||
* This is a multi line comment,
|
* This is a multi line comment,
|
||||||
* with some more words...*/
|
* with some more words...*/
|
||||||
|
|
||||||
### Indentation & Whitespace & 80 columns
|
Indention & Whitespace & 80 columns
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
To avoid confusion, indentations have to be 4 spaces. Do not use tabs!. When
|
To avoid confusion, indentations have to be 4 spaces. Do not use tabs!. When
|
||||||
wrapping parameters for function calls, align the parameter list with the first
|
wrapping parameters for function calls, align the parameter list with the first
|
||||||
@@ -290,7 +180,8 @@ splitting. Never split a line before columns 70 - 79 unless you
|
|||||||
have a really good reason. Be smart about formatting.
|
have a really good reason. Be smart about formatting.
|
||||||
|
|
||||||
|
|
||||||
### If, switch, & Code blocks
|
If, switch, & Code blocks
|
||||||
|
--------------------------
|
||||||
|
|
||||||
Always follow an 'if' keyword with a space but don't include additional
|
Always follow an 'if' keyword with a space but don't include additional
|
||||||
spaces following or preceding the parentheses in the conditional.
|
spaces following or preceding the parentheses in the conditional.
|
||||||
@@ -316,7 +207,7 @@ invoking functions.
|
|||||||
Braces for code blocks used by for, if, switch, while, do..while, etc. should
|
Braces for code blocks used by for, if, switch, while, do..while, etc. should
|
||||||
begin on the same line as the statement keyword and end on a line of their own.
|
begin on the same line as the statement keyword and end on a line of their own.
|
||||||
You should always include braces, even if the block only contains one
|
You should always include braces, even if the block only contains one
|
||||||
statement. **NOTE**: Functions are different and the beginning left brace should
|
statement. NOTE: Functions are different and the beginning left brace should
|
||||||
be located in the first column on the next line.
|
be located in the first column on the next line.
|
||||||
|
|
||||||
If the beginning statement has to be broken across lines due to length, the
|
If the beginning statement has to be broken across lines due to length, the
|
||||||
@@ -363,7 +254,8 @@ Bad examples:
|
|||||||
print("I should be in braces.\n");
|
print("I should be in braces.\n");
|
||||||
|
|
||||||
|
|
||||||
### Goto
|
Goto
|
||||||
|
-----
|
||||||
|
|
||||||
While many people have been academically taught that "goto"s are fundamentally
|
While many people have been academically taught that "goto"s are fundamentally
|
||||||
evil, they can greatly enhance readability and reduce memory leaks when used as
|
evil, they can greatly enhance readability and reduce memory leaks when used as
|
||||||
@@ -395,13 +287,14 @@ Good Examples:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
### Initialize pointers
|
Initialize pointers
|
||||||
|
-------------------
|
||||||
|
|
||||||
All pointer variables **MUST** be initialized to `NULL`. History has
|
All pointer variables MUST be initialized to NULL. History has
|
||||||
demonstrated that uninitialized pointer variables have lead to various
|
demonstrated that uninitialized pointer variables have lead to various
|
||||||
bugs and security issues.
|
bugs and security issues.
|
||||||
|
|
||||||
Pointers **MUST** be initialized even if the assignment directly follows
|
Pointers MUST be initialized even if the assignment directly follows
|
||||||
the declaration, like pointer2 in the example below, because the
|
the declaration, like pointer2 in the example below, because the
|
||||||
instructions sequence may change over time.
|
instructions sequence may change over time.
|
||||||
|
|
||||||
@@ -416,13 +309,15 @@ Good Example:
|
|||||||
|
|
||||||
pointer1 = some_func1();
|
pointer1 = some_func1();
|
||||||
|
|
||||||
### Typedefs
|
Typedefs
|
||||||
|
---------
|
||||||
|
|
||||||
libssh tries to avoid `typedef struct { .. } x_t;` so we do always try to use
|
libssh tries to avoid "typedef struct { .. } x_t;" so we do always try to use
|
||||||
`struct x { .. };`. We know there are still such typedefs in the code, but for
|
"struct x { .. };". We know there are still such typedefs in the code, but for
|
||||||
new code, please don't do that anymore.
|
new code, please don't do that anymore.
|
||||||
|
|
||||||
### Make use of helper variables
|
Make use of helper variables
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
Please try to avoid passing function calls as function parameters in new code.
|
Please try to avoid passing function calls as function parameters in new code.
|
||||||
This makes the code much easier to read and it's also easier to use the "step"
|
This makes the code much easier to read and it's also easier to use the "step"
|
||||||
@@ -472,13 +367,9 @@ an iterator style:
|
|||||||
But in general, please try to avoid this pattern.
|
But in general, please try to avoid this pattern.
|
||||||
|
|
||||||
|
|
||||||
### Control-Flow changing macros
|
Control-Flow changing macros
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
Macros like `STATUS_NOT_OK_RETURN` that change control flow (return/goto/etc)
|
Macros like STATUS_NOT_OK_RETURN that change control flow (return/goto/etc)
|
||||||
from within the macro are considered bad, because they look like function calls
|
from within the macro are considered bad, because they look like function calls
|
||||||
that never change control flow. Please do not introduce them.
|
that never change control flow. Please do not introduce them.
|
||||||
|
|
||||||
|
|
||||||
Have fun and happy libssh hacking!
|
|
||||||
|
|
||||||
The libssh Team
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
[](https://gitlab.com/libssh/libssh-mirror/commits/master)
|
[](https://gitlab.com/libssh/libssh-mirror/commits/master)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libssh)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
_ _ _ _
|
_ _ _ _
|
||||||
@@ -37,7 +36,7 @@ https://www.libssh.org
|
|||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Please read the file 'CONTRIBUTING.md' next to this README file. It explains
|
Please read the file 'SubmittingPatches' next to this README file. It explains
|
||||||
our copyright policy and how you should send patches for upstream inclusion.
|
our copyright policy and how you should send patches for upstream inclusion.
|
||||||
|
|
||||||
Have fun and happy libssh hacking!
|
Have fun and happy libssh hacking!
|
||||||
|
|||||||
118
SubmittingPatches
Normal file
118
SubmittingPatches
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
How to contribute a patch to libssh
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Please checkout the libssh source code using git. Change the code and then
|
||||||
|
use "git format-patch" to create a patch. The patch should be signed (see
|
||||||
|
below) and send it to libssh@libssh.org, or attach it to a bug report at
|
||||||
|
https://red.libssh.org/
|
||||||
|
|
||||||
|
For larger code changes, breaking the changes up into a set of simple
|
||||||
|
patches, each of which does a single thing, are much easier to review.
|
||||||
|
Patch sets like that will most likely have an easier time being merged
|
||||||
|
into the libssh code than large single patches that make lots of
|
||||||
|
changes in one large diff.
|
||||||
|
|
||||||
|
Ownership of the contributed code
|
||||||
|
==================================
|
||||||
|
|
||||||
|
libssh is a project with distributed copyright ownership, which means
|
||||||
|
we prefer the copyright on parts of libssh to be held by individuals
|
||||||
|
rather than corporations if possible. There are historical legal
|
||||||
|
reasons for this, but one of the best ways to explain it is that it's
|
||||||
|
much easier to work with individuals who have ownership than corporate
|
||||||
|
legal departments if we ever need to make reasonable compromises with
|
||||||
|
people using and working with libssh.
|
||||||
|
|
||||||
|
We track the ownership of every part of libssh via http://git.libssh.org,
|
||||||
|
our source code control system, so we know the provenance of every piece
|
||||||
|
of code that is committed to libssh.
|
||||||
|
|
||||||
|
So if possible, if you're doing libssh changes on behalf of a company
|
||||||
|
who normally owns all the work you do please get them to assign
|
||||||
|
personal copyright ownership of your changes to you as an individual,
|
||||||
|
that makes things very easy for us to work with and avoids bringing
|
||||||
|
corporate legal departments into the picture.
|
||||||
|
|
||||||
|
If you can't do this we can still accept patches from you owned by
|
||||||
|
your employer under a standard employment contract with corporate
|
||||||
|
copyright ownership. It just requires a simple set-up process first.
|
||||||
|
|
||||||
|
We use a process very similar to the way things are done in the Linux
|
||||||
|
Kernel community, so it should be very easy to get a sign off from
|
||||||
|
your corporate legal department. The only changes we've made are to
|
||||||
|
accommodate the license we use, which is LGPLv2 (or later) whereas the
|
||||||
|
Linux kernel uses GPLv2.
|
||||||
|
|
||||||
|
The process is called signing.
|
||||||
|
|
||||||
|
How to sign your work
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Once you have permission to contribute to libssh from your employer, simply
|
||||||
|
email a copy of the following text from your corporate email address to:
|
||||||
|
|
||||||
|
contributing@libssh.org
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
libssh Developer's Certificate of Origin. Version 1.0
|
||||||
|
|
||||||
|
|
||||||
|
By making a contribution to this project, I certify that:
|
||||||
|
|
||||||
|
(a) The contribution was created in whole or in part by me and I
|
||||||
|
have the right to submit it under the appropriate
|
||||||
|
version of the GNU General Public License; or
|
||||||
|
|
||||||
|
(b) The contribution is based upon previous work that, to the best of
|
||||||
|
my knowledge, is covered under an appropriate open source license
|
||||||
|
and I have the right under that license to submit that work with
|
||||||
|
modifications, whether created in whole or in part by me, under
|
||||||
|
the GNU General Public License, in the appropriate version; or
|
||||||
|
|
||||||
|
(c) The contribution was provided directly to me by some other
|
||||||
|
person who certified (a) or (b) and I have not modified it.
|
||||||
|
|
||||||
|
(d) I understand and agree that this project and the contribution are
|
||||||
|
public and that a record of the contribution (including all
|
||||||
|
metadata and personal information I submit with it, including my
|
||||||
|
sign-off) is maintained indefinitely and may be redistributed
|
||||||
|
consistent with the libssh Team's policies and the requirements of
|
||||||
|
the GNU GPL where they are relevant.
|
||||||
|
|
||||||
|
(e) I am granting this work to this project under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2.1 of
|
||||||
|
the License, or (at the option of the project) any later version.
|
||||||
|
|
||||||
|
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
|
||||||
|
|
||||||
|
We will maintain a copy of that email as a record that you have the
|
||||||
|
rights to contribute code to libssh under the required licenses whilst
|
||||||
|
working for the company where the email came from.
|
||||||
|
|
||||||
|
Then when sending in a patch via the normal mechanisms described
|
||||||
|
above, add a line that states:
|
||||||
|
|
||||||
|
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||||
|
|
||||||
|
using your real name and the email address you sent the original email
|
||||||
|
you used to send the libssh Developer's Certificate of Origin to us
|
||||||
|
(sorry, no pseudonyms or anonymous contributions.)
|
||||||
|
|
||||||
|
That's it! Such code can then quite happily contain changes that have
|
||||||
|
copyright messages such as:
|
||||||
|
|
||||||
|
(c) Example Corporation.
|
||||||
|
|
||||||
|
and can be merged into the libssh codebase in the same way as patches
|
||||||
|
from any other individual. You don't need to send in a copy of the
|
||||||
|
libssh Developer's Certificate of Origin for each patch, or inside each
|
||||||
|
patch. Just the sign-off message is all that is required once we've
|
||||||
|
received the initial email.
|
||||||
|
|
||||||
|
Have fun and happy libssh hacking !
|
||||||
|
|
||||||
|
The libssh Team
|
||||||
|
|
||||||
@@ -1,63 +1,11 @@
|
|||||||
#
|
# - add_cmocka_test(test_name test_source linklib1 ... linklibN)
|
||||||
|
|
||||||
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
||||||
# Copyright (c) 2007-2018 Andreas Schneider <asn@cryptomilk.org>
|
# Copyright (c) 2007-2018 Andreas Schneider <asn@cryptomilk.org>
|
||||||
# Copyright (c) 2018 Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
|
||||||
#
|
#
|
||||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
#.rst:
|
|
||||||
# AddCMockaTest
|
|
||||||
# -------------
|
|
||||||
#
|
|
||||||
# This file provides a function to add a test
|
|
||||||
#
|
|
||||||
# Functions provided
|
|
||||||
# ------------------
|
|
||||||
#
|
|
||||||
# ::
|
|
||||||
#
|
|
||||||
# add_cmocka_test(target_name
|
|
||||||
# SOURCES src1 src2 ... srcN
|
|
||||||
# [COMPILE_OPTIONS opt1 opt2 ... optN]
|
|
||||||
# [LINK_LIBRARIES lib1 lib2 ... libN]
|
|
||||||
# [LINK_OPTIONS lopt1 lop2 .. loptN]
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# ``target_name``:
|
|
||||||
# Required, expects the name of the test which will be used to define a target
|
|
||||||
#
|
|
||||||
# ``SOURCES``:
|
|
||||||
# Required, expects one or more source files names
|
|
||||||
#
|
|
||||||
# ``COMPILE_OPTIONS``:
|
|
||||||
# Optional, expects one or more options to be passed to the compiler
|
|
||||||
#
|
|
||||||
# ``LINK_LIBRARIES``:
|
|
||||||
# Optional, expects one or more libraries to be linked with the test
|
|
||||||
# executable.
|
|
||||||
#
|
|
||||||
# ``LINK_OPTIONS``:
|
|
||||||
# Optional, expects one or more options to be passed to the linker
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# .. code-block:: cmake
|
|
||||||
#
|
|
||||||
# add_cmocka_test(my_test
|
|
||||||
# SOURCES my_test.c other_source.c
|
|
||||||
# COMPILE_OPTIONS -g -Wall
|
|
||||||
# LINK_LIBRARIES mylib
|
|
||||||
# LINK_OPTIONS -Wl,--enable-syscall-fixup
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# Where ``my_test`` is the name of the test, ``my_test.c`` and
|
|
||||||
# ``other_source.c`` are sources for the binary, ``-g -Wall`` are compiler
|
|
||||||
# options to be used, ``mylib`` is a target of a library to be linked, and
|
|
||||||
# ``-Wl,--enable-syscall-fixup`` is an option passed to the linker.
|
|
||||||
#
|
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
@@ -69,52 +17,10 @@ if (CMAKE_CROSSCOMPILING)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(ADD_CMOCKA_TEST _TARGET_NAME)
|
function(ADD_CMOCKA_TEST _testName _testSource)
|
||||||
|
add_executable(${_testName} ${_testSource})
|
||||||
|
|
||||||
set(one_value_arguments
|
target_link_libraries(${_testName} ${ARGN})
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
endfunction (ADD_CMOCKA_TEST)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||||||
|
|
||||||
# Put the include dirs which are in the source or build tree
|
# Put the include dirs which are in the source or build tree
|
||||||
# before all other include dirs, so the headers in the sources
|
# before all other include dirs, so the headers in the sources
|
||||||
# are preferred over the already installed ones
|
# are prefered over the already installed ones
|
||||||
# since cmake 2.4.1
|
# since cmake 2.4.1
|
||||||
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
|
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
|
||||||
|
|
||||||
@@ -16,6 +16,3 @@ set(CMAKE_COLOR_MAKEFILE ON)
|
|||||||
|
|
||||||
# Create the compile command database for clang by default
|
# Create the compile command database for clang by default
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
# Always build with -fPIC
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
if (UNIX AND NOT WIN32)
|
if (UNIX AND NOT WIN32)
|
||||||
# Activate with: -DCMAKE_BUILD_TYPE=Profiling
|
# Activate with: -DCMAKE_BUILD_TYPE=Profiling
|
||||||
set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
|
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -fprofile-arcs -ftest-coverage"
|
||||||
CACHE STRING "Flags used by the C compiler during PROFILING builds.")
|
CACHE STRING "Flags used by the C compiler during PROFILING builds.")
|
||||||
set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage"
|
set(CMAKE_CXX_FLAGS_PROFILING "-g -O0 -fprofile-arcs -ftest-coverage"
|
||||||
CACHE STRING "Flags used by the CXX compiler during PROFILING builds.")
|
CACHE STRING "Flags used by the CXX compiler during PROFILING builds.")
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage"
|
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.")
|
CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.")
|
||||||
@@ -22,28 +22,4 @@ if (UNIX AND NOT WIN32)
|
|||||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
|
CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.")
|
||||||
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
|
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
|
||||||
CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")
|
CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")
|
||||||
|
|
||||||
# Activate with: -DCMAKE_BUILD_TYPE=MemorySanitizer
|
|
||||||
set(CMAKE_C_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
|
|
||||||
CACHE STRING "Flags used by the C compiler during MEMORYSANITIZER builds.")
|
|
||||||
set(CMAKE_CXX_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
|
|
||||||
CACHE STRING "Flags used by the CXX compiler during MEMORYSANITIZER builds.")
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
|
|
||||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
|
|
||||||
set(CMAKE_MODULE_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
|
|
||||||
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
|
|
||||||
set(CMAKE_EXEC_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
|
|
||||||
CACHE STRING "Flags used by the linker during MEMORYSANITIZER builds.")
|
|
||||||
|
|
||||||
# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer
|
|
||||||
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover=undefined,integer"
|
|
||||||
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=undefined,integer"
|
|
||||||
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()
|
endif()
|
||||||
|
|||||||
109
cmake/Modules/DefineInstallationPaths.cmake
Normal file
109
cmake/Modules/DefineInstallationPaths.cmake
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
if (UNIX OR OS2)
|
||||||
|
IF (NOT APPLICATION_NAME)
|
||||||
|
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
|
||||||
|
SET(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
|
ENDIF (NOT APPLICATION_NAME)
|
||||||
|
|
||||||
|
# Suffix for Linux
|
||||||
|
SET(LIB_SUFFIX
|
||||||
|
CACHE STRING "Define suffix of directory name (32/64)"
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(EXEC_INSTALL_PREFIX
|
||||||
|
"${CMAKE_INSTALL_PREFIX}"
|
||||||
|
CACHE PATH "Base directory for executables and libraries"
|
||||||
|
)
|
||||||
|
SET(SHARE_INSTALL_PREFIX
|
||||||
|
"${CMAKE_INSTALL_PREFIX}/share"
|
||||||
|
CACHE PATH "Base directory for files which go to share/"
|
||||||
|
)
|
||||||
|
SET(DATA_INSTALL_PREFIX
|
||||||
|
"${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}"
|
||||||
|
CACHE PATH "The parent directory where applications can install their data")
|
||||||
|
|
||||||
|
# The following are directories where stuff will be installed to
|
||||||
|
SET(BIN_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/bin"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)"
|
||||||
|
)
|
||||||
|
SET(SBIN_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/sbin"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)"
|
||||||
|
)
|
||||||
|
SET(LIB_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}"
|
||||||
|
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)"
|
||||||
|
)
|
||||||
|
SET(LIBEXEC_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/libexec"
|
||||||
|
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
|
||||||
|
)
|
||||||
|
SET(PLUGIN_INSTALL_DIR
|
||||||
|
"${LIB_INSTALL_DIR}/${APPLICATION_NAME}"
|
||||||
|
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})"
|
||||||
|
)
|
||||||
|
SET(INCLUDE_INSTALL_DIR
|
||||||
|
"${CMAKE_INSTALL_PREFIX}/include"
|
||||||
|
CACHE PATH "The subdirectory to the header prefix (default prefix/include)"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_INSTALL_DIR
|
||||||
|
"${LIB_INSTALL_DIR}/cmake"
|
||||||
|
CACHE PATH "The subdirectory to install cmake config files")
|
||||||
|
|
||||||
|
SET(DATA_INSTALL_DIR
|
||||||
|
"${DATA_INSTALL_PREFIX}"
|
||||||
|
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})"
|
||||||
|
)
|
||||||
|
SET(HTML_INSTALL_DIR
|
||||||
|
"${DATA_INSTALL_PREFIX}/doc/HTML"
|
||||||
|
CACHE PATH "The HTML install dir for documentation (default data/doc/html)"
|
||||||
|
)
|
||||||
|
SET(ICON_INSTALL_DIR
|
||||||
|
"${DATA_INSTALL_PREFIX}/icons"
|
||||||
|
CACHE PATH "The icon install dir (default data/icons/)"
|
||||||
|
)
|
||||||
|
SET(SOUND_INSTALL_DIR
|
||||||
|
"${DATA_INSTALL_PREFIX}/sounds"
|
||||||
|
CACHE PATH "The install dir for sound files (default data/sounds)"
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(LOCALE_INSTALL_DIR
|
||||||
|
"${SHARE_INSTALL_PREFIX}/locale"
|
||||||
|
CACHE PATH "The install dir for translations (default prefix/share/locale)"
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(XDG_APPS_DIR
|
||||||
|
"${SHARE_INSTALL_PREFIX}/applications/"
|
||||||
|
CACHE PATH "The XDG apps dir"
|
||||||
|
)
|
||||||
|
SET(XDG_DIRECTORY_DIR
|
||||||
|
"${SHARE_INSTALL_PREFIX}/desktop-directories"
|
||||||
|
CACHE PATH "The XDG directory"
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(SYSCONF_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/etc"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)"
|
||||||
|
)
|
||||||
|
SET(MAN_INSTALL_DIR
|
||||||
|
"${SHARE_INSTALL_PREFIX}/man"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)"
|
||||||
|
)
|
||||||
|
SET(INFO_INSTALL_DIR
|
||||||
|
"${SHARE_INSTALL_PREFIX}/info"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
# Same same
|
||||||
|
set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
|
||||||
|
set(SBIN_INSTALL_DIR "sbin" CACHE PATH "-")
|
||||||
|
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "-")
|
||||||
|
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
|
||||||
|
set(CMAKE_INSTALL_DIR "CMake" CACHE PATH "-")
|
||||||
|
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
|
||||||
|
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
|
||||||
|
set(ICON_INSTALL_DIR "icons" CACHE PATH "-")
|
||||||
|
set(SOUND_INSTALL_DIR "soudns" CACHE PATH "-")
|
||||||
|
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
|
||||||
|
endif ()
|
||||||
@@ -302,13 +302,12 @@ function(get_file_list _TARGET_NAME)
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
${_TARGET_NAME}_int ALL
|
${_TARGET_NAME}_int ALL
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-DOUTPUT_PATH=${_get_files_list_OUTPUT_PATH}
|
-DOUTPUT_PATH="${_get_files_list_OUTPUT_PATH}"
|
||||||
-DDIRECTORIES=${_get_files_list_DIRECTORIES}
|
-DDIRECTORIES="${_get_files_list_DIRECTORIES}"
|
||||||
-DFILES_PATTERNS=${_get_files_list_FILES_PATTERNS}
|
-DFILES_PATTERNS="${_get_files_list_FILES_PATTERNS}"
|
||||||
-P ${_GET_FILES_LIST_SCRIPT}
|
-P ${_GET_FILES_LIST_SCRIPT}
|
||||||
COMMENT
|
COMMENT
|
||||||
"Searching for files"
|
"Searching for files"
|
||||||
VERBATIM
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DEFINED _get_files_list_COPY_TO)
|
if (DEFINED _get_files_list_COPY_TO)
|
||||||
@@ -319,7 +318,6 @@ function(get_file_list _TARGET_NAME)
|
|||||||
${_FILES_LIST_OUTPUT_PATH} ${_get_files_list_COPY_TO}
|
${_FILES_LIST_OUTPUT_PATH} ${_get_files_list_COPY_TO}
|
||||||
DEPENDS ${_TARGET_NAME}_int
|
DEPENDS ${_TARGET_NAME}_int
|
||||||
COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}"
|
COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}"
|
||||||
VERBATIM
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
add_custom_target(${_TARGET_NAME} ALL
|
add_custom_target(${_TARGET_NAME} ALL
|
||||||
@@ -371,13 +369,12 @@ function(extract_symbols _TARGET_NAME)
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
${_TARGET_NAME}_int ALL
|
${_TARGET_NAME}_int ALL
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-DOUTPUT_PATH=${_SYMBOLS_OUTPUT_PATH}
|
-DOUTPUT_PATH="${_SYMBOLS_OUTPUT_PATH}"
|
||||||
-DHEADERS_LIST_FILE=${_HEADERS_LIST_FILE}
|
-DHEADERS_LIST_FILE="${_HEADERS_LIST_FILE}"
|
||||||
-DFILTER_PATTERN=${_extract_symbols_FILTER_PATTERN}
|
-DFILTER_PATTERN=${_extract_symbols_FILTER_PATTERN}
|
||||||
-P ${_EXTRACT_SYMBOLS_SCRIPT}
|
-P ${_EXTRACT_SYMBOLS_SCRIPT}
|
||||||
DEPENDS ${_extract_symbols_HEADERS_LIST}
|
DEPENDS ${_extract_symbols_HEADERS_LIST}
|
||||||
COMMENT "Extracting symbols from headers"
|
COMMENT "Extracting symbols from headers"
|
||||||
VERBATIM
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DEFINED _extract_symbols_COPY_TO)
|
if (DEFINED _extract_symbols_COPY_TO)
|
||||||
@@ -388,7 +385,6 @@ function(extract_symbols _TARGET_NAME)
|
|||||||
${_SYMBOLS_OUTPUT_PATH} ${_extract_symbols_COPY_TO}
|
${_SYMBOLS_OUTPUT_PATH} ${_extract_symbols_COPY_TO}
|
||||||
DEPENDS ${_TARGET_NAME}_int
|
DEPENDS ${_TARGET_NAME}_int
|
||||||
COMMENT "Copying ${_TARGET_NAME} to ${_extract_symbols_COPY_TO}"
|
COMMENT "Copying ${_TARGET_NAME} to ${_extract_symbols_COPY_TO}"
|
||||||
VERBATIM
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
add_custom_target(${_TARGET_NAME} ALL
|
add_custom_target(${_TARGET_NAME} ALL
|
||||||
@@ -453,37 +449,35 @@ function(generate_map_file _TARGET_NAME)
|
|||||||
${_TARGET_NAME}_int ALL
|
${_TARGET_NAME}_int ALL
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE}
|
-DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE}
|
||||||
-DSYMBOLS=${_SYMBOLS_FILE}
|
-DSYMBOLS="${_SYMBOLS_FILE}"
|
||||||
-DCURRENT_MAP=${_generate_map_file_CURRENT_MAP}
|
-DCURRENT_MAP=${_generate_map_file_CURRENT_MAP}
|
||||||
-DOUTPUT_PATH=${_MAP_OUTPUT_PATH}
|
-DOUTPUT_PATH="${_MAP_OUTPUT_PATH}"
|
||||||
-DFINAL=${_generate_map_file_FINAL}
|
-DFINAL=${_generate_map_file_FINAL}
|
||||||
-DBREAK_ABI=${_generate_map_file_BREAK_ABI}
|
-DBREAK_ABI=${_generate_map_file_BREAK_ABI}
|
||||||
-DRELEASE_NAME_VERSION=${_generate_map_file_RELEASE_NAME_VERSION}
|
-DRELEASE_NAME_VERSION=${_generate_map_file_RELEASE_NAME_VERSION}
|
||||||
-P ${_GENERATE_MAP_SCRIPT}
|
-P ${_GENERATE_MAP_SCRIPT}
|
||||||
DEPENDS ${_generate_map_file_SYMBOLS}
|
DEPENDS ${_generate_map_file_SYMBOLS}
|
||||||
COMMENT "Generating the map ${_TARGET_NAME}"
|
COMMENT "Generating the map ${_TARGET_NAME}"
|
||||||
VERBATIM
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add a custom command setting the map as OUTPUT to allow it to be added as
|
# Add a custom command setting the map as OUTPUT to allow it to be added as
|
||||||
# a generated source
|
# a generated source
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${_MAP_OUTPUT_PATH}
|
OUTPUT ${_MAP_OUTPUT_PATH}
|
||||||
DEPENDS ${_TARGET_NAME}_copy
|
DEPENDS ${_TARGET_NAME}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DEFINED _generate_map_file_COPY_TO)
|
if (DEFINED _generate_map_file_COPY_TO)
|
||||||
# Copy the generated map back to the COPY_TO
|
# Copy the generated map back to the COPY_TO
|
||||||
add_custom_target(${_TARGET_NAME}_copy ALL
|
add_custom_target(${_TARGET_NAME} ALL
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_COMMAND} -E copy_if_different ${_MAP_OUTPUT_PATH}
|
${CMAKE_COMMAND} -E copy_if_different ${_MAP_OUTPUT_PATH}
|
||||||
${_generate_map_file_COPY_TO}
|
${_generate_map_file_COPY_TO}
|
||||||
DEPENDS ${_TARGET_NAME}_int
|
DEPENDS ${_TARGET_NAME}_int
|
||||||
COMMENT "Copying ${_MAP_OUTPUT_PATH} to ${_generate_map_file_COPY_TO}"
|
COMMENT "Copying ${_MAP_OUTPUT_PATH} to ${_generate_map_file_COPY_TO}"
|
||||||
VERBATIM
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
add_custom_target(${_TARGET_NAME}_copy ALL
|
add_custom_target(${_TARGET_NAME} ALL
|
||||||
DEPENDS ${_TARGET_NAME}_int
|
DEPENDS ${_TARGET_NAME}_int
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
# - Try to find ARGP
|
# - Try to find ARGP
|
||||||
#
|
|
||||||
# The argp can be either shipped as part of libc (ex. glibc) or as a separate
|
|
||||||
# library that requires additional linking (ex. Windows, Mac, musl libc, ...)
|
|
||||||
#
|
|
||||||
# Once done this will define
|
# Once done this will define
|
||||||
#
|
#
|
||||||
# ARGP_ROOT_DIR - Set this variable to the root installation of ARGP
|
# ARGP_ROOT_DIR - Set this variable to the root installation of ARGP
|
||||||
|
|||||||
@@ -49,15 +49,7 @@ find_library(GCRYPT_LIBRARY
|
|||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
lib
|
lib
|
||||||
)
|
)
|
||||||
find_library(GCRYPT_ERROR_LIBRARY
|
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})
|
||||||
NAMES
|
|
||||||
gpg-error
|
|
||||||
libgpg-error-0
|
|
||||||
libgpg-error6-0
|
|
||||||
HINTS
|
|
||||||
${_GCRYPT_ROOT_HINTS_AND_PATHS}
|
|
||||||
)
|
|
||||||
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} ${GCRYPT_ERROR_LIBRARY})
|
|
||||||
|
|
||||||
if (GCRYPT_INCLUDE_DIR)
|
if (GCRYPT_INCLUDE_DIR)
|
||||||
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")
|
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI
|
# GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI
|
||||||
#
|
#
|
||||||
# Read-Only variables:
|
# Read-Only variables:
|
||||||
# GSSAPI_FLAVOR_MIT - set to TRUE if MIT Kerberos has been found
|
# GSSAPI_FLAVOR_MIT - set to TURE if MIT Kerberos has been found
|
||||||
# GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Keberos has been found
|
# GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Keberos has been found
|
||||||
# GSSAPI_FOUND - system has GSSAPI
|
# GSSAPI_FOUND - system has GSSAPI
|
||||||
# GSSAPI_INCLUDE_DIR - the GSSAPI include directory
|
# GSSAPI_INCLUDE_DIR - the GSSAPI include directory
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
# - Try to find softhsm
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# SOFTHSM_FOUND - system has softhsm
|
|
||||||
# SOFTHSM_LIBRARIES - Link these to use softhsm
|
|
||||||
#
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright (c) 2019 Sahana Prasad <sahana@redhat.com>
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
|
||||||
# see accompanying file Copyright.txt for details.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
find_library(SOFTHSM2_LIBRARY
|
|
||||||
NAMES
|
|
||||||
softhsm2
|
|
||||||
)
|
|
||||||
|
|
||||||
if (SOFTHSM2_LIBRARY)
|
|
||||||
set(SOFTHSM_LIBRARIES
|
|
||||||
${SOFTHSM_LIBRARIES}
|
|
||||||
${SOFTHSM2_LIBRARY}
|
|
||||||
)
|
|
||||||
endif (SOFTHSM2_LIBRARY)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(softhsm DEFAULT_MSG SOFTHSM_LIBRARIES)
|
|
||||||
|
|
||||||
# show the SOFTHSM_INCLUDE_DIR and SOFTHSM_LIBRARIES variables only in the advanced view
|
|
||||||
mark_as_advanced(SOFTHSM_LIBRARIES)
|
|
||||||
@@ -4,16 +4,14 @@
|
|||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#cmakedefine VERSION "${PROJECT_VERSION}"
|
#cmakedefine VERSION "${PROJECT_VERSION}"
|
||||||
|
|
||||||
|
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
|
||||||
|
#cmakedefine DATADIR "${DATADIR}"
|
||||||
|
#cmakedefine LIBDIR "${LIBDIR}"
|
||||||
|
#cmakedefine PLUGINDIR "${PLUGINDIR}"
|
||||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
||||||
#cmakedefine BINARYDIR "${BINARYDIR}"
|
#cmakedefine BINARYDIR "${BINARYDIR}"
|
||||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||||
|
|
||||||
/* Global bind configuration file path */
|
|
||||||
#cmakedefine GLOBAL_BIND_CONFIG "${GLOBAL_BIND_CONFIG}"
|
|
||||||
|
|
||||||
/* Global client configuration file path */
|
|
||||||
#cmakedefine GLOBAL_CLIENT_CONFIG "${GLOBAL_CLIENT_CONFIG}"
|
|
||||||
|
|
||||||
/************************** HEADER FILES *************************/
|
/************************** HEADER FILES *************************/
|
||||||
|
|
||||||
/* Define to 1 if you have the <argp.h> header file. */
|
/* Define to 1 if you have the <argp.h> header file. */
|
||||||
@@ -25,9 +23,6 @@
|
|||||||
/* Define to 1 if you have the <glob.h> header file. */
|
/* Define to 1 if you have the <glob.h> header file. */
|
||||||
#cmakedefine HAVE_GLOB_H 1
|
#cmakedefine HAVE_GLOB_H 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
|
|
||||||
#cmakedefine HAVE_VALGRIND_VALGRIND_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <pty.h> header file. */
|
/* Define to 1 if you have the <pty.h> header file. */
|
||||||
#cmakedefine HAVE_PTY_H 1
|
#cmakedefine HAVE_PTY_H 1
|
||||||
|
|
||||||
@@ -82,13 +77,13 @@
|
|||||||
/* Define to 1 if you have the <pthread.h> header file. */
|
/* Define to 1 if you have the <pthread.h> header file. */
|
||||||
#cmakedefine HAVE_PTHREAD_H 1
|
#cmakedefine HAVE_PTHREAD_H 1
|
||||||
|
|
||||||
/* Define to 1 if you have elliptic curve cryptography in openssl */
|
/* Define to 1 if you have eliptic curve cryptography in openssl */
|
||||||
#cmakedefine HAVE_OPENSSL_ECC 1
|
#cmakedefine HAVE_OPENSSL_ECC 1
|
||||||
|
|
||||||
/* Define to 1 if you have elliptic curve cryptography in gcrypt */
|
/* Define to 1 if you have eliptic curve cryptography in gcrypt */
|
||||||
#cmakedefine HAVE_GCRYPT_ECC 1
|
#cmakedefine HAVE_GCRYPT_ECC 1
|
||||||
|
|
||||||
/* Define to 1 if you have elliptic curve cryptography */
|
/* Define to 1 if you have eliptic curve cryptography */
|
||||||
#cmakedefine HAVE_ECC 1
|
#cmakedefine HAVE_ECC 1
|
||||||
|
|
||||||
/* Define to 1 if you have DSA */
|
/* Define to 1 if you have DSA */
|
||||||
@@ -97,37 +92,22 @@
|
|||||||
/* Define to 1 if you have gl_flags as a glob_t sturct member */
|
/* Define to 1 if you have gl_flags as a glob_t sturct member */
|
||||||
#cmakedefine HAVE_GLOB_GL_FLAGS_MEMBER 1
|
#cmakedefine HAVE_GLOB_GL_FLAGS_MEMBER 1
|
||||||
|
|
||||||
/* Define to 1 if you have OpenSSL with Ed25519 support */
|
|
||||||
#cmakedefine HAVE_OPENSSL_ED25519 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have OpenSSL with X25519 support */
|
|
||||||
#cmakedefine HAVE_OPENSSL_X25519 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have OpenSSL with Poly1305 support */
|
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_POLY1305 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have gcrypt with ChaCha20/Poly1305 support */
|
|
||||||
#cmakedefine HAVE_GCRYPT_CHACHA_POLY 1
|
|
||||||
|
|
||||||
/*************************** FUNCTIONS ***************************/
|
/*************************** FUNCTIONS ***************************/
|
||||||
|
|
||||||
/* Define to 1 if you have the `EVP_chacha20' function. */
|
/* Define to 1 if you have the `EVP_aes128_ctr' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_CHACHA20 1
|
#cmakedefine HAVE_OPENSSL_EVP_AES_CTR 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' or `EVP_KDF_CTX_new` function. */
|
/* Define to 1 if you have the `EVP_aes128_cbc' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX 1
|
#cmakedefine HAVE_OPENSSL_EVP_AES_CBC 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `FIPS_mode' function. */
|
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
|
#cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `EVP_DigestSign' function. */
|
/* Define to 1 if you have the `CRYPTO_ctr128_encrypt' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_DIGESTSIGN 1
|
#cmakedefine HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `EVP_DigestVerify' function. */
|
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_DIGESTVERIFY 1
|
#cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `OPENSSL_ia32cap_loc' function. */
|
|
||||||
#cmakedefine HAVE_OPENSSL_IA32CAP_LOC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `snprintf' function. */
|
/* Define to 1 if you have the `snprintf' function. */
|
||||||
#cmakedefine HAVE_SNPRINTF 1
|
#cmakedefine HAVE_SNPRINTF 1
|
||||||
@@ -198,9 +178,6 @@
|
|||||||
/* Define to 1 if you have the `SecureZeroMemory' function. */
|
/* Define to 1 if you have the `SecureZeroMemory' function. */
|
||||||
#cmakedefine HAVE_SECURE_ZERO_MEMORY 1
|
#cmakedefine HAVE_SECURE_ZERO_MEMORY 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `cmocka_set_test_filter' function. */
|
|
||||||
#cmakedefine HAVE_CMOCKA_SET_TEST_FILTER 1
|
|
||||||
|
|
||||||
/*************************** LIBRARIES ***************************/
|
/*************************** LIBRARIES ***************************/
|
||||||
|
|
||||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||||
@@ -215,22 +192,18 @@
|
|||||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
#cmakedefine HAVE_PTHREAD 1
|
#cmakedefine HAVE_PTHREAD 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `cmocka' library (-lcmocka). */
|
|
||||||
#cmakedefine HAVE_CMOCKA 1
|
|
||||||
|
|
||||||
/**************************** OPTIONS ****************************/
|
/**************************** OPTIONS ****************************/
|
||||||
|
|
||||||
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
|
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
|
||||||
#cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1
|
#cmakedefine HAVE_MSC_THREAD_LOCAL_STORAGE 1
|
||||||
|
|
||||||
#cmakedefine HAVE_FALLTHROUGH_ATTRIBUTE 1
|
#cmakedefine HAVE_FALLTHROUGH_ATTRIBUTE 1
|
||||||
#cmakedefine HAVE_UNUSED_ATTRIBUTE 1
|
|
||||||
#cmakedefine HAVE_WEAK_ATTRIBUTE 1
|
|
||||||
|
|
||||||
#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
|
#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
|
||||||
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
|
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
|
||||||
|
|
||||||
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
|
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
|
||||||
|
#cmakedefine HAVE_GCC_NARG_MACRO 1
|
||||||
|
|
||||||
#cmakedefine HAVE_COMPILER__FUNC__ 1
|
#cmakedefine HAVE_COMPILER__FUNC__ 1
|
||||||
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
|
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
|
||||||
@@ -249,15 +222,6 @@
|
|||||||
/* Define to 1 if you want to enable server support */
|
/* Define to 1 if you want to enable server support */
|
||||||
#cmakedefine WITH_SERVER 1
|
#cmakedefine WITH_SERVER 1
|
||||||
|
|
||||||
/* Define to 1 if you want to enable DH group exchange algorithms */
|
|
||||||
#cmakedefine WITH_GEX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you want to enable none cipher and MAC */
|
|
||||||
#cmakedefine WITH_INSECURE_NONE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you want to enable blowfish cipher support */
|
|
||||||
#cmakedefine WITH_BLOWFISH_CIPHER 1
|
|
||||||
|
|
||||||
/* Define to 1 if you want to enable debug output for crypto functions */
|
/* Define to 1 if you want to enable debug output for crypto functions */
|
||||||
#cmakedefine DEBUG_CRYPTO 1
|
#cmakedefine DEBUG_CRYPTO 1
|
||||||
|
|
||||||
@@ -273,9 +237,6 @@
|
|||||||
/* Define to 1 if you want to enable NaCl support */
|
/* Define to 1 if you want to enable NaCl support */
|
||||||
#cmakedefine WITH_NACL 1
|
#cmakedefine WITH_NACL 1
|
||||||
|
|
||||||
/* Define to 1 if you want to enable PKCS #11 URI support */
|
|
||||||
#cmakedefine WITH_PKCS11_URI 1
|
|
||||||
|
|
||||||
/*************************** ENDIAN *****************************/
|
/*************************** ENDIAN *****************************/
|
||||||
|
|
||||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||||
|
|||||||
@@ -13,13 +13,9 @@ if (DOXYGEN_FOUND)
|
|||||||
set(DOXYGEN_TAB_SIZE 4)
|
set(DOXYGEN_TAB_SIZE 4)
|
||||||
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
|
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
|
||||||
set(DOXYGEN_MARKDOWN_SUPPORT YES)
|
set(DOXYGEN_MARKDOWN_SUPPORT YES)
|
||||||
set(DOXYGEN_FULL_PATH_NAMES NO)
|
|
||||||
|
|
||||||
set(DOXYGEN_PREDEFINED DOXYGEN
|
set(DOXYGEN_PREDEFINED DOXYGEN
|
||||||
WITH_SERVER
|
PRINTF_ATTRIBUTE(x,y))
|
||||||
WITH_SFTP
|
|
||||||
PRINTF_ATTRIBUTE\(x,y\))
|
|
||||||
set(DOXYGEN_DOT_GRAPH_MAX_NODES 100)
|
|
||||||
|
|
||||||
set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style)
|
set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style)
|
||||||
set(DOXYGEN_HTML_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/that_style/header.html)
|
set(DOXYGEN_HTML_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/that_style/header.html)
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
# Install a FreeBSD CI instance
|
|
||||||
|
|
||||||
Install the following packages:
|
|
||||||
|
|
||||||
```
|
|
||||||
pkg install -y bash git gmake cmake cmocka openssl wget pkgconf ccache bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Create gitlab-runner user:
|
|
||||||
|
|
||||||
```
|
|
||||||
pw group add -n gitlab-runner
|
|
||||||
pw user add -n gitlab-runner -g gitlab-runner -s /usr/local/bin/bash
|
|
||||||
mkdir /home/gitlab-runner
|
|
||||||
chown gitlab-runner:gitlab-runner /home/gitlab-runner
|
|
||||||
```
|
|
||||||
|
|
||||||
Get the gitlab-runner binary for freebsd:
|
|
||||||
|
|
||||||
```
|
|
||||||
wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-freebsd-amd64
|
|
||||||
chmod +x /usr/local/bin/gitlab-runner
|
|
||||||
```
|
|
||||||
|
|
||||||
Create a log file and allow access:
|
|
||||||
|
|
||||||
```
|
|
||||||
touch /var/log/gitlab_runner.log && chown gitlab-runner:gitlab-runner /var/log/gitlab_runner.log
|
|
||||||
```
|
|
||||||
|
|
||||||
We need a start script to run it on boot:
|
|
||||||
|
|
||||||
```
|
|
||||||
mkdir -p /usr/local/etc/rc.d
|
|
||||||
cat > /usr/local/etc/rc.d/gitlab_runner << EOF
|
|
||||||
#!/usr/local/bin/bash
|
|
||||||
# PROVIDE: gitlab_runner
|
|
||||||
# REQUIRE: DAEMON NETWORKING
|
|
||||||
# BEFORE:
|
|
||||||
# KEYWORD:
|
|
||||||
|
|
||||||
. /etc/rc.subr
|
|
||||||
|
|
||||||
name="gitlab_runner"
|
|
||||||
rcvar="gitlab_runner_enable"
|
|
||||||
|
|
||||||
load_rc_config $name
|
|
||||||
|
|
||||||
user="gitlab-runner"
|
|
||||||
user_home="/home/gitlab-runner"
|
|
||||||
command="/usr/local/bin/gitlab-runner run"
|
|
||||||
pidfile="/var/run/${name}.pid"
|
|
||||||
|
|
||||||
start_cmd="gitlab_runner_start"
|
|
||||||
stop_cmd="gitlab_runner_stop"
|
|
||||||
status_cmd="gitlab_runner_status"
|
|
||||||
|
|
||||||
gitlab_runner_start()
|
|
||||||
{
|
|
||||||
export USER=${user}
|
|
||||||
export HOME=${user_home}
|
|
||||||
|
|
||||||
if checkyesno ${rcvar}; then
|
|
||||||
cd ${user_home}
|
|
||||||
/usr/sbin/daemon -u ${user} -p ${pidfile} ${command} > /var/log/gitlab_runner.log 2>&1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
gitlab_runner_stop()
|
|
||||||
{
|
|
||||||
if [ -f ${pidfile} ]; then
|
|
||||||
kill `cat ${pidfile}`
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
gitlab_runner_status()
|
|
||||||
{
|
|
||||||
if [ ! -f ${pidfile} ] || kill -0 `cat ${pidfile}`; then
|
|
||||||
echo "Service ${name} is not running."
|
|
||||||
else
|
|
||||||
echo "${name} appears to be running."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
run_rc_command $1
|
|
||||||
EOF
|
|
||||||
chmod +x /usr/local/etc/rc.d/gitlab_runner
|
|
||||||
```
|
|
||||||
|
|
||||||
Register your gitlab-runner with your gitlab project
|
|
||||||
|
|
||||||
```
|
|
||||||
su gitlab-runner -c 'gitlab-runner register'
|
|
||||||
```
|
|
||||||
|
|
||||||
Start the gitlab runner service:
|
|
||||||
|
|
||||||
```
|
|
||||||
sysrc -f /etc/rc.conf "gitlab_runner_enable=YES"
|
|
||||||
service gitlab_runner start
|
|
||||||
```
|
|
||||||
@@ -33,9 +33,6 @@ The process of authenticating by public key to a server is the following:
|
|||||||
used to authenticate the user).
|
used to authenticate the user).
|
||||||
- then, you retrieve the private key for this key and send a message
|
- then, you retrieve the private key for this key and send a message
|
||||||
proving that you know that private key.
|
proving that you know that private key.
|
||||||
- when several identity files are specified, then the order of processing of
|
|
||||||
these files is from the last-mentioned to the first one
|
|
||||||
(if specified in the ~/.ssh/config, then starting from the bottom to the top).
|
|
||||||
|
|
||||||
The function ssh_userauth_autopubkey() does this using the available keys in
|
The function ssh_userauth_autopubkey() does this using the available keys in
|
||||||
"~/.ssh/". The return values are the following:
|
"~/.ssh/". The return values are the following:
|
||||||
@@ -66,7 +63,7 @@ int authenticate_pubkey(ssh_session session)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
rc = ssh_userauth_publickey_auto(session, NULL);
|
||||||
|
|
||||||
if (rc == SSH_AUTH_ERROR)
|
if (rc == SSH_AUTH_ERROR)
|
||||||
{
|
{
|
||||||
@@ -130,7 +127,7 @@ The keyboard-interactive method is, as its name tells, interactive. The
|
|||||||
server will issue one or more challenges that the user has to answer,
|
server will issue one or more challenges that the user has to answer,
|
||||||
until the server takes an authentication decision.
|
until the server takes an authentication decision.
|
||||||
|
|
||||||
ssh_userauth_kbdint() is the the main keyboard-interactive function.
|
ssh_userauth_kbdint() is the the main keyboard-interactive function.
|
||||||
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
|
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
|
||||||
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
|
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
|
||||||
|
|
||||||
@@ -157,9 +154,9 @@ Here are a few remarks:
|
|||||||
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
|
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
|
||||||
- The server can send an empty question set (this is the default behavior
|
- The server can send an empty question set (this is the default behavior
|
||||||
on my system) after you have sent the answers to the first questions.
|
on my system) after you have sent the answers to the first questions.
|
||||||
You must still parse the answer, it might contain some
|
You must still parse the answer, it might contain some
|
||||||
message from the server saying hello or such things. Just call
|
message from the server saying hello or such things. Just call
|
||||||
ssh_userauth_kbdint() until needed.
|
ssh_userauth_kbdint() until needed.
|
||||||
- The meaning of "name", "prompt", "instruction" may be a little
|
- The meaning of "name", "prompt", "instruction" may be a little
|
||||||
confusing. An explanation is given in the RFC section that follows.
|
confusing. An explanation is given in the RFC section that follows.
|
||||||
|
|
||||||
@@ -190,7 +187,7 @@ keyboard-interactive authentication, coming from the RFC itself (rfc4256):
|
|||||||
the name and prompts. If the server presents names or prompts longer than 30
|
the name and prompts. If the server presents names or prompts longer than 30
|
||||||
characters, the client MAY truncate these fields to the length it can
|
characters, the client MAY truncate these fields to the length it can
|
||||||
display. If the client does truncate any fields, there MUST be an obvious
|
display. If the client does truncate any fields, there MUST be an obvious
|
||||||
indication that such truncation has occurred.
|
indication that such truncation has occured.
|
||||||
|
|
||||||
The instruction field SHOULD NOT be truncated. Clients SHOULD use control
|
The instruction field SHOULD NOT be truncated. Clients SHOULD use control
|
||||||
character filtering as discussed in [SSH-ARCH] to avoid attacks by
|
character filtering as discussed in [SSH-ARCH] to avoid attacks by
|
||||||
@@ -284,7 +281,7 @@ pass, ssh_userauth_none() might answer SSH_AUTH_SUCCESS.
|
|||||||
The following example shows how to perform "none" authentication:
|
The following example shows how to perform "none" authentication:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
int authenticate_none(ssh_session session)
|
int authenticate_kbdint(ssh_session session)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ curve25519-sha256@libssh.org.txt Aris Adamantiadis <aris@badcode.be>
|
|||||||
|
|
||||||
1. Introduction
|
1. Introduction
|
||||||
|
|
||||||
This document describes the key exchange method curve25519-sha256@libssh.org
|
This document describes the key exchange methode curve25519-sha256@libssh.org
|
||||||
for SSH version 2 protocol. It is provided as an alternative to the existing
|
for SSH version 2 protocol. It is provided as an alternative to the existing
|
||||||
key exchange mechanisms based on either Diffie-Hellman or Elliptic Curve Diffie-
|
key exchange mechanisms based on either Diffie-Hellman or Elliptic Curve Diffie-
|
||||||
Hellman [RFC5656].
|
Hellman [RFC5656].
|
||||||
The reason is the following : During summer of 2013, revelations from ex-
|
The reason is the following : During summer of 2013, revelations from ex-
|
||||||
consultant at NSA Edward Snowden gave proof that NSA willingly inserts backdoors
|
consultant at NSA Edward Snowden gave proof that NSA willingly inserts backdoors
|
||||||
into software, hardware components and published standards. While it is still
|
into softwares, hardware components and published standards. While it is still
|
||||||
believed that the mathematics behind ECC cryptography are still sound and solid,
|
believed that the mathematics behind ECC cryptography are still sound and solid,
|
||||||
some people (including Bruce Schneier [SCHNEIER]), showed their lack of confidence
|
some people (including Bruce Schneier [SCHNEIER]), showed their lack of confidence
|
||||||
in NIST-published curves such as nistp256, nistp384, nistp521, for which constant
|
in NIST-published curves such as nistp256, nistp384, nistp521, for which constant
|
||||||
@@ -42,8 +42,8 @@ The following is an overview of the key exchange process:
|
|||||||
Client Server
|
Client Server
|
||||||
------ ------
|
------ ------
|
||||||
Generate ephemeral key pair.
|
Generate ephemeral key pair.
|
||||||
SSH_MSG_KEX_ECDH_INIT -------->
|
SSH_MSG_KEX_ECDH_INIT -------->
|
||||||
Verify that client public key
|
Verify that client public key
|
||||||
length is 32 bytes.
|
length is 32 bytes.
|
||||||
Generate ephemeral key pair.
|
Generate ephemeral key pair.
|
||||||
Compute shared secret.
|
Compute shared secret.
|
||||||
@@ -55,7 +55,7 @@ Compute shared secret.
|
|||||||
Generate exchange hash.
|
Generate exchange hash.
|
||||||
Verify server's signature.
|
Verify server's signature.
|
||||||
|
|
||||||
* Optional but strongly recommended as this protects against MITM attacks.
|
* Optional but strongly recommanded as this protects against MITM attacks.
|
||||||
|
|
||||||
This is implemented using the same messages as described in RFC5656 chapter 4
|
This is implemented using the same messages as described in RFC5656 chapter 4
|
||||||
|
|
||||||
@@ -109,11 +109,11 @@ This number is calculated using the following procedure:
|
|||||||
side's public key and the local private key scalar.
|
side's public key and the local private key scalar.
|
||||||
|
|
||||||
The whole 32 bytes of the number X are then converted into a big integer k.
|
The whole 32 bytes of the number X are then converted into a big integer k.
|
||||||
This conversion follows the network byte order. This step differs from
|
This conversion follows the network byte order. This step differs from
|
||||||
RFC5656.
|
RFC5656.
|
||||||
|
|
||||||
[RFC5656] https://tools.ietf.org/html/rfc5656
|
[RFC5656] http://tools.ietf.org/html/rfc5656
|
||||||
[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929
|
[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929
|
||||||
[DJB] https://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
|
[DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
|
||||||
[Curve25519] "Curve25519: new Diffie-Hellman speed records."
|
[Curve25519] "Curve25519: new Diffie-Hellman speed records."
|
||||||
https://cr.yp.to/ecdh/curve25519-20060209.pdf
|
http://cr.yp.to/ecdh/curve25519-20060209.pdf
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Port forwarding comes in SSH protocol in two different flavours:
|
Port forwarding comes in SSH protocol in two different flavours:
|
||||||
direct or reverse port forwarding. Direct port forwarding is also
|
direct or reverse port forwarding. Direct port forwarding is also
|
||||||
named local port forwarding, and reverse port forwarding is also called
|
named local port forwardind, and reverse port forwarding is also called
|
||||||
remote port forwarding. SSH also allows X11 tunnels.
|
remote port forwarding. SSH also allows X11 tunnels.
|
||||||
|
|
||||||
|
|
||||||
@@ -23,15 +23,15 @@ Mail client application Google Mail
|
|||||||
5555 (arbitrary) |
|
5555 (arbitrary) |
|
||||||
| 143 (IMAP2)
|
| 143 (IMAP2)
|
||||||
V |
|
V |
|
||||||
SSH client =====> SSH server
|
SSH client =====> SSH server
|
||||||
|
|
||||||
Legend:
|
Legend:
|
||||||
--P-->: port connections through port P
|
--P-->: port connexion through port P
|
||||||
=====>: SSH tunnel
|
=====>: SSH tunnel
|
||||||
@endverbatim
|
@endverbatim
|
||||||
A mail client connects to port 5555 of a client. An encrypted tunnel is
|
A mail client connects to port 5555 of a client. An encrypted tunnel is
|
||||||
established to the server. The server connects to port 143 of Google Mail (the
|
established to the server. The server connects to port 143 of Google Mail (the
|
||||||
end point). Now the local mail client can retrieve mail.
|
end point). Now the local mail client can retreive mail.
|
||||||
|
|
||||||
|
|
||||||
@subsection forwarding_reverse Reverse port forwarding
|
@subsection forwarding_reverse Reverse port forwarding
|
||||||
@@ -51,7 +51,7 @@ Example of use of reverse port forwarding:
|
|||||||
SSH client <===== SSH server
|
SSH client <===== SSH server
|
||||||
|
|
||||||
Legend:
|
Legend:
|
||||||
--P-->: port connections through port P
|
--P-->: port connexion through port P
|
||||||
=====>: SSH tunnel
|
=====>: SSH tunnel
|
||||||
@endverbatim
|
@endverbatim
|
||||||
In this example, the SSH client establishes the tunnel,
|
In this example, the SSH client establishes the tunnel,
|
||||||
@@ -101,7 +101,7 @@ used to retrieve google's home page from the remote SSH server.
|
|||||||
int direct_forwarding(ssh_session session)
|
int direct_forwarding(ssh_session session)
|
||||||
{
|
{
|
||||||
ssh_channel forwarding_channel;
|
ssh_channel forwarding_channel;
|
||||||
int rc = SSH_ERROR;
|
int rc;
|
||||||
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
|
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
|
||||||
int nbytes, nwritten;
|
int nbytes, nwritten;
|
||||||
|
|
||||||
@@ -148,9 +148,9 @@ To do reverse port forwarding, call ssh_channel_listen_forward(),
|
|||||||
then ssh_channel_accept_forward().
|
then ssh_channel_accept_forward().
|
||||||
|
|
||||||
When you call ssh_channel_listen_forward(), you can let the remote server
|
When you call ssh_channel_listen_forward(), you can let the remote server
|
||||||
chose the non-privileged port it should listen to. Otherwise, you can chose
|
chose the non-priviledged port it should listen to. Otherwise, you can chose
|
||||||
your own privileged or non-privileged port. Beware that you should have
|
your own priviledged or non-priviledged port. Beware that you should have
|
||||||
administrative privileges on the remote server to open a privileged port
|
administrative priviledges on the remote server to open a priviledged port
|
||||||
(port number < 1024).
|
(port number < 1024).
|
||||||
|
|
||||||
Below is an example of a very rough web server waiting for connections on port
|
Below is an example of a very rough web server waiting for connections on port
|
||||||
@@ -165,8 +165,6 @@ int web_server(ssh_session session)
|
|||||||
char buffer[256];
|
char buffer[256];
|
||||||
int nbytes, nwritten;
|
int nbytes, nwritten;
|
||||||
int port = 0;
|
int port = 0;
|
||||||
char *peer_address = NULL;
|
|
||||||
int peer_port = 0;
|
|
||||||
char *helloworld = ""
|
char *helloworld = ""
|
||||||
"HTTP/1.1 200 OK\n"
|
"HTTP/1.1 200 OK\n"
|
||||||
"Content-Type: text/html\n"
|
"Content-Type: text/html\n"
|
||||||
@@ -189,8 +187,7 @@ int web_server(ssh_session session)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = ssh_channel_open_forward_port(session, 60000, &port,
|
channel = ssh_channel_accept_forward(session, 60000, &port);
|
||||||
&peer_address, &peer_port);
|
|
||||||
if (channel == NULL)
|
if (channel == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error waiting for incoming connection: %s\n",
|
fprintf(stderr, "Error waiting for incoming connection: %s\n",
|
||||||
@@ -207,7 +204,6 @@ int web_server(ssh_session session)
|
|||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
ssh_channel_send_eof(channel);
|
ssh_channel_send_eof(channel);
|
||||||
ssh_channel_free(channel);
|
ssh_channel_free(channel);
|
||||||
ssh_string_free_char(peer_address);
|
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if (strncmp(buffer, "GET /", 5)) continue;
|
if (strncmp(buffer, "GET /", 5)) continue;
|
||||||
@@ -220,15 +216,13 @@ int web_server(ssh_session session)
|
|||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
ssh_channel_send_eof(channel);
|
ssh_channel_send_eof(channel);
|
||||||
ssh_channel_free(channel);
|
ssh_channel_free(channel);
|
||||||
ssh_string_free_char(peer_address);
|
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
printf("Sent answer to %s:%d\n", peer_address, peer_port);
|
printf("Sent answer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_channel_send_eof(channel);
|
ssh_channel_send_eof(channel);
|
||||||
ssh_channel_free(channel);
|
ssh_channel_free(channel);
|
||||||
ssh_string_free_char(peer_address);
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|||||||
@@ -31,20 +31,20 @@ A SSH session goes through the following steps:
|
|||||||
- Invoke your own subsystem. This is outside the scope of this document,
|
- Invoke your own subsystem. This is outside the scope of this document,
|
||||||
but can be done.
|
but can be done.
|
||||||
|
|
||||||
- When everything is finished, just close the channels, and then the connection.
|
- When everything is finished, just close the channels, and then the connection.
|
||||||
|
|
||||||
The sftp and scp subsystems use channels, but libssh hides them to
|
The sftp and scp subsystems use channels, but libssh hides them to
|
||||||
the programmer. If you want to use those subsystems, instead of a channel,
|
the programmer. If you want to use those subsystems, instead of a channel,
|
||||||
you'll usually open a "sftp session" or a "scp session".
|
you'll usually open a "sftp session" or a "scp session".
|
||||||
|
|
||||||
|
|
||||||
@subsection setup Creating the session and setting options
|
@subsection setup Creating the session and setting options
|
||||||
|
|
||||||
The most important object in a SSH connection is the SSH session. In order
|
The most important object in a SSH connection is the SSH session. In order
|
||||||
to allocate a new SSH session, you use ssh_new(). Don't forget to
|
to allocate a new SSH session, you use ssh_new(). Don't forget to
|
||||||
always verify that the allocation succeeded.
|
always verify that the allocation successed.
|
||||||
@code
|
@code
|
||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -69,12 +69,12 @@ The ssh_options_set() function sets the options of the session. The most importa
|
|||||||
|
|
||||||
The complete list of options can be found in the documentation of ssh_options_set().
|
The complete list of options can be found in the documentation of ssh_options_set().
|
||||||
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
|
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
|
||||||
the local username of your account will be used.
|
the local username of your account will be used.
|
||||||
|
|
||||||
Here is a small example of how to use it:
|
Here is a small example of how to use it:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -122,7 +122,7 @@ Here's an example:
|
|||||||
@code
|
@code
|
||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -285,9 +285,9 @@ int verify_knownhost(ssh_session session)
|
|||||||
|
|
||||||
The authentication process is the way a service provider can identify a
|
The authentication process is the way a service provider can identify a
|
||||||
user and verify his/her identity. The authorization process is about enabling
|
user and verify his/her identity. The authorization process is about enabling
|
||||||
the authenticated user the access to resources. In SSH, the two concepts
|
the authenticated user the access to ressources. In SSH, the two concepts
|
||||||
are linked. After authentication, the server can grant the user access to
|
are linked. After authentication, the server can grant the user access to
|
||||||
several resources such as port forwarding, shell, sftp subsystem, and so on.
|
several ressources such as port forwarding, shell, sftp subsystem, and so on.
|
||||||
|
|
||||||
libssh supports several methods of authentication:
|
libssh supports several methods of authentication:
|
||||||
- "none" method. This method allows to get the available authentications
|
- "none" method. This method allows to get the available authentications
|
||||||
@@ -313,7 +313,7 @@ The example below shows an authentication with password:
|
|||||||
@code
|
@code
|
||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -338,7 +338,7 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the server's identity
|
// Verify the server's identity
|
||||||
// For the source code of verify_knownhost(), check previous example
|
// For the source code of verify_knowhost(), check previous example
|
||||||
if (verify_knownhost(my_ssh_session) < 0)
|
if (verify_knownhost(my_ssh_session) < 0)
|
||||||
{
|
{
|
||||||
ssh_disconnect(my_ssh_session);
|
ssh_disconnect(my_ssh_session);
|
||||||
@@ -415,7 +415,7 @@ int show_remote_processes(ssh_session session)
|
|||||||
}
|
}
|
||||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
ssh_channel_close(channel);
|
ssh_channel_close(channel);
|
||||||
@@ -431,9 +431,6 @@ int show_remote_processes(ssh_session session)
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Each ssh_channel_request_exec() needs to be run on freshly created
|
|
||||||
and connected (with ssh_channel_open_session()) channel.
|
|
||||||
|
|
||||||
@see @ref opening_shell
|
@see @ref opening_shell
|
||||||
@see @ref remote_command
|
@see @ref remote_command
|
||||||
@see @ref sftp_subsystem
|
@see @ref sftp_subsystem
|
||||||
@@ -459,7 +456,7 @@ might be recoverable. SSH_FATAL means the connection has an important
|
|||||||
problem and isn't probably recoverable.
|
problem and isn't probably recoverable.
|
||||||
|
|
||||||
Most of time, the error returned are SSH_FATAL, but some functions
|
Most of time, the error returned are SSH_FATAL, but some functions
|
||||||
(generally the ssh_request_xxx ones) may fail because of server denying request.
|
(generaly the ssh_request_xxx ones) may fail because of server denying request.
|
||||||
In these cases, SSH_REQUEST_DENIED is returned.
|
In these cases, SSH_REQUEST_DENIED is returned.
|
||||||
|
|
||||||
For thread safety, errors are bound to ssh_session objects.
|
For thread safety, errors are bound to ssh_session objects.
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ mean that you should not try to know about and understand these details.
|
|||||||
|
|
||||||
libssh is a Free Software / Open Source project. The libssh library
|
libssh is a Free Software / Open Source project. The libssh library
|
||||||
is distributed under LGPL license. The libssh project has nothing to do with
|
is distributed under LGPL license. The libssh project has nothing to do with
|
||||||
"libssh2", which is a completely different and independent project.
|
"libssh2", which is a completly different and independant project.
|
||||||
|
|
||||||
libssh can run on top of either libgcrypt or libcrypto,
|
libssh can run on top of either libgcrypt or libcrypto,
|
||||||
two general-purpose cryptographic libraries.
|
two general-purpose cryptographic libraries.
|
||||||
|
|
||||||
This tutorial concentrates for its main part on the "client" side of libssh.
|
This tutorial concentrates for its main part on the "client" side of libssh.
|
||||||
To learn how to accept incoming SSH connections (how to write a SSH server),
|
To learn how to accept incoming SSH connexions (how to write a SSH server),
|
||||||
you'll have to jump to the end of this document.
|
you'll have to jump to the end of this document.
|
||||||
|
|
||||||
This tutorial describes libssh version 0.5.0. This version is a little different
|
This tutorial describes libssh version 0.5.0. This version is a little different
|
||||||
|
|||||||
@@ -27,7 +27,4 @@ the dllimport attribute.
|
|||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If you're are statically linking with OpenSSL, read the "Linking your
|
|
||||||
application" section in the NOTES.[OS] in the OpenSSL source tree!
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
100
doc/mainpage.dox
100
doc/mainpage.dox
@@ -21,9 +21,9 @@ The libssh library provides:
|
|||||||
|
|
||||||
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
|
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
|
||||||
- <strong>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>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
|
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
|
||||||
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
||||||
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5
|
- <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>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
|
||||||
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
|
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
|
||||||
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
|
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
|
||||||
@@ -38,9 +38,9 @@ The libssh library provides:
|
|||||||
@section main-additional-features Additional Features
|
@section main-additional-features Additional Features
|
||||||
|
|
||||||
- Client <b>and</b> server support
|
- Client <b>and</b> server support
|
||||||
- SSHv2 protocol support
|
- SSHv2 and SSHv1 protocol support
|
||||||
- Supports <a href="https://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
|
- Supports <a href="http://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
|
||||||
- Automated test cases with nightly <a href="https://test.libssh.org/" target="_blank">tests</a>
|
- Automated test cases with nightly <a href="http://test.libssh.org/" target="_blank">tests</a>
|
||||||
- Event model based on poll(2), or a poll(2)-emulation.
|
- Event model based on poll(2), or a poll(2)-emulation.
|
||||||
|
|
||||||
@section main-copyright Copyright Policy
|
@section main-copyright Copyright Policy
|
||||||
@@ -111,7 +111,7 @@ By making a contribution to this project, I certify that:
|
|||||||
Free Software Foundation; either version 2.1 of
|
Free Software Foundation; either version 2.1 of
|
||||||
the License, or (at the option of the project) any later version.
|
the License, or (at the option of the project) any later version.
|
||||||
|
|
||||||
https://www.gnu.org/licenses/lgpl-2.1.html
|
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
@endverbatim
|
@endverbatim
|
||||||
|
|
||||||
We will maintain a copy of that email as a record that you have the rights to
|
We will maintain a copy of that email as a record that you have the rights to
|
||||||
@@ -149,83 +149,49 @@ The libssh Team
|
|||||||
|
|
||||||
@subsection main-rfc-secsh Secure Shell (SSH)
|
@subsection main-rfc-secsh Secure Shell (SSH)
|
||||||
|
|
||||||
The following RFC documents described SSH-2 protocol as an Internet standard.
|
The following RFC documents described SSH-2 protcol as an Internet standard.
|
||||||
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
|
- <a href="http://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
|
||||||
The Secure Shell (SSH) Protocol Assigned Numbers
|
The Secure Shell (SSH) Protocol Assigned Numbers
|
||||||
- <a href="https://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
|
- <a href="http://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
|
||||||
The Secure Shell (SSH) Protocol Architecture
|
The Secure Shell (SSH) Protocol Architecture
|
||||||
- <a href="https://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
|
- <a href="http://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
|
||||||
The Secure Shell (SSH) Authentication Protocol
|
The Secure Shell (SSH) Authentication Protocol
|
||||||
- <a href="https://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
|
- <a href="http://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
|
||||||
The Secure Shell (SSH) Transport Layer Protocol
|
The Secure Shell (SSH) Transport Layer Protocol
|
||||||
- <a href="https://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
|
- <a href="http://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
|
||||||
The Secure Shell (SSH) Connection Protocol
|
The Secure Shell (SSH) Connection Protocol
|
||||||
- <a href="https://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
|
- <a href="http://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
|
||||||
Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
||||||
(not implemented in libssh)
|
- <a href="http://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
|
||||||
- <a href="https://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
|
|
||||||
Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
|
Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
|
||||||
- <a href="https://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
|
- <a href="http://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
|
||||||
The Secure Shell (SSH) Session Channel Break Extension
|
The Secure Shell (SSH) Session Channel Break Extension
|
||||||
- <a href="https://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
|
- <a href="http://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
|
||||||
The Secure Shell (SSH) Transport Layer Encryption Modes
|
The Secure Shell (SSH) Transport Layer Encryption Modes
|
||||||
- <a href="https://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
|
- <a href="http://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
|
||||||
Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
|
Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
|
||||||
|
|
||||||
It was later modified and expanded by the following RFCs.
|
It was later modified and expanded by the following RFCs.
|
||||||
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
|
- <a href="http://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
|
||||||
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
|
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
|
||||||
Protocol
|
Protocol
|
||||||
- <a href="https://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
|
- <a href="http://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
|
||||||
RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
|
RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
|
||||||
(not implemented in libssh)
|
- <a href="http://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
|
||||||
- <a href="https://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
|
|
||||||
Generic Security Service Application Program Interface (GSS-API)
|
Generic Security Service Application Program Interface (GSS-API)
|
||||||
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
||||||
(only the authentication implemented in libssh)
|
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
||||||
- <a href="https://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
|
||||||
The Secure Shell (SSH) Public Key File Format
|
The Secure Shell (SSH) Public Key File Format
|
||||||
(not implemented in libssh)
|
- <a href="http://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
|
||||||
- <a href="https://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
|
|
||||||
AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
|
AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
|
||||||
(the algorithm negotiation implemented according to openssh.com)
|
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
||||||
- <a href="https://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
|
||||||
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
||||||
- <a href="https://tools.ietf.org/html/rfc6594" target="_blank">RFC 6594</a>,
|
|
||||||
Use of the SHA-256 Algorithm with RSA, DSA, and ECDSA in SSHFP Resource Records
|
|
||||||
(not implemented in libssh)
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc6668" target="_blank">RFC 6668</a>,
|
|
||||||
SHA-2 Data Integrity Verification for the Secure Shell (SSH) Transport Layer Protocol
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc7479" target="_blank">RFC 7479</a>,
|
|
||||||
Using Ed25519 in SSHFP Resource Records
|
|
||||||
(not implemented in libssh)
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc8160" target="_blank">RFC 8160</a>,
|
|
||||||
IUTF8 Terminal Mode in Secure Shell (SSH)
|
|
||||||
(not handled in libssh)
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc8270" target="_blank">RFC 8270</a>,
|
|
||||||
Increase the Secure Shell Minimum Recommended Diffie-Hellman Modulus Size to 2048 Bits
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc8308" target="_blank">RFC 8308</a>,
|
|
||||||
Extension Negotiation in the Secure Shell (SSH) Protocol
|
|
||||||
(only the "server-sig-algs" extension implemented)
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc8332" target="_blank">RFC 8332</a>,
|
|
||||||
Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc8709" target="_blank">RFC 8709</a>,
|
|
||||||
Ed25519 and Ed448 Public Key Algorithms for the Secure Shell (SSH) Protocol
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc8709" target="_blank">RFC 8731</a>,
|
|
||||||
Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448
|
|
||||||
- <a href="https://tools.ietf.org/html/rfc9142" target="_blank">RFC 9142</a>,
|
|
||||||
Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)
|
|
||||||
|
|
||||||
There are also drafts that are being currently developed and followed.
|
|
||||||
|
|
||||||
- <a href="https://tools.ietf.org/html/draft-miller-ssh-agent-03" target="_blank">draft-miller-ssh-agent-08</a>
|
|
||||||
SSH Agent Protocol
|
|
||||||
|
|
||||||
Interesting cryptography documents:
|
Interesting cryptography documents:
|
||||||
|
|
||||||
- <a href="https://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
|
- <a href="http://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
|
||||||
|
|
||||||
@subsection main-rfc-sftp Secure Shell File Transfer Protocol (SFTP)
|
@subsection main-rfc-sftp Secure Shell File Transfer Protocol (SFTP)
|
||||||
|
|
||||||
@@ -233,22 +199,26 @@ The protocol is not an Internet standard but it is still widely implemented.
|
|||||||
OpenSSH and most other implementation implement Version 3 of the protocol. We
|
OpenSSH and most other implementation implement Version 3 of the protocol. We
|
||||||
do the same in libssh.
|
do the same in libssh.
|
||||||
|
|
||||||
- <a href="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
|
- <a href="http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
|
||||||
draft-ietf-secsh-filexfer-02.txt</a>,
|
draft-ietf-secsh-filexfer-02.txt</a>,
|
||||||
SSH File Transfer Protocol
|
SSH File Transfer Protocol
|
||||||
|
|
||||||
@subsection main-rfc-extensions Secure Shell Extensions
|
@subsection main-rfc-extensions Secure Shell Extensions
|
||||||
|
|
||||||
|
The libssh project has an extension to support Curve25519 which is also supported by
|
||||||
|
the OpenSSH project.
|
||||||
|
|
||||||
|
- <a href="http://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt" target="_blank">curve25519-sha256@libssh.org</a>,
|
||||||
|
Curve25519-SHA256 for ECDH KEX
|
||||||
|
|
||||||
The OpenSSH project has defined some extensions to the protocol. We support some of
|
The OpenSSH project has defined some extensions to the protocol. We support some of
|
||||||
them like the statvfs calls in SFTP or the ssh-agent.
|
them like the statvfs calls in SFTP or the ssh-agent.
|
||||||
|
|
||||||
- <a href="https://api.libssh.org/rfc/PROTOCOL" target="_blank">
|
- <a href="http://api.libssh.org/rfc/PROTOCOL" target="_blank">
|
||||||
OpenSSH's deviations and extensions</a>
|
OpenSSH's deviations and extensions</a>
|
||||||
- <a href="https://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
|
- <a href="http://api.libssh.org/rfc/PROTOCOL.agent" target="_blank">
|
||||||
|
OpenSSH's ssh-agent</a>
|
||||||
|
- <a href="http://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
|
||||||
OpenSSH's pubkey certificate authentication</a>
|
OpenSSH's pubkey certificate authentication</a>
|
||||||
- <a href="https://api.libssh.org/rfc/PROTOCOL.chacha20poly1305" target="_blank">
|
|
||||||
chacha20-poly1305@openssh.com authenticated encryption mode</a>
|
|
||||||
- <a href="https://api.libssh.org/rfc/PROTOCOL.key" target="_blank">
|
|
||||||
OpenSSH private key format (openssh-key-v1)</a>
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
/**
|
|
||||||
@page libssh_tutor_pkcs11 Chapter 9: Authentication using PKCS #11 URIs
|
|
||||||
@section how_to How to use PKCS #11 URIs in libssh?
|
|
||||||
|
|
||||||
PKCS #11 is a Cryptographic Token Interface Standard that provides an API
|
|
||||||
to devices like smart cards that store cryptographic private information.
|
|
||||||
Such cryptographic devices are referenced as tokens. A mechanism through which
|
|
||||||
objects stored on the tokens can be uniquely identified is called PKCS #11 URI
|
|
||||||
(Uniform Resource Identifier) and is defined in RFC 7512
|
|
||||||
(https://tools.ietf.org/html/rfc7512).
|
|
||||||
|
|
||||||
Pre-requisites:
|
|
||||||
|
|
||||||
OpenSSL defines an abstract layer called the "engine" to achieve cryptographic
|
|
||||||
acceleration. The engine_pkcs11 module acts like an interface between the PKCS #11
|
|
||||||
modules and the OpenSSL engine.
|
|
||||||
|
|
||||||
To build and use libssh with PKCS #11 support:
|
|
||||||
1. Enable the cmake option: $ cmake -DWITH_PKCS11_URI=ON
|
|
||||||
2. Build with OpenSSL.
|
|
||||||
3. Install and configure engine_pkcs11 (https://github.com/OpenSC/libp11).
|
|
||||||
4. Plug in a working smart card or configure softhsm (https://www.opendnssec.org/softhsm).
|
|
||||||
|
|
||||||
The functions ssh_pki_import_pubkey_file() and ssh_pki_import_privkey_file() that
|
|
||||||
import the public and private keys from files respectively are now modified to support
|
|
||||||
PKCS #11 URIs. These functions automatically detect if the provided filename is a file path
|
|
||||||
or a PKCS #11 URI (when it begins with "pkcs11:"). If a PKCS #11 URI is detected,
|
|
||||||
the engine is loaded and initialized. Through the engine, the private/public key
|
|
||||||
corresponding to the PKCS #11 URI are loaded from the PKCS #11 device.
|
|
||||||
|
|
||||||
If you wish to authenticate using public keys on your own, follow the steps mentioned under
|
|
||||||
"Authentication with public keys" in Chapter 2 - A deeper insight into authentication.
|
|
||||||
|
|
||||||
The function pki_uri_import() is used to populate the public/private ssh_key from the
|
|
||||||
engine with PKCS #11 URIs as the look up.
|
|
||||||
|
|
||||||
Here is a minimalistic example of public key authentication using PKCS #11 URIs:
|
|
||||||
|
|
||||||
@code
|
|
||||||
int authenticate_pkcs11_URI(ssh_session session)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
char priv_uri[1042] = "pkcs11:token=my-token;object=my-object;type=private?pin-value=1234";
|
|
||||||
|
|
||||||
rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, priv_uri);
|
|
||||||
assert_int_equal(rc, SSH_OK)
|
|
||||||
|
|
||||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
|
||||||
|
|
||||||
if (rc == SSH_AUTH_ERROR)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Authentication with PKCS #11 URIs failed: %s\n",
|
|
||||||
ssh_get_error(session));
|
|
||||||
return SSH_AUTH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@subsection Caveats
|
|
||||||
|
|
||||||
We recommend the users to provide a specific PKCS #11 URI so that it matches only a single slot in the engine.
|
|
||||||
If the engine discovers multiple slots that could potentially contain the private keys referenced
|
|
||||||
by the provided PKCS #11 URI, the engine will not try to authenticate.
|
|
||||||
|
|
||||||
*/
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
@page libssh_tutor_scp Chapter 6: The SCP subsystem
|
@page libssh_tutor_scp Chapter 6: The SCP subsystem
|
||||||
@section scp_subsystem The SCP subsystem
|
@section scp_subsystem The SCP subsystem
|
||||||
|
|
||||||
The SCP subsystem has far less functionality than the SFTP subsystem.
|
The SCP subsystem has far less functionnality than the SFTP subsystem.
|
||||||
However, if you only need to copy files from and to the remote system,
|
However, if you only need to copy files from and to the remote system,
|
||||||
it does its job.
|
it does its job.
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ Let's say you want to copy the following tree of files to the remote site:
|
|||||||
+-- file1
|
+-- file1
|
||||||
+-- B --+
|
+-- B --+
|
||||||
| +-- file2
|
| +-- file2
|
||||||
-- A --+
|
-- A --+
|
||||||
| +-- file3
|
| +-- file3
|
||||||
+-- C --+
|
+-- C --+
|
||||||
+-- file4
|
+-- file4
|
||||||
@@ -210,7 +210,7 @@ int scp_receive(ssh_session session, ssh_scp scp)
|
|||||||
size = ssh_scp_request_get_size(scp);
|
size = ssh_scp_request_get_size(scp);
|
||||||
filename = strdup(ssh_scp_request_get_filename(scp));
|
filename = strdup(ssh_scp_request_get_filename(scp));
|
||||||
mode = ssh_scp_request_get_permissions(scp);
|
mode = ssh_scp_request_get_permissions(scp);
|
||||||
printf("Receiving file %s, size %d, permissions 0%o\n",
|
printf("Receiving file %s, size %d, permisssions 0%o\n",
|
||||||
filename, size, mode);
|
filename, size, mode);
|
||||||
free(filename);
|
free(filename);
|
||||||
|
|
||||||
|
|||||||
10
doc/sftp.dox
10
doc/sftp.dox
@@ -61,7 +61,7 @@ int sftp_helloworld(ssh_session session)
|
|||||||
rc = sftp_init(sftp);
|
rc = sftp_init(sftp);
|
||||||
if (rc != SSH_OK)
|
if (rc != SSH_OK)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error initializing SFTP session: code %d.\n",
|
fprintf(stderr, "Error initializing SFTP session: %s.\n",
|
||||||
sftp_get_error(sftp));
|
sftp_get_error(sftp));
|
||||||
sftp_free(sftp);
|
sftp_free(sftp);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -100,7 +100,7 @@ Possible errors are:
|
|||||||
|
|
||||||
@subsection sftp_mkdir Creating a directory
|
@subsection sftp_mkdir Creating a directory
|
||||||
|
|
||||||
The function sftp_mkdir() takes the "SFTP session" we just created as
|
The function sftp_mkdir() tahes the "SFTP session" we juste created as
|
||||||
its first argument. It also needs the name of the file to create, and the
|
its first argument. It also needs the name of the file to create, and the
|
||||||
desired permissions. The permissions are the same as for the usual mkdir()
|
desired permissions. The permissions are the same as for the usual mkdir()
|
||||||
function. To get a comprehensive list of the available permissions, use the
|
function. To get a comprehensive list of the available permissions, use the
|
||||||
@@ -358,19 +358,19 @@ int sftp_read_async(ssh_session session, sftp_session sftp)
|
|||||||
@subsection sftp_ls Listing the contents of a directory
|
@subsection sftp_ls Listing the contents of a directory
|
||||||
|
|
||||||
The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(),
|
The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(),
|
||||||
and sftp_closedir() enable to list the contents of a directory.
|
and sftp_closedir() enable to list the contents of a directory.
|
||||||
They use a new handle_type, "sftp_dir", which gives access to the
|
They use a new handle_type, "sftp_dir", which gives access to the
|
||||||
directory being read.
|
directory being read.
|
||||||
|
|
||||||
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
|
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
|
||||||
to a structure with information about a directory entry:
|
to a structure with informations about a directory entry:
|
||||||
- name: the name of the file or directory
|
- name: the name of the file or directory
|
||||||
- size: its size in bytes
|
- size: its size in bytes
|
||||||
- etc.
|
- etc.
|
||||||
|
|
||||||
sftp_readdir() might return NULL under two conditions:
|
sftp_readdir() might return NULL under two conditions:
|
||||||
- when the end of the directory has been met
|
- when the end of the directory has been met
|
||||||
- when an error occurred
|
- when an error occured
|
||||||
|
|
||||||
To tell the difference, call sftp_dir_eof().
|
To tell the difference, call sftp_dir_eof().
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ int interactive_shell_session(ssh_channel channel)
|
|||||||
|
|
||||||
Of course, this is a poor terminal emulator, since the echo from the keys
|
Of course, this is a poor terminal emulator, since the echo from the keys
|
||||||
pressed should not be done locally, but should be done by the remote side.
|
pressed should not be done locally, but should be done by the remote side.
|
||||||
Also, user's input should not be sent once "Enter" key is pressed, but
|
Also, user's input should not be sent once "Enter" key is pressed, but
|
||||||
immediately after each key is pressed. This can be accomplished
|
immediately after each key is pressed. This can be accomplished
|
||||||
by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
|
by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
|
||||||
cfmakeraw() is a standard function under Linux, on other systems you can
|
cfmakeraw() is a standard function under Linux, on other systems you can
|
||||||
@@ -245,13 +245,13 @@ provide a more elegant way to wait for data coming from many sources.
|
|||||||
|
|
||||||
The functions ssh_select() and ssh_channel_select() remind of the standard
|
The functions ssh_select() and ssh_channel_select() remind of the standard
|
||||||
UNIX select(2) function. The idea is to wait for "something" to happen:
|
UNIX select(2) function. The idea is to wait for "something" to happen:
|
||||||
incoming data to be read, outgoing data to block, or an exception to
|
incoming data to be read, outcoming data to block, or an exception to
|
||||||
occur. Both these functions do a "passive wait", i.e. you can safely use
|
occur. Both these functions do a "passive wait", i.e. you can safely use
|
||||||
them repeatedly in a loop, it will not consume exaggerate processor time
|
them repeatedly in a loop, it will not consume exaggerate processor time
|
||||||
and make your computer unresponsive. It is quite common to use these
|
and make your computer unresponsive. It is quite common to use these
|
||||||
functions in your application's main loop.
|
functions in your application's main loop.
|
||||||
|
|
||||||
The difference between ssh_select() and ssh_channel_select() is that
|
The difference between ssh_select() and ssh_channel_select() is that
|
||||||
ssh_channel_select() is simpler, but allows you only to watch SSH channels.
|
ssh_channel_select() is simpler, but allows you only to watch SSH channels.
|
||||||
ssh_select() is more complete and enables watching regular file descriptors
|
ssh_select() is more complete and enables watching regular file descriptors
|
||||||
as well, in the same function call.
|
as well, in the same function call.
|
||||||
@@ -320,36 +320,18 @@ int interactive_shell_session(ssh_session session, ssh_channel channel)
|
|||||||
If your remote application is graphical, you can forward the X11 protocol to
|
If your remote application is graphical, you can forward the X11 protocol to
|
||||||
your local computer.
|
your local computer.
|
||||||
|
|
||||||
To do that, you first declare a callback to manage channel_open_request_x11_function.
|
To do that, you first declare that you accept X11 connections with
|
||||||
Then you create the forwarding tunnel for the X11 protocol with ssh_channel_request_x11().
|
ssh_channel_accept_x11(). Then you create the forwarding tunnel for
|
||||||
|
the X11 protocol with ssh_channel_request_x11().
|
||||||
|
|
||||||
The following code performs channel initialization and shell session
|
The following code performs channel initialization and shell session
|
||||||
opening, and handles a parallel X11 connection:
|
opening, and handles a parallel X11 connection:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#include <libssh/callbacks.h>
|
|
||||||
|
|
||||||
ssh_channel x11channel = NULL;
|
|
||||||
|
|
||||||
ssh_channel x11_open_request_callback(ssh_session session, const char *shost, int sport, void *userdata)
|
|
||||||
{
|
|
||||||
x11channel = ssh_channel_new(session);
|
|
||||||
return x11channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
int interactive_shell_session(ssh_channel channel)
|
int interactive_shell_session(ssh_channel channel)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
ssh_channel x11channel;
|
||||||
struct ssh_callbacks_struct cb =
|
|
||||||
{
|
|
||||||
.channel_open_request_x11_function = x11_open_request_callback,
|
|
||||||
.userdata = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
ssh_callbacks_init(&cb);
|
|
||||||
rc = ssh_set_callbacks(session, &cb);
|
|
||||||
if (rc != SSH_OK) return rc;
|
|
||||||
|
|
||||||
rc = ssh_channel_request_pty(channel);
|
rc = ssh_channel_request_pty(channel);
|
||||||
if (rc != SSH_OK) return rc;
|
if (rc != SSH_OK) return rc;
|
||||||
@@ -368,15 +350,12 @@ int interactive_shell_session(ssh_channel channel)
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Don't forget to check the $DISPLAY environment variable on the remote
|
Don't forget to set the $DISPLAY environment variable on the remote
|
||||||
side, or the remote applications won't try using the X11 tunnel:
|
side, or the remote applications won't try using the X11 tunnel:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
$ echo $DISPLAY
|
$ export DISPLAY=:0
|
||||||
localhost:10.0
|
|
||||||
$ xclock &
|
$ xclock &
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
See an implementation example at https://gitlab.com/libssh/libssh-mirror/-/tree/master/examples/ssh_X11_client.c for details.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ libssh may be used in multithreaded applications, but under several conditions :
|
|||||||
- If libssh is statically linked, threading must be initialized by calling
|
- If libssh is statically linked, threading must be initialized by calling
|
||||||
ssh_init() before using any of libssh provided functions. This initialization
|
ssh_init() before using any of libssh provided functions. This initialization
|
||||||
must be done outside of any threading context. Don't forget to call
|
must be done outside of any threading context. Don't forget to call
|
||||||
ssh_finalize() to avoid memory leak
|
ssh_finalize() to avoid memory leak
|
||||||
- At all times, you may use different sessions inside threads, make parallel
|
- At all times, you may use different sessions inside threads, make parallel
|
||||||
connections, read/write on different sessions and so on. You *cannot* use a
|
connections, read/write on different sessions and so on. You *cannot* use a
|
||||||
single session (or channels for a single session) in several threads at the same
|
single session (or channels for a single session) in several threads at the same
|
||||||
time. This will most likely lead to internal state corruption. This limitation is
|
time. This will most likely lead to internal state corruption. This limitation is
|
||||||
being worked out and will maybe disappear later.
|
being worked out and will maybe disappear later.
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ set(examples_SRCS
|
|||||||
connect_ssh.c
|
connect_ssh.c
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(${libssh_BINARY_DIR}/include ${libssh_BINARY_DIR})
|
include_directories(
|
||||||
|
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||||
|
${CMAKE_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
if (ARGP_INCLUDE_DIR)
|
if (ARGP_INCLUDE_DIR)
|
||||||
include_directories(${ARGP_INCLUDE_DIR})
|
include_directories(${ARGP_INCLUDE_DIR})
|
||||||
@@ -15,85 +18,60 @@ endif()
|
|||||||
if (UNIX AND NOT WIN32)
|
if (UNIX AND NOT WIN32)
|
||||||
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
||||||
target_compile_options(libssh_scp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(libssh_scp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(libssh_scp ssh::ssh)
|
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
add_executable(scp_download scp_download.c ${examples_SRCS})
|
add_executable(scp_download scp_download.c ${examples_SRCS})
|
||||||
target_compile_options(scp_download PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(scp_download PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(scp_download ssh::ssh)
|
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
||||||
target_compile_options(sshnetcat PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(sshnetcat PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(sshnetcat ssh::ssh)
|
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
if (WITH_SFTP)
|
if (WITH_SFTP)
|
||||||
add_executable(samplesftp samplesftp.c ${examples_SRCS})
|
add_executable(samplesftp samplesftp.c ${examples_SRCS})
|
||||||
target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(samplesftp ssh::ssh)
|
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
|
||||||
endif (WITH_SFTP)
|
endif (WITH_SFTP)
|
||||||
|
|
||||||
add_executable(ssh-client ssh_client.c ${examples_SRCS})
|
add_executable(ssh-client ssh_client.c ${examples_SRCS})
|
||||||
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(ssh-client ssh::ssh)
|
target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
add_executable(ssh-X11-client ssh_X11_client.c ${examples_SRCS})
|
if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H))
|
||||||
target_compile_options(ssh-X11-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
|
||||||
target_link_libraries(ssh-X11-client ssh::ssh)
|
|
||||||
|
|
||||||
if (WITH_SERVER AND (ARGP_LIBRARIES OR HAVE_ARGP_H))
|
|
||||||
if (HAVE_LIBUTIL)
|
if (HAVE_LIBUTIL)
|
||||||
add_executable(ssh_server_fork ssh_server.c)
|
add_executable(ssh_server_fork ssh_server_fork.c)
|
||||||
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS} -DWITH_FORK)
|
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(ssh_server_fork ssh::ssh ${ARGP_LIBRARIES} util)
|
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util)
|
||||||
|
|
||||||
add_executable(ssh_server_pthread ssh_server.c)
|
|
||||||
target_compile_options(ssh_server_pthread PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
|
||||||
target_link_libraries(ssh_server_pthread ssh::ssh ${ARGP_LIBRARIES} pthread util)
|
|
||||||
endif (HAVE_LIBUTIL)
|
endif (HAVE_LIBUTIL)
|
||||||
|
|
||||||
if (WITH_GSSAPI AND GSSAPI_FOUND)
|
if (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||||
|
add_executable(samplesshd-cb samplesshd-cb.c)
|
||||||
|
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
|
target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||||
|
|
||||||
add_executable(proxy proxy.c)
|
add_executable(proxy proxy.c)
|
||||||
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(proxy ssh::ssh ${ARGP_LIBRARIES})
|
target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||||
|
|
||||||
add_executable(sshd_direct-tcpip sshd_direct-tcpip.c)
|
|
||||||
target_compile_options(sshd_direct-tcpip PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
|
||||||
target_link_libraries(sshd_direct-tcpip ssh::ssh ${ARGP_LIBRARIES})
|
|
||||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||||
|
|
||||||
add_executable(samplesshd-kbdint samplesshd-kbdint.c)
|
add_executable(samplesshd-kbdint samplesshd-kbdint.c)
|
||||||
target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(samplesshd-kbdint ssh::ssh ${ARGP_LIBRARIES})
|
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
|
||||||
|
|
||||||
add_executable(keygen2 keygen2.c ${examples_SRCS})
|
|
||||||
target_compile_options(keygen2 PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
|
||||||
target_link_libraries(keygen2 ssh::ssh ${ARGP_LIBRARIES})
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
endif (UNIX AND NOT WIN32)
|
endif (UNIX AND NOT WIN32)
|
||||||
|
|
||||||
if (WITH_SERVER)
|
|
||||||
add_executable(samplesshd-cb samplesshd-cb.c)
|
|
||||||
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
|
||||||
target_link_libraries(samplesshd-cb ssh::ssh)
|
|
||||||
if (ARGP_LIBRARIES OR HAVE_ARGP_H)
|
|
||||||
target_link_libraries(samplesshd-cb ${ARGP_LIBRARIES})
|
|
||||||
endif(ARGP_LIBRARIES OR HAVE_ARGP_H)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(exec exec.c ${examples_SRCS})
|
add_executable(exec exec.c ${examples_SRCS})
|
||||||
target_compile_options(exec PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(exec PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(exec ssh::ssh)
|
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
add_executable(senddata senddata.c ${examples_SRCS})
|
add_executable(senddata senddata.c ${examples_SRCS})
|
||||||
target_compile_options(senddata PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
target_compile_options(senddata PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
||||||
target_link_libraries(senddata ssh::ssh)
|
target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
add_executable(keygen keygen.c)
|
|
||||||
target_compile_options(keygen PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
|
|
||||||
target_link_libraries(keygen ssh::ssh)
|
|
||||||
|
|
||||||
add_executable(libsshpp libsshpp.cpp)
|
add_executable(libsshpp libsshpp.cpp)
|
||||||
target_link_libraries(libsshpp ssh::ssh)
|
target_link_libraries(libsshpp ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
|
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
|
||||||
target_link_libraries(libsshpp_noexcept ssh::ssh)
|
target_link_libraries(libsshpp_noexcept ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|||||||
@@ -100,39 +100,6 @@ int authenticate_kbdint(ssh_session session, const char *password)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int auth_keyfile(ssh_session session, char* keyfile)
|
|
||||||
{
|
|
||||||
ssh_key key = NULL;
|
|
||||||
char pubkey[132] = {0}; // +".pub"
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
snprintf(pubkey, sizeof(pubkey), "%s.pub", keyfile);
|
|
||||||
|
|
||||||
rc = ssh_pki_import_pubkey_file( pubkey, &key);
|
|
||||||
|
|
||||||
if (rc != SSH_OK)
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
|
|
||||||
rc = ssh_userauth_try_publickey(session, NULL, key);
|
|
||||||
|
|
||||||
ssh_key_free(key);
|
|
||||||
|
|
||||||
if (rc!=SSH_AUTH_SUCCESS)
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
|
|
||||||
rc = ssh_pki_import_privkey_file(keyfile, NULL, NULL, NULL, &key);
|
|
||||||
|
|
||||||
if (rc != SSH_OK)
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
|
|
||||||
rc = ssh_userauth_publickey(session, NULL, key);
|
|
||||||
|
|
||||||
ssh_key_free(key);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void error(ssh_session session)
|
static void error(ssh_session session)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
|
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
|
||||||
@@ -173,35 +140,6 @@ int authenticate_console(ssh_session session)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
|
||||||
char buffer[128] = {0};
|
|
||||||
char *p = NULL;
|
|
||||||
|
|
||||||
printf("Automatic pubkey failed. "
|
|
||||||
"Do you want to try a specific key? (y/n)\n");
|
|
||||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((buffer[0]=='Y') || (buffer[0]=='y')) {
|
|
||||||
printf("private key filename: ");
|
|
||||||
|
|
||||||
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
|
||||||
return SSH_AUTH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[sizeof(buffer) - 1] = '\0';
|
|
||||||
if ((p = strchr(buffer, '\n'))) {
|
|
||||||
*p = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = auth_keyfile(session, buffer);
|
|
||||||
|
|
||||||
if(rc == SSH_AUTH_SUCCESS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "failed with key\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to authenticate with keyboard interactive";
|
// Try to authenticate with keyboard interactive";
|
||||||
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
|
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
|
||||||
@@ -234,7 +172,7 @@ int authenticate_console(ssh_session session)
|
|||||||
banner = ssh_get_issue_banner(session);
|
banner = ssh_get_issue_banner(session);
|
||||||
if (banner) {
|
if (banner) {
|
||||||
printf("%s\n",banner);
|
printf("%s\n",banner);
|
||||||
SSH_STRING_FREE_CHAR(banner);
|
ssh_string_free_char(banner);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -14,10 +14,6 @@ clients must be made or how a client should react.
|
|||||||
#define EXAMPLES_COMMON_H_
|
#define EXAMPLES_COMMON_H_
|
||||||
|
|
||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
|
|
||||||
/** Zero a structure */
|
|
||||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
|
|
||||||
|
|
||||||
int authenticate_console(ssh_session session);
|
int authenticate_console(ssh_session session);
|
||||||
int authenticate_kbdint(ssh_session session, const char *password);
|
int authenticate_kbdint(ssh_session session, const char *password);
|
||||||
int verify_knownhost(ssh_session session);
|
int verify_knownhost(ssh_session session);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ int main(void) {
|
|||||||
ssh_session session;
|
ssh_session session;
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
int rbytes, wbytes, total = 0;
|
int nbytes;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
session = connect_ssh("localhost", NULL, 0);
|
session = connect_ssh("localhost", NULL, 0);
|
||||||
@@ -17,7 +17,7 @@ int main(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = ssh_channel_new(session);
|
channel = ssh_channel_new(session);;
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_disconnect(session);
|
ssh_disconnect(session);
|
||||||
ssh_free(session);
|
ssh_free(session);
|
||||||
@@ -35,30 +35,15 @@ int main(void) {
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
rbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
if (rbytes <= 0) {
|
while (nbytes > 0) {
|
||||||
goto failed;
|
if (fwrite(buffer, 1, nbytes, stdout) != (unsigned int) nbytes) {
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
wbytes = fwrite(buffer + total, 1, rbytes, stdout);
|
|
||||||
if (wbytes <= 0) {
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
}
|
||||||
|
|
||||||
total += wbytes;
|
if (nbytes < 0) {
|
||||||
|
|
||||||
/* When it was not possible to write the whole buffer to stdout */
|
|
||||||
if (wbytes < rbytes) {
|
|
||||||
rbytes -= wbytes;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
|
||||||
total = 0;
|
|
||||||
} while (rbytes > 0);
|
|
||||||
|
|
||||||
if (rbytes < 0) {
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/* keygen.c
|
|
||||||
* Sample implementation of ssh-keygen using libssh
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2019 Red Hat, Inc.
|
|
||||||
|
|
||||||
Author: Jakub Jelen <jjelen@redhat.com>
|
|
||||||
|
|
||||||
This file is part of the SSH Library
|
|
||||||
|
|
||||||
You are free to copy this file, modify it in any way, consider it being public
|
|
||||||
domain. This does not apply to the rest of the library though, but it is
|
|
||||||
allowed to cut-and-paste working code from this file to any license of
|
|
||||||
program.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libssh/libssh.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
ssh_key key = NULL;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/* Generate a new ED25519 private key file */
|
|
||||||
rv = ssh_pki_generate(SSH_KEYTYPE_ED25519, 0, &key);
|
|
||||||
if (rv != SSH_OK) {
|
|
||||||
fprintf(stderr, "Failed to generate private key");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write it to a file testkey in the current dirrectory */
|
|
||||||
rv = ssh_pki_export_privkey_file(key, NULL, NULL, NULL, "testkey");
|
|
||||||
if (rv != SSH_OK) {
|
|
||||||
fprintf(stderr, "Failed to write private key file");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,505 +0,0 @@
|
|||||||
/*
|
|
||||||
* keygen2.c - Generate SSH keys using libssh
|
|
||||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <libssh/libssh.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <argp.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
struct arguments_st {
|
|
||||||
enum ssh_keytypes_e type;
|
|
||||||
unsigned long bits;
|
|
||||||
char *file;
|
|
||||||
char *passphrase;
|
|
||||||
int action_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct argp_option options[] = {
|
|
||||||
{
|
|
||||||
.name = "bits",
|
|
||||||
.key = 'b',
|
|
||||||
.arg = "BITS",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "The size of the key to be generated. "
|
|
||||||
"If omitted, a default value is used depending on the TYPE. "
|
|
||||||
"Accepted values are: "
|
|
||||||
"1024, 2048, 3072 (default), 4096, and 8192 for TYPE=\"rsa\"; "
|
|
||||||
"256 (default), 384, and 521 for TYPE=\"ecdsa\"; "
|
|
||||||
"1024 (default) and 2048 for TYPE=\"dsa\"; "
|
|
||||||
"can be omitted for TYPE=\"ed25519\" "
|
|
||||||
"(it will be ignored if provided).\n",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "file",
|
|
||||||
.key = 'f',
|
|
||||||
.arg = "FILE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "The output file. "
|
|
||||||
"If not provided, the used file name will be generated "
|
|
||||||
"according to the key type as \"id_TYPE\" "
|
|
||||||
"(e.g. \"id_rsa\" for type \"rsa\"). "
|
|
||||||
"The public key file name is generated from the private key "
|
|
||||||
"file name by appending \".pub\".\n",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "passphrase",
|
|
||||||
.key = 'p',
|
|
||||||
.arg = "PASSPHRASE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "The passphrase used to encrypt the private key. "
|
|
||||||
"If omitted the file will not be encrypted.\n",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "type",
|
|
||||||
.key = 't',
|
|
||||||
.arg = "TYPE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "The type of the key to be generated. "
|
|
||||||
"Accepted values are: "
|
|
||||||
"\"rsa\", \"ecdsa\", \"ed25519\", and \"dsa\".\n",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "list",
|
|
||||||
.key = 'l',
|
|
||||||
.arg = NULL,
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "List the Fingerprint of the given key\n",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
/* End of the options */
|
|
||||||
0
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Parse a single option. */
|
|
||||||
static error_t parse_opt (int key, char *arg, struct argp_state *state)
|
|
||||||
{
|
|
||||||
/* Get the input argument from argp_parse, which we
|
|
||||||
* know is a pointer to our arguments structure.
|
|
||||||
*/
|
|
||||||
struct arguments_st *arguments = NULL;
|
|
||||||
error_t rc = 0;
|
|
||||||
|
|
||||||
if (state == NULL) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
arguments = state->input;
|
|
||||||
if (arguments == NULL) {
|
|
||||||
fprintf(stderr, "Error: NULL pointer to arguments structure "
|
|
||||||
"provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (key) {
|
|
||||||
case 'b':
|
|
||||||
errno = 0;
|
|
||||||
arguments->bits = strtoul(arg, NULL, 10);
|
|
||||||
if (errno != 0) {
|
|
||||||
rc = errno;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
arguments->file = strdup(arg);
|
|
||||||
if (arguments->file == NULL) {
|
|
||||||
fprintf(stderr, "Error: Out of memory\n");
|
|
||||||
rc = ENOMEM;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
arguments->passphrase = strdup(arg);
|
|
||||||
if (arguments->passphrase == NULL) {
|
|
||||||
fprintf(stderr, "Error: Out of memory\n");
|
|
||||||
rc = ENOMEM;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
if (!strcmp(arg, "rsa")) {
|
|
||||||
arguments->type = SSH_KEYTYPE_RSA;
|
|
||||||
}
|
|
||||||
else if (!strcmp(arg, "dsa")) {
|
|
||||||
arguments->type = SSH_KEYTYPE_DSS;
|
|
||||||
}
|
|
||||||
else if (!strcmp(arg, "ecdsa")) {
|
|
||||||
arguments->type = SSH_KEYTYPE_ECDSA;
|
|
||||||
}
|
|
||||||
else if (!strcmp(arg, "ed25519")) {
|
|
||||||
arguments->type = SSH_KEYTYPE_ED25519;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "Error: Invalid key type\n");
|
|
||||||
argp_usage(state);
|
|
||||||
rc = EINVAL;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
arguments->action_list = 1;
|
|
||||||
break;
|
|
||||||
case ARGP_KEY_ARG:
|
|
||||||
if (state->arg_num > 0) {
|
|
||||||
/* Too many arguments. */
|
|
||||||
printf("Error: Too many arguments\n");
|
|
||||||
argp_usage(state);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARGP_KEY_END:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ARGP_ERR_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int validate_args(struct arguments_st *args)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (args == NULL) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no other arguments needed for listing key fingerprints */
|
|
||||||
if (args->action_list) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args->type) {
|
|
||||||
case SSH_KEYTYPE_RSA:
|
|
||||||
switch (args->bits) {
|
|
||||||
case 0:
|
|
||||||
/* If not provided, use default value */
|
|
||||||
args->bits = 3072;
|
|
||||||
break;
|
|
||||||
case 1024:
|
|
||||||
case 2048:
|
|
||||||
case 3072:
|
|
||||||
case 4096:
|
|
||||||
case 8192:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_rsa");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_ECDSA:
|
|
||||||
switch (args->bits) {
|
|
||||||
case 0:
|
|
||||||
/* If not provided, use default value */
|
|
||||||
args->bits = 256;
|
|
||||||
break;
|
|
||||||
case 256:
|
|
||||||
case 384:
|
|
||||||
case 521:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_ecdsa");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_DSS:
|
|
||||||
switch (args->bits) {
|
|
||||||
case 0:
|
|
||||||
/* If not provided, use default value */
|
|
||||||
args->bits = 1024;
|
|
||||||
break;
|
|
||||||
case 1024:
|
|
||||||
case 2048:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_dsa");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_ED25519:
|
|
||||||
/* Ignore value and overwrite with a zero */
|
|
||||||
args->bits = 0;
|
|
||||||
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_ed25519");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: unknown key type\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Program documentation. */
|
|
||||||
static char doc[] = "Generate an SSH key pair. "
|
|
||||||
"The \"--type\" (short: \"-t\") option is required.";
|
|
||||||
|
|
||||||
/* Our argp parser */
|
|
||||||
static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL};
|
|
||||||
|
|
||||||
static void
|
|
||||||
list_fingerprint(char *file)
|
|
||||||
{
|
|
||||||
ssh_key key = NULL;
|
|
||||||
unsigned char *hash = NULL;
|
|
||||||
size_t hlen = 0;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = ssh_pki_import_privkey_file(file, NULL, NULL, NULL, &key);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
fprintf(stderr, "Failed to import private key %s\n", file);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = ssh_get_publickey_hash(key, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
fprintf(stderr, "Failed to get key fingerprint\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
|
||||||
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
ssh_key_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
ssh_key key = NULL;
|
|
||||||
int rc = 0;
|
|
||||||
char overwrite[1024] = "";
|
|
||||||
|
|
||||||
char *pubkey_file = NULL;
|
|
||||||
|
|
||||||
struct arguments_st arguments = {
|
|
||||||
.type = SSH_KEYTYPE_UNKNOWN,
|
|
||||||
.bits = 0,
|
|
||||||
.file = NULL,
|
|
||||||
.passphrase = NULL,
|
|
||||||
.action_list = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
argp_help(&argp, stdout, ARGP_HELP_DOC | ARGP_HELP_USAGE, argv[0]);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = validate_args(&arguments);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.action_list && arguments.file) {
|
|
||||||
list_fingerprint(arguments.file);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
rc = open(arguments.file, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
|
|
||||||
if (rc < 0) {
|
|
||||||
if (errno == EEXIST) {
|
|
||||||
printf("File \"%s\" exists. Overwrite it? (y|n) ", arguments.file);
|
|
||||||
rc = scanf("%1023s", overwrite);
|
|
||||||
if (rc > 0 && tolower(overwrite[0]) == 'y') {
|
|
||||||
rc = open(arguments.file, O_WRONLY);
|
|
||||||
if (rc > 0) {
|
|
||||||
close(rc);
|
|
||||||
errno = 0;
|
|
||||||
rc = chmod(arguments.file, S_IRUSR | S_IWUSR);
|
|
||||||
if (rc != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error(%d): Could not set file permissions\n",
|
|
||||||
errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: Could not create private key file\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Error opening \"%s\" file\n", arguments.file);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
close(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate a new private key */
|
|
||||||
rc = ssh_pki_generate(arguments.type, arguments.bits, &key);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
fprintf(stderr, "Error: Failed to generate keys");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the private key */
|
|
||||||
rc = ssh_pki_export_privkey_file(key, arguments.passphrase, NULL, NULL,
|
|
||||||
arguments.file);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
fprintf(stderr, "Error: Failed to write private key file");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If a passphrase was provided, overwrite and free it as it is not needed
|
|
||||||
* anymore */
|
|
||||||
if (arguments.passphrase != NULL) {
|
|
||||||
#ifdef HAVE_EXPLICIT_BZERO
|
|
||||||
explicit_bzero(arguments.passphrase, strlen(arguments.passphrase));
|
|
||||||
#else
|
|
||||||
bzero(arguments.passphrase, strlen(arguments.passphrase));
|
|
||||||
#endif
|
|
||||||
free(arguments.passphrase);
|
|
||||||
arguments.passphrase = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkey_file = (char *)malloc(strlen(arguments.file) + 5);
|
|
||||||
if (pubkey_file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(pubkey_file, "%s.pub", arguments.file);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
rc = open(pubkey_file,
|
|
||||||
O_CREAT | O_EXCL | O_WRONLY,
|
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
||||||
if (rc < 0) {
|
|
||||||
if (errno == EEXIST) {
|
|
||||||
printf("File \"%s\" exists. Overwrite it? (y|n) ", pubkey_file);
|
|
||||||
rc = scanf("%1023s", overwrite);
|
|
||||||
if (rc > 0 && tolower(overwrite[0]) == 'y') {
|
|
||||||
rc = open(pubkey_file, O_WRONLY);
|
|
||||||
if (rc > 0) {
|
|
||||||
close(rc);
|
|
||||||
errno = 0;
|
|
||||||
rc = chmod(pubkey_file,
|
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
||||||
if (rc != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error(%d): Could not set file permissions\n",
|
|
||||||
errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: Could not create public key file\n");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Error opening \"%s\" file\n", pubkey_file);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
close(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the public key */
|
|
||||||
rc = ssh_pki_export_pubkey_file(key, pubkey_file);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
fprintf(stderr, "Error: Failed to write public key file");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (key != NULL) {
|
|
||||||
ssh_key_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.file != NULL) {
|
|
||||||
free(arguments.file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.passphrase != NULL) {
|
|
||||||
#ifdef HAVE_EXPLICIT_BZERO
|
|
||||||
explicit_bzero(arguments.passphrase, strlen(arguments.passphrase));
|
|
||||||
#else
|
|
||||||
bzero(arguments.passphrase, strlen(arguments.passphrase));
|
|
||||||
#endif
|
|
||||||
free(arguments.passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pubkey_file != NULL) {
|
|
||||||
free(pubkey_file);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
@@ -32,86 +32,82 @@ clients must be made or how a client should react.
|
|||||||
#define strncasecmp _strnicmp
|
#define strncasecmp _strnicmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int verify_knownhost(ssh_session session)
|
int verify_knownhost(ssh_session session){
|
||||||
{
|
enum ssh_known_hosts_e state;
|
||||||
enum ssh_known_hosts_e state;
|
char buf[10];
|
||||||
char buf[10];
|
unsigned char *hash = NULL;
|
||||||
unsigned char *hash = NULL;
|
size_t hlen;
|
||||||
size_t hlen;
|
ssh_key srv_pubkey;
|
||||||
ssh_key srv_pubkey;
|
int rc;
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = ssh_get_server_publickey(session, &srv_pubkey);
|
rc = ssh_get_server_publickey(session, &srv_pubkey);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ssh_get_publickey_hash(srv_pubkey,
|
rc = ssh_get_publickey_hash(srv_pubkey,
|
||||||
SSH_PUBLICKEY_HASH_SHA256,
|
SSH_PUBLICKEY_HASH_SHA256,
|
||||||
&hash,
|
&hash,
|
||||||
&hlen);
|
&hlen);
|
||||||
ssh_key_free(srv_pubkey);
|
ssh_key_free(srv_pubkey);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = ssh_session_is_known_server(session);
|
state = ssh_session_is_known_server(session);
|
||||||
|
|
||||||
switch(state) {
|
switch(state){
|
||||||
case SSH_KNOWN_HOSTS_CHANGED:
|
|
||||||
fprintf(stderr,"Host key for server changed : server's one is now :\n");
|
|
||||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
fprintf(stderr,"For security reason, connection will be stopped\n");
|
|
||||||
return -1;
|
|
||||||
case SSH_KNOWN_HOSTS_OTHER:
|
|
||||||
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
|
|
||||||
fprintf(stderr,"An attacker might change the default server key to confuse your client"
|
|
||||||
"into thinking the key does not exist\n"
|
|
||||||
"We advise you to rerun the client with -d or -r for more safety.\n");
|
|
||||||
return -1;
|
|
||||||
case SSH_KNOWN_HOSTS_NOT_FOUND:
|
|
||||||
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
|
|
||||||
fprintf(stderr,"the file will be automatically created.\n");
|
|
||||||
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
|
||||||
FALL_THROUGH;
|
|
||||||
case SSH_SERVER_NOT_KNOWN:
|
|
||||||
fprintf(stderr,
|
|
||||||
"The server is unknown. Do you trust the host key (yes/no)?\n");
|
|
||||||
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(strncasecmp(buf,"yes",3)!=0){
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(strncasecmp(buf,"yes",3)==0){
|
|
||||||
rc = ssh_session_update_known_hosts(session);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
fprintf(stderr, "error %s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SSH_KNOWN_HOSTS_ERROR:
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
|
||||||
fprintf(stderr,"%s",ssh_get_error(session));
|
|
||||||
return -1;
|
|
||||||
case SSH_KNOWN_HOSTS_OK:
|
case SSH_KNOWN_HOSTS_OK:
|
||||||
break; /* ok */
|
break; /* ok */
|
||||||
}
|
case SSH_KNOWN_HOSTS_CHANGED:
|
||||||
|
fprintf(stderr,"Host key for server changed : server's one is now :\n");
|
||||||
|
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||||
|
return -1;
|
||||||
|
case SSH_KNOWN_HOSTS_OTHER:
|
||||||
|
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
|
||||||
|
fprintf(stderr,"An attacker might change the default server key to confuse your client"
|
||||||
|
"into thinking the key does not exist\n"
|
||||||
|
"We advise you to rerun the client with -d or -r for more safety.\n");
|
||||||
|
return -1;
|
||||||
|
case SSH_KNOWN_HOSTS_NOT_FOUND:
|
||||||
|
fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
|
||||||
|
fprintf(stderr,"the file will be automatically created.\n");
|
||||||
|
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
||||||
|
FALL_THROUGH;
|
||||||
|
case SSH_SERVER_NOT_KNOWN:
|
||||||
|
fprintf(stderr,
|
||||||
|
"The server is unknown. Do you trust the host key (yes/no)?\n");
|
||||||
|
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||||
|
|
||||||
ssh_clean_pubkey_hash(&hash);
|
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(strncasecmp(buf,"yes",3)!=0){
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||||
|
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(strncasecmp(buf,"yes",3)==0){
|
||||||
|
if (ssh_write_knownhost(session) < 0) {
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
fprintf(stderr, "error %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
break;
|
||||||
|
case SSH_KNOWN_HOSTS_ERROR:
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
fprintf(stderr,"%s",ssh_get_error(session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,233 +22,151 @@ program.
|
|||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include "examples_common.h"
|
#include "examples_common.h"
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 16384
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char **sources;
|
static char **sources;
|
||||||
static int nsources;
|
static int nsources;
|
||||||
static char *destination;
|
static char *destination;
|
||||||
static int verbosity = 0;
|
static int verbosity=0;
|
||||||
|
|
||||||
struct location {
|
struct location {
|
||||||
int is_ssh;
|
int is_ssh;
|
||||||
char *user;
|
char *user;
|
||||||
char *host;
|
char *host;
|
||||||
char *path;
|
char *path;
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
ssh_scp scp;
|
ssh_scp scp;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
READ,
|
READ,
|
||||||
WRITE
|
WRITE
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usage(const char *argv0) {
|
static void usage(const char *argv0){
|
||||||
fprintf(stderr, "Usage : %s [options] [[user@]host1:]file1 ... \n"
|
fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n"
|
||||||
" [[user@]host2:]destination\n"
|
" [[user@]host2:]destination\n"
|
||||||
"sample scp client - libssh-%s\n",
|
"sample scp client - libssh-%s\n",
|
||||||
// "Options :\n",
|
// "Options :\n",
|
||||||
// " -r : use RSA to verify host public key\n",
|
// " -r : use RSA to verify host public key\n",
|
||||||
argv0,
|
argv0,
|
||||||
ssh_version(0));
|
ssh_version(0));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int opts(int argc, char **argv) {
|
static int opts(int argc, char **argv){
|
||||||
int i;
|
int i;
|
||||||
|
while((i=getopt(argc,argv,"v"))!=-1){
|
||||||
while((i = getopt(argc, argv, "v")) != -1) {
|
switch(i){
|
||||||
switch(i) {
|
case 'v':
|
||||||
case 'v':
|
verbosity++;
|
||||||
verbosity++;
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
fprintf(stderr,"unknown option %c\n",optopt);
|
||||||
fprintf(stderr, "unknown option %c\n", optopt);
|
|
||||||
usage(argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsources = argc - optind - 1;
|
|
||||||
if (nsources < 1) {
|
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sources = malloc((nsources + 1) * sizeof(char *));
|
nsources=argc-optind-1;
|
||||||
if (sources == NULL) {
|
if(nsources < 1){
|
||||||
return -1;
|
usage(argv[0]);
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < nsources; ++i) {
|
|
||||||
sources[i] = argv[optind];
|
|
||||||
optind++;
|
|
||||||
}
|
|
||||||
|
|
||||||
sources[i] = NULL;
|
|
||||||
destination = argv[optind];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void location_free(struct location *loc)
|
|
||||||
{
|
|
||||||
if (loc) {
|
|
||||||
if (loc->path) {
|
|
||||||
free(loc->path);
|
|
||||||
}
|
|
||||||
loc->path = NULL;
|
|
||||||
if (loc->is_ssh) {
|
|
||||||
if (loc->host) {
|
|
||||||
free(loc->host);
|
|
||||||
}
|
|
||||||
loc->host = NULL;
|
|
||||||
if (loc->user) {
|
|
||||||
free(loc->user);
|
|
||||||
}
|
|
||||||
loc->user = NULL;
|
|
||||||
}
|
|
||||||
free(loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct location *parse_location(char *loc) {
|
|
||||||
struct location *location;
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
location = malloc(sizeof(struct location));
|
|
||||||
if (location == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(location, 0, sizeof(struct location));
|
|
||||||
|
|
||||||
location->host = location->user = NULL;
|
|
||||||
ptr = strchr(loc, ':');
|
|
||||||
|
|
||||||
if (ptr != NULL) {
|
|
||||||
location->is_ssh = 1;
|
|
||||||
location->path = strdup(ptr+1);
|
|
||||||
*ptr = '\0';
|
|
||||||
ptr = strchr(loc, '@');
|
|
||||||
|
|
||||||
if (ptr != NULL) {
|
|
||||||
location->host = strdup(ptr+1);
|
|
||||||
*ptr = '\0';
|
|
||||||
location->user = strdup(loc);
|
|
||||||
} else {
|
|
||||||
location->host = strdup(loc);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
location->is_ssh = 0;
|
|
||||||
location->path = strdup(loc);
|
|
||||||
}
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void close_location(struct location *loc) {
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (loc) {
|
|
||||||
if (loc->is_ssh) {
|
|
||||||
if (loc->scp) {
|
|
||||||
rc = ssh_scp_close(loc->scp);
|
|
||||||
if (rc == SSH_ERROR) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error closing scp: %s\n",
|
|
||||||
ssh_get_error(loc->session));
|
|
||||||
}
|
|
||||||
ssh_scp_free(loc->scp);
|
|
||||||
loc->scp = NULL;
|
|
||||||
}
|
|
||||||
if (loc->session) {
|
|
||||||
ssh_disconnect(loc->session);
|
|
||||||
ssh_free(loc->session);
|
|
||||||
loc->session = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (loc->file) {
|
|
||||||
fclose(loc->file);
|
|
||||||
loc->file = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int open_location(struct location *loc, int flag) {
|
|
||||||
if (loc->is_ssh && flag == WRITE) {
|
|
||||||
loc->session = connect_ssh(loc->host, loc->user, verbosity);
|
|
||||||
if (!loc->session) {
|
|
||||||
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path);
|
|
||||||
if (!loc->scp) {
|
|
||||||
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
|
|
||||||
ssh_disconnect(loc->session);
|
|
||||||
ssh_free(loc->session);
|
|
||||||
loc->session = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
|
|
||||||
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
|
|
||||||
ssh_scp_free(loc->scp);
|
|
||||||
loc->scp = NULL;
|
|
||||||
ssh_disconnect(loc->session);
|
|
||||||
ssh_free(loc->session);
|
|
||||||
loc->session = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else if (loc->is_ssh && flag == READ) {
|
|
||||||
loc->session = connect_ssh(loc->host, loc->user, verbosity);
|
|
||||||
if (!loc->session) {
|
|
||||||
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
loc->scp = ssh_scp_new(loc->session, SSH_SCP_READ, loc->path);
|
|
||||||
if (!loc->scp) {
|
|
||||||
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
|
|
||||||
ssh_disconnect(loc->session);
|
|
||||||
ssh_free(loc->session);
|
|
||||||
loc->session = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
|
|
||||||
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
|
|
||||||
ssh_scp_free(loc->scp);
|
|
||||||
loc->scp = NULL;
|
|
||||||
ssh_disconnect(loc->session);
|
|
||||||
ssh_free(loc->session);
|
|
||||||
loc->session = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
loc->file = fopen(loc->path, flag == READ ? "r":"w");
|
|
||||||
if (!loc->file) {
|
|
||||||
if (errno == EISDIR) {
|
|
||||||
if (loc->path != NULL && chdir(loc->path)) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error changing directory to %s: %s\n",
|
|
||||||
loc->path, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error opening %s: %s\n",
|
|
||||||
loc->path, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
sources=malloc((nsources + 1) * sizeof(char *));
|
||||||
|
if(sources == NULL)
|
||||||
|
return -1;
|
||||||
|
for(i=0;i<nsources;++i){
|
||||||
|
sources[i] = argv[optind];
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
sources[i]=NULL;
|
||||||
|
destination=argv[optind];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct location *parse_location(char *loc){
|
||||||
|
struct location *location;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
location = malloc(sizeof(struct location));
|
||||||
|
if (location == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(location, 0, sizeof(struct location));
|
||||||
|
|
||||||
|
location->host=location->user=NULL;
|
||||||
|
ptr=strchr(loc,':');
|
||||||
|
if(ptr != NULL){
|
||||||
|
location->is_ssh=1;
|
||||||
|
location->path=strdup(ptr+1);
|
||||||
|
*ptr='\0';
|
||||||
|
ptr=strchr(loc,'@');
|
||||||
|
if(ptr != NULL){
|
||||||
|
location->host=strdup(ptr+1);
|
||||||
|
*ptr='\0';
|
||||||
|
location->user=strdup(loc);
|
||||||
|
} else {
|
||||||
|
location->host=strdup(loc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
location->is_ssh=0;
|
||||||
|
location->path=strdup(loc);
|
||||||
|
}
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_location(struct location *loc, int flag){
|
||||||
|
if(loc->is_ssh && flag==WRITE){
|
||||||
|
loc->session=connect_ssh(loc->host,loc->user,verbosity);
|
||||||
|
if(!loc->session){
|
||||||
|
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path);
|
||||||
|
if(!loc->scp){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(ssh_scp_init(loc->scp)==SSH_ERROR){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
ssh_scp_free(loc->scp);
|
||||||
|
loc->scp = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else if(loc->is_ssh && flag==READ){
|
||||||
|
loc->session=connect_ssh(loc->host, loc->user,verbosity);
|
||||||
|
if(!loc->session){
|
||||||
|
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path);
|
||||||
|
if(!loc->scp){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(ssh_scp_init(loc->scp)==SSH_ERROR){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
ssh_scp_free(loc->scp);
|
||||||
|
loc->scp = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
loc->file=fopen(loc->path,flag==READ ? "r":"w");
|
||||||
|
if(!loc->file){
|
||||||
|
if(errno==EISDIR){
|
||||||
|
if(chdir(loc->path)){
|
||||||
|
fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief copies files from source location to destination
|
/** @brief copies files from source location to destination
|
||||||
@@ -256,201 +174,155 @@ static int open_location(struct location *loc, int flag) {
|
|||||||
* @param dest destination location
|
* @param dest destination location
|
||||||
* @param recursive Copy also directories
|
* @param recursive Copy also directories
|
||||||
*/
|
*/
|
||||||
static int do_copy(struct location *src, struct location *dest, int recursive) {
|
static int do_copy(struct location *src, struct location *dest, int recursive){
|
||||||
size_t size;
|
int size;
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
int w, r;
|
int w,r;
|
||||||
char buffer[BUF_SIZE];
|
char buffer[16384];
|
||||||
size_t total = 0;
|
int total=0;
|
||||||
mode_t mode;
|
int mode;
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
/* recursive mode doesn't work yet */
|
||||||
/* recursive mode doesn't work yet */
|
(void)recursive;
|
||||||
(void)recursive;
|
/* Get the file name and size*/
|
||||||
/* Get the file name and size*/
|
if(!src->is_ssh){
|
||||||
if (!src->is_ssh) {
|
fd = fileno(src->file);
|
||||||
fd = fileno(src->file);
|
if (fd < 0) {
|
||||||
if (fd < 0) {
|
fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno));
|
||||||
fprintf(stderr,
|
return -1;
|
||||||
"Invalid file pointer, error: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
r = fstat(fd, &s);
|
|
||||||
if (r < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
size = s.st_size;
|
|
||||||
mode = s.st_mode & ~S_IFMT;
|
|
||||||
filename = ssh_basename(src->path);
|
|
||||||
} else {
|
|
||||||
size = 0;
|
|
||||||
do {
|
|
||||||
r = ssh_scp_pull_request(src->scp);
|
|
||||||
if (r == SSH_SCP_REQUEST_NEWDIR) {
|
|
||||||
ssh_scp_deny_request(src->scp, "Not in recursive mode");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (r == SSH_SCP_REQUEST_NEWFILE) {
|
|
||||||
size = ssh_scp_request_get_size(src->scp);
|
|
||||||
filename = strdup(ssh_scp_request_get_filename(src->scp));
|
|
||||||
mode = ssh_scp_request_get_permissions(src->scp);
|
|
||||||
//ssh_scp_accept_request(src->scp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (r == SSH_ERROR) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: %s\n",
|
|
||||||
ssh_get_error(src->session));
|
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while(r != SSH_SCP_REQUEST_NEWFILE);
|
|
||||||
}
|
}
|
||||||
|
r = fstat(fd, &s);
|
||||||
if (dest->is_ssh) {
|
if (r < 0) {
|
||||||
r = ssh_scp_push_file(dest->scp, src->path, size, mode);
|
return -1;
|
||||||
// snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path);
|
|
||||||
if (r == SSH_ERROR) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"error: %s\n",
|
|
||||||
ssh_get_error(dest->session));
|
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
ssh_scp_free(dest->scp);
|
|
||||||
dest->scp = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!dest->file) {
|
|
||||||
dest->file = fopen(filename, "w");
|
|
||||||
if (!dest->file) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Cannot open %s for writing: %s\n",
|
|
||||||
filename, strerror(errno));
|
|
||||||
if (src->is_ssh) {
|
|
||||||
ssh_scp_deny_request(src->scp, "Cannot open local file");
|
|
||||||
}
|
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (src->is_ssh) {
|
|
||||||
ssh_scp_accept_request(src->scp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
size=s.st_size;
|
||||||
|
mode = s.st_mode & ~S_IFMT;
|
||||||
|
filename=ssh_basename(src->path);
|
||||||
|
} else {
|
||||||
|
size=0;
|
||||||
do {
|
do {
|
||||||
if (src->is_ssh) {
|
r=ssh_scp_pull_request(src->scp);
|
||||||
r = ssh_scp_read(src->scp, buffer, sizeof(buffer));
|
if(r==SSH_SCP_REQUEST_NEWDIR){
|
||||||
if (r == SSH_ERROR) {
|
ssh_scp_deny_request(src->scp,"Not in recursive mode");
|
||||||
fprintf(stderr,
|
continue;
|
||||||
"Error reading scp: %s\n",
|
}
|
||||||
ssh_get_error(src->session));
|
if(r==SSH_SCP_REQUEST_NEWFILE){
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
size=ssh_scp_request_get_size(src->scp);
|
||||||
return -1;
|
filename=strdup(ssh_scp_request_get_filename(src->scp));
|
||||||
}
|
mode=ssh_scp_request_get_permissions(src->scp);
|
||||||
|
//ssh_scp_accept_request(src->scp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
|
||||||
|
ssh_string_free_char(filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while(r != SSH_SCP_REQUEST_NEWFILE);
|
||||||
|
}
|
||||||
|
|
||||||
if (r == 0) {
|
if(dest->is_ssh){
|
||||||
break;
|
r=ssh_scp_push_file(dest->scp,src->path, size, mode);
|
||||||
}
|
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
|
||||||
} else {
|
if(r==SSH_ERROR){
|
||||||
r = fread(buffer, 1, sizeof(buffer), src->file);
|
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
|
||||||
if (r == 0) {
|
ssh_string_free_char(filename);
|
||||||
break;
|
ssh_scp_free(dest->scp);
|
||||||
}
|
dest->scp = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!dest->file){
|
||||||
|
dest->file=fopen(filename,"w");
|
||||||
|
if(!dest->file){
|
||||||
|
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
|
||||||
|
if(src->is_ssh)
|
||||||
|
ssh_scp_deny_request(src->scp,"Cannot open local file");
|
||||||
|
ssh_string_free_char(filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(src->is_ssh){
|
||||||
|
ssh_scp_accept_request(src->scp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if(src->is_ssh){
|
||||||
|
r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
|
||||||
|
ssh_string_free_char(filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(r==0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
r=fread(buffer,1,sizeof(buffer),src->file);
|
||||||
|
if(r==0)
|
||||||
|
break;
|
||||||
|
if(r<0){
|
||||||
|
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
|
||||||
|
ssh_string_free_char(filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dest->is_ssh){
|
||||||
|
w=ssh_scp_write(dest->scp,buffer,r);
|
||||||
|
if(w == SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
|
||||||
|
ssh_scp_free(dest->scp);
|
||||||
|
dest->scp=NULL;
|
||||||
|
ssh_string_free_char(filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w=fwrite(buffer,r,1,dest->file);
|
||||||
|
if(w<=0){
|
||||||
|
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
|
||||||
|
ssh_string_free_char(filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total+=r;
|
||||||
|
|
||||||
if (r < 0) {
|
} while(total < size);
|
||||||
fprintf(stderr,
|
ssh_string_free_char(filename);
|
||||||
"Error reading file: %s\n",
|
printf("wrote %d bytes\n",total);
|
||||||
strerror(errno));
|
return 0;
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest->is_ssh) {
|
|
||||||
w = ssh_scp_write(dest->scp, buffer, r);
|
|
||||||
if (w == SSH_ERROR) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error writing in scp: %s\n",
|
|
||||||
ssh_get_error(dest->session));
|
|
||||||
ssh_scp_free(dest->scp);
|
|
||||||
dest->scp = NULL;
|
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w = fwrite(buffer, r, 1, dest->file);
|
|
||||||
if (w <= 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error writing in local file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
total += r;
|
|
||||||
|
|
||||||
} while(total < size);
|
|
||||||
|
|
||||||
SSH_STRING_FREE_CHAR(filename);
|
|
||||||
printf("wrote %zu bytes\n", total);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv){
|
||||||
struct location *dest, *src;
|
struct location *dest, *src;
|
||||||
int i;
|
int i;
|
||||||
int r;
|
int r;
|
||||||
if (opts(argc, argv) < 0) {
|
if(opts(argc,argv)<0)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
dest=parse_location(destination);
|
||||||
|
if(open_location(dest,WRITE)<0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
for(i=0;i<nsources;++i){
|
||||||
|
src=parse_location(sources[i]);
|
||||||
|
if(open_location(src,READ)<0){
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
if(do_copy(src,dest,0) < 0){
|
||||||
ssh_init();
|
break;
|
||||||
|
|
||||||
dest = parse_location(destination);
|
|
||||||
if (dest == NULL) {
|
|
||||||
r = EXIT_FAILURE;
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (open_location(dest, WRITE) < 0) {
|
if (dest->is_ssh && dest->scp != NULL) {
|
||||||
location_free(dest);
|
r=ssh_scp_close(dest->scp);
|
||||||
r = EXIT_FAILURE;
|
if(r == SSH_ERROR){
|
||||||
goto end;
|
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
|
||||||
}
|
ssh_scp_free(dest->scp);
|
||||||
|
dest->scp=NULL;
|
||||||
for (i = 0; i < nsources; ++i) {
|
return -1;
|
||||||
src = parse_location(sources[i]);
|
}
|
||||||
if (src == NULL) {
|
} else {
|
||||||
r = EXIT_FAILURE;
|
fclose(dest->file);
|
||||||
goto close_dest;
|
dest->file=NULL;
|
||||||
}
|
}
|
||||||
|
ssh_disconnect(dest->session);
|
||||||
if (open_location(src, READ) < 0) {
|
ssh_finalize();
|
||||||
location_free(src);
|
return 0;
|
||||||
r = EXIT_FAILURE;
|
|
||||||
goto close_dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_copy(src, dest, 0) < 0) {
|
|
||||||
close_location(src);
|
|
||||||
location_free(src);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
close_location(src);
|
|
||||||
location_free(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
|
|
||||||
close_dest:
|
|
||||||
close_location(dest);
|
|
||||||
location_free(dest);
|
|
||||||
end:
|
|
||||||
ssh_finalize();
|
|
||||||
free(sources);
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ clients must be made or how a client should react.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 2048
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define USER "myuser"
|
#define USER "myuser"
|
||||||
#define PASSWORD "mypassword"
|
#define PASSWORD "mypassword"
|
||||||
|
|
||||||
@@ -229,7 +225,7 @@ int main(int argc, char **argv){
|
|||||||
.channel_open_request_session_function = new_session_channel
|
.channel_open_request_session_function = new_session_channel
|
||||||
};
|
};
|
||||||
|
|
||||||
char buf[BUF_SIZE];
|
char buf[2048];
|
||||||
char host[128]="";
|
char host[128]="";
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int i,r, rc;
|
int i,r, rc;
|
||||||
@@ -295,7 +291,7 @@ int main(int argc, char **argv){
|
|||||||
snprintf(buf,sizeof(buf), "Hello %s, welcome to the Sample SSH proxy.\r\nPlease select your destination: ", username);
|
snprintf(buf,sizeof(buf), "Hello %s, welcome to the Sample SSH proxy.\r\nPlease select your destination: ", username);
|
||||||
ssh_channel_write(chan, buf, strlen(buf));
|
ssh_channel_write(chan, buf, strlen(buf));
|
||||||
do{
|
do{
|
||||||
i=ssh_channel_read(chan,buf, sizeof(buf), 0);
|
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||||
if(i>0) {
|
if(i>0) {
|
||||||
ssh_channel_write(chan, buf, i);
|
ssh_channel_write(chan, buf, i);
|
||||||
if(strlen(host) + i < sizeof(host)){
|
if(strlen(host) + i < sizeof(host)){
|
||||||
|
|||||||
@@ -29,13 +29,11 @@ clients must be made or how a client should react.
|
|||||||
#include "examples_common.h"
|
#include "examples_common.h"
|
||||||
#ifdef WITH_SFTP
|
#ifdef WITH_SFTP
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 65536
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int verbosity;
|
static int verbosity;
|
||||||
static char *destination;
|
static char *destination;
|
||||||
|
|
||||||
|
#define DATALEN 65536
|
||||||
|
|
||||||
static void do_sftp(ssh_session session) {
|
static void do_sftp(ssh_session session) {
|
||||||
sftp_session sftp = sftp_new(session);
|
sftp_session sftp = sftp_new(session);
|
||||||
sftp_dir dir;
|
sftp_dir dir;
|
||||||
@@ -46,8 +44,8 @@ static void do_sftp(ssh_session session) {
|
|||||||
sftp_file to;
|
sftp_file to;
|
||||||
int len = 1;
|
int len = 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char data[BUF_SIZE] = {0};
|
char data[DATALEN] = {0};
|
||||||
char *lnk = NULL;
|
char *lnk;
|
||||||
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
@@ -86,7 +84,6 @@ static void do_sftp(ssh_session session) {
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
printf("readlink /tmp/sftp_symlink_test: %s\n", lnk);
|
printf("readlink /tmp/sftp_symlink_test: %s\n", lnk);
|
||||||
ssh_string_free_char(lnk);
|
|
||||||
|
|
||||||
sftp_unlink(sftp, "/tmp/sftp_symlink_test");
|
sftp_unlink(sftp, "/tmp/sftp_symlink_test");
|
||||||
|
|
||||||
@@ -174,7 +171,7 @@ static void do_sftp(ssh_session session) {
|
|||||||
sftp_attributes_free(file);
|
sftp_attributes_free(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* when file = NULL, an error has occurred OR the directory listing is end of
|
/* when file = NULL, an error has occured OR the directory listing is end of
|
||||||
* file */
|
* file */
|
||||||
if (!sftp_dir_eof(dir)) {
|
if (!sftp_dir_eof(dir)) {
|
||||||
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
||||||
@@ -226,9 +223,9 @@ static void do_sftp(ssh_session session) {
|
|||||||
to = sftp_open(sftp, "/tmp/grosfichier", O_WRONLY|O_CREAT, 0644);
|
to = sftp_open(sftp, "/tmp/grosfichier", O_WRONLY|O_CREAT, 0644);
|
||||||
|
|
||||||
for (i = 0; i < 1000; ++i) {
|
for (i = 0; i < 1000; ++i) {
|
||||||
len = sftp_write(to, data, sizeof(data));
|
len = sftp_write(to, data, DATALEN);
|
||||||
printf("wrote %d bytes\n", len);
|
printf("wrote %d bytes\n", len);
|
||||||
if (len != sizeof(data)) {
|
if (len != DATALEN) {
|
||||||
printf("chunk %d : %d (%s)\n", i, len, ssh_get_error(session));
|
printf("chunk %d : %d (%s)\n", i, len, ssh_get_error(session));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,14 +25,6 @@ clients must be made or how a client should react.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 2049
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KEYS_FOLDER
|
#ifndef KEYS_FOLDER
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define KEYS_FOLDER
|
#define KEYS_FOLDER
|
||||||
@@ -49,27 +41,6 @@ static int tries = 0;
|
|||||||
static int error = 0;
|
static int error = 0;
|
||||||
static ssh_channel chan=NULL;
|
static ssh_channel chan=NULL;
|
||||||
|
|
||||||
static int auth_none(ssh_session session,
|
|
||||||
const char *user,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
ssh_string banner = NULL;
|
|
||||||
|
|
||||||
(void)user; /* unused */
|
|
||||||
(void)userdata; /* unused */
|
|
||||||
|
|
||||||
ssh_set_auth_methods(session,
|
|
||||||
SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC);
|
|
||||||
|
|
||||||
banner = ssh_string_from_char("Banner Example\n");
|
|
||||||
if (banner != NULL) {
|
|
||||||
ssh_send_issue_banner(session, banner);
|
|
||||||
}
|
|
||||||
ssh_string_free(banner);
|
|
||||||
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int auth_password(ssh_session session, const char *user,
|
static int auth_password(ssh_session session, const char *user,
|
||||||
const char *password, void *userdata){
|
const char *password, void *userdata){
|
||||||
(void)userdata;
|
(void)userdata;
|
||||||
@@ -89,7 +60,6 @@ static int auth_password(ssh_session session, const char *user,
|
|||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_GSSAPI
|
|
||||||
static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata){
|
static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata){
|
||||||
ssh_gssapi_creds creds = ssh_gssapi_get_creds(session);
|
ssh_gssapi_creds creds = ssh_gssapi_get_creds(session);
|
||||||
(void)userdata;
|
(void)userdata;
|
||||||
@@ -102,7 +72,6 @@ static int auth_gssapi_mic(ssh_session session, const char *user, const char *pr
|
|||||||
authenticated = 1;
|
authenticated = 1;
|
||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int pty_request(ssh_session session, ssh_channel channel, const char *term,
|
static int pty_request(ssh_session session, ssh_channel channel, const char *term,
|
||||||
int x,int y, int px, int py, void *userdata){
|
int x,int y, int px, int py, void *userdata){
|
||||||
@@ -196,14 +165,6 @@ static struct argp_option options[] = {
|
|||||||
.doc = "Get verbose output.",
|
.doc = "Get verbose output.",
|
||||||
.group = 0
|
.group = 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.name = "config",
|
|
||||||
.key = 'f',
|
|
||||||
.arg = "FILE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Configuration file to use.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{NULL, 0, NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,9 +191,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
|||||||
case 'v':
|
case 'v':
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||||
break;
|
break;
|
||||||
case 'f':
|
|
||||||
ssh_bind_options_parse_config(sshbind, arg);
|
|
||||||
break;
|
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (state->arg_num >= 1) {
|
if (state->arg_num >= 1) {
|
||||||
/* Too many arguments. */
|
/* Too many arguments. */
|
||||||
@@ -263,15 +221,12 @@ int main(int argc, char **argv){
|
|||||||
ssh_event mainloop;
|
ssh_event mainloop;
|
||||||
struct ssh_server_callbacks_struct cb = {
|
struct ssh_server_callbacks_struct cb = {
|
||||||
.userdata = NULL,
|
.userdata = NULL,
|
||||||
.auth_none_function = auth_none,
|
|
||||||
.auth_password_function = auth_password,
|
.auth_password_function = auth_password,
|
||||||
#ifdef WITH_GSSAPI
|
|
||||||
.auth_gssapi_mic_function = auth_gssapi_mic,
|
.auth_gssapi_mic_function = auth_gssapi_mic,
|
||||||
#endif
|
|
||||||
.channel_open_request_session_function = new_session_channel
|
.channel_open_request_session_function = new_session_channel
|
||||||
};
|
};
|
||||||
|
|
||||||
char buf[BUF_SIZE];
|
char buf[2048];
|
||||||
int i;
|
int i;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -327,24 +282,19 @@ int main(int argc, char **argv){
|
|||||||
} else
|
} else
|
||||||
printf("Authenticated and got a channel\n");
|
printf("Authenticated and got a channel\n");
|
||||||
do{
|
do{
|
||||||
i=ssh_channel_read(chan, buf, sizeof(buf) - 1, 0);
|
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||||
if(i>0) {
|
if(i>0) {
|
||||||
if (ssh_channel_write(chan, buf, i) == SSH_ERROR) {
|
ssh_channel_write(chan, buf, i);
|
||||||
printf("error writing to channel\n");
|
if (write(1,buf,i) < 0) {
|
||||||
|
printf("error writing to buffer\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i] = '\0';
|
|
||||||
printf("%s", buf);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (buf[0] == '\x0d') {
|
if (buf[0] == '\x0d') {
|
||||||
if (ssh_channel_write(chan, "\n", 1) == SSH_ERROR) {
|
if (write(1, "\n", 1) < 0) {
|
||||||
printf("error writing to channel\n");
|
printf("error writing to buffer\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
ssh_channel_write(chan, "\n", 1);
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (i>0);
|
} while (i>0);
|
||||||
|
|||||||
@@ -23,11 +23,6 @@ clients must be made or how a client should react.
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 2048
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SSHD_USER "libssh"
|
#define SSHD_USER "libssh"
|
||||||
#define SSHD_PASSWORD "libssh"
|
#define SSHD_PASSWORD "libssh"
|
||||||
@@ -41,7 +36,6 @@ clients must be made or how a client should react.
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int port = 22;
|
static int port = 22;
|
||||||
static bool authenticated = false;
|
|
||||||
|
|
||||||
#ifdef WITH_PCAP
|
#ifdef WITH_PCAP
|
||||||
static const char *pcap_file = "debug.server.pcap";
|
static const char *pcap_file = "debug.server.pcap";
|
||||||
@@ -67,20 +61,11 @@ static void cleanup_pcap(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int auth_password(const char *user, const char *password)
|
static int auth_password(const char *user, const char *password){
|
||||||
{
|
if(strcmp(user, SSHD_USER))
|
||||||
int cmp;
|
|
||||||
|
|
||||||
cmp = strcmp(user, SSHD_USER);
|
|
||||||
if (cmp != 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
if(strcmp(password, SSHD_PASSWORD))
|
||||||
cmp = strcmp(password, SSHD_PASSWORD);
|
|
||||||
if (cmp != 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
authenticated = true;
|
|
||||||
return 1; // authenticated
|
return 1; // authenticated
|
||||||
}
|
}
|
||||||
#ifdef HAVE_ARGP_H
|
#ifdef HAVE_ARGP_H
|
||||||
@@ -215,7 +200,6 @@ static int kbdint_check_response(ssh_session session) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
authenticated = true;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +281,7 @@ int main(int argc, char **argv){
|
|||||||
ssh_bind sshbind;
|
ssh_bind sshbind;
|
||||||
ssh_message message;
|
ssh_message message;
|
||||||
ssh_channel chan=0;
|
ssh_channel chan=0;
|
||||||
char buf[BUF_SIZE];
|
char buf[2048];
|
||||||
int auth=0;
|
int auth=0;
|
||||||
int shell=0;
|
int shell=0;
|
||||||
int i;
|
int i;
|
||||||
@@ -344,7 +328,7 @@ int main(int argc, char **argv){
|
|||||||
|
|
||||||
/* proceed to authentication */
|
/* proceed to authentication */
|
||||||
auth = authenticate(session);
|
auth = authenticate(session);
|
||||||
if (!auth || !authenticated) {
|
if(!auth){
|
||||||
printf("Authentication error: %s\n", ssh_get_error(session));
|
printf("Authentication error: %s\n", ssh_get_error(session));
|
||||||
ssh_disconnect(session);
|
ssh_disconnect(session);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -369,9 +353,9 @@ int main(int argc, char **argv){
|
|||||||
}
|
}
|
||||||
} while(!chan);
|
} while(!chan);
|
||||||
|
|
||||||
if (!chan) {
|
if(!chan) {
|
||||||
printf("Error: client did not ask for a channel session (%s)\n",
|
printf("Error: cleint did not ask for a channel session (%s)\n",
|
||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
ssh_finalize();
|
ssh_finalize();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -403,7 +387,7 @@ int main(int argc, char **argv){
|
|||||||
|
|
||||||
printf("it works !\n");
|
printf("it works !\n");
|
||||||
do{
|
do{
|
||||||
i=ssh_channel_read(chan,buf, sizeof(buf), 0);
|
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||||
if(i>0) {
|
if(i>0) {
|
||||||
if(*buf == '' || *buf == '')
|
if(*buf == '' || *buf == '')
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ program.
|
|||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include "examples_common.h"
|
#include "examples_common.h"
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 16384
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int verbosity = 0;
|
static int verbosity = 0;
|
||||||
static const char *createcommand =
|
static const char *createcommand =
|
||||||
"rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && "
|
"rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && "
|
||||||
@@ -106,7 +102,7 @@ static void create_files(ssh_session session){
|
|||||||
|
|
||||||
static int fetch_files(ssh_session session){
|
static int fetch_files(ssh_session session){
|
||||||
int size;
|
int size;
|
||||||
char buffer[BUF_SIZE];
|
char buffer[16384];
|
||||||
int mode;
|
int mode;
|
||||||
char *filename;
|
char *filename;
|
||||||
int r;
|
int r;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ int main(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = ssh_channel_new(session);
|
channel = ssh_channel_new(session);;
|
||||||
if (channel == NULL) {
|
if (channel == NULL) {
|
||||||
ssh_disconnect(session);
|
ssh_disconnect(session);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,866 +0,0 @@
|
|||||||
/*
|
|
||||||
* ssh.c - Simple example of SSH X11 client using libssh
|
|
||||||
*
|
|
||||||
* Copyright (C) 2022 Marco Fortina
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the copyright holders give
|
|
||||||
* permission to link the code of portions of this program with the
|
|
||||||
* OpenSSL library under certain conditions as described in each
|
|
||||||
* individual source file, and distribute linked combinations
|
|
||||||
* including the two.
|
|
||||||
* You must obey the GNU General Public License in all respects
|
|
||||||
* for all of the code used other than OpenSSL. * If you modify
|
|
||||||
* file(s) with this exception, you may extend this exception to your
|
|
||||||
* version of the file(s), but you are not obligated to do so. * If you
|
|
||||||
* do not wish to do so, delete this exception statement from your
|
|
||||||
* version. * If you delete this exception statement from all source
|
|
||||||
* files in the program, then also delete it here.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ssh_X11_client
|
|
||||||
* ==============
|
|
||||||
*
|
|
||||||
* AUTHOR URL
|
|
||||||
* https://gitlab.com/marco.fortina/libssh-x11-client/
|
|
||||||
*
|
|
||||||
* This is a simple example of SSH X11 client using libssh.
|
|
||||||
*
|
|
||||||
* Features:
|
|
||||||
*
|
|
||||||
* - support local display (e.g. :0)
|
|
||||||
* - support remote display (e.g. localhost:10.0)
|
|
||||||
* - using callbacks and event polling to significantly reduce CPU utilization
|
|
||||||
* - use X11 forwarding with authentication spoofing (like openssh)
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
*
|
|
||||||
* - part of this code was inspired by openssh's one.
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
*
|
|
||||||
* - gcc >= 7.5.0
|
|
||||||
* - libssh >= 0.8.0
|
|
||||||
* - libssh-dev >= 0.8.0
|
|
||||||
*
|
|
||||||
* To Build:
|
|
||||||
* gcc -o ssh_X11_client ssh_X11_client.c -lssh -g
|
|
||||||
*
|
|
||||||
* Donations:
|
|
||||||
*
|
|
||||||
* If you liked this work and wish to support the developer please donate to:
|
|
||||||
* Bitcoin: 1N2rQimKbeUQA8N2LU5vGopYQJmZsBM2d6
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <libssh/libssh.h>
|
|
||||||
#include <libssh/callbacks.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data Structures and Macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _PATH_UNIX_X "/tmp/.X11-unix/X%d"
|
|
||||||
#define _XAUTH_CMD "/usr/bin/xauth list %s 2>/dev/null"
|
|
||||||
|
|
||||||
typedef struct item {
|
|
||||||
ssh_channel channel;
|
|
||||||
int fd_in;
|
|
||||||
int fd_out;
|
|
||||||
int protected;
|
|
||||||
struct item *next;
|
|
||||||
} node_t;
|
|
||||||
|
|
||||||
node_t *node = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mutex
|
|
||||||
*/
|
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function declarations
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Linked nodes to manage channel/fd tuples */
|
|
||||||
static void insert_item(ssh_channel channel, int fd_in, int fd_out, int protected);
|
|
||||||
static void delete_item(ssh_channel channel);
|
|
||||||
static node_t * search_item(ssh_channel channel);
|
|
||||||
|
|
||||||
/* X11 Display */
|
|
||||||
const char * ssh_gai_strerror(int gaierr);
|
|
||||||
static int x11_get_proto(const char *display, char **_proto, char **_data);
|
|
||||||
static void set_nodelay(int fd);
|
|
||||||
static int connect_local_xsocket_path(const char *pathname);
|
|
||||||
static int connect_local_xsocket(int display_number);
|
|
||||||
static int x11_connect_display(void);
|
|
||||||
|
|
||||||
/* Send data to channel */
|
|
||||||
static int copy_fd_to_channel_callback(int fd, int revents, void *userdata);
|
|
||||||
|
|
||||||
/* Read data from channel */
|
|
||||||
static int copy_channel_to_fd_callback(ssh_session session, ssh_channel channel, void *data, uint32_t len, int is_stderr, void *userdata);
|
|
||||||
|
|
||||||
/* EOF&Close channel */
|
|
||||||
static void channel_close_callback(ssh_session session, ssh_channel channel, void *userdata);
|
|
||||||
|
|
||||||
/* X11 Request */
|
|
||||||
static ssh_channel x11_open_request_callback(ssh_session session, const char *shost, int sport, void *userdata);
|
|
||||||
|
|
||||||
/* Main loop */
|
|
||||||
static int main_loop(ssh_channel channel);
|
|
||||||
|
|
||||||
/* Internals */
|
|
||||||
int64_t _current_timestamp(void);
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
const char *hostname = NULL;
|
|
||||||
int enableX11 = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callbacks Data Structures
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* SSH Channel Callbacks */
|
|
||||||
struct ssh_channel_callbacks_struct channel_cb =
|
|
||||||
{
|
|
||||||
.channel_data_function = copy_channel_to_fd_callback,
|
|
||||||
.channel_eof_function = channel_close_callback,
|
|
||||||
.channel_close_function = channel_close_callback,
|
|
||||||
.userdata = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/* SSH Callbacks */
|
|
||||||
struct ssh_callbacks_struct cb =
|
|
||||||
{
|
|
||||||
.channel_open_request_x11_function = x11_open_request_callback,
|
|
||||||
.userdata = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SSH Event Context
|
|
||||||
*/
|
|
||||||
|
|
||||||
short events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
|
|
||||||
ssh_event event;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal data structures
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct termios _saved_tio;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
int64_t
|
|
||||||
_current_timestamp(void) {
|
|
||||||
struct timeval tv;
|
|
||||||
int64_t milliseconds;
|
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
milliseconds = (int64_t)(tv.tv_sec) * 1000 + (tv.tv_usec / 1000);
|
|
||||||
|
|
||||||
return milliseconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_logging_callback(int priority, const char *function, const char *buffer, void *userdata)
|
|
||||||
{
|
|
||||||
FILE *fp = NULL;
|
|
||||||
char buf[100];
|
|
||||||
int64_t milliseconds;
|
|
||||||
|
|
||||||
time_t now = time (0);
|
|
||||||
|
|
||||||
(void)userdata;
|
|
||||||
|
|
||||||
strftime(buf, 100, "%Y-%m-%d %H:%M:%S", localtime (&now));
|
|
||||||
|
|
||||||
fp = fopen("debug.log","a");
|
|
||||||
if(fp == NULL)
|
|
||||||
{
|
|
||||||
printf("Error!");
|
|
||||||
exit(-11);
|
|
||||||
}
|
|
||||||
|
|
||||||
milliseconds = _current_timestamp();
|
|
||||||
|
|
||||||
fprintf(fp, "[%s.%jd, %d] %s: %s\n", buf, milliseconds, priority, function, buffer);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_enter_term_raw_mode(void)
|
|
||||||
{
|
|
||||||
struct termios tio;
|
|
||||||
int ret = tcgetattr(fileno(stdin), &tio);
|
|
||||||
if (ret != -1) {
|
|
||||||
_saved_tio = tio;
|
|
||||||
tio.c_iflag |= IGNPAR;
|
|
||||||
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
|
|
||||||
#ifdef IUCLC
|
|
||||||
tio.c_iflag &= ~IUCLC;
|
|
||||||
#endif
|
|
||||||
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
|
|
||||||
#ifdef IEXTEN
|
|
||||||
tio.c_lflag &= ~IEXTEN;
|
|
||||||
#endif
|
|
||||||
tio.c_oflag &= ~OPOST;
|
|
||||||
tio.c_cc[VMIN] = 1;
|
|
||||||
tio.c_cc[VTIME] = 0;
|
|
||||||
ret = tcsetattr(fileno(stdin), TCSADRAIN, &tio);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_leave_term_raw_mode(void)
|
|
||||||
{
|
|
||||||
int ret = tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
insert_item(ssh_channel channel, int fd_in, int fd_out, int protected)
|
|
||||||
{
|
|
||||||
node_t *node_iterator = NULL, *new = NULL;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
|
|
||||||
if (node == NULL) {
|
|
||||||
/* Calloc ensure that node is full of 0 */
|
|
||||||
node = (node_t *) calloc(1, sizeof(node_t));
|
|
||||||
node->channel = channel;
|
|
||||||
node->fd_in = fd_in;
|
|
||||||
node->fd_out = fd_out;
|
|
||||||
node->protected = protected;
|
|
||||||
node->next = NULL;
|
|
||||||
} else {
|
|
||||||
node_iterator = node;
|
|
||||||
while (node_iterator->next != NULL)
|
|
||||||
node_iterator = node_iterator->next;
|
|
||||||
/* Create the new node */
|
|
||||||
new = (node_t *) malloc(sizeof(node_t));
|
|
||||||
new->channel = channel;
|
|
||||||
new->fd_in = fd_in;
|
|
||||||
new->fd_out = fd_out;
|
|
||||||
new->protected = protected;
|
|
||||||
new->next = NULL;
|
|
||||||
node_iterator->next = new;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
delete_item(ssh_channel channel)
|
|
||||||
{
|
|
||||||
node_t *current = NULL, *previous = NULL;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
|
|
||||||
for (current = node; current; previous = current, current = current->next) {
|
|
||||||
if (current->channel != channel)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (previous == NULL)
|
|
||||||
node = current->next;
|
|
||||||
else
|
|
||||||
previous->next = current->next;
|
|
||||||
|
|
||||||
free(current);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static node_t *
|
|
||||||
search_item(ssh_channel channel)
|
|
||||||
{
|
|
||||||
node_t *current = node;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
|
|
||||||
while (current != NULL) {
|
|
||||||
if (current->channel == channel) {
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
return current;
|
|
||||||
} else {
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_nodelay(int fd)
|
|
||||||
{
|
|
||||||
int opt;
|
|
||||||
socklen_t optlen;
|
|
||||||
|
|
||||||
optlen = sizeof(opt);
|
|
||||||
if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "getsockopt TCP_NODELAY: %.100s", strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (opt == 1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fd %d is TCP_NODELAY", fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
opt = 1;
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fd %d setting TCP_NODELAY", fd);
|
|
||||||
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) == -1)
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "setsockopt TCP_NODELAY: %.100s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *
|
|
||||||
ssh_gai_strerror(int gaierr)
|
|
||||||
{
|
|
||||||
if (gaierr == EAI_SYSTEM && errno != 0)
|
|
||||||
return strerror(errno);
|
|
||||||
return gai_strerror(gaierr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
x11_get_proto(const char *display, char **_proto, char **_cookie)
|
|
||||||
{
|
|
||||||
char cmd[1024], line[512], xdisplay[512];
|
|
||||||
static char proto[512], cookie[512];
|
|
||||||
FILE *f = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
*_proto = proto;
|
|
||||||
*_cookie = cookie;
|
|
||||||
|
|
||||||
proto[0] = cookie[0] = '\0';
|
|
||||||
|
|
||||||
if (strncmp(display, "localhost:", 10) == 0) {
|
|
||||||
if ((ret = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", display + 10)) < 0 || (size_t)ret >= sizeof(xdisplay)) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display name too long. display: %s", display);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
display = xdisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), _XAUTH_CMD, display);
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "xauth cmd: %s", cmd);
|
|
||||||
|
|
||||||
f = popen(cmd, "r");
|
|
||||||
if (f && fgets(line, sizeof(line), f) && sscanf(line, "%*s %511s %511s", proto, cookie) == 2) {
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f) pclose(f);
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "proto: %s - cookie: %s - ret: %d", proto, cookie, ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
connect_local_xsocket_path(const char *pathname)
|
|
||||||
{
|
|
||||||
int sock;
|
|
||||||
struct sockaddr_un addr;
|
|
||||||
|
|
||||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
||||||
if (sock == -1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "socket: %.100s", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sun_family = AF_UNIX;
|
|
||||||
addr.sun_path[0] = '\0';
|
|
||||||
/* pathname is guaranteed to be initialized and larger than addr.sun_path[108] */
|
|
||||||
memcpy(addr.sun_path + 1, pathname, sizeof(addr.sun_path) - 1);
|
|
||||||
if (connect(sock, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(pathname)) == 0)
|
|
||||||
return sock;
|
|
||||||
close(sock);
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "connect %.100s: %.100s", addr.sun_path, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
connect_local_xsocket(int display_number)
|
|
||||||
{
|
|
||||||
char buf[1024] = {0};
|
|
||||||
snprintf(buf, sizeof(buf), _PATH_UNIX_X, display_number);
|
|
||||||
return connect_local_xsocket_path(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
x11_connect_display(void)
|
|
||||||
{
|
|
||||||
int display_number;
|
|
||||||
const char *display = NULL;
|
|
||||||
char buf[1024], *cp = NULL;
|
|
||||||
struct addrinfo hints, *ai = NULL, *aitop = NULL;
|
|
||||||
char strport[NI_MAXSERV];
|
|
||||||
int gaierr = 0, sock = 0;
|
|
||||||
|
|
||||||
/* Try to open a socket for the local X server. */
|
|
||||||
display = getenv("DISPLAY");
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display: %s", display);
|
|
||||||
|
|
||||||
if (!display) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if it is a unix domain socket. */
|
|
||||||
if (strncmp(display, "unix:", 5) == 0 || display[0] == ':') {
|
|
||||||
/* Connect to the unix domain socket. */
|
|
||||||
if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "Could not parse display number from DISPLAY: %.100s", display);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display_number: %d", display_number);
|
|
||||||
|
|
||||||
/* Create a socket. */
|
|
||||||
sock = connect_local_xsocket(display_number);
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "socket: %d", sock);
|
|
||||||
|
|
||||||
if (sock < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* OK, we now have a connection to the display. */
|
|
||||||
return sock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect to an inet socket. */
|
|
||||||
strncpy(buf, display, sizeof(buf) - 1);
|
|
||||||
cp = strchr(buf, ':');
|
|
||||||
if (!cp) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "Could not find ':' in DISPLAY: %.100s", display);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*cp = 0;
|
|
||||||
if (sscanf(cp + 1, "%d", &display_number) != 1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "Could not parse display number from DISPLAY: %.100s", display);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look up the host address */
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
snprintf(strport, sizeof(strport), "%u", 6000 + display_number);
|
|
||||||
if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
|
||||||
/* Create a socket. */
|
|
||||||
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
|
||||||
if (sock == -1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "socket: %.100s", strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Connect it to the display. */
|
|
||||||
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "connect %.100s port %u: %.100s", buf, 6000 + display_number, strerror(errno));
|
|
||||||
close(sock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Success */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
freeaddrinfo(aitop);
|
|
||||||
if (!ai) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "connect %.100s port %u: %.100s", buf, 6000 + display_number, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
set_nodelay(sock);
|
|
||||||
return sock;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
copy_fd_to_channel_callback(int fd, int revents, void *userdata)
|
|
||||||
{
|
|
||||||
ssh_channel channel = (ssh_channel)userdata;
|
|
||||||
char buf[2097152];
|
|
||||||
int sz = 0, ret = 0;
|
|
||||||
|
|
||||||
node_t *temp_node = search_item(channel);
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "event: %d - fd: %d", revents, fd);
|
|
||||||
|
|
||||||
if (!channel) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "channel does not exist.");
|
|
||||||
if (temp_node->protected == 0) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fcntl(fd, F_GETFD) == -1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fcntl error. fd: %d", fd);
|
|
||||||
ssh_channel_close(channel);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((revents & POLLIN) || (revents & POLLPRI)) {
|
|
||||||
sz = read(fd, buf, sizeof(buf));
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "sz: %d", sz);
|
|
||||||
if (sz > 0) {
|
|
||||||
ret = ssh_channel_write(channel, buf, sz);
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "channel_write ret: %d", ret);
|
|
||||||
} else if (sz < 0) {
|
|
||||||
ssh_channel_close(channel);
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
/* sz = 0. Why the hell I'm here? */
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "Why the hell am I here?: sz: %d", sz);
|
|
||||||
if (temp_node->protected == 0) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((revents & POLLHUP) || (revents & POLLNVAL) || (revents & POLLERR)) {
|
|
||||||
ssh_channel_close(channel);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
copy_channel_to_fd_callback(ssh_session session, ssh_channel channel, void *data, uint32_t len, int is_stderr, void *userdata)
|
|
||||||
{
|
|
||||||
node_t *temp_node = NULL;
|
|
||||||
int fd, sz;
|
|
||||||
|
|
||||||
(void)session;
|
|
||||||
(void)is_stderr;
|
|
||||||
(void)userdata;
|
|
||||||
|
|
||||||
temp_node = search_item(channel);
|
|
||||||
|
|
||||||
fd = temp_node->fd_out;
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "len: %d - fd: %d - is_stderr: %d", len, fd, is_stderr);
|
|
||||||
|
|
||||||
sz = write(fd, data, len);
|
|
||||||
|
|
||||||
return sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
channel_close_callback(ssh_session session, ssh_channel channel, void *userdata)
|
|
||||||
{
|
|
||||||
node_t *temp_node = NULL;
|
|
||||||
|
|
||||||
(void)session;
|
|
||||||
(void)userdata;
|
|
||||||
|
|
||||||
temp_node = search_item(channel);
|
|
||||||
|
|
||||||
if (temp_node != NULL) {
|
|
||||||
int fd = temp_node->fd_in;
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fd: %d", fd);
|
|
||||||
|
|
||||||
delete_item(channel);
|
|
||||||
ssh_event_remove_fd(event, fd);
|
|
||||||
|
|
||||||
if (temp_node->protected == 0) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ssh_channel
|
|
||||||
x11_open_request_callback(ssh_session session, const char *shost, int sport, void *userdata)
|
|
||||||
{
|
|
||||||
ssh_channel channel = NULL;
|
|
||||||
int sock;
|
|
||||||
|
|
||||||
(void)shost;
|
|
||||||
(void)sport;
|
|
||||||
(void)userdata;
|
|
||||||
|
|
||||||
channel = ssh_channel_new(session);
|
|
||||||
|
|
||||||
sock = x11_connect_display();
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "sock: %d", sock);
|
|
||||||
|
|
||||||
insert_item(channel, sock, sock, 0);
|
|
||||||
|
|
||||||
ssh_event_add_fd(event, sock, events, copy_fd_to_channel_callback, channel);
|
|
||||||
ssh_event_add_session(event, session);
|
|
||||||
|
|
||||||
ssh_add_channel_callbacks(channel, &channel_cb);
|
|
||||||
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MAIN LOOP
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
main_loop(ssh_channel channel)
|
|
||||||
{
|
|
||||||
ssh_session session = ssh_channel_get_session(channel);
|
|
||||||
|
|
||||||
insert_item(channel, fileno(stdin), fileno(stdout), 1);
|
|
||||||
|
|
||||||
ssh_callbacks_init(&channel_cb);
|
|
||||||
ssh_set_channel_callbacks(channel, &channel_cb);
|
|
||||||
|
|
||||||
event = ssh_event_new();
|
|
||||||
if (event == NULL) {
|
|
||||||
printf("Couldn't get a event\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssh_event_add_fd(event, fileno(stdin), events, copy_fd_to_channel_callback, channel) != SSH_OK) {
|
|
||||||
printf("Couldn't add an fd to the event\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ssh_event_add_session(event, session) != SSH_OK) {
|
|
||||||
printf("Couldn't add the session to the event\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (ssh_event_dopoll(event, 1000) == SSH_ERROR) {
|
|
||||||
printf("Error : %s\n", ssh_get_error(session));
|
|
||||||
/* fall through */
|
|
||||||
}
|
|
||||||
} while (!ssh_channel_is_closed(channel));
|
|
||||||
|
|
||||||
delete_item(channel);
|
|
||||||
ssh_event_remove_fd(event, fileno(stdin));
|
|
||||||
ssh_event_remove_session(event, session);
|
|
||||||
ssh_event_free(event);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* USAGE
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"Usage : ssh-X11-client [options] [login@]hostname\n"
|
|
||||||
"sample X11 client - libssh-%s\n"
|
|
||||||
"Options :\n"
|
|
||||||
" -l user : Specifies the user to log in as on the remote machine.\n"
|
|
||||||
" -p port : Port to connect to on the remote host.\n"
|
|
||||||
" -v : Verbose mode. Multiple -v options increase the verbosity. The maximum is 5.\n"
|
|
||||||
" -C : Requests compression of all data.\n"
|
|
||||||
" -x : Disables X11 forwarding.\n"
|
|
||||||
"\n",
|
|
||||||
ssh_version(0));
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int opts(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
while ((i = getopt(argc,argv,"x")) != -1) {
|
|
||||||
switch(i) {
|
|
||||||
case 'x':
|
|
||||||
enableX11 = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unknown option %c\n", optopt);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind < argc) {
|
|
||||||
hostname = argv[optind++];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostname == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MAIN
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
char *password = NULL;
|
|
||||||
|
|
||||||
ssh_session session = NULL;
|
|
||||||
ssh_channel channel = NULL;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
const char *display = NULL;
|
|
||||||
char *proto = NULL, *cookie = NULL;
|
|
||||||
|
|
||||||
ssh_set_log_callback(_logging_callback);
|
|
||||||
ret = ssh_init();
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
session = ssh_new();
|
|
||||||
if (session == NULL) exit(-1);
|
|
||||||
|
|
||||||
if (ssh_options_getopt(session, &argc, argv) || opts(argc, argv)) {
|
|
||||||
fprintf(stderr, "Error parsing command line: %s\n", ssh_get_error(session));
|
|
||||||
ssh_free(session);
|
|
||||||
ssh_finalize();
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssh_options_set(session, SSH_OPTIONS_HOST, hostname) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ssh_connect(session);
|
|
||||||
if (ret != SSH_OK) {
|
|
||||||
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
password = getpass("Password: ");
|
|
||||||
ret = ssh_userauth_password(session, NULL, password);
|
|
||||||
if (ret != SSH_AUTH_SUCCESS) {
|
|
||||||
fprintf(stderr, "Error authenticating with password: %s\n", ssh_get_error(session));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
channel = ssh_channel_new(session);
|
|
||||||
if (channel == NULL) return SSH_ERROR;
|
|
||||||
|
|
||||||
ret = ssh_channel_open_session(channel);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
ret = ssh_channel_request_pty(channel);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
ret = ssh_channel_change_pty_size(channel, 80, 24);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
if (enableX11 == 1) {
|
|
||||||
display = getenv("DISPLAY");
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display: %s", display);
|
|
||||||
|
|
||||||
if (display) {
|
|
||||||
ssh_callbacks_init(&cb);
|
|
||||||
ret = ssh_set_callbacks(session, &cb);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
if (x11_get_proto(display, &proto, &cookie) != 0) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "Using fake authentication data for X11 forwarding");
|
|
||||||
proto = NULL;
|
|
||||||
cookie = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "proto: %s - cookie: %s", proto, cookie);
|
|
||||||
/* See https://gitlab.com/libssh/libssh-mirror/-/blob/master/src/channels.c#L2062 for details. */
|
|
||||||
ret = ssh_channel_request_x11(channel, 0, proto, cookie, 0);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = _enter_term_raw_mode();
|
|
||||||
if (ret != 0) exit(-1);
|
|
||||||
|
|
||||||
ret = ssh_channel_request_shell(channel);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
ret = main_loop(channel);
|
|
||||||
if (ret != SSH_OK) return ret;
|
|
||||||
|
|
||||||
_leave_term_raw_mode();
|
|
||||||
|
|
||||||
ssh_channel_close(channel);
|
|
||||||
ssh_channel_free(channel);
|
|
||||||
ssh_disconnect(session);
|
|
||||||
ssh_free(session);
|
|
||||||
ssh_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,21 @@
|
|||||||
/* ssh_client.c */
|
/* client.c */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2003-2015 Aris Adamantiadis
|
Copyright 2003-2009 Aris Adamantiadis
|
||||||
*
|
|
||||||
* This file is part of the SSH Library
|
This file is part of the SSH Library
|
||||||
*
|
|
||||||
* You are free to copy this file, modify it in any way, consider it being public
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
* domain. This does not apply to the rest of the library though, but it is
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
* allowed to cut-and-paste working code from this file to any license of
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
* program.
|
program.
|
||||||
* The goal is to show the API in action. It's not a reference on how terminal
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
* clients must be made or how a client should react.
|
clients must be made or how a client should react.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@@ -45,10 +43,9 @@
|
|||||||
#include "examples_common.h"
|
#include "examples_common.h"
|
||||||
#define MAXCMD 10
|
#define MAXCMD 10
|
||||||
|
|
||||||
static char *host = NULL;
|
static char *host;
|
||||||
static char *user = NULL;
|
static char *user;
|
||||||
static char *cmds[MAXCMD];
|
static char *cmds[MAXCMD];
|
||||||
static char *config_file = NULL;
|
|
||||||
static struct termios terminal;
|
static struct termios terminal;
|
||||||
|
|
||||||
static char *pcap_file = NULL;
|
static char *pcap_file = NULL;
|
||||||
@@ -83,7 +80,7 @@ static void add_cmd(char *cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmds[n] = cmd;
|
cmds[n] = strdup(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
@@ -96,7 +93,6 @@ static void usage(void)
|
|||||||
" -p port : connect to port\n"
|
" -p port : connect to port\n"
|
||||||
" -d : use DSS to verify host public key\n"
|
" -d : use DSS to verify host public key\n"
|
||||||
" -r : use RSA to verify host public key\n"
|
" -r : use RSA to verify host public key\n"
|
||||||
" -F file : parse configuration file instead of default one\n"
|
|
||||||
#ifdef WITH_PCAP
|
#ifdef WITH_PCAP
|
||||||
" -P file : create a pcap debugging file\n"
|
" -P file : create a pcap debugging file\n"
|
||||||
#endif
|
#endif
|
||||||
@@ -113,14 +109,11 @@ static int opts(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while((i = getopt(argc,argv,"T:P:F:")) != -1) {
|
while((i = getopt(argc,argv,"T:P:")) != -1) {
|
||||||
switch(i){
|
switch(i){
|
||||||
case 'P':
|
case 'P':
|
||||||
pcap_file = optarg;
|
pcap_file = optarg;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
|
||||||
config_file = optarg;
|
|
||||||
break;
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
case 'T':
|
case 'T':
|
||||||
proxycommand = optarg;
|
proxycommand = optarg;
|
||||||
@@ -128,7 +121,7 @@ static int opts(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unknown option %c\n", optopt);
|
fprintf(stderr, "Unknown option %c\n", optopt);
|
||||||
return -1;
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (optind < argc) {
|
if (optind < argc) {
|
||||||
@@ -140,7 +133,7 @@ static int opts(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (host == NULL) {
|
if (host == NULL) {
|
||||||
return -1;
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -175,25 +168,22 @@ static void do_exit(int i)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssh_channel chan;
|
||||||
static int signal_delayed = 0;
|
static int signal_delayed = 0;
|
||||||
|
|
||||||
#ifdef SIGWINCH
|
|
||||||
static void sigwindowchanged(int i)
|
static void sigwindowchanged(int i)
|
||||||
{
|
{
|
||||||
(void) i;
|
(void) i;
|
||||||
signal_delayed = 1;
|
signal_delayed = 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void setsignal(void)
|
static void setsignal(void)
|
||||||
{
|
{
|
||||||
#ifdef SIGWINCH
|
|
||||||
signal(SIGWINCH, sigwindowchanged);
|
signal(SIGWINCH, sigwindowchanged);
|
||||||
#endif
|
|
||||||
signal_delayed = 0;
|
signal_delayed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sizechanged(ssh_channel chan)
|
static void sizechanged(void)
|
||||||
{
|
{
|
||||||
struct winsize win = {
|
struct winsize win = {
|
||||||
.ws_row = 0,
|
.ws_row = 0,
|
||||||
@@ -207,20 +197,19 @@ static void sizechanged(ssh_channel chan)
|
|||||||
static void select_loop(ssh_session session,ssh_channel channel)
|
static void select_loop(ssh_session session,ssh_channel channel)
|
||||||
{
|
{
|
||||||
ssh_connector connector_in, connector_out, connector_err;
|
ssh_connector connector_in, connector_out, connector_err;
|
||||||
int rc;
|
|
||||||
|
|
||||||
ssh_event event = ssh_event_new();
|
ssh_event event = ssh_event_new();
|
||||||
|
|
||||||
/* stdin */
|
/* stdin */
|
||||||
connector_in = ssh_connector_new(session);
|
connector_in = ssh_connector_new(session);
|
||||||
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDINOUT);
|
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDOUT);
|
||||||
ssh_connector_set_in_fd(connector_in, 0);
|
ssh_connector_set_in_fd(connector_in, 0);
|
||||||
ssh_event_add_connector(event, connector_in);
|
ssh_event_add_connector(event, connector_in);
|
||||||
|
|
||||||
/* stdout */
|
/* stdout */
|
||||||
connector_out = ssh_connector_new(session);
|
connector_out = ssh_connector_new(session);
|
||||||
ssh_connector_set_out_fd(connector_out, 1);
|
ssh_connector_set_out_fd(connector_out, 1);
|
||||||
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT);
|
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDOUT);
|
||||||
ssh_event_add_connector(event, connector_out);
|
ssh_event_add_connector(event, connector_out);
|
||||||
|
|
||||||
/* stderr */
|
/* stderr */
|
||||||
@@ -231,13 +220,9 @@ static void select_loop(ssh_session session,ssh_channel channel)
|
|||||||
|
|
||||||
while (ssh_channel_is_open(channel)) {
|
while (ssh_channel_is_open(channel)) {
|
||||||
if (signal_delayed) {
|
if (signal_delayed) {
|
||||||
sizechanged(channel);
|
sizechanged();
|
||||||
}
|
|
||||||
rc = ssh_event_dopoll(event, 60000);
|
|
||||||
if (rc == SSH_ERROR) {
|
|
||||||
fprintf(stderr, "Error in ssh_event_dopoll()\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
ssh_event_dopoll(event, 60000);
|
||||||
}
|
}
|
||||||
ssh_event_remove_connector(event, connector_in);
|
ssh_event_remove_connector(event, connector_in);
|
||||||
ssh_event_remove_connector(event, connector_out);
|
ssh_event_remove_connector(event, connector_out);
|
||||||
@@ -248,6 +233,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
|
|||||||
ssh_connector_free(connector_err);
|
ssh_connector_free(connector_err);
|
||||||
|
|
||||||
ssh_event_free(event);
|
ssh_event_free(event);
|
||||||
|
ssh_channel_free(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shell(ssh_session session)
|
static void shell(ssh_session session)
|
||||||
@@ -255,11 +241,7 @@ static void shell(ssh_session session)
|
|||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
struct termios terminal_local;
|
struct termios terminal_local;
|
||||||
int interactive=isatty(0);
|
int interactive=isatty(0);
|
||||||
|
|
||||||
channel = ssh_channel_new(session);
|
channel = ssh_channel_new(session);
|
||||||
if (channel == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
tcgetattr(0, &terminal_local);
|
tcgetattr(0, &terminal_local);
|
||||||
@@ -268,17 +250,16 @@ static void shell(ssh_session session)
|
|||||||
|
|
||||||
if (ssh_channel_open_session(channel)) {
|
if (ssh_channel_open_session(channel)) {
|
||||||
printf("Error opening channel : %s\n", ssh_get_error(session));
|
printf("Error opening channel : %s\n", ssh_get_error(session));
|
||||||
ssh_channel_free(channel);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
chan = channel;
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
ssh_channel_request_pty(channel);
|
ssh_channel_request_pty(channel);
|
||||||
sizechanged(channel);
|
sizechanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssh_channel_request_shell(channel)) {
|
if (ssh_channel_request_shell(channel)) {
|
||||||
printf("Requesting shell : %s\n", ssh_get_error(session));
|
printf("Requesting shell : %s\n", ssh_get_error(session));
|
||||||
ssh_channel_free(channel);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,33 +273,28 @@ static void shell(ssh_session session)
|
|||||||
if (interactive) {
|
if (interactive) {
|
||||||
do_cleanup(0);
|
do_cleanup(0);
|
||||||
}
|
}
|
||||||
ssh_channel_free(channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void batch_shell(ssh_session session)
|
static void batch_shell(ssh_session session)
|
||||||
{
|
{
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
char buffer[PATH_MAX];
|
char buffer[1024];
|
||||||
size_t i;
|
size_t i;
|
||||||
int s = 0;
|
int s = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
|
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
|
||||||
s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
|
s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
|
||||||
|
free(cmds[i]);
|
||||||
|
cmds[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = ssh_channel_new(session);
|
channel = ssh_channel_new(session);
|
||||||
if (channel == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh_channel_open_session(channel);
|
ssh_channel_open_session(channel);
|
||||||
if (ssh_channel_request_exec(channel, buffer)) {
|
if (ssh_channel_request_exec(channel, buffer)) {
|
||||||
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
|
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
|
||||||
ssh_channel_free(channel);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
select_loop(session, channel);
|
select_loop(session, channel);
|
||||||
ssh_channel_free(channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client(ssh_session session)
|
static int client(ssh_session session)
|
||||||
@@ -332,7 +308,7 @@ static int client(ssh_session session)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
|
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (proxycommand != NULL) {
|
if (proxycommand != NULL) {
|
||||||
@@ -340,13 +316,7 @@ static int client(ssh_session session)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Parse configuration file if specified: The command-line options will
|
ssh_options_parse_config(session, NULL);
|
||||||
* overwrite items loaded from configuration file */
|
|
||||||
if (config_file != NULL) {
|
|
||||||
ssh_options_parse_config(session, config_file);
|
|
||||||
} else {
|
|
||||||
ssh_options_parse_config(session, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssh_connect(session)) {
|
if (ssh_connect(session)) {
|
||||||
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
|
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
|
||||||
@@ -410,20 +380,18 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
|
|
||||||
ssh_init();
|
|
||||||
session = ssh_new();
|
session = ssh_new();
|
||||||
|
|
||||||
ssh_callbacks_init(&cb);
|
ssh_callbacks_init(&cb);
|
||||||
ssh_set_callbacks(session,&cb);
|
ssh_set_callbacks(session,&cb);
|
||||||
|
|
||||||
if (ssh_options_getopt(session, &argc, argv) || opts(argc, argv)) {
|
if (ssh_options_getopt(session, &argc, argv)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error parsing command line: %s\n",
|
"Error parsing command line: %s\n",
|
||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
ssh_free(session);
|
|
||||||
ssh_finalize();
|
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
opts(argc, argv);
|
||||||
signal(SIGTERM, do_exit);
|
signal(SIGTERM, do_exit);
|
||||||
|
|
||||||
set_pcap(session);
|
set_pcap(session);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ The goal is to show the API in action.
|
|||||||
#ifdef HAVE_LIBUTIL_H
|
#ifdef HAVE_LIBUTIL_H
|
||||||
#include <libutil.h>
|
#include <libutil.h>
|
||||||
#endif
|
#endif
|
||||||
#include <pthread.h>
|
|
||||||
#ifdef HAVE_PTY_H
|
#ifdef HAVE_PTY_H
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -38,13 +37,8 @@ The goal is to show the API in action.
|
|||||||
#endif
|
#endif
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 1048576
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KEYS_FOLDER
|
#ifndef KEYS_FOLDER
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define KEYS_FOLDER
|
#define KEYS_FOLDER
|
||||||
@@ -53,6 +47,9 @@ The goal is to show the API in action.
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define USER "myuser"
|
||||||
|
#define PASS "mypassword"
|
||||||
|
#define BUF_SIZE 1048576
|
||||||
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
|
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
|
||||||
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
|
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
|
||||||
|
|
||||||
@@ -72,13 +69,8 @@ static void set_default_keys(ssh_bind sshbind,
|
|||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
|
||||||
KEYS_FOLDER "ssh_host_ecdsa_key");
|
KEYS_FOLDER "ssh_host_ecdsa_key");
|
||||||
}
|
}
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
|
|
||||||
KEYS_FOLDER "ssh_host_ed25519_key");
|
|
||||||
}
|
}
|
||||||
#define DEF_STR_SIZE 1024
|
|
||||||
char authorizedkeys[DEF_STR_SIZE] = {0};
|
|
||||||
char username[128] = "myuser";
|
|
||||||
char password[128] = "mypassword";
|
|
||||||
#ifdef HAVE_ARGP_H
|
#ifdef HAVE_ARGP_H
|
||||||
const char *argp_program_version = "libssh server example "
|
const char *argp_program_version = "libssh server example "
|
||||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||||
@@ -133,30 +125,6 @@ static struct argp_option options[] = {
|
|||||||
.doc = "Set the ecdsa key.",
|
.doc = "Set the ecdsa key.",
|
||||||
.group = 0
|
.group = 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.name = "authorizedkeys",
|
|
||||||
.key = 'a',
|
|
||||||
.arg = "FILE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set the authorized keys file.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "user",
|
|
||||||
.key = 'u',
|
|
||||||
.arg = "USERNAME",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set expected username.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "pass",
|
|
||||||
.key = 'P',
|
|
||||||
.arg = "PASSWORD",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set expected password.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.name = "no-default-keys",
|
.name = "no-default-keys",
|
||||||
.key = 'n',
|
.key = 'n',
|
||||||
@@ -210,15 +178,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
|||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
|
||||||
ecdsa_already_set = 1;
|
ecdsa_already_set = 1;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
|
||||||
strncpy(authorizedkeys, arg, DEF_STR_SIZE-1);
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
strncpy(username, arg, sizeof(username) - 1);
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
strncpy(password, arg, sizeof(password) - 1);
|
|
||||||
break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
||||||
"3");
|
"3");
|
||||||
@@ -252,89 +211,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
|||||||
|
|
||||||
/* Our argp parser. */
|
/* Our argp parser. */
|
||||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||||
#else
|
|
||||||
static int parse_opt(int argc, char **argv, ssh_bind sshbind) {
|
|
||||||
int no_default_keys = 0;
|
|
||||||
int rsa_already_set = 0;
|
|
||||||
int dsa_already_set = 0;
|
|
||||||
int ecdsa_already_set = 0;
|
|
||||||
int key;
|
|
||||||
|
|
||||||
while((key = getopt(argc, argv, "a:d:e:k:np:P:r:u:v")) != -1) {
|
|
||||||
if (key == 'n') {
|
|
||||||
no_default_keys = 1;
|
|
||||||
} else if (key == 'p') {
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, optarg);
|
|
||||||
} else if (key == 'd') {
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, optarg);
|
|
||||||
dsa_already_set = 1;
|
|
||||||
} else if (key == 'k') {
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
|
|
||||||
/* We can't track the types of keys being added with this
|
|
||||||
option, so let's ensure we keep the keys we're adding
|
|
||||||
by just not setting the default keys */
|
|
||||||
no_default_keys = 1;
|
|
||||||
} else if (key == 'r') {
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, optarg);
|
|
||||||
rsa_already_set = 1;
|
|
||||||
} else if (key == 'e') {
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, optarg);
|
|
||||||
ecdsa_already_set = 1;
|
|
||||||
} else if (key == 'a') {
|
|
||||||
strncpy(authorizedkeys, optarg, DEF_STR_SIZE-1);
|
|
||||||
} else if (key == 'u') {
|
|
||||||
strncpy(username, optarg, sizeof(username) - 1);
|
|
||||||
} else if (key == 'P') {
|
|
||||||
strncpy(password, optarg, sizeof(password) - 1);
|
|
||||||
} else if (key == 'v') {
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
|
||||||
"3");
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key != -1) {
|
|
||||||
printf("Usage: %s [OPTION...] BINDADDR\n"
|
|
||||||
"libssh %s -- a Secure Shell protocol implementation\n"
|
|
||||||
"\n"
|
|
||||||
" -a, --authorizedkeys=FILE Set the authorized keys file.\n"
|
|
||||||
" -d, --dsakey=FILE Set the dsa key.\n"
|
|
||||||
" -e, --ecdsakey=FILE Set the ecdsa key.\n"
|
|
||||||
" -k, --hostkey=FILE Set a host key. Can be used multiple times.\n"
|
|
||||||
" Implies no default keys.\n"
|
|
||||||
" -n, --no-default-keys Do not set default key locations.\n"
|
|
||||||
" -p, --port=PORT Set the port to bind.\n"
|
|
||||||
" -P, --pass=PASSWORD Set expected password.\n"
|
|
||||||
" -r, --rsakey=FILE Set the rsa key.\n"
|
|
||||||
" -u, --user=USERNAME Set expected username.\n"
|
|
||||||
" -v, --verbose Get verbose output.\n"
|
|
||||||
" -?, --help Give this help list\n"
|
|
||||||
"\n"
|
|
||||||
"Mandatory or optional arguments to long options are also mandatory or optional\n"
|
|
||||||
"for any corresponding short options.\n"
|
|
||||||
"\n"
|
|
||||||
"Report bugs to <libssh@libssh.org>.\n",
|
|
||||||
argv[0], SSH_STRINGIFY(LIBSSH_VERSION));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind != argc - 1) {
|
|
||||||
printf("Usage: %s [OPTION...] BINDADDR\n", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, argv[optind]);
|
|
||||||
|
|
||||||
if (!no_default_keys) {
|
|
||||||
set_default_keys(sshbind,
|
|
||||||
rsa_already_set,
|
|
||||||
dsa_already_set,
|
|
||||||
ecdsa_already_set);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_ARGP_H */
|
#endif /* HAVE_ARGP_H */
|
||||||
|
|
||||||
/* A userdata struct for channel. */
|
/* A userdata struct for channel. */
|
||||||
@@ -549,7 +425,7 @@ static int auth_password(ssh_session session, const char *user,
|
|||||||
|
|
||||||
(void) session;
|
(void) session;
|
||||||
|
|
||||||
if (strcmp(user, username) == 0 && strcmp(pass, password) == 0) {
|
if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0) {
|
||||||
sdata->authenticated = 1;
|
sdata->authenticated = 1;
|
||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -558,53 +434,6 @@ static int auth_password(ssh_session session, const char *user,
|
|||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int auth_publickey(ssh_session session,
|
|
||||||
const char *user,
|
|
||||||
struct ssh_key_struct *pubkey,
|
|
||||||
char signature_state,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
|
||||||
|
|
||||||
(void) user;
|
|
||||||
(void) session;
|
|
||||||
|
|
||||||
if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
|
|
||||||
return SSH_AUTH_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signature_state != SSH_PUBLICKEY_STATE_VALID) {
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// valid so far. Now look through authorized keys for a match
|
|
||||||
if (authorizedkeys[0]) {
|
|
||||||
ssh_key key = NULL;
|
|
||||||
int result;
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
if (stat(authorizedkeys, &buf) == 0) {
|
|
||||||
result = ssh_pki_import_pubkey_file( authorizedkeys, &key );
|
|
||||||
if ((result != SSH_OK) || (key==NULL)) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Unable to import public key file %s\n",
|
|
||||||
authorizedkeys);
|
|
||||||
} else {
|
|
||||||
result = ssh_key_cmp( key, pubkey, SSH_KEY_CMP_PUBLIC );
|
|
||||||
ssh_key_free(key);
|
|
||||||
if (result == 0) {
|
|
||||||
sdata->authenticated = 1;
|
|
||||||
return SSH_AUTH_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no matches
|
|
||||||
sdata->authenticated = 0;
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssh_channel channel_open(ssh_session session, void *userdata) {
|
static ssh_channel channel_open(ssh_session session, void *userdata) {
|
||||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
||||||
|
|
||||||
@@ -643,8 +472,7 @@ static int process_stderr(socket_t fd, int revents, void *userdata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void handle_session(ssh_event event, ssh_session session) {
|
static void handle_session(ssh_event event, ssh_session session) {
|
||||||
int n;
|
int n, rc;
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
/* Structure for storing the pty size. */
|
/* Structure for storing the pty size. */
|
||||||
struct winsize wsize = {
|
struct winsize wsize = {
|
||||||
@@ -689,12 +517,6 @@ static void handle_session(ssh_event event, ssh_session session) {
|
|||||||
.channel_open_request_session_function = channel_open,
|
.channel_open_request_session_function = channel_open,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (authorizedkeys[0]) {
|
|
||||||
server_cb.auth_pubkey_function = auth_publickey;
|
|
||||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY);
|
|
||||||
} else
|
|
||||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
|
|
||||||
|
|
||||||
ssh_callbacks_init(&server_cb);
|
ssh_callbacks_init(&server_cb);
|
||||||
ssh_callbacks_init(&channel_cb);
|
ssh_callbacks_init(&channel_cb);
|
||||||
|
|
||||||
@@ -705,6 +527,7 @@ static void handle_session(ssh_event event, ssh_session session) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
|
||||||
ssh_event_add_session(event, session);
|
ssh_event_add_session(event, session);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
@@ -787,38 +610,18 @@ static void handle_session(ssh_event event, ssh_session session) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_FORK
|
|
||||||
/* SIGCHLD handler for cleaning up dead children. */
|
/* SIGCHLD handler for cleaning up dead children. */
|
||||||
static void sigchld_handler(int signo) {
|
static void sigchld_handler(int signo) {
|
||||||
(void) signo;
|
(void) signo;
|
||||||
while (waitpid(-1, NULL, WNOHANG) > 0);
|
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void *session_thread(void *arg) {
|
|
||||||
ssh_session session = arg;
|
|
||||||
ssh_event event;
|
|
||||||
|
|
||||||
event = ssh_event_new();
|
|
||||||
if (event != NULL) {
|
|
||||||
/* Blocks until the SSH session ends by either
|
|
||||||
* child thread exiting, or client disconnecting. */
|
|
||||||
handle_session(event, session);
|
|
||||||
ssh_event_free(event);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Could not create polling context\n");
|
|
||||||
}
|
|
||||||
ssh_disconnect(session);
|
|
||||||
ssh_free(session);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
ssh_bind sshbind;
|
ssh_bind sshbind;
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
int rc;
|
ssh_event event;
|
||||||
#ifdef WITH_FORK
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Set up SIGCHLD handler. */
|
/* Set up SIGCHLD handler. */
|
||||||
sa.sa_handler = sigchld_handler;
|
sa.sa_handler = sigchld_handler;
|
||||||
@@ -828,7 +631,6 @@ int main(int argc, char **argv) {
|
|||||||
fprintf(stderr, "Failed to register SIGCHLD handler\n");
|
fprintf(stderr, "Failed to register SIGCHLD handler\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
rc = ssh_init();
|
rc = ssh_init();
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -839,24 +641,20 @@ int main(int argc, char **argv) {
|
|||||||
sshbind = ssh_bind_new();
|
sshbind = ssh_bind_new();
|
||||||
if (sshbind == NULL) {
|
if (sshbind == NULL) {
|
||||||
fprintf(stderr, "ssh_bind_new failed\n");
|
fprintf(stderr, "ssh_bind_new failed\n");
|
||||||
ssh_finalize();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ARGP_H
|
#ifdef HAVE_ARGP_H
|
||||||
argp_parse(&argp, argc, argv, 0, 0, sshbind);
|
argp_parse(&argp, argc, argv, 0, 0, sshbind);
|
||||||
#else
|
#else
|
||||||
if (parse_opt(argc, argv, sshbind) < 0) {
|
(void) argc;
|
||||||
ssh_bind_free(sshbind);
|
(void) argv;
|
||||||
ssh_finalize();
|
|
||||||
return 1;
|
set_default_keys(sshbind, 0, 0, 0);
|
||||||
}
|
|
||||||
#endif /* HAVE_ARGP_H */
|
#endif /* HAVE_ARGP_H */
|
||||||
|
|
||||||
if(ssh_bind_listen(sshbind) < 0) {
|
if(ssh_bind_listen(sshbind) < 0) {
|
||||||
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
||||||
ssh_bind_free(sshbind);
|
|
||||||
ssh_finalize();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -869,9 +667,6 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
/* Blocks until there is a new incoming connection. */
|
/* Blocks until there is a new incoming connection. */
|
||||||
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
|
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
|
||||||
#ifdef WITH_FORK
|
|
||||||
ssh_event event;
|
|
||||||
|
|
||||||
switch(fork()) {
|
switch(fork()) {
|
||||||
case 0:
|
case 0:
|
||||||
/* Remove the SIGCHLD handler inherited from parent. */
|
/* Remove the SIGCHLD handler inherited from parent. */
|
||||||
@@ -897,16 +692,6 @@ int main(int argc, char **argv) {
|
|||||||
case -1:
|
case -1:
|
||||||
fprintf(stderr, "Failed to fork\n");
|
fprintf(stderr, "Failed to fork\n");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
pthread_t tid;
|
|
||||||
|
|
||||||
rc = pthread_create(&tid, NULL, session_thread, session);
|
|
||||||
if (rc == 0) {
|
|
||||||
pthread_detach(tid);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "Failed to pthread_create\n");
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
||||||
}
|
}
|
||||||
@@ -1,757 +0,0 @@
|
|||||||
/* This is a sample implementation of a libssh based SSH server */
|
|
||||||
/*
|
|
||||||
Copyright 2003-2009 Aris Adamantiadis
|
|
||||||
Copyright 2018 T. Wimmer
|
|
||||||
|
|
||||||
This file is part of the SSH Library
|
|
||||||
|
|
||||||
You are free to copy this file, modify it in any way, consider it being public
|
|
||||||
domain. This does not apply to the rest of the library though, but it is
|
|
||||||
allowed to cut-and-paste working code from this file to any license of
|
|
||||||
program.
|
|
||||||
The goal is to show the API in action. It's not a reference on how terminal
|
|
||||||
clients must be made or how a client should react.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Example:
|
|
||||||
./sshd_direct-tcpip -v -p 2022 -d serverkey.dsa -r serverkey.rsa 127.0.0.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <libssh/libssh.h>
|
|
||||||
#include <libssh/server.h>
|
|
||||||
#include <libssh/callbacks.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_ARGP_H
|
|
||||||
#include <argp.h>
|
|
||||||
#endif
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <poll.h>
|
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 16384
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
|
|
||||||
|
|
||||||
#ifndef __unused__
|
|
||||||
# ifdef HAVE_UNUSED_ATTRIBUTE
|
|
||||||
# define __unused__ __attribute__((unused))
|
|
||||||
# else /* HAVE_UNUSED_ATTRIBUTE */
|
|
||||||
# define __unused__
|
|
||||||
# endif /* HAVE_UNUSED_ATTRIBUTE */
|
|
||||||
#endif /* __unused__ */
|
|
||||||
|
|
||||||
#ifndef UNUSED_PARAM
|
|
||||||
#define UNUSED_PARAM(param) param __unused__
|
|
||||||
#endif /* UNUSED_PARAM */
|
|
||||||
|
|
||||||
#ifndef KEYS_FOLDER
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define KEYS_FOLDER
|
|
||||||
#else
|
|
||||||
#define KEYS_FOLDER "/etc/ssh/"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define USER "user"
|
|
||||||
#define PASSWORD "pwd"
|
|
||||||
|
|
||||||
struct event_fd_data_struct {
|
|
||||||
int *p_fd;
|
|
||||||
ssh_channel channel;
|
|
||||||
struct ssh_channel_callbacks_struct *cb_chan;
|
|
||||||
int stacked;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cleanup_node_struct {
|
|
||||||
struct event_fd_data_struct *data;
|
|
||||||
struct cleanup_node_struct *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool authenticated = false;
|
|
||||||
static int tries = 0;
|
|
||||||
static bool error_set = false;
|
|
||||||
static int sockets_cnt = 0;
|
|
||||||
static ssh_event mainloop = NULL;
|
|
||||||
static struct cleanup_node_struct *cleanup_stack = NULL;
|
|
||||||
|
|
||||||
static void _close_socket(struct event_fd_data_struct event_fd_data);
|
|
||||||
|
|
||||||
static void
|
|
||||||
cleanup_push(struct cleanup_node_struct** head_ref,
|
|
||||||
struct event_fd_data_struct *new_data)
|
|
||||||
{
|
|
||||||
// Allocate memory for node
|
|
||||||
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
|
|
||||||
|
|
||||||
if (*head_ref != NULL) {
|
|
||||||
new_node->next = *head_ref;
|
|
||||||
} else {
|
|
||||||
new_node->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy new_data
|
|
||||||
new_node->data = new_data;
|
|
||||||
|
|
||||||
// Change head pointer as new node is added at the beginning
|
|
||||||
(*head_ref) = new_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
do_cleanup(struct cleanup_node_struct **head_ref)
|
|
||||||
{
|
|
||||||
struct cleanup_node_struct *current = (*head_ref);
|
|
||||||
struct cleanup_node_struct *previous = NULL, *gone = NULL;
|
|
||||||
|
|
||||||
while (current != NULL) {
|
|
||||||
if (ssh_channel_is_closed(current->data->channel)) {
|
|
||||||
if (current == (*head_ref)) {
|
|
||||||
(*head_ref) = current->next;
|
|
||||||
}
|
|
||||||
if (previous != NULL) {
|
|
||||||
previous->next = current->next;
|
|
||||||
}
|
|
||||||
gone = current;
|
|
||||||
current = current->next;
|
|
||||||
|
|
||||||
if (gone->data->channel) {
|
|
||||||
_close_socket(*gone->data);
|
|
||||||
ssh_remove_channel_callbacks(gone->data->channel, gone->data->cb_chan);
|
|
||||||
ssh_channel_free(gone->data->channel);
|
|
||||||
gone->data->channel = NULL;
|
|
||||||
|
|
||||||
SAFE_FREE(gone->data->p_fd);
|
|
||||||
SAFE_FREE(gone->data->cb_chan);
|
|
||||||
SAFE_FREE(gone->data);
|
|
||||||
SAFE_FREE(gone);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "channel already freed!\n");
|
|
||||||
}
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== do_cleanup", "Freed.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ssh_channel_close(current->data->channel);
|
|
||||||
previous = current;
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
auth_password(ssh_session session,
|
|
||||||
const char *user,
|
|
||||||
const char *password,
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== auth_password", "Authenticating user %s pwd %s",
|
|
||||||
user,
|
|
||||||
password);
|
|
||||||
if (strcmp(user, USER) == 0 && strcmp(password, PASSWORD) == 0) {
|
|
||||||
authenticated = true;
|
|
||||||
printf("Authenticated\n");
|
|
||||||
return SSH_AUTH_SUCCESS;
|
|
||||||
}
|
|
||||||
if (tries >= 3) {
|
|
||||||
printf("Too many authentication tries\n");
|
|
||||||
ssh_disconnect(session);
|
|
||||||
error_set = true;
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
}
|
|
||||||
tries++;
|
|
||||||
return SSH_AUTH_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
auth_gssapi_mic(ssh_session session,
|
|
||||||
const char *user,
|
|
||||||
const char *principal,
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
ssh_gssapi_creds creds = ssh_gssapi_get_creds(session);
|
|
||||||
printf("Authenticating user %s with gssapi principal %s\n",
|
|
||||||
user, principal);
|
|
||||||
if (creds != NULL) {
|
|
||||||
printf("Received some gssapi credentials\n");
|
|
||||||
} else {
|
|
||||||
printf("Not received any forwardable creds\n");
|
|
||||||
}
|
|
||||||
printf("authenticated\n");
|
|
||||||
authenticated = true;
|
|
||||||
return SSH_AUTH_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
subsystem_request(UNUSED_PARAM(ssh_session session),
|
|
||||||
UNUSED_PARAM(ssh_channel channel),
|
|
||||||
const char *subsystem,
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== subsystem_request", "Channel subsystem request: %s",
|
|
||||||
subsystem);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ssh_channel_callbacks_struct channel_cb = {
|
|
||||||
.channel_subsystem_request_function = subsystem_request
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssh_channel
|
|
||||||
new_session_channel(UNUSED_PARAM(ssh_session session),
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== subsystem_request", "Session channel request");
|
|
||||||
/* For TCP forward only there seems to be no need for a session channel */
|
|
||||||
/*if(chan != NULL)
|
|
||||||
return NULL;
|
|
||||||
printf("Session channel request\n");
|
|
||||||
chan = ssh_channel_new(session);
|
|
||||||
ssh_callbacks_init(&channel_cb);
|
|
||||||
ssh_set_channel_callbacks(chan, &channel_cb);
|
|
||||||
return chan;*/
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
stack_socket_close(UNUSED_PARAM(ssh_session session),
|
|
||||||
struct event_fd_data_struct *event_fd_data)
|
|
||||||
{
|
|
||||||
if (event_fd_data->stacked != 1) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== stack_socket_close",
|
|
||||||
"Closing fd = %d sockets_cnt = %d", *event_fd_data->p_fd,
|
|
||||||
sockets_cnt);
|
|
||||||
event_fd_data->stacked = 1;
|
|
||||||
cleanup_push(&cleanup_stack, event_fd_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_close_socket(struct event_fd_data_struct event_fd_data)
|
|
||||||
{
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== close_socket",
|
|
||||||
"Closing fd = %d sockets_cnt = %d", *event_fd_data.p_fd,
|
|
||||||
sockets_cnt);
|
|
||||||
ssh_event_remove_fd(mainloop, *event_fd_data.p_fd);
|
|
||||||
sockets_cnt--;
|
|
||||||
#ifdef _WIN32
|
|
||||||
closesocket(*event_fd_data.p_fd);
|
|
||||||
#else
|
|
||||||
close(*event_fd_data.p_fd);
|
|
||||||
#endif // _WIN32
|
|
||||||
(*event_fd_data.p_fd) = SSH_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
service_request(UNUSED_PARAM(ssh_session session),
|
|
||||||
const char *service,
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== service_request", "Service request: %s", service);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
global_request(UNUSED_PARAM(ssh_session session),
|
|
||||||
ssh_message message,
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== global_request", "Global request, message type: %d",
|
|
||||||
ssh_message_type(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
my_channel_close_function(ssh_session session,
|
|
||||||
UNUSED_PARAM(ssh_channel channel),
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== my_channel_close_function",
|
|
||||||
"Channel closed by remote.");
|
|
||||||
|
|
||||||
stack_socket_close(session, event_fd_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
my_channel_eof_function(ssh_session session,
|
|
||||||
UNUSED_PARAM(ssh_channel channel),
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== my_channel_eof_function",
|
|
||||||
"Got EOF on channel. Shutting down write on socket (fd = %d).",
|
|
||||||
*event_fd_data->p_fd);
|
|
||||||
|
|
||||||
stack_socket_close(session, event_fd_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
my_channel_exit_status_function(UNUSED_PARAM(ssh_session session),
|
|
||||||
UNUSED_PARAM(ssh_channel channel),
|
|
||||||
int exit_status,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== my_channel_exit_status_function",
|
|
||||||
"Got exit status %d on channel fd = %d.",
|
|
||||||
exit_status, *event_fd_data->p_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
my_channel_data_function(ssh_session session,
|
|
||||||
UNUSED_PARAM(ssh_channel channel),
|
|
||||||
void *data,
|
|
||||||
uint32_t len,
|
|
||||||
UNUSED_PARAM(int is_stderr),
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
|
||||||
|
|
||||||
if (event_fd_data->channel == NULL) {
|
|
||||||
fprintf(stderr, "Why we're here? Stacked = %d\n", event_fd_data->stacked);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL,
|
|
||||||
"=== my_channel_data_function",
|
|
||||||
"%d bytes waiting on channel for reading. Fd = %d",
|
|
||||||
len,
|
|
||||||
*event_fd_data->p_fd);
|
|
||||||
if (len > 0) {
|
|
||||||
i = send(*event_fd_data->p_fd, data, len, 0);
|
|
||||||
}
|
|
||||||
if (i < 0) {
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== my_channel_data_function",
|
|
||||||
"Writing to tcp socket %d: %s", *event_fd_data->p_fd,
|
|
||||||
strerror(errno));
|
|
||||||
stack_socket_close(session, event_fd_data);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_channel_data_function", "Sent %d bytes", i);
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
my_fd_data_function(UNUSED_PARAM(socket_t fd),
|
|
||||||
int revents,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
|
|
||||||
ssh_channel channel = event_fd_data->channel;
|
|
||||||
ssh_session session;
|
|
||||||
int len, i, wr;
|
|
||||||
char buf[BUF_SIZE];
|
|
||||||
int blocking;
|
|
||||||
|
|
||||||
if (channel == NULL) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel == NULL!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
session = ssh_channel_get_session(channel);
|
|
||||||
|
|
||||||
if (ssh_channel_is_closed(channel)) {
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel is closed!");
|
|
||||||
stack_socket_close(session, event_fd_data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(revents & POLLIN)) {
|
|
||||||
if (revents & POLLPRI) {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLPRI");
|
|
||||||
}
|
|
||||||
if (revents & POLLOUT) {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLOUT");
|
|
||||||
}
|
|
||||||
if (revents & POLLHUP) {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLHUP");
|
|
||||||
}
|
|
||||||
if (revents & POLLNVAL) {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLNVAL");
|
|
||||||
}
|
|
||||||
if (revents & POLLERR) {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLERR");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blocking = ssh_is_blocking(session);
|
|
||||||
ssh_set_blocking(session, 0);
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS,
|
|
||||||
"=== my_fd_data_function",
|
|
||||||
"Trying to read from tcp socket fd = %d",
|
|
||||||
*event_fd_data->p_fd);
|
|
||||||
#ifdef _WIN32
|
|
||||||
struct sockaddr from;
|
|
||||||
int fromlen = sizeof(from);
|
|
||||||
len = recvfrom(*event_fd_data->p_fd, buf, sizeof(buf), 0, &from, &fromlen);
|
|
||||||
#else
|
|
||||||
len = recv(*event_fd_data->p_fd, buf, sizeof(buf), 0);
|
|
||||||
#endif // _WIN32
|
|
||||||
if (len < 0) {
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Reading from tcp socket: %s", strerror(errno));
|
|
||||||
|
|
||||||
ssh_channel_send_eof(channel);
|
|
||||||
}
|
|
||||||
else if (len > 0) {
|
|
||||||
if (ssh_channel_is_open(channel)) {
|
|
||||||
wr = 0;
|
|
||||||
do {
|
|
||||||
i = ssh_channel_write(channel, buf, len);
|
|
||||||
if (i < 0) {
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Error writing on the direct-tcpip channel: %d", i);
|
|
||||||
len = wr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wr += i;
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "ssh_channel_write (%d from %d)", wr, len);
|
|
||||||
} while (i > 0 && wr < len);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Can't write on closed channel!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "The destination host has disconnected!");
|
|
||||||
|
|
||||||
ssh_channel_close(channel);
|
|
||||||
#ifdef _WIN32
|
|
||||||
shutdown(*event_fd_data->p_fd, SD_RECEIVE);
|
|
||||||
#else
|
|
||||||
shutdown(*event_fd_data->p_fd, SHUT_RD);
|
|
||||||
#endif // _WIN32
|
|
||||||
}
|
|
||||||
ssh_set_blocking(session, blocking);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
open_tcp_socket(ssh_message msg)
|
|
||||||
{
|
|
||||||
struct sockaddr_in sin;
|
|
||||||
int forwardsock = -1;
|
|
||||||
struct hostent *host;
|
|
||||||
const char *dest_hostname;
|
|
||||||
int dest_port;
|
|
||||||
|
|
||||||
forwardsock = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (forwardsock < 0) {
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR opening socket: %s", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest_hostname = ssh_message_channel_request_open_destination(msg);
|
|
||||||
dest_port = ssh_message_channel_request_open_destination_port(msg);
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== open_tcp_socket", "Connecting to %s on port %d", dest_hostname, dest_port);
|
|
||||||
|
|
||||||
host = gethostbyname(dest_hostname);
|
|
||||||
if (host == NULL) {
|
|
||||||
close(forwardsock);
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR, no such host: %s", dest_hostname);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset((char *)&sin, '\0', sizeof(sin));
|
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
memcpy((char *)&sin.sin_addr.s_addr, (char *)host->h_addr, host->h_length);
|
|
||||||
sin.sin_port = htons(dest_port);
|
|
||||||
|
|
||||||
if (connect(forwardsock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
|
||||||
close(forwardsock);
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR connecting: %s", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockets_cnt++;
|
|
||||||
_ssh_log(SSH_LOG_FUNCTIONS, "=== open_tcp_socket", "Connected. sockets_cnt = %d", sockets_cnt);
|
|
||||||
return forwardsock;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
message_callback(UNUSED_PARAM(ssh_session session),
|
|
||||||
ssh_message message,
|
|
||||||
UNUSED_PARAM(void *userdata))
|
|
||||||
{
|
|
||||||
ssh_channel channel;
|
|
||||||
int socket_fd, *pFd;
|
|
||||||
struct ssh_channel_callbacks_struct *cb_chan;
|
|
||||||
struct event_fd_data_struct *event_fd_data;
|
|
||||||
|
|
||||||
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d",
|
|
||||||
ssh_message_type(message));
|
|
||||||
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message Subtype: %d",
|
|
||||||
ssh_message_subtype(message));
|
|
||||||
if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN) {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "channel_request_open");
|
|
||||||
|
|
||||||
if (ssh_message_subtype(message) == SSH_CHANNEL_DIRECT_TCPIP) {
|
|
||||||
channel = ssh_message_channel_request_open_reply_accept(message);
|
|
||||||
|
|
||||||
if (channel == NULL) {
|
|
||||||
_ssh_log(SSH_LOG_WARNING, "=== message_callback", "Accepting direct-tcpip channel failed!");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "Connected to channel!");
|
|
||||||
|
|
||||||
socket_fd = open_tcp_socket(message);
|
|
||||||
if (-1 == socket_fd) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFd = malloc(sizeof *pFd);
|
|
||||||
cb_chan = malloc(sizeof *cb_chan);
|
|
||||||
event_fd_data = malloc(sizeof *event_fd_data);
|
|
||||||
if (pFd == NULL || cb_chan == NULL || event_fd_data == NULL) {
|
|
||||||
SAFE_FREE(pFd);
|
|
||||||
SAFE_FREE(cb_chan);
|
|
||||||
SAFE_FREE(event_fd_data);
|
|
||||||
close(socket_fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*pFd) = socket_fd;
|
|
||||||
event_fd_data->channel = channel;
|
|
||||||
event_fd_data->p_fd = pFd;
|
|
||||||
event_fd_data->stacked = 0;
|
|
||||||
event_fd_data->cb_chan = cb_chan;
|
|
||||||
|
|
||||||
cb_chan->userdata = event_fd_data;
|
|
||||||
cb_chan->channel_eof_function = my_channel_eof_function;
|
|
||||||
cb_chan->channel_close_function = my_channel_close_function;
|
|
||||||
cb_chan->channel_data_function = my_channel_data_function;
|
|
||||||
cb_chan->channel_exit_status_function = my_channel_exit_status_function;
|
|
||||||
|
|
||||||
ssh_callbacks_init(cb_chan);
|
|
||||||
ssh_set_channel_callbacks(channel, cb_chan);
|
|
||||||
|
|
||||||
ssh_event_add_fd(mainloop, (socket_t)*pFd, POLLIN, my_fd_data_function, event_fd_data);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_ARGP_H
|
|
||||||
const char *argp_program_version = "libssh server example "
|
|
||||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
|
||||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
|
||||||
|
|
||||||
/* Program documentation. */
|
|
||||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
|
||||||
|
|
||||||
/* A description of the arguments we accept. */
|
|
||||||
static char args_doc[] = "BINDADDR";
|
|
||||||
|
|
||||||
/* The options we understand. */
|
|
||||||
static struct argp_option options[] = {
|
|
||||||
{
|
|
||||||
.name = "port",
|
|
||||||
.key = 'p',
|
|
||||||
.arg = "PORT",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set the port to bind.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "hostkey",
|
|
||||||
.key = 'k',
|
|
||||||
.arg = "FILE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set the host key.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "dsakey",
|
|
||||||
.key = 'd',
|
|
||||||
.arg = "FILE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set the dsa key.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "rsakey",
|
|
||||||
.key = 'r',
|
|
||||||
.arg = "FILE",
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Set the rsa key.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "verbose",
|
|
||||||
.key = 'v',
|
|
||||||
.arg = NULL,
|
|
||||||
.flags = 0,
|
|
||||||
.doc = "Get verbose output.",
|
|
||||||
.group = 0
|
|
||||||
},
|
|
||||||
{NULL, 0, NULL, 0, NULL, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Parse a single option. */
|
|
||||||
static error_t
|
|
||||||
parse_opt (int key, char *arg, struct argp_state *state)
|
|
||||||
{
|
|
||||||
/* Get the input argument from argp_parse, which we
|
|
||||||
* know is a pointer to our arguments structure.
|
|
||||||
*/
|
|
||||||
ssh_bind sshbind = state->input;
|
|
||||||
|
|
||||||
switch (key) {
|
|
||||||
case 'p':
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "1");
|
|
||||||
break;
|
|
||||||
case ARGP_KEY_ARG:
|
|
||||||
if (state->arg_num >= 1) {
|
|
||||||
/* Too many arguments. */
|
|
||||||
argp_usage (state);
|
|
||||||
}
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
|
||||||
break;
|
|
||||||
case ARGP_KEY_END:
|
|
||||||
if (state->arg_num < 1) {
|
|
||||||
/* Not enough arguments. */
|
|
||||||
argp_usage (state);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ARGP_ERR_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Our argp parser. */
|
|
||||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
|
||||||
#endif /* HAVE_ARGP_H */
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
ssh_session session;
|
|
||||||
ssh_bind sshbind;
|
|
||||||
struct ssh_server_callbacks_struct cb = {
|
|
||||||
.userdata = NULL,
|
|
||||||
.auth_password_function = auth_password,
|
|
||||||
.auth_gssapi_mic_function = auth_gssapi_mic,
|
|
||||||
.channel_open_request_session_function = new_session_channel,
|
|
||||||
.service_request_function = service_request
|
|
||||||
};
|
|
||||||
struct ssh_callbacks_struct cb_gen = {
|
|
||||||
.userdata = NULL,
|
|
||||||
.global_request_function = global_request
|
|
||||||
};
|
|
||||||
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
sshbind = ssh_bind_new();
|
|
||||||
session = ssh_new();
|
|
||||||
mainloop = ssh_event_new();
|
|
||||||
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
|
|
||||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
|
|
||||||
|
|
||||||
#ifdef HAVE_ARGP_H
|
|
||||||
/*
|
|
||||||
* Parse our arguments; every option seen by parse_opt will
|
|
||||||
* be reflected in arguments.
|
|
||||||
*/
|
|
||||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
|
||||||
#else
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ssh_bind_listen(sshbind) < 0) {
|
|
||||||
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssh_bind_accept(sshbind, session) == SSH_ERROR) {
|
|
||||||
printf("error accepting a connection : %s\n", ssh_get_error(sshbind));
|
|
||||||
ret = 1;
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh_callbacks_init(&cb);
|
|
||||||
ssh_callbacks_init(&cb_gen);
|
|
||||||
ssh_set_server_callbacks(session, &cb);
|
|
||||||
ssh_set_callbacks(session, &cb_gen);
|
|
||||||
ssh_set_message_callback(session, message_callback, (void *)NULL);
|
|
||||||
|
|
||||||
if (ssh_handle_key_exchange(session)) {
|
|
||||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
|
||||||
ret = 1;
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC);
|
|
||||||
ssh_event_add_session(mainloop, session);
|
|
||||||
|
|
||||||
while (!authenticated) {
|
|
||||||
if (error_set) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ssh_event_dopoll(mainloop, -1) == SSH_ERROR) {
|
|
||||||
printf("Error : %s\n", ssh_get_error(session));
|
|
||||||
ret = 1;
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error_set) {
|
|
||||||
printf("Error, exiting loop\n");
|
|
||||||
} else {
|
|
||||||
printf("Authenticated and got a channel\n");
|
|
||||||
|
|
||||||
while (!error_set) {
|
|
||||||
if (ssh_event_dopoll(mainloop, 100) == SSH_ERROR) {
|
|
||||||
printf("Error : %s\n", ssh_get_error(session));
|
|
||||||
ret = 1;
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
do_cleanup(&cleanup_stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shutdown:
|
|
||||||
ssh_disconnect(session);
|
|
||||||
ssh_bind_free(sshbind);
|
|
||||||
ssh_finalize();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -34,11 +34,6 @@ clients must be made or how a client should react.
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "examples_common.h"
|
#include "examples_common.h"
|
||||||
|
|
||||||
#ifndef BUF_SIZE
|
|
||||||
#define BUF_SIZE 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *host;
|
char *host;
|
||||||
const char *desthost="localhost";
|
const char *desthost="localhost";
|
||||||
const char *port="22";
|
const char *port="22";
|
||||||
@@ -82,7 +77,7 @@ static int opts(int argc, char **argv){
|
|||||||
static void select_loop(ssh_session session,ssh_channel channel){
|
static void select_loop(ssh_session session,ssh_channel channel){
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
char buffer[BUF_SIZE];
|
char buffer[4096];
|
||||||
/* channels will be set to the channels to poll.
|
/* channels will be set to the channels to poll.
|
||||||
* outchannels will contain the result of the poll
|
* outchannels will contain the result of the poll
|
||||||
*/
|
*/
|
||||||
@@ -95,7 +90,6 @@ static void select_loop(ssh_session session,ssh_channel channel){
|
|||||||
do{
|
do{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
ZERO_STRUCT(fds);
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
if(!eof)
|
if(!eof)
|
||||||
FD_SET(0,&fds);
|
FD_SET(0,&fds);
|
||||||
@@ -238,10 +232,9 @@ void set_pcap(ssh_session session){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_pcap(void);
|
void cleanup_pcap(void);
|
||||||
void cleanup_pcap(void)
|
void cleanup_pcap(){
|
||||||
{
|
|
||||||
ssh_pcap_file_free(pcap);
|
ssh_pcap_file_free(pcap);
|
||||||
pcap = NULL;
|
pcap=NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -26,14 +26,8 @@ install(
|
|||||||
FILES
|
FILES
|
||||||
${libssh_HDRS}
|
${libssh_HDRS}
|
||||||
DESTINATION
|
DESTINATION
|
||||||
${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}
|
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||||
COMPONENT
|
COMPONENT
|
||||||
headers
|
headers
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libssh_version.h.cmake
|
|
||||||
${libssh_BINARY_DIR}/include/libssh/libssh_version.h
|
|
||||||
@ONLY)
|
|
||||||
install(FILES ${libssh_BINARY_DIR}/include/libssh/libssh_version.h
|
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}
|
|
||||||
COMPONENT headers)
|
|
||||||
|
|||||||
@@ -70,10 +70,6 @@
|
|||||||
#define SSH_AGENT_RSA_SHA2_256 0x02
|
#define SSH_AGENT_RSA_SHA2_256 0x02
|
||||||
#define SSH_AGENT_RSA_SHA2_512 0x04
|
#define SSH_AGENT_RSA_SHA2_512 0x04
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ssh_agent_struct {
|
struct ssh_agent_struct {
|
||||||
struct ssh_socket_struct *sock;
|
struct ssh_socket_struct *sock;
|
||||||
ssh_buffer ident;
|
ssh_buffer ident;
|
||||||
@@ -81,6 +77,7 @@ struct ssh_agent_struct {
|
|||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
/* agent.c */
|
/* agent.c */
|
||||||
/**
|
/**
|
||||||
* @brief Create a new ssh agent structure.
|
* @brief Create a new ssh agent structure.
|
||||||
@@ -107,7 +104,7 @@ void ssh_agent_free(struct ssh_agent_struct *agent);
|
|||||||
*/
|
*/
|
||||||
int ssh_agent_is_running(struct ssh_session_struct *session);
|
int ssh_agent_is_running(struct ssh_session_struct *session);
|
||||||
|
|
||||||
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session);
|
int ssh_agent_get_ident_count(struct ssh_session_struct *session);
|
||||||
|
|
||||||
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||||
char **comment);
|
char **comment);
|
||||||
@@ -118,9 +115,6 @@ ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
|
|||||||
ssh_string ssh_agent_sign_data(ssh_session session,
|
ssh_string ssh_agent_sign_data(ssh_session session,
|
||||||
const ssh_key pubkey,
|
const ssh_key pubkey,
|
||||||
struct ssh_buffer_struct *data);
|
struct ssh_buffer_struct *data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __AGENT_H */
|
#endif /* __AGENT_H */
|
||||||
|
|||||||
@@ -23,10 +23,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "libssh/callbacks.h"
|
#include "libssh/callbacks.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner);
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure);
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_success);
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_success);
|
||||||
@@ -80,14 +76,6 @@ enum ssh_auth_state_e {
|
|||||||
SSH_AUTH_STATE_GSSAPI_TOKEN,
|
SSH_AUTH_STATE_GSSAPI_TOKEN,
|
||||||
/** We have sent the MIC and expecting to be authenticated */
|
/** We have sent the MIC and expecting to be authenticated */
|
||||||
SSH_AUTH_STATE_GSSAPI_MIC_SENT,
|
SSH_AUTH_STATE_GSSAPI_MIC_SENT,
|
||||||
/** We have offered a pubkey to check if it is supported */
|
|
||||||
SSH_AUTH_STATE_PUBKEY_OFFER_SENT,
|
|
||||||
/** We have sent pubkey and signature expecting to be authenticated */
|
|
||||||
SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
|
|
||||||
/** We have sent a password expecting to be authenticated */
|
|
||||||
SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
|
|
||||||
/** We have sent a request without auth information (method 'none') */
|
|
||||||
SSH_AUTH_STATE_AUTH_NONE_SENT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
@@ -104,8 +92,4 @@ enum ssh_auth_service_state_e {
|
|||||||
SSH_AUTH_SERVICE_DENIED,
|
SSH_AUTH_SERVICE_DENIED,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* AUTH_H_ */
|
#endif /* AUTH_H_ */
|
||||||
|
|||||||
@@ -25,16 +25,10 @@
|
|||||||
#include "libssh/libgcrypt.h"
|
#include "libssh/libgcrypt.h"
|
||||||
#include "libssh/libmbedcrypto.h"
|
#include "libssh/libmbedcrypto.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bignum ssh_make_string_bn(ssh_string string);
|
bignum ssh_make_string_bn(ssh_string string);
|
||||||
|
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout);
|
||||||
ssh_string ssh_make_bignum_string(bignum num);
|
ssh_string ssh_make_bignum_string(bignum num);
|
||||||
void ssh_print_bignum(const char *which, const_bignum num);
|
void ssh_print_bignum(const char *which, const bignum num);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BIGNUM_H_ */
|
#endif /* BIGNUM_H_ */
|
||||||
|
|||||||
@@ -22,13 +22,8 @@
|
|||||||
#define BIND_H_
|
#define BIND_H_
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/kex.h"
|
|
||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ssh_bind_struct {
|
struct ssh_bind_struct {
|
||||||
struct ssh_common_struct common; /* stuff common to ssh_bind and ssh_session */
|
struct ssh_common_struct common; /* stuff common to ssh_bind and ssh_session */
|
||||||
struct ssh_bind_callbacks_struct *bind_callbacks;
|
struct ssh_bind_callbacks_struct *bind_callbacks;
|
||||||
@@ -36,7 +31,7 @@ struct ssh_bind_struct {
|
|||||||
|
|
||||||
struct ssh_poll_handle_struct *poll;
|
struct ssh_poll_handle_struct *poll;
|
||||||
/* options */
|
/* options */
|
||||||
char *wanted_methods[SSH_KEX_METHODS];
|
char *wanted_methods[10];
|
||||||
char *banner;
|
char *banner;
|
||||||
char *ecdsakey;
|
char *ecdsakey;
|
||||||
char *dsakey;
|
char *dsakey;
|
||||||
@@ -51,18 +46,10 @@ struct ssh_bind_struct {
|
|||||||
unsigned int bindport;
|
unsigned int bindport;
|
||||||
int blocking;
|
int blocking;
|
||||||
int toaccept;
|
int toaccept;
|
||||||
bool config_processed;
|
|
||||||
char *config_dir;
|
|
||||||
char *pubkey_accepted_key_types;
|
|
||||||
char* moduli_file;
|
|
||||||
int rsa_min_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
||||||
*sshbind);
|
*sshbind);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BIND_H_ */
|
#endif /* BIND_H_ */
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* bind_config.h - Parse the SSH server configuration file
|
|
||||||
*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 by Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
|
||||||
*
|
|
||||||
* The SSH Library is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* The SSH Library is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with the SSH Library; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
* MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BIND_CONFIG_H_
|
|
||||||
#define BIND_CONFIG_H_
|
|
||||||
|
|
||||||
#include "libssh/server.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum ssh_bind_config_opcode_e {
|
|
||||||
/* Known but not allowed in Match block */
|
|
||||||
BIND_CFG_NOT_ALLOWED_IN_MATCH = -4,
|
|
||||||
/* Unknown opcode */
|
|
||||||
BIND_CFG_UNKNOWN = -3,
|
|
||||||
/* Known and not applicable to libssh */
|
|
||||||
BIND_CFG_NA = -2,
|
|
||||||
/* Known but not supported by current libssh version */
|
|
||||||
BIND_CFG_UNSUPPORTED = -1,
|
|
||||||
BIND_CFG_INCLUDE,
|
|
||||||
BIND_CFG_HOSTKEY,
|
|
||||||
BIND_CFG_LISTENADDRESS,
|
|
||||||
BIND_CFG_PORT,
|
|
||||||
BIND_CFG_LOGLEVEL,
|
|
||||||
BIND_CFG_CIPHERS,
|
|
||||||
BIND_CFG_MACS,
|
|
||||||
BIND_CFG_KEXALGORITHMS,
|
|
||||||
BIND_CFG_MATCH,
|
|
||||||
BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES,
|
|
||||||
BIND_CFG_HOSTKEY_ALGORITHMS,
|
|
||||||
|
|
||||||
BIND_CFG_MAX /* Keep this one last in the list */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* @brief Parse configuration file and set the options to the given ssh_bind
|
|
||||||
*
|
|
||||||
* @params[in] sshbind The ssh_bind context to be configured
|
|
||||||
* @params[in] filename The path to the configuration file
|
|
||||||
*
|
|
||||||
* @returns 0 on successful parsing the configuration file, -1 on error
|
|
||||||
*/
|
|
||||||
int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename);
|
|
||||||
|
|
||||||
/* @brief Parse configuration string and set the options to the given bind session
|
|
||||||
*
|
|
||||||
* @params[in] bind The ssh bind session
|
|
||||||
* @params[in] input Null terminated string containing the configuration
|
|
||||||
*
|
|
||||||
* @returns SSH_OK on successful parsing the configuration string,
|
|
||||||
* SSH_ERROR on error
|
|
||||||
*/
|
|
||||||
int ssh_bind_config_parse_string(ssh_bind bind, const char *input);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BIND_CONFIG_H_ */
|
|
||||||
@@ -49,10 +49,6 @@
|
|||||||
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
|
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
|
||||||
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
|
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Blowfish context */
|
/* Blowfish context */
|
||||||
typedef struct BlowfishContext {
|
typedef struct BlowfishContext {
|
||||||
uint32_t S[4][256]; /* S-Boxes */
|
uint32_t S[4][256]; /* S-Boxes */
|
||||||
@@ -88,9 +84,4 @@ void ssh_blf_cbc_decrypt(ssh_blf_ctx *, uint8_t *, uint8_t *, uint32_t);
|
|||||||
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t , uint16_t *);
|
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t , uint16_t *);
|
||||||
|
|
||||||
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
|
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _BLF_H */
|
#endif /* _BLF_H */
|
||||||
|
|||||||
@@ -27,10 +27,6 @@
|
|||||||
|
|
||||||
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
|
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ssh_buffer_set_secure(ssh_buffer buffer);
|
void ssh_buffer_set_secure(ssh_buffer buffer);
|
||||||
int ssh_buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
int ssh_buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
||||||
int ssh_buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
int ssh_buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
||||||
@@ -44,21 +40,21 @@ void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len);
|
|||||||
int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len);
|
int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len);
|
||||||
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
|
||||||
const char *format,
|
const char *format,
|
||||||
size_t argc,
|
int argc,
|
||||||
va_list ap);
|
va_list ap);
|
||||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
|
||||||
const char *format,
|
const char *format,
|
||||||
size_t argc,
|
int argc,
|
||||||
...);
|
...);
|
||||||
#define ssh_buffer_pack(buffer, format, ...) \
|
#define ssh_buffer_pack(buffer, format, ...) \
|
||||||
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||||
|
|
||||||
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
|
||||||
const char *format, size_t argc,
|
const char *format, int argc,
|
||||||
va_list ap);
|
va_list ap);
|
||||||
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
|
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
|
||||||
const char *format,
|
const char *format,
|
||||||
size_t argc,
|
int argc,
|
||||||
...);
|
...);
|
||||||
#define ssh_buffer_unpack(buffer, format, ...) \
|
#define ssh_buffer_unpack(buffer, format, ...) \
|
||||||
_ssh_buffer_unpack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
_ssh_buffer_unpack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||||
@@ -67,9 +63,9 @@ int ssh_buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
|
|||||||
int ssh_buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
|
int ssh_buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
|
||||||
|
|
||||||
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
|
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
|
||||||
uint32_t ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data);
|
int ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data);
|
||||||
uint32_t ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data);
|
int ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data);
|
||||||
uint32_t ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
|
int ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
|
||||||
|
|
||||||
/* ssh_buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
|
/* ssh_buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
|
||||||
ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
|
ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
|
||||||
@@ -78,8 +74,4 @@ ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
|
|||||||
uint32_t ssh_buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
|
uint32_t ssh_buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
|
||||||
uint32_t ssh_buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
|
uint32_t ssh_buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BUFFER_H_ */
|
#endif /* BUFFER_H_ */
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Andreas Schneider <asn@cryptomilk.org>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
#ifndef _BYTEARRAY_H
|
|
||||||
#define _BYTEARRAY_H
|
|
||||||
|
|
||||||
#define _DATA_BYTE_CONST(data, pos) \
|
|
||||||
((uint8_t)(((const uint8_t *)(data))[(pos)]))
|
|
||||||
|
|
||||||
#define _DATA_BYTE(data, pos) \
|
|
||||||
(((uint8_t *)(data))[(pos)])
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These macros pull or push integer values from byte arrays stored in
|
|
||||||
* little-endian byte order.
|
|
||||||
*/
|
|
||||||
#define PULL_LE_U8(data, pos) \
|
|
||||||
(_DATA_BYTE_CONST(data, pos))
|
|
||||||
|
|
||||||
#define PULL_LE_U16(data, pos) \
|
|
||||||
((uint16_t)PULL_LE_U8(data, pos) | ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8)
|
|
||||||
|
|
||||||
#define PULL_LE_U32(data, pos) \
|
|
||||||
((uint32_t)(PULL_LE_U16(data, pos) | ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16))
|
|
||||||
|
|
||||||
#define PULL_LE_U64(data, pos) \
|
|
||||||
((uint64_t)(PULL_LE_U32(data, pos) | ((uint64_t)PULL_LE_U32(data, (pos) + 4)) << 32))
|
|
||||||
|
|
||||||
|
|
||||||
#define PUSH_LE_U8(data, pos, val) \
|
|
||||||
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
|
|
||||||
|
|
||||||
#define PUSH_LE_U16(data, pos, val) \
|
|
||||||
(PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)), PUSH_LE_U8((data), (pos) + 1, (uint8_t)((uint16_t)(val) >> 8)))
|
|
||||||
|
|
||||||
#define PUSH_LE_U32(data, pos, val) \
|
|
||||||
(PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)), PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16)))
|
|
||||||
|
|
||||||
#define PUSH_LE_U64(data, pos, val) \
|
|
||||||
(PUSH_LE_U32((data), (pos), (uint32_t)((uint64_t)(val) & 0xffffffff)), PUSH_LE_U32((data), (pos) + 4, (uint32_t)((uint64_t)(val) >> 32)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These macros pull or push integer values from byte arrays stored in
|
|
||||||
* big-endian byte order (network byte order).
|
|
||||||
*/
|
|
||||||
#define PULL_BE_U8(data, pos) \
|
|
||||||
(_DATA_BYTE_CONST(data, pos))
|
|
||||||
|
|
||||||
#define PULL_BE_U16(data, pos) \
|
|
||||||
((((uint16_t)(PULL_BE_U8(data, pos))) << 8) | (uint16_t)PULL_BE_U8(data, (pos) + 1))
|
|
||||||
|
|
||||||
#define PULL_BE_U32(data, pos) \
|
|
||||||
((((uint32_t)PULL_BE_U16(data, pos)) << 16) | (uint32_t)(PULL_BE_U16(data, (pos) + 2)))
|
|
||||||
|
|
||||||
#define PULL_BE_U64(data, pos) \
|
|
||||||
((((uint64_t)PULL_BE_U32(data, pos)) << 32) | (uint64_t)(PULL_BE_U32(data, (pos) + 4)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define PUSH_BE_U8(data, pos, val) \
|
|
||||||
(_DATA_BYTE(data, pos) = ((uint8_t)(val)))
|
|
||||||
|
|
||||||
#define PUSH_BE_U16(data, pos, val) \
|
|
||||||
(PUSH_BE_U8((data), (pos), (uint8_t)(((uint16_t)(val)) >> 8)), PUSH_BE_U8((data), (pos) + 1, (uint8_t)((val) & 0xff)))
|
|
||||||
|
|
||||||
#define PUSH_BE_U32(data, pos, val) \
|
|
||||||
(PUSH_BE_U16((data), (pos), (uint16_t)(((uint32_t)(val)) >> 16)), PUSH_BE_U16((data), (pos) + 2, (uint16_t)((val) & 0xffff)))
|
|
||||||
|
|
||||||
#define PUSH_BE_U64(data, pos, val) \
|
|
||||||
(PUSH_BE_U32((data), (pos), (uint32_t)(((uint64_t)(val)) >> 32)), PUSH_BE_U32((data), (pos) + 4, (uint32_t)((val) & 0xffffffff)))
|
|
||||||
|
|
||||||
#endif /* _BYTEARRAY_H */
|
|
||||||
@@ -56,7 +56,7 @@ typedef void (*ssh_callback_int) (int code, void *user);
|
|||||||
* @returns number of bytes processed by the callee. The remaining bytes will
|
* @returns number of bytes processed by the callee. The remaining bytes will
|
||||||
* be sent in the next callback message, when more data is available.
|
* be sent in the next callback message, when more data is available.
|
||||||
*/
|
*/
|
||||||
typedef size_t (*ssh_callback_data) (const void *data, size_t len, void *user);
|
typedef int (*ssh_callback_data) (const void *data, size_t len, void *user);
|
||||||
|
|
||||||
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
|
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
|
||||||
|
|
||||||
@@ -81,9 +81,9 @@ typedef void (*ssh_log_callback) (ssh_session session, int priority,
|
|||||||
*
|
*
|
||||||
* @param priority Priority of the log, the smaller being the more important.
|
* @param priority Priority of the log, the smaller being the more important.
|
||||||
*
|
*
|
||||||
* @param function The function name calling the logging functions.
|
* @param function The function name calling the the logging fucntions.
|
||||||
*
|
*
|
||||||
* @param buffer The actual message
|
* @param message The actual message
|
||||||
*
|
*
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
*/
|
*/
|
||||||
@@ -117,8 +117,6 @@ typedef void (*ssh_global_request_callback) (ssh_session session,
|
|||||||
* sends back an X11 connection attempt. This is a client-side API
|
* sends back an X11 connection attempt. This is a client-side API
|
||||||
* @param session current session handler
|
* @param session current session handler
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @param originator_address IP address of the machine who sent the request
|
|
||||||
* @param originator_port port number of the machine who sent the request
|
|
||||||
* @returns a valid ssh_channel handle if the request is to be allowed
|
* @returns a valid ssh_channel handle if the request is to be allowed
|
||||||
* @returns NULL if the request should not be allowed
|
* @returns NULL if the request should not be allowed
|
||||||
* @warning The channel pointer returned by this callback must be closed by the application.
|
* @warning The channel pointer returned by this callback must be closed by the application.
|
||||||
@@ -223,8 +221,8 @@ typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *us
|
|||||||
* @param user User that wants to authenticate
|
* @param user User that wants to authenticate
|
||||||
* @param pubkey public key used for authentication
|
* @param pubkey public key used for authentication
|
||||||
* @param signature_state SSH_PUBLICKEY_STATE_NONE if the key is not signed (simple public key probe),
|
* @param signature_state SSH_PUBLICKEY_STATE_NONE if the key is not signed (simple public key probe),
|
||||||
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
|
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
|
||||||
* replied with a SSH_AUTH_DENIED.
|
* replied with a SSH_AUTH_DENIED.
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||||
@@ -270,11 +268,11 @@ typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const
|
|||||||
int n_oid, ssh_string *oids, void *userdata);
|
int n_oid, ssh_string *oids, void *userdata);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief handle the negotiation of a security context, server side.
|
* @brief handle the negociation of a security context, server side.
|
||||||
* @param session current session handler
|
* @param session current session handler
|
||||||
* @param[in] input_token input token provided by client
|
* @param[in] input_token input token provided by client
|
||||||
* @param[out] output_token output of the gssapi accept_sec_context method,
|
* @param[out] output_token output of the gssapi accept_sec_context method,
|
||||||
* NULL after completion.
|
* NULL after completion.
|
||||||
* @returns SSH_OK if the token was generated correctly or accept_sec_context
|
* @returns SSH_OK if the token was generated correctly or accept_sec_context
|
||||||
* returned GSS_S_COMPLETE
|
* returned GSS_S_COMPLETE
|
||||||
* @returns SSH_ERROR in case of error
|
* @returns SSH_ERROR in case of error
|
||||||
@@ -356,9 +354,6 @@ typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
|
|||||||
* This functions sets the callback structure to use your own callback
|
* This functions sets the callback structure to use your own callback
|
||||||
* functions for user authentication, new channels and requests.
|
* functions for user authentication, new channels and requests.
|
||||||
*
|
*
|
||||||
* Note, that the structure is not copied to the session structure so it needs
|
|
||||||
* to be valid for the whole session lifetime.
|
|
||||||
*
|
|
||||||
* @code
|
* @code
|
||||||
* struct ssh_server_callbacks_struct cb = {
|
* struct ssh_server_callbacks_struct cb = {
|
||||||
* .userdata = data,
|
* .userdata = data,
|
||||||
@@ -399,7 +394,7 @@ struct ssh_socket_callbacks_struct {
|
|||||||
*/
|
*/
|
||||||
ssh_callback_int_int exception;
|
ssh_callback_int_int exception;
|
||||||
/** This function is called when the ssh_socket_connect was used on the socket
|
/** This function is called when the ssh_socket_connect was used on the socket
|
||||||
* on nonblocking state, and the connection succeeded.
|
* on nonblocking state, and the connection successed.
|
||||||
*/
|
*/
|
||||||
ssh_callback_int_int connected;
|
ssh_callback_int_int connected;
|
||||||
};
|
};
|
||||||
@@ -553,9 +548,6 @@ typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
|
|||||||
* This functions sets the callback structure to use your own callback
|
* This functions sets the callback structure to use your own callback
|
||||||
* functions for auth, logging and status.
|
* functions for auth, logging and status.
|
||||||
*
|
*
|
||||||
* Note, that the callback structure is not copied into the session so it needs
|
|
||||||
* to be valid for the whole session lifetime.
|
|
||||||
*
|
|
||||||
* @code
|
* @code
|
||||||
* struct ssh_callbacks_struct cb = {
|
* struct ssh_callbacks_struct cb = {
|
||||||
* .userdata = data,
|
* .userdata = data,
|
||||||
@@ -627,7 +619,6 @@ typedef void (*ssh_channel_signal_callback) (ssh_session session,
|
|||||||
* @brief SSH channel exit status callback. Called when a channel has received an exit status
|
* @brief SSH channel exit status callback. Called when a channel has received an exit status
|
||||||
* @param session Current session handler
|
* @param session Current session handler
|
||||||
* @param channel the actual channel
|
* @param channel the actual channel
|
||||||
* @param exit_status Exit status of the ran command
|
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
*/
|
*/
|
||||||
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
|
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
|
||||||
@@ -640,7 +631,7 @@ typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
|
|||||||
* @param session Current session handler
|
* @param session Current session handler
|
||||||
* @param channel the actual channel
|
* @param channel the actual channel
|
||||||
* @param signal the signal name (without the SIG prefix)
|
* @param signal the signal name (without the SIG prefix)
|
||||||
* @param core a boolean telling whether a core has been dumped or not
|
* @param core a boolean telling wether a core has been dumped or not
|
||||||
* @param errmsg the description of the exception
|
* @param errmsg the description of the exception
|
||||||
* @param lang the language of the description (format: RFC 3066)
|
* @param lang the language of the description (format: RFC 3066)
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
@@ -655,13 +646,12 @@ typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SSH channel PTY request from a client.
|
* @brief SSH channel PTY request from a client.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param term The type of terminal emulation
|
* @param term The type of terminal emulation
|
||||||
* @param width width of the terminal, in characters
|
* @param width width of the terminal, in characters
|
||||||
* @param height height of the terminal, in characters
|
* @param height height of the terminal, in characters
|
||||||
* @param pxwidth width of the terminal, in pixels
|
* @param pxwidth width of the terminal, in pixels
|
||||||
* @param pwheight height of the terminal, in pixels
|
* @param pxheight height of the terminal, in pixels
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns 0 if the pty request is accepted
|
* @returns 0 if the pty request is accepted
|
||||||
* @returns -1 if the request is denied
|
* @returns -1 if the request is denied
|
||||||
@@ -675,7 +665,6 @@ typedef int (*ssh_channel_pty_request_callback) (ssh_session session,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SSH channel Shell request from a client.
|
* @brief SSH channel Shell request from a client.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns 0 if the shell request is accepted
|
* @returns 0 if the shell request is accepted
|
||||||
@@ -688,7 +677,6 @@ typedef int (*ssh_channel_shell_request_callback) (ssh_session session,
|
|||||||
* @brief SSH auth-agent-request from the client. This request is
|
* @brief SSH auth-agent-request from the client. This request is
|
||||||
* sent by a client when agent forwarding is available.
|
* sent by a client when agent forwarding is available.
|
||||||
* Server is free to ignore this callback, no answer is expected.
|
* Server is free to ignore this callback, no answer is expected.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
*/
|
*/
|
||||||
@@ -700,12 +688,7 @@ typedef void (*ssh_channel_auth_agent_req_callback) (ssh_session session,
|
|||||||
* @brief SSH X11 request from the client. This request is
|
* @brief SSH X11 request from the client. This request is
|
||||||
* sent by a client when X11 forwarding is requested(and available).
|
* sent by a client when X11 forwarding is requested(and available).
|
||||||
* Server is free to ignore this callback, no answer is expected.
|
* Server is free to ignore this callback, no answer is expected.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param single_connection If true, only one channel should be forwarded
|
|
||||||
* @param auth_protocol The X11 authentication method to be used
|
|
||||||
* @param auth_cookie Authentication cookie encoded hexadecimal
|
|
||||||
* @param screen_number Screen number
|
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
*/
|
*/
|
||||||
typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
|
typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
|
||||||
@@ -717,12 +700,11 @@ typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
|
|||||||
void *userdata);
|
void *userdata);
|
||||||
/**
|
/**
|
||||||
* @brief SSH channel PTY windows change (terminal size) from a client.
|
* @brief SSH channel PTY windows change (terminal size) from a client.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param width width of the terminal, in characters
|
* @param width width of the terminal, in characters
|
||||||
* @param height height of the terminal, in characters
|
* @param height height of the terminal, in characters
|
||||||
* @param pxwidth width of the terminal, in pixels
|
* @param pxwidth width of the terminal, in pixels
|
||||||
* @param pwheight height of the terminal, in pixels
|
* @param pxheight height of the terminal, in pixels
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns 0 if the pty request is accepted
|
* @returns 0 if the pty request is accepted
|
||||||
* @returns -1 if the request is denied
|
* @returns -1 if the request is denied
|
||||||
@@ -735,7 +717,6 @@ typedef int (*ssh_channel_pty_window_change_callback) (ssh_session session,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SSH channel Exec request from a client.
|
* @brief SSH channel Exec request from a client.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param command the shell command to be executed
|
* @param command the shell command to be executed
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
@@ -749,7 +730,6 @@ typedef int (*ssh_channel_exec_request_callback) (ssh_session session,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SSH channel environment request from a client.
|
* @brief SSH channel environment request from a client.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param env_name name of the environment value to be set
|
* @param env_name name of the environment value to be set
|
||||||
* @param env_value value of the environment value to be set
|
* @param env_value value of the environment value to be set
|
||||||
@@ -766,7 +746,6 @@ typedef int (*ssh_channel_env_request_callback) (ssh_session session,
|
|||||||
void *userdata);
|
void *userdata);
|
||||||
/**
|
/**
|
||||||
* @brief SSH channel subsystem request from a client.
|
* @brief SSH channel subsystem request from a client.
|
||||||
* @param session the session
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
* @param subsystem the subsystem required
|
* @param subsystem the subsystem required
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
@@ -781,8 +760,6 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
|
|||||||
/**
|
/**
|
||||||
* @brief SSH channel write will not block (flow control).
|
* @brief SSH channel write will not block (flow control).
|
||||||
*
|
*
|
||||||
* @param session the session
|
|
||||||
*
|
|
||||||
* @param channel the channel
|
* @param channel the channel
|
||||||
*
|
*
|
||||||
* @param[in] bytes size of the remote window in bytes. Writing as much data
|
* @param[in] bytes size of the remote window in bytes. Writing as much data
|
||||||
@@ -794,7 +771,7 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
|
|||||||
*/
|
*/
|
||||||
typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
|
typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
|
||||||
ssh_channel channel,
|
ssh_channel channel,
|
||||||
uint32_t bytes,
|
size_t bytes,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
struct ssh_channel_callbacks_struct {
|
struct ssh_channel_callbacks_struct {
|
||||||
@@ -872,16 +849,12 @@ typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
|
|||||||
* @brief Set the channel callback functions.
|
* @brief Set the channel callback functions.
|
||||||
*
|
*
|
||||||
* This functions sets the callback structure to use your own callback
|
* This functions sets the callback structure to use your own callback
|
||||||
* functions for channel data and exceptions.
|
* functions for channel data and exceptions
|
||||||
*
|
|
||||||
* Note, that the structure is not copied to the channel structure so it needs
|
|
||||||
* to be valid as for the whole life of the channel or until it is removed with
|
|
||||||
* ssh_remove_channel_callbacks().
|
|
||||||
*
|
*
|
||||||
* @code
|
* @code
|
||||||
* struct ssh_channel_callbacks_struct cb = {
|
* struct ssh_channel_callbacks_struct cb = {
|
||||||
* .userdata = data,
|
* .userdata = data,
|
||||||
* .channel_data_function = my_channel_data_function
|
* .channel_data = my_channel_data_function
|
||||||
* };
|
* };
|
||||||
* ssh_callbacks_init(&cb);
|
* ssh_callbacks_init(&cb);
|
||||||
* ssh_set_channel_callbacks(channel, &cb);
|
* ssh_set_channel_callbacks(channel, &cb);
|
||||||
@@ -934,7 +907,7 @@ LIBSSH_API int ssh_remove_channel_callbacks(ssh_channel channel,
|
|||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @addtogroup libssh_threads
|
/** @group libssh_threads
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -971,20 +944,9 @@ LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
|
|||||||
*cb);
|
*cb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a pointer to the appropriate callbacks structure for the
|
* @brief returns a pointer on the pthread threads callbacks, to be used with
|
||||||
* environment, to be used with ssh_threads_set_callbacks.
|
|
||||||
*
|
|
||||||
* @returns A pointer to a ssh_threads_callbacks_struct to be used with
|
|
||||||
* ssh_threads_set_callbacks.
|
* ssh_threads_set_callbacks.
|
||||||
*
|
* @warning you have to link with the library ssh_threads.
|
||||||
* @see ssh_threads_set_callbacks
|
|
||||||
*/
|
|
||||||
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_default(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a pointer on the pthread threads callbacks, to be used with
|
|
||||||
* ssh_threads_set_callbacks.
|
|
||||||
*
|
|
||||||
* @see ssh_threads_set_callbacks
|
* @see ssh_threads_set_callbacks
|
||||||
*/
|
*/
|
||||||
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
|
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
|
||||||
@@ -1006,7 +968,7 @@ LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void);
|
|||||||
*
|
*
|
||||||
* @param[in] cb The callback to set.
|
* @param[in] cb The callback to set.
|
||||||
*
|
*
|
||||||
* @return 0 on success, < 0 on error.
|
* @return 0 on success, < 0 on errror.
|
||||||
*/
|
*/
|
||||||
LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
|
LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,7 @@ struct chacha_ctx {
|
|||||||
#define CHACHA_NONCELEN 8
|
#define CHACHA_NONCELEN 8
|
||||||
#define CHACHA_CTRLEN 8
|
#define CHACHA_CTRLEN 8
|
||||||
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
|
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
|
||||||
|
#define CHACHA_BLOCKLEN 64
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
|
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
|
||||||
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
|
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
|
||||||
@@ -41,8 +38,4 @@ void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m,
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CHACHA_H */
|
#endif /* CHACHA_H */
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Author: Jakub Jelen <jjelen@redhat.com>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* chacha20-poly1305.h file
|
|
||||||
* This file includes definitions needed for Chacha20-poly1305 AEAD cipher
|
|
||||||
* using different crypto backends.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CHACHA20_POLY1305_H
|
|
||||||
#define CHACHA20_POLY1305_H
|
|
||||||
|
|
||||||
#define CHACHA20_BLOCKSIZE 64
|
|
||||||
#define CHACHA20_KEYLEN 32
|
|
||||||
|
|
||||||
#define POLY1305_TAGLEN 16
|
|
||||||
/* size of the keys k1 and k2 as defined in specs */
|
|
||||||
#define POLY1305_KEYLEN 32
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
#endif
|
|
||||||
struct ssh_packet_header {
|
|
||||||
uint32_t length;
|
|
||||||
uint8_t payload[];
|
|
||||||
}
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
__attribute__ ((packed))
|
|
||||||
#endif
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(pop)
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
#endif /* CHACHA20_POLY1305_H */
|
|
||||||
@@ -22,10 +22,6 @@
|
|||||||
#define CHANNELS_H_
|
#define CHANNELS_H_
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
* Describes the different possible states in a
|
* Describes the different possible states in a
|
||||||
* outgoing (client) channel request
|
* outgoing (client) channel request
|
||||||
@@ -39,7 +35,7 @@ enum ssh_channel_request_state_e {
|
|||||||
SSH_CHANNEL_REQ_STATE_ACCEPTED,
|
SSH_CHANNEL_REQ_STATE_ACCEPTED,
|
||||||
/** A request has been replied and refused */
|
/** A request has been replied and refused */
|
||||||
SSH_CHANNEL_REQ_STATE_DENIED,
|
SSH_CHANNEL_REQ_STATE_DENIED,
|
||||||
/** A request has been replied and an error happened */
|
/** A request has been replied and an error happend */
|
||||||
SSH_CHANNEL_REQ_STATE_ERROR
|
SSH_CHANNEL_REQ_STATE_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,16 +48,11 @@ enum ssh_channel_state_e {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* The channel has been closed by the remote side */
|
/* The channel has been closed by the remote side */
|
||||||
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x0001
|
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x1
|
||||||
|
|
||||||
/* The channel has been closed locally */
|
|
||||||
#define SSH_CHANNEL_FLAG_CLOSED_LOCAL 0x0002
|
|
||||||
|
|
||||||
/* The channel has been freed by the calling program */
|
/* 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 */
|
/* 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 {
|
struct ssh_channel_struct {
|
||||||
ssh_session session; /* SSH_SESSION pointer */
|
ssh_session session; /* SSH_SESSION pointer */
|
||||||
@@ -101,20 +92,12 @@ SSH_PACKET_CALLBACK(channel_rcv_close);
|
|||||||
SSH_PACKET_CALLBACK(channel_rcv_request);
|
SSH_PACKET_CALLBACK(channel_rcv_request);
|
||||||
SSH_PACKET_CALLBACK(channel_rcv_data);
|
SSH_PACKET_CALLBACK(channel_rcv_data);
|
||||||
|
|
||||||
int channel_default_bufferize(ssh_channel channel,
|
ssh_channel ssh_channel_new(ssh_session session);
|
||||||
void *data, uint32_t len,
|
int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||||
bool is_stderr);
|
int is_stderr);
|
||||||
int ssh_channel_flush(ssh_channel channel);
|
int ssh_channel_flush(ssh_channel channel);
|
||||||
uint32_t ssh_channel_new_id(ssh_session session);
|
uint32_t ssh_channel_new_id(ssh_session session);
|
||||||
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
||||||
void ssh_channel_do_free(ssh_channel channel);
|
void ssh_channel_do_free(ssh_channel channel);
|
||||||
int ssh_global_request(ssh_session session,
|
|
||||||
const char *request,
|
|
||||||
ssh_buffer buffer,
|
|
||||||
int reply);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CHANNELS_H_ */
|
#endif /* CHANNELS_H_ */
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* config.h - parse the ssh config file
|
|
||||||
*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009-2018 by Andreas Schneider <asn@cryptomilk.org>
|
|
||||||
*
|
|
||||||
* The SSH Library is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* The SSH Library is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with the SSH Library; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
* MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LIBSSH_CONFIG_H_
|
|
||||||
#define LIBSSH_CONFIG_H_
|
|
||||||
|
|
||||||
|
|
||||||
enum ssh_config_opcode_e {
|
|
||||||
/* Unknown opcode */
|
|
||||||
SOC_UNKNOWN = -3,
|
|
||||||
/* Known and not applicable to libssh */
|
|
||||||
SOC_NA = -2,
|
|
||||||
/* Known but not supported by current libssh version */
|
|
||||||
SOC_UNSUPPORTED = -1,
|
|
||||||
SOC_HOST,
|
|
||||||
SOC_MATCH,
|
|
||||||
SOC_HOSTNAME,
|
|
||||||
SOC_PORT,
|
|
||||||
SOC_USERNAME,
|
|
||||||
SOC_IDENTITY,
|
|
||||||
SOC_CIPHERS,
|
|
||||||
SOC_MACS,
|
|
||||||
SOC_COMPRESSION,
|
|
||||||
SOC_TIMEOUT,
|
|
||||||
SOC_STRICTHOSTKEYCHECK,
|
|
||||||
SOC_KNOWNHOSTS,
|
|
||||||
SOC_PROXYCOMMAND,
|
|
||||||
SOC_PROXYJUMP,
|
|
||||||
SOC_GSSAPISERVERIDENTITY,
|
|
||||||
SOC_GSSAPICLIENTIDENTITY,
|
|
||||||
SOC_GSSAPIDELEGATECREDENTIALS,
|
|
||||||
SOC_INCLUDE,
|
|
||||||
SOC_BINDADDRESS,
|
|
||||||
SOC_GLOBALKNOWNHOSTSFILE,
|
|
||||||
SOC_LOGLEVEL,
|
|
||||||
SOC_HOSTKEYALGORITHMS,
|
|
||||||
SOC_KEXALGORITHMS,
|
|
||||||
SOC_GSSAPIAUTHENTICATION,
|
|
||||||
SOC_KBDINTERACTIVEAUTHENTICATION,
|
|
||||||
SOC_PASSWORDAUTHENTICATION,
|
|
||||||
SOC_PUBKEYAUTHENTICATION,
|
|
||||||
SOC_PUBKEYACCEPTEDKEYTYPES,
|
|
||||||
SOC_REKEYLIMIT,
|
|
||||||
SOC_IDENTITYAGENT,
|
|
||||||
|
|
||||||
SOC_MAX /* Keep this one last in the list */
|
|
||||||
};
|
|
||||||
#endif /* LIBSSH_CONFIG_H_ */
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* config_parser.h - Common configuration file parser functions
|
|
||||||
*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 by Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
|
||||||
*
|
|
||||||
* The SSH Library is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* The SSH Library is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with the SSH Library; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
* MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_PARSER_H_
|
|
||||||
#define CONFIG_PARSER_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *ssh_config_get_cmd(char **str);
|
|
||||||
|
|
||||||
char *ssh_config_get_token(char **str);
|
|
||||||
|
|
||||||
long ssh_config_get_long(char **str, long notfound);
|
|
||||||
|
|
||||||
const char *ssh_config_get_str_tok(char **str, const char *def);
|
|
||||||
|
|
||||||
int ssh_config_get_yesno(char **str, int notfound);
|
|
||||||
|
|
||||||
/* @brief Parse SSH URI in format [user@]host[:port] from the given string
|
|
||||||
*
|
|
||||||
* @param[in] tok String to parse
|
|
||||||
* @param[out] username Pointer to the location, where the new username will
|
|
||||||
* be stored or NULL if we do not care about the result.
|
|
||||||
* @param[out] hostname Pointer to the location, where the new hostname will
|
|
||||||
* be stored or NULL if we do not care about the result.
|
|
||||||
* @param[out] port Pointer to the location, where the new port will
|
|
||||||
* be stored or NULL if we do not care about the result.
|
|
||||||
*
|
|
||||||
* @returns SSH_OK if the provided string is in format of SSH URI,
|
|
||||||
* SSH_ERROR on failure
|
|
||||||
*/
|
|
||||||
int ssh_config_parse_uri(const char *tok,
|
|
||||||
char **username,
|
|
||||||
char **hostname,
|
|
||||||
char **port);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* LIBSSH_CONFIG_H_ */
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
|
* crc32.c - simple CRC32 code
|
||||||
|
*
|
||||||
* This file is part of the SSH Library
|
* This file is part of the SSH Library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 by Anderson Toshiyuki Sasaki - Red Hat, Inc.
|
* Copyright (c) 2005 by Aris Adamantiadis
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -18,19 +20,9 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#ifndef _CRC32_H
|
||||||
#include "libssh/crypto.h"
|
#define _CRC32_H
|
||||||
|
|
||||||
int secure_memcmp(const void *s1, const void *s2, size_t n)
|
uint32_t ssh_crc32(const char *buf, uint32_t len);
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
uint8_t status = 0;
|
|
||||||
const uint8_t *p1 = s1;
|
|
||||||
const uint8_t *p2 = s2;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
#endif /* _CRC32_H */
|
||||||
status |= (p1[i] ^ p2[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (status != 0);
|
|
||||||
}
|
|
||||||
@@ -25,13 +25,10 @@
|
|||||||
#ifndef _CRYPTO_H_
|
#ifndef _CRYPTO_H_
|
||||||
#define _CRYPTO_H_
|
#define _CRYPTO_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
|
||||||
#include <mbedtls/gcm.h>
|
|
||||||
#endif
|
#endif
|
||||||
#include "libssh/wrapper.h"
|
#include "libssh/wrapper.h"
|
||||||
|
|
||||||
@@ -45,27 +42,17 @@
|
|||||||
#ifdef HAVE_OPENSSL_ECDH_H
|
#ifdef HAVE_OPENSSL_ECDH_H
|
||||||
#include <openssl/ecdh.h>
|
#include <openssl/ecdh.h>
|
||||||
#endif
|
#endif
|
||||||
#include "libssh/dh.h"
|
|
||||||
#include "libssh/ecdh.h"
|
#include "libssh/ecdh.h"
|
||||||
#include "libssh/kex.h"
|
#include "libssh/kex.h"
|
||||||
#include "libssh/curve25519.h"
|
#include "libssh/curve25519.h"
|
||||||
|
|
||||||
#define DIGEST_MAX_LEN 64
|
#define DIGEST_MAX_LEN 64
|
||||||
|
|
||||||
#define AES_GCM_TAGLEN 16
|
|
||||||
#define AES_GCM_IVLEN 12
|
|
||||||
|
|
||||||
enum ssh_key_exchange_e {
|
enum ssh_key_exchange_e {
|
||||||
/* diffie-hellman-group1-sha1 */
|
/* diffie-hellman-group1-sha1 */
|
||||||
SSH_KEX_DH_GROUP1_SHA1=1,
|
SSH_KEX_DH_GROUP1_SHA1=1,
|
||||||
/* diffie-hellman-group14-sha1 */
|
/* diffie-hellman-group14-sha1 */
|
||||||
SSH_KEX_DH_GROUP14_SHA1,
|
SSH_KEX_DH_GROUP14_SHA1,
|
||||||
#ifdef WITH_GEX
|
|
||||||
/* diffie-hellman-group-exchange-sha1 */
|
|
||||||
SSH_KEX_DH_GEX_SHA1,
|
|
||||||
/* diffie-hellman-group-exchange-sha256 */
|
|
||||||
SSH_KEX_DH_GEX_SHA256,
|
|
||||||
#endif /* WITH_GEX */
|
|
||||||
/* ecdh-sha2-nistp256 */
|
/* ecdh-sha2-nistp256 */
|
||||||
SSH_KEX_ECDH_SHA2_NISTP256,
|
SSH_KEX_ECDH_SHA2_NISTP256,
|
||||||
/* ecdh-sha2-nistp384 */
|
/* ecdh-sha2-nistp384 */
|
||||||
@@ -80,46 +67,25 @@ enum ssh_key_exchange_e {
|
|||||||
SSH_KEX_DH_GROUP16_SHA512,
|
SSH_KEX_DH_GROUP16_SHA512,
|
||||||
/* diffie-hellman-group18-sha512 */
|
/* diffie-hellman-group18-sha512 */
|
||||||
SSH_KEX_DH_GROUP18_SHA512,
|
SSH_KEX_DH_GROUP18_SHA512,
|
||||||
/* diffie-hellman-group14-sha256 */
|
|
||||||
SSH_KEX_DH_GROUP14_SHA256,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ssh_cipher_e {
|
enum ssh_cipher_e {
|
||||||
SSH_NO_CIPHER=0,
|
SSH_NO_CIPHER=0,
|
||||||
#ifdef WITH_BLOWFISH_CIPHER
|
|
||||||
SSH_BLOWFISH_CBC,
|
SSH_BLOWFISH_CBC,
|
||||||
#endif /* WITH_BLOWFISH_CIPHER */
|
|
||||||
SSH_3DES_CBC,
|
SSH_3DES_CBC,
|
||||||
SSH_AES128_CBC,
|
SSH_AES128_CBC,
|
||||||
SSH_AES192_CBC,
|
SSH_AES192_CBC,
|
||||||
SSH_AES256_CBC,
|
SSH_AES256_CBC,
|
||||||
SSH_AES128_CTR,
|
SSH_AES128_CTR,
|
||||||
SSH_AES192_CTR,
|
SSH_AES192_CTR,
|
||||||
SSH_AES256_CTR,
|
SSH_AES256_CTR
|
||||||
SSH_AEAD_AES128_GCM,
|
|
||||||
SSH_AEAD_AES256_GCM,
|
|
||||||
SSH_AEAD_CHACHA20_POLY1305
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dh_ctx;
|
|
||||||
|
|
||||||
struct ssh_crypto_struct {
|
struct ssh_crypto_struct {
|
||||||
bignum shared_secret;
|
bignum e,f,x,k,y;
|
||||||
struct dh_ctx *dh_ctx;
|
|
||||||
#ifdef WITH_GEX
|
|
||||||
size_t dh_pmin; size_t dh_pn; size_t dh_pmax; /* preferred group parameters */
|
|
||||||
#endif /* WITH_GEX */
|
|
||||||
#ifdef HAVE_ECDH
|
#ifdef HAVE_ECDH
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
|
||||||
* #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
*/
|
|
||||||
#if 1
|
|
||||||
EC_KEY *ecdh_privkey;
|
EC_KEY *ecdh_privkey;
|
||||||
#else
|
|
||||||
EVP_PKEY *ecdh_privkey;
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
#elif defined HAVE_GCRYPT_ECC
|
#elif defined HAVE_GCRYPT_ECC
|
||||||
gcry_sexp_t ecdh_privkey;
|
gcry_sexp_t ecdh_privkey;
|
||||||
#elif defined HAVE_LIBMBEDCRYPTO
|
#elif defined HAVE_LIBMBEDCRYPTO
|
||||||
@@ -134,9 +100,8 @@ struct ssh_crypto_struct {
|
|||||||
ssh_curve25519_pubkey curve25519_server_pubkey;
|
ssh_curve25519_pubkey curve25519_server_pubkey;
|
||||||
#endif
|
#endif
|
||||||
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
||||||
size_t session_id_len;
|
size_t digest_len; /* len of all the fields below */
|
||||||
unsigned char *session_id;
|
unsigned char *session_id;
|
||||||
size_t digest_len; /* len of the secret hash */
|
|
||||||
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
|
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
|
||||||
unsigned char *encryptIV;
|
unsigned char *encryptIV;
|
||||||
unsigned char *decryptIV;
|
unsigned char *decryptIV;
|
||||||
@@ -147,7 +112,6 @@ struct ssh_crypto_struct {
|
|||||||
unsigned char hmacbuf[DIGEST_MAX_LEN];
|
unsigned char hmacbuf[DIGEST_MAX_LEN];
|
||||||
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
||||||
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */
|
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */
|
||||||
bool in_hmac_etm, out_hmac_etm; /* Whether EtM mode is used or not */
|
|
||||||
|
|
||||||
ssh_key server_pubkey;
|
ssh_key server_pubkey;
|
||||||
int do_compress_out; /* idem */
|
int do_compress_out; /* idem */
|
||||||
@@ -161,8 +125,7 @@ struct ssh_crypto_struct {
|
|||||||
struct ssh_kex_struct client_kex;
|
struct ssh_kex_struct client_kex;
|
||||||
char *kex_methods[SSH_KEX_METHODS];
|
char *kex_methods[SSH_KEX_METHODS];
|
||||||
enum ssh_key_exchange_e kex_type;
|
enum ssh_key_exchange_e kex_type;
|
||||||
enum ssh_kdf_digest digest_type; /* Digest type for session keys derivation */
|
enum ssh_mac_e mac_type; /* Mac operations to use for key gen */
|
||||||
enum ssh_crypto_direction_e used; /* Is this crypto still used for either of directions? */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_cipher_struct {
|
struct ssh_cipher_struct {
|
||||||
@@ -173,7 +136,6 @@ struct ssh_cipher_struct {
|
|||||||
size_t keylen; /* length of the key structure */
|
size_t keylen; /* length of the key structure */
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_cipher_hd_t *key;
|
gcry_cipher_hd_t *key;
|
||||||
unsigned char last_iv[AES_GCM_IVLEN];
|
|
||||||
#elif defined HAVE_LIBCRYPTO
|
#elif defined HAVE_LIBCRYPTO
|
||||||
struct ssh_3des_key_schedule *des3_key;
|
struct ssh_3des_key_schedule *des3_key;
|
||||||
struct ssh_aes_key_schedule *aes_key;
|
struct ssh_aes_key_schedule *aes_key;
|
||||||
@@ -183,30 +145,17 @@ struct ssh_cipher_struct {
|
|||||||
mbedtls_cipher_context_t encrypt_ctx;
|
mbedtls_cipher_context_t encrypt_ctx;
|
||||||
mbedtls_cipher_context_t decrypt_ctx;
|
mbedtls_cipher_context_t decrypt_ctx;
|
||||||
mbedtls_cipher_type_t type;
|
mbedtls_cipher_type_t type;
|
||||||
#ifdef MBEDTLS_GCM_C
|
|
||||||
mbedtls_gcm_context gcm_ctx;
|
|
||||||
unsigned char last_iv[AES_GCM_IVLEN];
|
|
||||||
#endif /* MBEDTLS_GCM_C */
|
|
||||||
#endif
|
#endif
|
||||||
struct chacha20_poly1305_keysched *chacha20_schedule;
|
struct chacha20_poly1305_keysched *chacha20_schedule;
|
||||||
unsigned int keysize; /* bytes of key used. != keylen */
|
unsigned int keysize; /* bytes of key used. != keylen */
|
||||||
size_t tag_size; /* overhead required for tag */
|
size_t tag_size; /* overhead required for tag */
|
||||||
/* Counters for rekeying initialization */
|
|
||||||
uint32_t packets;
|
|
||||||
uint64_t blocks;
|
|
||||||
/* Rekeying limit for the cipher or manually enforced */
|
|
||||||
uint64_t max_blocks;
|
|
||||||
/* sets the new key for immediate use */
|
/* sets the new key for immediate use */
|
||||||
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||||
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||||
void (*encrypt)(struct ssh_cipher_struct *cipher,
|
void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||||
void *in,
|
unsigned long len);
|
||||||
void *out,
|
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||||
size_t len);
|
unsigned long len);
|
||||||
void (*decrypt)(struct ssh_cipher_struct *cipher,
|
|
||||||
void *in,
|
|
||||||
void *out,
|
|
||||||
size_t len);
|
|
||||||
void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||||
size_t len, uint8_t *mac, uint64_t seq);
|
size_t len, uint8_t *mac, uint64_t seq);
|
||||||
int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,
|
int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,
|
||||||
@@ -216,23 +165,6 @@ struct ssh_cipher_struct {
|
|||||||
void (*cleanup)(struct ssh_cipher_struct *cipher);
|
void (*cleanup)(struct ssh_cipher_struct *cipher);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void);
|
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void);
|
||||||
int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
|
|
||||||
unsigned char *key, size_t key_len,
|
|
||||||
uint8_t key_type, unsigned char *output,
|
|
||||||
size_t requested_len);
|
|
||||||
|
|
||||||
int secure_memcmp(const void *s1, const void *s2, size_t n);
|
|
||||||
#ifdef HAVE_LIBCRYPTO
|
|
||||||
ENGINE *pki_get_engine(void);
|
|
||||||
#endif /* HAVE_LIBCRYPTO */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _CRYPTO_H_ */
|
#endif /* _CRYPTO_H_ */
|
||||||
|
|||||||
@@ -33,10 +33,6 @@
|
|||||||
#define crypto_scalarmult crypto_scalarmult_curve25519
|
#define crypto_scalarmult crypto_scalarmult_curve25519
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CURVE25519_PUBKEY_SIZE 32
|
#define CURVE25519_PUBKEY_SIZE 32
|
||||||
#define CURVE25519_PRIVKEY_SIZE 32
|
#define CURVE25519_PRIVKEY_SIZE 32
|
||||||
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
|
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
|
||||||
@@ -52,14 +48,10 @@ typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
|
|||||||
|
|
||||||
|
|
||||||
int ssh_client_curve25519_init(ssh_session session);
|
int ssh_client_curve25519_init(ssh_session session);
|
||||||
void ssh_client_curve25519_remove_callbacks(ssh_session session);
|
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet);
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
void ssh_server_curve25519_init(ssh_session session);
|
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet);
|
||||||
#endif /* WITH_SERVER */
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CURVE25519_H_ */
|
#endif /* CURVE25519_H_ */
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.be>
|
|
||||||
*
|
|
||||||
* The SSH Library is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* The SSH Library is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with the SSH Library; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
* MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SRC_DH_GEX_H_
|
|
||||||
#define SRC_DH_GEX_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ssh_client_dhgex_init(ssh_session session);
|
|
||||||
void ssh_client_dhgex_remove_callbacks(ssh_session session);
|
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
|
||||||
void ssh_server_dhgex_init(ssh_session session);
|
|
||||||
#endif /* WITH_SERVER */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* SRC_DH_GEX_H_ */
|
|
||||||
@@ -25,51 +25,25 @@
|
|||||||
|
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
|
|
||||||
struct dh_ctx;
|
int ssh_dh_generate_e(ssh_session session);
|
||||||
|
int ssh_dh_generate_f(ssh_session session);
|
||||||
|
int ssh_dh_generate_x(ssh_session session);
|
||||||
|
int ssh_dh_generate_y(ssh_session session);
|
||||||
|
|
||||||
#define DH_CLIENT_KEYPAIR 0
|
|
||||||
#define DH_SERVER_KEYPAIR 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* functions implemented by crypto backends */
|
|
||||||
int ssh_dh_init_common(struct ssh_crypto_struct *crypto);
|
|
||||||
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto);
|
|
||||||
|
|
||||||
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
int ssh_dh_get_parameters(struct dh_ctx *ctx,
|
|
||||||
const_bignum *modulus, const_bignum *generator);
|
|
||||||
#else
|
|
||||||
int ssh_dh_get_parameters(struct dh_ctx *ctx,
|
|
||||||
bignum *modulus, bignum *generator);
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
int ssh_dh_set_parameters(struct dh_ctx *ctx,
|
|
||||||
const bignum modulus, const bignum generator);
|
|
||||||
|
|
||||||
int ssh_dh_keypair_gen_keys(struct dh_ctx *ctx, int peer);
|
|
||||||
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
|
|
||||||
const_bignum *priv, const_bignum *pub);
|
|
||||||
#else
|
|
||||||
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
|
|
||||||
bignum *priv, bignum *pub);
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
|
|
||||||
bignum priv, bignum pub);
|
|
||||||
|
|
||||||
int ssh_dh_compute_shared_secret(struct dh_ctx *ctx, int local, int remote,
|
|
||||||
bignum *dest);
|
|
||||||
|
|
||||||
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c);
|
|
||||||
|
|
||||||
/* common functions */
|
|
||||||
int ssh_dh_init(void);
|
int ssh_dh_init(void);
|
||||||
void ssh_dh_finalize(void);
|
void ssh_dh_finalize(void);
|
||||||
|
|
||||||
int ssh_dh_import_next_pubkey_blob(ssh_session session,
|
ssh_string ssh_dh_get_e(ssh_session session);
|
||||||
ssh_string pubkey_blob);
|
ssh_string ssh_dh_get_f(ssh_session session);
|
||||||
|
int ssh_dh_import_f(ssh_session session,ssh_string f_string);
|
||||||
|
int ssh_dh_import_e(ssh_session session, ssh_string e_string);
|
||||||
|
|
||||||
|
int ssh_dh_import_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
|
||||||
|
int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
|
||||||
|
|
||||||
|
int ssh_dh_build_k(ssh_session session);
|
||||||
|
int ssh_client_dh_init(ssh_session session);
|
||||||
|
int ssh_client_dh_reply(ssh_session session, ssh_buffer packet);
|
||||||
|
|
||||||
ssh_key ssh_dh_get_current_server_publickey(ssh_session session);
|
ssh_key ssh_dh_get_current_server_publickey(ssh_session session);
|
||||||
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
|
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
|
||||||
@@ -77,19 +51,11 @@ int ssh_dh_get_current_server_publickey_blob(ssh_session session,
|
|||||||
ssh_key ssh_dh_get_next_server_publickey(ssh_session session);
|
ssh_key ssh_dh_get_next_server_publickey(ssh_session session);
|
||||||
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
|
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
|
||||||
ssh_string *pubkey_blob);
|
ssh_string *pubkey_blob);
|
||||||
int dh_handshake(ssh_session session);
|
|
||||||
|
|
||||||
int ssh_client_dh_init(ssh_session session);
|
int ssh_make_sessionid(ssh_session session);
|
||||||
void ssh_client_dh_remove_callbacks(ssh_session session);
|
/* add data for the final cookie */
|
||||||
#ifdef WITH_SERVER
|
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||||
void ssh_server_dh_init(ssh_session session);
|
int ssh_hashbufout_add_cookie(ssh_session session);
|
||||||
#endif /* WITH_SERVER */
|
int ssh_generate_session_keys(ssh_session session);
|
||||||
int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet);
|
|
||||||
int ssh_fallback_group(uint32_t pmax, bignum *p, bignum *g);
|
|
||||||
bool ssh_dh_is_known_group(bignum modulus, bignum generator);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* DH_H_ */
|
#endif /* DH_H_ */
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#define ECDH_H_
|
#define ECDH_H_
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "libssh/callbacks.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBCRYPTO
|
#ifdef HAVE_LIBCRYPTO
|
||||||
#ifdef HAVE_OPENSSL_ECDH_H
|
#ifdef HAVE_OPENSSL_ECDH_H
|
||||||
@@ -42,24 +41,15 @@
|
|||||||
#define HAVE_ECDH 1
|
#define HAVE_ECDH 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* Common functions. */
|
||||||
extern "C" {
|
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks;
|
|
||||||
/* Backend-specific functions. */
|
/* Backend-specific functions. */
|
||||||
int ssh_client_ecdh_init(ssh_session session);
|
int ssh_client_ecdh_init(ssh_session session);
|
||||||
void ssh_client_ecdh_remove_callbacks(ssh_session session);
|
|
||||||
int ecdh_build_k(ssh_session session);
|
int ecdh_build_k(ssh_session session);
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
extern struct ssh_packet_callbacks_struct ssh_ecdh_server_callbacks;
|
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet);
|
||||||
void ssh_server_ecdh_init(ssh_session session);
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init);
|
|
||||||
#endif /* WITH_SERVER */
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ECDH_H_ */
|
#endif /* ECDH_H_ */
|
||||||
|
|||||||
@@ -24,10 +24,10 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup ed25519 ed25519 API
|
* @defgroup ed25519 ed25519 API
|
||||||
|
* @internal
|
||||||
* @brief API for DJB's ed25519
|
* @brief API for DJB's ed25519
|
||||||
*
|
*
|
||||||
* @{
|
* @{ */
|
||||||
*/
|
|
||||||
|
|
||||||
#define ED25519_PK_LEN 32
|
#define ED25519_PK_LEN 32
|
||||||
#define ED25519_SK_LEN 64
|
#define ED25519_SK_LEN 64
|
||||||
@@ -37,10 +37,6 @@ typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
|
|||||||
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
|
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
|
||||||
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
|
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
* @brief generate an ed25519 key pair
|
* @brief generate an ed25519 key pair
|
||||||
* @param[out] pk generated public key
|
* @param[out] pk generated public key
|
||||||
@@ -60,8 +56,8 @@ int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
|
|||||||
* @return 0 on success.
|
* @return 0 on success.
|
||||||
*/
|
*/
|
||||||
int crypto_sign_ed25519(
|
int crypto_sign_ed25519(
|
||||||
unsigned char *sm, uint64_t *smlen,
|
unsigned char *sm,unsigned long long *smlen,
|
||||||
const unsigned char *m, uint64_t mlen,
|
const unsigned char *m,unsigned long long mlen,
|
||||||
const ed25519_privkey sk);
|
const ed25519_privkey sk);
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
@@ -75,13 +71,9 @@ int crypto_sign_ed25519(
|
|||||||
* @returns 0 on success (supposedly).
|
* @returns 0 on success (supposedly).
|
||||||
*/
|
*/
|
||||||
int crypto_sign_ed25519_open(
|
int crypto_sign_ed25519_open(
|
||||||
unsigned char *m, uint64_t *mlen,
|
unsigned char *m,unsigned long long *mlen,
|
||||||
const unsigned char *sm, uint64_t smlen,
|
const unsigned char *sm,unsigned long long smlen,
|
||||||
const ed25519_pubkey pk);
|
const ed25519_pubkey pk);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ED25519_H_ */
|
#endif /* ED25519_H_ */
|
||||||
|
|||||||
@@ -33,17 +33,13 @@ typedef struct {
|
|||||||
uint32_t v[32];
|
uint32_t v[32];
|
||||||
} fe25519;
|
} fe25519;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void fe25519_freeze(fe25519 *r);
|
void fe25519_freeze(fe25519 *r);
|
||||||
|
|
||||||
void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
|
void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
|
||||||
|
|
||||||
void fe25519_pack(unsigned char r[32], const fe25519 *x);
|
void fe25519_pack(unsigned char r[32], const fe25519 *x);
|
||||||
|
|
||||||
uint32_t fe25519_iszero(const fe25519 *x);
|
int fe25519_iszero(const fe25519 *x);
|
||||||
|
|
||||||
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
|
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
|
||||||
|
|
||||||
@@ -69,8 +65,4 @@ void fe25519_invert(fe25519 *r, const fe25519 *x);
|
|||||||
|
|
||||||
void fe25519_pow2523(fe25519 *r, const fe25519 *x);
|
void fe25519_pow2523(fe25519 *r, const fe25519 *x);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,10 +28,6 @@ typedef struct
|
|||||||
fe25519 t;
|
fe25519 t;
|
||||||
} ge25519;
|
} ge25519;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const ge25519 ge25519_base;
|
extern const ge25519 ge25519_base;
|
||||||
|
|
||||||
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
|
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
|
||||||
@@ -44,8 +40,4 @@ void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25
|
|||||||
|
|
||||||
void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
|
void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,10 +29,6 @@
|
|||||||
|
|
||||||
typedef struct ssh_gssapi_struct *ssh_gssapi;
|
typedef struct ssh_gssapi_struct *ssh_gssapi;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids);
|
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server);
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server);
|
||||||
@@ -46,8 +42,4 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response);
|
|||||||
|
|
||||||
int ssh_gssapi_auth_mic(ssh_session session);
|
int ssh_gssapi_auth_mic(ssh_session session);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GSSAPI_H */
|
#endif /* GSSAPI_H */
|
||||||
|
|||||||
@@ -31,38 +31,19 @@ struct ssh_kex_struct {
|
|||||||
char *methods[SSH_KEX_METHODS];
|
char *methods[SSH_KEX_METHODS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
|
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
|
||||||
|
|
||||||
int ssh_send_kex(ssh_session session);
|
int ssh_send_kex(ssh_session session, int server_kex);
|
||||||
void ssh_list_kex(struct ssh_kex_struct *kex);
|
void ssh_list_kex(struct ssh_kex_struct *kex);
|
||||||
int ssh_set_client_kex(ssh_session session);
|
int ssh_set_client_kex(ssh_session session);
|
||||||
int ssh_kex_append_extensions(ssh_session session, struct ssh_kex_struct *pkex);
|
|
||||||
int ssh_kex_select_methods(ssh_session session);
|
int ssh_kex_select_methods(ssh_session session);
|
||||||
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
|
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
|
||||||
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
|
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
|
||||||
char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list);
|
|
||||||
char **ssh_space_tokenize(const char *chain);
|
char **ssh_space_tokenize(const char *chain);
|
||||||
int ssh_get_kex1(ssh_session session);
|
int ssh_get_kex1(ssh_session session);
|
||||||
char *ssh_find_matching(const char *in_d, const char *what_d);
|
char *ssh_find_matching(const char *in_d, const char *what_d);
|
||||||
const char *ssh_kex_get_supported_method(uint32_t algo);
|
const char *ssh_kex_get_supported_method(uint32_t algo);
|
||||||
const char *ssh_kex_get_default_methods(uint32_t algo);
|
const char *ssh_kex_get_default_methods(uint32_t algo);
|
||||||
const char *ssh_kex_get_fips_methods(uint32_t algo);
|
|
||||||
const char *ssh_kex_get_description(uint32_t algo);
|
const char *ssh_kex_get_description(uint32_t algo);
|
||||||
char *ssh_client_select_hostkeys(ssh_session session);
|
|
||||||
int ssh_send_rekex(ssh_session session);
|
|
||||||
int server_set_kex(ssh_session session);
|
|
||||||
int ssh_make_sessionid(ssh_session session);
|
|
||||||
/* add data for the final cookie */
|
|
||||||
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
|
||||||
int ssh_hashbufout_add_cookie(ssh_session session);
|
|
||||||
int ssh_generate_session_keys(ssh_session session);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* KEX_H_ */
|
#endif /* KEX_H_ */
|
||||||
|
|||||||
@@ -28,17 +28,13 @@
|
|||||||
struct ssh_public_key_struct {
|
struct ssh_public_key_struct {
|
||||||
int type;
|
int type;
|
||||||
const char *type_c; /* Don't free it ! it is static */
|
const char *type_c; /* Don't free it ! it is static */
|
||||||
#if defined(HAVE_LIBGCRYPT)
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_sexp_t dsa_pub;
|
gcry_sexp_t dsa_pub;
|
||||||
gcry_sexp_t rsa_pub;
|
gcry_sexp_t rsa_pub;
|
||||||
#elif defined(HAVE_LIBCRYPTO)
|
#elif HAVE_LIBCRYPTO
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
DSA *dsa_pub;
|
DSA *dsa_pub;
|
||||||
RSA *rsa_pub;
|
RSA *rsa_pub;
|
||||||
#else /* OPENSSL_VERSION_NUMBER */
|
#elif HAVE_LIBMBEDCRYPTO
|
||||||
EVP_PKEY *key_pub;
|
|
||||||
#endif
|
|
||||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
|
||||||
mbedtls_pk_context *rsa_pub;
|
mbedtls_pk_context *rsa_pub;
|
||||||
void *dsa_pub;
|
void *dsa_pub;
|
||||||
#endif
|
#endif
|
||||||
@@ -46,33 +42,21 @@ struct ssh_public_key_struct {
|
|||||||
|
|
||||||
struct ssh_private_key_struct {
|
struct ssh_private_key_struct {
|
||||||
int type;
|
int type;
|
||||||
#if defined(HAVE_LIBGCRYPT)
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_sexp_t dsa_priv;
|
gcry_sexp_t dsa_priv;
|
||||||
gcry_sexp_t rsa_priv;
|
gcry_sexp_t rsa_priv;
|
||||||
#elif defined(HAVE_LIBCRYPTO)
|
#elif defined HAVE_LIBCRYPTO
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
DSA *dsa_priv;
|
DSA *dsa_priv;
|
||||||
RSA *rsa_priv;
|
RSA *rsa_priv;
|
||||||
#else
|
#elif HAVE_LIBMBEDCRYPTO
|
||||||
EVP_PKEY *key_priv;
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
|
||||||
mbedtls_pk_context *rsa_priv;
|
mbedtls_pk_context *rsa_priv;
|
||||||
void *dsa_priv;
|
void *dsa_priv;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *ssh_type_to_char(int type);
|
const char *ssh_type_to_char(int type);
|
||||||
int ssh_type_from_name(const char *name);
|
int ssh_type_from_name(const char *name);
|
||||||
|
|
||||||
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s);
|
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* KEYS_H_ */
|
#endif /* KEYS_H_ */
|
||||||
|
|||||||
@@ -22,19 +22,6 @@
|
|||||||
#ifndef SSH_KNOWNHOSTS_H_
|
#ifndef SSH_KNOWNHOSTS_H_
|
||||||
#define SSH_KNOWNHOSTS_H_
|
#define SSH_KNOWNHOSTS_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
|
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
|
||||||
char *ssh_known_hosts_get_algorithms_names(ssh_session session);
|
|
||||||
enum ssh_known_hosts_e
|
|
||||||
ssh_session_get_known_hosts_entry_file(ssh_session session,
|
|
||||||
const char *filename,
|
|
||||||
struct ssh_knownhosts_entry **pentry);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* SSH_KNOWNHOSTS_H_ */
|
#endif /* SSH_KNOWNHOSTS_H_ */
|
||||||
|
|||||||
@@ -31,10 +31,6 @@
|
|||||||
typedef struct ssh_private_key_struct* ssh_private_key;
|
typedef struct ssh_private_key_struct* ssh_private_key;
|
||||||
typedef struct ssh_public_key_struct* ssh_public_key;
|
typedef struct ssh_public_key_struct* ssh_public_key;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LIBSSH_API int ssh_auth_list(ssh_session session);
|
LIBSSH_API int ssh_auth_list(ssh_session session);
|
||||||
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
|
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
|
||||||
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
|
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
|
||||||
@@ -92,19 +88,19 @@ SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel
|
|||||||
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
|
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
|
||||||
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
|
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||||
|
|
||||||
SSH_DEPRECATED LIBSSH_API void privatekey_free(ssh_private_key prv);
|
LIBSSH_API void privatekey_free(ssh_private_key prv);
|
||||||
SSH_DEPRECATED LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
|
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
|
||||||
int type, const char *passphrase);
|
int type, const char *passphrase);
|
||||||
SSH_DEPRECATED LIBSSH_API void publickey_free(ssh_public_key key);
|
LIBSSH_API void publickey_free(ssh_public_key key);
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
|
LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
|
||||||
ssh_string pubkey, int type);
|
ssh_string pubkey, int type);
|
||||||
SSH_DEPRECATED LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
|
LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
|
||||||
int *type);
|
int *type);
|
||||||
SSH_DEPRECATED LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
|
LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
|
||||||
SSH_DEPRECATED LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
|
LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
|
LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
|
||||||
ssh_string *publickey, int *type);
|
ssh_string *publickey, int *type);
|
||||||
SSH_DEPRECATED LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
|
LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
|
||||||
|
|
||||||
LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
|
LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
|
||||||
|
|
||||||
@@ -121,8 +117,4 @@ SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str);
|
|||||||
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
|
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
|
||||||
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
|
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* LEGACY_H_ */
|
#endif /* LEGACY_H_ */
|
||||||
|
|||||||
@@ -31,14 +31,18 @@
|
|||||||
#include <openssl/md5.h>
|
#include <openssl/md5.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/crypto.h>
|
|
||||||
|
|
||||||
typedef EVP_MD_CTX* SHACTX;
|
typedef EVP_MD_CTX* SHACTX;
|
||||||
typedef EVP_MD_CTX* SHA256CTX;
|
typedef EVP_MD_CTX* SHA256CTX;
|
||||||
typedef EVP_MD_CTX* SHA384CTX;
|
typedef EVP_MD_CTX* SHA384CTX;
|
||||||
typedef EVP_MD_CTX* SHA512CTX;
|
typedef EVP_MD_CTX* SHA512CTX;
|
||||||
typedef EVP_MD_CTX* MD5CTX;
|
typedef EVP_MD_CTX* MD5CTX;
|
||||||
typedef EVP_MD_CTX* HMACCTX;
|
typedef HMAC_CTX* HMACCTX;
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
typedef EVP_MD_CTX *EVPCTX;
|
||||||
|
#else
|
||||||
|
typedef void *EVPCTX;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||||
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
|
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
|
||||||
@@ -55,8 +59,11 @@ typedef EVP_MD_CTX* HMACCTX;
|
|||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
|
#define OPENSSL_0_9_7b 0x0090702fL
|
||||||
|
#if (OPENSSL_VERSION_NUMBER <= OPENSSL_0_9_7b)
|
||||||
|
#define BROKEN_AES_CTR
|
||||||
|
#endif
|
||||||
typedef BIGNUM* bignum;
|
typedef BIGNUM* bignum;
|
||||||
typedef const BIGNUM* const_bignum;
|
|
||||||
typedef BN_CTX* bignum_CTX;
|
typedef BN_CTX* bignum_CTX;
|
||||||
|
|
||||||
#define bignum_new() BN_new()
|
#define bignum_new() BN_new()
|
||||||
@@ -67,49 +74,19 @@ typedef BN_CTX* bignum_CTX;
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
#define bignum_set_word(bn,n) BN_set_word(bn,n)
|
#define bignum_set_word(bn,n) BN_set_word(bn,n)
|
||||||
#define bignum_bin2bn(data, datalen, dest) \
|
#define bignum_bin2bn(bn,datalen,data) BN_bin2bn(bn,datalen,data)
|
||||||
do { \
|
|
||||||
(*dest) = BN_new(); \
|
|
||||||
if ((*dest) != NULL) { \
|
|
||||||
BN_bin2bn(data,datalen,(*dest)); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
#define bignum_bn2dec(num) BN_bn2dec(num)
|
#define bignum_bn2dec(num) BN_bn2dec(num)
|
||||||
#define bignum_dec2bn(data, bn) BN_dec2bn(bn, data)
|
#define bignum_dec2bn(bn,data) BN_dec2bn(data,bn)
|
||||||
#define bignum_hex2bn(data, bn) BN_hex2bn(bn, data)
|
#define bignum_bn2hex(num) BN_bn2hex(num)
|
||||||
#define bignum_bn2hex(num, dest) (*dest)=(unsigned char *)BN_bn2hex(num)
|
|
||||||
#define bignum_rand(rnd, bits) BN_rand(rnd, bits, 0, 1)
|
#define bignum_rand(rnd, bits) BN_rand(rnd, bits, 0, 1)
|
||||||
#define bignum_rand_range(rnd, max) BN_rand_range(rnd, max)
|
|
||||||
#define bignum_ctx_new() BN_CTX_new()
|
#define bignum_ctx_new() BN_CTX_new()
|
||||||
#define bignum_ctx_free(num) BN_CTX_free(num)
|
#define bignum_ctx_free(num) BN_CTX_free(num)
|
||||||
#define bignum_ctx_invalid(ctx) ((ctx) == NULL)
|
|
||||||
#define bignum_mod_exp(dest,generator,exp,modulo,ctx) BN_mod_exp(dest,generator,exp,modulo,ctx)
|
#define bignum_mod_exp(dest,generator,exp,modulo,ctx) BN_mod_exp(dest,generator,exp,modulo,ctx)
|
||||||
#define bignum_add(dest, a, b) BN_add(dest, a, b)
|
#define bignum_num_bytes(num) BN_num_bytes(num)
|
||||||
#define bignum_sub(dest, a, b) BN_sub(dest, a, b)
|
#define bignum_num_bits(num) BN_num_bits(num)
|
||||||
#define bignum_mod(dest, a, b, ctx) BN_mod(dest, a, b, ctx)
|
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num,bit)
|
||||||
#define bignum_num_bytes(num) (size_t)BN_num_bytes(num)
|
#define bignum_bn2bin(num,ptr) BN_bn2bin(num,ptr)
|
||||||
#define bignum_num_bits(num) (size_t)BN_num_bits(num)
|
|
||||||
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num, (int)bit)
|
|
||||||
#define bignum_bn2bin(num,len, ptr) BN_bn2bin(num, ptr)
|
|
||||||
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
|
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
|
||||||
#define bignum_rshift1(dest, src) BN_rshift1(dest, src)
|
|
||||||
#define bignum_dup(orig, dest) do { \
|
|
||||||
if (*(dest) == NULL) { \
|
|
||||||
*(dest) = BN_dup(orig); \
|
|
||||||
} else { \
|
|
||||||
BN_copy(*(dest), orig); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns true if the OpenSSL is operating in FIPS mode */
|
|
||||||
#ifdef HAVE_OPENSSL_FIPS_MODE
|
|
||||||
#define ssh_fips_mode() (FIPS_mode() != 0)
|
|
||||||
#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
#define ssh_fips_mode() EVP_default_properties_is_fips_enabled(NULL)
|
|
||||||
#else
|
|
||||||
#define ssh_fips_mode() false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HAVE_LIBCRYPTO */
|
#endif /* HAVE_LIBCRYPTO */
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ typedef gcry_md_hd_t SHA384CTX;
|
|||||||
typedef gcry_md_hd_t SHA512CTX;
|
typedef gcry_md_hd_t SHA512CTX;
|
||||||
typedef gcry_md_hd_t MD5CTX;
|
typedef gcry_md_hd_t MD5CTX;
|
||||||
typedef gcry_md_hd_t HMACCTX;
|
typedef gcry_md_hd_t HMACCTX;
|
||||||
|
typedef gcry_md_hd_t EVPCTX;
|
||||||
#define SHA_DIGEST_LENGTH 20
|
#define SHA_DIGEST_LENGTH 20
|
||||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||||
#define MD5_DIGEST_LEN 16
|
#define MD5_DIGEST_LEN 16
|
||||||
@@ -49,8 +50,6 @@ typedef gcry_md_hd_t HMACCTX;
|
|||||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||||
|
|
||||||
typedef gcry_mpi_t bignum;
|
typedef gcry_mpi_t bignum;
|
||||||
typedef const struct gcry_mpi *const_bignum;
|
|
||||||
typedef void* bignum_CTX;
|
|
||||||
|
|
||||||
/* Constants for curves. */
|
/* Constants for curves. */
|
||||||
#define NID_gcrypt_nistp256 0
|
#define NID_gcrypt_nistp256 0
|
||||||
@@ -60,7 +59,6 @@ typedef void* bignum_CTX;
|
|||||||
/* missing gcrypt functions */
|
/* missing gcrypt functions */
|
||||||
int ssh_gcry_dec2bn(bignum *bn, const char *data);
|
int ssh_gcry_dec2bn(bignum *bn, const char *data);
|
||||||
char *ssh_gcry_bn2dec(bignum bn);
|
char *ssh_gcry_bn2dec(bignum bn);
|
||||||
int ssh_gcry_rand_range(bignum rnd, bignum max);
|
|
||||||
|
|
||||||
#define bignum_new() gcry_mpi_new(0)
|
#define bignum_new() gcry_mpi_new(0)
|
||||||
#define bignum_safe_free(num) do { \
|
#define bignum_safe_free(num) do { \
|
||||||
@@ -69,43 +67,21 @@ int ssh_gcry_rand_range(bignum rnd, bignum max);
|
|||||||
(num)=NULL; \
|
(num)=NULL; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define bignum_free(num) gcry_mpi_release(num)
|
#define bignum_set_word(bn,n) gcry_mpi_set_ui(bn,n)
|
||||||
#define bignum_ctx_new() NULL
|
#define bignum_bin2bn(bn,datalen,data) gcry_mpi_scan(data,GCRYMPI_FMT_USG,bn,datalen,NULL)
|
||||||
#define bignum_ctx_free(ctx) do {(ctx) = NULL;} while(0)
|
|
||||||
#define bignum_ctx_invalid(ctx) (ctx != NULL)
|
|
||||||
#define bignum_set_word(bn,n) (gcry_mpi_set_ui(bn,n)!=NULL ? 1 : 0)
|
|
||||||
#define bignum_bin2bn(data,datalen,dest) gcry_mpi_scan(dest,GCRYMPI_FMT_USG,data,datalen,NULL)
|
|
||||||
#define bignum_bn2dec(num) ssh_gcry_bn2dec(num)
|
#define bignum_bn2dec(num) ssh_gcry_bn2dec(num)
|
||||||
#define bignum_dec2bn(num, data) ssh_gcry_dec2bn(data, num)
|
#define bignum_dec2bn(num, data) ssh_gcry_dec2bn(data, num)
|
||||||
|
#define bignum_bn2hex(num,data) gcry_mpi_aprint(GCRYMPI_FMT_HEX,data,NULL,num)
|
||||||
#define bignum_bn2hex(num, data) \
|
#define bignum_hex2bn(num,datalen,data) gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,datalen,NULL)
|
||||||
gcry_mpi_aprint(GCRYMPI_FMT_HEX, data, NULL, (const gcry_mpi_t)num)
|
#define bignum_rand(num,bits) gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
|
||||||
|
#define bignum_mod_exp(dest,generator,exp,modulo) gcry_mpi_powm(dest,generator,exp,modulo)
|
||||||
#define bignum_hex2bn(data, num) (gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,0,NULL)==0?1:0)
|
|
||||||
#define bignum_rand(num,bits) 1,gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
|
|
||||||
#define bignum_mod_exp(dest,generator,exp,modulo, ctx) 1,gcry_mpi_powm(dest,generator,exp,modulo)
|
|
||||||
#define bignum_num_bits(num) gcry_mpi_get_nbits(num)
|
#define bignum_num_bits(num) gcry_mpi_get_nbits(num)
|
||||||
#define bignum_num_bytes(num) ((gcry_mpi_get_nbits(num)+7)/8)
|
#define bignum_num_bytes(num) ((gcry_mpi_get_nbits(num)+7)/8)
|
||||||
#define bignum_is_bit_set(num,bit) gcry_mpi_test_bit(num,bit)
|
#define bignum_is_bit_set(num,bit) gcry_mpi_test_bit(num,bit)
|
||||||
#define bignum_bn2bin(num,datalen,data) gcry_mpi_print(GCRYMPI_FMT_USG,data,datalen,NULL,num)
|
#define bignum_bn2bin(num,datalen,data) gcry_mpi_print(GCRYMPI_FMT_USG,data,datalen,NULL,num)
|
||||||
#define bignum_cmp(num1,num2) gcry_mpi_cmp(num1,num2)
|
#define bignum_cmp(num1,num2) gcry_mpi_cmp(num1,num2)
|
||||||
#define bignum_rshift1(dest, src) gcry_mpi_rshift (dest, src, 1)
|
|
||||||
#define bignum_add(dst, a, b) gcry_mpi_add(dst, a, b)
|
|
||||||
#define bignum_sub(dst, a, b) gcry_mpi_sub(dst, a, b)
|
|
||||||
#define bignum_mod(dst, a, b, ctx) 1,gcry_mpi_mod(dst, a, b)
|
|
||||||
#define bignum_rand_range(rnd, max) ssh_gcry_rand_range(rnd, max);
|
|
||||||
#define bignum_dup(orig, dest) do { \
|
|
||||||
if (*(dest) == NULL) { \
|
|
||||||
*(dest) = gcry_mpi_copy(orig); \
|
|
||||||
} else { \
|
|
||||||
gcry_mpi_set(*(dest), orig); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
/* Helper functions for data conversions. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* Helper functions for data conversions. */
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Extract an MPI from the given s-expression SEXP named NAME which is
|
/* Extract an MPI from the given s-expression SEXP named NAME which is
|
||||||
encoded using INFORMAT and store it in a newly allocated ssh_string
|
encoded using INFORMAT and store it in a newly allocated ssh_string
|
||||||
@@ -115,12 +91,6 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
|
|||||||
enum gcry_mpi_format informat,
|
enum gcry_mpi_format informat,
|
||||||
enum gcry_mpi_format outformat);
|
enum gcry_mpi_format outformat);
|
||||||
|
|
||||||
#define ssh_fips_mode() false
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HAVE_LIBGCRYPT */
|
#endif /* HAVE_LIBGCRYPT */
|
||||||
|
|
||||||
#endif /* LIBGCRYPT_H_ */
|
#endif /* LIBGCRYPT_H_ */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ typedef mbedtls_md_context_t *SHA384CTX;
|
|||||||
typedef mbedtls_md_context_t *SHA512CTX;
|
typedef mbedtls_md_context_t *SHA512CTX;
|
||||||
typedef mbedtls_md_context_t *MD5CTX;
|
typedef mbedtls_md_context_t *MD5CTX;
|
||||||
typedef mbedtls_md_context_t *HMACCTX;
|
typedef mbedtls_md_context_t *HMACCTX;
|
||||||
|
typedef mbedtls_md_context_t *EVPCTX;
|
||||||
|
|
||||||
#define SHA_DIGEST_LENGTH 20
|
#define SHA_DIGEST_LENGTH 20
|
||||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||||
@@ -59,8 +60,6 @@ typedef mbedtls_md_context_t *HMACCTX;
|
|||||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||||
|
|
||||||
typedef mbedtls_mpi *bignum;
|
typedef mbedtls_mpi *bignum;
|
||||||
typedef const mbedtls_mpi *const_bignum;
|
|
||||||
typedef void* bignum_CTX;
|
|
||||||
|
|
||||||
/* Constants for curves */
|
/* Constants for curves */
|
||||||
#define NID_mbedtls_nistp256 0
|
#define NID_mbedtls_nistp256 0
|
||||||
@@ -72,17 +71,11 @@ struct mbedtls_ecdsa_sig {
|
|||||||
bignum s;
|
bignum s;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bignum ssh_mbedcry_bn_new(void);
|
bignum ssh_mbedcry_bn_new(void);
|
||||||
void ssh_mbedcry_bn_free(bignum num);
|
void ssh_mbedcry_bn_free(bignum num);
|
||||||
unsigned char *ssh_mbedcry_bn2num(const_bignum num, int radix);
|
char *ssh_mbedcry_bn2num(bignum num, int radix);
|
||||||
int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom);
|
int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom);
|
||||||
int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
|
int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
|
||||||
int ssh_mbedcry_rand_range(bignum dest, bignum max);
|
|
||||||
int ssh_mbedcry_hex2bn(bignum *dest, char *data);
|
|
||||||
|
|
||||||
#define bignum_new() ssh_mbedcry_bn_new()
|
#define bignum_new() ssh_mbedcry_bn_new()
|
||||||
#define bignum_safe_free(num) do { \
|
#define bignum_safe_free(num) do { \
|
||||||
@@ -91,44 +84,22 @@ int ssh_mbedcry_hex2bn(bignum *dest, char *data);
|
|||||||
(num)=NULL; \
|
(num)=NULL; \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
#define bignum_ctx_new() NULL
|
#define bignum_set_word(bn, n) mbedtls_mpi_lset(bn, n) /* TODO fix
|
||||||
#define bignum_ctx_free(num) do {(num) = NULL;} while(0)
|
|
||||||
#define bignum_ctx_invalid(ctx) (ctx == NULL?0:1)
|
|
||||||
#define bignum_set_word(bn, n) (mbedtls_mpi_lset(bn, n)==0?1:0) /* TODO fix
|
|
||||||
overflow/underflow */
|
overflow/underflow */
|
||||||
#define bignum_bin2bn(data, datalen, bn) do { \
|
#define bignum_bin2bn(data, datalen, bn) mbedtls_mpi_read_binary(bn, data, \
|
||||||
*(bn) = bignum_new(); \
|
datalen)
|
||||||
if (*(bn) != NULL) { \
|
|
||||||
mbedtls_mpi_read_binary(*(bn), data, datalen); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
#define bignum_bn2dec(num) ssh_mbedcry_bn2num(num, 10)
|
#define bignum_bn2dec(num) ssh_mbedcry_bn2num(num, 10)
|
||||||
#define bignum_dec2bn(data, bn) mbedtls_mpi_read_string(bn, 10, data)
|
#define bignum_dec2bn(data, bn) mbedtls_mpi_read_string(bn, 10, data)
|
||||||
#define bignum_bn2hex(num, dest) (*dest)=ssh_mbedcry_bn2num(num, 16)
|
#define bignum_bn2hex(num) ssh_mbedcry_bn2num(num, 16)
|
||||||
#define bignum_hex2bn(data, dest) ssh_mbedcry_hex2bn(dest, data)
|
|
||||||
#define bignum_rand(rnd, bits) ssh_mbedcry_rand((rnd), (bits), 0, 1)
|
#define bignum_rand(rnd, bits) ssh_mbedcry_rand((rnd), (bits), 0, 1)
|
||||||
#define bignum_rand_range(rnd, max) ssh_mbedcry_rand_range(rnd, max)
|
|
||||||
#define bignum_mod_exp(dest, generator, exp, modulo, ctx) \
|
#define bignum_mod_exp(dest, generator, exp, modulo, ctx) \
|
||||||
(mbedtls_mpi_exp_mod(dest, generator, exp, modulo, NULL)==0?1:0)
|
mbedtls_mpi_exp_mod(dest, generator, exp, modulo, NULL)
|
||||||
#define bignum_add(dest, a, b) mbedtls_mpi_add_mpi(dest, a, b)
|
|
||||||
#define bignum_sub(dest, a, b) mbedtls_mpi_sub_mpi(dest, a, b)
|
|
||||||
#define bignum_mod(dest, a, b, ctx) \
|
|
||||||
(mbedtls_mpi_mod_mpi(dest, a, b) == 0 ? 1 : 0)
|
|
||||||
#define bignum_num_bytes(num) mbedtls_mpi_size(num)
|
#define bignum_num_bytes(num) mbedtls_mpi_size(num)
|
||||||
#define bignum_num_bits(num) mbedtls_mpi_bitlen(num)
|
#define bignum_num_bits(num) mbedtls_mpi_bitlen(num)
|
||||||
#define bignum_is_bit_set(num, bit) ssh_mbedcry_is_bit_set(num, bit)
|
#define bignum_is_bit_set(num, bit) ssh_mbedcry_is_bit_set(num, bit)
|
||||||
#define bignum_bn2bin(num, len, ptr) mbedtls_mpi_write_binary(num, ptr, \
|
#define bignum_bn2bin(num, ptr) mbedtls_mpi_write_binary(num, ptr, \
|
||||||
mbedtls_mpi_size(num))
|
mbedtls_mpi_size(num))
|
||||||
#define bignum_cmp(num1, num2) mbedtls_mpi_cmp_mpi(num1, num2)
|
#define bignum_cmp(num1, num2) mbedtls_mpi_cmp_mpi(num1, num2)
|
||||||
#define bignum_rshift1(dest, src) mbedtls_mpi_copy(dest, src), mbedtls_mpi_shift_r(dest, 1)
|
|
||||||
#define bignum_dup(orig, dest) do { \
|
|
||||||
if (*(dest) == NULL) { \
|
|
||||||
*(dest) = bignum_new(); \
|
|
||||||
} \
|
|
||||||
if (*(dest) != NULL) { \
|
|
||||||
mbedtls_mpi_copy(orig, *(dest)); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void);
|
mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void);
|
||||||
|
|
||||||
@@ -137,11 +108,5 @@ int ssh_mbedtls_random(void *where, int len, int strong);
|
|||||||
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
|
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
|
||||||
mbedtls_ecp_point *p);
|
mbedtls_ecp_point *p);
|
||||||
|
|
||||||
#define ssh_fips_mode() false
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HAVE_LIBMBEDCRYPTO */
|
#endif /* HAVE_LIBMBEDCRYPTO */
|
||||||
#endif /* LIBMBEDCRYPTO_H_ */
|
#endif /* LIBMBEDCRYPTO_H_ */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the SSH Library
|
* This file is part of the SSH Library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2023 by Aris Adamantiadis and the libssh team
|
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
#ifndef _LIBSSH_H
|
#ifndef _LIBSSH_H
|
||||||
#define _LIBSSH_H
|
#define _LIBSSH_H
|
||||||
|
|
||||||
#include <libssh/libssh_version.h>
|
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
#ifdef LIBSSH_STATIC
|
#ifdef LIBSSH_STATIC
|
||||||
#define LIBSSH_API
|
#define LIBSSH_API
|
||||||
@@ -49,8 +47,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
/* Visual Studio hasn't inttypes.h so it doesn't know uint32_t */
|
/* Visual Studio hasn't inttypes.h so it doesn't know uint32_t */
|
||||||
typedef int int32_t;
|
typedef int int32_t;
|
||||||
@@ -75,6 +71,23 @@
|
|||||||
#define SSH_STRINGIFY(s) SSH_TOSTRING(s)
|
#define SSH_STRINGIFY(s) SSH_TOSTRING(s)
|
||||||
#define SSH_TOSTRING(s) #s
|
#define SSH_TOSTRING(s) #s
|
||||||
|
|
||||||
|
/* libssh version macros */
|
||||||
|
#define SSH_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
|
||||||
|
#define SSH_VERSION_DOT(a, b, c) a ##.## b ##.## c
|
||||||
|
#define SSH_VERSION(a, b, c) SSH_VERSION_DOT(a, b, c)
|
||||||
|
|
||||||
|
/* libssh version */
|
||||||
|
#define LIBSSH_VERSION_MAJOR 0
|
||||||
|
#define LIBSSH_VERSION_MINOR 8
|
||||||
|
#define LIBSSH_VERSION_MICRO 3
|
||||||
|
|
||||||
|
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||||
|
LIBSSH_VERSION_MINOR, \
|
||||||
|
LIBSSH_VERSION_MICRO)
|
||||||
|
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
|
||||||
|
LIBSSH_VERSION_MINOR, \
|
||||||
|
LIBSSH_VERSION_MICRO)
|
||||||
|
|
||||||
/* GCC have printf type attribute check. */
|
/* GCC have printf type attribute check. */
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||||
@@ -82,7 +95,7 @@
|
|||||||
#define PRINTF_ATTRIBUTE(a,b)
|
#define PRINTF_ATTRIBUTE(a,b)
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#if !defined(SSH_SUPPRESS_DEPRECATED) && defined(__GNUC__)
|
#ifdef __GNUC__
|
||||||
#define SSH_DEPRECATED __attribute__ ((deprecated))
|
#define SSH_DEPRECATED __attribute__ ((deprecated))
|
||||||
#else
|
#else
|
||||||
#define SSH_DEPRECATED
|
#define SSH_DEPRECATED
|
||||||
@@ -155,13 +168,13 @@ enum ssh_auth_e {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* auth flags */
|
/* auth flags */
|
||||||
#define SSH_AUTH_METHOD_UNKNOWN 0x0000u
|
#define SSH_AUTH_METHOD_UNKNOWN 0
|
||||||
#define SSH_AUTH_METHOD_NONE 0x0001u
|
#define SSH_AUTH_METHOD_NONE 0x0001
|
||||||
#define SSH_AUTH_METHOD_PASSWORD 0x0002u
|
#define SSH_AUTH_METHOD_PASSWORD 0x0002
|
||||||
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004u
|
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004
|
||||||
#define SSH_AUTH_METHOD_HOSTBASED 0x0008u
|
#define SSH_AUTH_METHOD_HOSTBASED 0x0008
|
||||||
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010u
|
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010
|
||||||
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020u
|
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020
|
||||||
|
|
||||||
/* messages */
|
/* messages */
|
||||||
enum ssh_requests_e {
|
enum ssh_requests_e {
|
||||||
@@ -280,21 +293,10 @@ enum ssh_keytypes_e{
|
|||||||
SSH_KEYTYPE_DSS=1,
|
SSH_KEYTYPE_DSS=1,
|
||||||
SSH_KEYTYPE_RSA,
|
SSH_KEYTYPE_RSA,
|
||||||
SSH_KEYTYPE_RSA1,
|
SSH_KEYTYPE_RSA1,
|
||||||
SSH_KEYTYPE_ECDSA, /* deprecated */
|
SSH_KEYTYPE_ECDSA,
|
||||||
SSH_KEYTYPE_ED25519,
|
SSH_KEYTYPE_ED25519,
|
||||||
SSH_KEYTYPE_DSS_CERT01,
|
SSH_KEYTYPE_DSS_CERT01,
|
||||||
SSH_KEYTYPE_RSA_CERT01,
|
SSH_KEYTYPE_RSA_CERT01
|
||||||
SSH_KEYTYPE_ECDSA_P256,
|
|
||||||
SSH_KEYTYPE_ECDSA_P384,
|
|
||||||
SSH_KEYTYPE_ECDSA_P521,
|
|
||||||
SSH_KEYTYPE_ECDSA_P256_CERT01,
|
|
||||||
SSH_KEYTYPE_ECDSA_P384_CERT01,
|
|
||||||
SSH_KEYTYPE_ECDSA_P521_CERT01,
|
|
||||||
SSH_KEYTYPE_ED25519_CERT01,
|
|
||||||
SSH_KEYTYPE_SK_ECDSA,
|
|
||||||
SSH_KEYTYPE_SK_ECDSA_CERT01,
|
|
||||||
SSH_KEYTYPE_SK_ED25519,
|
|
||||||
SSH_KEYTYPE_SK_ED25519_CERT01,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ssh_keycmp_e {
|
enum ssh_keycmp_e {
|
||||||
@@ -357,7 +359,7 @@ enum {
|
|||||||
#define SSH_LOG_WARN 1
|
#define SSH_LOG_WARN 1
|
||||||
/** Get some information what's going on */
|
/** Get some information what's going on */
|
||||||
#define SSH_LOG_INFO 2
|
#define SSH_LOG_INFO 2
|
||||||
/** Get detailed debugging information **/
|
/** Get detailed debuging information **/
|
||||||
#define SSH_LOG_DEBUG 3
|
#define SSH_LOG_DEBUG 3
|
||||||
/** Get trace output, packet information, ... */
|
/** Get trace output, packet information, ... */
|
||||||
#define SSH_LOG_TRACE 4
|
#define SSH_LOG_TRACE 4
|
||||||
@@ -403,11 +405,6 @@ enum ssh_options_e {
|
|||||||
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
||||||
SSH_OPTIONS_NODELAY,
|
SSH_OPTIONS_NODELAY,
|
||||||
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||||
SSH_OPTIONS_PROCESS_CONFIG,
|
|
||||||
SSH_OPTIONS_REKEY_DATA,
|
|
||||||
SSH_OPTIONS_REKEY_TIME,
|
|
||||||
SSH_OPTIONS_RSA_MIN_SIZE,
|
|
||||||
SSH_OPTIONS_IDENTITY_AGENT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -434,7 +431,6 @@ enum ssh_scp_request_types {
|
|||||||
enum ssh_connector_flags_e {
|
enum ssh_connector_flags_e {
|
||||||
/** Only the standard stream of the channel */
|
/** Only the standard stream of the channel */
|
||||||
SSH_CONNECTOR_STDOUT = 1,
|
SSH_CONNECTOR_STDOUT = 1,
|
||||||
SSH_CONNECTOR_STDINOUT = 1,
|
|
||||||
/** Only the exception stream of the channel */
|
/** Only the exception stream of the channel */
|
||||||
SSH_CONNECTOR_STDERR = 2,
|
SSH_CONNECTOR_STDERR = 2,
|
||||||
/** Merge both standard and exception streams */
|
/** Merge both standard and exception streams */
|
||||||
@@ -455,8 +451,6 @@ LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
|
|||||||
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
|
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
|
||||||
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||||
int remoteport, const char *sourcehost, int localport);
|
int remoteport, const char *sourcehost, int localport);
|
||||||
LIBSSH_API int ssh_channel_open_forward_unix(ssh_channel channel, const char *remotepath,
|
|
||||||
const char *sourcehost, int localport);
|
|
||||||
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
|
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
|
||||||
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
|
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
|
||||||
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
|
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
|
||||||
@@ -479,6 +473,8 @@ LIBSSH_API int ssh_channel_request_x11(ssh_channel channel, int single_connectio
|
|||||||
const char *cookie, int screen_number);
|
const char *cookie, int screen_number);
|
||||||
LIBSSH_API int ssh_channel_request_auth_agent(ssh_channel channel);
|
LIBSSH_API int ssh_channel_request_auth_agent(ssh_channel channel);
|
||||||
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
|
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
|
||||||
|
LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
||||||
|
timeval * timeout);
|
||||||
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
|
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
|
||||||
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
|
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
|
||||||
ssh_counter counter);
|
ssh_counter counter);
|
||||||
@@ -509,12 +505,7 @@ LIBSSH_API char *ssh_dirname (const char *path);
|
|||||||
LIBSSH_API int ssh_finalize(void);
|
LIBSSH_API int ssh_finalize(void);
|
||||||
|
|
||||||
/* REVERSE PORT FORWARDING */
|
/* REVERSE PORT FORWARDING */
|
||||||
LIBSSH_API ssh_channel ssh_channel_open_forward_port(ssh_session session,
|
LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
|
||||||
int timeout_ms,
|
|
||||||
int *destination_port,
|
|
||||||
char **originator,
|
|
||||||
int *originator_port);
|
|
||||||
SSH_DEPRECATED LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
|
|
||||||
int timeout_ms,
|
int timeout_ms,
|
||||||
int *destination_port);
|
int *destination_port);
|
||||||
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
|
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
|
||||||
@@ -552,31 +543,6 @@ SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, in
|
|||||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
|
SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_write_knownhost(ssh_session session);
|
|
||||||
SSH_DEPRECATED LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_is_server_known(ssh_session session);
|
|
||||||
SSH_DEPRECATED LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
|
||||||
timeval * timeout);
|
|
||||||
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_close(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
|
|
||||||
SSH_DEPRECATED LIBSSH_API void ssh_scp_free(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_init(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
|
|
||||||
SSH_DEPRECATED LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API uint64_t ssh_scp_request_get_size64(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
|
|
||||||
SSH_DEPRECATED LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
|
|
||||||
|
|
||||||
|
|
||||||
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
||||||
@@ -586,6 +552,7 @@ LIBSSH_API int ssh_get_poll_flags(ssh_session session);
|
|||||||
LIBSSH_API int ssh_init(void);
|
LIBSSH_API int ssh_init(void);
|
||||||
LIBSSH_API int ssh_is_blocking(ssh_session session);
|
LIBSSH_API int ssh_is_blocking(ssh_session session);
|
||||||
LIBSSH_API int ssh_is_connected(ssh_session session);
|
LIBSSH_API int ssh_is_connected(ssh_session session);
|
||||||
|
LIBSSH_API int ssh_is_server_known(ssh_session session);
|
||||||
|
|
||||||
/* KNOWN HOSTS */
|
/* KNOWN HOSTS */
|
||||||
LIBSSH_API void ssh_knownhosts_entry_free(struct ssh_knownhosts_entry *entry);
|
LIBSSH_API void ssh_knownhosts_entry_free(struct ssh_knownhosts_entry *entry);
|
||||||
@@ -605,8 +572,9 @@ LIBSSH_API int ssh_session_export_known_hosts_entry(ssh_session session,
|
|||||||
char **pentry_string);
|
char **pentry_string);
|
||||||
LIBSSH_API int ssh_session_update_known_hosts(ssh_session session);
|
LIBSSH_API int ssh_session_update_known_hosts(ssh_session session);
|
||||||
|
|
||||||
LIBSSH_API enum ssh_known_hosts_e ssh_session_get_known_hosts_entry(ssh_session session,
|
LIBSSH_API enum ssh_known_hosts_e
|
||||||
struct ssh_knownhosts_entry **pentry);
|
ssh_session_get_known_hosts_entry(ssh_session session,
|
||||||
|
struct ssh_knownhosts_entry **pentry);
|
||||||
LIBSSH_API enum ssh_known_hosts_e ssh_session_is_known_server(ssh_session session);
|
LIBSSH_API enum ssh_known_hosts_e ssh_session_is_known_server(ssh_session session);
|
||||||
|
|
||||||
/* LOGGING */
|
/* LOGGING */
|
||||||
@@ -614,10 +582,6 @@ LIBSSH_API int ssh_set_log_level(int level);
|
|||||||
LIBSSH_API int ssh_get_log_level(void);
|
LIBSSH_API int ssh_get_log_level(void);
|
||||||
LIBSSH_API void *ssh_get_log_userdata(void);
|
LIBSSH_API void *ssh_get_log_userdata(void);
|
||||||
LIBSSH_API int ssh_set_log_userdata(void *data);
|
LIBSSH_API int ssh_set_log_userdata(void *data);
|
||||||
LIBSSH_API void ssh_vlog(int verbosity,
|
|
||||||
const char *function,
|
|
||||||
const char *format,
|
|
||||||
va_list *va) PRINTF_ATTRIBUTE(3, 0);
|
|
||||||
LIBSSH_API void _ssh_log(int verbosity,
|
LIBSSH_API void _ssh_log(int verbosity,
|
||||||
const char *function,
|
const char *function,
|
||||||
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||||
@@ -628,10 +592,7 @@ SSH_DEPRECATED LIBSSH_API void ssh_log(ssh_session session,
|
|||||||
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||||
|
|
||||||
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
|
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
|
||||||
LIBSSH_API int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);
|
|
||||||
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
|
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
|
||||||
#define SSH_MESSAGE_FREE(x) \
|
|
||||||
do { if ((x) != NULL) { ssh_message_free(x); (x) = NULL; } } while(0)
|
|
||||||
LIBSSH_API void ssh_message_free(ssh_message msg);
|
LIBSSH_API void ssh_message_free(ssh_message msg);
|
||||||
LIBSSH_API ssh_message ssh_message_get(ssh_session session);
|
LIBSSH_API ssh_message ssh_message_get(ssh_session session);
|
||||||
LIBSSH_API int ssh_message_subtype(ssh_message msg);
|
LIBSSH_API int ssh_message_subtype(ssh_message msg);
|
||||||
@@ -653,13 +614,7 @@ LIBSSH_API ssh_pcap_file ssh_pcap_file_new(void);
|
|||||||
LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup libssh_auth
|
* @brief SSH authentication callback.
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief SSH authentication callback for password and publickey auth.
|
|
||||||
*
|
*
|
||||||
* @param prompt Prompt to be displayed.
|
* @param prompt Prompt to be displayed.
|
||||||
* @param buf Buffer to save the password. You should null-terminate it.
|
* @param buf Buffer to save the password. You should null-terminate it.
|
||||||
@@ -674,11 +629,7 @@ LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
|
|||||||
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
|
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
|
||||||
int echo, int verify, void *userdata);
|
int echo, int verify, void *userdata);
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
LIBSSH_API ssh_key ssh_key_new(void);
|
LIBSSH_API ssh_key ssh_key_new(void);
|
||||||
#define SSH_KEY_FREE(x) \
|
|
||||||
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
|
|
||||||
LIBSSH_API void ssh_key_free (ssh_key key);
|
LIBSSH_API void ssh_key_free (ssh_key key);
|
||||||
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
|
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
|
||||||
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);
|
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);
|
||||||
@@ -688,7 +639,6 @@ LIBSSH_API int ssh_key_is_private(const ssh_key k);
|
|||||||
LIBSSH_API int ssh_key_cmp(const ssh_key k1,
|
LIBSSH_API int ssh_key_cmp(const ssh_key k1,
|
||||||
const ssh_key k2,
|
const ssh_key k2,
|
||||||
enum ssh_keycmp_e what);
|
enum ssh_keycmp_e what);
|
||||||
LIBSSH_API ssh_key ssh_key_dup(const ssh_key key);
|
|
||||||
|
|
||||||
LIBSSH_API int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
LIBSSH_API int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
||||||
ssh_key *pkey);
|
ssh_key *pkey);
|
||||||
@@ -741,9 +691,28 @@ LIBSSH_API char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
|
|||||||
unsigned char *hash,
|
unsigned char *hash,
|
||||||
size_t len);
|
size_t len);
|
||||||
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
|
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
|
||||||
|
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||||
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
|
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
|
||||||
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
|
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
|
||||||
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);
|
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);
|
||||||
|
LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_close(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
|
||||||
|
LIBSSH_API void ssh_scp_free(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_init(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
|
||||||
|
LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
|
||||||
|
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
|
||||||
|
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
|
||||||
|
LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
|
||||||
|
LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
|
||||||
|
LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
|
||||||
|
LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
|
||||||
|
LIBSSH_API uint64_t ssh_scp_request_get_size64(ssh_scp scp);
|
||||||
|
LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
|
||||||
|
LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
|
||||||
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||||
fd_set *readfds, struct timeval *timeout);
|
fd_set *readfds, struct timeval *timeout);
|
||||||
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
|
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
|
||||||
@@ -771,8 +740,6 @@ LIBSSH_API int ssh_userauth_publickey(ssh_session session,
|
|||||||
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
LIBSSH_API int ssh_userauth_agent(ssh_session session,
|
||||||
const char *username);
|
const char *username);
|
||||||
#endif
|
#endif
|
||||||
LIBSSH_API int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
|
|
||||||
char** value);
|
|
||||||
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
|
||||||
const char *username,
|
const char *username,
|
||||||
const char *passphrase);
|
const char *passphrase);
|
||||||
@@ -791,6 +758,8 @@ LIBSSH_API int ssh_userauth_kbdint_setanswer(ssh_session session, unsigned int i
|
|||||||
const char *answer);
|
const char *answer);
|
||||||
LIBSSH_API int ssh_userauth_gssapi(ssh_session session);
|
LIBSSH_API int ssh_userauth_gssapi(ssh_session session);
|
||||||
LIBSSH_API const char *ssh_version(int req_version);
|
LIBSSH_API const char *ssh_version(int req_version);
|
||||||
|
LIBSSH_API int ssh_write_knownhost(ssh_session session);
|
||||||
|
LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
|
||||||
|
|
||||||
LIBSSH_API void ssh_string_burn(ssh_string str);
|
LIBSSH_API void ssh_string_burn(ssh_string str);
|
||||||
LIBSSH_API ssh_string ssh_string_copy(ssh_string str);
|
LIBSSH_API ssh_string ssh_string_copy(ssh_string str);
|
||||||
@@ -841,7 +810,6 @@ LIBSSH_API int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t
|
|||||||
LIBSSH_API uint32_t ssh_buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
|
LIBSSH_API uint32_t ssh_buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
|
||||||
LIBSSH_API void *ssh_buffer_get(ssh_buffer buffer);
|
LIBSSH_API void *ssh_buffer_get(ssh_buffer buffer);
|
||||||
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
|
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
|
||||||
LIBSSH_API int ssh_session_set_disconnect_message(ssh_session session, const char *message);
|
|
||||||
|
|
||||||
#ifndef LIBSSH_LEGACY_0_4
|
#ifndef LIBSSH_LEGACY_0_4
|
||||||
#include "libssh/legacy.h"
|
#include "libssh/legacy.h"
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the SSH Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 by Heiko Thiery
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBSSH_VERSION_H
|
|
||||||
#define _LIBSSH_VERSION_H
|
|
||||||
|
|
||||||
/* libssh version macros */
|
|
||||||
#define SSH_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
|
|
||||||
#define SSH_VERSION_DOT(a, b, c) a ##.## b ##.## c
|
|
||||||
#define SSH_VERSION(a, b, c) SSH_VERSION_DOT(a, b, c)
|
|
||||||
|
|
||||||
/* libssh version */
|
|
||||||
#define LIBSSH_VERSION_MAJOR @libssh_VERSION_MAJOR@
|
|
||||||
#define LIBSSH_VERSION_MINOR @libssh_VERSION_MINOR@
|
|
||||||
#define LIBSSH_VERSION_MICRO @libssh_VERSION_PATCH@
|
|
||||||
|
|
||||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
|
||||||
LIBSSH_VERSION_MINOR, \
|
|
||||||
LIBSSH_VERSION_MICRO)
|
|
||||||
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
|
|
||||||
LIBSSH_VERSION_MINOR, \
|
|
||||||
LIBSSH_VERSION_MICRO)
|
|
||||||
|
|
||||||
#endif /* _LIBSSH_VERSION_H */
|
|
||||||
@@ -212,7 +212,7 @@ public:
|
|||||||
* @see ssh_userauth_kbdint
|
* @see ssh_userauth_kbdint
|
||||||
*/
|
*/
|
||||||
int userauthKbdint(const char* username, const char* submethods){
|
int userauthKbdint(const char* username, const char* submethods){
|
||||||
int ret = ssh_userauth_kbdint(c_session, username, submethods);
|
int ret=ssh_userauth_kbdint(c_session,NULL,NULL);
|
||||||
ssh_throw(ret);
|
ssh_throw(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -369,11 +369,13 @@ public:
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
void log(int priority, const char *format, ...){
|
void log(int priority, const char *format, ...){
|
||||||
|
char buffer[1024];
|
||||||
va_list va;
|
va_list va;
|
||||||
|
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
ssh_vlog(priority, "libsshpp", format, &va);
|
vsnprintf(buffer, sizeof(buffer), format, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
_ssh_log(priority, "libsshpp", "%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief copies options from a session to another
|
/** @brief copies options from a session to another
|
||||||
@@ -405,7 +407,7 @@ public:
|
|||||||
* @see ssh_write_knownhost
|
* @see ssh_write_knownhost
|
||||||
*/
|
*/
|
||||||
int writeKnownhost(){
|
int writeKnownhost(){
|
||||||
int ret = ssh_session_update_known_hosts(c_session);
|
int ret = ssh_write_knownhost(c_session);
|
||||||
ssh_throw(ret);
|
ssh_throw(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -523,7 +525,7 @@ public:
|
|||||||
return ssh_channel_is_open(channel) != 0;
|
return ssh_channel_is_open(channel) != 0;
|
||||||
}
|
}
|
||||||
int openForward(const char *remotehost, int remoteport,
|
int openForward(const char *remotehost, int remoteport,
|
||||||
const char *sourcehost, int localport=0){
|
const char *sourcehost=NULL, int localport=0){
|
||||||
int err=ssh_channel_open_forward(channel,remotehost,remoteport,
|
int err=ssh_channel_open_forward(channel,remotehost,remoteport,
|
||||||
sourcehost, localport);
|
sourcehost, localport);
|
||||||
ssh_throw(err);
|
ssh_throw(err);
|
||||||
@@ -630,8 +632,8 @@ public:
|
|||||||
* @param is_stderr write should be done on the stderr channel (server only)
|
* @param is_stderr write should be done on the stderr channel (server only)
|
||||||
* @returns number of bytes written
|
* @returns number of bytes written
|
||||||
* @throws SshException in case of error
|
* @throws SshException in case of error
|
||||||
* @see ssh_channel_write
|
* @see channel_write
|
||||||
* @see ssh_channel_write_stderr
|
* @see channel_write_stderr
|
||||||
*/
|
*/
|
||||||
int write(const void *data, size_t len, bool is_stderr=false){
|
int write(const void *data, size_t len, bool is_stderr=false){
|
||||||
int ret;
|
int ret;
|
||||||
@@ -669,7 +671,7 @@ private:
|
|||||||
|
|
||||||
inline Channel *Session::acceptForward(int timeout_ms){
|
inline Channel *Session::acceptForward(int timeout_ms){
|
||||||
ssh_channel forward =
|
ssh_channel forward =
|
||||||
ssh_channel_open_forward_port(c_session, timeout_ms, NULL, NULL, NULL);
|
ssh_channel_accept_forward(c_session, timeout_ms, NULL);
|
||||||
ssh_throw_null(c_session,forward);
|
ssh_throw_null(c_session,forward);
|
||||||
Channel *newchan = new Channel(*this,forward);
|
Channel *newchan = new Channel(*this,forward);
|
||||||
return newchan;
|
return newchan;
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ struct ssh_auth_request {
|
|||||||
int method;
|
int method;
|
||||||
char *password;
|
char *password;
|
||||||
struct ssh_key_struct *pubkey;
|
struct ssh_key_struct *pubkey;
|
||||||
char *sigtype;
|
char signature_state;
|
||||||
enum ssh_publickey_state_e signature_state;
|
|
||||||
char kbdint_response;
|
char kbdint_response;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,10 +91,6 @@ struct ssh_message_struct {
|
|||||||
struct ssh_global_request global_request;
|
struct ssh_global_request global_request;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open);
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_global_request);
|
SSH_PACKET_CALLBACK(ssh_packet_global_request);
|
||||||
|
|
||||||
@@ -106,10 +101,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request);
|
|||||||
|
|
||||||
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
|
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
|
||||||
const char *request, uint8_t want_reply);
|
const char *request, uint8_t want_reply);
|
||||||
|
void ssh_message_queue(ssh_session session, ssh_message message);
|
||||||
ssh_message ssh_message_pop_head(ssh_session session);
|
ssh_message ssh_message_pop_head(ssh_session session);
|
||||||
|
int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MESSAGES_H_ */
|
#endif /* MESSAGES_H_ */
|
||||||
|
|||||||
@@ -21,16 +21,11 @@
|
|||||||
#ifndef MISC_H_
|
#ifndef MISC_H_
|
||||||
#define MISC_H_
|
#define MISC_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* in misc.c */
|
/* in misc.c */
|
||||||
/* gets the user home dir. */
|
/* gets the user home dir. */
|
||||||
char *ssh_get_user_home_dir(void);
|
char *ssh_get_user_home_dir(void);
|
||||||
char *ssh_get_local_username(void);
|
char *ssh_get_local_username(void);
|
||||||
int ssh_file_readaccess_ok(const char *file);
|
int ssh_file_readaccess_ok(const char *file);
|
||||||
int ssh_dir_writeable(const char *path);
|
|
||||||
|
|
||||||
char *ssh_path_expand_tilde(const char *d);
|
char *ssh_path_expand_tilde(const char *d);
|
||||||
char *ssh_path_expand_escape(ssh_session session, const char *s);
|
char *ssh_path_expand_escape(ssh_session session, const char *s);
|
||||||
@@ -55,12 +50,6 @@ struct ssh_timestamp {
|
|||||||
long useconds;
|
long useconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ssh_quote_state_e {
|
|
||||||
NO_QUOTE,
|
|
||||||
SINGLE_QUOTE,
|
|
||||||
DOUBLE_QUOTE
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ssh_list *ssh_list_new(void);
|
struct ssh_list *ssh_list_new(void);
|
||||||
void ssh_list_free(struct ssh_list *list);
|
void ssh_list_free(struct ssh_list *list);
|
||||||
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
||||||
@@ -79,35 +68,17 @@ const void *_ssh_list_pop_head(struct ssh_list *list);
|
|||||||
|
|
||||||
/** @brief fetch the head element of a list and remove it from list
|
/** @brief fetch the head element of a list and remove it from list
|
||||||
* @param type type of the element to return
|
* @param type type of the element to return
|
||||||
* @param ssh_list the ssh_list to use
|
* @param list the ssh_list to use
|
||||||
* @return the first element of the list, or NULL if the list is empty
|
* @return the first element of the list, or NULL if the list is empty
|
||||||
*/
|
*/
|
||||||
#define ssh_list_pop_head(type, ssh_list)\
|
#define ssh_list_pop_head(type, ssh_list)\
|
||||||
((type)_ssh_list_pop_head(ssh_list))
|
((type)_ssh_list_pop_head(ssh_list))
|
||||||
|
|
||||||
int ssh_make_milliseconds(unsigned long sec, unsigned long usec);
|
int ssh_make_milliseconds(long sec, long usec);
|
||||||
void ssh_timestamp_init(struct ssh_timestamp *ts);
|
void ssh_timestamp_init(struct ssh_timestamp *ts);
|
||||||
int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout);
|
int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout);
|
||||||
int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
||||||
|
|
||||||
int ssh_match_group(const char *group, const char *object);
|
int ssh_match_group(const char *group, const char *object);
|
||||||
|
|
||||||
void uint64_inc(unsigned char *counter);
|
|
||||||
|
|
||||||
void ssh_log_hexdump(const char *descr, const unsigned char *what, size_t len);
|
|
||||||
|
|
||||||
int ssh_mkdirs(const char *pathname, mode_t mode);
|
|
||||||
|
|
||||||
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
|
|
||||||
int ssh_newline_vis(const char *string, char *buf, size_t buf_len);
|
|
||||||
int ssh_tmpname(char *name);
|
|
||||||
|
|
||||||
char *ssh_strreplace(const char *src, const char *pattern, const char *repl);
|
|
||||||
|
|
||||||
int ssh_check_hostname_syntax(const char *hostname);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MISC_H_ */
|
#endif /* MISC_H_ */
|
||||||
|
|||||||
@@ -21,19 +21,10 @@
|
|||||||
#ifndef _OPTIONS_H
|
#ifndef _OPTIONS_H
|
||||||
#define _OPTIONS_H
|
#define _OPTIONS_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ssh_config_parse_file(ssh_session session, const char *filename);
|
int ssh_config_parse_file(ssh_session session, const char *filename);
|
||||||
int ssh_config_parse_string(ssh_session session, const char *input);
|
|
||||||
int ssh_options_set_algo(ssh_session session,
|
int ssh_options_set_algo(ssh_session session,
|
||||||
enum ssh_kex_types_e algo,
|
enum ssh_kex_types_e algo,
|
||||||
const char *list);
|
const char *list);
|
||||||
int ssh_options_apply(ssh_session session);
|
int ssh_options_apply(ssh_session session);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _OPTIONS_H */
|
#endif /* _OPTIONS_H */
|
||||||
|
|||||||
@@ -43,18 +43,8 @@ enum ssh_packet_state_e {
|
|||||||
PACKET_STATE_PROCESSING
|
PACKET_STATE_PROCESSING
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ssh_packet_filter_result_e {
|
|
||||||
SSH_PACKET_UNKNOWN,
|
|
||||||
SSH_PACKET_ALLOWED,
|
|
||||||
SSH_PACKET_DENIED
|
|
||||||
};
|
|
||||||
|
|
||||||
int ssh_packet_send(ssh_session session);
|
int ssh_packet_send(ssh_session session);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
|
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
|
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
|
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
|
||||||
@@ -67,15 +57,13 @@ SSH_PACKET_CALLBACK(ssh_packet_ext_info);
|
|||||||
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
|
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ssh_packet_send_newkeys(ssh_session session);
|
|
||||||
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum);
|
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum);
|
||||||
int ssh_packet_parse_type(ssh_session session);
|
int ssh_packet_parse_type(ssh_session session);
|
||||||
//int packet_flush(ssh_session session, int enforce_blocking);
|
//int packet_flush(ssh_session session, int enforce_blocking);
|
||||||
|
|
||||||
size_t ssh_packet_socket_callback(const void *data, size_t len, void *user);
|
int ssh_packet_socket_callback(const void *data, size_t len, void *user);
|
||||||
void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s);
|
void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s);
|
||||||
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
|
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
|
||||||
void ssh_packet_remove_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
|
|
||||||
void ssh_packet_set_default_callbacks(ssh_session session);
|
void ssh_packet_set_default_callbacks(ssh_session session);
|
||||||
void ssh_packet_process(ssh_session session, uint8_t type);
|
void ssh_packet_process(ssh_session session, uint8_t type);
|
||||||
|
|
||||||
@@ -85,16 +73,8 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
|
|||||||
size_t start, size_t encrypted_size);
|
size_t start, size_t encrypted_size);
|
||||||
unsigned char *ssh_packet_encrypt(ssh_session session,
|
unsigned char *ssh_packet_encrypt(ssh_session session,
|
||||||
void *packet,
|
void *packet,
|
||||||
size_t len);
|
unsigned int len);
|
||||||
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
|
int ssh_packet_hmac_verify(ssh_session session,ssh_buffer buffer,
|
||||||
unsigned char *mac, enum ssh_hmac_e type);
|
unsigned char *mac, enum ssh_hmac_e type);
|
||||||
int ssh_packet_set_newkeys(ssh_session session,
|
|
||||||
enum ssh_crypto_direction_e direction);
|
|
||||||
struct ssh_crypto_struct *ssh_packet_get_current_crypto(ssh_session session,
|
|
||||||
enum ssh_crypto_direction_e direction);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PACKET_H_ */
|
#endif /* PACKET_H_ */
|
||||||
|
|||||||
@@ -27,10 +27,6 @@
|
|||||||
#ifdef WITH_PCAP
|
#ifdef WITH_PCAP
|
||||||
typedef struct ssh_pcap_context_struct* ssh_pcap_context;
|
typedef struct ssh_pcap_context_struct* ssh_pcap_context;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len);
|
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len);
|
||||||
|
|
||||||
ssh_pcap_context ssh_pcap_context_new(ssh_session session);
|
ssh_pcap_context ssh_pcap_context_new(ssh_session session);
|
||||||
@@ -45,9 +41,5 @@ int ssh_pcap_context_write(ssh_pcap_context,enum ssh_pcap_direction direction, v
|
|||||||
uint32_t len, uint32_t origlen);
|
uint32_t len, uint32_t origlen);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* WITH_PCAP */
|
#endif /* WITH_PCAP */
|
||||||
#endif /* PCAP_H_ */
|
#endif /* PCAP_H_ */
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#ifndef PKI_H_
|
#ifndef PKI_H_
|
||||||
#define PKI_H_
|
#define PKI_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#ifdef HAVE_OPENSSL_EC_H
|
#ifdef HAVE_OPENSSL_EC_H
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
@@ -29,19 +28,9 @@
|
|||||||
#ifdef HAVE_OPENSSL_ECDSA_H
|
#ifdef HAVE_OPENSSL_ECDSA_H
|
||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBCRYPTO
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#endif
|
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
|
|
||||||
/* If using OpenSSL implementation, define the signature length which would be
|
|
||||||
* defined in libssh/ed25519.h otherwise */
|
|
||||||
#define ED25519_SIG_LEN 64
|
|
||||||
#else
|
|
||||||
#include "libssh/ed25519.h"
|
#include "libssh/ed25519.h"
|
||||||
#endif
|
|
||||||
/* This definition is used for both OpenSSL and internal implementations */
|
|
||||||
#define ED25519_KEY_LEN 32
|
|
||||||
|
|
||||||
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
|
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
|
||||||
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
|
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
|
||||||
@@ -49,47 +38,31 @@
|
|||||||
#define SSH_KEY_FLAG_EMPTY 0x0
|
#define SSH_KEY_FLAG_EMPTY 0x0
|
||||||
#define SSH_KEY_FLAG_PUBLIC 0x0001
|
#define SSH_KEY_FLAG_PUBLIC 0x0001
|
||||||
#define SSH_KEY_FLAG_PRIVATE 0x0002
|
#define SSH_KEY_FLAG_PRIVATE 0x0002
|
||||||
#define SSH_KEY_FLAG_PKCS11_URI 0x0004
|
|
||||||
|
|
||||||
struct ssh_key_struct {
|
struct ssh_key_struct {
|
||||||
enum ssh_keytypes_e type;
|
enum ssh_keytypes_e type;
|
||||||
int flags;
|
int flags;
|
||||||
const char *type_c; /* Don't free it ! it is static */
|
const char *type_c; /* Don't free it ! it is static */
|
||||||
int ecdsa_nid;
|
int ecdsa_nid;
|
||||||
#if defined(HAVE_LIBGCRYPT)
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_sexp_t dsa;
|
gcry_sexp_t dsa;
|
||||||
gcry_sexp_t rsa;
|
gcry_sexp_t rsa;
|
||||||
gcry_sexp_t ecdsa;
|
gcry_sexp_t ecdsa;
|
||||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
#elif HAVE_LIBMBEDCRYPTO
|
||||||
mbedtls_pk_context *rsa;
|
mbedtls_pk_context *rsa;
|
||||||
mbedtls_ecdsa_context *ecdsa;
|
mbedtls_ecdsa_context *ecdsa;
|
||||||
void *dsa;
|
void *dsa;
|
||||||
#elif defined(HAVE_LIBCRYPTO)
|
#elif HAVE_LIBCRYPTO
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
DSA *dsa;
|
DSA *dsa;
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
|
||||||
* Move into the #if above
|
|
||||||
*/
|
|
||||||
# if defined(HAVE_OPENSSL_ECC)
|
|
||||||
EC_KEY *ecdsa;
|
EC_KEY *ecdsa;
|
||||||
# else
|
|
||||||
void *ecdsa;
|
|
||||||
# endif /* HAVE_OPENSSL_EC_H */
|
|
||||||
/* This holds either ENGINE key for PKCS#11 support or just key in
|
|
||||||
* high-level format required by OpenSSL 3.0 */
|
|
||||||
EVP_PKEY *key;
|
|
||||||
#endif /* HAVE_LIBGCRYPT */
|
|
||||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
|
|
||||||
uint8_t *ed25519_pubkey;
|
|
||||||
uint8_t *ed25519_privkey;
|
|
||||||
#else
|
#else
|
||||||
|
void *ecdsa;
|
||||||
|
#endif /* HAVE_OPENSSL_EC_H */
|
||||||
|
#endif
|
||||||
ed25519_pubkey *ed25519_pubkey;
|
ed25519_pubkey *ed25519_pubkey;
|
||||||
ed25519_privkey *ed25519_privkey;
|
ed25519_privkey *ed25519_privkey;
|
||||||
#endif
|
|
||||||
ssh_string sk_application;
|
|
||||||
void *cert;
|
void *cert;
|
||||||
enum ssh_keytypes_e cert_type;
|
enum ssh_keytypes_e cert_type;
|
||||||
};
|
};
|
||||||
@@ -98,69 +71,50 @@ struct ssh_signature_struct {
|
|||||||
enum ssh_keytypes_e type;
|
enum ssh_keytypes_e type;
|
||||||
enum ssh_digest_e hash_type;
|
enum ssh_digest_e hash_type;
|
||||||
const char *type_c;
|
const char *type_c;
|
||||||
#if defined(HAVE_LIBGCRYPT)
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_sexp_t dsa_sig;
|
gcry_sexp_t dsa_sig;
|
||||||
gcry_sexp_t rsa_sig;
|
gcry_sexp_t rsa_sig;
|
||||||
gcry_sexp_t ecdsa_sig;
|
gcry_sexp_t ecdsa_sig;
|
||||||
#elif defined(HAVE_LIBMBEDCRYPTO)
|
#elif defined HAVE_LIBCRYPTO
|
||||||
|
DSA_SIG *dsa_sig;
|
||||||
|
ssh_string rsa_sig;
|
||||||
|
# ifdef HAVE_OPENSSL_ECC
|
||||||
|
ECDSA_SIG *ecdsa_sig;
|
||||||
|
# else
|
||||||
|
void *ecdsa_sig;
|
||||||
|
# endif
|
||||||
|
#elif defined HAVE_LIBMBEDCRYPTO
|
||||||
ssh_string rsa_sig;
|
ssh_string rsa_sig;
|
||||||
struct mbedtls_ecdsa_sig ecdsa_sig;
|
struct mbedtls_ecdsa_sig ecdsa_sig;
|
||||||
#endif /* HAVE_LIBGCRYPT */
|
|
||||||
#if !defined(HAVE_LIBCRYPTO) || !defined(HAVE_OPENSSL_ED25519)
|
|
||||||
ed25519_signature *ed25519_sig;
|
|
||||||
#endif
|
#endif
|
||||||
ssh_string raw_sig;
|
ed25519_signature *ed25519_sig;
|
||||||
|
|
||||||
/* Security Key specific additions */
|
|
||||||
uint8_t sk_flags;
|
|
||||||
uint32_t sk_counter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ssh_signature_struct *ssh_signature;
|
typedef struct ssh_signature_struct *ssh_signature;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SSH Key Functions */
|
/* SSH Key Functions */
|
||||||
|
ssh_key ssh_key_dup(const ssh_key key);
|
||||||
void ssh_key_clean (ssh_key key);
|
void ssh_key_clean (ssh_key key);
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ssh_key_get_signature_algorithm(ssh_session session,
|
ssh_key_get_signature_algorithm(ssh_session session,
|
||||||
enum ssh_keytypes_e type);
|
enum ssh_keytypes_e type);
|
||||||
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
|
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
|
||||||
enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type);
|
|
||||||
enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
|
|
||||||
enum ssh_keytypes_e type);
|
|
||||||
enum ssh_digest_e ssh_key_hash_from_name(const char *name);
|
|
||||||
|
|
||||||
#define is_ecdsa_key_type(t) \
|
|
||||||
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
|
|
||||||
|
|
||||||
#define is_cert_type(kt)\
|
|
||||||
((kt) == SSH_KEYTYPE_DSS_CERT01 ||\
|
|
||||||
(kt) == SSH_KEYTYPE_RSA_CERT01 ||\
|
|
||||||
(kt) == SSH_KEYTYPE_SK_ECDSA_CERT01 ||\
|
|
||||||
(kt) == SSH_KEYTYPE_SK_ED25519_CERT01 ||\
|
|
||||||
((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
|
|
||||||
(kt) <= SSH_KEYTYPE_ED25519_CERT01))
|
|
||||||
|
|
||||||
/* SSH Signature Functions */
|
/* SSH Signature Functions */
|
||||||
ssh_signature ssh_signature_new(void);
|
ssh_signature ssh_signature_new(void);
|
||||||
void ssh_signature_free(ssh_signature sign);
|
void ssh_signature_free(ssh_signature sign);
|
||||||
#define SSH_SIGNATURE_FREE(x) \
|
|
||||||
do { ssh_signature_free(x); x = NULL; } while(0)
|
|
||||||
|
|
||||||
int ssh_pki_export_signature_blob(const ssh_signature sign,
|
int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||||
ssh_string *sign_blob);
|
ssh_string *sign_blob);
|
||||||
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||||
const ssh_key pubkey,
|
const ssh_key pubkey,
|
||||||
ssh_signature *psig);
|
ssh_signature *psig);
|
||||||
int ssh_pki_signature_verify(ssh_session session,
|
int ssh_pki_signature_verify_blob(ssh_session session,
|
||||||
ssh_signature sig,
|
ssh_string sig_blob,
|
||||||
const ssh_key key,
|
const ssh_key key,
|
||||||
const unsigned char *digest,
|
unsigned char *digest,
|
||||||
size_t dlen);
|
size_t dlen);
|
||||||
|
|
||||||
/* SSH Public Key Functions */
|
/* SSH Public Key Functions */
|
||||||
int ssh_pki_export_pubkey_blob(const ssh_key key,
|
int ssh_pki_export_pubkey_blob(const ssh_key key,
|
||||||
@@ -174,32 +128,16 @@ int ssh_pki_import_cert_blob(const ssh_string cert_blob,
|
|||||||
|
|
||||||
/* SSH Signing Functions */
|
/* SSH Signing Functions */
|
||||||
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
|
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
|
||||||
const ssh_key privatekey, enum ssh_digest_e hash_type);
|
const ssh_key privatekey);
|
||||||
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||||
struct ssh_buffer_struct *buf,
|
struct ssh_buffer_struct *buf,
|
||||||
const ssh_key pubkey);
|
const ssh_key pubkey);
|
||||||
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||||
const ssh_key privkey,
|
const ssh_key privkey);
|
||||||
const enum ssh_digest_e digest);
|
|
||||||
|
|
||||||
/* Temporary functions, to be removed after migration to ssh_key */
|
/* Temporary functions, to be removed after migration to ssh_key */
|
||||||
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);
|
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);
|
||||||
ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key);
|
ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key);
|
||||||
|
|
||||||
int ssh_key_algorithm_allowed(ssh_session session, const char *type);
|
int ssh_key_algorithm_allowed(ssh_session session, const char *type);
|
||||||
bool ssh_key_size_allowed(ssh_session session, ssh_key key);
|
|
||||||
|
|
||||||
/* Return the key size in bits */
|
|
||||||
int ssh_key_size(ssh_key key);
|
|
||||||
|
|
||||||
/* PKCS11 URI function to check if filename is a path or a PKCS11 URI */
|
|
||||||
#ifdef WITH_PKCS11_URI
|
|
||||||
bool ssh_pki_is_uri(const char *filename);
|
|
||||||
char *ssh_pki_export_pub_uri_from_priv_uri(const char *priv_uri);
|
|
||||||
#endif /* WITH_PKCS11_URI */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PKI_H_ */
|
#endif /* PKI_H_ */
|
||||||
|
|||||||
@@ -23,10 +23,6 @@
|
|||||||
|
|
||||||
#include "libssh/pki.h"
|
#include "libssh/pki.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* defined in bcrypt_pbkdf.c */
|
/* defined in bcrypt_pbkdf.c */
|
||||||
int bcrypt_pbkdf(const char *pass,
|
int bcrypt_pbkdf(const char *pass,
|
||||||
size_t passlen,
|
size_t passlen,
|
||||||
@@ -47,14 +43,6 @@ int bcrypt_pbkdf(const char *pass,
|
|||||||
/* Magic defined in OpenSSH/PROTOCOL.key */
|
/* Magic defined in OpenSSH/PROTOCOL.key */
|
||||||
#define OPENSSH_AUTH_MAGIC "openssh-key-v1"
|
#define OPENSSH_AUTH_MAGIC "openssh-key-v1"
|
||||||
|
|
||||||
/* Determine type of ssh key. */
|
|
||||||
enum ssh_key_e {
|
|
||||||
SSH_KEY_PUBLIC = 0,
|
|
||||||
SSH_KEY_PRIVATE
|
|
||||||
};
|
|
||||||
|
|
||||||
void pki_key_clean(ssh_key key);
|
|
||||||
|
|
||||||
int pki_key_ecdsa_nid_from_name(const char *name);
|
int pki_key_ecdsa_nid_from_name(const char *name);
|
||||||
const char *pki_key_ecdsa_nid_to_name(int nid);
|
const char *pki_key_ecdsa_nid_to_name(int nid);
|
||||||
const char *ssh_key_signature_to_char(enum ssh_keytypes_e type,
|
const char *ssh_key_signature_to_char(enum ssh_keytypes_e type,
|
||||||
@@ -73,8 +61,6 @@ int pki_key_compare(const ssh_key k1,
|
|||||||
const ssh_key k2,
|
const ssh_key k2,
|
||||||
enum ssh_keycmp_e what);
|
enum ssh_keycmp_e what);
|
||||||
|
|
||||||
int pki_key_check_hash_compatible(ssh_key key,
|
|
||||||
enum ssh_digest_e hash_type);
|
|
||||||
/* SSH Private Key Functions */
|
/* SSH Private Key Functions */
|
||||||
enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey);
|
enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey);
|
||||||
ssh_key pki_private_key_from_base64(const char *b64_key,
|
ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||||
@@ -123,29 +109,30 @@ int pki_privkey_build_ecdsa(ssh_key key,
|
|||||||
ssh_string pki_publickey_to_blob(const ssh_key key);
|
ssh_string pki_publickey_to_blob(const ssh_key key);
|
||||||
|
|
||||||
/* SSH Signature Functions */
|
/* SSH Signature Functions */
|
||||||
ssh_signature pki_sign_data(const ssh_key privkey,
|
|
||||||
enum ssh_digest_e hash_type,
|
|
||||||
const unsigned char *input,
|
|
||||||
size_t input_len);
|
|
||||||
int pki_verify_data_signature(ssh_signature signature,
|
|
||||||
const ssh_key pubkey,
|
|
||||||
const unsigned char *input,
|
|
||||||
size_t input_len);
|
|
||||||
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
||||||
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||||
const ssh_string sig_blob,
|
const ssh_string sig_blob,
|
||||||
enum ssh_keytypes_e type,
|
enum ssh_keytypes_e type,
|
||||||
enum ssh_digest_e hash_type);
|
enum ssh_digest_e hash_type);
|
||||||
|
int pki_signature_verify(ssh_session session,
|
||||||
|
const ssh_signature sig,
|
||||||
|
const ssh_key key,
|
||||||
|
const unsigned char *hash,
|
||||||
|
size_t hlen);
|
||||||
|
|
||||||
/* SSH Signing Functions */
|
/* SSH Signing Functions */
|
||||||
ssh_signature pki_do_sign(const ssh_key privkey,
|
#define pki_do_sign(key, hash, hlen) \
|
||||||
const unsigned char *input,
|
pki_do_sign_hash(key, hash, hlen, SSH_DIGEST_AUTO)
|
||||||
size_t input_len,
|
|
||||||
enum ssh_digest_e hash_type);
|
|
||||||
ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
||||||
const unsigned char *hash,
|
const unsigned char *hash,
|
||||||
size_t hlen,
|
size_t hlen,
|
||||||
enum ssh_digest_e hash_type);
|
enum ssh_digest_e hash_type);
|
||||||
|
#define pki_do_sign_sessionid(key, hash, hlen) \
|
||||||
|
pki_do_sign_sessionid_hash(key, hash, hlen, SSH_DIGEST_AUTO)
|
||||||
|
ssh_signature pki_do_sign_sessionid_hash(const ssh_key key,
|
||||||
|
const unsigned char *hash,
|
||||||
|
size_t hlen,
|
||||||
|
enum ssh_digest_e hash_type);
|
||||||
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
|
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
|
||||||
const unsigned char *hash, size_t hlen);
|
const unsigned char *hash, size_t hlen);
|
||||||
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
|
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
|
||||||
@@ -153,10 +140,10 @@ int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
|
|||||||
int pki_ed25519_key_cmp(const ssh_key k1,
|
int pki_ed25519_key_cmp(const ssh_key k1,
|
||||||
const ssh_key k2,
|
const ssh_key k2,
|
||||||
enum ssh_keycmp_e what);
|
enum ssh_keycmp_e what);
|
||||||
int pki_ed25519_key_dup(ssh_key new_key, const ssh_key key);
|
int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
|
||||||
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
|
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
|
||||||
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig);
|
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
|
||||||
int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob);
|
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
|
||||||
int pki_privkey_build_ed25519(ssh_key key,
|
int pki_privkey_build_ed25519(ssh_key key,
|
||||||
ssh_string pubkey,
|
ssh_string pubkey,
|
||||||
ssh_string privkey);
|
ssh_string privkey);
|
||||||
@@ -168,14 +155,4 @@ ssh_key ssh_pki_openssh_privkey_import(const char *text_key,
|
|||||||
ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
|
ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
|
||||||
const char *passphrase, ssh_auth_callback auth_fn, void *auth_data);
|
const char *passphrase, ssh_auth_callback auth_fn, void *auth_data);
|
||||||
|
|
||||||
#ifdef WITH_PKCS11_URI
|
|
||||||
/* URI Function */
|
|
||||||
int pki_uri_import(const char *uri_name, ssh_key *key, enum ssh_key_e key_type);
|
|
||||||
#endif /* WITH_PKCS11_URI */
|
|
||||||
|
|
||||||
bool ssh_key_size_allowed_rsa(int min_size, ssh_key key);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PKI_PRIV_H_ */
|
#endif /* PKI_PRIV_H_ */
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user