mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 20:30:38 +09:00
Compare commits
615 Commits
v0-2
...
release-0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
232aca8969 | ||
|
|
48deb0ca46 | ||
|
|
59889da5a5 | ||
|
|
a958f6498b | ||
|
|
3ec11b46e9 | ||
|
|
c17ce2697b | ||
|
|
7fa1804cf1 | ||
|
|
ad86a378d9 | ||
|
|
ed660c29c3 | ||
|
|
6f47401173 | ||
|
|
d247b86202 | ||
|
|
a1c7dd99be | ||
|
|
11a6ed907d | ||
|
|
a8ce546f69 | ||
|
|
6e56d1dfb2 | ||
|
|
b07ec7a3d1 | ||
|
|
09d4029ac1 | ||
|
|
b62d0732d2 | ||
|
|
90a6d431a7 | ||
|
|
f7448eeb1c | ||
|
|
d411260a68 | ||
|
|
f8f0663eb9 | ||
|
|
cedc635ed0 | ||
|
|
ff819489b7 | ||
|
|
37dc2a5279 | ||
|
|
50ebbe636e | ||
|
|
101bf21d41 | ||
|
|
ae3bb42da5 | ||
|
|
918a912cd5 | ||
|
|
7ba81b974e | ||
|
|
b5e868fb8b | ||
|
|
693c041ba9 | ||
|
|
39c7e3c7dd | ||
|
|
3873489688 | ||
|
|
d14a492019 | ||
|
|
848984f25f | ||
|
|
5a755a8219 | ||
|
|
910689126a | ||
|
|
87995db8fe | ||
|
|
70c9da4fb0 | ||
|
|
1ac654ec6c | ||
|
|
fecbdff179 | ||
|
|
894b73abe2 | ||
|
|
da4986e4bc | ||
|
|
08ab186471 | ||
|
|
439d995fed | ||
|
|
2e0b2e2e91 | ||
|
|
80ba62a519 | ||
|
|
a065e35e37 | ||
|
|
2eaf69ee06 | ||
|
|
a15a28e698 | ||
|
|
646a5a2cfc | ||
|
|
9196be1a42 | ||
|
|
1657d0932f | ||
|
|
f0432cc24f | ||
|
|
d008e5aeb8 | ||
|
|
2934765c76 | ||
|
|
f29e119c25 | ||
|
|
126dcd51e5 | ||
|
|
249e11bd2e | ||
|
|
cea0ac4455 | ||
|
|
ae81c4124e | ||
|
|
d75b53805d | ||
|
|
bc0491c098 | ||
|
|
1fd0237ddb | ||
|
|
69af190acb | ||
|
|
c7806a6a16 | ||
|
|
fdc1073e8a | ||
|
|
fb559c6ffd | ||
|
|
f7d2040d5a | ||
|
|
2e5f1c8955 | ||
|
|
184b711a04 | ||
|
|
5708fe1729 | ||
|
|
cc2df5487a | ||
|
|
fc50facaa3 | ||
|
|
8f8e9a2f50 | ||
|
|
ec714ea67d | ||
|
|
de138cd055 | ||
|
|
65331f470a | ||
|
|
d6e23b7628 | ||
|
|
f9baa6552c | ||
|
|
4bf12aaf56 | ||
|
|
7568e42f4e | ||
|
|
83b26b97b5 | ||
|
|
ce1a5d7578 | ||
|
|
57b7e73394 | ||
|
|
33a640e348 | ||
|
|
03c40ac79f | ||
|
|
53a24a4f78 | ||
|
|
8af13665ab | ||
|
|
4838742a8e | ||
|
|
8c45767d34 | ||
|
|
1d78b6d00e | ||
|
|
4c78793961 | ||
|
|
5c934d0970 | ||
|
|
1a280d859d | ||
|
|
dc07d46cca | ||
|
|
6c51183f0e | ||
|
|
61ebfcfa5c | ||
|
|
ff60d8ce22 | ||
|
|
c4169e3c41 | ||
|
|
0b7ae624a3 | ||
|
|
d9a0b90701 | ||
|
|
503bc1b95f | ||
|
|
cd71590fe0 | ||
|
|
1afe6b13c5 | ||
|
|
0d17b6778b | ||
|
|
43d881ba28 | ||
|
|
3d9fbe8eea | ||
|
|
152da07023 | ||
|
|
dda7808851 | ||
|
|
f40ae74f51 | ||
|
|
5b547812eb | ||
|
|
8060f51ec7 | ||
|
|
0e6359c63d | ||
|
|
3e1ed1707c | ||
|
|
2688c1a1d5 | ||
|
|
a08c56baf4 | ||
|
|
137669db3f | ||
|
|
98fbe3020d | ||
|
|
9345ba7030 | ||
|
|
17c146391c | ||
|
|
b27e5b6785 | ||
|
|
9827cac475 | ||
|
|
b23c68264d | ||
|
|
095775ef1b | ||
|
|
c98fce8596 | ||
|
|
e97275c7bc | ||
|
|
783825254a | ||
|
|
e7fc9ab369 | ||
|
|
2b705786c0 | ||
|
|
e46d2d024c | ||
|
|
06eceb3204 | ||
|
|
a7732ebbe5 | ||
|
|
6538121494 | ||
|
|
0534fee674 | ||
|
|
c31893d246 | ||
|
|
f0b14c7b7a | ||
|
|
0b4159d1ec | ||
|
|
015b1649b1 | ||
|
|
5b1c21593c | ||
|
|
2ed97906e3 | ||
|
|
deb9d30f4d | ||
|
|
65d09f3268 | ||
|
|
0881ba13d6 | ||
|
|
83971c0188 | ||
|
|
cc6199d9f0 | ||
|
|
e8f783eb36 | ||
|
|
a1802f1c32 | ||
|
|
d680160500 | ||
|
|
2317a58996 | ||
|
|
567cc5984a | ||
|
|
06a0dea2ad | ||
|
|
982045bb96 | ||
|
|
c3ee07d747 | ||
|
|
fa63c0adee | ||
|
|
78ad279a43 | ||
|
|
e13c2871ff | ||
|
|
f119a27bb6 | ||
|
|
23a55a0a0a | ||
|
|
1cdc7c6e43 | ||
|
|
5c662f6f6b | ||
|
|
afeaea318c | ||
|
|
29035f952c | ||
|
|
3024e3652f | ||
|
|
5fdcd4df7b | ||
|
|
634a2d20b8 | ||
|
|
75fb96f740 | ||
|
|
907b4075c0 | ||
|
|
ddd1d62429 | ||
|
|
84629a394e | ||
|
|
c26fb22122 | ||
|
|
4cc2acda3a | ||
|
|
2c75ad7e19 | ||
|
|
9f7d4d2d60 | ||
|
|
511213872b | ||
|
|
8dbe59efde | ||
|
|
b39fcd6470 | ||
|
|
a19aebba18 | ||
|
|
b1e62ad22b | ||
|
|
9d270f99a7 | ||
|
|
315e5aca84 | ||
|
|
bf312c50a9 | ||
|
|
52d20beb73 | ||
|
|
f11630ab68 | ||
|
|
f32e307899 | ||
|
|
83142315da | ||
|
|
db79fff00d | ||
|
|
5d23142599 | ||
|
|
1f6341f549 | ||
|
|
72aeba410f | ||
|
|
c1c4f299ff | ||
|
|
99946c7bcc | ||
|
|
0eedebd84a | ||
|
|
c1cd3b2974 | ||
|
|
2b4efa171e | ||
|
|
367f4b999a | ||
|
|
75c3996a49 | ||
|
|
320c70a170 | ||
|
|
387f6473f7 | ||
|
|
4d80a1559a | ||
|
|
fd79249df6 | ||
|
|
50616076c7 | ||
|
|
4a383ab3cf | ||
|
|
cefe239958 | ||
|
|
29e6f140fa | ||
|
|
b0778ca169 | ||
|
|
ac724eb3fb | ||
|
|
8ba57619fd | ||
|
|
10ddf310a6 | ||
|
|
5a84af65fa | ||
|
|
5d689c2d29 | ||
|
|
baee8c17b5 | ||
|
|
441929f8b8 | ||
|
|
75da135324 | ||
|
|
7592d9f42c | ||
|
|
62ac83a8ea | ||
|
|
4ad9235805 | ||
|
|
fbc6543c83 | ||
|
|
cedc9d71c3 | ||
|
|
39f8c7faab | ||
|
|
8fecf4d74c | ||
|
|
b5bda67235 | ||
|
|
d62a43ee9d | ||
|
|
56e13b227f | ||
|
|
a0b4b239fb | ||
|
|
4816afc9e8 | ||
|
|
5be3a3c066 | ||
|
|
75eddb1ebb | ||
|
|
45d8248efb | ||
|
|
47ff8d4679 | ||
|
|
0f075f4d95 | ||
|
|
57a5c50a54 | ||
|
|
e99966772e | ||
|
|
8a3c417e14 | ||
|
|
e6c0155567 | ||
|
|
ea59faaec9 | ||
|
|
6402559f28 | ||
|
|
9766b2f8d2 | ||
|
|
b875ce15e8 | ||
|
|
f59630cbbc | ||
|
|
afe0c8b2b5 | ||
|
|
e067061263 | ||
|
|
9001a34cd3 | ||
|
|
2f51befc0f | ||
|
|
03edd0ebb1 | ||
|
|
9704df65e3 | ||
|
|
a3c820cf94 | ||
|
|
e6474a34c3 | ||
|
|
b7f93a4779 | ||
|
|
cc92391034 | ||
|
|
a1e154e9d5 | ||
|
|
bfc428a0da | ||
|
|
44924db3e9 | ||
|
|
ab8523a391 | ||
|
|
460969a9ce | ||
|
|
5ef5841f99 | ||
|
|
163fbfa44d | ||
|
|
479744b146 | ||
|
|
a58b7b93de | ||
|
|
c373e9bb03 | ||
|
|
db2ff03392 | ||
|
|
dc5ef34b54 | ||
|
|
f402e8d113 | ||
|
|
ff73826b45 | ||
|
|
95cd02c000 | ||
|
|
263b8d4f9c | ||
|
|
d20ae18b00 | ||
|
|
fa01372c88 | ||
|
|
9dab7771fa | ||
|
|
038e6411da | ||
|
|
4308bb559c | ||
|
|
3df5a0dabe | ||
|
|
192657d88c | ||
|
|
57a6388b82 | ||
|
|
b9e91ce95a | ||
|
|
e4c521d896 | ||
|
|
70b422d0fb | ||
|
|
91afe0de8a | ||
|
|
e85b16ae49 | ||
|
|
a925c266ca | ||
|
|
c48d04b2c7 | ||
|
|
44ab293f0b | ||
|
|
bf4d29b963 | ||
|
|
25e80032ba | ||
|
|
7e3307cb44 | ||
|
|
cf8e444764 | ||
|
|
109c10bdfd | ||
|
|
3216520b4c | ||
|
|
09fdf0e8e6 | ||
|
|
845615cdd8 | ||
|
|
32fd37d1ad | ||
|
|
42bdb90751 | ||
|
|
2ed09734eb | ||
|
|
b15a04e463 | ||
|
|
2b12ffc820 | ||
|
|
55d42b9c53 | ||
|
|
07506763ff | ||
|
|
55791d1fe6 | ||
|
|
a2cce56134 | ||
|
|
59f04bfddd | ||
|
|
5b2586312a | ||
|
|
ac38bbc138 | ||
|
|
a092a84139 | ||
|
|
c6eb54c39e | ||
|
|
e8a9cb25fe | ||
|
|
08fcbdc97a | ||
|
|
841de3439d | ||
|
|
1a22d18afa | ||
|
|
baf2eaf165 | ||
|
|
ece047171a | ||
|
|
5dc03728ed | ||
|
|
50b701b4e4 | ||
|
|
b246356ab5 | ||
|
|
8f150afeeb | ||
|
|
74a06555f6 | ||
|
|
94021dcdb5 | ||
|
|
1ed7c90890 | ||
|
|
24fc1b2028 | ||
|
|
c608883205 | ||
|
|
c8269682fc | ||
|
|
2bbb005980 | ||
|
|
a565f255f0 | ||
|
|
10dedee3ef | ||
|
|
1ac6f38032 | ||
|
|
ea729492ec | ||
|
|
160f6a08d0 | ||
|
|
1f1e9dc15b | ||
|
|
4ca14e442c | ||
|
|
367fd0cb35 | ||
|
|
c50da458d1 | ||
|
|
576187c686 | ||
|
|
af454c0f34 | ||
|
|
317e90c1c1 | ||
|
|
8e34f0cf0c | ||
|
|
16084e548e | ||
|
|
118d4ee131 | ||
|
|
c847e13c47 | ||
|
|
7f06a999e3 | ||
|
|
cd5588aa75 | ||
|
|
f6e3f1d985 | ||
|
|
7eeb47ffad | ||
|
|
d36a208849 | ||
|
|
fc1cba4407 | ||
|
|
f2788c9866 | ||
|
|
e29ef25cdd | ||
|
|
639e924ef5 | ||
|
|
4174577db3 | ||
|
|
6ec84bfc2e | ||
|
|
13dcfa6bfc | ||
|
|
02ebbfdeca | ||
|
|
749e95cbf1 | ||
|
|
68710f3967 | ||
|
|
22b3122c6c | ||
|
|
640cf4cc93 | ||
|
|
e0ae9635ea | ||
|
|
e4624d6ed7 | ||
|
|
c841e984ba | ||
|
|
234844230c | ||
|
|
a7b70bc9ee | ||
|
|
2a118371fa | ||
|
|
e954d54215 | ||
|
|
3ad76af469 | ||
|
|
926375e8aa | ||
|
|
a8bb3024e8 | ||
|
|
38d8875021 | ||
|
|
e5b7e8fdfc | ||
|
|
3fab89b22f | ||
|
|
61bee4c60c | ||
|
|
04ab5c1b82 | ||
|
|
e9a7d98eac | ||
|
|
1715736f0f | ||
|
|
38176a753e | ||
|
|
89aac630ee | ||
|
|
abf9ccdc5c | ||
|
|
40ddc76e62 | ||
|
|
8333393470 | ||
|
|
89670904c0 | ||
|
|
29c57bab33 | ||
|
|
da1eee8c89 | ||
|
|
8948bf41f1 | ||
|
|
befca1dc8a | ||
|
|
83f481981d | ||
|
|
4f6fd0c451 | ||
|
|
faa83b2380 | ||
|
|
38d86e7e17 | ||
|
|
c4f65cb5dd | ||
|
|
586ed9103f | ||
|
|
d51dc0d80e | ||
|
|
efc3c494cc | ||
|
|
8c05aab03d | ||
|
|
323ee63a1d | ||
|
|
1e52650dbf | ||
|
|
7c6f1be5ea | ||
|
|
f84585ea2f | ||
|
|
aea8587586 | ||
|
|
8d3a43db7a | ||
|
|
7059e05a2a | ||
|
|
fe2bc30984 | ||
|
|
d1fefb4de3 | ||
|
|
cd3dd624b3 | ||
|
|
8d6d96657a | ||
|
|
6c6094538f | ||
|
|
db4ff30f38 | ||
|
|
8253e2170e | ||
|
|
2aeeb5a518 | ||
|
|
c8265940ea | ||
|
|
6492e3e69c | ||
|
|
081e81b813 | ||
|
|
688ac9382f | ||
|
|
1dc12b9cc5 | ||
|
|
01e789184a | ||
|
|
58fd38cd90 | ||
|
|
f8ef75c510 | ||
|
|
b7c65baef3 | ||
|
|
139eb4696c | ||
|
|
ef1a41efcf | ||
|
|
dbab7b5a18 | ||
|
|
b239fda60c | ||
|
|
f286e8c9b0 | ||
|
|
f7959bd5eb | ||
|
|
226e48b4b7 | ||
|
|
a7fbedf8d6 | ||
|
|
b3a0c6d9cb | ||
|
|
1100a22e98 | ||
|
|
18bce1e209 | ||
|
|
30d1bf863e | ||
|
|
0e82ddbd81 | ||
|
|
b5eb33bb69 | ||
|
|
2791ce7e01 | ||
|
|
8485c87cf2 | ||
|
|
5a75c0fd78 | ||
|
|
41dd2a2a3b | ||
|
|
2aa81c0544 | ||
|
|
0856ba3008 | ||
|
|
8d66a455f7 | ||
|
|
a4d98b58fc | ||
|
|
497c31d9a0 | ||
|
|
4db7fc77ff | ||
|
|
3b7940d05e | ||
|
|
2afc8a4f1c | ||
|
|
da65ee4dbb | ||
|
|
0dee533531 | ||
|
|
396db49a41 | ||
|
|
94e91b73f7 | ||
|
|
115450ac9b | ||
|
|
eb461d1dbe | ||
|
|
cfea89fb7c | ||
|
|
5309651849 | ||
|
|
30b02325cb | ||
|
|
1fceffa434 | ||
|
|
3f4c1976fd | ||
|
|
a459a8b4db | ||
|
|
4d203e8420 | ||
|
|
5ba2acde0a | ||
|
|
9ea6ea581d | ||
|
|
4373fc64e3 | ||
|
|
b6fbe97f24 | ||
|
|
d86ac9e04b | ||
|
|
71913c8fea | ||
|
|
8de3dc44ca | ||
|
|
ab54736b5d | ||
|
|
6026de4648 | ||
|
|
a9ef024f10 | ||
|
|
595a5d9ff2 | ||
|
|
356a8a7631 | ||
|
|
9f581a2809 | ||
|
|
d60783eeb7 | ||
|
|
ae4265d304 | ||
|
|
ee3b641fb1 | ||
|
|
c195e0fa7d | ||
|
|
f8d5bb9785 | ||
|
|
3a67aaa428 | ||
|
|
4c84a3e0f2 | ||
|
|
ff0f8b7608 | ||
|
|
9ff4afa523 | ||
|
|
10397d44db | ||
|
|
fc73b0b33f | ||
|
|
7b464d4e15 | ||
|
|
891539af6c | ||
|
|
1b627b3867 | ||
|
|
b06c167775 | ||
|
|
ace6eed6c0 | ||
|
|
cde3151634 | ||
|
|
cd4df00dff | ||
|
|
b2e50e8967 | ||
|
|
2c3e423480 | ||
|
|
8bcd65193c | ||
|
|
54ce86e3b1 | ||
|
|
904a5b2f7c | ||
|
|
ddd10236bd | ||
|
|
b4c65e41f6 | ||
|
|
79e9eb53d4 | ||
|
|
10afd9818c | ||
|
|
186667724a | ||
|
|
f80efcc260 | ||
|
|
2634f45e11 | ||
|
|
98f78e1102 | ||
|
|
8758b1260b | ||
|
|
04d916f3aa | ||
|
|
15d0dc7a4e | ||
|
|
ae4ef84702 | ||
|
|
1fd7a875be | ||
|
|
07d748ef5e | ||
|
|
3441e77ddc | ||
|
|
84430b2277 | ||
|
|
4ab28a049f | ||
|
|
3090d104cf | ||
|
|
75d5bb457f | ||
|
|
6aff00e762 | ||
|
|
2b07dcd1e3 | ||
|
|
affe522b25 | ||
|
|
f16cabc73e | ||
|
|
39a5b53eb5 | ||
|
|
fc8ad69f5c | ||
|
|
78b6e25ede | ||
|
|
e02a6e0225 | ||
|
|
fce4840c77 | ||
|
|
117fc43b69 | ||
|
|
01c0877495 | ||
|
|
33b948cab9 | ||
|
|
d3d7f08d6a | ||
|
|
3b38c66b3d | ||
|
|
390d9e53dc | ||
|
|
fae68cac8a | ||
|
|
cf89b6eb48 | ||
|
|
9249006e64 | ||
|
|
c9818a9948 | ||
|
|
e4d16db116 | ||
|
|
98711e9d0f | ||
|
|
6bda3c7466 | ||
|
|
139f59ec62 | ||
|
|
2ab6894132 | ||
|
|
63cff85b1a | ||
|
|
0151b6e170 | ||
|
|
ee54acb417 | ||
|
|
08e2408896 | ||
|
|
453b91903b | ||
|
|
5681c542f6 | ||
|
|
fe5f283c48 | ||
|
|
05495a263a | ||
|
|
40bce93e97 | ||
|
|
4d889e0af0 | ||
|
|
49c88c2cd7 | ||
|
|
1d3eeda7f9 | ||
|
|
fe98c015e9 | ||
|
|
d347b7e00f | ||
|
|
f99fefc587 | ||
|
|
eced7fb958 | ||
|
|
1486d844e7 | ||
|
|
78273fe5c5 | ||
|
|
3247a7683a | ||
|
|
39a8009e78 | ||
|
|
081adeb3d6 | ||
|
|
1edc164265 | ||
|
|
acb4e37957 | ||
|
|
02f2511985 | ||
|
|
a800db80e4 | ||
|
|
ec0c1ef63b | ||
|
|
b4cebfb03d | ||
|
|
461d9413d3 | ||
|
|
cf1e7fa836 | ||
|
|
14580705d5 | ||
|
|
6ab119d8dc | ||
|
|
f0b2c39d2f | ||
|
|
814cde9069 | ||
|
|
851560426f | ||
|
|
facc434ce4 | ||
|
|
4b8eb38586 | ||
|
|
d3e64a744e | ||
|
|
fad349fecd | ||
|
|
e1a1796783 | ||
|
|
b9e6ce934d | ||
|
|
5ea8088938 | ||
|
|
7ceaf5c43a | ||
|
|
f4bbc45bbe | ||
|
|
ff19095415 | ||
|
|
b8c78bdb5a | ||
|
|
73cde232be | ||
|
|
53226f98f2 | ||
|
|
22b422995f | ||
|
|
ac3d66ac69 | ||
|
|
903e22cd11 | ||
|
|
0679dd4fd8 | ||
|
|
8eaecdc7b8 | ||
|
|
cfbc063dd3 | ||
|
|
81de36e923 | ||
|
|
a80ad5cbd3 | ||
|
|
69a1fac7a1 | ||
|
|
1fd6a2e9e0 | ||
|
|
9414b53bef | ||
|
|
5f58fc773c | ||
|
|
3991b3a3aa | ||
|
|
58404116bc | ||
|
|
8c60d864c7 | ||
|
|
974a160fd3 | ||
|
|
5e03a95a93 | ||
|
|
5db7ec356b | ||
|
|
5d798f6225 | ||
|
|
7250e03f97 | ||
|
|
948c3f1bef | ||
|
|
55c7cc6839 | ||
|
|
ddf4a8e9c9 | ||
|
|
f4d74e285e | ||
|
|
fc0928a572 | ||
|
|
ed53a70854 | ||
|
|
460d0b402b | ||
|
|
2347065481 | ||
|
|
4259c9195c | ||
|
|
70aa33c041 | ||
|
|
944084964a | ||
|
|
f9f8ded7f0 | ||
|
|
6ea3888054 | ||
|
|
b11ddd23b2 | ||
|
|
c3e026c303 |
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.*
|
||||
*.swp
|
||||
*~$
|
||||
build
|
||||
cscope.*
|
||||
tags
|
||||
4
AUTHORS
4
AUTHORS
@@ -1,5 +1,7 @@
|
||||
Author(s):
|
||||
Aris Adamantiadis <aris (at) 0xbadc0de (dot) be> (project initiator)
|
||||
Aris Adamantiadis <aris@0xbadc0de.be> (project initiator)
|
||||
|
||||
Andreas Schneider <mail@cynapses.org> (developer)
|
||||
|
||||
Nick Zitzmann <seiryu (at) comcast (dot) net> (mostly client SFTP stuff)
|
||||
|
||||
|
||||
70
CMakeLists.txt
Normal file
70
CMakeLists.txt
Normal file
@@ -0,0 +1,70 @@
|
||||
project(libssh C)
|
||||
|
||||
# Required cmake version
|
||||
cmake_minimum_required(VERSION 2.6.0)
|
||||
|
||||
# global needed variables
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
|
||||
set(APPLICATION_VERSION "0.3.2")
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "3")
|
||||
set(APPLICATION_VERSION_PATCH "2")
|
||||
|
||||
set(LIBRARY_VERSION "3.2.0")
|
||||
set(LIBRARY_SOVERSION "3")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
set(CMAKE_MODULE_PATH
|
||||
${CMAKE_SOURCE_DIR}/cmake/Modules
|
||||
)
|
||||
|
||||
# add definitions
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
include(DefineInstallationPaths)
|
||||
include(DefineOptions.cmake)
|
||||
include(CPackConfig.cmake)
|
||||
|
||||
# disallow in-source build
|
||||
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.")
|
||||
|
||||
# add macros
|
||||
include(MacroAddPlugin)
|
||||
include(MacroCopyFile)
|
||||
|
||||
# search for libraries
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
find_package(OpenSSL)
|
||||
|
||||
if (NOT CRYPTO_FOUND)
|
||||
find_package(GCrypt)
|
||||
if (NOT GCRYPT_FOUND)
|
||||
message(FATAL_ERROR "Could not find OpenSSL or GCrypt")
|
||||
endif (NOT GCRYPT_FOUND)
|
||||
endif (NOT CRYPTO_FOUND)
|
||||
|
||||
# config.h checks
|
||||
include(ConfigureChecks.cmake)
|
||||
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
# check subdirectories
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(include)
|
||||
add_subdirectory(libssh)
|
||||
|
||||
# build samples
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
if (UNIX AND NOT WIN32)
|
||||
if (WITH_SFTP AND WITH_SERVER)
|
||||
add_executable(samplessh sample.c)
|
||||
add_executable(samplesshd samplesshd.c)
|
||||
|
||||
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY})
|
||||
endif (WITH_SFTP AND WITH_SERVER)
|
||||
endif (UNIX AND NOT WIN32)
|
||||
50
CPackConfig.cmake
Normal file
50
CPackConfig.cmake
Normal file
@@ -0,0 +1,50 @@
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# For help take a look at:
|
||||
# http://www.cmake.org/Wiki/CMake:CPackConfiguration
|
||||
|
||||
### general settings
|
||||
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH library")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README")
|
||||
set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
||||
|
||||
|
||||
### versions
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "2")
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
|
||||
### source generator
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
|
||||
### nsis generator
|
||||
set(CPACK_GENERATOR "NSIS")
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "libssh")
|
||||
|
||||
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME ${APPLICATION_NAME}-${CPACK_PACKAGE_VERSION})
|
||||
|
||||
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
|
||||
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers")
|
||||
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
|
||||
"Libraries used to build programs which use libssh")
|
||||
set(CPACK_COMPONENT_HEADERS_DESCRIPTION
|
||||
"C/C++ header files for use with libssh")
|
||||
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
|
||||
#set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime")
|
||||
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
|
||||
set(CPACK_COMPONENT_HEADERS_GROUP "Development")
|
||||
|
||||
include(CPack)
|
||||
207
ChangeLog
207
ChangeLog
@@ -1,80 +1,135 @@
|
||||
libssh-0.11-dev
|
||||
-server implementation development. I won't document it before it even works.
|
||||
-small bug corrected when connecting to sun ssh servers.
|
||||
-channel wierdness corrected (writing huge data packets)
|
||||
-channel_read_nonblocking added
|
||||
-channel bug where stderr wasn't correctly read fixed.
|
||||
-sftp_file_set_nonblocking added. It's now possible to have nonblocking SFTP IO
|
||||
-connect_status callback.
|
||||
-priv.h contains the internal functions, libssh.h the public interface
|
||||
-options_set_timeout (thx marcelo) really working.
|
||||
-tcp tunneling through channel_open_forward.
|
||||
-channel_request_exec()
|
||||
-channel_request_env()
|
||||
-ssh_get_pubkey_hash()
|
||||
-ssh_is_server_known()
|
||||
-ssh_write_known_host()
|
||||
-options_set_ssh_dir
|
||||
-how could this happen ! there weren't any channel_close !
|
||||
-nasty channel_free bug resolved.
|
||||
-removed the unsigned long all around the code. use only u8,u32 & u64.
|
||||
-it now compiles and runs under amd64 !
|
||||
-channel_request_pty_size
|
||||
-channel_change_pty_size
|
||||
-options_copy()
|
||||
-ported the doc to an HTML file.
|
||||
-small bugfix in packet.c
|
||||
-prefixed error constants with SSH_
|
||||
-sftp_stat, sftp_lstat, sftp_fstat. thanks Michel Bardiaux for the patch.
|
||||
-again channel number mismatch fixed.
|
||||
-fixed a bug in ssh_select making the select fail when a signal has been caught.
|
||||
-keyboard-interactive authentication working.
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
5th march 2004 : libssh-0.1
|
||||
-Begining of sftp subsystem implementation. It's stable enough to be used :)
|
||||
-some cleanup into channels implementation
|
||||
-Now every channel functions is called by its CHANNEL handler. no any way to play again with numbers.
|
||||
-added channel_poll() and channel_read(). Now, it's possible to manipulate channel streams only with channel_read() and channel_write(),
|
||||
with help of channel_poll().
|
||||
-changed the client so it uses the new channel_poll and channel_read interface
|
||||
-small use-after-free bug with channels resolved, and a noninitialised data of SIGNATURE struct.
|
||||
-changed stupidities in lot of function names.
|
||||
-removed a debug output file opened by default.
|
||||
-Added API.txt, the libssh programmer handbook. (I hate documentation)
|
||||
-Various bug fixes from Nick Zitzmann. Thank to him, libssh now runs under macosX !
|
||||
-Developed a cryptographic structure for handling protocols. Adding a custom-based cipher should be the story of thirty
|
||||
minutes. It now supports aes-256,aes-192,aes-128 and blowfish-128 !
|
||||
-An autoconf script which took me half of a day to set up. Respect it!
|
||||
-A ssh_select wrapper has been written.
|
||||
It all means the API has changed. not a lot but enough to be incompatible with anything which has been written.
|
||||
version 0.3.2 (released 2009-08-05)
|
||||
* Added ssh_init() function.
|
||||
* Added sftp_readlink() function.
|
||||
* Added sftp_symlink() function.
|
||||
* Fixed ssh_write_knownhost().
|
||||
* Fixed compilation on Solaris.
|
||||
* Fixed SSHv1 compilation.
|
||||
|
||||
10th october 2003 : libssh-0.0.4
|
||||
-some terminal code (eof handling) added
|
||||
-channels bugfix (it still needs some tweaking though)
|
||||
-zlib support
|
||||
-added a wrapper.c file. The goal is to provide a similar API to every cryptographic functions. bignums and sha/md5 are wrapped now.
|
||||
-more work than it first looks.
|
||||
-Support for other crypto libs planed (lighter libs)
|
||||
-Fixed stupid select() bug.
|
||||
-libssh now compiles and links with openssl 0.9.6 (but you're advised to upgrade)
|
||||
-RSA pubkey authentication code now works !
|
||||
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.
|
||||
|
||||
15th september 2003 : libssh-0.0.3
|
||||
-added install target in makefile
|
||||
-some cleanup in headers files and source code
|
||||
-change default banner and project name to libssh.
|
||||
-new file auth.c to support more and more authentication ways
|
||||
-bugfix(read offbyone) in send_kex
|
||||
-a base64 parser. don't read the source, it's awful. pure 0xbadc0de.
|
||||
-changed the client filename to "ssh". logic isn't it ?
|
||||
-dss publickey authentication ! still need to wait for the rsa one
|
||||
-bugfix in packet.c : now packet are completely read (and read blocks if waiting the packet)
|
||||
-new misc.c contains misc functions
|
||||
version 0.3 (released 2009-05-21)
|
||||
* Added support for ssh-agent authentication.
|
||||
* Added POSIX like sftp implementation.
|
||||
* Added error checking to all functions.
|
||||
* Added const to arguments where it was needed.
|
||||
* Added a channel_get_exit_status() function.
|
||||
* Added a channel_read_buffer() function, channel_read() is now
|
||||
a POSIX like function.
|
||||
* Added a more generic auth callback function.
|
||||
* Added printf attribute checking for log and error functions.
|
||||
* Added runtime function tracer support.
|
||||
* Added NSIS build support with CPack.
|
||||
* Added openssh hashed host support.
|
||||
* Added API documentation for all public functions.
|
||||
* Added asynchronous SFTP read function.
|
||||
* Added a ssh_bind_set_fd() function.
|
||||
* Fixed known_hosts parsing.
|
||||
* Fixed a lot of build warnings.
|
||||
* Fixed the Windows build.
|
||||
* Fixed a lot of memory leaks.
|
||||
* Fixed a double free corruption in the server support.
|
||||
* Fixed the "ssh_accept:" bug in server support.
|
||||
* Fixed important channel bugs.
|
||||
* Refactored the socket handling.
|
||||
* Switched to CMake build system.
|
||||
* Improved performance.
|
||||
|
||||
3rd september 2003: libssh-0.0.2
|
||||
initial release.
|
||||
-client supports both ssh and dss hostkey verification, but doesn't compare
|
||||
them to openssh's files. (~/.ssh/known_hosts)
|
||||
-the only supported authentication method is password.
|
||||
-compiles on linux and openbsd. freebsd and netbsd should work, too
|
||||
-Lot of work which hasn't been discussed here.
|
||||
version 0.2 (released 2007-11-29)
|
||||
* General cleanup
|
||||
* More comprehensive API
|
||||
* Up-to-date Doxygen documentation of each public function
|
||||
* Basic server-based support
|
||||
* Libgcrypt support (alternative to openssl and its license)
|
||||
* SSH1 support (disabled by default)
|
||||
* Added 3des-cbc
|
||||
* A lot of bugfixes
|
||||
|
||||
version 0.11-dev
|
||||
* Server implementation development.
|
||||
* Small bug corrected when connecting to sun ssh servers.
|
||||
* Channel wierdness corrected (writing huge data packets)
|
||||
* Channel_read_nonblocking added
|
||||
* Channel bug where stderr wasn't correctly read fixed.
|
||||
* Added sftp_file_set_nonblocking(), which is nonblocking SFTP IO
|
||||
* Connect_status callback.
|
||||
* Priv.h contains the internal functions, libssh.h the public interface
|
||||
* Options_set_timeout (thx marcelo) really working.
|
||||
* Tcp tunneling through channel_open_forward.
|
||||
* Channel_request_exec()
|
||||
* Channel_request_env()
|
||||
* Ssh_get_pubkey_hash()
|
||||
* Ssh_is_server_known()
|
||||
* Ssh_write_known_host()
|
||||
* Options_set_ssh_dir
|
||||
* How could this happen ! there weren't any channel_close !
|
||||
* Nasty channel_free bug resolved.
|
||||
* Removed the unsigned long all around the code. use only u8,u32 & u64.
|
||||
* It now compiles and runs under amd64 !
|
||||
* Channel_request_pty_size
|
||||
* Channel_change_pty_size
|
||||
* Options_copy()
|
||||
* Ported the doc to an HTML file.
|
||||
* Small bugfix in packet.c
|
||||
* Prefixed error constants with SSH_
|
||||
* Sftp_stat, sftp_lstat, sftp_fstat. thanks Michel Bardiaux for the patch.
|
||||
* Again channel number mismatch fixed.
|
||||
* Fixed a bug in ssh_select making the select fail when a signal has been
|
||||
caught.
|
||||
* Keyboard-interactive authentication working.
|
||||
|
||||
version 0.1 (released 2004-03-05)
|
||||
* Begining of sftp subsystem implementation.
|
||||
* Some cleanup into channels implementation
|
||||
* Now every channel functions is called by its CHANNEL handler.
|
||||
* Added channel_poll() and channel_read().
|
||||
* Changed the client so it uses the new channel_poll and channel_read interface
|
||||
* Small use-after-free bug with channels resolved
|
||||
* Changed stupidities in lot of function names.
|
||||
* Removed a debug output file opened by default.
|
||||
* Added API.txt, the libssh programmer handbook.
|
||||
* Various bug fixes from Nick Zitzmann.
|
||||
* Developed a cryptographic structure for handling protocols.
|
||||
* An autoconf script which took me half of a day to set up.
|
||||
* A ssh_select wrapper has been written.
|
||||
|
||||
version 0.0.4 (released 2003-10-10)
|
||||
* Some terminal code (eof handling) added
|
||||
* Channels bugfix (it still needs some tweaking though)
|
||||
* Zlib support
|
||||
* Added a wrapper.c file. The goal is to provide a similar API to every
|
||||
cryptographic functions. bignums and sha/md5 are wrapped now.
|
||||
* More work than it first looks.
|
||||
* Support for other crypto libs planed (lighter libs)
|
||||
* Fixed stupid select() bug.
|
||||
* Libssh now compiles and links with openssl 0.9.6
|
||||
* RSA pubkey authentication code now works !
|
||||
|
||||
version 0.0.3 (released 2003-09-15)
|
||||
* Added install target in makefile
|
||||
* Some cleanup in headers files and source code
|
||||
* Change default banner and project name to libssh.
|
||||
* New file auth.c to support more and more authentication ways
|
||||
* Bugfix(read offbyone) in send_kex
|
||||
* A base64 parser. don't read the source, it's awful. pure 0xbadc0de.
|
||||
* Changed the client filename to "ssh". logic isn't it ?
|
||||
* Dss publickey authentication ! still need to wait for the rsa one
|
||||
* Bugfix in packet.c
|
||||
* New misc.c contains misc functions
|
||||
|
||||
version 0.0.2 (released 2003-09-03)
|
||||
* Initial release.
|
||||
* Client supports both ssh and dss hostkey verification, but doesn't compare them to openssh's files. (~/.ssh/known_hosts)
|
||||
* The only supported authentication method is password.
|
||||
* Compiles on linux and openbsd. freebsd and netbsd should work, too
|
||||
* Lot of work which hasn't been discussed here.
|
||||
|
||||
56
ConfigureChecks.cmake
Normal file
56
ConfigureChecks.cmake
Normal file
@@ -0,0 +1,56 @@
|
||||
include(CheckIncludeFile)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckTypeSize)
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
set(PACKAGE ${APPLICATION_NAME})
|
||||
set(VERSION ${APPLICATION_VERSION})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
set(LIBDIR ${LIB_INSTALL_DIR})
|
||||
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
|
||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# HEADER FILES
|
||||
check_include_file(pty.h HAVE_PTY_H)
|
||||
check_include_file(terminos.h HAVE_TERMIOS_H)
|
||||
|
||||
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
|
||||
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
||||
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
|
||||
|
||||
# FUNCTIONS
|
||||
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
|
||||
if (WIN32)
|
||||
set(HAVE_GETADDRINFO TRUE)
|
||||
set(HAVE_GETHOSTBYNAME TRUE)
|
||||
set(HAVE_SELECT TRUE)
|
||||
else (WIN32)
|
||||
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
|
||||
check_function_exists(gethostbyname HAVE_GETHOSTBYNAME)
|
||||
check_function_exists(poll HAVE_POLL)
|
||||
check_function_exists(select HAVE_SELECT)
|
||||
endif (WIN32)
|
||||
|
||||
# LIBRARIES
|
||||
if (CRYPTO_FOUND)
|
||||
set(HAVE_LIBCRYPTO 1)
|
||||
endif (CRYPTO_FOUND)
|
||||
|
||||
if (GCRYPT_FOUND)
|
||||
set(HAVE_LIBGCRYPT 1)
|
||||
endif (GCRYPT_FOUND)
|
||||
|
||||
if (Z_LIBRARY)
|
||||
set(HAVE_LIBZ 1)
|
||||
endif (Z_LIBRARY)
|
||||
|
||||
# OPTIONS
|
||||
if (WITH_DEBUG_CRYPTO)
|
||||
set(DEBUG_CRYPTO 1)
|
||||
endif (WITH_DEBUG_CRYPTO)
|
||||
|
||||
6
DefineOptions.cmake
Normal file
6
DefineOptions.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
option(WITH_LIBZ "Build with ZLIB support" ON)
|
||||
option(WITH_SSH1 "Build with SSH1 support" OFF)
|
||||
option(WITH_SFTP "Build with SFTP support" ON)
|
||||
option(WITH_SERVER "Build with SSH server support" ON)
|
||||
option(WITH_STATIC_LIB "Build with a static library" OFF)
|
||||
option(WITH_DEBUG_CRYPTO "Build with cryto debut output" OFF)
|
||||
2
Doxyfile
2
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = libssh
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.2.1-svn
|
||||
PROJECT_NUMBER = 0.3-svn
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
||||
@@ -31,7 +31,7 @@ PROJECT_NAME = libssh
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.2.1-svn
|
||||
PROJECT_NUMBER = 0.3-svn
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
||||
258
INSTALL
258
INSTALL
@@ -1,236 +1,78 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
# How to build from source
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
## Requirements
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
### Common requirements
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
In order to build libssh, you need to install several components:
|
||||
|
||||
These are generic installation instructions.
|
||||
- A C compiler
|
||||
- [CMake](http://www.cmake.org) >= 2.6.0.
|
||||
- [openssl](http://www.openssl.org) >= 0.9.8
|
||||
or
|
||||
- [gcrypt](http://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
optional:
|
||||
- [libz](http://www.zlib.net) >= 1.2
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
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.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
## Building
|
||||
First, you need to configure the compilation, using CMake. Go inside the
|
||||
`build` dir. Create it if it doesn't exist.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
GNU/Linux and MacOS X:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
|
||||
make
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
### CMake standard options
|
||||
Here is a list of the most interesting options provided out of the box by
|
||||
CMake.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
- CMAKE_BUILD_TYPE: The type of build (can be Debug Release MinSizeRel
|
||||
RelWithDebInfo)
|
||||
- CMAKE_INSTALL_PREFIX: The prefix to use when running make install (Default
|
||||
to /usr/local on GNU/Linux and MacOS X)
|
||||
- CMAKE_C_COMPILER: The path to the C compiler
|
||||
- CMAKE_CXX_COMPILER: The path to the C++ compiler
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
### CMake options defined for libssh
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
Options are defined in the following files:
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
- DefineOptions.cmake
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
They can be changed with the -D option:
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
`cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DWITH_LIBZ=OFF ..`
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
### Browsing/editing CMake options
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
In addition to passing options on the command line, you can browse and edit
|
||||
CMake options using `cmakesetup` (Windows), `cmake-gui` or `ccmake` (GNU/Linux
|
||||
and MacOS X).
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
- Go to the build dir
|
||||
- On Windows: run `cmakesetup`
|
||||
- On GNU/Linux and MacOS X: run `ccmake ..`
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
## Installing
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
If you want to install libssh after compilation run:
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
make install
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
## Running
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
The libssh binary can be found in the `build/libssh` directory.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
## About this document
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
This document is written using [Markdown][] syntax, making it possible to
|
||||
provide usable information in both plain text and HTML format. Whenever
|
||||
modifying this document please use [Markdown][] syntax.
|
||||
|
||||
[markdown]: http://www.daringfireball.net/projects/markdown
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
CC= gcc
|
||||
DLLWRAP=dllwrap.exe
|
||||
DEFFILE=libssh.def
|
||||
STATICLIB=libssh.a
|
||||
LIB="c:\Program files\Microsoft Visual Studio .NET 2003\vc7\bin\lib.exe"
|
||||
INCS= -I. -Iinclude -Ic:/openssl/include -I"c:\Program files\gnuwin32\include"
|
||||
CFLAGS= $(INCS)
|
||||
LINK= -L. c:/openssl/lib/MinGW/libeay32.a "c:\program files\gnuwin32\lib\libz.a" c:\Dev-cpp\lib\libws2_32.a #-lws2_32 ##-lgdi32 -lshell32
|
||||
|
||||
libssh_HEADERS= config.h include/libssh/crypto.h include/libssh/libssh.h include/libssh/priv.h include/libssh/server.h include/libssh/sftp.h include/libssh/ssh1.h include/libssh/ssh2.h
|
||||
libssh_OBJS = libssh/auth1.o libssh/auth.o libssh/base64.o libssh/buffer.o \
|
||||
libssh/channels1.o libssh/channels.o libssh/client.o libssh/connect.o \
|
||||
libssh/crc32.o libssh/crypt.o libssh/dh.o libssh/error.o libssh/gcrypt_missing.o \
|
||||
libssh/gzip.o libssh/init.o libssh/kex.o libssh/keyfiles.o \
|
||||
libssh/keys.o libssh/messages.o libssh/misc.o libssh/options.o \
|
||||
libssh/packet.o libssh/server.o libssh/session.o libssh/sftp.o \
|
||||
libssh/sftpserver.o libssh/string.o libssh/wrapper.o libssh/socket.o \
|
||||
libssh/log.o
|
||||
|
||||
|
||||
all: libssh.dll samplesshd.exe libssh.lib
|
||||
|
||||
config.h: config.h.win32-openssl
|
||||
copy config.h.win32-openssl config.h
|
||||
|
||||
%.o: %.c $(libssh_HEADERS)
|
||||
$(CC) -c $< -o $@ $(CFLAGS)
|
||||
|
||||
sample.exe: sample.o $(libssh_OBJS)
|
||||
$(CC) $< -o $@ $(libssh_OBJS) $(LINK)
|
||||
samplesshd.exe: samplesshd.o $(libssh_OBJS)
|
||||
$(CC) $< -o $@ $(libssh_OBJS) $(LINK)
|
||||
|
||||
libssh.dll: $(libssh_OBJS)
|
||||
# $(CC) -shared $(libssh_OBJS) -o libssh.dll $(LINK)
|
||||
$(DLLWRAP) --export-all-symbols --output-def $(DEFFILE) --implib $(STATICLIB) $(libssh_OBJS) $(LINK) -o libssh.dll
|
||||
|
||||
libssh.lib: libssh.dll
|
||||
lib.bat
|
||||
clean:
|
||||
rm -f $(libssh_OBJS) samplesshd.exe sample.exe samplesshd.o sample.o libssh.dll config.h
|
||||
44
Makefile.am
44
Makefile.am
@@ -1,44 +0,0 @@
|
||||
SUBDIRS = libssh include
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/include
|
||||
|
||||
LDADD = $(top_builddir)/libssh/libssh.la
|
||||
|
||||
noinst_PROGRAMS = samplesshd samplessh
|
||||
|
||||
noinst_DATA = samplesftp doxygen
|
||||
|
||||
samplessh_SOURCES = sample.c
|
||||
|
||||
samplesshd_SOURCES = samplesshd.c
|
||||
|
||||
samplesftp: samplessh
|
||||
$(LN_S) -f samplessh samplesftp
|
||||
|
||||
if HAS_DOXYGEN
|
||||
install-doc: doxygen
|
||||
$(INSTALL) -d $(DESTDIR)$(docdir)/html
|
||||
$(INSTALL) --mode=644 doxygen/html/* $(DESTDIR)$(docdir)/html
|
||||
$(INSTALL) -d $(DESTDIR)$(docdir)/examples
|
||||
$(INSTALL) --mode=644 sample.c samplesshd.c $(DESTDIR)$(docdir)/examples
|
||||
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
|
||||
$(INSTALL) --mode=644 doxygen/man/man3/* $(DESTDIR)$(mandir)/man3
|
||||
|
||||
doxygen: clean-local
|
||||
@echo "Running doxygen..."
|
||||
doxygen $(srcdir)/Doxyfile
|
||||
doxygen-dev: clean-local
|
||||
@echo "Running internal doxygen"
|
||||
doxygen $(srcdir)/Doxyfile.internal
|
||||
else
|
||||
doxygen:
|
||||
doxygen-dev:
|
||||
install-doc: doxygen
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
-rm -rf doxygen
|
||||
|
||||
EXTRA_DIST = Doxyfile Doxyfile.internal
|
||||
|
||||
CLEANFILES = samplesftp
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
aclocal
|
||||
libtoolize --force --copy
|
||||
autoheader
|
||||
autoconf
|
||||
automake --add-missing --copy --gnu
|
||||
./configure $@
|
||||
152
build/build_make.sh
Executable file
152
build/build_make.sh
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Last Change: 2008-06-18 14:13:46
|
||||
#
|
||||
# Script to build libssh on UNIX.
|
||||
#
|
||||
# Copyright (c) 2006-2007 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
|
||||
SOURCE_DIR=".."
|
||||
|
||||
LANG=C
|
||||
export LANG
|
||||
|
||||
SCRIPT="$0"
|
||||
COUNT=0
|
||||
while [ -L "${SCRIPT}" ]
|
||||
do
|
||||
SCRIPT=$(readlink ${SCRIPT})
|
||||
COUNT=$(expr ${COUNT} + 1)
|
||||
if [ ${COUNT} -gt 100 ]; then
|
||||
echo "Too many symbolic links"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
BUILDDIR=$(dirname ${SCRIPT})
|
||||
|
||||
cleanup_and_exit () {
|
||||
if test "$1" = 0 -o -z "$1" ; then
|
||||
exit 0
|
||||
else
|
||||
exit $1
|
||||
fi
|
||||
}
|
||||
|
||||
function configure() {
|
||||
cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||
}
|
||||
|
||||
function compile() {
|
||||
CPUCOUNT=$(grep -c processor /proc/cpuinfo)
|
||||
if [ "${CPUCOUNT}" -gt "1" ]; then
|
||||
make -j${CPUCOUNT} $1 || cleanup_and_exit $?
|
||||
else
|
||||
make $1 || exit $?
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_build_dir() {
|
||||
find ! -path "*.svn*" ! -name "*.bat" ! -name "*.sh" ! -name "." -print0 | xargs -0 rm -rf
|
||||
}
|
||||
|
||||
function usage () {
|
||||
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help]"
|
||||
cleanup_and_exit
|
||||
}
|
||||
|
||||
cd ${BUILDDIR}
|
||||
|
||||
OPTIONS="--graphviz=${BUILDDIR}/libssh.dot -DUNIT_TESTING=ON -DWITH_SSH1=ON -DWITH_SERVER=ON"
|
||||
|
||||
while test -n "$1"; do
|
||||
PARAM="$1"
|
||||
ARG="$2"
|
||||
shift
|
||||
case ${PARAM} in
|
||||
*-*=*)
|
||||
ARG=${PARAM#*=}
|
||||
PARAM=${PARAM%%=*}
|
||||
set -- "----noarg=${PARAM}" "$@"
|
||||
esac
|
||||
case ${PARAM} in
|
||||
*-help|-h)
|
||||
#echo_help
|
||||
usage
|
||||
cleanup_and_exit
|
||||
;;
|
||||
*-build)
|
||||
DOMAKE="1"
|
||||
BUILD_TYPE="${ARG}"
|
||||
test -n "${BUILD_TYPE}" && shift
|
||||
;;
|
||||
*-clean)
|
||||
clean_build_dir
|
||||
cleanup_and_exit
|
||||
;;
|
||||
*-verbose)
|
||||
DOVERBOSE="1"
|
||||
;;
|
||||
*-memtest)
|
||||
OPTIONS="${OPTIONS} -DMEM_NULL_TESTS=ON"
|
||||
;;
|
||||
*-libsuffix)
|
||||
OPTIONS="${OPTIONS} -DLIB_SUFFIX=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-prefix)
|
||||
OPTIONS="${OPTIONS} -DCMAKE_INSTALL_PREFIX=${ARG}"
|
||||
shift
|
||||
;;
|
||||
*-sysconfdir)
|
||||
OPTIONS="${OPTIONS} -DSYSCONF_INSTALL_DIR=${ARG}"
|
||||
shift
|
||||
;;
|
||||
----noarg)
|
||||
echo "$ARG does not take an argument"
|
||||
cleanup_and_exit
|
||||
;;
|
||||
-*)
|
||||
echo Unknown Option "$PARAM". Exit.
|
||||
cleanup_and_exit 1
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ${DOMAKE} -eq 1 ]; then
|
||||
OPTIONS="${OPTIONS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE}"
|
||||
fi
|
||||
|
||||
if [ -n "${DOVERBOSE}" ]; then
|
||||
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=1"
|
||||
else
|
||||
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=0"
|
||||
fi
|
||||
|
||||
test -f "${BUILDDIR}/.build.log" && rm -f ${BUILDDIR}/.build.log
|
||||
touch ${BUILDDIR}/.build.log
|
||||
# log everything from here to .build.log
|
||||
exec 1> >(exec -a 'build logging tee' tee -a ${BUILDDIR}/.build.log) 2>&1
|
||||
echo "${HOST} started build at $(date)."
|
||||
echo
|
||||
|
||||
configure ${OPTIONS} "$@"
|
||||
|
||||
if [ -n "${DOMAKE}" ]; then
|
||||
test -n "${DOVERBOSE}" && compile VERBOSE=1 || compile
|
||||
fi
|
||||
|
||||
DOT=$(which dot 2>/dev/null)
|
||||
if [ -n "${DOT}" ]; then
|
||||
${DOT} -Tpng -o${BUILDDIR}/libssh.png ${BUILDDIR}/libssh.dot
|
||||
${DOT} -Tsvg -o${BUILDDIR}/libssh.svg ${BUILDDIR}/libssh.dot
|
||||
fi
|
||||
|
||||
exec >&0 2>&0 # so that the logging tee finishes
|
||||
sleep 1 # wait till tee terminates
|
||||
|
||||
cleanup_and_exit 0
|
||||
|
||||
22
cmake/Modules/COPYING-CMAKE-SCRIPTS
Normal file
22
cmake/Modules/COPYING-CMAKE-SCRIPTS
Normal file
@@ -0,0 +1,22 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
27
cmake/Modules/DefineCMakeDefaults.cmake
Normal file
27
cmake/Modules/DefineCMakeDefaults.cmake
Normal file
@@ -0,0 +1,27 @@
|
||||
# Always include srcdir and builddir in include path
|
||||
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
|
||||
# about every subdir
|
||||
# since cmake 2.4.0
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Put the include dirs which are in the source or build tree
|
||||
# before all other include dirs, so the headers in the sources
|
||||
# are prefered over the already installed ones
|
||||
# since cmake 2.4.1
|
||||
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
|
||||
|
||||
# Use colored output
|
||||
# since cmake 2.4.0
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
# Define the generic version of the libraries here
|
||||
set(GENERIC_LIB_VERSION "0.1.0")
|
||||
set(GENERIC_LIB_SOVERSION "0")
|
||||
|
||||
# Set the default build type to release with debug info
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo
|
||||
CACHE STRING
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
50
cmake/Modules/DefineCompilerFlags.cmake
Normal file
50
cmake/Modules/DefineCompilerFlags.cmake
Normal file
@@ -0,0 +1,50 @@
|
||||
# define system dependent compiler flags
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
if (UNIX AND NOT WIN32)
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
add_definitions(-Wall -Wextra -Wmissing-prototypes -Wdeclaration-after-statement -Wunused)
|
||||
|
||||
# with -fPIC
|
||||
check_c_compiler_flag("-fPIC" WITH_FPIC)
|
||||
if (WITH_FPIC)
|
||||
add_definitions(-fPIC)
|
||||
endif (WITH_FPIC)
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
# with large file support
|
||||
execute_process(
|
||||
COMMAND
|
||||
getconf LFS64_CFLAGS
|
||||
OUTPUT_VARIABLE
|
||||
_lfs_CFLAGS
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
# with large file support
|
||||
execute_process(
|
||||
COMMAND
|
||||
getconf LFS_CFLAGS
|
||||
OUTPUT_VARIABLE
|
||||
_lfs_CFLAGS
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
|
||||
|
||||
add_definitions(${_lfs_CFLAGS})
|
||||
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
|
||||
check_c_compiler_flag("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||
if (WITH_STACK_PROTECTOR)
|
||||
add_definitions(-fstack-protector)
|
||||
endif (WITH_STACK_PROTECTOR)
|
||||
|
||||
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
|
||||
if (WITH_FORTIFY_SOURCE)
|
||||
add_definitions(-D_FORTIFY_SOURCE=2)
|
||||
endif (WITH_FORTIFY_SOURCE)
|
||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||
endif (UNIX AND NOT WIN32)
|
||||
107
cmake/Modules/DefineInstallationPaths.cmake
Normal file
107
cmake/Modules/DefineInstallationPaths.cmake
Normal file
@@ -0,0 +1,107 @@
|
||||
if (UNIX)
|
||||
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(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)"
|
||||
)
|
||||
endif (UNIX)
|
||||
|
||||
if (WIN32)
|
||||
# Same same
|
||||
set(BIN_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(SBIN_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(LIB_INSTALL_DIR "lib" CACHE PATH "-")
|
||||
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
|
||||
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
|
||||
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
|
||||
set(ICON_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(SOUND_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
|
||||
endif (WIN32)
|
||||
|
||||
77
cmake/Modules/FindGCrypt.cmake
Normal file
77
cmake/Modules/FindGCrypt.cmake
Normal file
@@ -0,0 +1,77 @@
|
||||
# - Try to find GCrypt
|
||||
# Once done this will define
|
||||
#
|
||||
# GCRYPT_FOUND - system has GCrypt
|
||||
# GCRYPT_INCLUDE_DIRS - the GCrypt include directory
|
||||
# GCRYPT_LIBRARIES - Link these to use GCrypt
|
||||
# GCRYPT_DEFINITIONS - Compiler switches required for using GCrypt
|
||||
#
|
||||
# Copyright (c) 2009 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(GCRYPT_FOUND TRUE)
|
||||
else (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
|
||||
|
||||
find_path(GCRYPT_INCLUDE_DIR
|
||||
NAMES
|
||||
gcrypt.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
mark_as_advanced(GCRYPT_INCLUDE_DIR)
|
||||
|
||||
find_library(GCRYPT_LIBRARY
|
||||
NAMES
|
||||
gcrypt
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(GCRYPT_LIBRARY)
|
||||
|
||||
if (GCRYPT_LIBRARY)
|
||||
set(GCRYPT_FOUND TRUE CACHE INTERNAL "Wether the gcrypt library has been found" FORCE)
|
||||
endif (GCRYPT_LIBRARY)
|
||||
|
||||
set(GCRYPT_INCLUDE_DIRS
|
||||
${GCRYPT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (GCRYPT_FOUND)
|
||||
set(GCRYPT_LIBRARIES
|
||||
${GCRYPT_LIBRARIES}
|
||||
${GCRYPT_LIBRARY}
|
||||
)
|
||||
endif (GCRYPT_FOUND)
|
||||
|
||||
if (GCRYPT_INCLUDE_DIRS AND GCRYPT_LIBRARIES)
|
||||
set(GCRYPT_FOUND TRUE)
|
||||
endif (GCRYPT_INCLUDE_DIRS AND GCRYPT_LIBRARIES)
|
||||
|
||||
if (GCRYPT_FOUND)
|
||||
if (NOT GCrypt_FIND_QUIETLY)
|
||||
message(STATUS "Found GCrypt: ${GCRYPT_LIBRARIES}")
|
||||
endif (NOT GCrypt_FIND_QUIETLY)
|
||||
else (GCRYPT_FOUND)
|
||||
if (GCrypt_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find GCrypt")
|
||||
endif (GCrypt_FIND_REQUIRED)
|
||||
endif (GCRYPT_FOUND)
|
||||
|
||||
# show the GCRYPT_INCLUDE_DIRS and GCRYPT_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(GCRYPT_INCLUDE_DIRS GCRYPT_LIBRARIES)
|
||||
|
||||
endif (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
|
||||
|
||||
159
cmake/Modules/FindOpenSSL.cmake
Normal file
159
cmake/Modules/FindOpenSSL.cmake
Normal file
@@ -0,0 +1,159 @@
|
||||
# - Try to find OpenSSL
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENSSL_FOUND - system has OpenSSL
|
||||
# OPENSSL_INCLUDE_DIRS - the OpenSSL include directory
|
||||
# OPENSSL_LIBRARIES - Link these to use OpenSSL
|
||||
# OPENSSL_DEFINITIONS - Compiler switches required for using OpenSSL
|
||||
#
|
||||
# Copyright (c) 2009 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(OPENSSL_FOUND TRUE)
|
||||
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
|
||||
include(UsePkgConfig)
|
||||
pkgconfig(openssl _OPENSSL_INCLUDEDIR _OPENSSL_LIBDIR _OPENSSL_LDFLAGS _OPENSSL_CFLAGS)
|
||||
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_OPENSSL openssl)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
|
||||
|
||||
find_path(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
openssl/ssl.h
|
||||
PATHS
|
||||
${_OPENSSL_INCLUDEDIR}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
mark_as_advanced(OPENSSL_INCLUDE_DIR)
|
||||
|
||||
find_library(SSL_LIBRARY
|
||||
NAMES
|
||||
ssl
|
||||
PATHS
|
||||
${_OPENSSL_LIBDIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(SSL_LIBRARY)
|
||||
|
||||
find_library(SSLEAY32_LIBRARY
|
||||
NAMES
|
||||
ssleay32
|
||||
PATHS
|
||||
${_OPENSSL_LIBDIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(SSLEAY32_LIBRARY)
|
||||
|
||||
find_library(SSLEAY32MD_LIBRARY
|
||||
NAMES
|
||||
ssleay32MD
|
||||
PATHS
|
||||
${_OPENSSL_LIBDIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(SSLEAY32MD_LIBRARY)
|
||||
|
||||
find_library(CRYPTO_LIBRARY
|
||||
NAMES
|
||||
crypto
|
||||
PATHS
|
||||
${_OPENSSL_LIBDIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(CRYPTO_LIBRARY)
|
||||
|
||||
if (SSL_LIBRARY)
|
||||
set(SSL_FOUND TRUE CACHE INTERNAL "Wether the ssl library has been found" FORCE)
|
||||
endif (SSL_LIBRARY)
|
||||
|
||||
if (SSLEAY32_LIBRARY)
|
||||
set(SSLEAY32_FOUND TRUE CACHE INTERNAL "Wether the ssleay32 library has been found" FORCE)
|
||||
endif (SSLEAY32_LIBRARY)
|
||||
|
||||
if (SSLEAY32MD_LIBRARY)
|
||||
set(SSLEAY32MD_FOUND TRUE CACHE INTERNAL "Wether the ssleay32MD library has been found" FORCE)
|
||||
endif (SSLEAY32MD_LIBRARY)
|
||||
|
||||
if (CRYPTO_LIBRARY)
|
||||
set(CRYPTO_FOUND TRUE CACHE INTERNAL "Wether the crypto library has been found" FORCE)
|
||||
endif (CRYPTO_LIBRARY)
|
||||
|
||||
set(OPENSSL_INCLUDE_DIRS
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (SSL_FOUND)
|
||||
set(OPENSSL_LIBRARIES
|
||||
${OPENSSL_LIBRARIES}
|
||||
${SSL_LIBRARY}
|
||||
)
|
||||
endif (SSL_FOUND)
|
||||
|
||||
if (SSLEAY32_FOUND)
|
||||
set(OPENSSL_LIBRARIES
|
||||
${OPENSSL_LIBRARIES}
|
||||
${SSLEAY32_LIBRARY}
|
||||
)
|
||||
endif (SSLEAY32_FOUND)
|
||||
|
||||
if (SSLEAY32MD_FOUND)
|
||||
set(OPENSSL_LIBRARIES
|
||||
${OPENSSL_LIBRARIES}
|
||||
${SSLEAY32MD_LIBRARY}
|
||||
)
|
||||
endif (SSLEAY32MD_FOUND)
|
||||
|
||||
if (CRYPTO_FOUND)
|
||||
set(OPENSSL_LIBRARIES
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CRYPTO_LIBRARY}
|
||||
)
|
||||
endif (CRYPTO_FOUND)
|
||||
|
||||
if (OPENSSL_INCLUDE_DIRS AND OPENSSL_LIBRARIES)
|
||||
set(OPENSSL_FOUND TRUE)
|
||||
endif (OPENSSL_INCLUDE_DIRS AND OPENSSL_LIBRARIES)
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
if (NOT OpenSSL_FIND_QUIETLY)
|
||||
message(STATUS "Found OpenSSL: ${OPENSSL_LIBRARIES}")
|
||||
endif (NOT OpenSSL_FIND_QUIETLY)
|
||||
else (OPENSSL_FOUND)
|
||||
if (OpenSSL_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find OpenSSL")
|
||||
endif (OpenSSL_FIND_REQUIRED)
|
||||
endif (OPENSSL_FOUND)
|
||||
|
||||
# show the OPENSSL_INCLUDE_DIRS and OPENSSL_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(OPENSSL_INCLUDE_DIRS OPENSSL_LIBRARIES)
|
||||
|
||||
endif (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
|
||||
79
cmake/Modules/FindZLIB.cmake
Normal file
79
cmake/Modules/FindZLIB.cmake
Normal file
@@ -0,0 +1,79 @@
|
||||
# - Try to find ZLIB
|
||||
# Once done this will define
|
||||
#
|
||||
# ZLIB_FOUND - system has ZLIB
|
||||
# ZLIB_INCLUDE_DIRS - the ZLIB include directory
|
||||
# ZLIB_LIBRARIES - Link these to use ZLIB
|
||||
# ZLIB_DEFINITIONS - Compiler switches required for using ZLIB
|
||||
#
|
||||
# Copyright (c) 2009 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(ZLIB_FOUND TRUE)
|
||||
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
|
||||
find_path(ZLIB_INCLUDE_DIR
|
||||
NAMES
|
||||
zlib.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
mark_as_advanced(ZLIB_INCLUDE_DIR)
|
||||
|
||||
find_library(Z_LIBRARY
|
||||
NAMES
|
||||
z
|
||||
zlib
|
||||
zlib1
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(Z_LIBRARY)
|
||||
|
||||
if (Z_LIBRARY)
|
||||
set(Z_FOUND TRUE)
|
||||
endif (Z_LIBRARY)
|
||||
|
||||
set(ZLIB_INCLUDE_DIRS
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (Z_FOUND)
|
||||
set(ZLIB_LIBRARIES
|
||||
${ZLIB_LIBRARIES}
|
||||
${Z_LIBRARY}
|
||||
)
|
||||
endif (Z_FOUND)
|
||||
|
||||
if (ZLIB_INCLUDE_DIRS AND ZLIB_LIBRARIES)
|
||||
set(ZLIB_FOUND TRUE)
|
||||
endif (ZLIB_INCLUDE_DIRS AND ZLIB_LIBRARIES)
|
||||
|
||||
if (ZLIB_FOUND)
|
||||
if (NOT ZLIB_FIND_QUIETLY)
|
||||
message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES}")
|
||||
endif (NOT ZLIB_FIND_QUIETLY)
|
||||
else (ZLIB_FOUND)
|
||||
if (ZLIB_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find ZLIB")
|
||||
endif (ZLIB_FIND_REQUIRED)
|
||||
endif (ZLIB_FOUND)
|
||||
|
||||
# show the ZLIB_INCLUDE_DIRS and ZLIB_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(ZLIB_INCLUDE_DIRS ZLIB_LIBRARIES)
|
||||
|
||||
endif (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
|
||||
21
cmake/Modules/MacroAddCompileFlags.cmake
Normal file
21
cmake/Modules/MacroAddCompileFlags.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
# - MACRO_ADD_COMPILE_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_COMPILE_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} COMPILE_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags ${_flags} ${ARGN})
|
||||
else (_flags)
|
||||
set(_flags ${ARGN})
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_FLAGS ${_flags})
|
||||
|
||||
endmacro (MACRO_ADD_COMPILE_FLAGS)
|
||||
20
cmake/Modules/MacroAddLinkFlags.cmake
Normal file
20
cmake/Modules/MacroAddLinkFlags.cmake
Normal file
@@ -0,0 +1,20 @@
|
||||
# - MACRO_ADD_LINK_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ADD_LINK_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} LINK_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags "${_flags} ${ARGN}")
|
||||
else (_flags)
|
||||
set(_flags "${ARGN}")
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${_flags}")
|
||||
|
||||
endmacro (MACRO_ADD_LINK_FLAGS)
|
||||
30
cmake/Modules/MacroAddPlugin.cmake
Normal file
30
cmake/Modules/MacroAddPlugin.cmake
Normal file
@@ -0,0 +1,30 @@
|
||||
# - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN)
|
||||
#
|
||||
# Create a plugin from the given source files.
|
||||
# If WITH_PREFIX is given, the resulting plugin will have the
|
||||
# prefix "lib", otherwise it won't.
|
||||
#
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX)
|
||||
|
||||
if (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC)
|
||||
else (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC ${_with_PREFIX})
|
||||
endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
|
||||
add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN})
|
||||
|
||||
if (_first_SRC)
|
||||
set_target_properties(${_target_NAME} PROPERTIES PREFIX "")
|
||||
endif (_first_SRC)
|
||||
|
||||
endmacro (MACRO_ADD_PLUGIN _name _sources)
|
||||
|
||||
33
cmake/Modules/MacroCopyFile.cmake
Normal file
33
cmake/Modules/MacroCopyFile.cmake
Normal file
@@ -0,0 +1,33 @@
|
||||
# - macro_copy_file(_src _dst)
|
||||
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
|
||||
#
|
||||
# Example:
|
||||
# macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.)
|
||||
# Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory
|
||||
#
|
||||
# Copyright (c) 2006-2007 Wengo
|
||||
# Copyright (c) 2006-2008 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING file.
|
||||
|
||||
|
||||
macro (macro_copy_file _src _dst)
|
||||
# Removes all path containing .svn or CVS or CMakeLists.txt during the copy
|
||||
if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
|
||||
if (CMAKE_VERBOSE_MAKEFILE)
|
||||
message(STATUS "Copy file from ${_src} to ${_dst}")
|
||||
endif (CMAKE_VERBOSE_MAKEFILE)
|
||||
|
||||
# Creates directory if necessary
|
||||
get_filename_component(_path ${_dst} PATH)
|
||||
file(MAKE_DIRECTORY ${_path})
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst}
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
endmacro (macro_copy_file)
|
||||
17
cmake/Modules/MacroEnsureOutOfSourceBuild.cmake
Normal file
17
cmake/Modules/MacroEnsureOutOfSourceBuild.cmake
Normal file
@@ -0,0 +1,17 @@
|
||||
# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage)
|
||||
|
||||
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource)
|
||||
if (_insource)
|
||||
message(SEND_ERROR "${_errorMessage}")
|
||||
message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.")
|
||||
endif (_insource)
|
||||
|
||||
endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)
|
||||
127
cmake/Modules/UseDoxygen.cmake
Normal file
127
cmake/Modules/UseDoxygen.cmake
Normal file
@@ -0,0 +1,127 @@
|
||||
# -helper macro to add a "doc" target with CMake build system.
|
||||
# and configure doxy.config.in to doxy.config
|
||||
#
|
||||
# target "doc" allows building the documentation with doxygen/dot on WIN32 and Linux
|
||||
# Creates .chm windows help file if MS HTML help workshop
|
||||
# (available from http://msdn.microsoft.com/workshop/author/htmlhelp)
|
||||
# is installed with its DLLs in PATH.
|
||||
#
|
||||
#
|
||||
# Please note, that the tools, e.g.:
|
||||
# doxygen, dot, latex, dvips, makeindex, gswin32, etc.
|
||||
# must be in path.
|
||||
#
|
||||
# Note about Visual Studio Projects:
|
||||
# MSVS has its own path environment which may differ from the shell.
|
||||
# See "Menu Tools/Options/Projects/VC++ Directories" in VS 7.1
|
||||
#
|
||||
# author Jan Woetzel 2004-2006
|
||||
# www.mip.informatik.uni-kiel.de/~jw
|
||||
|
||||
|
||||
FIND_PACKAGE(Doxygen)
|
||||
|
||||
IF (DOXYGEN_FOUND)
|
||||
|
||||
# click+jump in Emacs and Visual Studio (for doxy.config) (jw)
|
||||
IF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
|
||||
SET(DOXY_WARN_FORMAT "\"$file($line) : $text \"")
|
||||
ELSE (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
|
||||
SET(DOXY_WARN_FORMAT "\"$file:$line: $text \"")
|
||||
ENDIF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
|
||||
|
||||
# we need latex for doxygen because of the formulas
|
||||
FIND_PACKAGE(LATEX)
|
||||
IF (NOT LATEX_COMPILER)
|
||||
MESSAGE(STATUS "latex command LATEX_COMPILER not found but usually required. You will probably get warnings and user inetraction on doxy run.")
|
||||
ENDIF (NOT LATEX_COMPILER)
|
||||
IF (NOT MAKEINDEX_COMPILER)
|
||||
MESSAGE(STATUS "makeindex command MAKEINDEX_COMPILER not found but usually required.")
|
||||
ENDIF (NOT MAKEINDEX_COMPILER)
|
||||
IF (NOT DVIPS_CONVERTER)
|
||||
MESSAGE(STATUS "dvips command DVIPS_CONVERTER not found but usually required.")
|
||||
ENDIF (NOT DVIPS_CONVERTER)
|
||||
FIND_PROGRAM(DOXYGEN_DOT_EXECUTABLE_PATH NAMES dot)
|
||||
IF (DOXYGEN_DOT_EXECUTABLE_PATH)
|
||||
SET(DOXYGEN_DOT_FOUND "YES")
|
||||
ENDIF (DOXYGEN_DOT_EXECUTABLE_PATH)
|
||||
|
||||
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
|
||||
MESSAGE(STATUS "Generate ${CMAKE_CURRENT_BINARY_DIR}/doxy.config from doxy.config.in")
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/doxy.config
|
||||
@ONLY )
|
||||
# use (configured) doxy.config from (out of place) BUILD tree:
|
||||
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/doxy.config")
|
||||
ELSE (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
|
||||
# use static hand-edited doxy.config from SOURCE tree:
|
||||
SET(DOXY_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
MESSAGE(STATUS "WARNING: using existing ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config instead of configuring from doxy.config.in file.")
|
||||
ELSE (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
IF (EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
|
||||
# using template doxy.config.in
|
||||
MESSAGE(STATUS "Generate ${CMAKE_CURRENT_BINARY_DIR}/doxy.config from doxy.config.in")
|
||||
CONFIGURE_FILE(${CMAKE_MODULE_PATH}/doxy.config.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/doxy.config
|
||||
@ONLY )
|
||||
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/doxy.config")
|
||||
ELSE (EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
|
||||
# failed completely...
|
||||
MESSAGE(SEND_ERROR "Please create ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in (or doxy.config as fallback)")
|
||||
ENDIF(EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
|
||||
|
||||
ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
|
||||
|
||||
ADD_CUSTOM_TARGET(doc ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
|
||||
|
||||
# create a windows help .chm file using hhc.exe
|
||||
# HTMLHelp DLL must be in path!
|
||||
# fallback: use hhw.exe interactively
|
||||
IF (WIN32)
|
||||
FIND_PACKAGE(HTMLHelp)
|
||||
IF (HTML_HELP_COMPILER)
|
||||
SET (TMP "${CMAKE_CURRENT_BINARY_DIR}\\doc\\html\\index.hhp")
|
||||
STRING(REGEX REPLACE "[/]" "\\\\" HHP_FILE ${TMP} )
|
||||
# MESSAGE(SEND_ERROR "DBG HHP_FILE=${HHP_FILE}")
|
||||
ADD_CUSTOM_TARGET(winhelp ${HTML_HELP_COMPILER} ${HHP_FILE})
|
||||
ADD_DEPENDENCIES (winhelp doc)
|
||||
|
||||
IF (NOT TARGET_DOC_SKIP_INSTALL)
|
||||
# install windows help?
|
||||
# determine useful name for output file
|
||||
# should be project and version unique to allow installing
|
||||
# multiple projects into one global directory
|
||||
IF (EXISTS "${PROJECT_BINARY_DIR}/doc/html/index.chm")
|
||||
IF (PROJECT_NAME)
|
||||
SET(OUT "${PROJECT_NAME}")
|
||||
ELSE (PROJECT_NAME)
|
||||
SET(OUT "Documentation") # default
|
||||
ENDIF(PROJECT_NAME)
|
||||
IF (${PROJECT_NAME}_VERSION_MAJOR)
|
||||
SET(OUT "${OUT}-${${PROJECT_NAME}_VERSION_MAJOR}")
|
||||
IF (${PROJECT_NAME}_VERSION_MINOR)
|
||||
SET(OUT "${OUT}.${${PROJECT_NAME}_VERSION_MINOR}")
|
||||
IF (${PROJECT_NAME}_VERSION_PATCH)
|
||||
SET(OUT "${OUT}.${${PROJECT_NAME}_VERSION_PATCH}")
|
||||
ENDIF(${PROJECT_NAME}_VERSION_PATCH)
|
||||
ENDIF(${PROJECT_NAME}_VERSION_MINOR)
|
||||
ENDIF(${PROJECT_NAME}_VERSION_MAJOR)
|
||||
# keep suffix
|
||||
SET(OUT "${OUT}.chm")
|
||||
|
||||
#MESSAGE("DBG ${PROJECT_BINARY_DIR}/doc/html/index.chm \n${OUT}")
|
||||
# create target used by install and package commands
|
||||
INSTALL(FILES "${PROJECT_BINARY_DIR}/doc/html/index.chm"
|
||||
DESTINATION "doc"
|
||||
RENAME "${OUT}"
|
||||
)
|
||||
ENDIF(EXISTS "${PROJECT_BINARY_DIR}/doc/html/index.chm")
|
||||
ENDIF(NOT TARGET_DOC_SKIP_INSTALL)
|
||||
|
||||
ENDIF(HTML_HELP_COMPILER)
|
||||
# MESSAGE(SEND_ERROR "HTML_HELP_COMPILER=${HTML_HELP_COMPILER}")
|
||||
ENDIF (WIN32)
|
||||
ENDIF(DOXYGEN_FOUND)
|
||||
|
||||
87
config.h.cmake
Normal file
87
config.h.cmake
Normal file
@@ -0,0 +1,87 @@
|
||||
/* Name of package */
|
||||
#cmakedefine PACKAGE "${APPLICATION_NAME}"
|
||||
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION "${APPLICATION_VERSION}"
|
||||
|
||||
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
|
||||
#cmakedefine DATADIR "${DATADIR}"
|
||||
#cmakedefine LIBDIR "${LIBDIR}"
|
||||
#cmakedefine PLUGINDIR "${PLUGINDIR}"
|
||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
||||
#cmakedefine BINARYDIR "${BINARYDIR}"
|
||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||
|
||||
/************************** HEADER FILES *************************/
|
||||
|
||||
/* Define to 1 if you have the <pty.h> header file. */
|
||||
#cmakedefine HAVE_PTY_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#cmakedefine HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/aes.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_AES_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_BLOWFISH_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/des.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_DES_H 1
|
||||
|
||||
/*************************** FUNCTIONS ***************************/
|
||||
|
||||
/* Define to 1 if you have the `cfmakeraw' function. */
|
||||
#cmakedefine HAVE_CFMAKERAW 1
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#cmakedefine HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname' function. */
|
||||
#cmakedefine HAVE_GETHOSTBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#cmakedefine HAVE_POLL 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#cmakedefine HAVE_SELECT 1
|
||||
|
||||
/*************************** LIBRARIES ***************************/
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#cmakedefine HAVE_LIBCRYPTO 1
|
||||
|
||||
/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
|
||||
#cmakedefine HAVE_LIBGCRYPT 1
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
#cmakedefine HAVE_LIBZ 1
|
||||
|
||||
/**************************** OPTIONS ****************************/
|
||||
|
||||
/* Define to 1 if you want to enable ZLIB */
|
||||
#cmakedefine WITH_LIBZ 1
|
||||
|
||||
/* Define to 1 if you want to enable SSH1 */
|
||||
#cmakedefine WITH_SFTP 1
|
||||
|
||||
/* Define to 1 if you want to enable SSH1 */
|
||||
#cmakedefine WITH_SSH1 1
|
||||
|
||||
/* Define to 1 if you want to enable server support */
|
||||
#cmakedefine WITH_SERVER 1
|
||||
|
||||
/* Define to 1 if you want to enable debug output for crypto functions */
|
||||
#cmakedefine DEBUG_CRYPTO 1
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
/* # undef WORDS_BIGENDIAN */
|
||||
# endif
|
||||
#endif
|
||||
@@ -1,193 +0,0 @@
|
||||
/* config.h. Manually tweaked for Windows. */
|
||||
|
||||
/* Define to 1 if you have the `cfmakeraw' function. */
|
||||
#define HAVE_CFMAKERAW 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the `endpwent' function. */
|
||||
/* #undef HAVE_ENDPWENT */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <gcrypt.h> header file. */
|
||||
/* #undef HAVE_GCRYPT_H */
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#define HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname' function. */
|
||||
#define HAVE_GETHOSTBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `getpass' function. */
|
||||
/* #undef HAVE_GETPASS */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#define HAVE_LIBCRYPTO 1
|
||||
|
||||
/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
|
||||
/* #undef HAVE_LIBGCRYPT */
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
#define HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
/* #undef HAVE_NETDB_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
/* #undef HAVE_NETINET_IN_H */
|
||||
|
||||
/* Define to 1 if you have the <openssl/aes.h> header file. */
|
||||
#define HAVE_OPENSSL_AES_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
|
||||
#define HAVE_OPENSSL_BLOWFISH_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/des.h> header file. */
|
||||
#define HAVE_OPENSSL_DES_H 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
/* #undef HAVE_POLL */
|
||||
|
||||
/* Define to 1 if you have the <pty.h> header file. */
|
||||
/* #undef HAVE_PTY_H */
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#define HAVE_REALLOC 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define to 1 if you want to enable SSH1 */
|
||||
/* #undef HAVE_SSH1 */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
/* #undef HAVE_SYS_POLL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKET_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
/* #undef HAVE_TERMIOS_H */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#define HAVE_ZLIB_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libssh"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "aris@0xbadc0de.be"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libssh"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libssh 0.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libssh"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.2.1-win-svn"
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type of arg 1 for `select'. */
|
||||
#define SELECT_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||
#define SELECT_TYPE_ARG234 (fd_set *)
|
||||
|
||||
/* Define to the type of arg 5 for `select'. */
|
||||
#define SELECT_TYPE_ARG5 (struct timeval *)
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.2.1-win-svn"
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
/* #undef realloc */
|
||||
135
configure.ac
135
configure.ac
@@ -1,135 +0,0 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libssh], 0.2.1-svn, [aris@0xbadc0de.be])
|
||||
AM_INIT_AUTOMAKE(1.9)
|
||||
AC_CONFIG_SRCDIR([sample.c])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
# LT Version numbers, remember to change them just *before* a release.
|
||||
# (Interfaces removed: CURRENT++, AGE=0, REVISION=0)
|
||||
# (Interfaces added: CURRENT++, AGE++, REVISION=0)
|
||||
# (No interfaces changed: REVISION++)
|
||||
LIBSSH_CURRENT=3
|
||||
LIBSSH_AGE=1
|
||||
LIBSSH_REVISION=0
|
||||
AC_SUBST(LIBSSH_CURRENT)
|
||||
AC_SUBST(LIBSSH_AGE)
|
||||
AC_SUBST(LIBSSH_REVISION)
|
||||
|
||||
# Check for the OS.
|
||||
AC_CANONICAL_HOST
|
||||
case "$host" in
|
||||
*-apple*)
|
||||
LIBSSH_LDFLAGS="-prebind -seg1addr 0x3a000000 -headerpad_max_install_names"
|
||||
;;
|
||||
*)
|
||||
LIBSSH_LDFLAGS=""
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(LIBSSH_LDFLAGS)
|
||||
|
||||
AC_MSG_CHECKING([version script options])
|
||||
case "$host" in
|
||||
*-*-linux*)
|
||||
LIBSSH_VERS="$LIBSSH_LDFLAGS -Wl,--version-script,libssh.vers"
|
||||
;;
|
||||
*-*-gnu*)
|
||||
LIBSSH_VERS="$LIBSSH_LDFLAGS -Wl,--version-script,libssh.vers"
|
||||
;;
|
||||
esac
|
||||
AC_ARG_WITH([versioned-symbol],
|
||||
AC_HELP_STRING([--with-versioned-symbol],[Use versioned symbols]),
|
||||
[if test "$withval" = "yes"; then
|
||||
LIBSSH_VERS="$LIBSSH_LDFLAGS -Wl,--version-script,libssh.vers"
|
||||
else
|
||||
LIBSSH_VERS=""
|
||||
fi], [ : ])
|
||||
|
||||
AC_SUBST(LIBSSH_VERS)
|
||||
|
||||
enable_ssh1=${enable_ssh1:-"no"}
|
||||
AC_ARG_ENABLE(ssh1, AC_HELP_STRING([--enable-ssh1], [enable SSH1 support]))
|
||||
AC_MSG_CHECKING([for SSH1 support])
|
||||
if test "$enable_ssh1" = "yes" ; then
|
||||
AC_DEFINE(HAVE_SSH1,1,[Define to 1 if you want to enable SSH1])
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_ssh1])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_LIBTOOL
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CHECK_PROG([DOXYGEN], [doxygen], [yes], [no])
|
||||
AM_CONDITIONAL([HAS_DOXYGEN], [test x"$DOXYGEN" = xyes])
|
||||
|
||||
# Checks for libraries.
|
||||
with_gcrypt=${with_gcrypt:-"no"}
|
||||
AC_ARG_WITH([libgcrypt],
|
||||
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt instead of libcrypto]),
|
||||
[if test "$withval" = "yes"; then
|
||||
with_gcrypt="yes"
|
||||
AC_CHECK_LIB([gcrypt], [gcry_md_open])
|
||||
fi], [ : ])
|
||||
|
||||
if test "$with_gcrypt" = "no"; then
|
||||
AC_CHECK_LIB([crypto], [BN_init])
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([z], [deflateInit_])
|
||||
AC_SEARCH_LIBS([hstrerror],[nsl resolv])
|
||||
AC_SEARCH_LIBS([getaddrinfo],[nsl socket])
|
||||
AC_SEARCH_LIBS([gethostbyname],[nsl resolv])
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h \
|
||||
sys/time.h termios.h unistd.h openssl/aes.h openssl/blowfish.h \
|
||||
openssl/des.h zlib.h sys/poll.h stdint.h pty.h gcrypt.h])
|
||||
|
||||
#Warn user when no openssl available
|
||||
if test "$with_gcrypt" = "no" && (test "$ac_cv_header_openssl_aes_h" != "yes" ||
|
||||
test "$ac_cv_header_openssl_blowfish_h" != "yes"); then
|
||||
echo "Can't find valid openssl files [e.g openssl/aes.h]"
|
||||
echo "Please install Openssl-devel"
|
||||
exit
|
||||
fi
|
||||
|
||||
#Warn user when no libgcrypt available
|
||||
if test "$with_gcrypt" = "yes" && test "$ac_cv_header_gcrypt_h" != "yes"; then
|
||||
echo "Can't find valid libgcrypt files [e.g gcrypt.h]"
|
||||
echo "Please install libgcrypt-devel"
|
||||
exit
|
||||
fi
|
||||
|
||||
#if ! test x"$ac_cv_header_zlib_h" != x"yes"; then
|
||||
# echo "Can't find zlib.h"
|
||||
# echo "Compression support won't be compiled in"
|
||||
#fi
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_HEADER_TIME
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_REALLOC
|
||||
AC_FUNC_SELECT_ARGTYPES
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS([endpwent getaddrinfo gethostbyname getpass memmove memset \
|
||||
cfmakeraw select socket strchr strdup strerror strstr poll])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
libssh/Makefile
|
||||
include/Makefile
|
||||
include/libssh/Makefile])
|
||||
AC_OUTPUT
|
||||
7
debian/README.Debian
vendored
7
debian/README.Debian
vendored
@@ -1,7 +0,0 @@
|
||||
libssh for Debian
|
||||
----------------------
|
||||
|
||||
This is a package for the library libssh with the soname 2.
|
||||
There are some other projects which have nearly the same name, so be careful.
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Fri, 27 Jul 2007 14:59:00 +0200
|
||||
50
debian/changelog
vendored
50
debian/changelog
vendored
@@ -1,50 +0,0 @@
|
||||
libssh (0.2+svn20070321-5) UNRELEASED; urgency=low
|
||||
|
||||
* NOT RELEASED YET
|
||||
* Use now official Vcs-* field
|
||||
* Use new Homepage field instead of old pseudo-field
|
||||
* BumpStandards-Version to 3.7.3 (no further changes)
|
||||
* debian/libssh-2-doc.doc-base: fix doc-base-unknown-section
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Thu, 08 Nov 2007 05:59:18 +0100
|
||||
|
||||
libssh (0.2+svn20070321-4) unstable; urgency=low
|
||||
|
||||
* debian/control:
|
||||
- Add XS-Vcs-Svn and XS-Vcs-Browser fields.
|
||||
- Change to ${binary:Version} for versionized dependencies.
|
||||
* Add debian/README.Debian to disambiguate the package name
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Fri, 27 Jul 2007 15:00:06 +0200
|
||||
|
||||
libssh (0.2+svn20070321-3) unstable; urgency=low
|
||||
|
||||
* Fix wrong versionized Replaces for -doc package
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Thu, 5 Apr 2007 17:58:27 +0200
|
||||
|
||||
libssh (0.2+svn20070321-2) unstable; urgency=low
|
||||
|
||||
* Split devel package into devel and documentation packages
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Mon, 26 Mar 2007 15:29:51 +0200
|
||||
|
||||
libssh (0.2+svn20070321-1) unstable; urgency=low
|
||||
|
||||
* New svn snapshot:
|
||||
- Fix broken include in include/libssh/server.h (Closes: #410020)
|
||||
- Fix nasty bug in server side code
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Mon, 26 Mar 2007 15:06:40 +0200
|
||||
|
||||
libssh (0.2-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
-- Laurent Bigonville <bigon@bigon.be> Fri, 29 Dec 2006 07:40:20 +0100
|
||||
|
||||
libssh (0.2~rc-1) unstable; urgency=low
|
||||
|
||||
* Initial release (Closes: #316872)
|
||||
|
||||
-- Jean-Philippe Garcia Ballester <giga@le-pec.org> Wed, 20 Dec 2006 23:56:50 +0100
|
||||
1
debian/compat
vendored
1
debian/compat
vendored
@@ -1 +0,0 @@
|
||||
5
|
||||
65
debian/control
vendored
65
debian/control
vendored
@@ -1,65 +0,0 @@
|
||||
Source: libssh
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Maintainer: Jean-Philippe Garcia Ballester <giga@le-pec.org>
|
||||
Uploaders: Laurent Bigonville <bigon@bigon.be>
|
||||
Build-Depends: cdbs, debhelper (>= 5), libgcrypt11-dev, libz-dev, doxygen
|
||||
Standards-Version: 3.7.3
|
||||
Vcs-Svn: svn://svn.berlios.de/libssh/trunk
|
||||
Vcs-Browser: http://svn.berlios.de/wsvn/libssh/trunk/
|
||||
Homepage: http://0xbadc0de.be/wiki/doku.php?id=libssh:libssh
|
||||
|
||||
Package: libssh-2
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: A tiny C SSH library
|
||||
The ssh library was designed to be used by programmers needing a working SSH
|
||||
implementation by the mean of a library. The complete control of the client
|
||||
is made by the programmer. With libssh, you can remotely execute programs,
|
||||
transfer files, use a secure and transparent tunnel for your remote programs.
|
||||
With its SFTP implementation, you can play with remote files easily.
|
||||
|
||||
Package: libssh-2-dev
|
||||
Provides: libssh-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Depends: libssh-2 (= ${binary:Version}), libgcrypt11-dev, zlib1g-dev
|
||||
Suggests: libssh-2-doc
|
||||
Conflicts: libssh-dev
|
||||
Description: A tiny C SSH library. Development files
|
||||
The ssh library was designed to be used by programmers needing a working SSH
|
||||
implementation by the mean of a library. The complete control of the client
|
||||
is made by the programmer. With libssh, you can remotely execute programs,
|
||||
transfer files, use a secure and transparent tunnel for your remote programs.
|
||||
With its SFTP implementation, you can play with remote files easily.
|
||||
.
|
||||
This package contains development files.
|
||||
|
||||
Package: libssh-2-dbg
|
||||
Priority: extra
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Depends: libssh-2 (= ${binary:Version})
|
||||
Description: A tiny C SSH library. Debug symbols
|
||||
The ssh library was designed to be used by programmers needing a working SSH
|
||||
implementation by the mean of a library. The complete control of the client
|
||||
is made by the programmer. With libssh, you can remotely execute programs,
|
||||
transfer files, use a secure and transparent tunnel for your remote programs.
|
||||
With its SFTP implementation, you can play with remote files easily.
|
||||
.
|
||||
This package contains debug symbols.
|
||||
|
||||
Package: libssh-2-doc
|
||||
Section: doc
|
||||
Architecture: all
|
||||
Suggests: doc-base
|
||||
Replaces: libssh-2-dev (<< 0.2+svn20070321-2)
|
||||
Description: A tiny C SSH library. Documentation files
|
||||
The ssh library was designed to be used by programmers needing a working SSH
|
||||
implementation by the mean of a library. The complete control of the client
|
||||
is made by the programmer. With libssh, you can remotely execute programs,
|
||||
transfer files, use a secure and transparent tunnel for your remote programs.
|
||||
With its SFTP implementation, you can play with remote files easily.
|
||||
.
|
||||
This package contains documentation files.
|
||||
33
debian/copyright
vendored
33
debian/copyright
vendored
@@ -1,33 +0,0 @@
|
||||
This package was debianized by Laurent Bigonville <bigon@bigon.be> on
|
||||
Thu, 16 Nov 2006 20:34:01 +0100.
|
||||
|
||||
It was downloaded from http://www.0xbadc0de.be/
|
||||
|
||||
Upstream Author: Aris Adamantiadis (aka spacewalker) <aris@0xbadc0de.be>
|
||||
|
||||
Copyright: 2003 Aris Adamantiadis
|
||||
|
||||
License:
|
||||
|
||||
This package 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 of the License, or (at your option) any later version.
|
||||
|
||||
This package 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 package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in `/usr/share/common-licenses/LGPL'.
|
||||
|
||||
|
||||
The Debian packaging is
|
||||
(C) 2005-2006, Jean-Philippe Garcia Ballester <giga@le-pec.org>,
|
||||
(C) 2006-2007, Laurent Bigonville <bigon@bigon.be> and
|
||||
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
||||
2
debian/libssh-2-dev.install
vendored
2
debian/libssh-2-dev.install
vendored
@@ -1,2 +0,0 @@
|
||||
debian/tmp/usr/include/*
|
||||
debian/tmp/usr/lib/libssh.{a,la,so}
|
||||
9
debian/libssh-2-doc.doc-base
vendored
9
debian/libssh-2-doc.doc-base
vendored
@@ -1,9 +0,0 @@
|
||||
Document: libssh
|
||||
Title: Debian libssh Manual
|
||||
Author: Aris Adamantiadis <aris@0xbadc0de.be>
|
||||
Abstract: This manual describes libssh API.
|
||||
Section: Apps/Programming
|
||||
|
||||
Format: HTML
|
||||
Index: /usr/share/doc/libssh-2-doc/html/index.html
|
||||
Files: /usr/share/doc/libssh-2-doc/html/*
|
||||
1
debian/libssh-2-doc.docs
vendored
1
debian/libssh-2-doc.docs
vendored
@@ -1 +0,0 @@
|
||||
debian/tmp/usr/share/doc/libssh/html
|
||||
1
debian/libssh-2-doc.examples
vendored
1
debian/libssh-2-doc.examples
vendored
@@ -1 +0,0 @@
|
||||
debian/tmp/usr/share/doc/libssh/examples/*
|
||||
1
debian/libssh-2-doc.manpages
vendored
1
debian/libssh-2-doc.manpages
vendored
@@ -1 +0,0 @@
|
||||
doxygen/man/man3/ssh_*
|
||||
1
debian/libssh-2.install
vendored
1
debian/libssh-2.install
vendored
@@ -1 +0,0 @@
|
||||
debian/tmp/usr/lib/libssh.so.*
|
||||
2
debian/libssh-2.lintian-overrides
vendored
2
debian/libssh-2.lintian-overrides
vendored
@@ -1,2 +0,0 @@
|
||||
# We use libssh-2 name to avoid name clash with libssh2 package.
|
||||
libssh-2: package-name-doesnt-match-sonames libssh2
|
||||
21
debian/rules
vendored
21
debian/rules
vendored
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
# Sample debian/rules that uses cdbs. Originaly written by Robert Millan.
|
||||
# This file is public domain.
|
||||
|
||||
DEB_AUTO_CLEANUP_RCS := yes
|
||||
|
||||
# Add here any variable or target overrides you need
|
||||
|
||||
|
||||
include /usr/share/cdbs/1/class/autotools.mk
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
#include /usr/share/cdbs/1/rules/simple-patchsys.mk
|
||||
|
||||
DEB_CONFIGURE_EXTRA_FLAGS = --with-libgcrypt --enable-ssh1
|
||||
DEB_DBG_PACKAGE_libssh-2 = libssh-2-dbg
|
||||
|
||||
install/libssh-2::
|
||||
install -D -m 644 debian/libssh-2.lintian-overrides debian/libssh-2/usr/share/lintian/overrides/libssh-2
|
||||
|
||||
install/libssh-2-doc::
|
||||
make install-doc DESTDIR=debian/tmp
|
||||
2
debian/watch
vendored
2
debian/watch
vendored
@@ -1,2 +0,0 @@
|
||||
version=3
|
||||
http://0xbadc0de.be/libssh/libssh-(.*)\.tgz
|
||||
5
doc/CMakeLists.txt
Normal file
5
doc/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Build the documentation
|
||||
#
|
||||
include(UseDoxygen OPTIONAL)
|
||||
|
||||
1540
doc/doxy.config.in
Normal file
1540
doc/doxy.config.in
Normal file
File diff suppressed because it is too large
Load Diff
3
include/CMakeLists.txt
Normal file
3
include/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
project(headers C)
|
||||
|
||||
add_subdirectory(libssh)
|
||||
@@ -1 +0,0 @@
|
||||
SUBDIRS = libssh
|
||||
38
include/libssh/CMakeLists.txt
Normal file
38
include/libssh/CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
project(libssh-headers C)
|
||||
|
||||
set(libssh_HDRS
|
||||
libssh.h
|
||||
crypto.h
|
||||
ssh2.h
|
||||
)
|
||||
|
||||
if (WITH_SFTP)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
sftp.h
|
||||
)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
if (WITH_SSH1)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
ssh1.h
|
||||
)
|
||||
endif (WITH_SSH1)
|
||||
|
||||
if (WITH_SERVER)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
server.h
|
||||
)
|
||||
endif (WITH_SERVER)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${libssh_HDRS}
|
||||
DESTINATION
|
||||
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||
COMPONENT
|
||||
headers
|
||||
)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
libsshdir = $(includedir)/libssh
|
||||
libssh_HEADERS = crypto.h libssh.h priv.h server.h sftp.h ssh1.h ssh2.h
|
||||
nodist_libssh_HEADERS = config.h
|
||||
|
||||
config.h:
|
||||
$(LN_S) $(top_builddir)/config.h ./config.h
|
||||
|
||||
DISTCLEANFILES = config.h
|
||||
49
include/libssh/agent.h
Normal file
49
include/libssh/agent.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef __AGENT_H
|
||||
#define __AGENT_H
|
||||
|
||||
/* Messages for the authentication agent connection. */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||
#define SSH_AGENTC_RSA_CHALLENGE 3
|
||||
#define SSH_AGENT_RSA_RESPONSE 4
|
||||
#define SSH_AGENT_FAILURE 5
|
||||
#define SSH_AGENT_SUCCESS 6
|
||||
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
|
||||
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
|
||||
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
|
||||
|
||||
/* private OpenSSH extensions for SSH2 */
|
||||
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
|
||||
#define SSH2_AGENT_IDENTITIES_ANSWER 12
|
||||
#define SSH2_AGENTC_SIGN_REQUEST 13
|
||||
#define SSH2_AGENT_SIGN_RESPONSE 14
|
||||
#define SSH2_AGENTC_ADD_IDENTITY 17
|
||||
#define SSH2_AGENTC_REMOVE_IDENTITY 18
|
||||
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
|
||||
|
||||
/* smartcard */
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
|
||||
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||
|
||||
/* lock/unlock the agent */
|
||||
#define SSH_AGENTC_LOCK 22
|
||||
#define SSH_AGENTC_UNLOCK 23
|
||||
|
||||
/* add key with constraints */
|
||||
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
|
||||
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
/* extended failure messages */
|
||||
#define SSH2_AGENT_FAILURE 30
|
||||
|
||||
/* additional error code for ssh.com's ssh-agent2 */
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
|
||||
#define SSH_AGENT_OLD_SIGNATURE 0x01
|
||||
|
||||
#endif /* __AGENT_H */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
@@ -1,44 +1,43 @@
|
||||
/*
|
||||
Copyright 2003 Aris Adamantiadis
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
/*
|
||||
* crypto.h is an include file for internal structures of libssh
|
||||
* It hasn't to be into the final development set of files (and btw
|
||||
* the filename would cause problems on most systems).
|
||||
*/
|
||||
|
||||
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. */
|
||||
|
||||
/* Crypto.h is an include file for internal structures of libssh */
|
||||
/* It hasn't to be into the final development set of files (and btw the filename would cause problems on most systems) */
|
||||
/* Openssl has (really) stupid defines */
|
||||
#ifdef set_key
|
||||
#undef set_key
|
||||
#endif
|
||||
#ifdef cbc_encrypt
|
||||
#undef cbc_encrypt
|
||||
#endif
|
||||
#ifdef cbc_decrypt
|
||||
#undef cbc_decrypt
|
||||
#endif
|
||||
#ifdef des_set_key
|
||||
#undef des_set_key
|
||||
#endif
|
||||
|
||||
#ifdef GCRYPT
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
struct crypto_struct {
|
||||
char *name; /* ssh name of the algorithm */
|
||||
const char *name; /* ssh name of the algorithm */
|
||||
unsigned int blocksize; /* blocksize of the algo */
|
||||
unsigned int keylen; /* length of the key structure */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
@@ -48,15 +47,22 @@ struct crypto_struct {
|
||||
#endif
|
||||
unsigned int keysize; /* bytes of key used. != keylen */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV); /* sets the new key for immediate use */
|
||||
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
|
||||
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
|
||||
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
|
||||
/* sets the new key for immediate use */
|
||||
int (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
|
||||
int (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
|
||||
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key); /* sets the new key for immediate use */
|
||||
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
|
||||
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
|
||||
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
|
||||
/* sets the new key for immediate use */
|
||||
int (*set_encrypt_key)(struct crypto_struct *cipher, void *key);
|
||||
int (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
|
||||
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,
|
||||
unsigned long len, void *IV);
|
||||
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,
|
||||
unsigned long len, void *IV);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1,46 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2003-2008 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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_H
|
||||
#define _LIBSSH_H
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#else /* _MSC_VER */
|
||||
//visual studio hasn't inttypes.h so it doesn't know uint32_t
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
#include <sys/select.h> /* for fd_set * */
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#else
|
||||
#include <sys/select.h> /* for fd_set * */
|
||||
#include <netdb.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define SSH_STRINGIFY(s) SSH_TOSTRING(s)
|
||||
#define SSH_TOSTRING(s) #s
|
||||
|
||||
#define LIBSSH_VERSION "libssh-0.2.1-svn"
|
||||
/* 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 3
|
||||
#define LIBSSH_VERSION_MICRO 1
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
#define LIBSSH_VERSION SSH_VERSION(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
LIBSSH_VERSION_MICRO)
|
||||
|
||||
/* GCC have printf type attribute check. */
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE(a,b)
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -52,6 +77,7 @@ typedef struct public_key_struct PUBLIC_KEY;
|
||||
typedef struct private_key_struct PRIVATE_KEY;
|
||||
typedef struct ssh_options_struct SSH_OPTIONS;
|
||||
typedef struct channel_struct CHANNEL;
|
||||
typedef struct agent_struct AGENT;
|
||||
typedef struct ssh_session SSH_SESSION;
|
||||
typedef struct ssh_kbdint SSH_KBDINT;
|
||||
|
||||
@@ -107,6 +133,7 @@ typedef int socket_t;
|
||||
#define SSH_SERVER_KNOWN_OK 1
|
||||
#define SSH_SERVER_KNOWN_CHANGED 2
|
||||
#define SSH_SERVER_FOUND_OTHER 3
|
||||
#define SSH_SERVER_FILE_NOT_FOUND 4
|
||||
|
||||
#ifndef MD5_DIGEST_LEN
|
||||
#define MD5_DIGEST_LEN 16
|
||||
@@ -118,15 +145,18 @@ typedef int socket_t;
|
||||
#define SSH_FATAL 2
|
||||
#define SSH_EINTR 3
|
||||
|
||||
/* error return codes */
|
||||
/* Error return codes */
|
||||
#define SSH_OK 0 /* No error */
|
||||
#define SSH_ERROR -1 /* error of some kind */
|
||||
#define SSH_AGAIN 1 /* the nonblocking call must be repeated */
|
||||
#define SSH_ERROR -1 /* Error of some kind */
|
||||
#define SSH_AGAIN -2 /* The nonblocking call must be repeated */
|
||||
#define SSH_EOF -127 /* We have already a eof */
|
||||
|
||||
char *ssh_get_error(void *error);
|
||||
const char *ssh_get_error(void *error);
|
||||
int ssh_get_error_code(void *error);
|
||||
void ssh_say(int priority, const char *format, ...);
|
||||
void ssh_set_verbosity(int num);
|
||||
|
||||
/* version checks */
|
||||
const char *ssh_version(int req_version);
|
||||
|
||||
/** \addtogroup ssh_log
|
||||
* @{
|
||||
*/
|
||||
@@ -159,36 +189,41 @@ enum {
|
||||
#define SSH_LOG_FUNCTIONS 4 // every function in and return
|
||||
*/
|
||||
/* log.c */
|
||||
void ssh_log(SSH_SESSION *session, int prioriry, char *format, ...);
|
||||
void ssh_log(SSH_SESSION *session, int prioriry, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||
|
||||
/* session.c */
|
||||
SSH_SESSION *ssh_new();
|
||||
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options);
|
||||
SSH_SESSION *ssh_new(void);
|
||||
socket_t ssh_get_fd(SSH_SESSION *session);
|
||||
void ssh_silent_disconnect(SSH_SESSION *session);
|
||||
int ssh_get_version(SSH_SESSION *session);
|
||||
int ssh_get_status(SSH_SESSION *session);
|
||||
const char *ssh_get_disconnect_message(SSH_SESSION *session);
|
||||
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options);
|
||||
void ssh_set_fd_toread(SSH_SESSION *session);
|
||||
void ssh_set_fd_towrite(SSH_SESSION *session);
|
||||
void ssh_set_fd_except(SSH_SESSION *session);
|
||||
void ssh_set_blocking(SSH_SESSION *session, int blocking);
|
||||
void ssh_silent_disconnect(SSH_SESSION *session);
|
||||
|
||||
|
||||
/* client.c */
|
||||
int ssh_connect(SSH_SESSION *session);
|
||||
void ssh_disconnect(SSH_SESSION *session);
|
||||
int ssh_service_request(SSH_SESSION *session,char *service);
|
||||
int ssh_service_request(SSH_SESSION *session, const char *service);
|
||||
char *ssh_get_issue_banner(SSH_SESSION *session);
|
||||
int ssh_get_openssh_version(SSH_SESSION *session);
|
||||
/* get copyright informations */
|
||||
const char *ssh_copyright();
|
||||
const char *ssh_copyright(void);
|
||||
|
||||
/* string.h */
|
||||
|
||||
/* You can use these functions, they won't change */
|
||||
/* makestring returns a newly allocated string from a char * ptr */
|
||||
/* string_from_char returns a newly allocated string from a char *ptr */
|
||||
STRING *string_from_char(const char *what);
|
||||
/* it returns the string len in host byte orders. str->size is big endian warning ! */
|
||||
int string_len(STRING *str);
|
||||
STRING *string_new(unsigned int size);
|
||||
/* string_fill copies the data in the string. it does NOT check for boundary so allocate enough place with string_new */
|
||||
void string_fill(STRING *str, const void *data,int len);
|
||||
size_t string_len(STRING *str);
|
||||
STRING *string_new(size_t size);
|
||||
/* string_fill copies the data in the string. */
|
||||
int string_fill(STRING *str, const void *data, size_t len);
|
||||
/* returns a newly allocated char array with the str string and a final nul caracter */
|
||||
char *string_to_char(STRING *str);
|
||||
STRING *string_copy(STRING *str);
|
||||
@@ -197,99 +232,127 @@ void string_burn(STRING *str);
|
||||
void *string_data(STRING *str);
|
||||
void string_free(STRING *str);
|
||||
|
||||
/* deprecated */
|
||||
void ssh_crypto_init();
|
||||
|
||||
/* useful for debug */
|
||||
void ssh_print_hexa(char *descr, const unsigned char *what, int len);
|
||||
char *ssh_get_hexa(const unsigned char *what, size_t len);
|
||||
void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||
int ssh_get_random(void *where,int len,int strong);
|
||||
|
||||
/* this one can be called by the client to see the hash of the public key before accepting it */
|
||||
int ssh_get_pubkey_hash(SSH_SESSION *session,unsigned char hash[MD5_DIGEST_LEN]);
|
||||
int ssh_get_pubkey_hash(SSH_SESSION *session, unsigned char **hash);
|
||||
STRING *ssh_get_pubkey(SSH_SESSION *session);
|
||||
|
||||
/* in connect.c */
|
||||
int ssh_fd_poll(SSH_SESSION *session,int *write, int *except);
|
||||
int ssh_select(CHANNEL **channels,CHANNEL **outchannels, socket_t maxfd, fd_set *readfds, struct timeval *timeout);
|
||||
int ssh_select(CHANNEL **channels, CHANNEL **outchannels, socket_t maxfd,
|
||||
fd_set *readfds, struct timeval *timeout);
|
||||
|
||||
void publickey_free(PUBLIC_KEY *key);
|
||||
|
||||
/* in keyfiles.c */
|
||||
|
||||
PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,char *passphrase);
|
||||
PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session, const char *filename,
|
||||
int type, const char *passphrase);
|
||||
STRING *publickey_to_string(PUBLIC_KEY *key);
|
||||
PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv);
|
||||
void private_key_free(PRIVATE_KEY *prv);
|
||||
STRING *publickey_from_file(SSH_SESSION *session, char *filename,int *_type);
|
||||
STRING *publickey_from_next_file(SSH_SESSION *session,char **pub_keys_path,char **keys_path,
|
||||
char **privkeyfile,int *type,int *count);
|
||||
void privatekey_free(PRIVATE_KEY *prv);
|
||||
STRING *publickey_from_file(SSH_SESSION *session, const char *filename,
|
||||
int *type);
|
||||
int ssh_is_server_known(SSH_SESSION *session);
|
||||
int ssh_write_knownhost(SSH_SESSION *session);
|
||||
|
||||
/* in channels.c */
|
||||
|
||||
CHANNEL *channel_new(SSH_SESSION *session);
|
||||
int channel_open_forward(CHANNEL *channel,char *remotehost, int remoteport, char *sourcehost, int localport);
|
||||
int channel_open_forward(CHANNEL *channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport);
|
||||
int channel_open_session(CHANNEL *channel);
|
||||
void channel_free(CHANNEL *channel);
|
||||
int channel_request_pty(CHANNEL *channel);
|
||||
int channel_request_pty_size(CHANNEL *channel, char *term,int cols, int rows);
|
||||
int channel_request_pty_size(CHANNEL *channel, const char *term,
|
||||
int cols, int rows);
|
||||
int channel_change_pty_size(CHANNEL *channel,int cols,int rows);
|
||||
int channel_request_shell(CHANNEL *channel);
|
||||
int channel_request_subsystem(CHANNEL *channel, char *system);
|
||||
int channel_request_env(CHANNEL *channel,char *name, char *value);
|
||||
int channel_request_exec(CHANNEL *channel, char *cmd);
|
||||
int channel_request_subsystem(CHANNEL *channel, const char *system);
|
||||
int channel_request_env(CHANNEL *channel, const char *name, const char *value);
|
||||
int channel_request_exec(CHANNEL *channel, const char *cmd);
|
||||
int channel_request_sftp(CHANNEL *channel);
|
||||
int channel_write(CHANNEL *channel,void *data,int len);
|
||||
int channel_write(CHANNEL *channel, const void *data, u32 len);
|
||||
int channel_send_eof(CHANNEL *channel);
|
||||
int channel_is_eof(CHANNEL *channel);
|
||||
int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr);
|
||||
int channel_read(CHANNEL *channel, void *dest, u32 count, int is_stderr);
|
||||
int channel_read_buffer(CHANNEL *channel, BUFFER *buffer, u32 count,
|
||||
int is_stderr);
|
||||
int channel_poll(CHANNEL *channel, int is_stderr);
|
||||
int channel_close(CHANNEL *channel);
|
||||
int channel_read_nonblocking(CHANNEL *channel, char *dest, int len, int is_stderr);
|
||||
void channel_set_blocking(CHANNEL *channel, int blocking);
|
||||
int channel_read_nonblocking(CHANNEL *channel, void *dest, u32 count,
|
||||
int is_stderr);
|
||||
int channel_is_open(CHANNEL *channel);
|
||||
int channel_is_closed(CHANNEL *channel);
|
||||
int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptchans, struct
|
||||
timeval * timeout);
|
||||
SSH_SESSION *channel_get_session(CHANNEL *channel);
|
||||
int channel_get_exit_status(CHANNEL *channel);
|
||||
/* in options.c */
|
||||
|
||||
SSH_OPTIONS *ssh_options_new();
|
||||
/**
|
||||
* @brief SSH authentication callback.
|
||||
*
|
||||
* @param prompt Prompt to be displayed.
|
||||
* @param buf Buffer to save the password. You should null-terminate it.
|
||||
* @param len Length of the buffer.
|
||||
* @param echo Enable or disable the echo of what you type.
|
||||
* @param verify Should the password be verified?
|
||||
* @param userdata Userdata to be passed to the callback function. Useful
|
||||
* for GUI applications.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
|
||||
int echo, int verify, void *userdata);
|
||||
|
||||
SSH_OPTIONS *ssh_options_new(void);
|
||||
SSH_OPTIONS *ssh_options_copy(SSH_OPTIONS *opt);
|
||||
void ssh_options_free(SSH_OPTIONS *opt);
|
||||
int ssh_options_set_wanted_algos(SSH_OPTIONS *opt, int algo, const char *list);
|
||||
void ssh_options_set_username(SSH_OPTIONS *opt, const char *username);
|
||||
void ssh_options_set_port(SSH_OPTIONS *opt, unsigned int port);
|
||||
int ssh_options_set_username(SSH_OPTIONS *opt, const char *username);
|
||||
int ssh_options_set_port(SSH_OPTIONS *opt, unsigned int port);
|
||||
int ssh_options_getopt(SSH_OPTIONS *options, int *argcptr, char **argv);
|
||||
void ssh_options_set_host(SSH_OPTIONS *opt, const char *host);
|
||||
void ssh_options_set_fd(SSH_OPTIONS *opt, socket_t fd);
|
||||
void ssh_options_set_bind(SSH_OPTIONS *opt, const char *bindaddr, int port);
|
||||
void ssh_options_set_identity(SSH_OPTIONS *opt, const char *identity);
|
||||
void ssh_options_set_status_callback(SSH_OPTIONS *opt, void (*callback)
|
||||
int ssh_options_set_host(SSH_OPTIONS *opt, const char *host);
|
||||
int ssh_options_set_fd(SSH_OPTIONS *opt, socket_t fd);
|
||||
int ssh_options_set_bind(SSH_OPTIONS *opt, const char *bindaddr, int port);
|
||||
int ssh_options_set_ssh_dir(SSH_OPTIONS *opt, const char *dir);
|
||||
int ssh_options_set_known_hosts_file(SSH_OPTIONS *opt, const char *dir);
|
||||
int ssh_options_set_identity(SSH_OPTIONS *opt, const char *identity);
|
||||
int ssh_options_set_banner(SSH_OPTIONS *opt, const char *banner);
|
||||
int ssh_options_set_status_callback(SSH_OPTIONS *opt, void (*callback)
|
||||
(void *arg, float status), void *arg);
|
||||
void ssh_options_set_timeout(SSH_OPTIONS *opt, long seconds, long usec);
|
||||
void ssh_options_set_ssh_dir(SSH_OPTIONS *opt, const char *dir);
|
||||
void ssh_options_set_known_hosts_file(SSH_OPTIONS *opt, const char *dir);
|
||||
void ssh_options_allow_ssh1(SSH_OPTIONS *opt, int allow);
|
||||
void ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow);
|
||||
void ssh_options_set_dsa_server_key(SSH_OPTIONS *opt, const char *dsakey);
|
||||
void ssh_options_set_rsa_server_key(SSH_OPTIONS *opt, const char *rsakey);
|
||||
void ssh_options_set_log_function(SSH_OPTIONS *opt,
|
||||
void (*callback)(const char *message, SSH_SESSION *session, int verbosity ));
|
||||
void ssh_options_set_log_verbosity(SSH_OPTIONS *opt, int verbosity);
|
||||
int ssh_options_set_timeout(SSH_OPTIONS *opt, long seconds, long usec);
|
||||
int ssh_options_allow_ssh1(SSH_OPTIONS *opt, int allow);
|
||||
int ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow);
|
||||
int ssh_options_set_log_function(SSH_OPTIONS *opt,
|
||||
void (*callback)(const char *message, SSH_SESSION *session, int verbosity));
|
||||
int ssh_options_set_log_verbosity(SSH_OPTIONS *opt, int verbosity);
|
||||
int ssh_options_set_dsa_server_key(SSH_OPTIONS *opt, const char *dsakey);
|
||||
int ssh_options_set_rsa_server_key(SSH_OPTIONS *opt, const char *rsakey);
|
||||
int ssh_options_set_auth_callback(SSH_OPTIONS *opt, ssh_auth_callback cb,
|
||||
void *userdata);
|
||||
|
||||
|
||||
/* buffer.c */
|
||||
|
||||
/** creates a new buffer
|
||||
*/
|
||||
BUFFER *buffer_new();
|
||||
BUFFER *buffer_new(void);
|
||||
void buffer_free(BUFFER *buffer);
|
||||
/* buffer_get returns a pointer to the begining of the buffer. no position is taken into account */
|
||||
void *buffer_get(BUFFER *buffer);
|
||||
/* same here */
|
||||
int buffer_get_len(BUFFER *buffer);
|
||||
u32 buffer_get_len(BUFFER *buffer);
|
||||
|
||||
|
||||
/* in auth.c */
|
||||
int ssh_auth_list(SSH_SESSION *session);
|
||||
/* these functions returns AUTH_ERROR is some serious error has happened,
|
||||
AUTH_SUCCESS if success,
|
||||
AUTH_PARTIAL if partial success,
|
||||
@@ -299,18 +362,24 @@ int ssh_userauth_none(SSH_SESSION *session, const char *username);
|
||||
int ssh_userauth_password(SSH_SESSION *session, const char *username, const char *password);
|
||||
int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username, int type, STRING *publickey);
|
||||
int ssh_userauth_pubkey(SSH_SESSION *session, const char *username, STRING *publickey, PRIVATE_KEY *privatekey);
|
||||
int ssh_userauth_autopubkey(SSH_SESSION *session);
|
||||
int ssh_userauth_agent_pubkey(SSH_SESSION *session, const char *username,
|
||||
PUBLIC_KEY *publickey);
|
||||
int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase);
|
||||
int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, const char *submethods);
|
||||
int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session);
|
||||
char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
|
||||
char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
|
||||
char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, int i, char *echo);
|
||||
void ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i, const char *answer);
|
||||
const char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
|
||||
const char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
|
||||
const char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session, unsigned int i, char *echo);
|
||||
int ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i,
|
||||
const char *answer);
|
||||
|
||||
|
||||
/* init.c */
|
||||
int ssh_finalize();
|
||||
int ssh_init(void);
|
||||
int ssh_finalize(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* _LIBSSH_H */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2003-2008 Aris Adamantiadis
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
|
||||
/* priv.h file */
|
||||
/* This include file contains everything you shouldn't deal with in user programs. */
|
||||
/* Consider that anything in this file might change without notice; libssh.h file will keep */
|
||||
/* backward compatibility on binary & source */
|
||||
/*
|
||||
* priv.h file
|
||||
* This include file contains everything you shouldn't deal with in
|
||||
* user programs. Consider that anything in this file might change
|
||||
* without notice; libssh.h file will keep backward compatibility
|
||||
* on binary & source
|
||||
*/
|
||||
|
||||
#ifndef _LIBSSH_PRIV_H
|
||||
#define _LIBSSH_PRIV_H
|
||||
@@ -37,8 +41,8 @@ MA 02111-1307, USA. */
|
||||
/* some constants */
|
||||
#define MAX_PACKET_LEN 262144
|
||||
#define ERROR_BUFFERLEN 1024
|
||||
#define CLIENTBANNER1 "SSH-1.5-" LIBSSH_VERSION
|
||||
#define CLIENTBANNER2 "SSH-2.0-" LIBSSH_VERSION
|
||||
#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
|
||||
/* some types for public keys */
|
||||
#define TYPE_DSS 1
|
||||
@@ -129,6 +133,28 @@ typedef BN_CTX* bignum_CTX;
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/* poll support */
|
||||
#ifdef HAVE_POLL
|
||||
#include <poll.h>
|
||||
typedef struct pollfd pollfd_t;
|
||||
#else /* HAVE_POLL */
|
||||
typedef struct pollfd_s {
|
||||
socket_t fd; /* file descriptor */
|
||||
short events; /* requested events */
|
||||
short revents; /* returned events */
|
||||
} pollfd_t;
|
||||
|
||||
#define POLLIN 0x001 /* There is data to read. */
|
||||
#define POLLPRI 0x002 /* There is urgent data to read. */
|
||||
#define POLLOUT 0x004 /* Writing now will not block. */
|
||||
|
||||
#define POLLERR 0x008 /* Error condition. */
|
||||
#define POLLHUP 0x010 /* Hung up. */
|
||||
#define POLLNVAL 0x020 /* Invalid polling request. */
|
||||
|
||||
typedef unsigned long int nfds_t;
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
/* wrapper.c */
|
||||
MD5CTX md5_init(void);
|
||||
void md5_update(MD5CTX c, const void *data, unsigned long len);
|
||||
@@ -148,15 +174,19 @@ void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
|
||||
struct string_struct {
|
||||
u32 size;
|
||||
unsigned char string[MAX_PACKET_LEN];
|
||||
} __attribute__ ((packed));
|
||||
}
|
||||
#if !defined(__SUNPRO_C)
|
||||
__attribute__ ((packed))
|
||||
#endif
|
||||
;
|
||||
|
||||
/** Describes a buffer state at a moment
|
||||
*/
|
||||
struct buffer_struct {
|
||||
char *data;
|
||||
int used;
|
||||
int allocated;
|
||||
int pos;
|
||||
u32 used;
|
||||
u32 allocated;
|
||||
u32 pos;
|
||||
};
|
||||
|
||||
/* i should remove it one day */
|
||||
@@ -173,7 +203,7 @@ typedef struct kex_struct {
|
||||
|
||||
struct public_key_struct {
|
||||
int type;
|
||||
char *type_c; /* Don't free it ! it is static */
|
||||
const char *type_c; /* Don't free it ! it is static */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t dsa_pub;
|
||||
gcry_sexp_t rsa_pub;
|
||||
@@ -228,7 +258,8 @@ struct ssh_options_struct {
|
||||
int use_nonexisting_algo; /* if user sets a not supported algorithm for kex, don't complain */
|
||||
char *wanted_methods[10]; /* the kex methods can be choosed. better use the kex fonctions to do that */
|
||||
void *wanted_cookie; /* wants a specific cookie to be sent ? if null, generate a new one */
|
||||
void *passphrase_function; /* this functions will be called if a keyphrase is needed. look keyfiles.c for more info */
|
||||
ssh_auth_callback auth_function; /* this functions will be called if e.g. a keyphrase is needed. */
|
||||
void *auth_userdata;
|
||||
void (*connect_status_function)(void *arg, float status); /* status callback function */
|
||||
void *connect_status_arg; /* arbitrary argument */
|
||||
long timeout; /* seconds */
|
||||
@@ -244,7 +275,7 @@ struct ssh_options_struct {
|
||||
typedef struct ssh_crypto_struct {
|
||||
bignum e,f,x,k,y;
|
||||
unsigned char session_id[SHA_DIGEST_LEN];
|
||||
|
||||
|
||||
unsigned char encryptIV[SHA_DIGEST_LEN*2];
|
||||
unsigned char decryptIV[SHA_DIGEST_LEN*2];
|
||||
|
||||
@@ -256,7 +287,7 @@ typedef struct ssh_crypto_struct {
|
||||
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
|
||||
struct crypto_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
||||
STRING *server_pubkey;
|
||||
char *server_pubkey_type;
|
||||
const char *server_pubkey_type;
|
||||
int do_compress_out; /* idem */
|
||||
int do_compress_in; /* don't set them, set the option instead */
|
||||
void *compress_out_ctx; /* don't touch it */
|
||||
@@ -283,6 +314,18 @@ struct channel_struct {
|
||||
void *userarg;
|
||||
int version;
|
||||
int blocking;
|
||||
int exit_status;
|
||||
};
|
||||
|
||||
struct agent_struct {
|
||||
struct socket *sock;
|
||||
BUFFER *ident;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
struct keys_struct {
|
||||
const char *privatekey;
|
||||
const char *publickey;
|
||||
};
|
||||
|
||||
struct ssh_session {
|
||||
@@ -294,37 +337,38 @@ struct ssh_session {
|
||||
int protoversion;
|
||||
int server;
|
||||
int client;
|
||||
int openssh;
|
||||
u32 send_seq;
|
||||
u32 recv_seq;
|
||||
/* status flags */
|
||||
int closed;
|
||||
int closed_by_except;
|
||||
|
||||
int connected;
|
||||
|
||||
int connected;
|
||||
/* !=0 when the user got a session handle */
|
||||
int alive;
|
||||
/* two previous are deprecated */
|
||||
int auth_service_asked;
|
||||
|
||||
|
||||
/* socket status */
|
||||
int blocking; // functions should block
|
||||
|
||||
STRING *banner; /* that's the issue banner from
|
||||
|
||||
STRING *banner; /* that's the issue banner from
|
||||
the server */
|
||||
char *remotebanner; /* that's the SSH- banner from
|
||||
remote host. */
|
||||
char *discon_msg; /* disconnect message from
|
||||
char *discon_msg; /* disconnect message from
|
||||
the remote host */
|
||||
BUFFER *in_buffer;
|
||||
PACKET in_packet;
|
||||
BUFFER *out_buffer;
|
||||
|
||||
|
||||
/* the states are used by the nonblocking stuff to remember */
|
||||
/* where it was before being interrupted */
|
||||
int packet_state;
|
||||
int dh_handshake_state;
|
||||
STRING *dh_server_signature; //information used by dh_handshake.
|
||||
|
||||
|
||||
KEX server_kex;
|
||||
KEX client_kex;
|
||||
BUFFER *in_hashbuf;
|
||||
@@ -334,8 +378,9 @@ struct ssh_session {
|
||||
|
||||
CHANNEL *channels; /* linked list of channels */
|
||||
int maxchannel;
|
||||
int exec_channel_opened; /* version 1 only. more
|
||||
int exec_channel_opened; /* version 1 only. more
|
||||
info in channels1.c */
|
||||
AGENT *agent; /* ssh agent */
|
||||
|
||||
/* keyb interactive data */
|
||||
struct ssh_kbdint *kbdint;
|
||||
@@ -344,7 +389,7 @@ struct ssh_session {
|
||||
PRIVATE_KEY *rsa_key;
|
||||
PRIVATE_KEY *dsa_key;
|
||||
/* auths accepted by server */
|
||||
int auth_methods;
|
||||
int auth_methods;
|
||||
int hostkeys; /* contains type of host key wanted by client, in server impl */
|
||||
struct ssh_message *ssh_message; /* ssh message */
|
||||
int log_verbosity; /*cached copy of the option structure */
|
||||
@@ -398,7 +443,7 @@ struct ssh_channel_request {
|
||||
u32 pxwidth;
|
||||
u32 pxheight;
|
||||
STRING *modes;
|
||||
|
||||
|
||||
/* env type request */
|
||||
char *var_name;
|
||||
char *var_value;
|
||||
@@ -416,25 +461,72 @@ struct ssh_message {
|
||||
struct ssh_channel_request channel_request;
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
/* agent.c */
|
||||
/**
|
||||
* @brief Create a new ssh agent structure.
|
||||
*
|
||||
* @return An allocated ssh agent structure or NULL on error.
|
||||
*/
|
||||
struct agent_struct *agent_new(struct ssh_session *session);
|
||||
|
||||
void agent_close(struct agent_struct *agent);
|
||||
|
||||
/**
|
||||
* @brief Free an allocated ssh agent structure.
|
||||
*
|
||||
* @param agent The ssh agent structure to free.
|
||||
*/
|
||||
void agent_free(struct agent_struct *agent);
|
||||
|
||||
/**
|
||||
* @brief Check if the ssh agent is running.
|
||||
*
|
||||
* @param session The ssh session to check for the agent.
|
||||
*
|
||||
* @return 1 if it is running, 0 if not.
|
||||
*/
|
||||
int agent_is_running(struct ssh_session *session);
|
||||
|
||||
int agent_get_ident_count(struct ssh_session *session);
|
||||
|
||||
struct public_key_struct *agent_get_next_ident(struct ssh_session *session,
|
||||
char **comment);
|
||||
|
||||
struct public_key_struct *agent_get_first_ident(struct ssh_session *session,
|
||||
char **comment);
|
||||
|
||||
STRING *agent_sign_data(struct ssh_session *session,
|
||||
struct buffer_struct *data,
|
||||
struct public_key_struct *pubkey);
|
||||
#endif
|
||||
|
||||
/* poll.c */
|
||||
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout);
|
||||
|
||||
/* socket.c */
|
||||
|
||||
struct socket;
|
||||
void ssh_socket_init();
|
||||
int ssh_socket_init(void);
|
||||
struct socket *ssh_socket_new(SSH_SESSION *session);
|
||||
void ssh_socket_free(struct socket *s);
|
||||
void ssh_socket_set_fd(struct socket *s, socket_t fd);
|
||||
socket_t ssh_socket_get_fd(struct socket *s);
|
||||
#ifndef _WIN32
|
||||
int ssh_socket_unix(struct socket *s, const char *path);
|
||||
#endif
|
||||
void ssh_socket_close(struct socket *s);
|
||||
int ssh_socket_read(struct socket *s, void *buffer, int len);
|
||||
int ssh_socket_write(struct socket *s,const void *buffer, int len);
|
||||
int ssh_socket_is_open(struct socket *s);
|
||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set);
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max);
|
||||
int ssh_socket_completeread(struct socket *s, void *buffer, int len);
|
||||
int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len);
|
||||
int ssh_socket_completeread(struct socket *s, void *buffer, u32 len);
|
||||
int ssh_socket_completewrite(struct socket *s, const void *buffer, u32 len);
|
||||
int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session, u32 len);
|
||||
int ssh_socket_nonblocking_flush(struct socket *s);
|
||||
int ssh_socket_blocking_flush(struct socket *s);
|
||||
int ssh_socket_poll(struct socket *s, int *write, int *except);
|
||||
int ssh_socket_poll(struct socket *s, int *writeable, int *except);
|
||||
void ssh_socket_set_towrite(struct socket *s);
|
||||
void ssh_socket_set_toread(struct socket *s);
|
||||
void ssh_socket_set_except(struct socket *s);
|
||||
@@ -451,27 +543,30 @@ int ssh_send_banner(SSH_SESSION *session, int is_server);
|
||||
char *ssh_get_banner(SSH_SESSION *session);
|
||||
|
||||
/* errors.c */
|
||||
void ssh_set_error(void *error,int code,char *descr,...);
|
||||
void ssh_set_error(void *error, int code, const char *descr, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||
|
||||
/* in dh.c */
|
||||
/* DH key generation */
|
||||
void dh_generate_e(SSH_SESSION *session);
|
||||
void ssh_print_bignum(char *which,bignum num);
|
||||
void dh_generate_x(SSH_SESSION *session);
|
||||
void dh_generate_y(SSH_SESSION *session);
|
||||
void dh_generate_f(SSH_SESSION *session);
|
||||
void ssh_crypto_finalize();
|
||||
void ssh_print_bignum(const char *which,bignum num);
|
||||
int dh_generate_e(SSH_SESSION *session);
|
||||
int dh_generate_f(SSH_SESSION *session);
|
||||
int dh_generate_x(SSH_SESSION *session);
|
||||
int dh_generate_y(SSH_SESSION *session);
|
||||
|
||||
int ssh_crypto_init(void);
|
||||
void ssh_crypto_finalize(void);
|
||||
|
||||
STRING *dh_get_e(SSH_SESSION *session);
|
||||
STRING *dh_get_f(SSH_SESSION *session);
|
||||
void dh_import_f(SSH_SESSION *session,STRING *f_string);
|
||||
void dh_import_e(SSH_SESSION *session, STRING *e_string);
|
||||
int dh_import_f(SSH_SESSION *session,STRING *f_string);
|
||||
int dh_import_e(SSH_SESSION *session, STRING *e_string);
|
||||
void dh_import_pubkey(SSH_SESSION *session,STRING *pubkey_string);
|
||||
void dh_build_k(SSH_SESSION *session);
|
||||
void make_sessionid(SSH_SESSION *session);
|
||||
int dh_build_k(SSH_SESSION *session);
|
||||
int make_sessionid(SSH_SESSION *session);
|
||||
/* add data for the final cookie */
|
||||
void hashbufin_add_cookie(SSH_SESSION *session,unsigned char *cookie);
|
||||
void hashbufout_add_cookie(SSH_SESSION *session);
|
||||
void generate_session_keys(SSH_SESSION *session);
|
||||
int hashbufin_add_cookie(SSH_SESSION *session, unsigned char *cookie);
|
||||
int hashbufout_add_cookie(SSH_SESSION *session);
|
||||
int generate_session_keys(SSH_SESSION *session);
|
||||
/* returns 1 if server signature ok, 0 otherwise. The NEXT crypto is checked, not the current one */
|
||||
int signature_verify(SSH_SESSION *session,STRING *signature);
|
||||
bignum make_string_bn(STRING *string);
|
||||
@@ -495,13 +590,13 @@ int packet_wait(SSH_SESSION *session,int type,int blocking);
|
||||
int packet_flush(SSH_SESSION *session, int enforce_blocking);
|
||||
/* connect.c */
|
||||
SSH_SESSION *ssh_session_new();
|
||||
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,const char
|
||||
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,const char
|
||||
*bind_addr, int port, long timeout, long usec);
|
||||
|
||||
/* in kex.c */
|
||||
extern char *ssh_kex_nums[];
|
||||
void ssh_send_kex(SSH_SESSION *session,int server_kex);
|
||||
void ssh_list_kex(KEX *kex);
|
||||
extern const char *ssh_kex_nums[];
|
||||
int ssh_send_kex(SSH_SESSION *session, int server_kex);
|
||||
void ssh_list_kex(SSH_SESSION *session, KEX *kex);
|
||||
int set_kex(SSH_SESSION *session);
|
||||
int ssh_get_kex(SSH_SESSION *session, int server_kex);
|
||||
int verify_existing_algo(int algo, const char *name);
|
||||
@@ -511,67 +606,79 @@ char *ssh_find_matching(const char *in_d, const char *what_d);
|
||||
|
||||
/* in keyfiles.c */
|
||||
|
||||
PRIVATE_KEY *_privatekey_from_file(void *session,char *filename,int type);
|
||||
PRIVATE_KEY *_privatekey_from_file(void *session, const char *filename,
|
||||
int type);
|
||||
STRING *try_publickey_from_file(SSH_SESSION *session,
|
||||
struct keys_struct keytab,
|
||||
char **privkeyfile, int *type);
|
||||
|
||||
/* in keys.c */
|
||||
char *ssh_type_to_char(int type);
|
||||
const char *ssh_type_to_char(int type);
|
||||
int ssh_type_from_name(const char *name);
|
||||
|
||||
PRIVATE_KEY *privatekey_make_dss(SSH_SESSION *session, BUFFER *buffer);
|
||||
PRIVATE_KEY *privatekey_make_rsa(SSH_SESSION *session, BUFFER *buffer,
|
||||
const char *type);
|
||||
PRIVATE_KEY *privatekey_from_string(SSH_SESSION *session, STRING *privkey_s);
|
||||
|
||||
PUBLIC_KEY *publickey_make_dss(SSH_SESSION *session, BUFFER *buffer);
|
||||
PUBLIC_KEY *publickey_make_rsa(SSH_SESSION *session, BUFFER *buffer,char *type);
|
||||
PUBLIC_KEY *publickey_make_rsa(SSH_SESSION *session, BUFFER *buffer, int type);
|
||||
PUBLIC_KEY *publickey_from_string(SSH_SESSION *session, STRING *pubkey_s);
|
||||
SIGNATURE *signature_from_string(SSH_SESSION *session, STRING *signature,PUBLIC_KEY *pubkey,int needed_type);
|
||||
void signature_free(SIGNATURE *sign);
|
||||
STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf,
|
||||
STRING *ssh_do_sign_with_agent(struct ssh_session *session,
|
||||
struct buffer_struct *buf, struct public_key_struct *publickey);
|
||||
STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf,
|
||||
PRIVATE_KEY *privatekey);
|
||||
STRING *ssh_sign_session_id(SSH_SESSION *session, PRIVATE_KEY *privatekey);
|
||||
STRING *ssh_encrypt_rsa1(SSH_SESSION *session, STRING *data, PUBLIC_KEY *key);
|
||||
/* channel.c */
|
||||
void channel_handle(SSH_SESSION *session, int type);
|
||||
CHANNEL *channel_new(SSH_SESSION *session);
|
||||
void channel_default_bufferize(CHANNEL *channel, void *data, int len,
|
||||
int channel_default_bufferize(CHANNEL *channel, void *data, int len,
|
||||
int is_stderr);
|
||||
u32 ssh_channel_new_id(SSH_SESSION *session);
|
||||
CHANNEL *ssh_channel_from_local(SSH_SESSION *session,u32 num);
|
||||
CHANNEL *ssh_channel_from_local(SSH_SESSION *session, u32 id);
|
||||
|
||||
/* options.c */
|
||||
|
||||
void ssh_options_free(SSH_OPTIONS *opt);
|
||||
/* this function must be called when no specific username has been asked. it has to guess it */
|
||||
int ssh_options_default_username(SSH_OPTIONS *opt);
|
||||
int ssh_options_default_ssh_dir(SSH_OPTIONS *opt);
|
||||
int ssh_options_default_known_hosts_file(SSH_OPTIONS *opt);
|
||||
|
||||
/* buffer.c */
|
||||
void buffer_add_ssh_string(BUFFER *buffer,STRING *string);
|
||||
void buffer_add_u8(BUFFER *buffer, u8 data);
|
||||
void buffer_add_u32(BUFFER *buffer, u32 data);
|
||||
void buffer_add_u64(BUFFER *buffer,u64 data);
|
||||
void buffer_add_data(BUFFER *buffer,const void *data, int len);
|
||||
void buffer_add_data_begin(BUFFER *buffer,const void *data,int len);
|
||||
void buffer_add_buffer(BUFFER *buffer, BUFFER *source);
|
||||
void buffer_reinit(BUFFER *buffer);
|
||||
int buffer_add_ssh_string(BUFFER *buffer, STRING *string);
|
||||
int buffer_add_u8(BUFFER *buffer, u8 data);
|
||||
int buffer_add_u32(BUFFER *buffer, u32 data);
|
||||
int buffer_add_u64(BUFFER *buffer, u64 data);
|
||||
int buffer_add_data(BUFFER *buffer, const void *data, u32 len);
|
||||
int buffer_prepend_data(BUFFER *buffer, const void *data, u32 len);
|
||||
int buffer_add_buffer(BUFFER *buffer, BUFFER *source);
|
||||
int buffer_reinit(BUFFER *buffer);
|
||||
|
||||
/* buffer_get_rest returns a pointer to the current position into the buffer */
|
||||
void *buffer_get_rest(BUFFER *buffer);
|
||||
/* buffer_get_rest_len returns the number of bytes which can be read */
|
||||
int buffer_get_rest_len(BUFFER *buffer);
|
||||
u32 buffer_get_rest_len(BUFFER *buffer);
|
||||
|
||||
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
|
||||
int buffer_get_u8(BUFFER *buffer,u8 *data);
|
||||
int buffer_get_u32(BUFFER *buffer,u32 *data);
|
||||
int buffer_get_u8(BUFFER *buffer, u8 *data);
|
||||
int buffer_get_u32(BUFFER *buffer, u32 *data);
|
||||
int buffer_get_u64(BUFFER *buffer, u64 *data);
|
||||
|
||||
int buffer_get_data(BUFFER *buffer,void *data,int requestedlen);
|
||||
u32 buffer_get_data(BUFFER *buffer, void *data, u32 requestedlen);
|
||||
/* buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
|
||||
STRING *buffer_get_ssh_string(BUFFER *buffer);
|
||||
/* gets a string out of a SSH-1 mpint */
|
||||
STRING *buffer_get_mpint(BUFFER *buffer);
|
||||
/* buffer_pass_bytes acts as if len bytes have been read (used for padding) */
|
||||
int buffer_pass_bytes_end(BUFFER *buffer,int len);
|
||||
int buffer_pass_bytes(BUFFER *buffer, int len);
|
||||
u32 buffer_pass_bytes_end(BUFFER *buffer, u32 len);
|
||||
u32 buffer_pass_bytes(BUFFER *buffer, u32 len);
|
||||
|
||||
/* in base64.c */
|
||||
BUFFER *base64_to_bin(char *source);
|
||||
unsigned char *bin_to_base64(unsigned char *source, int len);
|
||||
BUFFER *base64_to_bin(const char *source);
|
||||
unsigned char *bin_to_base64(const unsigned char *source, int len);
|
||||
|
||||
/* gzip.c */
|
||||
int compress_buffer(SSH_SESSION *session,BUFFER *buf);
|
||||
@@ -580,22 +687,22 @@ int decompress_buffer(SSH_SESSION *session,BUFFER *buf);
|
||||
/* wrapper.c */
|
||||
int crypt_set_algorithms(SSH_SESSION *);
|
||||
int crypt_set_algorithms_server(SSH_SESSION *session);
|
||||
CRYPTO *crypto_new();
|
||||
CRYPTO *crypto_new(void);
|
||||
void crypto_free(CRYPTO *crypto);
|
||||
|
||||
/* crc32.c */
|
||||
u32 ssh_crc32(char *buffer, int len);
|
||||
u32 ssh_crc32(const char *buf, u32 len);
|
||||
|
||||
/* auth1.c */
|
||||
int ssh_userauth1_none(SSH_SESSION *session, char *username);
|
||||
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, char *username,
|
||||
int ssh_userauth1_none(SSH_SESSION *session, const char *username);
|
||||
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
|
||||
int type, STRING *pubkey);
|
||||
int ssh_userauth1_password(SSH_SESSION *session, char *username,
|
||||
char *password);
|
||||
int ssh_userauth1_password(SSH_SESSION *session, const char *username,
|
||||
const char *password);
|
||||
/* in misc.c */
|
||||
/* gets the user home dir. */
|
||||
char *ssh_get_user_home_dir();
|
||||
int ssh_file_readaccess_ok(char *file);
|
||||
char *ssh_get_user_home_dir(void);
|
||||
int ssh_file_readaccess_ok(const char *file);
|
||||
|
||||
/* macro for byte ordering */
|
||||
u64 ntohll(u64);
|
||||
@@ -603,20 +710,29 @@ u64 ntohll(u64);
|
||||
|
||||
/* channels1.c */
|
||||
int channel_open_session1(CHANNEL *channel);
|
||||
int channel_request_pty_size1(CHANNEL *channel, char *terminal,int cols,
|
||||
int rows);
|
||||
int channel_request_pty_size1(CHANNEL *channel, const char *terminal,
|
||||
int cols, int rows);
|
||||
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows);
|
||||
int channel_request_shell1(CHANNEL *channel);
|
||||
int channel_request_exec1(CHANNEL *channel, char *cmd);
|
||||
void channel_handle1(SSH_SESSION *session,int type);
|
||||
int channel_write1(CHANNEL *channel, void *data, int len);
|
||||
int channel_request_exec1(CHANNEL *channel, const char *cmd);
|
||||
int channel_handle1(SSH_SESSION *session, int type);
|
||||
int channel_write1(CHANNEL *channel, const void *data, int len);
|
||||
|
||||
/* session.c */
|
||||
|
||||
int ssh_handle_packets(SSH_SESSION *session);
|
||||
|
||||
/* match.c */
|
||||
int match_hostname(const char *host, const char *pattern, unsigned int len);
|
||||
|
||||
/* log.c */
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#if defined(__SUNPRO_C)
|
||||
#define __FUNCTION__ __func__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _enter_function(sess) \
|
||||
do {\
|
||||
if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \
|
||||
@@ -636,6 +752,21 @@ int ssh_handle_packets(SSH_SESSION *session);
|
||||
#define enter_function() _enter_function(session)
|
||||
#define leave_function() _leave_function(session)
|
||||
|
||||
/** Free memory space */
|
||||
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
|
||||
|
||||
/** Zero a structure */
|
||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
|
||||
|
||||
/** Zero a structure given a pointer to the structure */
|
||||
#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
|
||||
|
||||
/** Get the size of an array */
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
/** Overwrite the complete string with 'X' */
|
||||
#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0)
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
/* gcrypt_missing.c */
|
||||
int my_gcry_dec2bn(bignum *bn, const char *data);
|
||||
@@ -643,7 +774,8 @@ char *my_gcry_bn2dec(bignum bn);
|
||||
#endif /* !HAVE_LIBGCRYPT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBSSH_PRIV_H */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
/*
|
||||
Copyright 2004 Aris Adamantiadis
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
/**
|
||||
* @defgroup ssh_server SSH Server
|
||||
* @addtogroup ssh_server
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
@@ -30,14 +37,88 @@ extern "C" {
|
||||
|
||||
typedef struct ssh_bind_struct SSH_BIND;
|
||||
|
||||
SSH_BIND *ssh_bind_new();
|
||||
/**
|
||||
* @brief Creates a new SSH server bind.
|
||||
*
|
||||
* @return A newly allocated ssh_bind session pointer.
|
||||
*/
|
||||
SSH_BIND *ssh_bind_new(void);
|
||||
|
||||
/**
|
||||
* @brief Set the opitons for the current SSH server bind.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to use.
|
||||
*
|
||||
* @param options The option structure to set.
|
||||
*/
|
||||
void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options);
|
||||
|
||||
/**
|
||||
* @brief Start listening to the socket.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to use.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int ssh_bind_listen(SSH_BIND *ssh_bind);
|
||||
void ssh_bind_set_blocking(SSH_BIND *ssh_bind,int blocking);
|
||||
int ssh_bind_get_fd(SSH_BIND *ssh_bind);
|
||||
int ssh_bind_set_toaccept(SSH_BIND *ssh_bind);
|
||||
|
||||
/**
|
||||
* @brief Set the session to blocking/nonblocking mode.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to use.
|
||||
*
|
||||
* @param blocking Zero for nonblocking mode.
|
||||
*/
|
||||
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking);
|
||||
|
||||
/**
|
||||
* @brief Recover the file descriptor from the session.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to get the fd from.
|
||||
*
|
||||
* @return The file descriptor.
|
||||
*/
|
||||
socket_t ssh_bind_get_fd(SSH_BIND *ssh_bind);
|
||||
|
||||
/**
|
||||
* @brief Set the file descriptor for a session.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to set the fd.
|
||||
*
|
||||
* @param fd The file descriptor.
|
||||
*/
|
||||
void ssh_bind_set_fd(SSH_BIND *ssh_bind, socket_t fd);
|
||||
|
||||
/**
|
||||
* @brief Allow the file descriptor to accept new sessions.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to use.
|
||||
*/
|
||||
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind);
|
||||
|
||||
/**
|
||||
* @brief Accept an incoming ssh connection and initialize the session.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to accept a connection.
|
||||
*
|
||||
* @return A newly allocated ssh session, NULL on error.
|
||||
*/
|
||||
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind);
|
||||
|
||||
/**
|
||||
* @brief Free a ssh servers bind.
|
||||
*
|
||||
* @param ssh_bind The ssh server bind to free.
|
||||
*/
|
||||
void ssh_bind_free(SSH_BIND *ssh_bind);
|
||||
|
||||
/**
|
||||
* @brief Exchange the banner and cryptographic keys.
|
||||
*
|
||||
* @param session The ssh session to accept a connection.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int ssh_accept(SSH_SESSION *session);
|
||||
|
||||
/* messages.c */
|
||||
@@ -77,7 +158,7 @@ void ssh_message_free(SSH_MESSAGE *msg);
|
||||
char *ssh_message_auth_user(SSH_MESSAGE *msg);
|
||||
char *ssh_message_auth_password(SSH_MESSAGE *msg);
|
||||
int ssh_message_auth_reply_success(SSH_MESSAGE *msg,int partial);
|
||||
void ssh_message_auth_set_methods(SSH_MESSAGE *msg, int methods);
|
||||
int ssh_message_auth_set_methods(SSH_MESSAGE *msg, int methods);
|
||||
|
||||
CHANNEL *ssh_message_channel_request_open_reply_accept(SSH_MESSAGE *msg);
|
||||
|
||||
@@ -92,3 +173,8 @@ int ssh_message_channel_request_reply_success(SSH_MESSAGE *msg);
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* SERVER_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1,23 +1,40 @@
|
||||
/* sftp headers */
|
||||
/*
|
||||
Copyright 2003-2005 Aris Adamantiadis
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
/**
|
||||
* @file sftp.h
|
||||
*
|
||||
* @brief SFTP handling functions
|
||||
*
|
||||
* SFTP commands are channeled by the ssh sftp subsystem. Every packet is
|
||||
* sent/read using a SFTP_PACKET type structure. Related to these packets,
|
||||
* most of the server answers are messages having an ID and a message
|
||||
* specific part. It is described by SFTP_MESSAGE when reading a message,
|
||||
* the sftp system puts it into the queue, so the process having asked for
|
||||
* it can fetch it, while continuing to read for other messages (it is
|
||||
* inspecified in which order messages may be sent back to the client
|
||||
*
|
||||
* @defgroup ssh_sftp SFTP Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SFTP_H
|
||||
#define SFTP_H
|
||||
@@ -26,6 +43,21 @@ MA 02111-1307, USA. */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define SFTP_DEPRECATED __attribute__ ((deprecated))
|
||||
#else
|
||||
#define SFTP_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef uid_t
|
||||
typedef long uid_t;
|
||||
#endif /* uid_t */
|
||||
#ifndef gid_t
|
||||
typedef long gid_t;
|
||||
#endif /* gid_t */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
typedef struct sftp_session_struct {
|
||||
SSH_SESSION *session;
|
||||
CHANNEL *channel;
|
||||
@@ -129,65 +161,525 @@ typedef struct sftp_attributes{
|
||||
|
||||
#define LIBSFTP_VERSION 3
|
||||
|
||||
/**
|
||||
* @brief Start a new sftp session.
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @return A new sftp session or NULL on error.
|
||||
*/
|
||||
SFTP_SESSION *sftp_new(SSH_SESSION *session);
|
||||
|
||||
/**
|
||||
* @brief Close and deallocate a sftp session.
|
||||
*
|
||||
* @param sftp The sftp session handle to free.
|
||||
*/
|
||||
void sftp_free(SFTP_SESSION *sftp);
|
||||
|
||||
/**
|
||||
* @brief Initialize the sftp session with the server.
|
||||
*
|
||||
* @param sftp The sftp session to initialize.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh error set.
|
||||
*/
|
||||
int sftp_init(SFTP_SESSION *sftp);
|
||||
|
||||
/**
|
||||
* @brief Get the last sftp error.
|
||||
*
|
||||
* Use this function to get the latest error set by a posix like sftp function.
|
||||
*
|
||||
* @param sftp The sftp session where the error is saved.
|
||||
*
|
||||
* @return The saved error (see server responses), < 0 if an error
|
||||
* in the function occured.
|
||||
*/
|
||||
int sftp_get_error(SFTP_SESSION *sftp);
|
||||
|
||||
/**
|
||||
* @brief Open a directory used to obtain directory entries.
|
||||
*
|
||||
* @param session The sftp session handle to open the directory.
|
||||
* @param path The path of the directory to open.
|
||||
*
|
||||
* @return A sftp directory handle or NULL on error with ssh and
|
||||
* sftp error set.
|
||||
*
|
||||
* @see sftp_readdir
|
||||
* @see sftp_closedir
|
||||
*/
|
||||
SFTP_DIR *sftp_opendir(SFTP_SESSION *session, const char *path);
|
||||
/* reads one file and attribute from opened directory. fails at end */
|
||||
|
||||
/**
|
||||
* @brief Get a single file attributes structure of a directory.
|
||||
*
|
||||
* @param session The sftp session handle to read the directory entry.
|
||||
* @param dir The opened sftp directory handle to read from.
|
||||
*
|
||||
* @return A file attribute structure or NULL at the end of the
|
||||
* directory.
|
||||
*
|
||||
* @see sftp_opendir()
|
||||
* @see sftp_attribute_free()
|
||||
* @see sftp_closedir()
|
||||
*/
|
||||
SFTP_ATTRIBUTES *sftp_readdir(SFTP_SESSION *session, SFTP_DIR *dir);
|
||||
/* returns 1 if the directory was EOF */
|
||||
|
||||
/**
|
||||
* @brief Tell if the directory has reached EOF (End Of File).
|
||||
*
|
||||
* @param dir The sftp directory handle.
|
||||
*
|
||||
* @return 1 if the directory is EOF, 0 if not.
|
||||
*
|
||||
* @see sftp_readdir()
|
||||
*/
|
||||
int sftp_dir_eof(SFTP_DIR *dir);
|
||||
|
||||
/**
|
||||
* @brief Get information about a file or directory.
|
||||
*
|
||||
* @param session The sftp session handle.
|
||||
* @param path The path to the file or directory to obtain the
|
||||
* information.
|
||||
*
|
||||
* @return The sftp attributes structure of the file or directory,
|
||||
* NULL on error with ssh and sftp error set.
|
||||
*/
|
||||
SFTP_ATTRIBUTES *sftp_stat(SFTP_SESSION *session, const char *path);
|
||||
|
||||
/**
|
||||
* @brief Get information about a file or directory.
|
||||
*
|
||||
* Identical to sftp_stat, but if the file or directory is a symbolic link,
|
||||
* then the link itself is stated, not the file that it refers to.
|
||||
*
|
||||
* @param session The sftp session handle.
|
||||
* @param path The path to the file or directory to obtain the
|
||||
* information.
|
||||
*
|
||||
* @return The sftp attributes structure of the file or directory,
|
||||
* NULL on error with ssh and sftp error set.
|
||||
*/
|
||||
SFTP_ATTRIBUTES *sftp_lstat(SFTP_SESSION *session, const char *path);
|
||||
/* sftp_lstat stats a file but doesn't follow symlinks */
|
||||
|
||||
/**
|
||||
* @brief Get information about a file or directory from a file handle.
|
||||
*
|
||||
* @param file The sftp file handle to get the stat information.
|
||||
*
|
||||
* @return The sftp attributes structure of the file or directory,
|
||||
* NULL on error with ssh and sftp error set.
|
||||
*/
|
||||
SFTP_ATTRIBUTES *sftp_fstat(SFTP_FILE *file);
|
||||
|
||||
/**
|
||||
* @brief Free a sftp attribute structure.
|
||||
*
|
||||
* @param file The sftp attribute structure to free.
|
||||
*/
|
||||
void sftp_attributes_free(SFTP_ATTRIBUTES *file);
|
||||
int sftp_dir_close(SFTP_DIR *dir);
|
||||
int sftp_file_close(SFTP_FILE *file);
|
||||
/* access are the sames than the ones from ansi fopen() */
|
||||
SFTP_FILE *sftp_open(SFTP_SESSION *session, const char *file, int access, SFTP_ATTRIBUTES *attr);
|
||||
int sftp_read(SFTP_FILE *file, void *dest, int len);
|
||||
u32 sftp_async_read_begin(SFTP_FILE *file, int len);
|
||||
int sftp_async_read(SFTP_FILE *file, void *data, int len, u32 id);
|
||||
int sftp_write(SFTP_FILE *file, const void *source, int len);
|
||||
void sftp_seek(SFTP_FILE *file, int new_offset);
|
||||
void sftp_seek64(SFTP_FILE *file, u64 new_offset);
|
||||
|
||||
/**
|
||||
* @brief Close a directory handle opened by sftp_opendir().
|
||||
*
|
||||
* @param dir The sftp directory handle to close.
|
||||
*
|
||||
* @return Returns SSH_NO_ERROR or SSH_ERROR if an error occured.
|
||||
*/
|
||||
int sftp_closedir(SFTP_DIR *dir);
|
||||
|
||||
/**
|
||||
* @deprecated Use sftp_closedir() instead.
|
||||
*/
|
||||
int sftp_dir_close(SFTP_DIR *dir) SFTP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @brief Close an open file handle.
|
||||
*
|
||||
* @param file The open sftp file handle to close.
|
||||
*
|
||||
* @return Returns SSH_NO_ERROR or SSH_ERROR if an error occured.
|
||||
*
|
||||
* @see sftp_open()
|
||||
*/
|
||||
int sftp_close(SFTP_FILE *file);
|
||||
|
||||
/**
|
||||
* @deprecated Use sftp_close() instead.
|
||||
*/
|
||||
int sftp_file_close(SFTP_FILE *file) SFTP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @brief Open a file on the server.
|
||||
*
|
||||
* @param session The sftp session handle.
|
||||
*
|
||||
* @param file The file to be opened.
|
||||
*
|
||||
* @param access Is one of O_RDONLY, O_WRONLY or O_RDWR which request
|
||||
* opening the file read-only,write-only or read/write.
|
||||
* Acesss may also be bitwise-or'd with one or more of
|
||||
* the following:
|
||||
* O_CREAT - If the file does not exist it will be
|
||||
* created.
|
||||
* O_EXCL - When used with O_CREAT, if the file already
|
||||
* exists it is an error and the open will fail.
|
||||
* O_TRUNC - If the file already exists it will be
|
||||
* truncated.
|
||||
*
|
||||
* @param mode Mode specifies the permissions to use if a new file is
|
||||
* created. It is modified by the process's umask in
|
||||
* the usual way: The permissions of the created file are
|
||||
* (mode & ~umask)
|
||||
*
|
||||
* @return A sftp file handle, NULL on error with ssh and sftp
|
||||
* error set.
|
||||
*/
|
||||
SFTP_FILE *sftp_open(SFTP_SESSION *session, const char *file, int flags,
|
||||
mode_t mode);
|
||||
|
||||
void sftp_file_set_nonblocking(SFTP_FILE *handle);
|
||||
|
||||
void sftp_file_set_blocking(SFTP_FILE *handle);
|
||||
|
||||
/**
|
||||
* @brief Read from a file using an opened sftp file handle.
|
||||
*
|
||||
* @param file The opened sftp file handle to be read from.
|
||||
*
|
||||
* @param buf Pointer to buffer to recieve read data.
|
||||
*
|
||||
* @param count Size of the buffer in bytes.
|
||||
*
|
||||
* @return Number of bytes written, < 0 on error with ssh and sftp
|
||||
* error set.
|
||||
*/
|
||||
ssize_t sftp_read(SFTP_FILE *file, void *buf, size_t count);
|
||||
|
||||
/**
|
||||
* @brief Start an asynchronous read from a file using an opened sftp file handle.
|
||||
*
|
||||
* Its goal is to avoid the slowdowns related to the request/response pattern
|
||||
* of a synchronous read. To do so, you must call 2 functions:
|
||||
*
|
||||
* sftp_async_read_begin() and sftp_async_read().
|
||||
*
|
||||
* The first step is to call sftp_async_read_begin(). This function returns a
|
||||
* request identifier. The second step is to call sftp_async_read() using the
|
||||
* returned identifier.
|
||||
*
|
||||
* @param file The opened sftp file handle to be read from.
|
||||
*
|
||||
* @param len Size to read in bytes.
|
||||
*
|
||||
* @return An identifier corresponding to the sent request, < 0 on
|
||||
* error.
|
||||
*
|
||||
* @warning When calling this function, the internal offset is
|
||||
* updated corresponding to the len parameter.
|
||||
*
|
||||
* @warning A call to sftp_async_read_begin() sends a request to
|
||||
* the server. When the server answers, libssh allocates
|
||||
* memory to store it until sftp_async_read() is called.
|
||||
* Not calling sftp_async_read() will lead to memory
|
||||
* leaks.
|
||||
*
|
||||
* @see sftp_async_read()
|
||||
* @see sftp_open()
|
||||
*/
|
||||
int sftp_async_read_begin(SFTP_FILE *file, u32 len);
|
||||
|
||||
/**
|
||||
* @brief Wait for an asynchronous read to complete and save the data.
|
||||
*
|
||||
* @param file The opened sftp file handle to be read from.
|
||||
*
|
||||
* @param data Pointer to buffer to recieve read data.
|
||||
*
|
||||
* @param len Size of the buffer in bytes. It should be bigger or
|
||||
* equal to the length parameter of the
|
||||
* sftp_async_read_begin() call.
|
||||
*
|
||||
* @param id The identifier returned by the sftp_async_read_begin()
|
||||
* function.
|
||||
*
|
||||
* @return Number of bytes read, 0 on EOF, SSH_ERROR if an error
|
||||
* occured, SSH_AGAIN if the file is opened in nonblocking
|
||||
* mode and the request hasn't been executed yet.
|
||||
*
|
||||
* @warning A call to this function with an invalid identifier
|
||||
* will never return.
|
||||
*
|
||||
* @see sftp_async_read_begin()
|
||||
*/
|
||||
int sftp_async_read(SFTP_FILE *file, void *data, u32 len, u32 id);
|
||||
|
||||
/**
|
||||
* @brief Write to a file using an opened sftp file handle.
|
||||
*
|
||||
* @param file Open sftp file handle to write to.
|
||||
*
|
||||
* @param buf Pointer to buffer to write data.
|
||||
*
|
||||
* @param count Size of buffer in bytes.
|
||||
*
|
||||
* @return Number of bytes written, < 0 on error with ssh and sftp
|
||||
* error set.
|
||||
*
|
||||
* @see sftp_open()
|
||||
* @see sftp_read()
|
||||
* @see sftp_close()
|
||||
*/
|
||||
ssize_t sftp_write(SFTP_FILE *file, const void *buf, size_t count);
|
||||
|
||||
/**
|
||||
* @brief Seek to a specific location in a file.
|
||||
*
|
||||
* @param file Open sftp file handle to seek in.
|
||||
*
|
||||
* @param new_offset Offset in bytes to seek.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int sftp_seek(SFTP_FILE *file, u32 new_offset);
|
||||
|
||||
/**
|
||||
* @brief Seek to a specific location in a file. This is the
|
||||
* 64bit version.
|
||||
*
|
||||
* @param file Open sftp file handle to seek in.
|
||||
*
|
||||
* @param new_offset Offset in bytes to seek.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int sftp_seek64(SFTP_FILE *file, u64 new_offset);
|
||||
|
||||
/**
|
||||
* @brief Report current byte position in file.
|
||||
*
|
||||
* @param file Open sftp file handle.
|
||||
*
|
||||
* @return The offset of the current byte relative to the beginning
|
||||
* of the file associated with the file descriptor. < 0 on
|
||||
* error.
|
||||
*/
|
||||
unsigned long sftp_tell(SFTP_FILE *file);
|
||||
|
||||
/**
|
||||
* @brief Rewinds the position of the file pointer to the beginning of the
|
||||
* file.
|
||||
*
|
||||
* @param file Open sftp file handle.
|
||||
*/
|
||||
void sftp_rewind(SFTP_FILE *file);
|
||||
int sftp_rm(SFTP_SESSION *sftp, char *file);
|
||||
|
||||
/**
|
||||
* @deprecated Use sftp_unlink() instead.
|
||||
*/
|
||||
int sftp_rm(SFTP_SESSION *sftp, const char *file) SFTP_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @brief Unlink (delete) a file.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param file The file to unlink/delete.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_unlink(SFTP_SESSION *sftp, const char *file);
|
||||
|
||||
/**
|
||||
* @brief Remove a directoy.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param directory The directory to remove.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_rmdir(SFTP_SESSION *sftp, const char *directory);
|
||||
int sftp_mkdir(SFTP_SESSION *sftp, const char *directory, SFTP_ATTRIBUTES *attr);
|
||||
|
||||
/**
|
||||
* @brief Create a directory.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param directory The directory to create.
|
||||
*
|
||||
* @param mode Specifies the permissions to use. It is modified by the
|
||||
* process's umask in the usual way:
|
||||
* The permissions of the created file are (mode & ~umask)
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_mkdir(SFTP_SESSION *sftp, const char *directory, mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Rename or move a file or directory.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param original The original url (source url) of file or directory to
|
||||
* be moved.
|
||||
*
|
||||
* @param newname The new url (destination url) of the file or directory
|
||||
* after the move.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_rename(SFTP_SESSION *sftp, const char *original, const char *newname);
|
||||
|
||||
/**
|
||||
* @brief Set file attributes on a file, directory or symbolic link.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param file The file which attributes should be changed.
|
||||
*
|
||||
* @param attr The file attributes structure with the attributes set
|
||||
* which should be changed.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_setstat(SFTP_SESSION *sftp, const char *file, SFTP_ATTRIBUTES *attr);
|
||||
|
||||
/**
|
||||
* @brief Change the file owner and group
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param file The file which owner and group should be changed.
|
||||
*
|
||||
* @param owner The new owner which should be set.
|
||||
*
|
||||
* @param group The new group which should be set.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_chown(SFTP_SESSION *sftp, const char *file, uid_t owner, gid_t group);
|
||||
|
||||
/**
|
||||
* @brief Change permissions of a file
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param file The file which owner and group should be changed.
|
||||
*
|
||||
* @param mode Specifies the permissions to use. It is modified by the
|
||||
* process's umask in the usual way:
|
||||
* The permissions of the created file are (mode & ~umask)
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_chmod(SFTP_SESSION *sftp, const char *file, mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Change the last modification and access time of a file.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param file The file which owner and group should be changed.
|
||||
*
|
||||
* @param times A timeval structure which contains the desired access
|
||||
* and modification time.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_utimes(SFTP_SESSION *sftp, const char *file, const struct timeval *times);
|
||||
|
||||
/**
|
||||
* @brief Create a symbolic link.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param target Specifies the target of the symlink.
|
||||
*
|
||||
* @param dest Specifies the path name of the symlink to be created.
|
||||
*
|
||||
* @return 0 on success, < 0 on error with ssh and sftp error set.
|
||||
*/
|
||||
int sftp_symlink(SFTP_SESSION *sftp, const char *target, const char *dest);
|
||||
|
||||
/**
|
||||
* @brief Read the value of a symbolic link.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param path Specifies the path name of the symlink to be read.
|
||||
*
|
||||
* @return The target of the link, NULL on error.
|
||||
*/
|
||||
char *sftp_readlink(SFTP_SESSION *sftp, const char *path);
|
||||
|
||||
/**
|
||||
* @brief Canonicalize a sftp path.
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @param path The path to be canonicalized.
|
||||
*
|
||||
* @return The canonicalize path, NULL on error.
|
||||
*/
|
||||
char *sftp_canonicalize_path(SFTP_SESSION *sftp, const char *path);
|
||||
|
||||
#ifndef NO_SERVER
|
||||
/**
|
||||
* @brief Get the version of the SFTP protocol supported by the server
|
||||
*
|
||||
* @param sftp The sftp session handle.
|
||||
*
|
||||
* @return The server version.
|
||||
*/
|
||||
int sftp_server_version(SFTP_SESSION *sftp);
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
/**
|
||||
* @brief Create a new sftp server session.
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @param chan The ssh channel to use.
|
||||
*
|
||||
* @return A new sftp server session.
|
||||
*/
|
||||
SFTP_SESSION *sftp_server_new(SSH_SESSION *session, CHANNEL *chan);
|
||||
|
||||
/**
|
||||
* @brief Intialize the sftp server.
|
||||
*
|
||||
* @param sftp The sftp session to init.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int sftp_server_init(SFTP_SESSION *sftp);
|
||||
#endif
|
||||
#endif /* WITH_SERVER */
|
||||
|
||||
/* this is not a public interface */
|
||||
#define SFTP_HANDLES 256
|
||||
SFTP_PACKET *sftp_packet_read(SFTP_SESSION *sftp);
|
||||
int sftp_packet_write(SFTP_SESSION *sftp,u8 type, BUFFER *payload);
|
||||
void sftp_packet_free(SFTP_PACKET *packet);
|
||||
void buffer_add_attributes(BUFFER *buffer, SFTP_ATTRIBUTES *attr);
|
||||
int buffer_add_attributes(BUFFER *buffer, SFTP_ATTRIBUTES *attr);
|
||||
SFTP_ATTRIBUTES *sftp_parse_attr(SFTP_SESSION *session, BUFFER *buf,int expectname);
|
||||
/* sftpserver.c */
|
||||
|
||||
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp);
|
||||
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg);
|
||||
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, char *name, SFTP_ATTRIBUTES *attr);
|
||||
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, const char *name,
|
||||
SFTP_ATTRIBUTES *attr);
|
||||
int sftp_reply_handle(SFTP_CLIENT_MESSAGE *msg, STRING *handle);
|
||||
STRING *sftp_handle_alloc(SFTP_SESSION *sftp, void *info);
|
||||
int sftp_reply_attr(SFTP_CLIENT_MESSAGE *msg, SFTP_ATTRIBUTES *attr);
|
||||
void *sftp_handle(SFTP_SESSION *sftp, STRING *handle);
|
||||
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status, char *message);
|
||||
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, char *file, char *longname,
|
||||
SFTP_ATTRIBUTES *attr);
|
||||
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status, const char *message);
|
||||
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, const char *file,
|
||||
const char *longname, SFTP_ATTRIBUTES *attr);
|
||||
int sftp_reply_names(SFTP_CLIENT_MESSAGE *msg);
|
||||
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, void *data, int len);
|
||||
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, const void *data, int len);
|
||||
void sftp_handle_remove(SFTP_SESSION *sftp, void *handle);
|
||||
|
||||
/* SFTP commands and constants */
|
||||
@@ -270,6 +762,11 @@ void sftp_handle_remove(SFTP_SESSION *sftp, void *handle);
|
||||
#define SSH_FXF_EXCL 0x20
|
||||
#define SSH_FXF_TEXT 0x40
|
||||
|
||||
/* rename flags */
|
||||
#define SSH_FXF_RENAME_OVERWRITE 0x00000001
|
||||
#define SSH_FXF_RENAME_ATOMIC 0x00000002
|
||||
#define SSH_FXF_RENAME_NATIVE 0x00000004
|
||||
|
||||
#define SFTP_OPEN SSH_FXP_OPEN
|
||||
#define SFTP_CLOSE SSH_FXP_CLOSE
|
||||
#define SFTP_READ SSH_FXP_READ
|
||||
@@ -290,8 +787,12 @@ void sftp_handle_remove(SFTP_SESSION *sftp, void *handle);
|
||||
#define SFTP_SYMLINK SSH_FXP_SYMLINK
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} ;
|
||||
#endif
|
||||
|
||||
#endif /* SFTP_H */
|
||||
|
||||
/** @} */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
15
lib.bat
15
lib.bat
@@ -1,15 +0,0 @@
|
||||
@SET VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE
|
||||
@SET VCINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003
|
||||
@SET FrameworkDir=C:\WINDOWS\Microsoft.NET\Framework
|
||||
@SET FrameworkVersion=v1.1.4322
|
||||
@SET FrameworkSDKDir=C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1
|
||||
@set DevEnvDir=%VSINSTALLDIR%
|
||||
|
||||
@rem
|
||||
@rem Root of Visual C++ installed files.
|
||||
@rem
|
||||
@set MSVCDir=%VCINSTALLDIR%\VC7
|
||||
@set PATH=%DevEnvDir%;%MSVCDir%\BIN;%VCINSTALLDIR%\Common7\Tools;%VCINSTALLDIR%\Common7\Tools\bin\prerelease;%VCINSTALLDIR%\Common7\Tools\bin;%FrameworkSDKDir%\bin;%FrameworkDir%\%FrameworkVersion%;%PATH%;
|
||||
@set INCLUDE=%MSVCDir%\ATLMFC\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\PlatformSDK\include\prerelease;%MSVCDir%\PlatformSDK\include;%FrameworkSDKDir%\include;%INCLUDE%
|
||||
@set LIB=%MSVCDir%\ATLMFC\LIB;%MSVCDir%\LIB;%MSVCDir%\PlatformSDK\lib\prerelease;%MSVCDir%\PlatformSDK\lib;%FrameworkSDKDir%\lib;%LIB%
|
||||
"c:\Program files\Microsoft Visual Studio .NET 2003\vc7\bin\lib.exe" /machine:i386 /def:libssh.def
|
||||
427
libssh.dev
427
libssh.dev
@@ -1,427 +0,0 @@
|
||||
[Project]
|
||||
FileName=libssh.dev
|
||||
Name=libssh
|
||||
UnitCount=38
|
||||
Type=1
|
||||
Ver=1
|
||||
ObjFiles=
|
||||
Includes=
|
||||
Libs=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
MakeIncludes=
|
||||
Compiler=
|
||||
CppCompiler=
|
||||
Linker=
|
||||
IsCpp=0
|
||||
Icon=
|
||||
ExeOutput=
|
||||
ObjectOutput=
|
||||
OverrideOutput=0
|
||||
OverrideOutputName=libssh.exe
|
||||
HostApplication=
|
||||
Folders=include
|
||||
CommandLine=
|
||||
UseCustomMakefile=1
|
||||
CustomMakefile=Makefile.Windows
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=0000000000000000000000
|
||||
|
||||
[Unit1]
|
||||
FileName=libssh\init.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit2]
|
||||
FileName=libssh\kex.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit3]
|
||||
FileName=libssh\keyfiles.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit4]
|
||||
FileName=libssh\keys.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit5]
|
||||
FileName=libssh\messages.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit6]
|
||||
FileName=libssh\misc.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit7]
|
||||
FileName=libssh\options.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit8]
|
||||
FileName=libssh\packet.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit9]
|
||||
FileName=libssh\server.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit10]
|
||||
FileName=libssh\session.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit11]
|
||||
FileName=libssh\sftp.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit12]
|
||||
FileName=libssh\sftpserver.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit13]
|
||||
FileName=libssh\socket.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit14]
|
||||
FileName=libssh\string.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit15]
|
||||
FileName=libssh\wrapper.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit16]
|
||||
FileName=libssh\auth1.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit17]
|
||||
FileName=libssh\auth.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit18]
|
||||
FileName=libssh\base64.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit19]
|
||||
FileName=libssh\buffer.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit20]
|
||||
FileName=libssh\channels1.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit21]
|
||||
FileName=libssh\channels.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit22]
|
||||
FileName=libssh\client.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit23]
|
||||
FileName=libssh\connect.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit24]
|
||||
FileName=libssh\crc32.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit25]
|
||||
FileName=libssh\crypt.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit26]
|
||||
FileName=libssh\dh.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit27]
|
||||
FileName=libssh\error.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit28]
|
||||
FileName=libssh\gcrypt_missing.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit29]
|
||||
FileName=libssh\gzip.c
|
||||
CompileCpp=0
|
||||
Folder=libssh
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit30]
|
||||
FileName=include\libssh\crypto.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit31]
|
||||
FileName=include\libssh\libssh.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit32]
|
||||
FileName=include\libssh\priv.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit33]
|
||||
FileName=include\libssh\server.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit34]
|
||||
FileName=include\libssh\sftp.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit35]
|
||||
FileName=include\libssh\ssh1.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit36]
|
||||
FileName=include\libssh\ssh2.h
|
||||
CompileCpp=0
|
||||
Folder=include
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[VersionInfo]
|
||||
Major=0
|
||||
Minor=1
|
||||
Release=1
|
||||
Build=1
|
||||
LanguageID=1033
|
||||
CharsetID=1252
|
||||
CompanyName=
|
||||
FileVersion=
|
||||
FileDescription=Developed using the Dev-C++ IDE
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=
|
||||
AutoIncBuildNr=0
|
||||
|
||||
[Unit37]
|
||||
FileName=lib.bat
|
||||
Folder=libssh
|
||||
Compile=0
|
||||
Link=0
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit38]
|
||||
FileName=Makefile.Windows
|
||||
Folder=libssh
|
||||
Compile=0
|
||||
Link=0
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
178
libssh/CMakeLists.txt
Normal file
178
libssh/CMakeLists.txt
Normal file
@@ -0,0 +1,178 @@
|
||||
project(libssh-library C)
|
||||
|
||||
set(LIBSSH_PUBLIC_INCLUDE_DIRS
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
CACHE INTERNAL "libssh public include directories"
|
||||
)
|
||||
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${CMAKE_BINARY_DIR}
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(LIBSSH_SHARED_LIBRARY
|
||||
ssh_shared
|
||||
CACHE INTERNAL "libssh shared library"
|
||||
)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
set(LIBSSH_STATIC_LIBRARY
|
||||
ssh_static
|
||||
CACHE INTERNAL "libssh static library"
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
ws2_32
|
||||
)
|
||||
endif (WIN32)
|
||||
|
||||
if (CRYPTO_LIBRARY)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${CRYPTO_LIBRARY}
|
||||
)
|
||||
endif (CRYPTO_LIBRARY)
|
||||
|
||||
if (GCRYPT_LIBRARY)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
${GCRYPT_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${GCRYPT_LIBRARY}
|
||||
)
|
||||
endif (GCRYPT_LIBRARY)
|
||||
|
||||
|
||||
set(libssh_SRCS
|
||||
agent.c
|
||||
auth.c
|
||||
base64.c
|
||||
buffer.c
|
||||
channels.c
|
||||
client.c
|
||||
connect.c
|
||||
crc32.c
|
||||
crypt.c
|
||||
dh.c
|
||||
error.c
|
||||
gcrypt_missing.c
|
||||
gzip.c
|
||||
init.c
|
||||
kex.c
|
||||
keyfiles.c
|
||||
keys.c
|
||||
log.c
|
||||
match.c
|
||||
messages.c
|
||||
misc.c
|
||||
options.c
|
||||
packet.c
|
||||
poll.c
|
||||
session.c
|
||||
socket.c
|
||||
string.c
|
||||
wrapper.c
|
||||
libssh.map
|
||||
)
|
||||
|
||||
if (WITH_SFTP)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
sftp.c
|
||||
)
|
||||
|
||||
if (WITH_SERVER)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
sftpserver.c
|
||||
)
|
||||
endif (WITH_SERVER)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
if (WITH_SSH1)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
auth1.c
|
||||
channels1.c
|
||||
)
|
||||
endif (WITH_SSH1)
|
||||
|
||||
if (WITH_SERVER)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
server.c
|
||||
)
|
||||
endif (WITH_SERVER)
|
||||
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS})
|
||||
|
||||
target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
COMPONENT
|
||||
libraries
|
||||
)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS})
|
||||
|
||||
target_link_libraries(${LIBSSH_STATIC_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
COMPONENT
|
||||
libraries
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
lib_LTLIBRARIES = libssh.la
|
||||
|
||||
libssh_la_SOURCES = auth1.c auth.c base64.c buffer.c \
|
||||
channels1.c channels.c client.c connect.c \
|
||||
crc32.c crypt.c dh.c error.c gcrypt_missing.c \
|
||||
gzip.c init.c kex.c keyfiles.c \
|
||||
keys.c messages.c misc.c options.c \
|
||||
packet.c server.c session.c sftp.c \
|
||||
sftpserver.c string.c wrapper.c \
|
||||
socket.c log.c match.c
|
||||
|
||||
libssh_la_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
libssh_la_LDFLAGS = -version-info $(LIBSSH_CURRENT):$(LIBSSH_REVISION):$(LIBSSH_AGE)
|
||||
501
libssh/agent.c
Normal file
501
libssh/agent.c
Normal file
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* agent.c - ssh agent functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2008-2009 by Andreas Schneider <mail@cynapses.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.
|
||||
*/
|
||||
|
||||
/* This file is based on authfd.c from OpenSSH */
|
||||
|
||||
/*
|
||||
* How does the ssh-agent work?
|
||||
*
|
||||
* a) client sends a request to get a list of all keys
|
||||
* the agent returns the cound and all public keys
|
||||
* b) iterate over them to check if the server likes one
|
||||
* c) the client sends a sign request to the agent
|
||||
* type, pubkey as blob, data to sign, flags
|
||||
* the agent returns the signed data
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/agent.h"
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/* macro to check for "agent failure" message */
|
||||
#define agent_failed(x) \
|
||||
(((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
|
||||
((x) == SSH2_AGENT_FAILURE))
|
||||
|
||||
static u32 agent_get_u32(const void *vp) {
|
||||
const u8 *p = (const u8 *)vp;
|
||||
u32 v;
|
||||
|
||||
v = (u32)p[0] << 24;
|
||||
v |= (u32)p[1] << 16;
|
||||
v |= (u32)p[2] << 8;
|
||||
v |= (u32)p[3];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void agent_put_u32(void *vp, u32 v) {
|
||||
u8 *p = (u8 *)vp;
|
||||
|
||||
p[0] = (u8)(v >> 24) & 0xff;
|
||||
p[1] = (u8)(v >> 16) & 0xff;
|
||||
p[2] = (u8)(v >> 8) & 0xff;
|
||||
p[3] = (u8)v & 0xff;
|
||||
}
|
||||
|
||||
static size_t atomicio(struct socket *s, void *buf, size_t n, int do_read) {
|
||||
char *b = buf;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
struct pollfd pfd;
|
||||
int fd = ssh_socket_get_fd(s);
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = do_read ? POLLIN : POLLOUT;
|
||||
|
||||
while (n > pos) {
|
||||
if (do_read) {
|
||||
res = read(fd, b + pos, n - pos);
|
||||
} else {
|
||||
res = write(fd, b + pos, n - pos);
|
||||
}
|
||||
switch (res) {
|
||||
case -1:
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
#ifdef EWOULDBLOCK
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
#else
|
||||
if (errno == EAGAIN) {
|
||||
#endif
|
||||
(void) poll(&pfd, 1, -1);
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t) res;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
AGENT *agent_new(struct ssh_session *session) {
|
||||
AGENT *agent = NULL;
|
||||
|
||||
agent = malloc(sizeof(AGENT));
|
||||
if (agent == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(agent);
|
||||
|
||||
agent->count = 0;
|
||||
agent->sock = ssh_socket_new(session);
|
||||
if (agent->sock == NULL) {
|
||||
SAFE_FREE(agent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
void agent_close(struct agent_struct *agent) {
|
||||
if (agent == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getenv("SSH_AUTH_SOCK")) {
|
||||
ssh_socket_close(agent->sock);
|
||||
}
|
||||
}
|
||||
|
||||
void agent_free(AGENT *agent) {
|
||||
if (agent) {
|
||||
if (agent->ident) {
|
||||
buffer_free(agent->ident);
|
||||
}
|
||||
if (agent->sock) {
|
||||
agent_close(agent);
|
||||
ssh_socket_free(agent->sock);
|
||||
}
|
||||
SAFE_FREE(agent);
|
||||
}
|
||||
}
|
||||
|
||||
static int agent_connect(SSH_SESSION *session) {
|
||||
const char *auth_sock = NULL;
|
||||
|
||||
if (session == NULL || session->agent == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auth_sock = getenv("SSH_AUTH_SOCK");
|
||||
|
||||
if (auth_sock && *auth_sock) {
|
||||
if (ssh_socket_unix(session->agent->sock, auth_sock) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int agent_decode_reply(struct ssh_session *session, int type) {
|
||||
switch (type) {
|
||||
case SSH_AGENT_FAILURE:
|
||||
case SSH2_AGENT_FAILURE:
|
||||
case SSH_COM_AGENT2_FAILURE:
|
||||
ssh_log(session, SSH_LOG_RARE, "SSH_AGENT_FAILURE");
|
||||
return 0;
|
||||
case SSH_AGENT_SUCCESS:
|
||||
return 1;
|
||||
default:
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad response from authentication agent: %d", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int agent_talk(struct ssh_session *session,
|
||||
struct buffer_struct *request, struct buffer_struct *reply) {
|
||||
u32 len = 0;
|
||||
u8 payload[1024] = {0};
|
||||
|
||||
len = buffer_get_len(request);
|
||||
ssh_log(session, SSH_LOG_PACKET, "agent_talk - len of request: %u", len);
|
||||
agent_put_u32(payload, len);
|
||||
|
||||
/* send length and then the request packet */
|
||||
if (atomicio(session->agent->sock, payload, 4, 0) == 4) {
|
||||
buffer_get_data(request, payload, len);
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"agent_talk - sending request, payload[0] = %u", payload[0]);
|
||||
if (atomicio(session->agent->sock, payload, len, 0)
|
||||
!= len) {
|
||||
ssh_log(session, SSH_LOG_PACKET, "atomicio sending request failed: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"atomicio sending request length failed: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* wait for response, read the length of the response packet */
|
||||
if (atomicio(session->agent->sock, payload, 4, 1) != 4) {
|
||||
ssh_log(session, SSH_LOG_PACKET, "atomicio read response length failed: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = agent_get_u32(payload);
|
||||
if (len > 256 * 1024) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Authentication response too long: %u", len);
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_PACKET, "agent_talk - response length: %u", len);
|
||||
|
||||
while (len > 0) {
|
||||
size_t n = len;
|
||||
if (n > sizeof(payload)) {
|
||||
n = sizeof(payload);
|
||||
}
|
||||
if (atomicio(session->agent->sock, payload, n, 1) != n) {
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Error reading response from authentication socket.");
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_data(reply, payload, n) < 0) {
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS,
|
||||
"Not enough space");
|
||||
return -1;
|
||||
}
|
||||
len -= n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int agent_get_ident_count(struct ssh_session *session) {
|
||||
BUFFER *request = NULL;
|
||||
BUFFER *reply = NULL;
|
||||
unsigned int type = 0;
|
||||
unsigned int c1 = 0, c2 = 0;
|
||||
u8 buf[4] = {0};
|
||||
|
||||
switch (session->version) {
|
||||
case 1:
|
||||
c1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
|
||||
c2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
|
||||
break;
|
||||
case 2:
|
||||
c1 = SSH2_AGENTC_REQUEST_IDENTITIES;
|
||||
c2 = SSH2_AGENT_IDENTITIES_ANSWER;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* send message to the agent requesting the list of identities */
|
||||
request = buffer_new();
|
||||
if (buffer_add_u8(request, c1) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
return -1;
|
||||
}
|
||||
|
||||
reply = buffer_new();
|
||||
if (reply == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (agent_talk(session, request, reply) < 0) {
|
||||
buffer_free(request);
|
||||
return 0;
|
||||
}
|
||||
buffer_free(request);
|
||||
|
||||
/* get message type and verify the answer */
|
||||
buffer_get_u8(reply, (u8 *) &type);
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"agent_ident_count - answer type: %d, expected answer: %d",
|
||||
type, c2);
|
||||
if (agent_failed(type)) {
|
||||
return 0;
|
||||
} else if (type != c2) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad authentication reply message type: %d", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_get_u32(reply, (u32 *) buf);
|
||||
session->agent->count = agent_get_u32(buf);
|
||||
ssh_log(session, SSH_LOG_PACKET, "agent_ident_count - count: %d",
|
||||
session->agent->count);
|
||||
if (session->agent->count > 1024) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Too many identities in authentication reply: %d",
|
||||
session->agent->count);
|
||||
buffer_free(reply);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (session->agent->ident) {
|
||||
buffer_free(session->agent->ident);
|
||||
}
|
||||
session->agent->ident = reply;
|
||||
|
||||
return session->agent->count;
|
||||
}
|
||||
|
||||
/* caller has to free commment */
|
||||
struct public_key_struct *agent_get_first_ident(struct ssh_session *session,
|
||||
char **comment) {
|
||||
if (agent_get_ident_count(session) > 0) {
|
||||
return agent_get_next_ident(session, comment);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* caller has to free commment */
|
||||
struct public_key_struct *agent_get_next_ident(struct ssh_session *session,
|
||||
char **comment) {
|
||||
struct public_key_struct *pubkey = NULL;
|
||||
struct string_struct *blob = NULL;
|
||||
struct string_struct *tmp = NULL;
|
||||
|
||||
if (session->agent->count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(session->version) {
|
||||
case 1:
|
||||
return NULL;
|
||||
case 2:
|
||||
/* get the blob */
|
||||
blob = buffer_get_ssh_string(session->agent->ident);
|
||||
if (blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the comment */
|
||||
tmp = buffer_get_ssh_string(session->agent->ident);
|
||||
if (tmp == NULL) {
|
||||
string_free(blob);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (comment) {
|
||||
*comment = string_to_char(tmp);
|
||||
} else {
|
||||
string_free(blob);
|
||||
string_free(tmp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
string_free(tmp);
|
||||
|
||||
/* get key from blob */
|
||||
pubkey = publickey_from_string(session, blob);
|
||||
string_free(blob);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pubkey;
|
||||
}
|
||||
|
||||
STRING *agent_sign_data(struct ssh_session *session,
|
||||
struct buffer_struct *data,
|
||||
struct public_key_struct *pubkey) {
|
||||
struct string_struct *blob = NULL;
|
||||
struct string_struct *sig = NULL;
|
||||
struct buffer_struct *request = NULL;
|
||||
struct buffer_struct *reply = NULL;
|
||||
int type = SSH2_AGENT_FAILURE;
|
||||
int flags = 0;
|
||||
u32 dlen = 0;
|
||||
|
||||
/* create blob from the pubkey */
|
||||
blob = publickey_to_string(pubkey);
|
||||
|
||||
request = buffer_new();
|
||||
if (request == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* create request */
|
||||
if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* adds len + blob */
|
||||
if (buffer_add_ssh_string(request, blob) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Add data */
|
||||
dlen = buffer_get_len(data);
|
||||
if (buffer_add_u32(request, htonl(dlen)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(request, buffer_get(data), dlen) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(request, htonl(flags)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
string_free(blob);
|
||||
|
||||
reply = buffer_new();
|
||||
if (reply == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* send the request */
|
||||
if (agent_talk(session, request, reply) < 0) {
|
||||
buffer_free(request);
|
||||
return NULL;
|
||||
}
|
||||
buffer_free(request);
|
||||
|
||||
/* check if reply is valid */
|
||||
if (buffer_get_u8(reply, (u8 *) &type) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (agent_failed(type)) {
|
||||
ssh_log(session, SSH_LOG_RARE, "Agent reports failure in signing the key");
|
||||
buffer_free(reply);
|
||||
return NULL;
|
||||
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
|
||||
ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type);
|
||||
buffer_free(reply);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig = buffer_get_ssh_string(reply);
|
||||
|
||||
buffer_free(reply);
|
||||
|
||||
return sig;
|
||||
error:
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough memory");
|
||||
string_free(blob);
|
||||
buffer_free(request);
|
||||
buffer_free(reply);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int agent_is_running(SSH_SESSION *session) {
|
||||
if (session == NULL || session->agent == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssh_socket_is_open(session->agent->sock)) {
|
||||
return 1;
|
||||
} else {
|
||||
if (agent_connect(session) < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
2097
libssh/auth.c
2097
libssh/auth.c
File diff suppressed because it is too large
Load Diff
248
libssh/auth1.c
248
libssh/auth1.c
@@ -1,77 +1,98 @@
|
||||
/* auth1.c deals with authentication with SSH-1 protocol */
|
||||
/*
|
||||
Copyright (c) 2005-2008 Aris Adamantiadis
|
||||
* auth1.c - authentication with SSH-1 protocol
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
The SSH Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The SSH Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the SSH Library; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh1.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
static void burn(char *ptr){
|
||||
if(ptr)
|
||||
memset(ptr,'X',strlen(ptr));
|
||||
}
|
||||
*/
|
||||
#ifdef HAVE_SSH1
|
||||
static int wait_auth1_status(SSH_SESSION *session){
|
||||
/* wait for a packet */
|
||||
if(packet_read(session))
|
||||
return SSH_AUTH_ERROR;
|
||||
if(packet_translate(session))
|
||||
return SSH_AUTH_ERROR;
|
||||
switch(session->in_packet.type){
|
||||
case SSH_SMSG_SUCCESS:
|
||||
return SSH_AUTH_SUCCESS;
|
||||
case SSH_SMSG_FAILURE:
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
ssh_set_error(session,SSH_FATAL,"Was waiting for a SUCCESS or "
|
||||
"FAILURE, got %d",session->in_packet.type);
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh1.h"
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
static int wait_auth1_status(SSH_SESSION *session) {
|
||||
/* wait for a packet */
|
||||
if (packet_read(session) != SSH_OK) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if(packet_translate(session) != SSH_OK) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
switch(session->in_packet.type) {
|
||||
case SSH_SMSG_SUCCESS:
|
||||
return SSH_AUTH_SUCCESS;
|
||||
case SSH_SMSG_FAILURE:
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_FATAL, "Was waiting for a SUCCESS or "
|
||||
"FAILURE, got %d", session->in_packet.type);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
static int send_username(SSH_SESSION *session, char *username){
|
||||
STRING *user;
|
||||
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
|
||||
if(session->auth_service_asked)
|
||||
return session->auth_service_asked;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_USER);
|
||||
if(!username)
|
||||
if(!(username=session->options->username)){
|
||||
if(ssh_options_default_username(session->options))
|
||||
return session->auth_service_asked=SSH_AUTH_ERROR;
|
||||
else
|
||||
username=session->options->username;
|
||||
}
|
||||
user=string_from_char(username);
|
||||
buffer_add_ssh_string(session->out_buffer,user);
|
||||
free(user);
|
||||
packet_send(session);
|
||||
session->auth_service_asked=wait_auth1_status(session);
|
||||
|
||||
static int send_username(SSH_SESSION *session, const char *username) {
|
||||
STRING *user = NULL;
|
||||
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
|
||||
if(session->auth_service_asked) {
|
||||
return session->auth_service_asked;
|
||||
}
|
||||
|
||||
if (!username) {
|
||||
if(!(username = session->options->username)) {
|
||||
if(ssh_options_default_username(session->options)) {
|
||||
return session->auth_service_asked = SSH_AUTH_ERROR;
|
||||
} else {
|
||||
username = session->options->username;
|
||||
}
|
||||
}
|
||||
}
|
||||
user = string_from_char(username);
|
||||
if (user == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) {
|
||||
string_free(user);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
if (buffer_add_ssh_string(session->out_buffer, user) < 0) {
|
||||
string_free(user);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
string_free(user);
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
session->auth_service_asked = wait_auth1_status(session);
|
||||
|
||||
return session->auth_service_asked;
|
||||
}
|
||||
|
||||
/* use the "none" authentication question */
|
||||
|
||||
int ssh_userauth1_none(SSH_SESSION *session,char *username){
|
||||
return send_username(session,username);
|
||||
int ssh_userauth1_none(SSH_SESSION *session, const char *username){
|
||||
return send_username(session, username);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -115,9 +136,13 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,int type, STR
|
||||
/** \internal
|
||||
* \todo implement ssh1 public key
|
||||
*/
|
||||
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, char *username, int type,
|
||||
STRING *pubkey){
|
||||
return SSH_AUTH_DENIED;
|
||||
int ssh_userauth1_offer_pubkey(SSH_SESSION *session, const char *username,
|
||||
int type, STRING *pubkey) {
|
||||
(void) session;
|
||||
(void) username;
|
||||
(void) type;
|
||||
(void) pubkey;
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -167,39 +192,64 @@ int ssh_userauth_pubkey(SSH_SESSION *session, char *username, STRING *publickey,
|
||||
}
|
||||
*/
|
||||
|
||||
int ssh_userauth1_password(SSH_SESSION *session,char *username,char *password){
|
||||
STRING *password_s;
|
||||
int err;
|
||||
err=send_username(session,username);
|
||||
if(err!=SSH_AUTH_DENIED)
|
||||
return err;
|
||||
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
|
||||
* easy to guess password sizes.
|
||||
* not that sure ...
|
||||
*/
|
||||
/* XXX fix me here ! */
|
||||
/* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
|
||||
if(strlen(password)>=0){
|
||||
/* not risky to disclose the size of such a big password .. */
|
||||
password_s=string_from_char(password);
|
||||
} else {
|
||||
/* fill the password string from random things. the strcpy
|
||||
* ensure there is at least a nul byte after the password.
|
||||
* most implementation won't see the garbage at end.
|
||||
* why garbage ? because nul bytes will be compressed by
|
||||
* gzip and disclose password len.
|
||||
*/
|
||||
password_s=string_new(128);
|
||||
ssh_get_random(password_s->string,128,0);
|
||||
strcpy((char *)password_s->string,password);
|
||||
}
|
||||
int ssh_userauth1_password(SSH_SESSION *session, const char *username,
|
||||
const char *password) {
|
||||
STRING *pwd = NULL;
|
||||
int rc;
|
||||
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_AUTH_PASSWORD);
|
||||
buffer_add_ssh_string(session->out_buffer,password_s);
|
||||
string_burn(password_s);
|
||||
free(password_s);
|
||||
packet_send(session);
|
||||
return wait_auth1_status(session);
|
||||
rc = send_username(session, username);
|
||||
if (rc != SSH_AUTH_DENIED) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
|
||||
* easy to guess password sizes.
|
||||
* not that sure ...
|
||||
*/
|
||||
|
||||
/* XXX fix me here ! */
|
||||
/* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
|
||||
if(1 || strlen(password) >= 128) {
|
||||
/* not risky to disclose the size of such a big password .. */
|
||||
pwd = string_from_char(password);
|
||||
if (pwd == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
} else {
|
||||
/* fill the password string from random things. the strcpy
|
||||
* ensure there is at least a nul byte after the password.
|
||||
* most implementation won't see the garbage at end.
|
||||
* why garbage ? because nul bytes will be compressed by
|
||||
* gzip and disclose password len.
|
||||
*/
|
||||
pwd = string_new(128);
|
||||
if (pwd == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
ssh_get_random( pwd->string, 128, 0);
|
||||
strcpy((char *) pwd->string, password);
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) {
|
||||
string_burn(pwd);
|
||||
string_free(pwd);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
if (buffer_add_ssh_string(session->out_buffer, pwd) < 0) {
|
||||
string_burn(pwd);
|
||||
string_free(pwd);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
string_burn(pwd);
|
||||
string_free(pwd);
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
return wait_auth1_status(session);
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSH1 */
|
||||
#endif /* WITH_SSH1 */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
437
libssh/base64.c
437
libssh/base64.c
@@ -1,217 +1,286 @@
|
||||
/* base64 contains the needed support for base64 alphabet system, */
|
||||
/* as described in RFC1521 */
|
||||
/*
|
||||
Copyright 2003-2005 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* base64.c - support for base64 alphabet system, described in RFC1521
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005-2005 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* just the dirtiest part of code i ever made */
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
static char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/" ;
|
||||
|
||||
/* transformations */
|
||||
#define SET_A(n,i) do { n |= (i&63) <<18; } while (0)
|
||||
#define SET_B(n,i) do { n |= (i&63) <<12; } while (0)
|
||||
#define SET_C(n,i) do { n |= (i&63) << 6; } while (0)
|
||||
#define SET_D(n,i) do { n |= (i&63); } while (0)
|
||||
static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
#define GET_A(n) ((n & 0xff0000) >> 16)
|
||||
#define GET_B(n) ((n & 0xff00) >> 8)
|
||||
#define GET_C(n) (n & 0xff)
|
||||
/* Transformations */
|
||||
#define SET_A(n, i) do { (n) |= ((i) & 63) <<18; } while (0)
|
||||
#define SET_B(n, i) do { (n) |= ((i) & 63) <<12; } while (0)
|
||||
#define SET_C(n, i) do { (n) |= ((i) & 63) << 6; } while (0)
|
||||
#define SET_D(n, i) do { (n) |= ((i) & 63); } while (0)
|
||||
|
||||
static int _base64_to_bin(unsigned char dest[3], char *source,int num);
|
||||
#define GET_A(n) (((n) & 0xff0000) >> 16)
|
||||
#define GET_B(n) (((n) & 0xff00) >> 8)
|
||||
#define GET_C(n) ((n) & 0xff)
|
||||
|
||||
static int _base64_to_bin(unsigned char dest[3], const char *source, int num);
|
||||
static int get_equals(char *string);
|
||||
|
||||
/* first part : base 64 to binary */
|
||||
/* First part: base64 to binary */
|
||||
|
||||
/** \brief base64_to_bin translates a base64 string into a binary one. important,
|
||||
* \returns NULL if something went wrong (ie incorrect char)
|
||||
* \returns BUFFER containing the decoded string
|
||||
* \internal
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Translates a base64 string into a binary one.
|
||||
*
|
||||
* @returns A buffer containing the decoded string, NULL if something went
|
||||
* wrong (e.g. incorrect char).
|
||||
*/
|
||||
BUFFER *base64_to_bin(const char *source) {
|
||||
BUFFER *buffer = NULL;
|
||||
unsigned char block[3];
|
||||
char *base64;
|
||||
char *ptr;
|
||||
size_t len;
|
||||
int equals;
|
||||
|
||||
BUFFER *base64_to_bin(char *source){
|
||||
int len;
|
||||
int equals;
|
||||
BUFFER *buffer=buffer_new();
|
||||
unsigned char block[3];
|
||||
base64 = strdup(source);
|
||||
if (base64 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = base64;
|
||||
|
||||
/* get the number of equals signs, which mirrors the padding */
|
||||
equals=get_equals(source);
|
||||
if(equals>2){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
/* Get the number of equals signs, which mirrors the padding */
|
||||
equals = get_equals(ptr);
|
||||
if (equals > 2) {
|
||||
SAFE_FREE(base64);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = buffer_new();
|
||||
if (buffer == NULL) {
|
||||
SAFE_FREE(base64);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(ptr);
|
||||
while (len > 4) {
|
||||
if (_base64_to_bin(block, ptr, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
len=strlen(source);
|
||||
while(len>4){
|
||||
if(_base64_to_bin(block,source,3)){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
buffer_add_data(buffer,block,3);
|
||||
len-=4;
|
||||
source+=4;
|
||||
if (buffer_add_data(buffer, block, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* depending of the number of bytes resting, there are 3 possibilities (from the rfc) */
|
||||
switch(len){
|
||||
/* (1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded output will be
|
||||
an integral multiple of 4 characters with no "=" padding */
|
||||
case 4:
|
||||
if(equals!=0){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
if(_base64_to_bin(block,source,3)){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
buffer_add_data(buffer,block,3);
|
||||
return buffer;
|
||||
/*(2) the final quantum of encoding input is exactly 8 bits; here, the final
|
||||
unit of encoded output will be two characters followed by two "="
|
||||
padding characters */
|
||||
case 2:
|
||||
if(equals!=2){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
if(_base64_to_bin(block,source,1)){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
buffer_add_data(buffer,block,1);
|
||||
return buffer;
|
||||
/* the final quantum of encoding input is
|
||||
exactly 16 bits; here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character */
|
||||
case 3:
|
||||
if(equals!=1){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
if(_base64_to_bin(block,source,2)){
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
buffer_add_data(buffer,block,2);
|
||||
return buffer;
|
||||
default:
|
||||
/* 4,3,2 are the only padding size allowed */
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
len -= 4;
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on the number of bytes resting, there are 3 possibilities
|
||||
* from the RFC.
|
||||
*/
|
||||
switch (len) {
|
||||
/*
|
||||
* (1) The final quantum of encoding input is an integral multiple of
|
||||
* 24 bits. Here, the final unit of encoded output will be an integral
|
||||
* multiple of 4 characters with no "=" padding
|
||||
*/
|
||||
case 4:
|
||||
if (equals != 0) {
|
||||
goto error;
|
||||
}
|
||||
if (_base64_to_bin(block, ptr, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer, block, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(base64);
|
||||
|
||||
return buffer;
|
||||
/*
|
||||
* (2) The final quantum of encoding input is exactly 8 bits; here, the
|
||||
* final unit of encoded output will be two characters followed by
|
||||
* two "=" padding characters.
|
||||
*/
|
||||
case 2:
|
||||
if (equals != 2){
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (_base64_to_bin(block, ptr, 1) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer, block, 1) < 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(base64);
|
||||
|
||||
return buffer;
|
||||
/*
|
||||
* The final quantum of encoding input is exactly 16 bits. Here, the final
|
||||
* unit of encoded output will be three characters followed by one "="
|
||||
* padding character.
|
||||
*/
|
||||
case 3:
|
||||
if (equals != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (_base64_to_bin(block, ptr, 2) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer,block,2) < 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(base64);
|
||||
|
||||
return buffer;
|
||||
default:
|
||||
/* 4,3,2 are the only padding size allowed */
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
SAFE_FREE(base64);
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define BLOCK(letter,n) do { ptr=strchr(alphabet,source[n]);\
|
||||
if(!ptr) return -1;\
|
||||
i=ptr-alphabet;\
|
||||
SET_##letter(*block,i);\
|
||||
} while(0)
|
||||
/* returns 0 if ok, -1 if not (ie invalid char into the stuff) */
|
||||
static int to_block4(unsigned long *block, char *source,int num){
|
||||
char *ptr;
|
||||
unsigned int i;
|
||||
*block=0;
|
||||
if(num<1)
|
||||
return 0;
|
||||
BLOCK(A,0); /* 6 bits */
|
||||
BLOCK(B,1); /* 12 */
|
||||
if(num<2)
|
||||
return 0;
|
||||
BLOCK(C,2); /* 18 */
|
||||
if(num < 3)
|
||||
return 0;
|
||||
BLOCK(D,3); /* 24 */
|
||||
#define BLOCK(letter, n) do {ptr = strchr(alphabet, source[n]); \
|
||||
if(!ptr) return -1; \
|
||||
i = ptr - alphabet; \
|
||||
SET_##letter(*block, i); \
|
||||
} while(0)
|
||||
|
||||
/* Returns 0 if ok, -1 if not (ie invalid char into the stuff) */
|
||||
static int to_block4(unsigned long *block, const char *source, int num) {
|
||||
char *ptr;
|
||||
unsigned int i;
|
||||
|
||||
*block = 0;
|
||||
if (num < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLOCK(A, 0); /* 6 bit */
|
||||
BLOCK(B,1); /* 12 bit */
|
||||
|
||||
if (num < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLOCK(C, 2); /* 18 bit */
|
||||
|
||||
if (num < 3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLOCK(D, 3); /* 24 bit */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* num = numbers of final bytes to be decoded */
|
||||
static int _base64_to_bin(unsigned char dest[3], char *source,int num){
|
||||
unsigned long block;
|
||||
if(to_block4(&block,source,num))
|
||||
return -1;
|
||||
dest[0]=GET_A(block);
|
||||
dest[1]=GET_B(block);
|
||||
dest[2]=GET_C(block);
|
||||
return 0;
|
||||
static int _base64_to_bin(unsigned char dest[3], const char *source, int num) {
|
||||
unsigned long block;
|
||||
|
||||
if (to_block4(&block, source, num) < 0) {
|
||||
return -1;
|
||||
}
|
||||
dest[0] = GET_A(block);
|
||||
dest[1] = GET_B(block);
|
||||
dest[2] = GET_C(block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* counts the number of "=" signs, and replace them by zeroes */
|
||||
static int get_equals(char *string){
|
||||
char *ptr=string;
|
||||
int num=0;
|
||||
while((ptr=strchr(ptr,'='))){
|
||||
num++;
|
||||
*ptr=0;
|
||||
ptr++;
|
||||
}
|
||||
/* Count the number of "=" signs and replace them by zeroes */
|
||||
static int get_equals(char *string) {
|
||||
char *ptr = string;
|
||||
int num = 0;
|
||||
|
||||
return num;
|
||||
while ((ptr=strchr(ptr,'=')) != NULL) {
|
||||
num++;
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
/* thanks sysk for debugging my mess :) */
|
||||
#define BITS(n) ((1<<n)-1)
|
||||
static void _bin_to_base64(unsigned char *dest, unsigned char source[3], int len){
|
||||
switch (len){
|
||||
case 1:
|
||||
dest[0]=alphabet[(source[0]>>2)];
|
||||
dest[1]=alphabet[((source[0] & BITS(2)) << 4)];
|
||||
dest[2]='=';
|
||||
dest[3]='=';
|
||||
break;
|
||||
case 2:
|
||||
dest[0]=alphabet[source[0]>>2];
|
||||
dest[1]=alphabet[(source[1]>>4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2]=alphabet[(source[1]&BITS(4)) << 2];
|
||||
dest[3]='=';
|
||||
break;
|
||||
case 3:
|
||||
dest[0]=alphabet[(source[0]>>2)];
|
||||
dest[1]=alphabet[(source[1]>>4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2]=alphabet[ (source[2] >> 6) | (source[1]&BITS(4)) << 2];
|
||||
dest[3]=alphabet[source[2]&BITS(6)];
|
||||
break;
|
||||
}
|
||||
#define BITS(n) ((1 << (n)) - 1)
|
||||
static void _bin_to_base64(unsigned char *dest, const unsigned char source[3],
|
||||
int len) {
|
||||
switch (len) {
|
||||
case 1:
|
||||
dest[0] = alphabet[(source[0] >> 2)];
|
||||
dest[1] = alphabet[((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = '=';
|
||||
dest[3] = '=';
|
||||
break;
|
||||
case 2:
|
||||
dest[0] = alphabet[source[0] >> 2];
|
||||
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = alphabet[(source[1] & BITS(4)) << 2];
|
||||
dest[3] = '=';
|
||||
break;
|
||||
case 3:
|
||||
dest[0] = alphabet[(source[0] >> 2)];
|
||||
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
|
||||
dest[2] = alphabet[ (source[2] >> 6) | (source[1] & BITS(4)) << 2];
|
||||
dest[3] = alphabet[source[2] & BITS(6)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
/** \brief Converts binary data to a base64 string
|
||||
* \returns the converted string
|
||||
* \internal
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Converts binary data to a base64 string.
|
||||
*
|
||||
* @returns the converted string
|
||||
*/
|
||||
unsigned char *bin_to_base64(unsigned char *source, int len){
|
||||
int flen=len + (3 - (len %3)); /* round to upper 3 multiple */
|
||||
unsigned char *buffer;
|
||||
unsigned char *ptr;
|
||||
flen=(4 * flen)/3 + 1 ;
|
||||
ptr=buffer=malloc(flen);
|
||||
while(len>0){
|
||||
_bin_to_base64(ptr,source,len>3?3:len);
|
||||
ptr+=4;
|
||||
source +=3;
|
||||
len -=3;
|
||||
}
|
||||
ptr[0]=0;
|
||||
return buffer;
|
||||
unsigned char *bin_to_base64(const unsigned char *source, int len) {
|
||||
unsigned char *base64;
|
||||
unsigned char *ptr;
|
||||
int flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
|
||||
flen = (4 * flen) / 3 + 1;
|
||||
|
||||
base64 = malloc(flen);
|
||||
if (base64 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = base64;
|
||||
|
||||
while(len > 0){
|
||||
_bin_to_base64(ptr, source, len > 3 ? 3 : len);
|
||||
ptr += 4;
|
||||
source += 3;
|
||||
len -= 3;
|
||||
}
|
||||
ptr[0] = '\0';
|
||||
|
||||
return base64;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
312
libssh/buffer.c
312
libssh/buffer.c
@@ -1,25 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2003-2008 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* buffer.c - buffer functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/** \defgroup ssh_buffer SSH Buffers
|
||||
@@ -31,50 +39,69 @@ MA 02111-1307, USA. */
|
||||
*/
|
||||
|
||||
/** \brief creates a new buffer
|
||||
* \return a new initialized buffer
|
||||
* \return a new initialized buffer, NULL on error.
|
||||
*/
|
||||
BUFFER *buffer_new(){
|
||||
BUFFER *buffer=malloc(sizeof(BUFFER));
|
||||
memset(buffer,0,sizeof(BUFFER));
|
||||
return buffer;
|
||||
struct buffer_struct *buffer_new(void) {
|
||||
struct buffer_struct *buf = malloc(sizeof(struct buffer_struct));
|
||||
|
||||
if (buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(buf, 0, sizeof(struct buffer_struct));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** \brief deallocate a buffer
|
||||
* \param buffer buffer to free
|
||||
*/
|
||||
void buffer_free(BUFFER *buffer){
|
||||
// printf("buffer %p : free(%p);\n",buffer,buffer->data);
|
||||
if(buffer->data){
|
||||
memset(buffer->data,0,buffer->allocated); /* burn the data */
|
||||
free(buffer->data);
|
||||
}
|
||||
memset(buffer,'x',sizeof (*buffer));
|
||||
free(buffer);
|
||||
void buffer_free(struct buffer_struct *buffer) {
|
||||
if (buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer->data) {
|
||||
/* burn the data */
|
||||
memset(buffer->data, 0, buffer->allocated);
|
||||
SAFE_FREE(buffer->data);
|
||||
}
|
||||
memset(buffer, 'X', sizeof(*buffer));
|
||||
SAFE_FREE(buffer);
|
||||
}
|
||||
|
||||
static void realloc_buffer(BUFFER *buffer,int needed){
|
||||
int smallest=1;
|
||||
// find the smallest power of two which is greater or equal to needed
|
||||
while(smallest<=needed)
|
||||
smallest <<= 1;
|
||||
needed=smallest;
|
||||
// printf("buffer %p : realloc(%x,%d)=",buffer,buffer->data,needed);
|
||||
buffer->data=realloc(buffer->data,needed);
|
||||
// printf("%p\n",buffer->data);
|
||||
buffer->allocated=needed;
|
||||
static int realloc_buffer(struct buffer_struct *buffer, int needed) {
|
||||
int smallest = 1;
|
||||
char *new = NULL;
|
||||
/* Find the smallest power of two which is greater or equal to needed */
|
||||
while(smallest <= needed) {
|
||||
smallest <<= 1;
|
||||
}
|
||||
needed = smallest;
|
||||
new = realloc(buffer->data, needed);
|
||||
if (new == NULL) {
|
||||
return -1;
|
||||
}
|
||||
buffer->data = new;
|
||||
buffer->allocated = needed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief reinitialize a buffer
|
||||
* \param buffer buffer
|
||||
* \return 0 on sucess, < 0 on error
|
||||
*/
|
||||
void buffer_reinit(BUFFER *buffer){
|
||||
memset(buffer->data,0,buffer->used);
|
||||
buffer->used=0;
|
||||
buffer->pos=0;
|
||||
if(buffer->allocated > 127){
|
||||
realloc_buffer(buffer,127);
|
||||
int buffer_reinit(struct buffer_struct *buffer) {
|
||||
memset(buffer->data, 0, buffer->used);
|
||||
buffer->used = 0;
|
||||
buffer->pos = 0;
|
||||
if(buffer->allocated > 127) {
|
||||
if (realloc_buffer(buffer, 127) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -83,45 +110,74 @@ void buffer_reinit(BUFFER *buffer){
|
||||
* \param data data pointer
|
||||
* \param len length of data
|
||||
*/
|
||||
void buffer_add_data(BUFFER *buffer,const void *data,int len){
|
||||
if(buffer->allocated < buffer->used+len)
|
||||
realloc_buffer(buffer,buffer->used+len);
|
||||
memcpy(buffer->data+buffer->used,data,len);
|
||||
buffer->used+=len;
|
||||
int buffer_add_data(struct buffer_struct *buffer, const void *data, u32 len) {
|
||||
if (buffer->allocated < (buffer->used + len)) {
|
||||
if (realloc_buffer(buffer, buffer->used + len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buffer->data+buffer->used, data, len);
|
||||
buffer->used+=len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief add a SSH string to the tail of buffer
|
||||
* \param buffer buffer
|
||||
* \param string SSH String to add
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
void buffer_add_ssh_string(BUFFER *buffer,STRING *string){
|
||||
u32 len=ntohl(string->size);
|
||||
buffer_add_data(buffer,string,len+sizeof(u32));
|
||||
int buffer_add_ssh_string(struct buffer_struct *buffer,
|
||||
struct string_struct *string) {
|
||||
u32 len = 0;
|
||||
|
||||
len = ntohl(string->size);
|
||||
if (buffer_add_data(buffer, string, len + sizeof(u32)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/** \internal
|
||||
* \brief add a 32 bits unsigned integer to the tail of buffer
|
||||
* \param buffer buffer
|
||||
* \param data 32 bits integer
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
void buffer_add_u32(BUFFER *buffer,u32 data){
|
||||
buffer_add_data(buffer,&data,sizeof(data));
|
||||
int buffer_add_u32(struct buffer_struct *buffer,u32 data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief add a 64 bits unsigned integer to the tail of buffer
|
||||
* \param buffer buffer
|
||||
* \param data 64 bits integer
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
void buffer_add_u64(BUFFER *buffer,u64 data){
|
||||
buffer_add_data(buffer,&data,sizeof(data));
|
||||
int buffer_add_u64(struct buffer_struct *buffer, u64 data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/** \internal
|
||||
* \brief add a 8 bits unsigned integer to the tail of buffer
|
||||
* \param buffer buffer
|
||||
* \param data 8 bits integer
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
void buffer_add_u8(BUFFER *buffer,u8 data){
|
||||
buffer_add_data(buffer,&data,sizeof(u8));
|
||||
int buffer_add_u8(struct buffer_struct *buffer,u8 data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(u8)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -129,22 +185,35 @@ void buffer_add_u8(BUFFER *buffer,u8 data){
|
||||
* \param buffer buffer
|
||||
* \param data data to add
|
||||
* \param len length of data
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
void buffer_add_data_begin(BUFFER *buffer, const void *data, int len){
|
||||
if(buffer->allocated < buffer->used + len)
|
||||
realloc_buffer(buffer,buffer->used+len);
|
||||
memmove(buffer->data+len,buffer->data,buffer->used);
|
||||
memcpy(buffer->data,data,len);
|
||||
buffer->used+=len;
|
||||
int buffer_prepend_data(struct buffer_struct *buffer, const void *data,
|
||||
u32 len) {
|
||||
if (buffer->allocated < (buffer->used + len)) {
|
||||
if (realloc_buffer(buffer, buffer->used + len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
memmove(buffer->data + len, buffer->data, buffer->used);
|
||||
memcpy(buffer->data, data, len);
|
||||
buffer->used += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief append data from a buffer to tail of another
|
||||
* \param buffer destination buffer
|
||||
* \param source source buffer. Doesn't take position in buffer into account
|
||||
* \return 0 on success, -1 on error.
|
||||
*/
|
||||
void buffer_add_buffer(BUFFER *buffer, BUFFER *source){
|
||||
buffer_add_data(buffer,buffer_get(source),buffer_get_len(source));
|
||||
int buffer_add_buffer(struct buffer_struct *buffer,
|
||||
struct buffer_struct *source) {
|
||||
if (buffer_add_data(buffer, buffer_get(source), buffer_get_len(source)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief get a pointer on the head of the buffer
|
||||
@@ -154,8 +223,8 @@ void buffer_add_buffer(BUFFER *buffer, BUFFER *source){
|
||||
* \see buffer_get_rest()
|
||||
* \see buffer_get_len()
|
||||
*/
|
||||
void *buffer_get(BUFFER *buffer){
|
||||
return buffer->data;
|
||||
void *buffer_get(struct buffer_struct *buffer){
|
||||
return buffer->data;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -165,8 +234,8 @@ void *buffer_get(BUFFER *buffer){
|
||||
* \see buffer_get_rest_len()
|
||||
* \see buffer_get()
|
||||
*/
|
||||
void *buffer_get_rest(BUFFER *buffer){
|
||||
return buffer->data+buffer->pos;
|
||||
void *buffer_get_rest(struct buffer_struct *buffer){
|
||||
return buffer->data + buffer->pos;
|
||||
}
|
||||
|
||||
/** \brief get length of the buffer, not counting position
|
||||
@@ -174,7 +243,7 @@ void *buffer_get_rest(BUFFER *buffer){
|
||||
* \return length of the buffer
|
||||
* \see buffer_get()
|
||||
*/
|
||||
int buffer_get_len(BUFFER *buffer){
|
||||
u32 buffer_get_len(struct buffer_struct *buffer){
|
||||
return buffer->used;
|
||||
}
|
||||
|
||||
@@ -184,7 +253,7 @@ int buffer_get_len(BUFFER *buffer){
|
||||
* \return length of the buffer
|
||||
* \see buffer_get_rest()
|
||||
*/
|
||||
int buffer_get_rest_len(BUFFER *buffer){
|
||||
u32 buffer_get_rest_len(struct buffer_struct *buffer){
|
||||
return buffer->used - buffer->pos;
|
||||
}
|
||||
|
||||
@@ -195,7 +264,7 @@ int buffer_get_rest_len(BUFFER *buffer){
|
||||
* \param len number of bytes to eat
|
||||
* \return new size of the buffer
|
||||
*/
|
||||
int buffer_pass_bytes(BUFFER *buffer,int len){
|
||||
u32 buffer_pass_bytes(struct buffer_struct *buffer, u32 len){
|
||||
if(buffer->used < buffer->pos+len)
|
||||
return 0;
|
||||
buffer->pos+=len;
|
||||
@@ -213,7 +282,7 @@ int buffer_pass_bytes(BUFFER *buffer,int len){
|
||||
* \param len number of bytes to remove from tail
|
||||
* \return new size of the buffer
|
||||
*/
|
||||
int buffer_pass_bytes_end(BUFFER *buffer,int len){
|
||||
u32 buffer_pass_bytes_end(struct buffer_struct *buffer, u32 len){
|
||||
if(buffer->used < buffer->pos + len)
|
||||
return 0;
|
||||
buffer->used-=len;
|
||||
@@ -228,7 +297,7 @@ int buffer_pass_bytes_end(BUFFER *buffer,int len){
|
||||
* \returns 0 if there is not enough data in buffer
|
||||
* \returns len otherwise.
|
||||
*/
|
||||
int buffer_get_data(BUFFER *buffer, void *data, int len){
|
||||
u32 buffer_get_data(struct buffer_struct *buffer, void *data, u32 len){
|
||||
if(buffer->pos+len>buffer->used)
|
||||
return 0; /*no enough data in buffer */
|
||||
memcpy(data,buffer->data+buffer->pos,len);
|
||||
@@ -242,7 +311,7 @@ int buffer_get_data(BUFFER *buffer, void *data, int len){
|
||||
* \returns 0 if there is not enough data in buffer
|
||||
* \returns 1 otherwise.
|
||||
*/
|
||||
int buffer_get_u8(BUFFER *buffer, u8 *data){
|
||||
int buffer_get_u8(struct buffer_struct *buffer, u8 *data){
|
||||
return buffer_get_data(buffer,data,sizeof(u8));
|
||||
}
|
||||
|
||||
@@ -253,7 +322,7 @@ int buffer_get_u8(BUFFER *buffer, u8 *data){
|
||||
* \returns 0 if there is not enough data in buffer
|
||||
* \returns 4 otherwise.
|
||||
*/
|
||||
int buffer_get_u32(BUFFER *buffer, u32 *data){
|
||||
int buffer_get_u32(struct buffer_struct *buffer, u32 *data){
|
||||
return buffer_get_data(buffer,data,sizeof(u32));
|
||||
}
|
||||
/** \internal
|
||||
@@ -263,7 +332,7 @@ int buffer_get_u32(BUFFER *buffer, u32 *data){
|
||||
* \returns 0 if there is not enough data in buffer
|
||||
* \returns 8 otherwise.
|
||||
*/
|
||||
int buffer_get_u64(BUFFER *buffer, u64 *data){
|
||||
int buffer_get_u64(struct buffer_struct *buffer, u64 *data){
|
||||
return buffer_get_data(buffer,data,sizeof(u64));
|
||||
}
|
||||
/** \internal
|
||||
@@ -272,23 +341,30 @@ int buffer_get_u64(BUFFER *buffer, u64 *data){
|
||||
* \returns The SSH String read
|
||||
* \returns NULL otherwise.
|
||||
*/
|
||||
STRING *buffer_get_ssh_string(BUFFER *buffer){
|
||||
u32 stringlen;
|
||||
u32 hostlen;
|
||||
STRING *str;
|
||||
if(buffer_get_u32(buffer,&stringlen)==0)
|
||||
return NULL;
|
||||
hostlen=ntohl(stringlen);
|
||||
/* verify if there is enough space in buffer to get it */
|
||||
if(buffer->pos+hostlen>buffer->used)
|
||||
return NULL; /* it is indeed */
|
||||
str=string_new(hostlen);
|
||||
if(buffer_get_data(buffer,str->string,hostlen)!=hostlen){
|
||||
// should never happen
|
||||
free(str);
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
struct string_struct *buffer_get_ssh_string(struct buffer_struct *buffer) {
|
||||
u32 stringlen;
|
||||
u32 hostlen;
|
||||
struct string_struct *str = NULL;
|
||||
|
||||
if (buffer_get_u32(buffer, &stringlen) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
hostlen = ntohl(stringlen);
|
||||
/* verify if there is enough space in buffer to get it */
|
||||
if ((buffer->pos + hostlen) > buffer->used) {
|
||||
return NULL; /* it is indeed */
|
||||
}
|
||||
str = string_new(hostlen);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (buffer_get_data(buffer, str->string, hostlen) != hostlen) {
|
||||
/* should never happen */
|
||||
SAFE_FREE(str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
/** \internal
|
||||
* \brief gets a mpint out of the buffer. Adjusts the read pointer.
|
||||
@@ -298,22 +374,28 @@ STRING *buffer_get_ssh_string(BUFFER *buffer){
|
||||
* \returns NULL otherwise
|
||||
*/
|
||||
|
||||
STRING *buffer_get_mpint(BUFFER *buffer){
|
||||
u16 bits;
|
||||
u32 len;
|
||||
STRING *str;
|
||||
if(buffer_get_data(buffer,&bits,sizeof(u16))!= sizeof(u16))
|
||||
return NULL;
|
||||
bits=ntohs(bits);
|
||||
len=(bits+7)/8;
|
||||
if(buffer->pos+len > buffer->used)
|
||||
return NULL;
|
||||
str=string_new(len);
|
||||
if(buffer_get_data(buffer,str->string,len)!=len){
|
||||
free(str);
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
struct string_struct *buffer_get_mpint(struct buffer_struct *buffer) {
|
||||
u16 bits;
|
||||
u32 len;
|
||||
struct string_struct *str = NULL;
|
||||
|
||||
if (buffer_get_data(buffer, &bits, sizeof(u16)) != sizeof(u16)) {
|
||||
return NULL;
|
||||
}
|
||||
bits = ntohs(bits);
|
||||
len = (bits + 7) / 8;
|
||||
if ((buffer->pos + len) > buffer->used) {
|
||||
return NULL;
|
||||
}
|
||||
str = string_new(len);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (buffer_get_data(buffer, str->string, len) != len) {
|
||||
SAFE_FREE(str);
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
2741
libssh/channels.c
2741
libssh/channels.c
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,26 @@
|
||||
/* channels1.c */
|
||||
/* Support for SSH-1 type channels */
|
||||
/*
|
||||
Copyright 2005 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* channels1.c - Support for SSH-1 type channels
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -27,29 +29,38 @@ MA 02111-1307, USA. */
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh1.h"
|
||||
|
||||
#ifdef HAVE_SSH1
|
||||
#ifdef WITH_SSH1
|
||||
|
||||
/* this is a big hack. In fact, SSH-1 doesn't make a clever use of channels.
|
||||
* The whole packets concerning Shells are sent outside of a channel.
|
||||
/*
|
||||
* This is a big hack. In fact, SSH1 doesn't make a clever use of channels.
|
||||
* The whole packets concerning shells are sent outside of a channel.
|
||||
* Thus, an inside limitation of this behaviour is that you can't only
|
||||
* request one Shell.
|
||||
* And i don't even know yet how they managed to imbed two "channel"
|
||||
* into one protocol.
|
||||
* request one shell.
|
||||
* The question is stil how they managed to imbed two "channel" into one
|
||||
* protocol.
|
||||
*/
|
||||
|
||||
int channel_open_session1(CHANNEL *chan){
|
||||
// we guess we are requesting an *exec* channel. It can only have
|
||||
// only one exec channel. so we abort with an error if we need more than
|
||||
SSH_SESSION *session=chan->session;
|
||||
if(session->exec_channel_opened){
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"SSH-1 supports only one execution channel. One has already been opened");
|
||||
return -1;
|
||||
}
|
||||
session->exec_channel_opened=1;
|
||||
chan->open=1;
|
||||
ssh_say(2,"Opened a ssh1 channel session\n");
|
||||
return 0;
|
||||
int channel_open_session1(CHANNEL *chan) {
|
||||
/*
|
||||
* We guess we are requesting an *exec* channel. It can only have one exec
|
||||
* channel. So we abort with an error if we need more than one.
|
||||
*/
|
||||
SSH_SESSION *session = chan->session;
|
||||
if (session->exec_channel_opened) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"SSH1 supports only one execution channel. "
|
||||
"One has already been opened");
|
||||
return -1;
|
||||
}
|
||||
session->exec_channel_opened = 1;
|
||||
chan->open = 1;
|
||||
chan->local_maxpacket = 32000;
|
||||
chan->local_window = 64000;
|
||||
ssh_log(session, SSH_LOG_PACKET, "Opened a SSH1 channel session");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 10 SSH_CMSG_REQUEST_PTY
|
||||
*
|
||||
* string TERM environment variable value (e.g. vt100)
|
||||
@@ -62,156 +73,233 @@ int channel_open_session1(CHANNEL *chan){
|
||||
* much simplier under ssh2. I just hope the defaults values are ok ...
|
||||
*/
|
||||
|
||||
int channel_request_pty_size1(CHANNEL *channel, char *terminal, int col,
|
||||
int row){
|
||||
STRING *str;
|
||||
SSH_SESSION *session=channel->session;
|
||||
str=string_from_char(terminal);
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_REQUEST_PTY);
|
||||
buffer_add_ssh_string(session->out_buffer,str);
|
||||
free(str);
|
||||
buffer_add_u32(session->out_buffer,ntohl(row));
|
||||
buffer_add_u32(session->out_buffer,ntohl(col));
|
||||
buffer_add_u32(session->out_buffer,0); /* x */
|
||||
buffer_add_u32(session->out_buffer,0); /* y */
|
||||
buffer_add_u8(session->out_buffer,0); /* tty things */
|
||||
ssh_say(2,"Opening a ssh1 pty\n");
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
if(packet_read(session))
|
||||
return -1;
|
||||
if(packet_translate(session))
|
||||
return -1;
|
||||
switch (session->in_packet.type){
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_say(2,"pty : Success\n");
|
||||
return 0;
|
||||
break;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,
|
||||
"Server denied PTY allocation");
|
||||
ssh_say(2,"pty : denied\n");
|
||||
break;
|
||||
default:
|
||||
ssh_say(2,"pty : error\n");
|
||||
ssh_set_error(session,SSH_FATAL,
|
||||
"Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
return -1;
|
||||
}
|
||||
int channel_request_pty_size1(CHANNEL *channel, const char *terminal, int col,
|
||||
int row) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
STRING *str = NULL;
|
||||
|
||||
str = string_from_char(terminal);
|
||||
if (str == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
|
||||
buffer_add_ssh_string(session->out_buffer, str) < 0) {
|
||||
string_free(str);
|
||||
return -1;
|
||||
}
|
||||
string_free(str);
|
||||
|
||||
if (buffer_add_u32(session->out_buffer, ntohl(row)) < 0 ||
|
||||
buffer_add_u32(session->out_buffer, ntohl(col)) < 0 ||
|
||||
buffer_add_u32(session->out_buffer, 0) < 0 || /* x */
|
||||
buffer_add_u32(session->out_buffer, 0) < 0 || /* y */
|
||||
buffer_add_u8(session->out_buffer, 0) < 0) { /* tty things */
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
|
||||
if (packet_send(session) != SSH_OK ||
|
||||
packet_read(session) != SSH_OK ||
|
||||
packet_translate(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (session->in_packet.type) {
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_log(session, SSH_LOG_RARE, "PTY: Success");
|
||||
return 0;
|
||||
break;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Server denied PTY allocation");
|
||||
ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
|
||||
break;
|
||||
default:
|
||||
ssh_log(session, SSH_LOG_RARE, "PTY: error\n");
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows){
|
||||
SSH_SESSION *session=channel->session;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_WINDOW_SIZE);
|
||||
buffer_add_u32(session->out_buffer,ntohl(rows));
|
||||
buffer_add_u32(session->out_buffer,ntohl(cols));
|
||||
buffer_add_u32(session->out_buffer,0);
|
||||
buffer_add_u32(session->out_buffer,0);
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
ssh_say(2,"Change pty size send\n");
|
||||
packet_wait(session,SSH_SMSG_SUCCESS,1);
|
||||
switch (session->in_packet.type){
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_say(2,"pty size changed\n");
|
||||
return 0;
|
||||
break;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_say(2,"pty size change denied\n");
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"pty size change denied");
|
||||
return -1;
|
||||
}
|
||||
ssh_set_error(session,SSH_FATAL,"Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 ||
|
||||
buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 ||
|
||||
buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 ||
|
||||
buffer_add_u32(session->out_buffer, 0) < 0 ||
|
||||
buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Change pty size send");
|
||||
|
||||
if (packet_wait(session, SSH_SMSG_SUCCESS, 1) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (session->in_packet.type) {
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty size changed");
|
||||
return 0;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty size change denied");
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int channel_request_shell1(CHANNEL *channel){
|
||||
SSH_SESSION *session=channel->session;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL);
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
ssh_say(2,"Launched a shell\n");
|
||||
int channel_request_shell1(CHANNEL *channel) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Launched a shell");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int channel_request_exec1(CHANNEL *channel, const char *cmd) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
STRING *command = NULL;
|
||||
|
||||
command = string_from_char(cmd);
|
||||
if (command == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 ||
|
||||
buffer_add_ssh_string(session->out_buffer, command) < 0) {
|
||||
string_free(command);
|
||||
return -1;
|
||||
}
|
||||
string_free(command);
|
||||
|
||||
if(packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int channel_rcv_data1(SSH_SESSION *session, int is_stderr) {
|
||||
CHANNEL *channel = session->channels;
|
||||
STRING *str = NULL;
|
||||
|
||||
str = buffer_get_ssh_string(session->in_buffer);
|
||||
if (str == NULL) {
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Adding %zu bytes data in %d",
|
||||
string_len(str), is_stderr);
|
||||
|
||||
if (channel_default_bufferize(channel, str->string, string_len(str),
|
||||
is_stderr) < 0) {
|
||||
string_free(str);
|
||||
return -1;
|
||||
}
|
||||
string_free(str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int channel_request_exec1(CHANNEL *channel, char *cmd){
|
||||
SSH_SESSION *session=channel->session;
|
||||
STRING *command=string_from_char(cmd);
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_CMD);
|
||||
buffer_add_ssh_string(session->out_buffer,command);
|
||||
free(command);
|
||||
if(packet_send(session))
|
||||
static int channel_rcv_close1(SSH_SESSION *session) {
|
||||
CHANNEL *channel = session->channels;
|
||||
u32 status;
|
||||
|
||||
buffer_get_u32(session->in_buffer, &status);
|
||||
/*
|
||||
* It's much more than a channel closing. spec says it's the last
|
||||
* message sent by server (strange)
|
||||
*/
|
||||
|
||||
/* actually status is lost somewhere */
|
||||
channel->open = 0;
|
||||
channel->remote_eof = 1;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int channel_handle1(SSH_SESSION *session, int type) {
|
||||
ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type);
|
||||
switch (type) {
|
||||
case SSH_SMSG_STDOUT_DATA:
|
||||
if (channel_rcv_data1(session,0) < 0) {
|
||||
return -1;
|
||||
ssh_say(2,"executing %s...\n",cmd);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SSH_SMSG_EXITSTATUS:
|
||||
if (channel_rcv_close1(session) < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Unexepected message %d", type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void channel_rcv_data1(SSH_SESSION *session, int is_stderr){
|
||||
CHANNEL *channel;
|
||||
STRING *str;
|
||||
channel=session->channels; // Easy. hack this when multiple channel
|
||||
// are comming
|
||||
str=buffer_get_ssh_string(session->in_buffer);
|
||||
if(!str){
|
||||
ssh_say(0,"Invalid data packet !\n");
|
||||
return;
|
||||
int channel_write1(CHANNEL *channel, const void *data, int len) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
int origlen = len;
|
||||
int effectivelen;
|
||||
|
||||
while (len > 0) {
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) {
|
||||
return -1;
|
||||
}
|
||||
ssh_say(3,"adding %d bytes data in %d\n",string_len(str),is_stderr);
|
||||
channel_default_bufferize(channel,str->string,string_len(str),
|
||||
is_stderr);
|
||||
free(str);
|
||||
}
|
||||
|
||||
static void channel_rcv_close1(SSH_SESSION *session){
|
||||
CHANNEL *channel=session->channels;
|
||||
u32 status;
|
||||
buffer_get_u32(session->in_buffer,&status);
|
||||
/* it's much more than a channel closing. spec says it's the last
|
||||
* message sent by server (strange)
|
||||
*/
|
||||
/* actually status is lost somewhere */
|
||||
channel->open=0;
|
||||
channel->remote_eof=1;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_EXIT_CONFIRMATION);
|
||||
packet_send(session);
|
||||
}
|
||||
|
||||
void channel_handle1(SSH_SESSION *session, int type){
|
||||
ssh_say(3,"Channel_handle1(%d)\n",type);
|
||||
switch (type){
|
||||
case SSH_SMSG_STDOUT_DATA:
|
||||
channel_rcv_data1(session,0);
|
||||
break;
|
||||
case SSH_SMSG_EXITSTATUS:
|
||||
channel_rcv_close1(session);
|
||||
break;
|
||||
default:
|
||||
ssh_say(0,"Unexepected message %d\n",type);
|
||||
effectivelen = len > 32000 ? 32000 : len;
|
||||
|
||||
if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
|
||||
buffer_add_data(session->out_buffer, data, effectivelen) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int channel_write1(CHANNEL *channel, void *data, int len){
|
||||
SSH_SESSION *session=channel->session;
|
||||
int origlen=len;
|
||||
int effectivelen;
|
||||
while(len>0){
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_STDIN_DATA);
|
||||
if(len > 32000)
|
||||
effectivelen=32000;
|
||||
else
|
||||
effectivelen=len;
|
||||
buffer_add_u32(session->out_buffer,htonl(effectivelen));
|
||||
buffer_add_data(session->out_buffer,data,effectivelen);
|
||||
data+=effectivelen;
|
||||
len-=effectivelen;
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
data += effectivelen;
|
||||
len -= effectivelen;
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
return origlen;
|
||||
}
|
||||
|
||||
return origlen;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSH1 */
|
||||
#endif /* WITH_SSH1 */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
1001
libssh/client.c
1001
libssh/client.c
File diff suppressed because it is too large
Load Diff
639
libssh/connect.c
639
libssh/connect.c
@@ -1,42 +1,51 @@
|
||||
/* connect.c */
|
||||
/* it handles connections to ssh servers */
|
||||
/*
|
||||
Copyright (c) 2003-2008 Aris Adamantiadis
|
||||
* connect.c - handles connections to ssh servers
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
The SSH Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The SSH Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the SSH Library; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WIN32_WINNT 0x0501 //getaddrinfo, freeaddrinfo, getnameinfo
|
||||
/* getaddrinfo, freeaddrinfo, getnameinfo */
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include "wspiapi.h" //workaround for w2k systems
|
||||
#else
|
||||
|
||||
#include "wspiapi.h" /* Workaround for w2k systems */
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
@@ -47,267 +56,359 @@ MA 02111-1307, USA. */
|
||||
#error "Your system must have getaddrinfo()"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef _WIN32
|
||||
static void sock_set_nonblocking(socket_t sock) {
|
||||
fcntl(sock,F_SETFL,O_NONBLOCK);
|
||||
u_long nonblocking = 1;
|
||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||
}
|
||||
static void sock_set_blocking(socket_t sock){
|
||||
fcntl(sock,F_SETFL,0);
|
||||
|
||||
static void sock_set_blocking(socket_t sock) {
|
||||
u_long nonblocking = 0;
|
||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||
}
|
||||
#else
|
||||
|
||||
#ifndef gai_strerror
|
||||
char WSAAPI *gai_strerrorA(int code) {
|
||||
static char buf[256];
|
||||
|
||||
snprintf(buf, sizeof(buf), "Undetermined error code (%d)", code);
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif /* gai_strerror */
|
||||
|
||||
#else /* _WIN32 */
|
||||
static void sock_set_nonblocking(socket_t sock) {
|
||||
u_long nonblocking = 1;
|
||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||
}
|
||||
static void sock_set_blocking(socket_t sock){
|
||||
u_long nonblocking = 0;
|
||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
char WSAAPI *gai_strerrorA(int code){
|
||||
static char buffer[256];
|
||||
snprintf(buffer,256,"Undetermined error code (%d)",code);
|
||||
return buffer;
|
||||
static void sock_set_blocking(socket_t sock) {
|
||||
fcntl(sock, F_SETFL, 0);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
static int getai(const char *host, int port, struct addrinfo **ai) {
|
||||
const char *service = NULL;
|
||||
struct addrinfo hints;
|
||||
char s_port[10];
|
||||
|
||||
ZERO_STRUCT(hints);
|
||||
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (port == 0) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
} else {
|
||||
snprintf(s_port, sizeof(s_port), "%hu", port);
|
||||
service = s_port;
|
||||
}
|
||||
|
||||
return getaddrinfo(host, service, &hints, ai);
|
||||
}
|
||||
|
||||
#endif
|
||||
static int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host,
|
||||
int port, struct addrinfo *ai, long timeout, long usec, socket_t s) {
|
||||
struct timeval to;
|
||||
fd_set set;
|
||||
int rc = 0;
|
||||
unsigned int len = sizeof(rc);
|
||||
|
||||
static int getai(const char *host, int port, struct addrinfo **ai)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
char *service=NULL;
|
||||
char s_port[10];
|
||||
enter_function();
|
||||
|
||||
memset(&hints,0,sizeof(hints));
|
||||
hints.ai_protocol=IPPROTO_TCP;
|
||||
hints.ai_family=PF_UNSPEC;
|
||||
hints.ai_socktype=SOCK_STREAM;
|
||||
if(port==0){
|
||||
hints.ai_flags=AI_PASSIVE;
|
||||
to.tv_sec = timeout;
|
||||
to.tv_usec = usec;
|
||||
|
||||
sock_set_nonblocking(s);
|
||||
|
||||
/* The return value is checked later */
|
||||
connect(s, ai->ai_addr, ai->ai_addrlen);
|
||||
freeaddrinfo(ai);
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(s, &set);
|
||||
|
||||
rc = select(s + 1, NULL, &set, NULL, &to);
|
||||
if (rc == 0) {
|
||||
/* timeout */
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Timeout while connecting to %s:%d", host, port);
|
||||
close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Select error: %s", strerror(errno));
|
||||
close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
/* Get connect(2) return code. Zero means no error */
|
||||
getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Connect to %s:%d failed: %s", host, port, strerror(rc));
|
||||
close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* s is connected ? */
|
||||
ssh_log(session, SSH_LOG_PACKET, "Socket connected with timeout\n");
|
||||
sock_set_blocking(s);
|
||||
|
||||
leave_function();
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Connect to an IPv4 or IPv6 host specified by its IP address or
|
||||
* hostname.
|
||||
*
|
||||
* @returns A file descriptor, < 0 on error.
|
||||
*/
|
||||
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,
|
||||
const char *bind_addr, int port, long timeout, long usec) {
|
||||
socket_t s = -1;
|
||||
int rc;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *itr;
|
||||
|
||||
enter_function();
|
||||
|
||||
rc = getai(host, port, &ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (itr = ai; itr != NULL; itr = itr->ai_next){
|
||||
/* create socket */
|
||||
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
|
||||
if (s < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Socket create failed: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind_addr) {
|
||||
struct addrinfo *bind_ai;
|
||||
struct addrinfo *bind_itr;
|
||||
|
||||
ssh_log(session, SSH_LOG_PACKET, "Resolving %s\n", bind_addr);
|
||||
|
||||
rc = getai(host, 0, &bind_ai);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to resolve bind address %s (%s)",
|
||||
bind_addr,
|
||||
gai_strerror(rc));
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
|
||||
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Binding local address: %s", strerror(errno));
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(bind_ai);
|
||||
|
||||
/* Cannot bind to any local addresses */
|
||||
if (bind_itr == NULL) {
|
||||
close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeout || usec) {
|
||||
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
|
||||
timeout, usec, s);
|
||||
leave_function();
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno));
|
||||
close(s);
|
||||
s = -1;
|
||||
leave_function();
|
||||
continue;
|
||||
} else {
|
||||
snprintf(s_port,sizeof(s_port),"%hu",port);
|
||||
service=s_port;
|
||||
/* We are connected */
|
||||
break;
|
||||
}
|
||||
return getaddrinfo(host,service,&hints,ai);
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
leave_function();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host, int port, struct addrinfo *ai,
|
||||
long timeout, long usec,socket_t s)
|
||||
{
|
||||
struct timeval to;
|
||||
fd_set set;
|
||||
int ret=0;
|
||||
unsigned int len=sizeof(ret);
|
||||
enter_function();
|
||||
to.tv_sec=timeout;
|
||||
to.tv_usec=usec;
|
||||
sock_set_nonblocking(s);
|
||||
connect(s,ai->ai_addr,ai->ai_addrlen);
|
||||
freeaddrinfo(ai);
|
||||
FD_ZERO(&set);
|
||||
FD_SET(s,&set);
|
||||
ret=select(s+1,NULL,&set,NULL,&to);
|
||||
if(ret==0){
|
||||
/* timeout */
|
||||
ssh_set_error(session,SSH_FATAL,"Timeout while connecting to %s:%d",host,port);
|
||||
close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
if(ret<0){
|
||||
ssh_set_error(session,SSH_FATAL,"Select error : %s",strerror(errno));
|
||||
close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
/* get connect(2) return code. zero means no error */
|
||||
getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&ret,&len);
|
||||
if (ret!=0){
|
||||
ssh_set_error(session,SSH_FATAL,"Connecting : %s",strerror(ret));
|
||||
close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
/* s is connected ? */
|
||||
ssh_log(session,SSH_LOG_PACKET,"socket connected with timeout\n");
|
||||
sock_set_blocking(s);
|
||||
leave_function();
|
||||
return s;
|
||||
}
|
||||
/**
|
||||
* @addtogroup ssh_session
|
||||
* @{ */
|
||||
|
||||
/** \internal
|
||||
* \brief connect_host connects to an IPv4 (or IPv6) host
|
||||
* specified by its IP address or hostname.
|
||||
* \returns file descriptor
|
||||
* \returns less than 0 value
|
||||
*/
|
||||
|
||||
socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
||||
*bind_addr, int port,long timeout, long usec){
|
||||
socket_t s=-1;
|
||||
int my_errno;
|
||||
struct addrinfo *ai, *ai2;
|
||||
enter_function();
|
||||
my_errno=getai(host, port, &ai);
|
||||
if (my_errno){
|
||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,gai_strerror(my_errno));
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(ai2=ai;ai2!=NULL;ai2=ai2->ai_next){
|
||||
/* create socket */
|
||||
s=socket(ai2->ai_family,ai2->ai_socktype,ai2->ai_protocol);
|
||||
if(s<0){
|
||||
ssh_set_error(session,SSH_FATAL,"socket : %s",strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(bind_addr){
|
||||
struct addrinfo *bind_ai, *bind_ai2;
|
||||
|
||||
ssh_log(session,SSH_LOG_PACKET,"resolving %s\n",bind_addr);
|
||||
my_errno=getai(host,0,&bind_ai);
|
||||
if (my_errno){
|
||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,gai_strerror(my_errno));
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(bind_ai2=bind_ai;bind_ai2!=NULL;bind_ai2=bind_ai2->ai_next){
|
||||
if(bind(s,bind_ai2->ai_addr,bind_ai2->ai_addrlen)<0){
|
||||
ssh_set_error(session,SSH_FATAL,"Binding local address : %s",strerror(errno));
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(bind_ai);
|
||||
if(bind_ai2==NULL){ /*cannot bind to any local addresses*/
|
||||
close(s);
|
||||
s=-1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(timeout||usec){
|
||||
socket_t ret=ssh_connect_ai_timeout(session,host,port,ai2,timeout,usec,s);
|
||||
leave_function();
|
||||
return ret;
|
||||
}
|
||||
if(connect(s,ai2->ai_addr,ai2->ai_addrlen)<0){
|
||||
ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
|
||||
close(s);
|
||||
s=-1;
|
||||
leave_function();
|
||||
continue;
|
||||
}
|
||||
else{ /*we are connected*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
leave_function();
|
||||
return s;
|
||||
}
|
||||
|
||||
/** \addtogroup ssh_session
|
||||
* * @{ */
|
||||
|
||||
/** This functions acts more or less like the select(2) syscall.\n
|
||||
/**
|
||||
* @brief A wrapper for the select syscall
|
||||
*
|
||||
* This functions acts more or less like the select(2) syscall.\n
|
||||
* There is no support for writing or exceptions.\n
|
||||
* \brief wrapper for the select syscall
|
||||
* \param channels arrays of channels pointers finished by an NULL. It is never rewritten/
|
||||
* \param outchannels arrays of same size that "channels", it hasn't to be initialized
|
||||
* \param maxfd maximum +1 file descriptor from readfds
|
||||
* \param readfds an fd_set of file descriptors to be select'ed for reading
|
||||
* \param timeout a timeout for the select
|
||||
* \see select(2)
|
||||
* \return -1 if an error occured. E_INTR if it was interrupted. In that case, just restart it.
|
||||
* \warning libssh is not threadsafe. That means that if a signal is caught during the processing
|
||||
* of this function, you cannot call ssh functions on sessions that are busy with ssh_select()
|
||||
*
|
||||
* @param channels Arrays of channels pointers terminated by a NULL.
|
||||
* It is never rewritten.
|
||||
*
|
||||
* @param outchannels Arrays of same size that "channels", there is no need
|
||||
* to initialize it.
|
||||
*
|
||||
* @param maxfd Maximum +1 file descriptor from readfds.
|
||||
*
|
||||
* @param readfds A fd_set of file descriptors to be select'ed for
|
||||
* reading.
|
||||
*
|
||||
* @param timeout A timeout for the select.
|
||||
*
|
||||
* @return -1 if an error occured. E_INTR if it was interrupted. In that case,
|
||||
* just restart it.
|
||||
*
|
||||
* @warning libssh is not threadsafe here. That means that if a signal is caught
|
||||
* during the processing of this function, you cannot call ssh functions on
|
||||
* sessions that are busy with ssh_select().
|
||||
*
|
||||
* @see select(2)
|
||||
*/
|
||||
int ssh_select(CHANNEL **channels,CHANNEL **outchannels, socket_t maxfd, fd_set *readfds, struct timeval *timeout){
|
||||
struct timeval zerotime;
|
||||
fd_set localset,localset2;
|
||||
int rep;
|
||||
int i,j;
|
||||
int set;
|
||||
int ssh_select(CHANNEL **channels, CHANNEL **outchannels, socket_t maxfd,
|
||||
fd_set *readfds, struct timeval *timeout) {
|
||||
struct timeval zerotime;
|
||||
fd_set localset, localset2;
|
||||
int rep;
|
||||
int set;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
zerotime.tv_sec=0;
|
||||
zerotime.tv_usec=0;
|
||||
/* first, poll the maxfd file descriptors from the user with a zero-second timeout. they have the bigger priority */
|
||||
if(maxfd>0){
|
||||
memcpy(&localset,readfds, sizeof(fd_set));
|
||||
rep=select(maxfd,&localset,NULL,NULL,&zerotime);
|
||||
// catch the eventual errors
|
||||
if(rep==-1)
|
||||
return -1;
|
||||
}
|
||||
j=0;
|
||||
// polls every channel.
|
||||
for(i=0;channels[i];i++){
|
||||
if(channels[i]->session->alive){
|
||||
if(channel_poll(channels[i],0)>0){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
} else
|
||||
if(channel_poll(channels[i],1)>0){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
outchannels[j]=NULL;
|
||||
/* look into the localset for active fd */
|
||||
set=0;
|
||||
for(i=0;(i<maxfd) && !set;i++)
|
||||
if(FD_ISSET(i,&localset))
|
||||
set=1;
|
||||
// j!=0 means a channel has data
|
||||
if( (j!=0) || (set!=0)){
|
||||
if(maxfd>0)
|
||||
memcpy(readfds,&localset,sizeof(fd_set));
|
||||
return 0;
|
||||
}
|
||||
/* at this point, not any channel had any data ready for reading, nor any fd had data for reading */
|
||||
memcpy(&localset,readfds,sizeof(fd_set));
|
||||
for(i=0;channels[i];i++){
|
||||
if(channels[i]->session->alive){
|
||||
ssh_socket_fd_set(channels[i]->session->socket,&localset,&maxfd);
|
||||
}
|
||||
}
|
||||
rep=select(maxfd,&localset,NULL,NULL,timeout);
|
||||
if(rep==-1 && errno==EINTR){
|
||||
return SSH_EINTR; /* interrupted by a signal */
|
||||
}
|
||||
if(rep==-1){
|
||||
/* was the error due to a libssh's Channel or from a closed descriptor from the user ? user closed descriptors have been
|
||||
caught in the first select and not closed since that moment. that case shouldn't occur at all */
|
||||
return -1;
|
||||
}
|
||||
/* set the data_to_read flag on each session */
|
||||
for(i=0;channels[i];i++)
|
||||
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
|
||||
ssh_socket_set_toread(channels[i]->session->socket);
|
||||
zerotime.tv_sec = 0;
|
||||
zerotime.tv_usec = 0;
|
||||
|
||||
/* now, test each channel */
|
||||
j=0;
|
||||
for(i=0;channels[i];i++){
|
||||
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
|
||||
if((channel_poll(channels[i],0)>0) || (channel_poll(channels[i],1)>0)){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
}
|
||||
/*
|
||||
* First, poll the maxfd file descriptors from the user with a zero-second
|
||||
* timeout. They have the bigger priority.
|
||||
*/
|
||||
if (maxfd > 0) {
|
||||
memcpy(&localset, readfds, sizeof(fd_set));
|
||||
rep = select(maxfd, &localset, NULL, NULL, &zerotime);
|
||||
/* catch the eventual errors */
|
||||
if (rep==-1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Poll every channel */
|
||||
j = 0;
|
||||
for (i = 0; channels[i]; i++) {
|
||||
if (channels[i]->session->alive) {
|
||||
if(channel_poll(channels[i], 0) > 0) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
} else {
|
||||
if(channel_poll(channels[i], 1) > 0) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
outchannels[j] = NULL;
|
||||
|
||||
/* Look into the localset for active fd */
|
||||
set = 0;
|
||||
for (i = 0; (i < maxfd) && !set; i++) {
|
||||
if (FD_ISSET(i, &localset)) {
|
||||
set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* j != 0 means a channel has data */
|
||||
if( (j != 0) || (set != 0)) {
|
||||
if(maxfd > 0) {
|
||||
memcpy(readfds, &localset, sizeof(fd_set));
|
||||
}
|
||||
outchannels[j]=NULL;
|
||||
FD_ZERO(&localset2);
|
||||
for(i=0;i<maxfd;i++)
|
||||
if(FD_ISSET(i,readfds) && FD_ISSET(i,&localset))
|
||||
FD_SET(i,&localset2);
|
||||
memcpy(readfds,&localset2,sizeof(fd_set));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, not any channel had any data ready for reading, nor any fd
|
||||
* had data for reading.
|
||||
*/
|
||||
memcpy(&localset, readfds, sizeof(fd_set));
|
||||
for (i = 0; channels[i]; i++) {
|
||||
if (channels[i]->session->alive) {
|
||||
ssh_socket_fd_set(channels[i]->session->socket, &localset, &maxfd);
|
||||
}
|
||||
}
|
||||
|
||||
rep = select(maxfd, &localset, NULL, NULL, timeout);
|
||||
if (rep == -1 && errno == EINTR) {
|
||||
/* Interrupted by a signal */
|
||||
return SSH_EINTR;
|
||||
}
|
||||
|
||||
if (rep == -1) {
|
||||
/*
|
||||
* Was the error due to a libssh's channel or from a closed descriptor from
|
||||
* the user? User closed descriptors have been caught in the first select
|
||||
* and not closed since that moment. That case shouldn't occur at all
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the data_to_read flag on each session */
|
||||
for (i = 0; channels[i]; i++) {
|
||||
if (channels[i]->session->alive &&
|
||||
ssh_socket_fd_isset(channels[i]->session->socket,&localset)) {
|
||||
ssh_socket_set_toread(channels[i]->session->socket);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, test each channel */
|
||||
j = 0;
|
||||
for (i = 0; channels[i]; i++) {
|
||||
if (channels[i]->session->alive &&
|
||||
ssh_socket_fd_isset(channels[i]->session->socket,&localset)) {
|
||||
if ((channel_poll(channels[i],0) > 0) ||
|
||||
(channel_poll(channels[i], 1) > 0)) {
|
||||
outchannels[j] = channels[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
outchannels[j] = NULL;
|
||||
|
||||
FD_ZERO(&localset2);
|
||||
for (i = 0; i < maxfd; i++) {
|
||||
if (FD_ISSET(i, readfds) && FD_ISSET(i, &localset)) {
|
||||
FD_SET(i, &localset2);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(readfds, &localset2, sizeof(fd_set));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
132
libssh/crc32.c
132
libssh/crc32.c
@@ -1,15 +1,15 @@
|
||||
/* simple CRC32 code */
|
||||
/*
|
||||
* Copyright 2005 Aris Adamantiadis
|
||||
* crc32.c - simple CRC32 code
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005 by Aris Adamantiadis
|
||||
*
|
||||
* 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
|
||||
@@ -18,71 +18,75 @@
|
||||
* 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. */
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
static u32 crc_table[] = {
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
|
||||
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
|
||||
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
|
||||
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
|
||||
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
|
||||
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
|
||||
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
|
||||
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
|
||||
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
|
||||
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
|
||||
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
|
||||
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
|
||||
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
|
||||
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
|
||||
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
|
||||
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
|
||||
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
|
||||
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
|
||||
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
|
||||
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
|
||||
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
|
||||
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
|
||||
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
|
||||
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
|
||||
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
|
||||
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
|
||||
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
|
||||
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
|
||||
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
|
||||
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
|
||||
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
|
||||
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
|
||||
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
|
||||
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
|
||||
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
|
||||
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
|
||||
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
|
||||
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
|
||||
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
|
||||
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
|
||||
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
|
||||
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
|
||||
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
|
||||
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
|
||||
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
|
||||
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
|
||||
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
|
||||
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
|
||||
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
|
||||
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
|
||||
0x2d02ef8dUL
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
|
||||
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
|
||||
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
|
||||
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
|
||||
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
|
||||
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
|
||||
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
|
||||
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
|
||||
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
|
||||
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
|
||||
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
|
||||
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
|
||||
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
|
||||
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
|
||||
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
|
||||
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
|
||||
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
|
||||
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
|
||||
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
|
||||
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
|
||||
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
|
||||
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
|
||||
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
|
||||
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
|
||||
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
|
||||
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
|
||||
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
|
||||
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
|
||||
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
|
||||
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
|
||||
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
|
||||
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
|
||||
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
|
||||
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
|
||||
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
|
||||
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
|
||||
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
|
||||
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
|
||||
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
|
||||
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
|
||||
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
|
||||
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
|
||||
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
|
||||
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
|
||||
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
|
||||
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
|
||||
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
|
||||
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
|
||||
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
|
||||
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
|
||||
0x2d02ef8dUL
|
||||
};
|
||||
|
||||
u32 ssh_crc32(char *buf, int len) {
|
||||
u32 ret=0;
|
||||
while(len>0){
|
||||
ret=crc_table[(ret ^ *buf) & 0xff] ^ (ret >> 8);
|
||||
--len;
|
||||
++buf;
|
||||
}
|
||||
return ret;
|
||||
u32 ssh_crc32(const char *buf, u32 len) {
|
||||
u32 ret = 0;
|
||||
while(len > 0) {
|
||||
ret = crc_table[(ret ^ *buf) & 0xff] ^ (ret >> 8);
|
||||
--len;
|
||||
++buf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
283
libssh/crypt.c
283
libssh/crypt.c
@@ -1,30 +1,35 @@
|
||||
/* crypt.c */
|
||||
/* it just contains the shit necessary to make blowfish-cbc work ... */
|
||||
/*
|
||||
Copyright 2003 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* crypt.c - blowfish-cbc code
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_CRYPTO
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/evp.h>
|
||||
@@ -35,86 +40,168 @@ MA 02111-1307, USA. */
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
u32 packet_decrypt_len(SSH_SESSION *session, char *crypted){
|
||||
u32 decrypted;
|
||||
if(session->current_crypto)
|
||||
packet_decrypt(session,crypted,session->current_crypto->in_cipher->blocksize);
|
||||
memcpy(&decrypted,crypted,sizeof(decrypted));
|
||||
ssh_log(session,SSH_LOG_PACKET,"packet size decrypted : %d (0x%lx)",ntohl(decrypted),ntohl(decrypted));
|
||||
return ntohl(decrypted);
|
||||
}
|
||||
|
||||
int packet_decrypt(SSH_SESSION *session, void *data,u32 len){
|
||||
struct crypto_struct *crypto=session->current_crypto->in_cipher;
|
||||
char *out=malloc(len);
|
||||
ssh_log(session,SSH_LOG_PACKET,"Decrypting %d bytes",len);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
crypto->set_decrypt_key(crypto,session->current_crypto->decryptkey,session->current_crypto->decryptIV);
|
||||
crypto->cbc_decrypt(crypto,data,out,len);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
crypto->set_decrypt_key(crypto,session->current_crypto->decryptkey);
|
||||
crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
|
||||
#endif
|
||||
memcpy(data,out,len);
|
||||
memset(out,0,len);
|
||||
free(out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){
|
||||
struct crypto_struct *crypto;
|
||||
HMACCTX ctx;
|
||||
char *out;
|
||||
unsigned int finallen;
|
||||
u32 seq=ntohl(session->send_seq);
|
||||
if(!session->current_crypto)
|
||||
return NULL; /* nothing to do here */
|
||||
crypto= session->current_crypto->out_cipher;
|
||||
ssh_log(session,SSH_LOG_PACKET,"encrypting packet with seq num: %d, len: %d",session->send_seq,len);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey,session->current_crypto->encryptIV);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey);
|
||||
#endif
|
||||
out=malloc(len);
|
||||
if(session->version==2){
|
||||
ctx=hmac_init(session->current_crypto->encryptMAC,20,HMAC_SHA1);
|
||||
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));
|
||||
hmac_update(ctx,data,len);
|
||||
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("mac :",data,len);
|
||||
if(finallen!=20)
|
||||
printf("Final len is %d\n",finallen);
|
||||
ssh_print_hexa("packet hmac",session->current_crypto->hmacbuf,20);
|
||||
#endif
|
||||
u32 decrypted;
|
||||
|
||||
if (session->current_crypto) {
|
||||
if (packet_decrypt(session, crypted,
|
||||
session->current_crypto->in_cipher->blocksize) < 0) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
crypto->cbc_encrypt(crypto,data,out,len);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
crypto->cbc_encrypt(crypto,data,out,len,session->current_crypto->encryptIV);
|
||||
#endif
|
||||
memcpy(data,out,len);
|
||||
memset(out,0,len);
|
||||
free(out);
|
||||
if(session->version==2)
|
||||
return session->current_crypto->hmacbuf;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&decrypted,crypted,sizeof(decrypted));
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"Packet size decrypted: %lu (0x%lx)",
|
||||
(long unsigned int) ntohl(decrypted),
|
||||
(long unsigned int) ntohl(decrypted));
|
||||
return ntohl(decrypted);
|
||||
}
|
||||
|
||||
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,unsigned char *mac){
|
||||
HMACCTX ctx;
|
||||
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
|
||||
unsigned int len;
|
||||
u32 seq=htonl(session->recv_seq);
|
||||
ctx=hmac_init(session->current_crypto->decryptMAC,20,HMAC_SHA1);
|
||||
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));
|
||||
hmac_update(ctx,buffer_get(buffer),buffer_get_len(buffer));
|
||||
hmac_final(ctx,hmacbuf,&len);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("received mac",mac,len);
|
||||
ssh_print_hexa("Computed mac",hmacbuf,len);
|
||||
ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(u32));
|
||||
int packet_decrypt(SSH_SESSION *session, void *data,u32 len) {
|
||||
struct crypto_struct *crypto = session->current_crypto->in_cipher;
|
||||
char *out = NULL;
|
||||
|
||||
out = malloc(len);
|
||||
if (out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session,SSH_LOG_PACKET, "Decrypting %d bytes", len);
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey,
|
||||
session->current_crypto->decryptIV) < 0) {
|
||||
SAFE_FREE(out);
|
||||
return -1;
|
||||
}
|
||||
crypto->cbc_decrypt(crypto,data,out,len);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey) < 0) {
|
||||
SAFE_FREE(out);
|
||||
return -1;
|
||||
}
|
||||
crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
|
||||
#endif
|
||||
return memcmp(mac,hmacbuf,len);
|
||||
|
||||
memcpy(data,out,len);
|
||||
memset(out,0,len);
|
||||
|
||||
SAFE_FREE(out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *packet_encrypt(SSH_SESSION *session, void *data, u32 len) {
|
||||
struct crypto_struct *crypto = NULL;
|
||||
HMACCTX ctx = NULL;
|
||||
char *out = NULL;
|
||||
unsigned int finallen;
|
||||
u32 seq;
|
||||
|
||||
if (!session->current_crypto) {
|
||||
return NULL; /* nothing to do here */
|
||||
}
|
||||
|
||||
out = malloc(len);
|
||||
if (out == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seq = ntohl(session->send_seq);
|
||||
crypto = session->current_crypto->out_cipher;
|
||||
|
||||
ssh_log(session, SSH_LOG_PACKET,
|
||||
"Encrypting packet with seq num: %d, len: %d",
|
||||
session->send_seq,len);
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey,
|
||||
session->current_crypto->encryptIV) < 0) {
|
||||
SAFE_FREE(out);
|
||||
return NULL;
|
||||
}
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey) < 0) {
|
||||
SAFE_FREE(out);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (session->version == 2) {
|
||||
ctx = hmac_init(session->current_crypto->encryptMAC,20,HMAC_SHA1);
|
||||
if (ctx == NULL) {
|
||||
SAFE_FREE(out);
|
||||
return NULL;
|
||||
}
|
||||
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));
|
||||
hmac_update(ctx,data,len);
|
||||
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("mac: ",data,len);
|
||||
if (finallen != 20) {
|
||||
printf("Final len is %d\n",finallen);
|
||||
}
|
||||
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
crypto->cbc_encrypt(crypto, data, out, len);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
crypto->cbc_encrypt(crypto, data, out, len,
|
||||
session->current_crypto->encryptIV);
|
||||
#endif
|
||||
|
||||
memcpy(data, out, len);
|
||||
memset(out, 0, len);
|
||||
SAFE_FREE(out);
|
||||
|
||||
if (session->version == 2) {
|
||||
return session->current_crypto->hmacbuf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Verify the hmac of a packet
|
||||
*
|
||||
* @param session The session to use.
|
||||
* @param buffer The buffer to verify the hmac from.
|
||||
* @param mac The mac to compare with the hmac.
|
||||
*
|
||||
* @return 0 if hmac and mac are equal, < 0 if not or an error
|
||||
* occured.
|
||||
*/
|
||||
int packet_hmac_verify(SSH_SESSION *session, BUFFER *buffer,
|
||||
unsigned char *mac) {
|
||||
unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0};
|
||||
HMACCTX ctx;
|
||||
unsigned int len;
|
||||
u32 seq;
|
||||
|
||||
ctx = hmac_init(session->current_crypto->decryptMAC, 20, HMAC_SHA1);
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
seq = htonl(session->recv_seq);
|
||||
|
||||
hmac_update(ctx, (unsigned char *) &seq, sizeof(u32));
|
||||
hmac_update(ctx, buffer_get(buffer), buffer_get_len(buffer));
|
||||
hmac_final(ctx, hmacbuf, &len);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("received mac",mac,len);
|
||||
ssh_print_hexa("Computed mac",hmacbuf,len);
|
||||
ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(u32));
|
||||
#endif
|
||||
if (memcmp(mac, hmacbuf, len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
1299
libssh/dh.c
1299
libssh/dh.c
File diff suppressed because it is too large
Load Diff
134
libssh/error.c
134
libssh/error.c
@@ -1,79 +1,95 @@
|
||||
/*
|
||||
Copyright 2003-2008 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* error.c - functions for ssh error handling
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "libssh/priv.h"
|
||||
/** \defgroup ssh_error SSH Errors
|
||||
* \brief error handling
|
||||
|
||||
/**
|
||||
* @defgroup ssh_error SSH Errors
|
||||
*
|
||||
* @brief Functions for error handling.
|
||||
*/
|
||||
|
||||
/** \addtogroup ssh_error
|
||||
/**
|
||||
* @addtogroup ssh_error
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int verbosity;
|
||||
|
||||
/* ssh_set_error registers an error with a description. the error code is the class of error, and description is obvious.*/
|
||||
void ssh_set_error(void *error,int code,char *descr,...){
|
||||
struct error_struct *err= error;
|
||||
va_list va;
|
||||
va_start(va,descr);
|
||||
vsnprintf(err->error_buffer,ERROR_BUFFERLEN,descr,va);
|
||||
va_end(va);
|
||||
err->error_code=code;
|
||||
}
|
||||
|
||||
/** \brief retrieve an error text message
|
||||
* \param error the ssh session pointer
|
||||
* \return a static string describing the error
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Registers an error with a description.
|
||||
*
|
||||
* @param error The class of error.
|
||||
*
|
||||
* @param code The class of error.
|
||||
*
|
||||
* @param descr The description, which can be a format string.
|
||||
*
|
||||
* @param ... The arguments for the format string.
|
||||
*/
|
||||
char *ssh_get_error(void *error){
|
||||
struct error_struct *err=error;
|
||||
return err->error_buffer;
|
||||
void ssh_set_error(void *error, int code, const char *descr, ...) {
|
||||
struct error_struct *err = error;
|
||||
va_list va;
|
||||
va_start(va, descr);
|
||||
vsnprintf(err->error_buffer, ERROR_BUFFERLEN, descr, va);
|
||||
va_end(va);
|
||||
err->error_code = code;
|
||||
}
|
||||
|
||||
/** \brief retrieve the error code from the last
|
||||
* error
|
||||
* \param error the ssh session pointer
|
||||
* \return SSH_NO_ERROR no error occured\n
|
||||
* SSH_REQUEST_DENIED The last request was denied but situation
|
||||
* is recoverable\n
|
||||
* SSH_FATAL A fatal error occured. this could be an unexpected disconnection\n
|
||||
* Other error codes are internal but can be considered same than SSH_FATAL
|
||||
/**
|
||||
* @brief Retrieve the error text message from the last error.
|
||||
*
|
||||
* @param error The SSH session pointer.
|
||||
*
|
||||
* @return A static string describing the error.
|
||||
*/
|
||||
int ssh_get_error_code(void *error){
|
||||
struct error_struct *err=error;
|
||||
return err->error_code;
|
||||
const char *ssh_get_error(void *error) {
|
||||
struct error_struct *err = error;
|
||||
|
||||
return err->error_buffer;
|
||||
}
|
||||
|
||||
void ssh_say(int priority, const char *format, ...){
|
||||
va_list va;
|
||||
va_start(va,format);
|
||||
if(priority <= verbosity)
|
||||
vfprintf(stderr,format,va);
|
||||
va_end(va);
|
||||
}
|
||||
/**
|
||||
* @brief Retrieve the error code from the last error.
|
||||
*
|
||||
* @param error The SSH session pointer.
|
||||
*
|
||||
* \return SSH_NO_ERROR No error occured\n
|
||||
* SSH_REQUEST_DENIED The last request was denied but situation is
|
||||
* recoverable\n
|
||||
* SSH_FATAL A fatal error occured. This could be an unexpected
|
||||
* disconnection\n
|
||||
*
|
||||
* \nOther error codes are internal but can be considered same than
|
||||
* SSH_FATAL.
|
||||
*/
|
||||
int ssh_get_error_code(void *error) {
|
||||
struct error_struct *err = error;
|
||||
|
||||
void ssh_set_verbosity(int num){
|
||||
verbosity=num;
|
||||
return err->error_code;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1,76 +1,99 @@
|
||||
/* gcrypt_missing.c */
|
||||
/* This file contains routines that are in OpenSSL but not in libgcrypt */
|
||||
|
||||
/*
|
||||
Copyright 2003,04,06 Aris Adamantiadis
|
||||
* gcrypt_missing.c - routines that are in OpenSSL but not in libgcrypt.
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2006 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
The SSH Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The SSH Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the SSH Library; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
#include <stdlib.h>
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
int my_gcry_dec2bn(bignum *bn, const char *data)
|
||||
{
|
||||
int my_gcry_dec2bn(bignum *bn, const char *data) {
|
||||
int count;
|
||||
|
||||
|
||||
*bn = bignum_new();
|
||||
if (*bn == NULL) {
|
||||
return 0;
|
||||
}
|
||||
gcry_mpi_set_ui(*bn, 0);
|
||||
for (count = 0; data[count]; ++count)
|
||||
{
|
||||
for (count = 0; data[count]; count++) {
|
||||
gcry_mpi_mul_ui(*bn, *bn, 10);
|
||||
gcry_mpi_add_ui(*bn, *bn, data[count] - '0');
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
char *my_gcry_bn2dec(bignum bn)
|
||||
{
|
||||
char *my_gcry_bn2dec(bignum bn) {
|
||||
bignum bndup, num, ten;
|
||||
char *ret;
|
||||
int count, count2;
|
||||
int size, rsize;
|
||||
char *ret;
|
||||
bignum bndup, num, ten;
|
||||
char decnum;
|
||||
|
||||
|
||||
size = gcry_mpi_get_nbits(bn) * 3;
|
||||
rsize = size / 10 + size / 1000 + 2;
|
||||
|
||||
ret = malloc(rsize + 1);
|
||||
if (!gcry_mpi_cmp_ui(bn, 0))
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gcry_mpi_cmp_ui(bn, 0)) {
|
||||
strcpy(ret, "0");
|
||||
else
|
||||
{
|
||||
for (bndup = gcry_mpi_copy(bn), ten = bignum_new(), num = bignum_new(),
|
||||
bignum_set_word(ten, 10), count = rsize; count; --count)
|
||||
{
|
||||
} else {
|
||||
ten = bignum_new();
|
||||
if (ten == NULL) {
|
||||
SAFE_FREE(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
num = bignum_new();
|
||||
if (num == NULL) {
|
||||
SAFE_FREE(ret);
|
||||
bignum_free(ten);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (bndup = gcry_mpi_copy(bn), bignum_set_word(ten, 10), count = rsize;
|
||||
count; count--) {
|
||||
gcry_mpi_div(bndup, num, bndup, ten, 0);
|
||||
for (decnum = 0, count2 = gcry_mpi_get_nbits(num); count2; decnum *= 2,
|
||||
decnum += (gcry_mpi_test_bit(num, count2 - 1) ? 1 : 0), --count2)
|
||||
;
|
||||
for (decnum = 0, count2 = gcry_mpi_get_nbits(num); count2;
|
||||
decnum *= 2, decnum += (gcry_mpi_test_bit(num, count2 - 1) ? 1 : 0),
|
||||
count2--)
|
||||
;
|
||||
ret[count - 1] = decnum + '0';
|
||||
}
|
||||
for (count = 0; count < rsize && ret[count] == '0'; ++count)
|
||||
for (count = 0; count < rsize && ret[count] == '0'; count++)
|
||||
;
|
||||
for (count2 = 0; count2 < rsize - count; ++count2)
|
||||
for (count2 = 0; count2 < rsize - count; ++count2) {
|
||||
ret[count2] = ret[count2 + count];
|
||||
}
|
||||
ret[count2] = 0;
|
||||
bignum_free(num);
|
||||
bignum_free(bndup);
|
||||
bignum_free(ten);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
301
libssh/gzip.c
301
libssh/gzip.c
@@ -1,141 +1,216 @@
|
||||
/* gzip.c */
|
||||
/* include hooks for compression of packets */
|
||||
/*
|
||||
Copyright 2003 Aris Adamantiadis
|
||||
* gzip.c - hooks for compression of packets
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.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.
|
||||
*/
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
The SSH Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The SSH Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the SSH Library; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
#include "config.h"
|
||||
#include "libssh/priv.h"
|
||||
#ifdef HAVE_LIBZ
|
||||
#undef NO_GZIP
|
||||
#else
|
||||
#define NO_GZIP
|
||||
#endif
|
||||
|
||||
#ifndef NO_GZIP
|
||||
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
|
||||
|
||||
#include <zlib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BLOCKSIZE 4092
|
||||
|
||||
static z_stream *initcompress(SSH_SESSION *session,int level){
|
||||
z_stream *stream=malloc(sizeof(z_stream));
|
||||
int status;
|
||||
memset(stream,0,sizeof(z_stream));
|
||||
status=deflateInit(stream,level);
|
||||
if (status!=0)
|
||||
ssh_set_error(session,SSH_FATAL,"status %d inititalising zlib deflate",status);
|
||||
return stream;
|
||||
static z_stream *initcompress(SSH_SESSION *session, int level) {
|
||||
z_stream *stream = NULL;
|
||||
int status;
|
||||
|
||||
stream = malloc(sizeof(z_stream));
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(stream, 0, sizeof(z_stream));
|
||||
|
||||
status = deflateInit(stream, level);
|
||||
if (status != Z_OK) {
|
||||
SAFE_FREE(stream);
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"status %d inititalising zlib deflate", status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
BUFFER *gzip_compress(SSH_SESSION *session,BUFFER *source,int level){
|
||||
BUFFER *dest;
|
||||
static unsigned char out_buf[BLOCKSIZE];
|
||||
void *in_ptr=buffer_get(source);
|
||||
unsigned long in_size=buffer_get_len(source);
|
||||
unsigned long len;
|
||||
int status;
|
||||
z_stream *zout=session->current_crypto->compress_out_ctx;
|
||||
if(!zout)
|
||||
zout=session->current_crypto->compress_out_ctx=initcompress(session,level);
|
||||
dest=buffer_new();
|
||||
zout->next_out=out_buf;
|
||||
zout->next_in=in_ptr;
|
||||
zout->avail_in=in_size;
|
||||
do {
|
||||
zout->avail_out=BLOCKSIZE;
|
||||
status=deflate(zout,Z_PARTIAL_FLUSH);
|
||||
if(status !=0){
|
||||
ssh_set_error(session,SSH_FATAL,"status %d deflating zlib packet",status);
|
||||
return NULL;
|
||||
}
|
||||
len=BLOCKSIZE-zout->avail_out;
|
||||
buffer_add_data(dest,out_buf,len);
|
||||
zout->next_out=out_buf;
|
||||
} while (zout->avail_out == 0);
|
||||
static BUFFER *gzip_compress(SSH_SESSION *session,BUFFER *source,int level){
|
||||
z_stream *zout = session->current_crypto->compress_out_ctx;
|
||||
void *in_ptr = buffer_get(source);
|
||||
unsigned long in_size = buffer_get_len(source);
|
||||
BUFFER *dest = NULL;
|
||||
static unsigned char out_buf[BLOCKSIZE] = {0};
|
||||
unsigned long len;
|
||||
int status;
|
||||
|
||||
return dest;
|
||||
if(zout == NULL) {
|
||||
zout = session->current_crypto->compress_out_ctx = initcompress(session, level);
|
||||
if (zout == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dest = buffer_new();
|
||||
if (dest == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zout->next_out = out_buf;
|
||||
zout->next_in = in_ptr;
|
||||
zout->avail_in = in_size;
|
||||
do {
|
||||
zout->avail_out = BLOCKSIZE;
|
||||
status = deflate(zout, Z_PARTIAL_FLUSH);
|
||||
if (status != Z_OK) {
|
||||
buffer_free(dest);
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"status %d deflating zlib packet", status);
|
||||
return NULL;
|
||||
}
|
||||
len = BLOCKSIZE - zout->avail_out;
|
||||
if (buffer_add_data(dest, out_buf, len) < 0) {
|
||||
buffer_free(dest);
|
||||
return NULL;
|
||||
}
|
||||
zout->next_out = out_buf;
|
||||
} while (zout->avail_out == 0);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int compress_buffer(SSH_SESSION *session,BUFFER *buf){
|
||||
BUFFER *dest=gzip_compress(session,buf,9);
|
||||
if(!dest)
|
||||
return -1;
|
||||
buffer_reinit(buf);
|
||||
buffer_add_data(buf,buffer_get(dest),buffer_get_len(dest));
|
||||
int compress_buffer(SSH_SESSION *session, BUFFER *buf) {
|
||||
BUFFER *dest = NULL;
|
||||
|
||||
dest = gzip_compress(session, buf, 9);
|
||||
if (dest == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_reinit(buf) < 0) {
|
||||
buffer_free(dest);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
|
||||
buffer_free(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_free(dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decompression */
|
||||
|
||||
static z_stream *initdecompress(SSH_SESSION *session){
|
||||
z_stream *stream=malloc(sizeof(z_stream));
|
||||
int status;
|
||||
memset(stream,0,sizeof(z_stream));
|
||||
status=inflateInit(stream);
|
||||
if (status!=0){
|
||||
ssh_set_error(session,SSH_FATAL,"Status = %d initiating inflate context !",status);
|
||||
free(stream);
|
||||
stream=NULL;
|
||||
}
|
||||
return stream;
|
||||
static z_stream *initdecompress(SSH_SESSION *session) {
|
||||
z_stream *stream = NULL;
|
||||
int status;
|
||||
|
||||
stream = malloc(sizeof(z_stream));
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(stream,0,sizeof(z_stream));
|
||||
|
||||
status = inflateInit(stream);
|
||||
if (status != Z_OK) {
|
||||
SAFE_FREE(stream);
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Status = %d initiating inflate context!", status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
BUFFER *gzip_decompress(SSH_SESSION *session,BUFFER *source){
|
||||
BUFFER *dest;
|
||||
static unsigned char out_buf[BLOCKSIZE];
|
||||
void *in_ptr=buffer_get_rest(source);
|
||||
unsigned long in_size=buffer_get_rest_len(source);
|
||||
unsigned long len;
|
||||
int status;
|
||||
z_stream *zin=session->current_crypto->compress_in_ctx;
|
||||
if(!zin)
|
||||
zin=session->current_crypto->compress_in_ctx=initdecompress(session);
|
||||
dest=buffer_new();
|
||||
zin->next_out=out_buf;
|
||||
zin->next_in=in_ptr;
|
||||
zin->avail_in=in_size;
|
||||
do {
|
||||
zin->avail_out=BLOCKSIZE;
|
||||
status=inflate(zin,Z_PARTIAL_FLUSH);
|
||||
if(status !=Z_OK){
|
||||
ssh_set_error(session,SSH_FATAL,"status %d inflating zlib packet",status);
|
||||
buffer_free(dest);
|
||||
return NULL;
|
||||
}
|
||||
len=BLOCKSIZE-zin->avail_out;
|
||||
buffer_add_data(dest,out_buf,len);
|
||||
zin->next_out=out_buf;
|
||||
} while (zin->avail_out == 0);
|
||||
static BUFFER *gzip_decompress(SSH_SESSION *session, BUFFER *source) {
|
||||
z_stream *zin = session->current_crypto->compress_in_ctx;
|
||||
void *in_ptr = buffer_get_rest(source);
|
||||
unsigned long in_size = buffer_get_rest_len(source);
|
||||
static unsigned char out_buf[BLOCKSIZE] = {0};
|
||||
BUFFER *dest = NULL;
|
||||
unsigned long len;
|
||||
int status;
|
||||
|
||||
return dest;
|
||||
if (zin == NULL) {
|
||||
zin = session->current_crypto->compress_in_ctx = initdecompress(session);
|
||||
if (zin == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dest = buffer_new();
|
||||
if (dest == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zin->next_out = out_buf;
|
||||
zin->next_in = in_ptr;
|
||||
zin->avail_in = in_size;
|
||||
|
||||
do {
|
||||
zin->avail_out = BLOCKSIZE;
|
||||
status = inflate(zin, Z_PARTIAL_FLUSH);
|
||||
if (status != Z_OK) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"status %d inflating zlib packet", status);
|
||||
buffer_free(dest);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = BLOCKSIZE - zin->avail_out;
|
||||
if (buffer_add_data(dest,out_buf,len) < 0) {
|
||||
buffer_free(dest);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zin->next_out = out_buf;
|
||||
} while (zin->avail_out == 0);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int decompress_buffer(SSH_SESSION *session,BUFFER *buf){
|
||||
BUFFER *dest=gzip_decompress(session,buf);
|
||||
buffer_reinit(buf);
|
||||
if(!dest){
|
||||
return -1; /* failed */
|
||||
}
|
||||
buffer_reinit(buf);
|
||||
buffer_add_data(buf,buffer_get(dest),buffer_get_len(dest));
|
||||
BUFFER *dest = NULL;
|
||||
|
||||
dest = gzip_decompress(session,buf);
|
||||
if (dest == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_reinit(buf) < 0) {
|
||||
buffer_free(dest);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_data(buf, buffer_get(dest), buffer_get_len(dest)) < 0) {
|
||||
buffer_free(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_free(dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NO_GZIP */
|
||||
#endif /* HAVE_LIBZ && WITH_LIBZ */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1,40 +1,61 @@
|
||||
/* init.c */
|
||||
/* This file handles initialization and finalization of the library */
|
||||
|
||||
/*
|
||||
Copyright 2003,04,06 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* init.c - initialization and finalization of the library
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2006 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup ssh_session
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief finalize and cleanup all libssh and cryptographic data structures
|
||||
* \returns 0
|
||||
* @brief initialize global cryptographic data structures.
|
||||
*
|
||||
* This function should only be called once, at the begining of the program, in the main thread. It may be omitted if your program is not multithreaded.
|
||||
*
|
||||
* @returns 0
|
||||
*/
|
||||
int ssh_finalize()
|
||||
{
|
||||
int ssh_init(void) {
|
||||
if(ssh_crypto_init())
|
||||
return -1;
|
||||
if(ssh_socket_init())
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Finalize and cleanup all libssh and cryptographic data structures.
|
||||
*
|
||||
* This function should only be called once, at the end of the program!
|
||||
*
|
||||
* @returns -1 in case of error
|
||||
@returns 0 otherwise
|
||||
*/
|
||||
int ssh_finalize(void) {
|
||||
ssh_crypto_finalize();
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_control(GCRYCTL_TERM_SECMEM);
|
||||
@@ -50,3 +71,4 @@ int ssh_finalize()
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
815
libssh/kex.c
815
libssh/kex.c
@@ -1,27 +1,35 @@
|
||||
/* kex.c is used well, in key exchange :-) */
|
||||
/*
|
||||
Copyright (c) 2003-2008 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* kex.c - key exchange
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/ssh1.h"
|
||||
@@ -44,31 +52,68 @@ MA 02111-1307, USA. */
|
||||
#define DES "3des-cbc"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
|
||||
#define ZLIB "none,zlib"
|
||||
#else
|
||||
#define ZLIB "none"
|
||||
#endif
|
||||
|
||||
char *default_methods[]={
|
||||
"diffie-hellman-group1-sha1","ssh-dss,ssh-rsa",AES BLOWFISH DES,AES BLOWFISH
|
||||
DES, "hmac-sha1","hmac-sha1","none","none","","",NULL };
|
||||
char *supported_methods[]={
|
||||
"diffie-hellman-group1-sha1","ssh-dss,ssh-rsa",AES BLOWFISH DES,AES BLOWFISH
|
||||
DES, "hmac-sha1","hmac-sha1",ZLIB,ZLIB,"","",NULL };
|
||||
const char *default_methods[] = {
|
||||
"diffie-hellman-group1-sha1",
|
||||
"ssh-dss,ssh-rsa",
|
||||
AES BLOWFISH DES,
|
||||
AES BLOWFISH DES,
|
||||
"hmac-sha1",
|
||||
"hmac-sha1",
|
||||
"none",
|
||||
"none",
|
||||
"",
|
||||
"",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *supported_methods[] = {
|
||||
"diffie-hellman-group1-sha1",
|
||||
"ssh-dss,ssh-rsa",
|
||||
AES BLOWFISH DES,
|
||||
AES BLOWFISH DES,
|
||||
"hmac-sha1",
|
||||
"hmac-sha1",
|
||||
ZLIB,
|
||||
ZLIB,
|
||||
"",
|
||||
"",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* descriptions of the key exchange packet */
|
||||
char *ssh_kex_nums[]={
|
||||
"kex algos","server host key algo","encryption client->server","encryption server->client",
|
||||
"mac algo client->server","mac algo server->client","compression algo client->server",
|
||||
"compression algo server->client","languages client->server","languages server->client",NULL};
|
||||
const char *ssh_kex_nums[] = {
|
||||
"kex algos",
|
||||
"server host key algo",
|
||||
"encryption client->server",
|
||||
"encryption server->client",
|
||||
"mac algo client->server",
|
||||
"mac algo server->client",
|
||||
"compression algo client->server",
|
||||
"compression algo server->client",
|
||||
"languages client->server",
|
||||
"languages server->client",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* tokenize will return a token of strings delimited by ",". the first element has to be freed */
|
||||
static char **tokenize(const char *chain){
|
||||
char **tokens;
|
||||
int n=1;
|
||||
int i=0;
|
||||
char *tmp = strdup(chain);
|
||||
char *ptr = tmp;
|
||||
char *tmp;
|
||||
char *ptr;
|
||||
|
||||
tmp = strdup(chain);
|
||||
if (tmp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = tmp;
|
||||
while(*ptr){
|
||||
if(*ptr==','){
|
||||
n++;
|
||||
@@ -78,6 +123,10 @@ static char **tokenize(const char *chain){
|
||||
}
|
||||
/* now n contains the number of tokens, the first possibly empty if the list was empty too e.g. "" */
|
||||
tokens=malloc(sizeof(char *) * (n+1) ); /* +1 for the null */
|
||||
if (tokens == NULL) {
|
||||
SAFE_FREE(tmp);
|
||||
return NULL;
|
||||
}
|
||||
ptr=tmp;
|
||||
for(i=0;i<n;i++){
|
||||
tokens[i]=ptr;
|
||||
@@ -90,12 +139,20 @@ static char **tokenize(const char *chain){
|
||||
}
|
||||
|
||||
/* same as tokenize(), but with spaces instead of ',' */
|
||||
/* TODO FIXME rewrite me! */
|
||||
char **space_tokenize(const char *chain){
|
||||
char **tokens;
|
||||
int n=1;
|
||||
int i=0;
|
||||
char *tmp = strdup(chain);
|
||||
char *ptr = tmp;
|
||||
char *tmp;
|
||||
char *ptr;
|
||||
|
||||
tmp = strdup(chain);
|
||||
if (tmp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = tmp;
|
||||
|
||||
while(*ptr==' ')
|
||||
++ptr; /* skip initial spaces */
|
||||
while(*ptr){
|
||||
@@ -109,7 +166,11 @@ char **space_tokenize(const char *chain){
|
||||
ptr++;
|
||||
}
|
||||
/* now n contains the number of tokens, the first possibly empty if the list was empty too e.g. "" */
|
||||
tokens=malloc(sizeof(char *) * (n+1) ); /* +1 for the null */
|
||||
tokens = malloc(sizeof(char *) * (n + 1)); /* +1 for the null */
|
||||
if (tokens == NULL) {
|
||||
SAFE_FREE(tmp);
|
||||
return NULL;
|
||||
}
|
||||
ptr=tmp; /* we don't pass the initial spaces because the "tmp" pointer is needed by the caller */
|
||||
/* function to free the tokens. */
|
||||
for(i=0;i<n;i++){
|
||||
@@ -134,17 +195,26 @@ char *ssh_find_matching(const char *in_d, const char *what_d){
|
||||
char ** tok_in, **tok_what;
|
||||
int i_in, i_what;
|
||||
char *ret;
|
||||
|
||||
if( ! (in_d && what_d))
|
||||
return NULL; /* don't deal with null args */
|
||||
ssh_say(3,"find_matching(\"%s\",\"%s\") = ",in_d,what_d);
|
||||
tok_in=tokenize(in_d);
|
||||
tok_what=tokenize(what_d);
|
||||
|
||||
if ((in_d == NULL) || (what_d == NULL)) {
|
||||
return NULL; /* don't deal with null args */
|
||||
}
|
||||
|
||||
tok_in = tokenize(in_d);
|
||||
if (tok_in == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tok_what = tokenize(what_d);
|
||||
if (tok_what == NULL) {
|
||||
SAFE_FREE(tok_in[0]);
|
||||
SAFE_FREE(tok_in);
|
||||
}
|
||||
|
||||
for(i_in=0; tok_in[i_in]; ++i_in){
|
||||
for(i_what=0; tok_what[i_what] ; ++i_what){
|
||||
if(!strcmp(tok_in[i_in],tok_what[i_what])){
|
||||
/* match */
|
||||
ssh_say(3,"\"%s\"\n",tok_in[i_in]);
|
||||
ret=strdup(tok_in[i_in]);
|
||||
/* free the tokens */
|
||||
free(tok_in[0]);
|
||||
@@ -155,7 +225,6 @@ char *ssh_find_matching(const char *in_d, const char *what_d){
|
||||
}
|
||||
}
|
||||
}
|
||||
ssh_say(3,"NULL\n");
|
||||
free(tok_in[0]);
|
||||
free(tok_what[0]);
|
||||
free(tok_in);
|
||||
@@ -163,55 +232,96 @@ char *ssh_find_matching(const char *in_d, const char *what_d){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ssh_get_kex(SSH_SESSION *session,int server_kex ){
|
||||
STRING *str;
|
||||
char *strings[10];
|
||||
int i;
|
||||
enter_function();
|
||||
if(packet_wait(session,SSH2_MSG_KEXINIT,1)){
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,16)!=16){
|
||||
ssh_set_error(session,SSH_FATAL,"get_kex(): no cookie in packet");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
hashbufin_add_cookie(session,session->server_kex.cookie);
|
||||
memset(strings,0,sizeof(char *)*10);
|
||||
for(i=0;i<10;++i){
|
||||
str=buffer_get_ssh_string(session->in_buffer);
|
||||
if(!str)
|
||||
break;
|
||||
if(str){
|
||||
buffer_add_ssh_string(session->in_hashbuf,str);
|
||||
strings[i]=string_to_char(str);
|
||||
free(str);
|
||||
} else
|
||||
strings[i]=NULL;
|
||||
}
|
||||
/* copy the server kex info into an array of strings */
|
||||
if(server_kex){
|
||||
session->client_kex.methods=malloc( 10 * sizeof(char **));
|
||||
for(i=0;i<10;++i)
|
||||
session->client_kex.methods[i]=strings[i];
|
||||
} else { // client
|
||||
session->server_kex.methods=malloc( 10 * sizeof(char **));
|
||||
for(i=0;i<10;++i)
|
||||
session->server_kex.methods[i]=strings[i];
|
||||
}
|
||||
int ssh_get_kex(SSH_SESSION *session, int server_kex) {
|
||||
STRING *str = NULL;
|
||||
char *strings[10];
|
||||
int i;
|
||||
|
||||
enter_function();
|
||||
|
||||
if (packet_wait(session, SSH2_MSG_KEXINIT, 1) != SSH_OK) {
|
||||
leave_function();
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_get_data(session->in_buffer,session->server_kex.cookie,16) != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "get_kex(): no cookie in packet");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hashbufin_add_cookie(session, session->server_kex.cookie) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "get_kex(): adding cookie failed");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(strings, 0, sizeof(char *) * 10);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
str = buffer_get_ssh_string(session->in_buffer);
|
||||
if (str == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
strings[i] = string_to_char(str);
|
||||
if (strings[i] == NULL) {
|
||||
goto error;
|
||||
}
|
||||
string_free(str);
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
/* copy the server kex info into an array of strings */
|
||||
if (server_kex) {
|
||||
session->client_kex.methods = malloc(10 * sizeof(char **));
|
||||
if (session->client_kex.methods == NULL) {
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
session->client_kex.methods[i] = strings[i];
|
||||
}
|
||||
} else { /* client */
|
||||
session->server_kex.methods = malloc(10 * sizeof(char **));
|
||||
if (session->server_kex.methods == NULL) {
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
session->server_kex.methods[i] = strings[i];
|
||||
}
|
||||
}
|
||||
|
||||
leave_function();
|
||||
return 0;
|
||||
error:
|
||||
string_free(str);
|
||||
for (i = 0; i < 10; i++) {
|
||||
SAFE_FREE(strings[i]);
|
||||
}
|
||||
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ssh_list_kex(KEX *kex){
|
||||
int i=0;
|
||||
void ssh_list_kex(struct ssh_session *session, KEX *kex) {
|
||||
int i = 0;
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("session cookie",kex->cookie,16);
|
||||
ssh_print_hexa("session cookie", kex->cookie, 16);
|
||||
#endif
|
||||
for(i=0;i<10;i++){
|
||||
ssh_say(2,"%s : %s\n",ssh_kex_nums[i],kex->methods[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "%s: %s",
|
||||
ssh_kex_nums[i], kex->methods[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* set_kex basicaly look at the option structure of the session and set the output kex message */
|
||||
@@ -223,7 +333,7 @@ int set_kex(SSH_SESSION *session){
|
||||
KEX *client=&session->client_kex;
|
||||
SSH_OPTIONS *options=session->options;
|
||||
int i;
|
||||
char *wanted;
|
||||
const char *wanted;
|
||||
enter_function();
|
||||
/* the client might ask for a specific cookie to be sent. useful for server debugging */
|
||||
if(options->wanted_cookie)
|
||||
@@ -231,6 +341,11 @@ int set_kex(SSH_SESSION *session){
|
||||
else
|
||||
ssh_get_random(client->cookie,16,0);
|
||||
client->methods=malloc(10 * sizeof(char **));
|
||||
if (client->methods == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "No space left");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
memset(client->methods,0,10*sizeof(char **));
|
||||
for (i=0;i<10;i++){
|
||||
if(!(wanted=options->wanted_methods[i]))
|
||||
@@ -242,35 +357,76 @@ int set_kex(SSH_SESSION *session){
|
||||
leave_function();
|
||||
return -1;
|
||||
} else {
|
||||
if(i>=SSH_LANG_C_S && !client->methods[i])
|
||||
client->methods[i]=strdup(""); // we can safely do that for languages
|
||||
if ((i >= SSH_LANG_C_S) && (client->methods[i] == NULL)) {
|
||||
/* we can safely do that for languages */
|
||||
client->methods[i] = strdup("");
|
||||
if (client->methods[i] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
leave_function();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this function only sends the predefined set of kex methods */
|
||||
void ssh_send_kex(SSH_SESSION *session, int server_kex){
|
||||
STRING *str;
|
||||
int i=0;
|
||||
KEX *kex=(server_kex ? &session->server_kex : &session->client_kex);
|
||||
enter_function();
|
||||
buffer_add_u8(session->out_buffer,SSH2_MSG_KEXINIT);
|
||||
buffer_add_data(session->out_buffer,kex->cookie,16);
|
||||
hashbufout_add_cookie(session);
|
||||
ssh_list_kex(kex);
|
||||
for(i=0;i<10;i++){
|
||||
str=string_from_char(kex->methods[i]);
|
||||
buffer_add_ssh_string(session->out_hashbuf,str);
|
||||
buffer_add_ssh_string(session->out_buffer,str);
|
||||
free(str);
|
||||
/* this function only sends the predefined set of kex methods */
|
||||
int ssh_send_kex(SSH_SESSION *session, int server_kex) {
|
||||
KEX *kex = (server_kex ? &session->server_kex : &session->client_kex);
|
||||
STRING *str = NULL;
|
||||
int i;
|
||||
|
||||
enter_function();
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (hashbufout_add_cookie(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_list_kex(session, kex);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
str = string_from_char(kex->methods[i]);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
i=0;
|
||||
buffer_add_u8(session->out_buffer,0);
|
||||
buffer_add_u32(session->out_buffer,0);
|
||||
packet_send(session);
|
||||
|
||||
if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_ssh_string(session->out_buffer, str) < 0) {
|
||||
goto error;
|
||||
}
|
||||
string_free(str);
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
leave_function();
|
||||
return 0;
|
||||
error:
|
||||
buffer_free(session->out_buffer);
|
||||
buffer_free(session->out_hashbuf);
|
||||
string_free(str);
|
||||
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns 1 if at least one of the name algos is in the default algorithms table */
|
||||
@@ -289,33 +445,58 @@ int verify_existing_algo(int algo, const char *name){
|
||||
/* makes a STRING contating 3 strings : ssh-rsa1,e and n */
|
||||
/* this is a public key in openssh's format */
|
||||
static STRING *make_rsa1_string(STRING *e, STRING *n){
|
||||
BUFFER *buffer=buffer_new();
|
||||
STRING *rsa=string_from_char("ssh-rsa1");
|
||||
STRING *ret;
|
||||
buffer_add_ssh_string(buffer,rsa);
|
||||
free(rsa);
|
||||
buffer_add_ssh_string(buffer,e);
|
||||
buffer_add_ssh_string(buffer,n);
|
||||
ret=string_new(buffer_get_len(buffer));
|
||||
string_fill(ret,buffer_get(buffer),buffer_get_len(buffer));
|
||||
buffer_free(buffer);
|
||||
return ret;
|
||||
BUFFER *buffer = NULL;
|
||||
STRING *rsa = NULL;
|
||||
STRING *ret = NULL;
|
||||
|
||||
buffer = buffer_new();
|
||||
rsa = string_from_char("ssh-rsa1");
|
||||
|
||||
if (buffer_add_ssh_string(buffer, rsa) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_ssh_string(buffer, e) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_ssh_string(buffer, n) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = string_new(buffer_get_len(buffer));
|
||||
if (ret == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
string_fill(ret, buffer_get(buffer), buffer_get_len(buffer));
|
||||
error:
|
||||
buffer_free(buffer);
|
||||
string_free(rsa);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void build_session_id1(SSH_SESSION *session, STRING *servern,
|
||||
STRING *hostn){
|
||||
MD5CTX md5=md5_init();
|
||||
static int build_session_id1(SSH_SESSION *session, STRING *servern,
|
||||
STRING *hostn) {
|
||||
MD5CTX md5 = NULL;
|
||||
|
||||
md5 = md5_init();
|
||||
if (md5 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("host modulus",hostn->string,string_len(hostn));
|
||||
ssh_print_hexa("server modulus",servern->string,string_len(servern));
|
||||
ssh_print_hexa("host modulus",hostn->string,string_len(hostn));
|
||||
ssh_print_hexa("server modulus",servern->string,string_len(servern));
|
||||
#endif
|
||||
md5_update(md5,hostn->string,string_len(hostn));
|
||||
md5_update(md5,servern->string,string_len(servern));
|
||||
md5_update(md5,session->server_kex.cookie,8);
|
||||
md5_final(session->next_crypto->session_id,md5);
|
||||
md5_update(md5,hostn->string,string_len(hostn));
|
||||
md5_update(md5,servern->string,string_len(servern));
|
||||
md5_update(md5,session->server_kex.cookie,8);
|
||||
md5_final(session->next_crypto->session_id,md5);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN);
|
||||
ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 1 if the modulus of k1 is < than the one of k2 */
|
||||
@@ -348,39 +529,65 @@ static int modulus_smaller(PUBLIC_KEY *k1, PUBLIC_KEY *k2){
|
||||
}
|
||||
|
||||
#define ABS(A) ( (A)<0 ? -(A):(A) )
|
||||
STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *svrkey,
|
||||
PUBLIC_KEY *hostkey,int slen, int hlen ){
|
||||
unsigned char buffer[32];
|
||||
int i;
|
||||
STRING *data1,*data2;
|
||||
/* first, generate a session key */
|
||||
|
||||
ssh_get_random(session->next_crypto->encryptkey,32,1);
|
||||
memcpy(buffer,session->next_crypto->encryptkey,32);
|
||||
memcpy(session->next_crypto->decryptkey,
|
||||
session->next_crypto->encryptkey,32);
|
||||
static STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *srvkey,
|
||||
PUBLIC_KEY *hostkey, int slen, int hlen) {
|
||||
unsigned char buffer[32] = {0};
|
||||
int i;
|
||||
STRING *data1 = NULL;
|
||||
STRING *data2 = NULL;
|
||||
|
||||
/* first, generate a session key */
|
||||
ssh_get_random(session->next_crypto->encryptkey, 32, 1);
|
||||
memcpy(buffer, session->next_crypto->encryptkey, 32);
|
||||
memcpy(session->next_crypto->decryptkey, session->next_crypto->encryptkey, 32);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("session key",buffer,32);
|
||||
ssh_print_hexa("session key",buffer,32);
|
||||
#endif
|
||||
/* xor session key with session_id */
|
||||
for (i=0;i<16;++i)
|
||||
buffer[i]^=session->next_crypto->session_id[i];
|
||||
data1=string_new(32);
|
||||
string_fill(data1,buffer,32);
|
||||
if(ABS(hlen-slen)<128){
|
||||
ssh_say(1,"Difference between server modulus and host modulus is only %d. It's illegal and may not work\n",
|
||||
ABS(hlen-slen));
|
||||
|
||||
/* xor session key with session_id */
|
||||
for (i = 0; i < 16; i++) {
|
||||
buffer[i] ^= session->next_crypto->session_id[i];
|
||||
}
|
||||
data1 = string_new(32);
|
||||
if (data1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
string_fill(data1, buffer, 32);
|
||||
if (ABS(hlen - slen) < 128){
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS,
|
||||
"Difference between server modulus and host modulus is only %d. "
|
||||
"It's illegal and may not work",
|
||||
ABS(hlen - slen));
|
||||
}
|
||||
|
||||
if (modulus_smaller(srvkey, hostkey)) {
|
||||
data2 = ssh_encrypt_rsa1(session, data1, srvkey);
|
||||
string_free(data1);
|
||||
data1 = NULL;
|
||||
if (data2 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if(modulus_smaller(svrkey,hostkey)){
|
||||
data2=ssh_encrypt_rsa1(session,data1,svrkey);
|
||||
free(data1);
|
||||
data1=ssh_encrypt_rsa1(session,data2,hostkey);
|
||||
} else {
|
||||
data2=ssh_encrypt_rsa1(session,data1,hostkey);
|
||||
free(data1);
|
||||
data1=ssh_encrypt_rsa1(session,data2,svrkey);
|
||||
data1 = ssh_encrypt_rsa1(session, data2, hostkey);
|
||||
string_free(data2);
|
||||
if (data1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return data1;
|
||||
} else {
|
||||
data2 = ssh_encrypt_rsa1(session, data1, hostkey);
|
||||
string_free(data1);
|
||||
data1 = NULL;
|
||||
if (data2 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
data1 = ssh_encrypt_rsa1(session, data2, srvkey);
|
||||
string_free(data2);
|
||||
if (data1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return data1;
|
||||
}
|
||||
|
||||
|
||||
@@ -399,116 +606,186 @@ STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *svrkey,
|
||||
* 32-bit int supported_authentications_mask
|
||||
*/
|
||||
|
||||
int ssh_get_kex1(SSH_SESSION *session){
|
||||
u32 server_bits, host_bits, protocol_flags,
|
||||
supported_ciphers_mask, supported_authentications_mask;
|
||||
STRING *server_exp=NULL;
|
||||
STRING *server_mod=NULL;
|
||||
STRING *host_exp=NULL;
|
||||
STRING *host_mod=NULL;
|
||||
STRING *serverkey;
|
||||
STRING *hostkey;
|
||||
STRING *enc_session;
|
||||
PUBLIC_KEY *svr,*host;
|
||||
int ko;
|
||||
u16 bits;
|
||||
enter_function();
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"Waiting for a SSH_SMSG_PUBLIC_KEY");
|
||||
if(packet_wait(session,SSH_SMSG_PUBLIC_KEY,1)){
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"Got a SSH_SMSG_PUBLIC_KEY");
|
||||
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,8)!=8){
|
||||
ssh_set_error(session,SSH_FATAL,"Can't get cookie in buffer");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
buffer_get_u32(session->in_buffer,&server_bits);
|
||||
server_exp=buffer_get_mpint(session->in_buffer);
|
||||
server_mod=buffer_get_mpint(session->in_buffer);
|
||||
buffer_get_u32(session->in_buffer,&host_bits);
|
||||
host_exp=buffer_get_mpint(session->in_buffer);
|
||||
host_mod=buffer_get_mpint(session->in_buffer);
|
||||
buffer_get_u32(session->in_buffer,&protocol_flags);
|
||||
buffer_get_u32(session->in_buffer,&supported_ciphers_mask);
|
||||
ko=buffer_get_u32(session->in_buffer,&supported_authentications_mask);
|
||||
if((ko!=sizeof(u32)) || !host_mod || !host_exp || !server_mod || !server_exp){
|
||||
ssh_log(session,SSH_LOG_RARE,"Invalid SSH_SMSG_PUBLIC_KEY packet");
|
||||
ssh_set_error(session,SSH_FATAL,"Invalid SSH_SMSG_PUBLIC_KEY packet");
|
||||
if(host_mod)
|
||||
free(host_mod);
|
||||
if(host_exp)
|
||||
free(host_exp);
|
||||
if(server_mod)
|
||||
free(server_mod);
|
||||
if(server_exp)
|
||||
free(server_exp);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
server_bits=ntohl(server_bits);
|
||||
host_bits=ntohl(host_bits);
|
||||
protocol_flags=ntohl(protocol_flags);
|
||||
supported_ciphers_mask=ntohl(supported_ciphers_mask);
|
||||
supported_authentications_mask=ntohl(supported_authentications_mask);
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"server bits: %d ; host bits: %d Protocol flags : %.8lx ; "
|
||||
"cipher mask : %.8lx ; auth mask: %.8lx",server_bits,
|
||||
host_bits,protocol_flags,supported_ciphers_mask,
|
||||
supported_authentications_mask);
|
||||
serverkey=make_rsa1_string(server_exp,server_mod);
|
||||
hostkey=make_rsa1_string(host_exp,host_mod);
|
||||
build_session_id1(session,server_mod,host_mod);
|
||||
free(server_exp);
|
||||
free(server_mod);
|
||||
free(host_exp);
|
||||
free(host_mod);
|
||||
svr=publickey_from_string(session, serverkey);
|
||||
host=publickey_from_string(session, hostkey);
|
||||
session->next_crypto->server_pubkey=string_copy(hostkey);
|
||||
session->next_crypto->server_pubkey_type="ssh-rsa1";
|
||||
int ssh_get_kex1(SSH_SESSION *session) {
|
||||
STRING *server_exp = NULL;
|
||||
STRING *server_mod = NULL;
|
||||
STRING *host_exp = NULL;
|
||||
STRING *host_mod = NULL;
|
||||
STRING *serverkey = NULL;
|
||||
STRING *hostkey = NULL;
|
||||
STRING *enc_session = NULL;
|
||||
PUBLIC_KEY *srv = NULL;
|
||||
PUBLIC_KEY *host = NULL;
|
||||
u32 server_bits;
|
||||
u32 host_bits;
|
||||
u32 protocol_flags;
|
||||
u32 supported_ciphers_mask;
|
||||
u32 supported_authentications_mask;
|
||||
u16 bits;
|
||||
int rc = -1;
|
||||
int ko;
|
||||
|
||||
/* now, we must choose an encryption algo */
|
||||
/* hardcode 3des */
|
||||
if(!(supported_ciphers_mask & (1<<SSH_CIPHER_3DES))){
|
||||
ssh_set_error(session,SSH_FATAL,"Remote server doesn't accept 3des");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"sending SSH_CMSG_SESSION_KEY");
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_SESSION_KEY);
|
||||
buffer_add_u8(session->out_buffer,SSH_CIPHER_3DES);
|
||||
buffer_add_data(session->out_buffer,session->server_kex.cookie,8);
|
||||
|
||||
enc_session=encrypt_session_key(session,svr,host,server_bits, host_bits);
|
||||
bits=string_len(enc_session)*8 - 7;
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"%d bits,%d bytes encrypted session",bits,string_len(enc_session));
|
||||
bits=htons(bits);
|
||||
/* the encrypted mpint */
|
||||
buffer_add_data(session->out_buffer,&bits,sizeof(u16));
|
||||
buffer_add_data(session->out_buffer,enc_session->string,
|
||||
string_len(enc_session));
|
||||
/* the protocol flags */
|
||||
buffer_add_u32(session->out_buffer,0);
|
||||
|
||||
packet_send(session);
|
||||
/* we can set encryption */
|
||||
if(crypt_set_algorithms(session)){
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
session->current_crypto=session->next_crypto;
|
||||
session->next_crypto=NULL;
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"Waiting for a SSH_SMSG_SUCCESS");
|
||||
if(packet_wait(session,SSH_SMSG_SUCCESS,1)){
|
||||
char buffer[1024];
|
||||
snprintf(buffer,sizeof(buffer),"Key exchange failed : %s",ssh_get_error(session));
|
||||
ssh_set_error(session,SSH_FATAL,"%s",buffer);
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session,SSH_LOG_PROTOCOL,"received SSH_SMSG_SUCCESS\n");
|
||||
enter_function();
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
|
||||
if (packet_wait(session, SSH_SMSG_PUBLIC_KEY, 1) != SSH_OK) {
|
||||
leave_function();
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY");
|
||||
if (buffer_get_data(session->in_buffer, session->server_kex.cookie, 8) != 8) {
|
||||
ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer");
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_get_u32(session->in_buffer, &server_bits);
|
||||
server_exp = buffer_get_mpint(session->in_buffer);
|
||||
if (server_exp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
server_mod = buffer_get_mpint(session->in_buffer);
|
||||
if (server_mod == NULL) {
|
||||
goto error;
|
||||
}
|
||||
buffer_get_u32(session->in_buffer, &host_bits);
|
||||
host_exp = buffer_get_mpint(session->in_buffer);
|
||||
if (host_exp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
host_mod = buffer_get_mpint(session->in_buffer);
|
||||
if (host_mod == NULL) {
|
||||
goto error;
|
||||
}
|
||||
buffer_get_u32(session->in_buffer, &protocol_flags);
|
||||
buffer_get_u32(session->in_buffer, &supported_ciphers_mask);
|
||||
ko = buffer_get_u32(session->in_buffer, &supported_authentications_mask);
|
||||
|
||||
if ((ko != sizeof(u32)) || !host_mod || !host_exp
|
||||
|| !server_mod || !server_exp) {
|
||||
ssh_log(session, SSH_LOG_RARE, "Invalid SSH_SMSG_PUBLIC_KEY packet");
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid SSH_SMSG_PUBLIC_KEY packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
server_bits = ntohl(server_bits);
|
||||
host_bits = ntohl(host_bits);
|
||||
protocol_flags = ntohl(protocol_flags);
|
||||
supported_ciphers_mask = ntohl(supported_ciphers_mask);
|
||||
supported_authentications_mask = ntohl(supported_authentications_mask);
|
||||
ssh_log(session, SSH_LOG_PROTOCOL,
|
||||
"Server bits: %d; Host bits: %d; Protocol flags: %.8lx; "
|
||||
"Cipher mask: %.8lx; Auth mask: %.8lx",
|
||||
server_bits,
|
||||
host_bits,
|
||||
(unsigned long int) protocol_flags,
|
||||
(unsigned long int) supported_ciphers_mask,
|
||||
(unsigned long int) supported_authentications_mask);
|
||||
|
||||
serverkey = make_rsa1_string(server_exp, server_mod);
|
||||
if (serverkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
hostkey = make_rsa1_string(host_exp,host_mod);
|
||||
if (serverkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (build_session_id1(session, server_mod, host_mod) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
srv = publickey_from_string(session, serverkey);
|
||||
if (srv == NULL) {
|
||||
goto error;
|
||||
}
|
||||
host = publickey_from_string(session, hostkey);
|
||||
if (host == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->next_crypto->server_pubkey = string_copy(hostkey);
|
||||
if (session->next_crypto->server_pubkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
session->next_crypto->server_pubkey_type = "ssh-rsa1";
|
||||
|
||||
/* now, we must choose an encryption algo */
|
||||
/* hardcode 3des */
|
||||
if (!(supported_ciphers_mask & (1 << SSH_CIPHER_3DES))) {
|
||||
ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY");
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, session->server_kex.cookie, 8) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits);
|
||||
if (enc_session == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
bits = string_len(enc_session) * 8 - 7;
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session",
|
||||
bits, string_len(enc_session));
|
||||
bits = htons(bits);
|
||||
/* the encrypted mpint */
|
||||
if (buffer_add_data(session->out_buffer, &bits, sizeof(u16)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, enc_session->string,
|
||||
string_len(enc_session)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* the protocol flags */
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* we can set encryption */
|
||||
if (crypt_set_algorithms(session)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->current_crypto = session->next_crypto;
|
||||
session->next_crypto = NULL;
|
||||
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
|
||||
if (packet_wait(session,SSH_SMSG_SUCCESS,1) != SSH_OK) {
|
||||
char buffer[1024] = {0};
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"Key exchange failed: %s", ssh_get_error(session));
|
||||
ssh_set_error(session, SSH_FATAL, "%s",buffer);
|
||||
goto error;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");
|
||||
|
||||
rc = 0;
|
||||
error:
|
||||
string_free(host_mod);
|
||||
string_free(host_exp);
|
||||
string_free(server_mod);
|
||||
string_free(server_exp);
|
||||
string_free(serverkey);
|
||||
string_free(hostkey);
|
||||
|
||||
publickey_free(srv);
|
||||
publickey_free(host);
|
||||
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
2037
libssh/keyfiles.c
2037
libssh/keyfiles.c
File diff suppressed because it is too large
Load Diff
1915
libssh/keys.c
1915
libssh/keys.c
File diff suppressed because it is too large
Load Diff
185
libssh/libssh.map
Normal file
185
libssh/libssh.map
Normal file
@@ -0,0 +1,185 @@
|
||||
SSH_0.3 {
|
||||
global:
|
||||
buffer_free;
|
||||
buffer_get;
|
||||
buffer_get_len;
|
||||
buffer_new;
|
||||
channel_change_pty_size;
|
||||
channel_close;
|
||||
channel_free;
|
||||
channel_get_exit_status;
|
||||
channel_get_session;
|
||||
channel_is_closed;
|
||||
channel_is_eof;
|
||||
channel_is_open;
|
||||
channel_new;
|
||||
channel_open_forward;
|
||||
channel_open_session;
|
||||
channel_poll;
|
||||
channel_read;
|
||||
channel_read_buffer;
|
||||
channel_read_nonblocking;
|
||||
channel_request_env;
|
||||
channel_request_exec;
|
||||
channel_request_pty;
|
||||
channel_request_pty_size;
|
||||
channel_request_sftp;
|
||||
channel_request_shell;
|
||||
channel_request_subsystem;
|
||||
channel_select;
|
||||
channel_send_eof;
|
||||
channel_set_blocking;
|
||||
channel_write;
|
||||
privatekey_free;
|
||||
privatekey_from_file;
|
||||
publickey_free;
|
||||
publickey_from_file;
|
||||
publickey_from_privatekey;
|
||||
publickey_to_string;
|
||||
sftp_async_read;
|
||||
sftp_async_read_begin;
|
||||
sftp_attributes_free;
|
||||
sftp_canonicalize_path;
|
||||
sftp_chmod;
|
||||
sftp_chown;
|
||||
sftp_close;
|
||||
sftp_closedir;
|
||||
sftp_dir_eof;
|
||||
sftp_file_set_blocking;
|
||||
sftp_file_set_nonblocking;
|
||||
sftp_free;
|
||||
sftp_fstat;
|
||||
sftp_get_error;
|
||||
sftp_init;
|
||||
sftp_lstat;
|
||||
sftp_mkdir;
|
||||
sftp_new;
|
||||
sftp_open;
|
||||
sftp_opendir;
|
||||
sftp_read;
|
||||
sftp_readdir;
|
||||
sftp_readlink;
|
||||
sftp_rename;
|
||||
sftp_rewind;
|
||||
sftp_rmdir;
|
||||
sftp_seek;
|
||||
sftp_seek64;
|
||||
sftp_server_init;
|
||||
sftp_server_new;
|
||||
sftp_server_version;
|
||||
sftp_setstat;
|
||||
sftp_stat;
|
||||
sftp_symlink;
|
||||
sftp_tell;
|
||||
sftp_tell64;
|
||||
sftp_unlink;
|
||||
sftp_utimes;
|
||||
sftp_write;
|
||||
ssh_accept;
|
||||
ssh_auth_list;
|
||||
ssh_bind_accept;
|
||||
ssh_bind_fd_toaccept;
|
||||
ssh_bind_free;
|
||||
ssh_bind_get_fd;
|
||||
ssh_bind_listen;
|
||||
ssh_bind_new;
|
||||
ssh_bind_set_blocking;
|
||||
ssh_bind_set_fd;
|
||||
ssh_bind_set_options;
|
||||
ssh_clean_pubkey_hash;
|
||||
ssh_connect;
|
||||
ssh_copyright;
|
||||
ssh_disconnect;
|
||||
ssh_fd_poll;
|
||||
ssh_finalize;
|
||||
ssh_get_disconnect_message;
|
||||
ssh_get_error;
|
||||
ssh_get_error_code;
|
||||
ssh_get_fd;
|
||||
ssh_get_hexa;
|
||||
ssh_get_issue_banner;
|
||||
ssh_get_openssh_version;
|
||||
ssh_get_pubkey;
|
||||
ssh_get_pubkey_hash;
|
||||
ssh_get_random;
|
||||
ssh_get_status;
|
||||
ssh_get_version;
|
||||
ssh_init;
|
||||
ssh_is_server_known;
|
||||
ssh_log;
|
||||
ssh_message_auth_password;
|
||||
ssh_message_auth_publickey;
|
||||
ssh_message_auth_reply_pk_ok;
|
||||
ssh_message_auth_reply_success;
|
||||
ssh_message_auth_set_methods;
|
||||
ssh_message_auth_user;
|
||||
ssh_message_channel_request_open_reply_accept;
|
||||
ssh_message_channel_request_reply_success;
|
||||
ssh_message_free;
|
||||
ssh_message_get;
|
||||
ssh_message_reply_default;
|
||||
ssh_message_retrieve;
|
||||
ssh_message_service_reply_success;
|
||||
ssh_message_service_service;
|
||||
ssh_message_subtype;
|
||||
ssh_message_type;
|
||||
ssh_new;
|
||||
ssh_options_allow_ssh1;
|
||||
ssh_options_allow_ssh2;
|
||||
ssh_options_copy;
|
||||
ssh_options_free;
|
||||
ssh_options_getopt;
|
||||
ssh_options_new;
|
||||
ssh_options_set_auth_callback;
|
||||
ssh_options_set_banner;
|
||||
ssh_options_set_bind;
|
||||
ssh_options_set_dsa_server_key;
|
||||
ssh_options_set_fd;
|
||||
ssh_options_set_host;
|
||||
ssh_options_set_identity;
|
||||
ssh_options_set_known_hosts_file;
|
||||
ssh_options_set_log_function;
|
||||
ssh_options_set_log_verbosity;
|
||||
ssh_options_set_port;
|
||||
ssh_options_set_rsa_server_key;
|
||||
ssh_options_set_ssh_dir;
|
||||
ssh_options_set_status_callback;
|
||||
ssh_options_set_timeout;
|
||||
ssh_options_set_username;
|
||||
ssh_options_set_wanted_algos;
|
||||
ssh_print_hexa;
|
||||
ssh_select;
|
||||
ssh_service_request;
|
||||
ssh_set_blocking;
|
||||
ssh_set_fd_except;
|
||||
ssh_set_fd_toread;
|
||||
ssh_set_fd_towrite;
|
||||
ssh_set_options;
|
||||
ssh_silent_disconnect;
|
||||
ssh_userauth_agent_pubkey;
|
||||
ssh_userauth_autopubkey;
|
||||
ssh_userauth_kbdint;
|
||||
ssh_userauth_kbdint_getinstruction;
|
||||
ssh_userauth_kbdint_getname;
|
||||
ssh_userauth_kbdint_getnprompts;
|
||||
ssh_userauth_kbdint_getprompt;
|
||||
ssh_userauth_kbdint_setanswer;
|
||||
ssh_userauth_list;
|
||||
ssh_userauth_none;
|
||||
ssh_userauth_offer_pubkey;
|
||||
ssh_userauth_password;
|
||||
ssh_userauth_pubkey;
|
||||
ssh_version;
|
||||
ssh_write_knownhost;
|
||||
string_burn;
|
||||
string_copy;
|
||||
string_data;
|
||||
string_fill;
|
||||
string_free;
|
||||
string_from_char;
|
||||
string_len;
|
||||
string_new;
|
||||
string_to_char;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -1,61 +0,0 @@
|
||||
SSH_0.2 {
|
||||
global:
|
||||
ssh_get_error; ssh_get_error_code; ssh_say; ssh_set_verbosity;
|
||||
ssh_new; ssh_set_options; ssh_get_fd; ssh_silent_disconnect;
|
||||
ssh_connect; ssh_disconnect; ssh_service_request; ssh_get_issue_banner;
|
||||
ssh_copyright; ssh_get_version; ssh_finalize;
|
||||
ssh_set_fd_toread; ssh_set_fd_towrite; ssh_set_fd_except;
|
||||
string_from_char; string_len; string_new; string_fill; string_to_char;
|
||||
string_copy; string_burn; string_data;
|
||||
ssh_crypto_init;
|
||||
ssh_print_hexa; ssh_get_random;
|
||||
ssh_get_pubkey_hash; ssh_get_pubkey;
|
||||
ssh_fd_poll; ssh_select; publickey_free;
|
||||
privatekey_from_file; publickey_to_string; publickey_from_privatekey;
|
||||
private_key_free; publickey_from_file; publickey_from_next_file;
|
||||
ssh_is_server_known; ssh_write_knownhost;
|
||||
channel_new; channel_open_forward; channel_open_session; channel_free;
|
||||
channel_request_pty; channel_request_pty_size; channel_change_pty_size;
|
||||
channel_request_shell; channel_request_subsystem; channel_request_env;
|
||||
channel_request_exec; channel_request_sftp; channel_write;
|
||||
channel_send_eof; channel_read; channel_poll; channel_close;
|
||||
channel_read_nonblocking; channel_is_open;
|
||||
channel_is_closed; channel_is_eof; channel_select;
|
||||
ssh_options_new; ssh_options_copy; ssh_options_set_wanted_algos;
|
||||
ssh_options_set_username; ssh_options_set_port; ssh_options_getopt;
|
||||
ssh_options_set_host; ssh_options_set_fd; ssh_options_set_bind;
|
||||
ssh_options_set_identity; ssh_options_set_status_callback;
|
||||
ssh_options_set_timeout; ssh_options_set_ssh_dir;
|
||||
ssh_options_set_known_hosts_file; ssh_options_allow_ssh1;
|
||||
ssh_options_allow_ssh2; ssh_options_set_dsa_server_key;
|
||||
ssh_options_set_rsa_server_key;
|
||||
buffer_new; buffer_free; buffer_get; buffer_get_len;
|
||||
ssh_userauth_none; ssh_userauth_password; ssh_userauth_offer_pubkey;
|
||||
ssh_userauth_pubkey; ssh_userauth_autopubkey; ssh_userauth_kbdint;
|
||||
ssh_userauth_kbdint_getnprompts; ssh_userauth_kbdint_getname;
|
||||
ssh_userauth_kbdint_getinstruction; ssh_userauth_kbdint_getprompt;
|
||||
ssh_userauth_kbdint_setanswer;
|
||||
sftp_new; sftp_free; sftp_init; sftp_opendir; sftp_readdir; sftp_dir_eof;
|
||||
sftp_stat; sftp_lstat; sftp_fstat; sftp_attributes_free; sftp_dir_close;
|
||||
sftp_file_close; sftp_open; sftp_read; sftp_write; sftp_seek; sftp_tell;
|
||||
sftp_rewind; sftp_rm; sftp_rmdir; sftp_mkdir; sftp_rename; sftp_setstat;
|
||||
sftp_canonicalize_path; sftp_server_new; sftp_server_init;
|
||||
sftp_get_client_message; sftp_client_message_free; sftp_reply_name;
|
||||
sftp_reply_handle; sftp_handle_alloc; sftp_reply_attr; sftp_handle;
|
||||
sftp_reply_status; sftp_reply_names_add; sftp_reply_names;
|
||||
sftp_reply_data; sftp_handle_remove;
|
||||
ssh_bind_new; ssh_bind_set_options; ssh_bind_listen; ssh_bind_set_blocking;
|
||||
ssh_bind_get_fd; ssh_bind_set_toaccept; ssh_bind_accept; ssh_bind_free;
|
||||
ssh_accept;
|
||||
ssh_message_get; ssh_message_type; ssh_message_subtype;
|
||||
ssh_message_reply_default; ssh_message_free; ssh_message_auth_user;
|
||||
ssh_message_auth_password; ssh_message_auth_reply_success;
|
||||
ssh_message_auth_set_methods;
|
||||
ssh_message_channel_request_open_reply_accept;
|
||||
ssh_message_channel_request_channel; ssh_message_channel_request_pty_term;
|
||||
ssh_message_channel_request_subsystem;
|
||||
ssh_message_channel_request_reply_success;
|
||||
set_encrypt_key; set_decrypt_key; cbc_encrypt; cbc_decrypt;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
89
libssh/log.c
89
libssh/log.c
@@ -1,8 +1,10 @@
|
||||
/*
|
||||
* Copyright 2008 Aris Adamantiadis
|
||||
* log.c - logging and debugging functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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
|
||||
@@ -16,46 +18,61 @@
|
||||
* 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. */
|
||||
|
||||
|
||||
/** \defgroup ssh_log SSH logging
|
||||
* \brief Logging functions for debugging and problem resolving
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
/** \addtogroup ssh_log
|
||||
* @{ */
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
/** \brief logs an event
|
||||
* \param session the SSH session
|
||||
* \param verbosity verbosity of the event
|
||||
* \param format format string of the log entry
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/**
|
||||
* @defgroup ssh_log SSH Logging
|
||||
*
|
||||
* @brief Logging functions for debugging and problem resolving
|
||||
*/
|
||||
void ssh_log(SSH_SESSION *session, int verbosity, char *format, ...){
|
||||
char buffer[1024];
|
||||
char buf2[256];
|
||||
int min;
|
||||
va_list va;
|
||||
if(verbosity <= session->log_verbosity){
|
||||
va_start(va,format);
|
||||
vsnprintf(buffer,sizeof(buffer),format,va);
|
||||
va_end(va);
|
||||
if(session->options->log_function)
|
||||
session->options->log_function(buffer,session,verbosity);
|
||||
else if(verbosity==SSH_LOG_FUNCTIONS){
|
||||
if(session->log_indent > 255)
|
||||
min=255;
|
||||
else
|
||||
min=session->log_indent;
|
||||
memset(buf2,' ',min);
|
||||
buf2[min]=0;
|
||||
fprintf(stderr,"[func] %s%s\n",buf2,buffer);
|
||||
} else {
|
||||
fprintf(stderr,"[%d] %s\n",verbosity,buffer);
|
||||
}
|
||||
}
|
||||
/** \addtogroup ssh_log
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief Log a SSH event.
|
||||
*
|
||||
* @param session The SSH session.
|
||||
*
|
||||
* @param verbosity The verbosity of the event.
|
||||
*
|
||||
* @param format The format string of the log entry.
|
||||
*/
|
||||
void ssh_log(SSH_SESSION *session, int verbosity, const char *format, ...) {
|
||||
char buffer[1024];
|
||||
char indent[256];
|
||||
int min;
|
||||
va_list va;
|
||||
|
||||
if (verbosity <= session->log_verbosity) {
|
||||
va_start(va, format);
|
||||
vsnprintf(buffer, sizeof(buffer), format, va);
|
||||
va_end(va);
|
||||
|
||||
if (session->options->log_function) {
|
||||
session->options->log_function(buffer, session, verbosity);
|
||||
} else if (verbosity == SSH_LOG_FUNCTIONS) {
|
||||
if (session->log_indent > 255) {
|
||||
min = 255;
|
||||
} else {
|
||||
min = session->log_indent;
|
||||
}
|
||||
|
||||
memset(indent, ' ', min);
|
||||
indent[min] = '\0';
|
||||
|
||||
fprintf(stderr, "[func] %s%s\n", indent, buffer);
|
||||
} else {
|
||||
fprintf(stderr, "[%d] %s\n", verbosity, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
226
libssh/match.c
226
libssh/match.c
@@ -10,6 +10,7 @@
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@@ -34,142 +35,151 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/*
|
||||
* Returns true if the given string matches the pattern (which may contain ?
|
||||
* and * as wildcards), and zero if it does not match.
|
||||
*/
|
||||
static int match_pattern(const char *s, const char *pattern) {
|
||||
for (;;) {
|
||||
/* If at end of pattern, accept if also at end of string. */
|
||||
if (!*pattern) {
|
||||
return !*s;
|
||||
}
|
||||
|
||||
int
|
||||
match_pattern(const char *s, const char *pattern)
|
||||
{
|
||||
for (;;) {
|
||||
/* If at end of pattern, accept if also at end of string. */
|
||||
if (!*pattern)
|
||||
return !*s;
|
||||
if (*pattern == '*') {
|
||||
/* Skip the asterisk. */
|
||||
pattern++;
|
||||
|
||||
if (*pattern == '*') {
|
||||
/* Skip the asterisk. */
|
||||
pattern++;
|
||||
/* If at end of pattern, accept immediately. */
|
||||
if (!*pattern)
|
||||
return 1;
|
||||
|
||||
/* If at end of pattern, accept immediately. */
|
||||
if (!*pattern)
|
||||
return 1;
|
||||
/* If next character in pattern is known, optimize. */
|
||||
if (*pattern != '?' && *pattern != '*') {
|
||||
/*
|
||||
* Look instances of the next character in
|
||||
* pattern, and try to match starting from
|
||||
* those.
|
||||
*/
|
||||
for (; *s; s++)
|
||||
if (*s == *pattern && match_pattern(s + 1, pattern + 1)) {
|
||||
return 1;
|
||||
}
|
||||
/* Failed. */
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Move ahead one character at a time and try to
|
||||
* match at each position.
|
||||
*/
|
||||
for (; *s; s++) {
|
||||
if (match_pattern(s, pattern)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Failed. */
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* There must be at least one more character in the string.
|
||||
* If we are at the end, fail.
|
||||
*/
|
||||
if (!*s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If next character in pattern is known, optimize. */
|
||||
if (*pattern != '?' && *pattern != '*') {
|
||||
/*
|
||||
* Look instances of the next character in
|
||||
* pattern, and try to match starting from
|
||||
* those.
|
||||
*/
|
||||
for (; *s; s++)
|
||||
if (*s == *pattern &&
|
||||
match_pattern(s + 1, pattern + 1))
|
||||
return 1;
|
||||
/* Failed. */
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Move ahead one character at a time and try to
|
||||
* match at each position.
|
||||
*/
|
||||
for (; *s; s++)
|
||||
if (match_pattern(s, pattern))
|
||||
return 1;
|
||||
/* Failed. */
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* There must be at least one more character in the string.
|
||||
* If we are at the end, fail.
|
||||
*/
|
||||
if (!*s)
|
||||
return 0;
|
||||
/* Check if the next character of the string is acceptable. */
|
||||
if (*pattern != '?' && *pattern != *s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if the next character of the string is acceptable. */
|
||||
if (*pattern != '?' && *pattern != *s)
|
||||
return 0;
|
||||
/* Move to the next character, both in string and in pattern. */
|
||||
s++;
|
||||
pattern++;
|
||||
}
|
||||
|
||||
/* Move to the next character, both in string and in pattern. */
|
||||
s++;
|
||||
pattern++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Tries to match the string against the
|
||||
* comma-separated sequence of subpatterns (each possibly preceded by ! to
|
||||
* indicate negation). Returns -1 if negation matches, 1 if there is
|
||||
* a positive match, 0 if there is no match at all.
|
||||
* Tries to match the string against the comma-separated sequence of subpatterns
|
||||
* (each possibly preceded by ! to indicate negation).
|
||||
* Returns -1 if negation matches, 1 if there is a positive match, 0 if there is
|
||||
* no match at all.
|
||||
*/
|
||||
static int match_pattern_list(const char *string, const char *pattern,
|
||||
unsigned int len, int dolower) {
|
||||
char sub[1024];
|
||||
int negated;
|
||||
int got_positive;
|
||||
unsigned int i, subi;
|
||||
|
||||
int
|
||||
match_pattern_list(const char *string, const char *pattern, u_int len,
|
||||
int dolower)
|
||||
{
|
||||
char sub[1024];
|
||||
int negated;
|
||||
int got_positive;
|
||||
u_int i, subi;
|
||||
got_positive = 0;
|
||||
for (i = 0; i < len;) {
|
||||
/* Check if the subpattern is negated. */
|
||||
if (pattern[i] == '!') {
|
||||
negated = 1;
|
||||
i++;
|
||||
} else {
|
||||
negated = 0;
|
||||
}
|
||||
|
||||
got_positive = 0;
|
||||
for (i = 0; i < len;) {
|
||||
/* Check if the subpattern is negated. */
|
||||
if (pattern[i] == '!') {
|
||||
negated = 1;
|
||||
i++;
|
||||
} else
|
||||
negated = 0;
|
||||
/*
|
||||
* Extract the subpattern up to a comma or end. Convert the
|
||||
* subpattern to lowercase.
|
||||
*/
|
||||
for (subi = 0;
|
||||
i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
|
||||
subi++, i++) {
|
||||
sub[subi] = dolower && isupper(pattern[i]) ?
|
||||
(char)tolower(pattern[i]) : pattern[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the subpattern up to a comma or end. Convert the
|
||||
* subpattern to lowercase.
|
||||
*/
|
||||
for (subi = 0;
|
||||
i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
|
||||
subi++, i++)
|
||||
sub[subi] = dolower && isupper(pattern[i]) ?
|
||||
(char)tolower(pattern[i]) : pattern[i];
|
||||
/* If subpattern too long, return failure (no match). */
|
||||
if (subi >= sizeof(sub) - 1)
|
||||
return 0;
|
||||
/* If subpattern too long, return failure (no match). */
|
||||
if (subi >= sizeof(sub) - 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the subpattern was terminated by a comma, skip the comma. */
|
||||
if (i < len && pattern[i] == ',')
|
||||
i++;
|
||||
/* If the subpattern was terminated by a comma, skip the comma. */
|
||||
if (i < len && pattern[i] == ',') {
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Null-terminate the subpattern. */
|
||||
sub[subi] = '\0';
|
||||
/* Null-terminate the subpattern. */
|
||||
sub[subi] = '\0';
|
||||
|
||||
/* Try to match the subpattern against the string. */
|
||||
if (match_pattern(string, sub)) {
|
||||
if (negated)
|
||||
return -1; /* Negative */
|
||||
else
|
||||
got_positive = 1; /* Positive */
|
||||
}
|
||||
}
|
||||
/* Try to match the subpattern against the string. */
|
||||
if (match_pattern(string, sub)) {
|
||||
if (negated) {
|
||||
return -1; /* Negative */
|
||||
} else {
|
||||
got_positive = 1; /* Positive */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return success if got a positive match. If there was a negative
|
||||
* match, we have already returned -1 and never get here.
|
||||
*/
|
||||
return got_positive;
|
||||
/*
|
||||
* Return success if got a positive match. If there was a negative
|
||||
* match, we have already returned -1 and never get here.
|
||||
*/
|
||||
return got_positive;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tries to match the host name (which must be in all lowercase) against the
|
||||
* comma-separated sequence of subpatterns (each possibly preceded by ! to
|
||||
* indicate negation). Returns -1 if negation matches, 1 if there is
|
||||
* a positive match, 0 if there is no match at all.
|
||||
* indicate negation).
|
||||
* Returns -1 if negation matches, 1 if there is a positive match, 0 if there
|
||||
* is no match at all.
|
||||
*/
|
||||
int
|
||||
match_hostname(const char *host, const char *pattern, u_int len)
|
||||
{
|
||||
return match_pattern_list(host, pattern, len, 1);
|
||||
int match_hostname(const char *host, const char *pattern, unsigned int len) {
|
||||
return match_pattern_list(host, pattern, len, 1);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
1073
libssh/messages.c
1073
libssh/messages.c
File diff suppressed because it is too large
Load Diff
165
libssh/misc.c
165
libssh/misc.c
@@ -1,25 +1,26 @@
|
||||
/* misc.c */
|
||||
/* some misc routines than aren't really part of the ssh protocols but can be useful to the client */
|
||||
|
||||
/*
|
||||
Copyright 2003 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* misc.c - useful client functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003 by Aris Adamantiadis
|
||||
* Copyright (c) 2008-2009 by Andreas Schneider <mail@cynapses.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
@@ -28,59 +29,125 @@ MA 02111-1307, USA. */
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WIN32_IE 0x0400 //SHGetSpecialFolderPath
|
||||
#include <shlobj.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <pwd.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
char *ssh_get_user_home_dir(){
|
||||
static char szPath[PATH_MAX] = {0};
|
||||
struct passwd *pwd = NULL;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#define GCRYPT_STRING "/gnutls"
|
||||
#else
|
||||
#define GCRYPT_STRING ""
|
||||
#endif
|
||||
|
||||
pwd = getpwuid(getuid());
|
||||
if (pwd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
#define CRYPTO_STRING "/openssl"
|
||||
#else
|
||||
#define CRYPTO_STRING ""
|
||||
#endif
|
||||
|
||||
snprintf(szPath, PATH_MAX - 1, "%s", pwd->pw_dir);
|
||||
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
|
||||
#define LIBZ_STRING "/zlib"
|
||||
#else
|
||||
#define LIBZ_STRING ""
|
||||
#endif
|
||||
|
||||
/** \defgroup ssh_misc SSH Misc
|
||||
* \brief Misc functions
|
||||
*/
|
||||
/** \addtogroup ssh_misc
|
||||
* @{ */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
char *ssh_get_user_home_dir(void) {
|
||||
static char szPath[MAX_PATH] = {0};
|
||||
|
||||
if (SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, TRUE)) {
|
||||
return szPath;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
|
||||
char *ssh_get_user_home_dir(){
|
||||
static char szPath[MAX_PATH];
|
||||
if (SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, TRUE))
|
||||
return szPath;
|
||||
else
|
||||
return NULL;
|
||||
char *ssh_get_user_home_dir(void) {
|
||||
static char szPath[PATH_MAX] = {0};
|
||||
struct passwd *pwd = NULL;
|
||||
|
||||
pwd = getpwuid(getuid());
|
||||
if (pwd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(szPath, PATH_MAX - 1, "%s", pwd->pw_dir);
|
||||
|
||||
return szPath;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* we have read access on file */
|
||||
int ssh_file_readaccess_ok(char *file){
|
||||
if(!access(file,R_OK))
|
||||
return 1;
|
||||
int ssh_file_readaccess_ok(const char *file) {
|
||||
if (access(file, R_OK) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
u64 ntohll(u64 a){
|
||||
u64 ntohll(u64 a) {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
return a;
|
||||
return a;
|
||||
#else
|
||||
u32 low=a & 0xffffffff;
|
||||
u32 high = a >> 32 ;
|
||||
low=ntohl(low);
|
||||
high=ntohl(high);
|
||||
return (( ((u64)low) << 32) | ( high));
|
||||
u32 low = a & 0xffffffff;
|
||||
u32 high = a >> 32 ;
|
||||
low = ntohl(low);
|
||||
high = ntohl(high);
|
||||
|
||||
return ((((u64) low) << 32) | ( high));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if libssh is the required version or get the version
|
||||
* string.
|
||||
*
|
||||
* @param req_version The version required.
|
||||
*
|
||||
* @return If the version of libssh is newer than the version
|
||||
* required it will return a version string.
|
||||
* NULL if the version is older.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* @code
|
||||
* if (ssh_version(SSH_VERSION_INT(0,2,1)) == NULL) {
|
||||
* fprintf(stderr, "libssh version is too old!\n");
|
||||
* exit(1);
|
||||
* }
|
||||
*
|
||||
* if (debug) {
|
||||
* printf("libssh %s\n", ssh_version(0));
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
const char *ssh_version(int req_version) {
|
||||
if (req_version <= LIBSSH_VERSION_INT) {
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) GCRYPT_STRING CRYPTO_STRING
|
||||
LIBZ_STRING;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
1289
libssh/options.c
1289
libssh/options.c
File diff suppressed because it is too large
Load Diff
1210
libssh/packet.c
1210
libssh/packet.c
File diff suppressed because it is too large
Load Diff
206
libssh/poll.c
Normal file
206
libssh/poll.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* poll.c - poll wrapper
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* vim: ts=2 sw=2 et cindent
|
||||
*/
|
||||
|
||||
/* This code is based on glib's gpoll */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
#include <poll.h>
|
||||
|
||||
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
return poll((struct pollfd *) fds, nfds, timeout);
|
||||
}
|
||||
|
||||
#else /* HAVE_POLL */
|
||||
#ifdef _WIN32
|
||||
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
|
||||
#include <winsock2.h>
|
||||
|
||||
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
return WSAPoll(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
#else /* _WIN32_WINNT */
|
||||
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
static int poll_rest (HANDLE *handles, int nhandles,
|
||||
pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
DWORD ready;
|
||||
pollfd_t *f;
|
||||
int recursed_result;
|
||||
|
||||
if (nhandles == 0) {
|
||||
/* No handles to wait for, just the timeout */
|
||||
if (timeout == INFINITE) {
|
||||
ready = WAIT_FAILED;
|
||||
} else {
|
||||
SleepEx(timeout, 1);
|
||||
ready = WAIT_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
/* Wait for just handles */
|
||||
ready = WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
|
||||
#if 0
|
||||
if (ready == WAIT_FAILED) {
|
||||
fprintf(stderr, "WaitForMultipleObjectsEx failed: %d\n", GetLastError());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ready == WAIT_FAILED) {
|
||||
return -1;
|
||||
} else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
|
||||
return 0;
|
||||
} else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles) {
|
||||
for (f = fds; f < &fds[nfds]; f++) {
|
||||
if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
|
||||
f->revents = f->events;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If no timeout and polling several handles, recurse to poll
|
||||
* the rest of them.
|
||||
*/
|
||||
if (timeout == 0 && nhandles > 1) {
|
||||
/* Remove the handle that fired */
|
||||
int i;
|
||||
if (ready < nhandles - 1) {
|
||||
for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
|
||||
handles[i-1] = handles[i];
|
||||
}
|
||||
}
|
||||
nhandles--;
|
||||
recursed_result = poll_rest(handles, nhandles, fds, nfds, 0);
|
||||
if (recursed_result < 0) {
|
||||
return -1;
|
||||
}
|
||||
return recursed_result + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssh_poll(pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
|
||||
pollfd_t *f;
|
||||
int nhandles = 0;
|
||||
int rc = -1;
|
||||
|
||||
if (fds == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nfds >= MAXIMUM_WAIT_OBJECTS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (f = fds; f < &fds[nfds]; f++) {
|
||||
if (f->fd > 0) {
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Don't add the same handle several times into the array, as
|
||||
* docs say that is not allowed, even if it actually does seem
|
||||
* to work.
|
||||
*/
|
||||
for (i = 0; i < nhandles; i++) {
|
||||
if (handles[i] == (HANDLE) f->fd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == nhandles) {
|
||||
if (nhandles == MAXIMUM_WAIT_OBJECTS) {
|
||||
break;
|
||||
} else {
|
||||
handles[nhandles++] = (HANDLE) f->fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeout == -1) {
|
||||
timeout = INFINITE;
|
||||
}
|
||||
|
||||
if (nhandles > 1) {
|
||||
/*
|
||||
* First check if one or several of them are immediately
|
||||
* available.
|
||||
*/
|
||||
rc = poll_rest(handles, nhandles, fds, nfds, 0);
|
||||
|
||||
/*
|
||||
* If not, and we have a significant timeout, poll again with
|
||||
* timeout then. Note that this will return indication for only
|
||||
* one event, or only for messages. We ignore timeouts less than
|
||||
* ten milliseconds as they are mostly pointless on Windows, the
|
||||
* MsgWaitForMultipleObjectsEx() call will timeout right away
|
||||
* anyway.
|
||||
*/
|
||||
if (rc == 0 && (timeout == INFINITE || timeout >= 10)) {
|
||||
rc = poll_rest(handles, nhandles, fds, nfds, timeout);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Just polling for one thing, so no need to check first if
|
||||
* available immediately
|
||||
*/
|
||||
rc = poll_rest(handles, nhandles, fds, nfds, timeout);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
for (f = fds; f < &fds[nfds]; f++) {
|
||||
f->revents = 0;
|
||||
}
|
||||
errno = EBADF;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* _WIN32_WINNT */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
716
libssh/server.c
716
libssh/server.c
@@ -1,23 +1,25 @@
|
||||
/* server.c */
|
||||
/*
|
||||
Copyright 2004,2005 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* server.c - functions for creating a SSH server
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2004-2005 by Aris Adamantiadis
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup ssh_server SSH Server
|
||||
@@ -25,279 +27,489 @@ MA 02111-1307, USA. */
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#define SOCKOPT_TYPE_ARG4 char
|
||||
|
||||
/* We need to provide hstrerror. Not we can't call the parameter h_errno because it's #defined */
|
||||
inline char* hstrerror(int h_errno_val) {
|
||||
static char text[50];
|
||||
snprintf(text,sizeof(text),"gethostbyname error %d\n", h_errno_val);
|
||||
return text;
|
||||
}
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#define SOCKOPT_TYPE_ARG4 int
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/server.h"
|
||||
#include "libssh/ssh2.h"
|
||||
|
||||
// TODO: must use getaddrinfo
|
||||
static socket_t bind_socket(SSH_BIND *ssh_bind,char *hostname, int port) {
|
||||
struct sockaddr_in myaddr;
|
||||
int opt = 1;
|
||||
socket_t s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
struct hostent *hp=NULL;
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <winsock2.h>
|
||||
#define SOCKOPT_TYPE_ARG4 char
|
||||
|
||||
/* We need to provide hstrerror. Not we can't call the parameter h_errno because it's #defined */
|
||||
inline char *hstrerror(int h_errno_val) {
|
||||
static char text[50] = {0};
|
||||
|
||||
snprintf(text, sizeof(text), "gethostbyname error %d\n", h_errno_val);
|
||||
|
||||
return text;
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#define SOCKOPT_TYPE_ARG4 int
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* TODO FIXME: must use getaddrinfo */
|
||||
static socket_t bind_socket(SSH_BIND *ssh_bind, const char *hostname,
|
||||
int port) {
|
||||
struct sockaddr_in myaddr;
|
||||
struct hostent *hp=NULL;
|
||||
socket_t s;
|
||||
int opt = 1;
|
||||
|
||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL, "%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME
|
||||
hp=gethostbyname(hostname);
|
||||
hp = gethostbyname(hostname);
|
||||
#endif
|
||||
if(!hp){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"resolving %s: %s",hostname,hstrerror(h_errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&myaddr, 0, sizeof(myaddr));
|
||||
memcpy(&myaddr.sin_addr,hp->h_addr,hp->h_length);
|
||||
myaddr.sin_family=hp->h_addrtype;
|
||||
myaddr.sin_port = htons(port);
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
|
||||
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"Binding to %s:%d : %s",hostname,port,
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
if (hp == NULL) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL,
|
||||
"Resolving %s: %s", hostname, hstrerror(h_errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&myaddr, 0, sizeof(myaddr));
|
||||
memcpy(&myaddr.sin_addr, hp->h_addr, hp->h_length);
|
||||
myaddr.sin_family = hp->h_addrtype;
|
||||
myaddr.sin_port = htons(port);
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL,
|
||||
"Setting socket options failed: %s", hstrerror(h_errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL, "Binding to %s:%d: %s",
|
||||
hostname,
|
||||
port,
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
SSH_BIND *ssh_bind_new(){
|
||||
SSH_BIND *ptr=malloc(sizeof(SSH_BIND));
|
||||
memset(ptr,0,sizeof(*ptr));
|
||||
ptr->bindfd=-1;
|
||||
return ptr;
|
||||
SSH_BIND *ssh_bind_new(void) {
|
||||
SSH_BIND *ptr;
|
||||
|
||||
ptr = malloc(sizeof(SSH_BIND));
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(ptr);
|
||||
ptr->bindfd = -1;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options){
|
||||
ssh_bind->options=options;
|
||||
void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options) {
|
||||
ssh_bind->options = options;
|
||||
}
|
||||
|
||||
int ssh_bind_listen(SSH_BIND *ssh_bind){
|
||||
char *host;
|
||||
int fd;
|
||||
if(!ssh_bind->options)
|
||||
return -1;
|
||||
ssh_socket_init();
|
||||
host=ssh_bind->options->bindaddr;
|
||||
if(!host)
|
||||
host="0.0.0.0";
|
||||
fd=bind_socket(ssh_bind,host,ssh_bind->options->bindport);
|
||||
if(fd<0)
|
||||
return -1;
|
||||
ssh_bind->bindfd=fd;
|
||||
if(listen(fd,10)<0){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"listening to socket %d: %s",
|
||||
fd,strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
int ssh_bind_listen(SSH_BIND *ssh_bind) {
|
||||
const char *host;
|
||||
int fd;
|
||||
|
||||
if (ssh_bind->options == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_init() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
host = ssh_bind->options->bindaddr;
|
||||
if (host == NULL) {
|
||||
host = "0.0.0.0";
|
||||
}
|
||||
|
||||
fd = bind_socket(ssh_bind, host, ssh_bind->options->bindport);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
ssh_bind->bindfd = fd;
|
||||
|
||||
if (listen(fd, 10) < 0) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL,
|
||||
"Listening to socket %d: %s",
|
||||
fd, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking){
|
||||
ssh_bind->blocking=blocking?1:0;
|
||||
void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking) {
|
||||
ssh_bind->blocking = blocking ? 1 : 0;
|
||||
}
|
||||
|
||||
int ssh_bind_get_fd(SSH_BIND *ssh_bind){
|
||||
return ssh_bind->bindfd;
|
||||
socket_t ssh_bind_get_fd(SSH_BIND *ssh_bind) {
|
||||
return ssh_bind->bindfd;
|
||||
}
|
||||
|
||||
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind){
|
||||
ssh_bind->toaccept=1;
|
||||
void ssh_bind_set_fd(SSH_BIND *ssh_bind, socket_t fd) {
|
||||
ssh_bind->bindfd = fd;
|
||||
}
|
||||
|
||||
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind){
|
||||
SSH_SESSION *session;
|
||||
PRIVATE_KEY *dsa=NULL, *rsa=NULL;
|
||||
if(ssh_bind->bindfd<0){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"Can't accept new clients on a "
|
||||
"not bound socket.");
|
||||
return NULL;
|
||||
void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind) {
|
||||
ssh_bind->toaccept = 1;
|
||||
}
|
||||
|
||||
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind) {
|
||||
SSH_SESSION *session;
|
||||
PRIVATE_KEY *dsa = NULL;
|
||||
PRIVATE_KEY *rsa = NULL;
|
||||
int fd = -1;
|
||||
|
||||
if (ssh_bind->bindfd < 0) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL,
|
||||
"Can't accept new clients on a not bound socket.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ssh_bind->options->dsakey == NULL || ssh_bind->options->rsakey == NULL) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL,
|
||||
"DSA or RSA host key file must be set before accept()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ssh_bind->options->dsakey) {
|
||||
dsa = _privatekey_from_file(ssh_bind, ssh_bind->options->dsakey, TYPE_DSS);
|
||||
if (dsa == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if(!ssh_bind->options->dsakey && !ssh_bind->options->rsakey){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"DSA or RSA host key file must be set before accept()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ssh_bind->options->rsakey) {
|
||||
rsa = _privatekey_from_file(ssh_bind, ssh_bind->options->rsakey, TYPE_RSA);
|
||||
if (rsa == NULL) {
|
||||
privatekey_free(dsa);
|
||||
return NULL;
|
||||
}
|
||||
if(ssh_bind->options->dsakey){
|
||||
dsa=_privatekey_from_file(ssh_bind,ssh_bind->options->dsakey,TYPE_DSS);
|
||||
if(!dsa)
|
||||
return NULL;
|
||||
ssh_say(2,"Dsa private key read successfuly\n");
|
||||
}
|
||||
if(ssh_bind->options->rsakey){
|
||||
rsa=_privatekey_from_file(ssh_bind,ssh_bind->options->rsakey,TYPE_RSA);
|
||||
if(!rsa){
|
||||
if(dsa)
|
||||
private_key_free(dsa);
|
||||
return NULL;
|
||||
}
|
||||
ssh_say(2,"RSA private key read successfuly\n");
|
||||
}
|
||||
int fd=accept(ssh_bind->bindfd,NULL,NULL);
|
||||
if(fd<0){
|
||||
ssh_set_error(ssh_bind,SSH_FATAL,"Accepting a new connection: %s",
|
||||
strerror(errno));
|
||||
if(dsa)
|
||||
private_key_free(dsa);
|
||||
if(rsa)
|
||||
private_key_free(rsa);
|
||||
return NULL;
|
||||
}
|
||||
session=ssh_new();
|
||||
session->server=1;
|
||||
session->version=2;
|
||||
ssh_socket_free(session->socket);
|
||||
session->socket=ssh_socket_new(session);
|
||||
ssh_socket_set_fd(session->socket,fd);
|
||||
session->options=ssh_options_copy(ssh_bind->options);
|
||||
session->dsa_key=dsa;
|
||||
session->rsa_key=rsa;
|
||||
return session;
|
||||
}
|
||||
|
||||
fd = accept(ssh_bind->bindfd, NULL, NULL);
|
||||
if (fd < 0) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL,
|
||||
"Accepting a new connection: %s",
|
||||
strerror(errno));
|
||||
privatekey_free(dsa);
|
||||
privatekey_free(rsa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
session = ssh_new();
|
||||
if (session == NULL) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL, "Not enough space");
|
||||
privatekey_free(dsa);
|
||||
privatekey_free(rsa);
|
||||
return NULL;
|
||||
}
|
||||
session->server = 1;
|
||||
session->version = 2;
|
||||
session->options = ssh_options_copy(ssh_bind->options);
|
||||
if (session->options == NULL) {
|
||||
ssh_set_error(ssh_bind, SSH_FATAL, "No space left");
|
||||
privatekey_free(dsa);
|
||||
privatekey_free(rsa);
|
||||
ssh_cleanup(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_socket_free(session->socket);
|
||||
session->socket = ssh_socket_new(session);
|
||||
if (session->socket == NULL) {
|
||||
privatekey_free(dsa);
|
||||
privatekey_free(rsa);
|
||||
ssh_cleanup(session);
|
||||
return NULL;
|
||||
}
|
||||
ssh_socket_set_fd(session->socket,fd);
|
||||
session->dsa_key = dsa;
|
||||
session->rsa_key = rsa;
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
void ssh_bind_free(SSH_BIND *ssh_bind){
|
||||
if(ssh_bind->bindfd>=0)
|
||||
close(ssh_bind->bindfd);
|
||||
ssh_bind->bindfd=-1;
|
||||
if(ssh_bind->options)
|
||||
ssh_options_free(ssh_bind->options);
|
||||
free(ssh_bind);
|
||||
if (ssh_bind == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssh_bind->bindfd >= 0) {
|
||||
close(ssh_bind->bindfd);
|
||||
}
|
||||
ssh_bind->bindfd = -1;
|
||||
if (ssh_bind->options) {
|
||||
ssh_options_free(ssh_bind->options);
|
||||
}
|
||||
SAFE_FREE(ssh_bind);
|
||||
}
|
||||
|
||||
extern char *supported_methods[];
|
||||
|
||||
int server_set_kex(SSH_SESSION * session) {
|
||||
KEX *server = &session->server_kex;
|
||||
SSH_OPTIONS *options = session->options;
|
||||
int i;
|
||||
char *wanted;
|
||||
memset(server,0,sizeof(KEX));
|
||||
// the program might ask for a specific cookie to be sent. useful for server
|
||||
// debugging
|
||||
if (options->wanted_cookie)
|
||||
memcpy(server->cookie, options->wanted_cookie, 16);
|
||||
else
|
||||
ssh_get_random(server->cookie, 16,0);
|
||||
if(session->dsa_key && session->rsa_key){
|
||||
ssh_options_set_wanted_algos(options,SSH_HOSTKEYS,"ssh-dss,ssh-rsa");
|
||||
} else {
|
||||
if(session->dsa_key)
|
||||
ssh_options_set_wanted_algos(options,SSH_HOSTKEYS,"ssh-dss");
|
||||
else
|
||||
ssh_options_set_wanted_algos(options,SSH_HOSTKEYS,"ssh-rsa");
|
||||
static int server_set_kex(SSH_SESSION * session) {
|
||||
KEX *server = &session->server_kex;
|
||||
SSH_OPTIONS *options = session->options;
|
||||
int i, j;
|
||||
char *wanted;
|
||||
|
||||
ZERO_STRUCTP(server);
|
||||
/*
|
||||
* The program might ask for a specific cookie to be sent. Useful for server
|
||||
* debugging
|
||||
*/
|
||||
if (options->wanted_cookie) {
|
||||
memcpy(server->cookie, options->wanted_cookie, 16);
|
||||
} else {
|
||||
ssh_get_random(server->cookie, 16, 0);
|
||||
}
|
||||
|
||||
if (session->dsa_key != NULL && session->rsa_key != NULL) {
|
||||
if (ssh_options_set_wanted_algos(options, SSH_HOSTKEYS,
|
||||
"ssh-dss,ssh-rsa") < 0) {
|
||||
return -1;
|
||||
}
|
||||
server->methods = malloc(10 * sizeof(char **));
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (!(wanted = options->wanted_methods[i]))
|
||||
wanted = supported_methods[i];
|
||||
server->methods[i] = strdup(wanted);
|
||||
//printf("server->methods[%d]=%s\n",i,wanted);
|
||||
} else if (session->dsa_key != NULL) {
|
||||
if (ssh_options_set_wanted_algos(options, SSH_HOSTKEYS, "ssh-dss") < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
if (ssh_options_set_wanted_algos(options, SSH_HOSTKEYS, "ssh-rsa") < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
server->methods = malloc(10 * sizeof(char **));
|
||||
if (server->methods == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if ((wanted = options->wanted_methods[i]) == NULL) {
|
||||
wanted = supported_methods[i];
|
||||
}
|
||||
server->methods[i] = strdup(wanted);
|
||||
if (server->methods[i] == NULL) {
|
||||
for (j = i - 1; j <= 0; j--) {
|
||||
SAFE_FREE(server->methods[j]);
|
||||
}
|
||||
SAFE_FREE(server->methods);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dh_handshake_server(SSH_SESSION *session){
|
||||
STRING *e,*f,*pubkey,*sign;
|
||||
PUBLIC_KEY *pub;
|
||||
PRIVATE_KEY *prv;
|
||||
BUFFER *buf=buffer_new();
|
||||
if(packet_wait(session, SSH2_MSG_KEXDH_INIT ,1))
|
||||
return -1;
|
||||
e=buffer_get_ssh_string(session->in_buffer);
|
||||
if(!e){
|
||||
ssh_set_error(session,SSH_FATAL,"No e number in client request");
|
||||
return -1;
|
||||
}
|
||||
dh_import_e(session,e);
|
||||
free(e);
|
||||
dh_generate_y(session);
|
||||
dh_generate_f(session);
|
||||
f=dh_get_f(session);
|
||||
switch(session->hostkeys){
|
||||
case TYPE_DSS:
|
||||
prv=session->dsa_key;
|
||||
break;
|
||||
case TYPE_RSA:
|
||||
prv=session->rsa_key;
|
||||
break;
|
||||
default:
|
||||
prv=NULL;
|
||||
}
|
||||
pub=publickey_from_privatekey(prv);
|
||||
pubkey=publickey_to_string(pub);
|
||||
publickey_free(pub);
|
||||
dh_import_pubkey(session,pubkey);
|
||||
dh_build_k(session);
|
||||
make_sessionid(session);
|
||||
sign=ssh_sign_session_id(session,prv);
|
||||
buffer_free(buf);
|
||||
/* free private keys as they should not be readable past this point */
|
||||
if(session->rsa_key){
|
||||
private_key_free(session->rsa_key);
|
||||
session->rsa_key=NULL;
|
||||
}
|
||||
if(session->dsa_key){
|
||||
private_key_free(session->dsa_key);
|
||||
session->dsa_key=NULL;
|
||||
}
|
||||
buffer_add_u8(session->out_buffer,SSH2_MSG_KEXDH_REPLY);
|
||||
buffer_add_ssh_string(session->out_buffer,pubkey);
|
||||
buffer_add_ssh_string(session->out_buffer,f);
|
||||
buffer_add_ssh_string(session->out_buffer,sign);
|
||||
free(sign);
|
||||
packet_send(session);
|
||||
free(f);
|
||||
buffer_add_u8(session->out_buffer,SSH2_MSG_NEWKEYS);
|
||||
packet_send(session);
|
||||
ssh_say(2,"SSH_MSG_NEWKEYS sent\n");
|
||||
static int dh_handshake_server(SSH_SESSION *session) {
|
||||
STRING *e;
|
||||
STRING *f;
|
||||
STRING *pubkey;
|
||||
STRING *sign;
|
||||
PUBLIC_KEY *pub;
|
||||
PRIVATE_KEY *prv;
|
||||
|
||||
packet_wait(session,SSH2_MSG_NEWKEYS,1);
|
||||
ssh_say(2,"Got SSH_MSG_NEWKEYS\n");
|
||||
generate_session_keys(session);
|
||||
/* once we got SSH2_MSG_NEWKEYS we can switch next_crypto and current_crypto */
|
||||
if(session->current_crypto)
|
||||
crypto_free(session->current_crypto);
|
||||
/* XXX later, include a function to change keys */
|
||||
session->current_crypto=session->next_crypto;
|
||||
session->next_crypto=crypto_new();
|
||||
return 0;
|
||||
if (packet_wait(session, SSH2_MSG_KEXDH_INIT, 1) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = buffer_get_ssh_string(session->in_buffer);
|
||||
if (e == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "No e number in client request");
|
||||
return -1;
|
||||
}
|
||||
if (dh_import_e(session, e) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Cannot import e number");
|
||||
string_free(e);
|
||||
return -1;
|
||||
}
|
||||
string_free(e);
|
||||
|
||||
if (dh_generate_y(session) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create y number");
|
||||
return -1;
|
||||
}
|
||||
if (dh_generate_f(session) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create f number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
f = dh_get_f(session);
|
||||
if (f == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not get the f number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(session->hostkeys){
|
||||
case TYPE_DSS:
|
||||
prv = session->dsa_key;
|
||||
break;
|
||||
case TYPE_RSA:
|
||||
prv = session->rsa_key;
|
||||
break;
|
||||
default:
|
||||
prv = NULL;
|
||||
}
|
||||
|
||||
pub = publickey_from_privatekey(prv);
|
||||
if (pub == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Could not get the public key from the private key");
|
||||
string_free(f);
|
||||
return -1;
|
||||
}
|
||||
pubkey = publickey_to_string(pub);
|
||||
publickey_free(pub);
|
||||
if (pubkey == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
string_free(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dh_import_pubkey(session, pubkey);
|
||||
if (dh_build_k(session) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not import the public key");
|
||||
string_free(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (make_sessionid(session) != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||
string_free(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sign = ssh_sign_session_id(session, prv);
|
||||
if (sign == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
string_free(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Free private keys as they should not be readable after this point */
|
||||
if (session->rsa_key) {
|
||||
privatekey_free(session->rsa_key);
|
||||
session->rsa_key = NULL;
|
||||
}
|
||||
if (session->dsa_key) {
|
||||
privatekey_free(session->dsa_key);
|
||||
session->dsa_key = NULL;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 ||
|
||||
buffer_add_ssh_string(session->out_buffer, pubkey) < 0 ||
|
||||
buffer_add_ssh_string(session->out_buffer, f) < 0 ||
|
||||
buffer_add_ssh_string(session->out_buffer, sign) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
buffer_free(session->out_buffer);
|
||||
string_free(f);
|
||||
string_free(sign);
|
||||
return -1;
|
||||
}
|
||||
string_free(f);
|
||||
string_free(sign);
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||
buffer_free(session->out_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
|
||||
|
||||
if (packet_wait(session, SSH2_MSG_NEWKEYS, 1) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_PACKET, "Got SSH_MSG_NEWKEYS");
|
||||
|
||||
if (generate_session_keys(session) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and
|
||||
* current_crypto
|
||||
*/
|
||||
if (session->current_crypto) {
|
||||
crypto_free(session->current_crypto);
|
||||
}
|
||||
|
||||
/* FIXME TODO later, include a function to change keys */
|
||||
session->current_crypto = session->next_crypto;
|
||||
session->next_crypto = crypto_new();
|
||||
if (session->next_crypto == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* do the banner and key exchange */
|
||||
int ssh_accept(SSH_SESSION *session){
|
||||
ssh_send_banner(session,1);
|
||||
ssh_crypto_init();
|
||||
session->alive=1;
|
||||
session->clientbanner=ssh_get_banner(session);
|
||||
server_set_kex(session);
|
||||
ssh_send_kex(session,1);
|
||||
if(ssh_get_kex(session,1))
|
||||
return -1;
|
||||
ssh_list_kex(&session->client_kex);
|
||||
crypt_set_algorithms_server(session);
|
||||
if(dh_handshake_server(session))
|
||||
return -1;
|
||||
session->connected=1;
|
||||
return 0;
|
||||
|
||||
/* Do the banner and key exchange */
|
||||
int ssh_accept(SSH_SESSION *session) {
|
||||
if (ssh_send_banner(session, 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->alive = 1;
|
||||
|
||||
session->clientbanner = ssh_get_banner(session);
|
||||
if (session->clientbanner == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (server_set_kex(session) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_send_kex(session, 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_get_kex(session,1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_list_kex(session, &session->client_kex);
|
||||
crypt_set_algorithms_server(session);
|
||||
|
||||
if (dh_handshake_server(session) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->connected = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @}
|
||||
*/
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
361
libssh/session.c
361
libssh/session.c
@@ -1,10 +1,10 @@
|
||||
/* session.c */
|
||||
/* contains the non-networking functions ssh_* */
|
||||
/*
|
||||
* Copyright (c) 2005-2008 Aris Adamantiadis
|
||||
* session.c - non-networking functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005-2008 by Aris Adamantiadis
|
||||
*
|
||||
* 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
|
||||
@@ -18,7 +18,8 @@
|
||||
* 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. */
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -36,78 +37,118 @@
|
||||
/** \brief creates a new ssh session
|
||||
* \returns new ssh_session pointer
|
||||
*/
|
||||
SSH_SESSION *ssh_new() {
|
||||
SSH_SESSION *session=malloc(sizeof (SSH_SESSION));
|
||||
memset(session,0,sizeof(SSH_SESSION));
|
||||
session->next_crypto=crypto_new();
|
||||
session->maxchannel=FIRST_CHANNEL;
|
||||
session->socket=ssh_socket_new(session);
|
||||
session->alive=0;
|
||||
session->auth_methods=0;
|
||||
session->blocking=1;
|
||||
session->log_indent=0;
|
||||
session->out_buffer=buffer_new();
|
||||
session->in_buffer=buffer_new();
|
||||
SSH_SESSION *ssh_new(void) {
|
||||
SSH_SESSION *session;
|
||||
|
||||
session = malloc(sizeof (SSH_SESSION));
|
||||
if (session == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(session, 0, sizeof(SSH_SESSION));
|
||||
|
||||
session->next_crypto = crypto_new();
|
||||
if (session->next_crypto == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
session->maxchannel = FIRST_CHANNEL;
|
||||
session->socket = ssh_socket_new(session);
|
||||
if (session->socket == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
session->alive = 0;
|
||||
session->auth_methods = 0;
|
||||
session->blocking = 1;
|
||||
session->log_indent = 0;
|
||||
|
||||
session->out_buffer = buffer_new();
|
||||
if (session->out_buffer == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
session->in_buffer=buffer_new();
|
||||
if (session->in_buffer == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
session->agent = agent_new(session);
|
||||
if (session->agent == NULL) {
|
||||
goto err;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
return session;
|
||||
|
||||
err:
|
||||
ssh_cleanup(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ssh_cleanup(SSH_SESSION *session){
|
||||
enter_function();
|
||||
int i;
|
||||
if(session->serverbanner)
|
||||
free(session->serverbanner);
|
||||
if(session->clientbanner)
|
||||
free(session->clientbanner);
|
||||
if(session->in_buffer)
|
||||
buffer_free(session->in_buffer);
|
||||
if(session->out_buffer)
|
||||
buffer_free(session->out_buffer);
|
||||
if(session->banner)
|
||||
free(session->banner);
|
||||
if(session->options)
|
||||
ssh_options_free(session->options);
|
||||
if(session->current_crypto)
|
||||
crypto_free(session->current_crypto);
|
||||
if(session->next_crypto)
|
||||
crypto_free(session->next_crypto);
|
||||
if(session->socket)
|
||||
ssh_socket_free(session->socket);
|
||||
// delete all channels
|
||||
while(session->channels)
|
||||
channel_free(session->channels);
|
||||
if(session->client_kex.methods)
|
||||
for(i=0;i<10;i++)
|
||||
if(session->client_kex.methods[i])
|
||||
free(session->client_kex.methods[i]);
|
||||
if(session->server_kex.methods)
|
||||
for(i=0;i<10;++i)
|
||||
if(session->server_kex.methods[i])
|
||||
free(session->server_kex.methods[i]);
|
||||
free(session->client_kex.methods);
|
||||
free(session->server_kex.methods);
|
||||
if(session->dsa_key)
|
||||
private_key_free(session->dsa_key);
|
||||
if(session->rsa_key)
|
||||
private_key_free(session->rsa_key);
|
||||
if(session->ssh_message){
|
||||
ssh_message_free(session->ssh_message);
|
||||
free(session->ssh_message);
|
||||
void ssh_cleanup(SSH_SESSION *session) {
|
||||
int i;
|
||||
enter_function();
|
||||
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_FREE(session->serverbanner);
|
||||
SAFE_FREE(session->clientbanner);
|
||||
SAFE_FREE(session->banner);
|
||||
buffer_free(session->in_buffer);
|
||||
buffer_free(session->out_buffer);
|
||||
crypto_free(session->current_crypto);
|
||||
crypto_free(session->next_crypto);
|
||||
ssh_socket_free(session->socket);
|
||||
/* delete all channels */
|
||||
while (session->channels) {
|
||||
channel_free(session->channels);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
agent_free(session->agent);
|
||||
#endif /* _WIN32 */
|
||||
if (session->client_kex.methods) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
SAFE_FREE(session->client_kex.methods[i]);
|
||||
}
|
||||
memset(session,'X',sizeof(SSH_SESSION)); /* burn connection, it could hangs
|
||||
sensitive datas */
|
||||
free(session);
|
||||
//leave_function();
|
||||
}
|
||||
|
||||
if (session->server_kex.methods) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
SAFE_FREE(session->server_kex.methods[i]);
|
||||
}
|
||||
}
|
||||
SAFE_FREE(session->client_kex.methods);
|
||||
SAFE_FREE(session->server_kex.methods);
|
||||
|
||||
privatekey_free(session->dsa_key);
|
||||
privatekey_free(session->rsa_key);
|
||||
ssh_message_free(session->ssh_message);
|
||||
ssh_options_free(session->options);
|
||||
|
||||
/* burn connection, it could hang sensitive datas */
|
||||
memset(session,'X',sizeof(SSH_SESSION));
|
||||
|
||||
SAFE_FREE(session);
|
||||
/* FIXME: leave_function(); ??? */
|
||||
}
|
||||
|
||||
/** \brief disconnect impolitely from remote host
|
||||
* \param session current ssh session
|
||||
*/
|
||||
void ssh_silent_disconnect(SSH_SESSION *session){
|
||||
enter_function();
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
ssh_disconnect(session);
|
||||
//leave_function();
|
||||
void ssh_silent_disconnect(SSH_SESSION *session) {
|
||||
enter_function();
|
||||
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
ssh_disconnect(session);
|
||||
/* FIXME: leave_function(); ??? */
|
||||
}
|
||||
|
||||
/** \brief set the options for the current session
|
||||
@@ -116,9 +157,13 @@ void ssh_silent_disconnect(SSH_SESSION *session){
|
||||
* \see ssh_new()
|
||||
* \see ssh_options_new()
|
||||
*/
|
||||
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options){
|
||||
session->options=options;
|
||||
session->log_verbosity=options->log_verbosity;
|
||||
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options) {
|
||||
if (session == NULL || options == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
session->options = options;
|
||||
session->log_verbosity = options->log_verbosity;
|
||||
}
|
||||
|
||||
/** \brief set the session in blocking/nonblocking mode
|
||||
@@ -126,8 +171,12 @@ void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options){
|
||||
* \param blocking zero for nonblocking mode
|
||||
* \bug nonblocking code is in development and won't work as expected
|
||||
*/
|
||||
void ssh_set_blocking(SSH_SESSION *session,int blocking){
|
||||
session->blocking=blocking?1:0;
|
||||
void ssh_set_blocking(SSH_SESSION *session, int blocking) {
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
session->blocking = blocking ? 1 : 0;
|
||||
}
|
||||
|
||||
/** In case you'd need the file descriptor of the connection
|
||||
@@ -137,72 +186,109 @@ void ssh_set_blocking(SSH_SESSION *session,int blocking){
|
||||
* \return file descriptor of the connection, or -1 if it is
|
||||
* not connected
|
||||
*/
|
||||
socket_t ssh_get_fd(SSH_SESSION *session) {
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_t ssh_get_fd(SSH_SESSION *session){
|
||||
return ssh_socket_get_fd(session->socket);
|
||||
return ssh_socket_get_fd(session->socket);
|
||||
}
|
||||
|
||||
/** \brief say to the session it has data to read on the file descriptor without blocking
|
||||
* \param session ssh session
|
||||
*/
|
||||
void ssh_set_fd_toread(SSH_SESSION *session){
|
||||
ssh_socket_set_toread(session->socket);
|
||||
void ssh_set_fd_toread(SSH_SESSION *session) {
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_socket_set_toread(session->socket);
|
||||
}
|
||||
|
||||
/** \brief say the session it may write to the file descriptor without blocking
|
||||
* \param session ssh session
|
||||
*/
|
||||
void ssh_set_fd_towrite(SSH_SESSION *session){
|
||||
ssh_socket_set_towrite(session->socket);
|
||||
void ssh_set_fd_towrite(SSH_SESSION *session) {
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_socket_set_towrite(session->socket);
|
||||
}
|
||||
|
||||
/** \brief say the session it has an exception to catch on the file descriptor
|
||||
* \param session ssh session
|
||||
*/
|
||||
void ssh_set_fd_except(SSH_SESSION *session){
|
||||
ssh_socket_set_except(session->socket);
|
||||
void ssh_set_fd_except(SSH_SESSION *session) {
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_socket_set_except(session->socket);
|
||||
}
|
||||
|
||||
/** \warning I don't remember if this should be internal or not
|
||||
*/
|
||||
/* looks if there is data to read on the socket and parse it. */
|
||||
int ssh_handle_packets(SSH_SESSION *session){
|
||||
int w,err,r,i=0;
|
||||
enter_function();
|
||||
do {
|
||||
r=ssh_socket_poll(session->socket,&w,&err);
|
||||
if(r<=0){
|
||||
leave_function();
|
||||
return r; // error or no data available
|
||||
}
|
||||
/* if an exception happened, it will be trapped by packet_read() */
|
||||
if(packet_read(session)||packet_translate(session)){
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
packet_parse(session);
|
||||
++i;
|
||||
} while(r>0);
|
||||
leave_function();
|
||||
return r;
|
||||
int ssh_handle_packets(SSH_SESSION *session) {
|
||||
int w = 0;
|
||||
int e = 0;
|
||||
int rc = -1;
|
||||
|
||||
enter_function();
|
||||
|
||||
do {
|
||||
rc = ssh_socket_poll(session->socket, &w, &e);
|
||||
if (rc <= 0) {
|
||||
/* error or no data available */
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* if an exception happened, it will be trapped by packet_read() */
|
||||
if ((packet_read(session) != SSH_OK) ||
|
||||
(packet_translate(session) != SSH_OK)) {
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet_parse(session);
|
||||
} while(rc > 0);
|
||||
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** \brief get session status
|
||||
* \param session ssh session
|
||||
* \returns a bitmask including SSH_CLOSED, SSH_READ_PENDING or SSH_CLOSED_ERROR
|
||||
* which respectively means the session is closed, has data to read on the connection socket and session was closed due to an error
|
||||
/**
|
||||
* @brief Get session status
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @returns A bitmask including SSH_CLOSED, SSH_READ_PENDING or SSH_CLOSED_ERROR
|
||||
* which respectively means the session is closed, has data to read on
|
||||
* the connection socket and session was closed due to an error.
|
||||
*/
|
||||
int ssh_get_status(SSH_SESSION *session){
|
||||
int ret=0;
|
||||
int socketstate=ssh_socket_get_status(session->socket);
|
||||
if(session->closed)
|
||||
ret |= SSH_CLOSED;
|
||||
if(socketstate & SSH_READ_PENDING)
|
||||
ret |= SSH_READ_PENDING;
|
||||
if(session->closed && socketstate & SSH_CLOSED_ERROR)
|
||||
ret |= SSH_CLOSED_ERROR;
|
||||
return ret;
|
||||
int ssh_get_status(SSH_SESSION *session) {
|
||||
int socketstate;
|
||||
int r = 0;
|
||||
|
||||
if (session == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
socketstate = ssh_socket_get_status(session->socket);
|
||||
|
||||
if (session->closed) {
|
||||
r |= SSH_CLOSED;
|
||||
}
|
||||
if (socketstate & SSH_READ_PENDING) {
|
||||
r |= SSH_READ_PENDING;
|
||||
}
|
||||
if (session->closed && (socketstate & SSH_CLOSED_ERROR)) {
|
||||
r |= SSH_CLOSED_ERROR;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/** \brief get the disconnect message from the server
|
||||
@@ -210,28 +296,41 @@ int ssh_get_status(SSH_SESSION *session){
|
||||
* \return message sent by the server along with the disconnect, or NULL in which case the reason of the disconnect may be found with ssh_get_error.
|
||||
* \see ssh_get_error()
|
||||
*/
|
||||
const char *ssh_get_disconnect_message(SSH_SESSION *session){
|
||||
if(!session->closed)
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Connection not closed"
|
||||
" yet");
|
||||
else if(session->closed_by_except)
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Connection closed by "
|
||||
"socket error");
|
||||
else if(!session->discon_msg)
|
||||
ssh_set_error(session,SSH_FATAL,"Connection correctly closed but "
|
||||
"no disconnect message");
|
||||
else
|
||||
return session->discon_msg;
|
||||
const char *ssh_get_disconnect_message(SSH_SESSION *session) {
|
||||
if (session == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!session->closed) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Connection not closed yet");
|
||||
} else if(session->closed_by_except) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Connection closed by socket error");
|
||||
} else if(!session->discon_msg) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Connection correctly closed but no disconnect message");
|
||||
} else {
|
||||
return session->discon_msg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief get the protocol version of the session
|
||||
* \param session ssh session
|
||||
* \return 1 or 2, for ssh1 or ssh2
|
||||
/**
|
||||
* @brief Get the protocol version of the session.
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @return 1 or 2, for ssh1 or ssh2, < 0 on error.
|
||||
*/
|
||||
int ssh_get_version(SSH_SESSION *session){
|
||||
return session->version;
|
||||
int ssh_get_version(SSH_SESSION *session) {
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return session->version;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
3835
libssh/sftp.c
3835
libssh/sftp.c
File diff suppressed because it is too large
Load Diff
@@ -1,264 +1,489 @@
|
||||
/* sftpserver.c contains server based function for the sftp protocol */
|
||||
/*
|
||||
Copyright 2005 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* sftpserver.c - server based function for the sftp protocol
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/sftp.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/priv.h"
|
||||
|
||||
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp) {
|
||||
SFTP_PACKET *packet;
|
||||
SFTP_CLIENT_MESSAGE *msg;
|
||||
BUFFER *payload;
|
||||
STRING *tmp;
|
||||
|
||||
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp){
|
||||
SFTP_PACKET *packet=sftp_packet_read(sftp);
|
||||
SFTP_CLIENT_MESSAGE *msg=malloc(sizeof (SFTP_CLIENT_MESSAGE));
|
||||
BUFFER *payload;
|
||||
STRING *tmp;
|
||||
memset(msg,0,sizeof(SFTP_CLIENT_MESSAGE));
|
||||
if(!packet)
|
||||
msg = malloc(sizeof (SFTP_CLIENT_MESSAGE));
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(msg);
|
||||
|
||||
packet = sftp_packet_read(sftp);
|
||||
if (packet == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
payload = packet->payload;
|
||||
msg->type = packet->type;
|
||||
msg->sftp = sftp;
|
||||
|
||||
buffer_get_u32(payload, &msg->id);
|
||||
|
||||
switch(msg->type) {
|
||||
case SSH_FXP_CLOSE:
|
||||
case SSH_FXP_READDIR:
|
||||
msg->handle = buffer_get_ssh_string(payload);
|
||||
if (msg->handle == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
payload=packet->payload;
|
||||
ssh_say(2,"received sftp packet type %d\n",packet->type);
|
||||
msg->type=packet->type;
|
||||
msg->sftp=sftp;
|
||||
buffer_get_u32(payload,&msg->id);
|
||||
switch(msg->type){
|
||||
case SSH_FXP_CLOSE:
|
||||
case SSH_FXP_READDIR:
|
||||
msg->handle=buffer_get_ssh_string(payload);
|
||||
break;
|
||||
case SSH_FXP_READ:
|
||||
msg->handle=buffer_get_ssh_string(payload);
|
||||
buffer_get_u64(payload,&msg->offset);
|
||||
buffer_get_u32(payload,&msg->len);
|
||||
break;
|
||||
case SSH_FXP_WRITE:
|
||||
msg->handle=buffer_get_ssh_string(payload);
|
||||
buffer_get_u64(payload,&msg->offset);
|
||||
msg->data=buffer_get_ssh_string(payload);
|
||||
break;
|
||||
case SSH_FXP_REMOVE:
|
||||
case SSH_FXP_RMDIR:
|
||||
case SSH_FXP_OPENDIR:
|
||||
case SSH_FXP_READLINK:
|
||||
case SSH_FXP_REALPATH:
|
||||
tmp=buffer_get_ssh_string(payload);
|
||||
msg->filename=string_to_char(tmp);
|
||||
free(tmp);
|
||||
break;
|
||||
case SSH_FXP_RENAME:
|
||||
case SSH_FXP_SYMLINK:
|
||||
tmp=buffer_get_ssh_string(payload);
|
||||
msg->filename=string_to_char(tmp);
|
||||
free(tmp);
|
||||
msg->data=buffer_get_ssh_string(payload);
|
||||
break;
|
||||
case SSH_FXP_MKDIR:
|
||||
case SSH_FXP_SETSTAT:
|
||||
tmp=buffer_get_ssh_string(payload);
|
||||
msg->filename=string_to_char(tmp);
|
||||
free(tmp);
|
||||
msg->attr=sftp_parse_attr(sftp, payload,0);
|
||||
break;
|
||||
case SSH_FXP_FSETSTAT:
|
||||
msg->handle=buffer_get_ssh_string(payload);
|
||||
msg->attr=sftp_parse_attr(sftp, payload,0);
|
||||
break;
|
||||
case SSH_FXP_LSTAT:
|
||||
case SSH_FXP_STAT:
|
||||
tmp=buffer_get_ssh_string(payload);
|
||||
msg->filename=string_to_char(tmp);
|
||||
free(tmp);
|
||||
if(sftp->version >3)
|
||||
buffer_get_u32(payload,&msg->flags);
|
||||
break;
|
||||
case SSH_FXP_OPEN:
|
||||
tmp=buffer_get_ssh_string(payload);
|
||||
msg->filename=string_to_char(tmp);
|
||||
free(tmp);
|
||||
buffer_get_u32(payload,&msg->flags);
|
||||
msg->attr=sftp_parse_attr(sftp, payload,0);
|
||||
case SSH_FXP_FSTAT:
|
||||
msg->handle=buffer_get_ssh_string(payload);
|
||||
buffer_get_u32(payload,&msg->flags);
|
||||
break;
|
||||
default:
|
||||
printf("Received handled sftp message %d\n",msg->type);
|
||||
}
|
||||
msg->flags=ntohl(msg->flags);
|
||||
msg->offset=ntohll(msg->offset);
|
||||
msg->len=ntohl(msg->len);
|
||||
sftp_packet_free(packet);
|
||||
return msg;
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_READ:
|
||||
msg->handle = buffer_get_ssh_string(payload);
|
||||
if (msg->handle == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
buffer_get_u64(payload, &msg->offset);
|
||||
buffer_get_u32(payload, &msg->len);
|
||||
break;
|
||||
case SSH_FXP_WRITE:
|
||||
msg->handle = buffer_get_ssh_string(payload);
|
||||
if (msg->handle == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
buffer_get_u64(payload, &msg->offset);
|
||||
msg->data = buffer_get_ssh_string(payload);
|
||||
if (msg->data == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_REMOVE:
|
||||
case SSH_FXP_RMDIR:
|
||||
case SSH_FXP_OPENDIR:
|
||||
case SSH_FXP_READLINK:
|
||||
case SSH_FXP_REALPATH:
|
||||
tmp = buffer_get_ssh_string(payload);
|
||||
if (tmp == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->filename = string_to_char(tmp);
|
||||
string_free(tmp);
|
||||
if (msg->filename == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_RENAME:
|
||||
case SSH_FXP_SYMLINK:
|
||||
tmp = buffer_get_ssh_string(payload);
|
||||
if (tmp == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->filename = string_to_char(tmp);
|
||||
string_free(tmp);
|
||||
if (msg->filename == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->data = buffer_get_ssh_string(payload);
|
||||
if (msg->data == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_MKDIR:
|
||||
case SSH_FXP_SETSTAT:
|
||||
tmp = buffer_get_ssh_string(payload);
|
||||
if (tmp == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->filename=string_to_char(tmp);
|
||||
string_free(tmp);
|
||||
if (msg->filename == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->attr = sftp_parse_attr(sftp, payload, 0);
|
||||
if (msg->attr == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_FSETSTAT:
|
||||
msg->handle = buffer_get_ssh_string(payload);
|
||||
if (msg->handle == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->attr = sftp_parse_attr(sftp, payload, 0);
|
||||
if (msg->attr == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_LSTAT:
|
||||
case SSH_FXP_STAT:
|
||||
tmp = buffer_get_ssh_string(payload);
|
||||
if (tmp == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->filename = string_to_char(tmp);
|
||||
string_free(tmp);
|
||||
if (msg->filename == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
if(sftp->version > 3) {
|
||||
buffer_get_u32(payload,&msg->flags);
|
||||
}
|
||||
break;
|
||||
case SSH_FXP_OPEN:
|
||||
tmp=buffer_get_ssh_string(payload);
|
||||
if (tmp == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msg->filename = string_to_char(tmp);
|
||||
string_free(tmp);
|
||||
if (msg->filename == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
buffer_get_u32(payload,&msg->flags);
|
||||
msg->attr = sftp_parse_attr(sftp, payload, 0);
|
||||
if (msg->attr == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
case SSH_FXP_FSTAT:
|
||||
msg->handle = buffer_get_ssh_string(payload);
|
||||
if (msg->handle == NULL) {
|
||||
sftp_client_message_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
buffer_get_u32(payload, &msg->flags);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Received unhandled sftp message %d\n", msg->type);
|
||||
}
|
||||
|
||||
msg->flags = ntohl(msg->flags);
|
||||
msg->offset = ntohll(msg->offset);
|
||||
msg->len = ntohl(msg->len);
|
||||
sftp_packet_free(packet);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg){
|
||||
if(msg->filename)
|
||||
free(msg->filename);
|
||||
if(msg->data)
|
||||
free(msg->data);
|
||||
if(msg->attr)
|
||||
sftp_attributes_free(msg->attr);
|
||||
if(msg->handle)
|
||||
free(msg->handle);
|
||||
memset(msg,'X',sizeof(*msg));
|
||||
free(msg);
|
||||
void sftp_client_message_free(SFTP_CLIENT_MESSAGE *msg) {
|
||||
if (msg == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_FREE(msg->filename);
|
||||
string_free(msg->data);
|
||||
string_free(msg->handle);
|
||||
sftp_attributes_free(msg->attr);
|
||||
|
||||
ZERO_STRUCTP(msg);
|
||||
SAFE_FREE(msg);
|
||||
}
|
||||
|
||||
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, char *name, SFTP_ATTRIBUTES *attr){
|
||||
BUFFER *out=buffer_new();
|
||||
STRING *file=string_from_char(name);
|
||||
int r;
|
||||
buffer_add_u32(out,msg->id);
|
||||
buffer_add_u32(out,htonl(1));
|
||||
buffer_add_ssh_string(out,file);
|
||||
buffer_add_ssh_string(out,file); /* the protocol is broken here between 3 & 4 */
|
||||
free(file);
|
||||
buffer_add_attributes(out,attr);
|
||||
r=sftp_packet_write(msg->sftp,SSH_FXP_NAME,out);
|
||||
int sftp_reply_name(SFTP_CLIENT_MESSAGE *msg, const char *name,
|
||||
SFTP_ATTRIBUTES *attr) {
|
||||
BUFFER *out;
|
||||
STRING *file;
|
||||
|
||||
out = buffer_new();
|
||||
if (out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
file = string_from_char(name);
|
||||
if (file == NULL) {
|
||||
buffer_free(out);
|
||||
return r<0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(out, msg->id) < 0 ||
|
||||
buffer_add_u32(out, htonl(1)) < 0 ||
|
||||
buffer_add_ssh_string(out, file) < 0 ||
|
||||
buffer_add_ssh_string(out, file) < 0 || /* The protocol is broken here between 3 & 4 */
|
||||
buffer_add_attributes(out, attr) < 0 ||
|
||||
sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) {
|
||||
buffer_free(out);
|
||||
string_free(file);
|
||||
return -1;
|
||||
}
|
||||
buffer_free(out);
|
||||
string_free(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sftp_reply_handle(SFTP_CLIENT_MESSAGE *msg, STRING *handle){
|
||||
BUFFER *out=buffer_new();
|
||||
int r;
|
||||
buffer_add_u32(out,msg->id);
|
||||
buffer_add_ssh_string(out,handle);
|
||||
r=sftp_packet_write(msg->sftp,SSH_FXP_HANDLE,out);
|
||||
BUFFER *out;
|
||||
|
||||
out = buffer_new();
|
||||
if (out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(out, msg->id) < 0 ||
|
||||
buffer_add_ssh_string(out, handle) < 0 ||
|
||||
sftp_packet_write(msg->sftp, SSH_FXP_HANDLE, out) < 0) {
|
||||
buffer_free(out);
|
||||
return r<0;
|
||||
return -1;
|
||||
}
|
||||
buffer_free(out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sftp_reply_attr(SFTP_CLIENT_MESSAGE *msg, SFTP_ATTRIBUTES *attr){
|
||||
BUFFER *out=buffer_new();
|
||||
int r;
|
||||
buffer_add_u32(out,msg->id);
|
||||
buffer_add_attributes(out,attr);
|
||||
r=sftp_packet_write(msg->sftp,SSH_FXP_ATTRS,out);
|
||||
int sftp_reply_attr(SFTP_CLIENT_MESSAGE *msg, SFTP_ATTRIBUTES *attr) {
|
||||
BUFFER *out;
|
||||
|
||||
out = buffer_new();
|
||||
if (out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(out, msg->id) < 0 ||
|
||||
buffer_add_attributes(out, attr) < 0 ||
|
||||
sftp_packet_write(msg->sftp, SSH_FXP_ATTRS, out) < 0) {
|
||||
buffer_free(out);
|
||||
return r<0;
|
||||
return -1;
|
||||
}
|
||||
buffer_free(out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, char *file, char *longname,
|
||||
SFTP_ATTRIBUTES *attr){
|
||||
STRING *name=string_from_char(file);
|
||||
if(!msg->attrbuf)
|
||||
msg->attrbuf=buffer_new();
|
||||
buffer_add_ssh_string(msg->attrbuf,name);
|
||||
free(name);
|
||||
name=string_from_char(longname);
|
||||
buffer_add_ssh_string(msg->attrbuf,name);
|
||||
free(name);
|
||||
buffer_add_attributes(msg->attrbuf,attr);
|
||||
msg->attr_num++;
|
||||
return 0;
|
||||
int sftp_reply_names_add(SFTP_CLIENT_MESSAGE *msg, const char *file,
|
||||
const char *longname, SFTP_ATTRIBUTES *attr) {
|
||||
STRING *name;
|
||||
|
||||
name = string_from_char(file);
|
||||
if (name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->attrbuf == NULL) {
|
||||
msg->attrbuf = buffer_new();
|
||||
if (msg->attrbuf == NULL) {
|
||||
string_free(name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(msg->attrbuf, name) < 0) {
|
||||
string_free(name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
string_free(name);
|
||||
name = string_from_char(longname);
|
||||
if (name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_ssh_string(msg->attrbuf,name) < 0 ||
|
||||
buffer_add_attributes(msg->attrbuf,attr) < 0) {
|
||||
string_free(name);
|
||||
return -1;
|
||||
}
|
||||
string_free(name);
|
||||
msg->attr_num++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sftp_reply_names(SFTP_CLIENT_MESSAGE *msg){
|
||||
BUFFER *out=buffer_new();
|
||||
int r;
|
||||
buffer_add_u32(out,msg->id);
|
||||
buffer_add_u32(out,htonl(msg->attr_num));
|
||||
buffer_add_data(out,buffer_get(msg->attrbuf),
|
||||
buffer_get_len(msg->attrbuf));
|
||||
r=sftp_packet_write(msg->sftp,SSH_FXP_NAME,out);
|
||||
int sftp_reply_names(SFTP_CLIENT_MESSAGE *msg) {
|
||||
BUFFER *out;
|
||||
|
||||
out = buffer_new();
|
||||
if (out == NULL) {
|
||||
buffer_free(msg->attrbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(out, msg->id) < 0 ||
|
||||
buffer_add_u32(out, htonl(msg->attr_num)) < 0 ||
|
||||
buffer_add_data(out, buffer_get(msg->attrbuf),
|
||||
buffer_get_len(msg->attrbuf)) < 0 ||
|
||||
sftp_packet_write(msg->sftp, SSH_FXP_NAME, out) < 0) {
|
||||
buffer_free(out);
|
||||
buffer_free(msg->attrbuf);
|
||||
msg->attr_num=0;
|
||||
msg->attrbuf=NULL;
|
||||
return r<0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_free(out);
|
||||
buffer_free(msg->attrbuf);
|
||||
|
||||
msg->attr_num = 0;
|
||||
msg->attrbuf = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status, char *message){
|
||||
BUFFER *out=buffer_new();
|
||||
int r;
|
||||
STRING *s;
|
||||
buffer_add_u32(out,msg->id);
|
||||
buffer_add_u32(out,htonl(status));
|
||||
s=string_from_char(message?message:"");
|
||||
buffer_add_ssh_string(out,s);
|
||||
free(s);
|
||||
buffer_add_u32(out,0); // language string
|
||||
r=sftp_packet_write(msg->sftp,SSH_FXP_STATUS,out);
|
||||
int sftp_reply_status(SFTP_CLIENT_MESSAGE *msg, u32 status,
|
||||
const char *message) {
|
||||
BUFFER *out;
|
||||
STRING *s;
|
||||
|
||||
out = buffer_new();
|
||||
if (out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = string_from_char(message ? message : "");
|
||||
if (s == NULL) {
|
||||
buffer_free(out);
|
||||
return r<0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, void *data, int len){
|
||||
BUFFER *out=buffer_new();
|
||||
int r;
|
||||
buffer_add_u32(out,msg->id);
|
||||
buffer_add_u32(out,ntohl(len));
|
||||
buffer_add_data(out,data,len);
|
||||
r=sftp_packet_write(msg->sftp,SSH_FXP_DATA,out);
|
||||
if (buffer_add_u32(out, msg->id) < 0 ||
|
||||
buffer_add_u32(out, htonl(status)) < 0 ||
|
||||
buffer_add_ssh_string(out, s) < 0 ||
|
||||
buffer_add_u32(out, 0) < 0 || /* language string */
|
||||
sftp_packet_write(msg->sftp, SSH_FXP_STATUS, out) < 0) {
|
||||
buffer_free(out);
|
||||
return r<0;
|
||||
string_free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_free(out);
|
||||
string_free(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this function will return you a new handle to give the client.
|
||||
int sftp_reply_data(SFTP_CLIENT_MESSAGE *msg, const void *data, int len) {
|
||||
BUFFER *out;
|
||||
|
||||
out = buffer_new();
|
||||
if (out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(out, msg->id) < 0 ||
|
||||
buffer_add_u32(out, ntohl(len)) < 0 ||
|
||||
buffer_add_data(out, data, len) < 0 ||
|
||||
sftp_packet_write(msg->sftp, SSH_FXP_DATA, out) < 0) {
|
||||
buffer_free(out);
|
||||
return -1;
|
||||
}
|
||||
buffer_free(out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will return you a new handle to give the client.
|
||||
* the function accepts an info that can be retrieved later with
|
||||
* the handle. Care is given that a corrupted handle won't give a
|
||||
* valid info (or worse). */
|
||||
STRING *sftp_handle_alloc(SFTP_SESSION *sftp, void *info){
|
||||
int i;
|
||||
u32 val;
|
||||
STRING *ret;
|
||||
if(!sftp->handles){
|
||||
sftp->handles=malloc(sizeof(void *) * SFTP_HANDLES);
|
||||
memset(sftp->handles,0,sizeof(void *)*SFTP_HANDLES);
|
||||
* valid info (or worse).
|
||||
*/
|
||||
STRING *sftp_handle_alloc(SFTP_SESSION *sftp, void *info) {
|
||||
STRING *ret;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
if (sftp->handles == NULL) {
|
||||
sftp->handles = malloc(sizeof(void *) * SFTP_HANDLES);
|
||||
if (sftp->handles == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for(i=0; i<SFTP_HANDLES;++i)
|
||||
if(!sftp->handles[i])
|
||||
break;
|
||||
if(i==SFTP_HANDLES)
|
||||
return NULL; // no handle available
|
||||
val=i;
|
||||
ret=string_new(4);
|
||||
memcpy(ret->string,&val,sizeof(u32));
|
||||
sftp->handles[i]=info;
|
||||
return ret;
|
||||
memset(sftp->handles, 0, sizeof(void *) * SFTP_HANDLES);
|
||||
}
|
||||
|
||||
for (i = 0; i < SFTP_HANDLES; i++) {
|
||||
if (sftp->handles[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == SFTP_HANDLES) {
|
||||
return NULL; /* no handle available */
|
||||
}
|
||||
|
||||
val = i;
|
||||
ret = string_new(4);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(ret->string, &val, sizeof(u32));
|
||||
sftp->handles[i] = info;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *sftp_handle(SFTP_SESSION *sftp, STRING *handle){
|
||||
u32 val;
|
||||
if(!sftp->handles)
|
||||
return NULL;
|
||||
if(string_len(handle)!=sizeof(val))
|
||||
return NULL;
|
||||
memcpy(&val,handle->string,sizeof(u32));
|
||||
if(val>SFTP_HANDLES)
|
||||
return NULL;
|
||||
return sftp->handles[val];
|
||||
u32 val;
|
||||
|
||||
if (sftp->handles == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (string_len(handle) != sizeof(u32)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&val, handle->string, sizeof(u32));
|
||||
|
||||
if (val > SFTP_HANDLES) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sftp->handles[val];
|
||||
}
|
||||
|
||||
void sftp_handle_remove(SFTP_SESSION *sftp, void *handle){
|
||||
int i;
|
||||
for(i=0;i<SFTP_HANDLES;++i){
|
||||
if(sftp->handles[i]==handle){
|
||||
sftp->handles[i]=NULL;
|
||||
break;
|
||||
}
|
||||
void sftp_handle_remove(SFTP_SESSION *sftp, void *handle) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SFTP_HANDLES; i++) {
|
||||
if (sftp->handles[i] == handle) {
|
||||
sftp->handles[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
853
libssh/socket.c
853
libssh/socket.c
File diff suppressed because it is too large
Load Diff
175
libssh/string.c
175
libssh/string.c
@@ -1,27 +1,36 @@
|
||||
/*
|
||||
Copyright 2003-2008 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
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. */
|
||||
* string.c - ssh string functions
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/** \defgroup ssh_string SSH Strings
|
||||
* \brief string manipulations
|
||||
*/
|
||||
@@ -33,14 +42,37 @@ MA 02111-1307, USA. */
|
||||
* \param size size of the string
|
||||
* \return the newly allocated string
|
||||
*/
|
||||
STRING *string_new(unsigned int size){
|
||||
STRING *str=malloc(size + 4);
|
||||
str->size=htonl(size);
|
||||
return str;
|
||||
struct string_struct *string_new(size_t size) {
|
||||
struct string_struct *str = NULL;
|
||||
|
||||
str = malloc(size + 4);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str->size = htonl(size);
|
||||
return str;
|
||||
}
|
||||
|
||||
void string_fill(STRING *str, const void *data,int len){
|
||||
memcpy(str->string,data,len);
|
||||
/**
|
||||
* @brief Fill a string with given data. The string should be big enough.
|
||||
*
|
||||
* @param s An allocated string to fill with data.
|
||||
*
|
||||
* @param data The data to fill the string with.
|
||||
*
|
||||
* @param len Size of data.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int string_fill(struct string_struct *s, const void *data, size_t len) {
|
||||
if ((s == NULL) || (data == NULL) ||
|
||||
(len == 0) || (len > s->size)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(s->string, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,22 +81,31 @@ void string_fill(STRING *str, const void *data,int len){
|
||||
* \return the newly allocated string.
|
||||
* \warning The nul byte is not copied nor counted in the ouput string.
|
||||
*/
|
||||
STRING *string_from_char(const char *what){
|
||||
STRING *ptr;
|
||||
int len=strlen(what);
|
||||
ptr=malloc(4 + len);
|
||||
ptr->size=htonl(len);
|
||||
memcpy(ptr->string,what,len);
|
||||
return ptr;
|
||||
struct string_struct *string_from_char(const char *what) {
|
||||
struct string_struct *ptr = NULL;
|
||||
size_t len = strlen(what);
|
||||
|
||||
ptr = malloc(4 + len);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ptr->size = htonl(len);
|
||||
memcpy(ptr->string, what, len);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief returns the size of a SSH string
|
||||
* \param str the input SSH string
|
||||
* \return size of the content of str
|
||||
* \return size of the content of str, 0 on error
|
||||
*/
|
||||
int string_len(STRING *str){
|
||||
return ntohl(str->size);
|
||||
size_t string_len(struct string_struct *s) {
|
||||
if (s == NULL) {
|
||||
return ntohl(0);
|
||||
}
|
||||
|
||||
return ntohl(s->size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,38 +115,70 @@ int string_len(STRING *str){
|
||||
* \warning If the input SSH string contains zeroes, some parts of
|
||||
* the output string may not be readable with regular libc functions.
|
||||
*/
|
||||
char *string_to_char(STRING *str){
|
||||
int len=ntohl(str->size)+1;
|
||||
char *string=malloc(len);
|
||||
memcpy(string,str->string,len-1);
|
||||
string[len-1]=0;
|
||||
return string;
|
||||
char *string_to_char(struct string_struct *s) {
|
||||
size_t len = ntohl(s->size) + 1;
|
||||
char *new = malloc(len);
|
||||
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(new, s->string, len - 1);
|
||||
new[len - 1] = '\0';
|
||||
return new;
|
||||
}
|
||||
|
||||
STRING *string_copy(STRING *str){
|
||||
STRING *ret=malloc(ntohl(str->size)+4);
|
||||
ret->size=str->size;
|
||||
memcpy(ret->string,str->string,ntohl(str->size));
|
||||
return ret;
|
||||
/**
|
||||
* @brief Copy a string, return a newly allocated string. The caller has to
|
||||
* free the string.
|
||||
*
|
||||
* @param s String to copy.
|
||||
*
|
||||
* @return Newly allocated copy of the string, NULL on error.
|
||||
*/
|
||||
struct string_struct *string_copy(struct string_struct *s) {
|
||||
struct string_struct *new = malloc(ntohl(s->size) + 4);
|
||||
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->size = s->size;
|
||||
memcpy(new->string, s->string, ntohl(s->size));
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/** \brief destroy data in a string so it couldn't appear in a core dump
|
||||
* \param s string to burn
|
||||
*/
|
||||
void string_burn(STRING *s){
|
||||
memset(s->string,'X',string_len(s));
|
||||
void string_burn(struct string_struct *s) {
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
memset(s->string, 'X', string_len(s));
|
||||
}
|
||||
|
||||
void *string_data(STRING *s){
|
||||
return s->string;
|
||||
/**
|
||||
* @brief Get the payload of the string.
|
||||
*
|
||||
* @param s The string to get the data from.
|
||||
*
|
||||
* @return Return the data of the string or NULL on error.
|
||||
*/
|
||||
void *string_data(struct string_struct *s) {
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief deallocate a STRING object
|
||||
* \param s String to delete
|
||||
*/
|
||||
void string_free(STRING *s){
|
||||
free(s);
|
||||
void string_free(struct string_struct *s) {
|
||||
SAFE_FREE(s);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
1157
libssh/wrapper.c
1157
libssh/wrapper.c
File diff suppressed because it is too large
Load Diff
210
sample.c
210
sample.c
@@ -40,7 +40,7 @@ char *cmds[MAXCMD];
|
||||
struct termios terminal;
|
||||
void do_sftp(SSH_SESSION *session);
|
||||
|
||||
void add_cmd(char *cmd){
|
||||
static void add_cmd(char *cmd){
|
||||
int n;
|
||||
for(n=0;cmds[n] && (n<MAXCMD);n++);
|
||||
if(n==MAXCMD)
|
||||
@@ -48,17 +48,19 @@ void add_cmd(char *cmd){
|
||||
cmds[n]=strdup(cmd);
|
||||
}
|
||||
|
||||
void usage(){
|
||||
static void usage(){
|
||||
fprintf(stderr,"Usage : ssh [options] [login@]hostname\n"
|
||||
"sample client - libssh-%s\n"
|
||||
"Options :\n"
|
||||
" -l user : log in as user\n"
|
||||
" -p port : connect to port\n"
|
||||
" -d : use DSS to verify host public key\n"
|
||||
" -r : use RSA to verify host public key\n");
|
||||
" -r : use RSA to verify host public key\n",
|
||||
ssh_version(0));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int opts(int argc, char **argv){
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
if(strstr(argv[0],"sftp"))
|
||||
sftp=1;
|
||||
@@ -92,32 +94,42 @@ static void cfmakeraw(struct termios *termios_p){
|
||||
#endif
|
||||
|
||||
|
||||
void do_cleanup(){
|
||||
tcsetattr(0,TCSANOW,&terminal);
|
||||
static void do_cleanup(int i) {
|
||||
/* unused variable */
|
||||
(void) i;
|
||||
|
||||
tcsetattr(0,TCSANOW,&terminal);
|
||||
}
|
||||
void do_exit(){
|
||||
do_cleanup();
|
||||
exit(0);
|
||||
|
||||
static void do_exit(int i) {
|
||||
/* unused variable */
|
||||
(void) i;
|
||||
|
||||
do_cleanup(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
CHANNEL *chan;
|
||||
int signal_delayed=0;
|
||||
void setsignal();
|
||||
void sigwindowchanged(){
|
||||
signal_delayed=1;
|
||||
|
||||
static void sigwindowchanged(int i){
|
||||
(void) i;
|
||||
signal_delayed=1;
|
||||
}
|
||||
void sizechanged(){
|
||||
|
||||
static void setsignal(void){
|
||||
signal(SIGWINCH, sigwindowchanged);
|
||||
signal_delayed=0;
|
||||
}
|
||||
|
||||
static void sizechanged(void){
|
||||
struct winsize win = { 0, 0, 0, 0 };
|
||||
ioctl(1, TIOCGWINSZ, &win);
|
||||
channel_change_pty_size(chan,win.ws_col, win.ws_row);
|
||||
// printf("Changed pty size\n");
|
||||
setsignal();
|
||||
}
|
||||
void setsignal(){
|
||||
signal(SIGWINCH,sigwindowchanged);
|
||||
signal_delayed=0;
|
||||
}
|
||||
|
||||
void select_loop(SSH_SESSION *session,CHANNEL *channel){
|
||||
static void select_loop(SSH_SESSION *session,CHANNEL *channel){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
char buffer[10];
|
||||
@@ -168,32 +180,39 @@ void select_loop(SSH_SESSION *session,CHANNEL *channel){
|
||||
// we already looked for input from stdin. Now, we are looking for input from the channel
|
||||
|
||||
if(channel && channel_is_closed(channel)){
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
|
||||
channel_free(channel);
|
||||
channel=NULL;
|
||||
channels[0]=NULL;
|
||||
}
|
||||
if(channels[0]){
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
|
||||
lus=channel_read(channel,readbuf,0,0);
|
||||
lus=channel_read_buffer(channel,readbuf,0,0);
|
||||
if(lus==-1){
|
||||
ssh_say(0,"error reading channel : %s\n",ssh_get_error(session));
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_say(1,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
|
||||
channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
write(1,buffer_get(readbuf),lus);
|
||||
}
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
|
||||
lus=channel_read(channel,readbuf,0,1);
|
||||
lus=channel_read_buffer(channel,readbuf,0,1);
|
||||
if(lus==-1){
|
||||
ssh_say(0,"error reading channel : %s\n",ssh_get_error(session));
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_say(1,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
@@ -209,7 +228,7 @@ void select_loop(SSH_SESSION *session,CHANNEL *channel){
|
||||
}
|
||||
|
||||
|
||||
void shell(SSH_SESSION *session){
|
||||
static void shell(SSH_SESSION *session){
|
||||
CHANNEL *channel;
|
||||
struct termios terminal_local;
|
||||
int interactive=isatty(0);
|
||||
@@ -240,7 +259,7 @@ void shell(SSH_SESSION *session){
|
||||
select_loop(session,channel);
|
||||
}
|
||||
|
||||
void batch_shell(SSH_SESSION *session){
|
||||
static void batch_shell(SSH_SESSION *session){
|
||||
CHANNEL *channel;
|
||||
char buffer[1024];
|
||||
int i,s=0;
|
||||
@@ -254,10 +273,11 @@ void batch_shell(SSH_SESSION *session){
|
||||
}
|
||||
select_loop(session,channel);
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_SFTP
|
||||
/* it's just a proof of concept code for sftp, till i write a real documentation about it */
|
||||
void do_sftp(SSH_SESSION *session){
|
||||
SFTP_SESSION *sftp=sftp_new(session);
|
||||
SFTP_SESSION *sftp_session=sftp_new(session);
|
||||
SFTP_DIR *dir;
|
||||
SFTP_ATTRIBUTES *file;
|
||||
SFTP_FILE *fichier;
|
||||
@@ -265,62 +285,72 @@ void do_sftp(SSH_SESSION *session){
|
||||
int len=1;
|
||||
int i;
|
||||
char data[8000];
|
||||
if(!sftp){
|
||||
ssh_say(0,"sftp error initialising channel : %s\n",ssh_get_error(session));
|
||||
if(!sftp_session){
|
||||
fprintf(stderr, "sftp error initialising channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(sftp_init(sftp)){
|
||||
ssh_say(0,"error initialising sftp : %s\n",ssh_get_error(session));
|
||||
if(sftp_init(sftp_session)){
|
||||
fprintf(stderr, "error initialising sftp: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
/* the connection is made */
|
||||
/* opening a directory */
|
||||
dir=sftp_opendir(sftp,"./");
|
||||
dir=sftp_opendir(sftp_session,"./");
|
||||
if(!dir) {
|
||||
ssh_say(0,"Directory not opened(%s)\n",ssh_get_error(session));
|
||||
fprintf(stderr, "Directory not opened(%s)\n", ssh_get_error(session));
|
||||
return ;
|
||||
}
|
||||
/* reading the whole directory, file by file */
|
||||
while((file=sftp_readdir(sftp,dir))){
|
||||
ssh_say(0,"%30s(%.8lo) : %.5d.%.5d : %.10lld bytes\n",file->name,file->permissions,file->uid,file->gid,file->size);
|
||||
while((file=sftp_readdir(sftp_session,dir))){
|
||||
fprintf(stderr, "%30s(%.8o) : %.5d.%.5d : %.10llu bytes\n",
|
||||
file->name,
|
||||
file->permissions,
|
||||
file->uid,
|
||||
file->gid,
|
||||
(long long unsigned int) file->size);
|
||||
sftp_attributes_free(file);
|
||||
}
|
||||
/* when file=NULL, an error has occured OR the directory listing is end of file */
|
||||
if(!sftp_dir_eof(dir)){
|
||||
ssh_say(0,"error : %s\n",ssh_get_error(session));
|
||||
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(sftp_dir_close(dir)){
|
||||
ssh_say(0,"Error : %s\n",ssh_get_error(session));
|
||||
if(sftp_closedir(dir)){
|
||||
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
/* this will open a file and copy it into your /home directory */
|
||||
/* the small buffer size was intended to stress the library. of course, you can use a buffer till 20kbytes without problem */
|
||||
|
||||
fichier=sftp_open(sftp,"/usr/bin/ssh",O_RDONLY,NULL);
|
||||
fichier=sftp_open(sftp_session,"/usr/bin/ssh",O_RDONLY, 0);
|
||||
if(!fichier){
|
||||
ssh_say(0,"Error opening /usr/bin/ssh : %s\n",ssh_get_error(session));
|
||||
fprintf(stderr, "Error opening /usr/bin/ssh: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
/* open a file for writing... */
|
||||
to=sftp_open(sftp,"ssh-copy",O_WRONLY | O_CREAT,NULL);
|
||||
to=sftp_open(sftp_session,"ssh-copy",O_WRONLY | O_CREAT, 0);
|
||||
if(!to){
|
||||
ssh_say(0,"Error opening ssh-copy for writing : %s\n",ssh_get_error(session));
|
||||
fprintf(stderr, "Error opening ssh-copy for writing: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
while((len=sftp_read(fichier,data,4096)) > 0){
|
||||
if(sftp_write(to,data,len)!=len){
|
||||
ssh_say(0,"error writing %d bytes : %s\n",len,ssh_get_error(session));
|
||||
fprintf(stderr, "Error writing %d bytes: %s\n",
|
||||
len, ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("finished\n");
|
||||
if(len<0)
|
||||
ssh_say(0,"Error reading file : %s\n",ssh_get_error(session));
|
||||
sftp_file_close(fichier);
|
||||
sftp_file_close(to);
|
||||
printf("fichiers ferm<EFBFBD>\n");
|
||||
to=sftp_open(sftp,"/tmp/grosfichier",O_WRONLY|O_CREAT,NULL);
|
||||
fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session));
|
||||
sftp_close(fichier);
|
||||
sftp_close(to);
|
||||
printf("fichiers ferm\n");
|
||||
to=sftp_open(sftp_session,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644);
|
||||
for(i=0;i<1000;++i){
|
||||
len=sftp_write(to,data,8000);
|
||||
printf("wrote %d bytes\n",len);
|
||||
@@ -328,15 +358,17 @@ void do_sftp(SSH_SESSION *session){
|
||||
printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session));
|
||||
}
|
||||
}
|
||||
sftp_file_close(to);
|
||||
sftp_close(to);
|
||||
/* close the sftp session */
|
||||
sftp_free(sftp);
|
||||
sftp_free(sftp_session);
|
||||
printf("session sftp termin<69>\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int auth_kbdint(SSH_SESSION *session){
|
||||
static int auth_kbdint(SSH_SESSION *session){
|
||||
int err=ssh_userauth_kbdint(session,NULL,NULL);
|
||||
char *name,*instruction,*prompt,*ptr;
|
||||
const char *name, *instruction, *prompt;
|
||||
char *ptr;
|
||||
char buffer[128];
|
||||
int i,n;
|
||||
char echo;
|
||||
@@ -356,11 +388,15 @@ int auth_kbdint(SSH_SESSION *session){
|
||||
buffer[sizeof(buffer)-1]=0;
|
||||
if((ptr=strchr(buffer,'\n')))
|
||||
*ptr=0;
|
||||
ssh_userauth_kbdint_setanswer(session,i,buffer);
|
||||
if (ssh_userauth_kbdint_setanswer(session,i,buffer) < 0) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
memset(buffer,0,strlen(buffer));
|
||||
} else {
|
||||
ptr=getpass(prompt);
|
||||
ssh_userauth_kbdint_setanswer(session,i,ptr);
|
||||
if (ssh_userauth_kbdint_setanswer(session,i,ptr) < 0) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
err=ssh_userauth_kbdint(session,NULL,NULL);
|
||||
@@ -374,9 +410,11 @@ int main(int argc, char **argv){
|
||||
int auth=0;
|
||||
char *password;
|
||||
char *banner;
|
||||
char *hexa;
|
||||
int state;
|
||||
char buf[10];
|
||||
unsigned char hash[MD5_DIGEST_LEN];
|
||||
unsigned char *hash = NULL;
|
||||
int hlen;
|
||||
|
||||
options=ssh_options_new();
|
||||
if(ssh_options_getopt(options,&argc, argv)){
|
||||
@@ -384,10 +422,19 @@ int main(int argc, char **argv){
|
||||
usage();
|
||||
}
|
||||
opts(argc,argv);
|
||||
signal(SIGTERM,do_exit);
|
||||
if(user)
|
||||
ssh_options_set_username(options,user);
|
||||
ssh_options_set_host(options,host);
|
||||
signal(SIGTERM, do_exit);
|
||||
|
||||
if (user) {
|
||||
if (ssh_options_set_username(options,user) < 0) {
|
||||
ssh_options_free(options);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_options_set_host(options,host) < 0) {
|
||||
ssh_options_free(options);
|
||||
return 1;
|
||||
}
|
||||
session=ssh_new();
|
||||
ssh_set_options(session,options);
|
||||
if(ssh_connect(session)){
|
||||
@@ -397,13 +444,20 @@ int main(int argc, char **argv){
|
||||
return 1;
|
||||
}
|
||||
state=ssh_is_server_known(session);
|
||||
|
||||
hlen = ssh_get_pubkey_hash(session, &hash);
|
||||
if (hlen < 0) {
|
||||
ssh_disconnect(session);
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
switch(state){
|
||||
case SSH_SERVER_KNOWN_OK:
|
||||
break; /* ok */
|
||||
case SSH_SERVER_KNOWN_CHANGED:
|
||||
fprintf(stderr,"Host key for server changed : server's one is now :\n");
|
||||
ssh_get_pubkey_hash(session,hash);
|
||||
ssh_print_hexa("Public key hash",hash,MD5_DIGEST_LEN);
|
||||
ssh_print_hexa("Public key hash",hash, hlen);
|
||||
free(hash);
|
||||
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||
ssh_disconnect(session);
|
||||
ssh_finalize();
|
||||
@@ -416,10 +470,15 @@ int main(int argc, char **argv){
|
||||
ssh_disconnect(session);
|
||||
ssh_finalize();
|
||||
exit(-1);
|
||||
case SSH_SERVER_FILE_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 behaviour */
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
hexa = ssh_get_hexa(hash, hlen);
|
||||
fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");
|
||||
ssh_get_pubkey_hash(session,hash);
|
||||
ssh_print_hexa("Public key hash",hash,MD5_DIGEST_LEN);
|
||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||
free(hexa);
|
||||
fgets(buf,sizeof(buf),stdin);
|
||||
if(strncasecmp(buf,"yes",3)!=0){
|
||||
ssh_disconnect(session);
|
||||
@@ -428,17 +487,22 @@ int main(int argc, char **argv){
|
||||
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||
fgets(buf,sizeof(buf),stdin);
|
||||
if(strncasecmp(buf,"yes",3)==0){
|
||||
if(ssh_write_knownhost(session))
|
||||
fprintf(stderr,"error %s\n",ssh_get_error(session));
|
||||
if (ssh_write_knownhost(session) < 0) {
|
||||
free(hash);
|
||||
fprintf(stderr, "error %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case SSH_SERVER_ERROR:
|
||||
free(hash);
|
||||
fprintf(stderr,"%s",ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
ssh_finalize();
|
||||
exit(-1);
|
||||
}
|
||||
free(hash);
|
||||
|
||||
ssh_userauth_none(session, NULL);
|
||||
|
||||
@@ -454,7 +518,7 @@ int main(int argc, char **argv){
|
||||
printf("\n");
|
||||
|
||||
/* no ? you should :) */
|
||||
auth=ssh_userauth_autopubkey(session);
|
||||
auth=ssh_userauth_autopubkey(session, NULL);
|
||||
if(auth==SSH_AUTH_ERROR){
|
||||
fprintf(stderr,"Authenticating with pubkey: %s\n",ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
@@ -484,10 +548,10 @@ int main(int argc, char **argv){
|
||||
}
|
||||
memset(password,0,strlen(password));
|
||||
}
|
||||
ssh_say(1,"Authentication success\n");
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
|
||||
if(strstr(argv[0],"sftp")){
|
||||
sftp=1;
|
||||
ssh_say(1,"doing sftp instead\n");
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Doing sftp instead");
|
||||
}
|
||||
if(!sftp){
|
||||
if(!cmds[0])
|
||||
@@ -495,10 +559,12 @@ int main(int argc, char **argv){
|
||||
else
|
||||
batch_shell(session);
|
||||
}
|
||||
#ifdef WITH_SFTP
|
||||
else
|
||||
do_sftp(session);
|
||||
do_sftp(session);
|
||||
#endif
|
||||
if(!sftp && !cmds[0])
|
||||
do_cleanup();
|
||||
do_cleanup(0);
|
||||
ssh_disconnect(session);
|
||||
ssh_finalize();
|
||||
|
||||
|
||||
13
samplesshd.c
13
samplesshd.c
@@ -31,7 +31,7 @@ MA 02111-1307, USA. */
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
|
||||
int auth_password(char *user, char *password){
|
||||
static int auth_password(char *user, char *password){
|
||||
if(strcmp(user,"aris"))
|
||||
return 0;
|
||||
if(strcmp(password,"lala"))
|
||||
@@ -45,6 +45,7 @@ int main(int argc, char **argv){
|
||||
SSH_BIND *ssh_bind;
|
||||
SSH_MESSAGE *message;
|
||||
CHANNEL *chan=0;
|
||||
BUFFER *buf;
|
||||
int auth=0;
|
||||
int sftp=0;
|
||||
int i;
|
||||
@@ -62,9 +63,9 @@ int main(int argc, char **argv){
|
||||
printf("error accepting a connection : %s\n",ssh_get_error(ssh_bind));
|
||||
return 1;
|
||||
}
|
||||
printf("Socket connecté : %d\n",ssh_get_fd(session));
|
||||
printf("Socket connected: fd = %d\n", ssh_get_fd(session));
|
||||
if(ssh_accept(session)){
|
||||
printf("ssh_accept : %s\n",ssh_get_error(session));
|
||||
printf("ssh_accept: %s\n",ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
@@ -98,7 +99,7 @@ int main(int argc, char **argv){
|
||||
ssh_message_free(message);
|
||||
} while (!auth);
|
||||
if(!auth){
|
||||
printf("error : %s\n",ssh_get_error(session));
|
||||
printf("auth error: %s\n",ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
@@ -142,9 +143,9 @@ int main(int argc, char **argv){
|
||||
return 1;
|
||||
}
|
||||
printf("it works !\n");
|
||||
BUFFER *buf=buffer_new();
|
||||
buf=buffer_new();
|
||||
do{
|
||||
i=channel_read(chan,buf,0,0);
|
||||
i=channel_read_buffer(chan,buf,0,0);
|
||||
if(i>0)
|
||||
write(1,buffer_get(buf),buffer_get_len(buf));
|
||||
} while (i>0);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
all: test_tunnel
|
||||
all: test_tunnel test_exec
|
||||
CFLAGS=-I../include/ -g -Wall
|
||||
LDFLAGS=-lssh -L../libssh/.libs
|
||||
LDFLAGS=-lssh -L../build/libssh/
|
||||
|
||||
test_tunnel: test_tunnel.o authentication.o connection.o
|
||||
gcc -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_exec: test_exec.o authentication.o connection.o
|
||||
gcc -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o test_tunnel
|
||||
|
||||
@@ -47,7 +47,7 @@ static int auth_kbdint(SSH_SESSION *session){
|
||||
}
|
||||
|
||||
int authenticate (SSH_SESSION *session){
|
||||
int auth=ssh_userauth_autopubkey(session);
|
||||
int auth=ssh_userauth_autopubkey(session, NULL);
|
||||
char *password;
|
||||
if(auth==SSH_AUTH_ERROR){
|
||||
fprintf(stderr,"Authenticating with pubkey: %s\n",ssh_get_error(session));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user