mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-05 21:00:33 +09:00
Compare commits
1806 Commits
v0-2
...
libssh-0.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e27b31c9c4 | ||
|
|
684b7f6a57 | ||
|
|
b0b2fd768c | ||
|
|
9180bfffcd | ||
|
|
058bb0f4ea | ||
|
|
64b125700e | ||
|
|
6f650a61ca | ||
|
|
d4e95f4653 | ||
|
|
26be91fb8e | ||
|
|
43a3becf08 | ||
|
|
d127d68b9f | ||
|
|
730da3e3c2 | ||
|
|
661722753b | ||
|
|
ac445a1e18 | ||
|
|
b7a3d41baf | ||
|
|
096475b356 | ||
|
|
d08554dabd | ||
|
|
cbe8f8b760 | ||
|
|
8987bc53e0 | ||
|
|
39802b31fe | ||
|
|
e5a2aef1bf | ||
|
|
edb03bd224 | ||
|
|
1204f43ea9 | ||
|
|
b542bc9e4e | ||
|
|
61a97ccede | ||
|
|
a1ef27c0b8 | ||
|
|
fb8f2cd11b | ||
|
|
1d8a9ddf84 | ||
|
|
bea66b6476 | ||
|
|
a8111934d5 | ||
|
|
f201e983b0 | ||
|
|
81332e1e27 | ||
|
|
ea84f50603 | ||
|
|
ccc94e7ab6 | ||
|
|
4c05be0c1b | ||
|
|
a493a90c59 | ||
|
|
4a18df8574 | ||
|
|
cfa74c1dc6 | ||
|
|
de706de8c3 | ||
|
|
71fa0dc6bb | ||
|
|
914a2d8e41 | ||
|
|
956b64d348 | ||
|
|
91489cd378 | ||
|
|
615bc3b8f7 | ||
|
|
5b645419fd | ||
|
|
c436e07022 | ||
|
|
188fb37801 | ||
|
|
44fed3eb9b | ||
|
|
36abd82a7e | ||
|
|
fd6d0b6897 | ||
|
|
09b0018b93 | ||
|
|
2624e603d4 | ||
|
|
fd61eda16d | ||
|
|
a6dda5fefd | ||
|
|
da8356b477 | ||
|
|
e5fb20c17b | ||
|
|
c472bd7437 | ||
|
|
8796756ae5 | ||
|
|
9c8f285a98 | ||
|
|
8154e24027 | ||
|
|
629cfbccc4 | ||
|
|
c5990791db | ||
|
|
16241938af | ||
|
|
6a8cb38dd3 | ||
|
|
bac2227ee2 | ||
|
|
dcb50cc0c8 | ||
|
|
f503c4a3e1 | ||
|
|
a56c925da9 | ||
|
|
833cc00014 | ||
|
|
09e8cf33d7 | ||
|
|
a03bb2fbf7 | ||
|
|
bb784ec6be | ||
|
|
996c00c81c | ||
|
|
30bdca07e9 | ||
|
|
b4b49cf3f6 | ||
|
|
189796e94f | ||
|
|
2431c7d925 | ||
|
|
fc9c61714f | ||
|
|
e096658df3 | ||
|
|
b1d58c5454 | ||
|
|
ced66eb11f | ||
|
|
1b44daddf6 | ||
|
|
a309c1b38e | ||
|
|
e56aaf5f44 | ||
|
|
632cee4426 | ||
|
|
af25fc35d1 | ||
|
|
db49b84a44 | ||
|
|
c5f4b8c1c7 | ||
|
|
6a0daddd8f | ||
|
|
af997b221d | ||
|
|
9d6855702e | ||
|
|
daf256e15f | ||
|
|
0eddcb4424 | ||
|
|
b7f6794e03 | ||
|
|
cd9fc88151 | ||
|
|
fbe0f37e1b | ||
|
|
c496194614 | ||
|
|
ca639ceb63 | ||
|
|
e85537aac4 | ||
|
|
e839c9cae6 | ||
|
|
100e94c18e | ||
|
|
e7f7b4e499 | ||
|
|
eca8b53868 | ||
|
|
b8767be373 | ||
|
|
9658eade0b | ||
|
|
689536ec92 | ||
|
|
3ff2999228 | ||
|
|
4f65104ecc | ||
|
|
242e1c342c | ||
|
|
935e3b70ae | ||
|
|
8d1bfb5a85 | ||
|
|
2ac664968d | ||
|
|
1199ad8f47 | ||
|
|
c12559f8f6 | ||
|
|
840e1abcdc | ||
|
|
e3594ba0ec | ||
|
|
0d07dc5355 | ||
|
|
4170258595 | ||
|
|
dacfc41d21 | ||
|
|
5158877b72 | ||
|
|
a785ba3c4d | ||
|
|
92dbd4eca2 | ||
|
|
a7144c5b6b | ||
|
|
5a8a2a56af | ||
|
|
d464b57fa5 | ||
|
|
c950ed3b4c | ||
|
|
5144f390ca | ||
|
|
f5e2c94ae3 | ||
|
|
8078d4f674 | ||
|
|
ac785e0aa3 | ||
|
|
541519e563 | ||
|
|
58feb0c983 | ||
|
|
72e08d5dd9 | ||
|
|
f812ace256 | ||
|
|
057704c097 | ||
|
|
92f20ec85a | ||
|
|
a26194ece0 | ||
|
|
22b1e5bc7c | ||
|
|
38d6d38c1f | ||
|
|
215c41710e | ||
|
|
97d261dc79 | ||
|
|
892ebf35f1 | ||
|
|
05cd7296ba | ||
|
|
93a2d79459 | ||
|
|
30e4096c66 | ||
|
|
03b387cf47 | ||
|
|
131e3b968f | ||
|
|
4bf8ee8032 | ||
|
|
63c42f066f | ||
|
|
9e40e60bc4 | ||
|
|
8f850585dd | ||
|
|
4b07157fc6 | ||
|
|
867944b939 | ||
|
|
b0c2be25a6 | ||
|
|
c1ecec7cda | ||
|
|
00d68d63fa | ||
|
|
5d87ca94a8 | ||
|
|
1e827a8e81 | ||
|
|
20e637968a | ||
|
|
5c581f8a4c | ||
|
|
d67cbdc926 | ||
|
|
a63dbc07f3 | ||
|
|
6a3cd6c20f | ||
|
|
8a9ce6239a | ||
|
|
f3685f0f73 | ||
|
|
50a119dd0a | ||
|
|
8abdaa7abf | ||
|
|
80ef7d9304 | ||
|
|
84df46f805 | ||
|
|
460d43f050 | ||
|
|
625692f4c5 | ||
|
|
0e2bbdd25b | ||
|
|
6b52aaff1c | ||
|
|
227764a803 | ||
|
|
624676b1cc | ||
|
|
a236a15c6c | ||
|
|
cb775092bc | ||
|
|
8d7d313498 | ||
|
|
c6e1792696 | ||
|
|
90fc5554e1 | ||
|
|
e579dfb342 | ||
|
|
0c93914948 | ||
|
|
670dd17044 | ||
|
|
b945cbca52 | ||
|
|
f8361d324e | ||
|
|
0b46f68c5f | ||
|
|
2917e71aad | ||
|
|
551b87b65b | ||
|
|
5b6f048197 | ||
|
|
a17472ff2b | ||
|
|
7fbb926c0b | ||
|
|
bb5f5281c0 | ||
|
|
9140242cbe | ||
|
|
bcea8921ba | ||
|
|
076dfb8294 | ||
|
|
d631ce32ed | ||
|
|
4439d5c774 | ||
|
|
ac6278feb7 | ||
|
|
d1e1103198 | ||
|
|
4f83918109 | ||
|
|
6b27966c9c | ||
|
|
a016d356fa | ||
|
|
61852635b5 | ||
|
|
184f1e1706 | ||
|
|
dfa01d0862 | ||
|
|
82547867eb | ||
|
|
7d9f889911 | ||
|
|
13ece2a2f8 | ||
|
|
e57d5a45b9 | ||
|
|
ec12da273e | ||
|
|
fdffa42c02 | ||
|
|
d679d5d7ef | ||
|
|
2464a25de7 | ||
|
|
e12253168c | ||
|
|
1540dad17f | ||
|
|
350838d1b5 | ||
|
|
f23880ddee | ||
|
|
be3e5c35cf | ||
|
|
73c0cd050e | ||
|
|
c54d6b7f8a | ||
|
|
2b6fa19fe5 | ||
|
|
3f538b3ddd | ||
|
|
2faaefade9 | ||
|
|
ef1866db76 | ||
|
|
d4072082d0 | ||
|
|
a7237e8cea | ||
|
|
bc2db562e5 | ||
|
|
93ce8e8ffd | ||
|
|
98bacf032f | ||
|
|
e795dae8f2 | ||
|
|
459fa3734f | ||
|
|
52d6b7b914 | ||
|
|
5331489581 | ||
|
|
2945a42c75 | ||
|
|
1f47730a82 | ||
|
|
1b88542fbe | ||
|
|
530629c5a7 | ||
|
|
98b5f07631 | ||
|
|
f46bf41813 | ||
|
|
8e632b14d1 | ||
|
|
4728ac54fc | ||
|
|
da86340551 | ||
|
|
fc8fdcb16b | ||
|
|
be68cfe923 | ||
|
|
cb48057098 | ||
|
|
ef91ac4ea0 | ||
|
|
1646ce970c | ||
|
|
08906e0f7f | ||
|
|
887d201bd3 | ||
|
|
1267240810 | ||
|
|
296767afc4 | ||
|
|
13f3679b2f | ||
|
|
f3a6c3152c | ||
|
|
80d7ccb522 | ||
|
|
78abf5a88d | ||
|
|
ad231ccd30 | ||
|
|
d4a6c27a83 | ||
|
|
e7a06ad3b4 | ||
|
|
d2bf90c982 | ||
|
|
69ac51dfaa | ||
|
|
3e2f714248 | ||
|
|
530c17e2ef | ||
|
|
31043334f4 | ||
|
|
361e37dc66 | ||
|
|
df55918a41 | ||
|
|
e6329c72d1 | ||
|
|
8bd29736d2 | ||
|
|
0b2cf70622 | ||
|
|
b0446ad55d | ||
|
|
d04ce30b03 | ||
|
|
512b776245 | ||
|
|
d44919dfd4 | ||
|
|
99d45c686c | ||
|
|
2bc03d22a1 | ||
|
|
fa17f33d2b | ||
|
|
400fc350a7 | ||
|
|
6f65e6ae67 | ||
|
|
635a263f64 | ||
|
|
17f592d4dd | ||
|
|
7dc183126a | ||
|
|
4fe1656cf8 | ||
|
|
a883330101 | ||
|
|
f0d811edc6 | ||
|
|
438083542d | ||
|
|
4fa2e4dde1 | ||
|
|
32c0e1c99a | ||
|
|
b4c62ac9ea | ||
|
|
a0e98f585a | ||
|
|
7c728acd12 | ||
|
|
38b87aab08 | ||
|
|
33c41074a7 | ||
|
|
936c65f03e | ||
|
|
825581d0dc | ||
|
|
942b993f57 | ||
|
|
e6bc4b4ff9 | ||
|
|
04e224c3b4 | ||
|
|
19ab9a015f | ||
|
|
94fe52870b | ||
|
|
55470aaaf1 | ||
|
|
6a26335158 | ||
|
|
256e88690d | ||
|
|
3a94c94f20 | ||
|
|
473d3e0b3a | ||
|
|
d5df18a14f | ||
|
|
bffaa86664 | ||
|
|
1922341e2a | ||
|
|
bcfab67daf | ||
|
|
27f170011e | ||
|
|
5cb4c9451f | ||
|
|
80408d5357 | ||
|
|
47d11734e1 | ||
|
|
14d6b8856f | ||
|
|
48e4df4ac0 | ||
|
|
f5d0f232c8 | ||
|
|
d6a5e5cb68 | ||
|
|
751f202f56 | ||
|
|
37eeb854e4 | ||
|
|
57d752a1c3 | ||
|
|
ef1cfbea70 | ||
|
|
038c764055 | ||
|
|
3ea33f9ab6 | ||
|
|
1758c172a2 | ||
|
|
2a6cbed121 | ||
|
|
92fc2d6993 | ||
|
|
2dba4839ad | ||
|
|
0825abd03a | ||
|
|
f58441f474 | ||
|
|
0e82cdeadc | ||
|
|
b6901ec4b9 | ||
|
|
ea4aa26dbb | ||
|
|
98221f4e36 | ||
|
|
8e2699e161 | ||
|
|
01eb20e13f | ||
|
|
b129181809 | ||
|
|
3253ece2a2 | ||
|
|
4b462449cf | ||
|
|
4f8907a524 | ||
|
|
7b1359042c | ||
|
|
da9cd2e64d | ||
|
|
5d1636985b | ||
|
|
088b86d4fe | ||
|
|
9a89fba332 | ||
|
|
0bc032726d | ||
|
|
b2f571e544 | ||
|
|
338a3d9b05 | ||
|
|
5687d6e79a | ||
|
|
a9ec8b055f | ||
|
|
5f69d494ad | ||
|
|
3d8cfa9973 | ||
|
|
0d5cc01f1c | ||
|
|
d7581c4daa | ||
|
|
524302ca7e | ||
|
|
2617024136 | ||
|
|
26d40b5354 | ||
|
|
c4356531f7 | ||
|
|
873e02fc6a | ||
|
|
985db35173 | ||
|
|
c4e67730a3 | ||
|
|
9f7e2c3252 | ||
|
|
5675fbe73e | ||
|
|
5b1c985a0e | ||
|
|
bedc65313f | ||
|
|
9f53906209 | ||
|
|
be837cdbc2 | ||
|
|
38359672a5 | ||
|
|
1b471256d4 | ||
|
|
30e22fed6e | ||
|
|
8b719e51cf | ||
|
|
72b62d3064 | ||
|
|
5f24a84298 | ||
|
|
1eaf55c5f6 | ||
|
|
9d3b84c914 | ||
|
|
b391a7603a | ||
|
|
45b551d4f7 | ||
|
|
15e4ec38f2 | ||
|
|
8c318fcb21 | ||
|
|
a2fe4b2b2c | ||
|
|
e36c9c529b | ||
|
|
41c4e1f5c8 | ||
|
|
75a0281a6b | ||
|
|
a92545517a | ||
|
|
fe31fcaeef | ||
|
|
f7ea9a3f27 | ||
|
|
b0c03280d1 | ||
|
|
5eb7c7b6ec | ||
|
|
b7af2b2959 | ||
|
|
9f02a817ff | ||
|
|
6345afabf8 | ||
|
|
899db7cf22 | ||
|
|
f45dc29eb2 | ||
|
|
d2f38da094 | ||
|
|
697d51cd93 | ||
|
|
f9b0dca7bd | ||
|
|
03087e020c | ||
|
|
4f75fdcd14 | ||
|
|
031c06419b | ||
|
|
254a08f540 | ||
|
|
76ead916ce | ||
|
|
ab2dafc44a | ||
|
|
325cc4e395 | ||
|
|
c1604eff08 | ||
|
|
77b52a5e69 | ||
|
|
d414c4f500 | ||
|
|
398bc769ce | ||
|
|
49f57a8d0d | ||
|
|
fbe102bada | ||
|
|
2cca490076 | ||
|
|
f7842e3a4b | ||
|
|
38421403d2 | ||
|
|
461dde231c | ||
|
|
0785c522f0 | ||
|
|
2656c6b4ac | ||
|
|
ed5ebe7458 | ||
|
|
d71d6afa34 | ||
|
|
2f8f230f61 | ||
|
|
285388409f | ||
|
|
aff5786ed3 | ||
|
|
f97928c740 | ||
|
|
bca73b8340 | ||
|
|
e67d834156 | ||
|
|
a93f2d8bfe | ||
|
|
8c55294ea9 | ||
|
|
50d8d75d89 | ||
|
|
bcc2d8474c | ||
|
|
e34da1b94d | ||
|
|
717eff71dd | ||
|
|
ad95cbc542 | ||
|
|
b30aff6d4d | ||
|
|
bf9a82ad9a | ||
|
|
c1efcd28f5 | ||
|
|
1fa9409554 | ||
|
|
adcd2e38e9 | ||
|
|
c19fb5656b | ||
|
|
74939b8b8d | ||
|
|
29a229724b | ||
|
|
a9fafc32a8 | ||
|
|
2de227a88b | ||
|
|
31ad140d20 | ||
|
|
bcf4e56fe0 | ||
|
|
1834ca3820 | ||
|
|
ad4a4120b7 | ||
|
|
0800f7ba56 | ||
|
|
36576babe8 | ||
|
|
ba9f5b7d95 | ||
|
|
11a5383604 | ||
|
|
d991606493 | ||
|
|
14048354d5 | ||
|
|
94b689e19d | ||
|
|
8066100f53 | ||
|
|
f60c22628a | ||
|
|
53e608cbc4 | ||
|
|
d10e73ffd7 | ||
|
|
1e75841036 | ||
|
|
32bf28e7ef | ||
|
|
fd5aeba117 | ||
|
|
24b524040b | ||
|
|
e533c3f33b | ||
|
|
41ab19e1d0 | ||
|
|
77475bdd55 | ||
|
|
0c70e80d47 | ||
|
|
5aa4592f0c | ||
|
|
855b73de87 | ||
|
|
136f4d3b0d | ||
|
|
714edcb8d9 | ||
|
|
a6b6a61775 | ||
|
|
39c9a6dfed | ||
|
|
561df8d9a2 | ||
|
|
48a20a6137 | ||
|
|
8ef0fbc294 | ||
|
|
51a21823f9 | ||
|
|
7a68331fcd | ||
|
|
d896d6393b | ||
|
|
6d531ed0a6 | ||
|
|
06df7c1b31 | ||
|
|
2b108483ce | ||
|
|
23c745d335 | ||
|
|
eb361626cb | ||
|
|
b0f8ca556b | ||
|
|
e41e28744f | ||
|
|
e862f04527 | ||
|
|
42519db55d | ||
|
|
019cb77b84 | ||
|
|
296f6a9217 | ||
|
|
d688ed2553 | ||
|
|
b4c0b03694 | ||
|
|
e721c122d3 | ||
|
|
8cd0d0040e | ||
|
|
e5542b027b | ||
|
|
5aa9cf2fcf | ||
|
|
a924869096 | ||
|
|
8c08b062d0 | ||
|
|
96b06e8bb4 | ||
|
|
a8efffa969 | ||
|
|
ef0215fcf2 | ||
|
|
82beeea619 | ||
|
|
a18a3813fb | ||
|
|
b8180f4069 | ||
|
|
94b00cc762 | ||
|
|
e4701e7c86 | ||
|
|
fc625b8a8e | ||
|
|
703f125882 | ||
|
|
4581b24b48 | ||
|
|
1d84821d93 | ||
|
|
07f607ec4c | ||
|
|
c3833c6c03 | ||
|
|
65008e2d3c | ||
|
|
d33a97b663 | ||
|
|
6f9fea7fd5 | ||
|
|
c8d978f4e9 | ||
|
|
558f889aae | ||
|
|
937268eb3e | ||
|
|
8be7ece1f5 | ||
|
|
6127da58f2 | ||
|
|
15e4e7e9da | ||
|
|
d484d4e129 | ||
|
|
985019ab64 | ||
|
|
870c9a7a08 | ||
|
|
2a6341c08c | ||
|
|
78e7873e92 | ||
|
|
7ecec3eb94 | ||
|
|
f4facc4e10 | ||
|
|
edffc2a291 | ||
|
|
c30a25e64c | ||
|
|
b9a9f54c45 | ||
|
|
f57d2c3277 | ||
|
|
11a1ae59f4 | ||
|
|
cd1129b9b8 | ||
|
|
216cabc563 | ||
|
|
5dd4f7604f | ||
|
|
94ce1ea451 | ||
|
|
f3697a0d5c | ||
|
|
8f0d40a1dd | ||
|
|
a138a52021 | ||
|
|
518a9b8d8c | ||
|
|
64ae0525cf | ||
|
|
dc88a937f0 | ||
|
|
ac93e2aea7 | ||
|
|
560e938038 | ||
|
|
2a5d71971c | ||
|
|
a59e65336d | ||
|
|
55ef7bc012 | ||
|
|
d3f1d094f7 | ||
|
|
421fb2a829 | ||
|
|
517e58d3dc | ||
|
|
0eaa650e32 | ||
|
|
4fbe572c02 | ||
|
|
7c0ce909ed | ||
|
|
f95157297e | ||
|
|
89993dd757 | ||
|
|
75e7c30594 | ||
|
|
5032a9f13c | ||
|
|
4f34062623 | ||
|
|
255f5bd73f | ||
|
|
0ec847bbe7 | ||
|
|
08bc076a0a | ||
|
|
2c014256f7 | ||
|
|
488e822c8d | ||
|
|
2234c115f2 | ||
|
|
b23b3f1d99 | ||
|
|
46b249f5ce | ||
|
|
b1b42aeb9c | ||
|
|
56c867edfa | ||
|
|
40c1a7e91f | ||
|
|
9739dae794 | ||
|
|
81793de030 | ||
|
|
a5157e69b1 | ||
|
|
101a65378c | ||
|
|
91ef298e7d | ||
|
|
739234afb9 | ||
|
|
4ecefb5017 | ||
|
|
444008aabc | ||
|
|
45857bc606 | ||
|
|
da9b2e25f6 | ||
|
|
fc508f9494 | ||
|
|
3573bd4d87 | ||
|
|
c7ee14e786 | ||
|
|
fac56bae32 | ||
|
|
c5c1698cde | ||
|
|
4df7daec82 | ||
|
|
26d04ff037 | ||
|
|
5713481838 | ||
|
|
74c9c1afa9 | ||
|
|
e159f04df8 | ||
|
|
4a21b6f168 | ||
|
|
fe16cce405 | ||
|
|
8ba02b6f4c | ||
|
|
f5191ec222 | ||
|
|
144126789c | ||
|
|
8dcfc9849e | ||
|
|
b28fb6654c | ||
|
|
9294c3284c | ||
|
|
9278dc0666 | ||
|
|
af519d73ae | ||
|
|
3a326793fd | ||
|
|
f31a14b793 | ||
|
|
7886326aa8 | ||
|
|
31cc03f8e6 | ||
|
|
cf7449c525 | ||
|
|
b0cdbf5b22 | ||
|
|
231e378157 | ||
|
|
431d8fe7c7 | ||
|
|
9ee4d6c697 | ||
|
|
3f14d7a54a | ||
|
|
52acb3fcac | ||
|
|
a8d08a9478 | ||
|
|
c691aa3e32 | ||
|
|
430e570629 | ||
|
|
65dc4f1186 | ||
|
|
6b320a00a0 | ||
|
|
22be109956 | ||
|
|
4bb790fb5d | ||
|
|
7d32ec5d28 | ||
|
|
20e7ec96ae | ||
|
|
2e563e0fa8 | ||
|
|
cbd0a8f4b5 | ||
|
|
ecbe577be3 | ||
|
|
84db436e3b | ||
|
|
904c6ed853 | ||
|
|
186e07b415 | ||
|
|
4ab63d3d8c | ||
|
|
696ef7aecc | ||
|
|
9603f2520b | ||
|
|
a5a806f7ee | ||
|
|
fa294e8603 | ||
|
|
97d2f755c4 | ||
|
|
83536ab7d1 | ||
|
|
6cdbc01208 | ||
|
|
833903e8ec | ||
|
|
c53383a316 | ||
|
|
dfc35699ea | ||
|
|
b7a7c816df | ||
|
|
090f036205 | ||
|
|
8738e93dc0 | ||
|
|
ee2bee88ee | ||
|
|
6ffd38d25e | ||
|
|
250273cf1a | ||
|
|
bc15f7b7aa | ||
|
|
7c3040c624 | ||
|
|
c584b55488 | ||
|
|
5a2abd34ce | ||
|
|
14eb593af3 | ||
|
|
b2b7bc3b77 | ||
|
|
fddbf1f94c | ||
|
|
5d5f6cc60c | ||
|
|
ae64c19f20 | ||
|
|
e5abc065aa | ||
|
|
4ce265b105 | ||
|
|
154e99f2ba | ||
|
|
dab450be32 | ||
|
|
a3db621899 | ||
|
|
e26c6d20fe | ||
|
|
a75a2bf533 | ||
|
|
8dcfc3c94a | ||
|
|
19c4027194 | ||
|
|
0efd50df26 | ||
|
|
a127c8827a | ||
|
|
dcb5a81735 | ||
|
|
4abdf47923 | ||
|
|
d39dce85b4 | ||
|
|
e736725d35 | ||
|
|
d61a699543 | ||
|
|
320b6c0cd8 | ||
|
|
7cf05075a0 | ||
|
|
3e0959fa1b | ||
|
|
d87b29b678 | ||
|
|
2c16a3c0e8 | ||
|
|
dc3d9bb2ab | ||
|
|
fd4ed3909e | ||
|
|
3f29a3d4fa | ||
|
|
1a894b65d4 | ||
|
|
6e82193175 | ||
|
|
32ac1e04ec | ||
|
|
a47a9ecad1 | ||
|
|
d07aef725e | ||
|
|
b5eb08ad09 | ||
|
|
3ce7d7a28c | ||
|
|
9da13d4ff8 | ||
|
|
7d49e49e74 | ||
|
|
0689304cff | ||
|
|
8dd4972fda | ||
|
|
51436cc3a3 | ||
|
|
b168b8f03f | ||
|
|
9e9e7e95ee | ||
|
|
c805f0cdcb | ||
|
|
e4bbba2b15 | ||
|
|
3a5af7fb61 | ||
|
|
34f2d50e29 | ||
|
|
40d0ca7963 | ||
|
|
095f348172 | ||
|
|
67c062e45e | ||
|
|
4516e7bdcb | ||
|
|
90d72c214e | ||
|
|
8fd6c8bc02 | ||
|
|
863cd6fcba | ||
|
|
38fda265e8 | ||
|
|
72058bfbcc | ||
|
|
74e23a7fa2 | ||
|
|
6372f671ed | ||
|
|
8501ca2ea0 | ||
|
|
1264557f0e | ||
|
|
f34cd24f80 | ||
|
|
9cd5e97596 | ||
|
|
9f59be3224 | ||
|
|
dea644bbd6 | ||
|
|
8bcb835aa4 | ||
|
|
eec3532955 | ||
|
|
8424c7a747 | ||
|
|
464176d511 | ||
|
|
e8a1d135e2 | ||
|
|
b707b5e2a4 | ||
|
|
c987fd8c53 | ||
|
|
d083554dff | ||
|
|
ec3af2c5cb | ||
|
|
f857d4aff7 | ||
|
|
39d6ef884a | ||
|
|
492d1f24c8 | ||
|
|
60e5a32d27 | ||
|
|
f8d0055503 | ||
|
|
8baaf64a72 | ||
|
|
6ae69e0df0 | ||
|
|
92ca76721a | ||
|
|
6af2e3fc10 | ||
|
|
9bec3ee48e | ||
|
|
17ca9d9da7 | ||
|
|
c1711243f0 | ||
|
|
fdfd12716e | ||
|
|
dc0d945f28 | ||
|
|
96465a52ee | ||
|
|
512fa6e601 | ||
|
|
12d43e2967 | ||
|
|
e8648416b8 | ||
|
|
b971834d10 | ||
|
|
94ee9effe6 | ||
|
|
81bc13e066 | ||
|
|
1297da380e | ||
|
|
4ee3b28ecb | ||
|
|
757f8a6323 | ||
|
|
a25b06ecfc | ||
|
|
6b703b8d6a | ||
|
|
c97d0d1220 | ||
|
|
7520d9c7b9 | ||
|
|
2577214517 | ||
|
|
8e7bd43016 | ||
|
|
e7b74c57f3 | ||
|
|
cfdd4296a8 | ||
|
|
3407509ed7 | ||
|
|
3ac62dda51 | ||
|
|
3465b592e7 | ||
|
|
ca499a5495 | ||
|
|
8a1d832f80 | ||
|
|
758df26582 | ||
|
|
6ae558b541 | ||
|
|
68f53540df | ||
|
|
48ba9c9bc1 | ||
|
|
245deb2abe | ||
|
|
549ea0d7ba | ||
|
|
94d1112c55 | ||
|
|
0c47227144 | ||
|
|
a2505078da | ||
|
|
35532a63fe | ||
|
|
514ab6eed2 | ||
|
|
c41e3a8e68 | ||
|
|
7d71340241 | ||
|
|
40bcc0bed8 | ||
|
|
74009e2be5 | ||
|
|
40871ab1cc | ||
|
|
2fc4c7e335 | ||
|
|
da8263b3f6 | ||
|
|
12db7c4bc1 | ||
|
|
db3ef37771 | ||
|
|
7f32558e08 | ||
|
|
228ac78397 | ||
|
|
b6656a1525 | ||
|
|
84ec17964e | ||
|
|
ef5dc6cd2b | ||
|
|
84e6aca5c5 | ||
|
|
ebd0987376 | ||
|
|
20baf4f5b6 | ||
|
|
335a0fe768 | ||
|
|
b25ebf4bdb | ||
|
|
804bb44eda | ||
|
|
1b15896e8b | ||
|
|
055fbe1d87 | ||
|
|
648e5d62ba | ||
|
|
49de20aa5c | ||
|
|
13d534e89a | ||
|
|
1944dc8b5f | ||
|
|
f2ca2d50b5 | ||
|
|
b361fb5898 | ||
|
|
8d1faa0dbc | ||
|
|
77baa2df15 | ||
|
|
a229cb4676 | ||
|
|
682ed18123 | ||
|
|
3aae59c224 | ||
|
|
6f3505bf6b | ||
|
|
bfdc48e320 | ||
|
|
fcda8beb1c | ||
|
|
d0647afae5 | ||
|
|
a6383cec51 | ||
|
|
44fd5ff451 | ||
|
|
ea34f37d43 | ||
|
|
23dcc2c7f3 | ||
|
|
91f7d127ea | ||
|
|
43c1245396 | ||
|
|
43288bc4f2 | ||
|
|
2e22d6ef99 | ||
|
|
6509b6e742 | ||
|
|
d2ce0042b3 | ||
|
|
0dcb63ff5e | ||
|
|
bebbac1bd8 | ||
|
|
a1870a62cf | ||
|
|
1ef1a77421 | ||
|
|
98819f92e3 | ||
|
|
ebce70eba1 | ||
|
|
ed257b982a | ||
|
|
1b7877f6ed | ||
|
|
7500b0564c | ||
|
|
0c992ece3b | ||
|
|
e124249a8b | ||
|
|
d950d6af52 | ||
|
|
55abcfeef6 | ||
|
|
49b3712891 | ||
|
|
b9a8b22728 | ||
|
|
65f8e86e41 | ||
|
|
9780f22866 | ||
|
|
46b2b99f63 | ||
|
|
c92f54102e | ||
|
|
964d5f88cc | ||
|
|
ad7e9d88fb | ||
|
|
3ace7817b4 | ||
|
|
0de35ca8f0 | ||
|
|
80b6cf77b0 | ||
|
|
79b4bf4ac2 | ||
|
|
ab6b510408 | ||
|
|
ab52ca01ad | ||
|
|
64b72f8d3a | ||
|
|
ffc9806e6d | ||
|
|
984fb41b98 | ||
|
|
a1e05c62ae | ||
|
|
076e884873 | ||
|
|
2f6fbbd706 | ||
|
|
4924ac8099 | ||
|
|
7962029bdc | ||
|
|
f83f837de7 | ||
|
|
48b719cf68 | ||
|
|
96afa4530c | ||
|
|
270a8a26fa | ||
|
|
92a50f731c | ||
|
|
76d6838223 | ||
|
|
0bfb9d476c | ||
|
|
91bb1b2de6 | ||
|
|
810adadf2e | ||
|
|
8da712ea61 | ||
|
|
56cfb8036f | ||
|
|
f332dd810e | ||
|
|
d1c6fa9261 | ||
|
|
b00e2ad40e | ||
|
|
ca9f42a20f | ||
|
|
e939786836 | ||
|
|
11cc5f5815 | ||
|
|
d60b1ec1a2 | ||
|
|
ae11589205 | ||
|
|
70b9475449 | ||
|
|
02aecc1278 | ||
|
|
3e90a11599 | ||
|
|
b4095189d7 | ||
|
|
c0b4c4d60c | ||
|
|
12da24c056 | ||
|
|
d821117033 | ||
|
|
30266f7627 | ||
|
|
10b625e180 | ||
|
|
10f27457d3 | ||
|
|
af1f431364 | ||
|
|
272a4d1e45 | ||
|
|
3a95ecfe74 | ||
|
|
14ae9a7f0c | ||
|
|
51f1918109 | ||
|
|
fa27956daf | ||
|
|
ab0d8a3828 | ||
|
|
efded18724 | ||
|
|
f52bc064e9 | ||
|
|
75f066dfcd | ||
|
|
535ff07f0f | ||
|
|
5e002635fc | ||
|
|
e71c28f6a0 | ||
|
|
c0e091a52f | ||
|
|
8ab0f8e51f | ||
|
|
cce34a6176 | ||
|
|
89f0311927 | ||
|
|
e455f6f756 | ||
|
|
17f2645a32 | ||
|
|
9f034aca9c | ||
|
|
22bdfa3886 | ||
|
|
ef8246a592 | ||
|
|
110d201e02 | ||
|
|
be4f695c5c | ||
|
|
792def7a65 | ||
|
|
840cecbe0e | ||
|
|
27d25752e9 | ||
|
|
a479b30298 | ||
|
|
86620fc991 | ||
|
|
b3dfd5cffc | ||
|
|
f0858ff6b2 | ||
|
|
7b7280e728 | ||
|
|
2523ed0779 | ||
|
|
e736b1a40e | ||
|
|
cbf012c337 | ||
|
|
c360ed1d9a | ||
|
|
22e74e3bab | ||
|
|
02b3104215 | ||
|
|
26a5294116 | ||
|
|
5e4c78e114 | ||
|
|
e74305c5eb | ||
|
|
499f9aa707 | ||
|
|
4dee9a3e68 | ||
|
|
399041180f | ||
|
|
3f55fb5b22 | ||
|
|
37a4a65d60 | ||
|
|
ccd886feb4 | ||
|
|
b1bc283e9a | ||
|
|
be75fac7ff | ||
|
|
6ec65c6f9d | ||
|
|
71ab0cf6cc | ||
|
|
1e0e8a5493 | ||
|
|
4b65aea401 | ||
|
|
98ff6fbbce | ||
|
|
43e0d73b63 | ||
|
|
58294442d3 | ||
|
|
2e9c13dad0 | ||
|
|
9c667ebc26 | ||
|
|
d1b772f1bc | ||
|
|
876f843f23 | ||
|
|
0e2e0983f3 | ||
|
|
6063a8d09c | ||
|
|
40778d4ba9 | ||
|
|
60d6954b75 | ||
|
|
bf376b6d4f | ||
|
|
ff52e3630f | ||
|
|
f1f17f18dc | ||
|
|
7c759b9615 | ||
|
|
d54e9550da | ||
|
|
d7c0270c89 | ||
|
|
7a37f9faf7 | ||
|
|
149a2b4a18 | ||
|
|
ab5b4c7cfe | ||
|
|
e78334688f | ||
|
|
566fda70a5 | ||
|
|
62cebe23d9 | ||
|
|
42aacc7106 | ||
|
|
8ed9cdce80 | ||
|
|
a3a7f17d0f | ||
|
|
571dd56eca | ||
|
|
f6f0988d10 | ||
|
|
f9d1542542 | ||
|
|
d32fe11da3 | ||
|
|
cd7f6bea57 | ||
|
|
c3dc60103f | ||
|
|
2a2616f65c | ||
|
|
f643c34ee8 | ||
|
|
0f77578ee2 | ||
|
|
3e314e863c | ||
|
|
adbb087221 | ||
|
|
3a8d839e86 | ||
|
|
358647f5d9 | ||
|
|
5e76118512 | ||
|
|
e3bdc393cb | ||
|
|
04b49d46c1 | ||
|
|
74b7fb7bba | ||
|
|
c70694c594 | ||
|
|
fef87793a0 | ||
|
|
79c475c917 | ||
|
|
3dd03fec21 | ||
|
|
e8e07f7376 | ||
|
|
1c5ae7dd97 | ||
|
|
f65e3566a2 | ||
|
|
6b0a89a288 | ||
|
|
f84ebc2e27 | ||
|
|
b359229a2e | ||
|
|
496a8e12d9 | ||
|
|
0e8e124d20 | ||
|
|
9a8d4cd0fd | ||
|
|
ffed8b03bb | ||
|
|
5bd38a5f37 | ||
|
|
ab60d1d678 | ||
|
|
5223fa5740 | ||
|
|
95558d54b0 | ||
|
|
068a7dfc49 | ||
|
|
abd8b17a04 | ||
|
|
343e6e482a | ||
|
|
aae1df0589 | ||
|
|
0a57ebb3a9 | ||
|
|
9afad28255 | ||
|
|
8b21b51a78 | ||
|
|
2003a81b44 | ||
|
|
abe6c7c728 | ||
|
|
f78045dfd3 | ||
|
|
39729bd3de | ||
|
|
f6d2a66de2 | ||
|
|
7de3122b42 | ||
|
|
88f4e9ea24 | ||
|
|
4133f484ae | ||
|
|
041aff8060 | ||
|
|
7c7096d8f8 | ||
|
|
fd7b7bc3b5 | ||
|
|
bb034e8e1d | ||
|
|
d37a475816 | ||
|
|
4845642611 | ||
|
|
de8808cb47 | ||
|
|
ca978a9e81 | ||
|
|
ffca268bee | ||
|
|
6a3d31acb7 | ||
|
|
f28352707a | ||
|
|
4b363928f6 | ||
|
|
929f5ca25b | ||
|
|
7ff80a2666 | ||
|
|
480dfd9050 | ||
|
|
bdb32afa20 | ||
|
|
f90ae73b6d | ||
|
|
7fed54b1e5 | ||
|
|
d5840aa1f0 | ||
|
|
6f2225e8fb | ||
|
|
07a9e6b7c6 | ||
|
|
86e6444656 | ||
|
|
8ef62cf784 | ||
|
|
8051ab044c | ||
|
|
18bce13617 | ||
|
|
2a10019f82 | ||
|
|
df4c62212c | ||
|
|
97b6036cbf | ||
|
|
df4f7ed5b8 | ||
|
|
0792c015d6 | ||
|
|
8344598910 | ||
|
|
16870abed7 | ||
|
|
65850a1bad | ||
|
|
1137f0d48c | ||
|
|
d9a50f04e7 | ||
|
|
4aa7d73b43 | ||
|
|
3804e72e24 | ||
|
|
b8508020e5 | ||
|
|
324be0eabd | ||
|
|
cfe5f83cf8 | ||
|
|
a1ad0deb32 | ||
|
|
7c575a2418 | ||
|
|
47cac13c0a | ||
|
|
16d1ef8933 | ||
|
|
b500d76929 | ||
|
|
aef9471217 | ||
|
|
f3454d571e | ||
|
|
1df1f86f7e | ||
|
|
f9db9c5a9c | ||
|
|
96bafeca4c | ||
|
|
626d8ec637 | ||
|
|
f3b36af50e | ||
|
|
385b640d1d | ||
|
|
d4bc6fa954 | ||
|
|
8bae43876f | ||
|
|
fbfea94559 | ||
|
|
6a04b43a45 | ||
|
|
049c62098c | ||
|
|
6801959989 | ||
|
|
8463d9d7c6 | ||
|
|
c497f057a0 | ||
|
|
fc0af0f0d8 | ||
|
|
330c2004a1 | ||
|
|
0b10493e90 | ||
|
|
d23e64fc52 | ||
|
|
fd83d69440 | ||
|
|
461e46b814 | ||
|
|
4f95146151 | ||
|
|
3eb21053d0 | ||
|
|
92db6f8c6d | ||
|
|
0fd0c6d293 | ||
|
|
b49973f17b | ||
|
|
978d265da8 | ||
|
|
cf6dddce34 | ||
|
|
2c4bbe51dd | ||
|
|
756d441f8c | ||
|
|
db6aa88bc4 | ||
|
|
e707af1cd7 | ||
|
|
380a70d650 | ||
|
|
2dc3b5c675 | ||
|
|
63011c29a0 | ||
|
|
e68c3b09a6 | ||
|
|
0793bf5aa6 | ||
|
|
d9b7e4cb7a | ||
|
|
8e6ab1809f | ||
|
|
86418bfbbe | ||
|
|
1e1c13f756 | ||
|
|
8dae851836 | ||
|
|
db284d60b9 | ||
|
|
bfc6c7e606 | ||
|
|
9b13390ad0 | ||
|
|
81fe4299f7 | ||
|
|
5e4bc6ec79 | ||
|
|
f3612879a8 | ||
|
|
57088c4375 | ||
|
|
011ab7c8fe | ||
|
|
e4422d6605 | ||
|
|
14e1d015ee | ||
|
|
3da1c17acb | ||
|
|
7e9f0803c5 | ||
|
|
f989452b3e | ||
|
|
a2780d1dd4 | ||
|
|
ddca45804b | ||
|
|
f92e12c7b0 | ||
|
|
e4da8b99fe | ||
|
|
b993579079 | ||
|
|
807cb635c1 | ||
|
|
3ad559cc23 | ||
|
|
ec02ce0ec2 | ||
|
|
1b9676a0cc | ||
|
|
f4b3ef7604 | ||
|
|
e9974c2053 | ||
|
|
de532ee550 | ||
|
|
67b44e4417 | ||
|
|
83f65031c0 | ||
|
|
63053541e6 | ||
|
|
a040e2e3db | ||
|
|
678d445075 | ||
|
|
3558b9e6b6 | ||
|
|
590c3e2f51 | ||
|
|
28a7343320 | ||
|
|
766bae9d76 | ||
|
|
94a57df0c9 | ||
|
|
5f93742c5e | ||
|
|
9457c770df | ||
|
|
bccb9b16a5 | ||
|
|
1355029ec9 | ||
|
|
5dc8d6069d | ||
|
|
60837b1538 | ||
|
|
debfd1f3a3 | ||
|
|
4f70cc13e2 | ||
|
|
b4111c5c18 | ||
|
|
b9b7174d85 | ||
|
|
69ceaae9a9 | ||
|
|
1abdb28995 | ||
|
|
81dab99afc | ||
|
|
291522772d | ||
|
|
26d1ac325b | ||
|
|
1311d03415 | ||
|
|
549fd32574 | ||
|
|
9f14bbd6ad | ||
|
|
e8f7801540 | ||
|
|
cdde79418a | ||
|
|
9b97da65e6 | ||
|
|
1dcaebe1ce | ||
|
|
28b5d0f875 | ||
|
|
ba217dec1c | ||
|
|
3b8c4dc750 | ||
|
|
5d1fa1be24 | ||
|
|
c8e82528fc | ||
|
|
104e6d39ab | ||
|
|
3f778d9a31 | ||
|
|
a935ad1857 | ||
|
|
7abb3941c8 | ||
|
|
194880b869 | ||
|
|
737f588b3b | ||
|
|
6d5b36fb79 | ||
|
|
8ce6bd3459 | ||
|
|
5b8338d115 | ||
|
|
e73cbbe18c | ||
|
|
69a01b3657 | ||
|
|
e406b81d34 | ||
|
|
fdc2751952 | ||
|
|
fa11083fcb | ||
|
|
2bc8819e8f | ||
|
|
23b6c95e04 | ||
|
|
c041bcc6d9 | ||
|
|
fc5dd23afa | ||
|
|
91d0660cc3 | ||
|
|
fb5769b4be | ||
|
|
56ee212641 | ||
|
|
8f3891e968 | ||
|
|
958a775afa | ||
|
|
e776dc16c9 | ||
|
|
9450a3c987 | ||
|
|
1939a55c3c | ||
|
|
2a116bb291 | ||
|
|
d01c7320f9 | ||
|
|
ea0315ed88 | ||
|
|
85a5eb9499 | ||
|
|
3cd06a1f26 | ||
|
|
19c3d02805 | ||
|
|
b534bfc520 | ||
|
|
ef2c8d66f1 | ||
|
|
1a6038baa5 | ||
|
|
41a8fb5810 | ||
|
|
8843d8b68d | ||
|
|
2aec79ce36 | ||
|
|
bbcbc8425c | ||
|
|
ed8178f3c3 | ||
|
|
933527fc77 | ||
|
|
bf8d139b2d | ||
|
|
093983b804 | ||
|
|
103292dd99 | ||
|
|
76b6b1c694 | ||
|
|
1301864f92 | ||
|
|
d5b6f6cc37 | ||
|
|
052073c36d | ||
|
|
60c778ad7f | ||
|
|
71100dadcd | ||
|
|
5ba33438f3 | ||
|
|
708c0d32a2 | ||
|
|
3659e8c04a | ||
|
|
c4cf349729 | ||
|
|
2c99566697 | ||
|
|
42470857e2 | ||
|
|
8724f97a19 | ||
|
|
8960992267 | ||
|
|
730af24de8 | ||
|
|
a3fa6f3099 | ||
|
|
4dafc25927 | ||
|
|
e671ebcd99 | ||
|
|
bab8508eba | ||
|
|
77cd4795c5 | ||
|
|
dc83f36a00 | ||
|
|
8336c91e9c | ||
|
|
1bea53375b | ||
|
|
3af55a4f49 | ||
|
|
cf482ae3bf | ||
|
|
916958a2bb | ||
|
|
e2af94289f | ||
|
|
fa4c81cfb9 | ||
|
|
7dbc66e4a3 | ||
|
|
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 |
1
.clang_complete
Normal file
1
.clang_complete
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-Iinclude -Ibuild
|
||||||
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):
|
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)
|
Nick Zitzmann <seiryu (at) comcast (dot) net> (mostly client SFTP stuff)
|
||||||
|
|
||||||
|
|||||||
119
CMakeLists.txt
Normal file
119
CMakeLists.txt
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
project(libssh C)
|
||||||
|
|
||||||
|
# Required cmake version
|
||||||
|
cmake_minimum_required(VERSION 2.6.0)
|
||||||
|
|
||||||
|
# global needed variables
|
||||||
|
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
|
|
||||||
|
set(APPLICATION_VERSION_MAJOR "0")
|
||||||
|
set(APPLICATION_VERSION_MINOR "5")
|
||||||
|
set(APPLICATION_VERSION_PATCH "2")
|
||||||
|
|
||||||
|
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||||
|
|
||||||
|
# SOVERSION scheme: CURRENT.AGE.REVISION
|
||||||
|
# If there was an incompatible interface change:
|
||||||
|
# Increment CURRENT. Set AGE and REVISION to 0
|
||||||
|
# If there was a compatible interface change:
|
||||||
|
# Increment AGE. Set REVISION to 0
|
||||||
|
# If the source code was changed, but there were no interface changes:
|
||||||
|
# Increment REVISION.
|
||||||
|
set(LIBRARY_VERSION "4.2.2")
|
||||||
|
set(LIBRARY_SOVERSION "4")
|
||||||
|
|
||||||
|
# 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(DefinePlatformDefaults)
|
||||||
|
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
|
||||||
|
if (WITH_LIBZ)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
endif (WITH_LIBZ)
|
||||||
|
|
||||||
|
if (WITH_GCRYPT)
|
||||||
|
find_package(GCrypt REQUIRED)
|
||||||
|
if (NOT GCRYPT_FOUND)
|
||||||
|
message(FATAL_ERROR "Could not find GCrypt")
|
||||||
|
endif (NOT GCRYPT_FOUND)
|
||||||
|
else (WITH_GCRYPT)
|
||||||
|
find_package(OpenSSL)
|
||||||
|
if (NOT OPENSSL_FOUND)
|
||||||
|
find_package(GCrypt)
|
||||||
|
if (NOT GCRYPT_FOUND)
|
||||||
|
message(FATAL_ERROR "Could not find OpenSSL or GCrypt")
|
||||||
|
endif (NOT GCRYPT_FOUND)
|
||||||
|
endif (NOT OPENSSL_FOUND)
|
||||||
|
endif(WITH_GCRYPT)
|
||||||
|
|
||||||
|
# Find out if we have threading available
|
||||||
|
set(CMAKE_THREAD_PREFER_PTHREADS ON)
|
||||||
|
find_package(Threads)
|
||||||
|
|
||||||
|
# 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(src)
|
||||||
|
|
||||||
|
# pkg-config file
|
||||||
|
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
|
||||||
|
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
|
||||||
|
DESTINATION
|
||||||
|
${LIB_INSTALL_DIR}/pkgconfig
|
||||||
|
COMPONENT
|
||||||
|
pkgconfig
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(examples)
|
||||||
|
|
||||||
|
if (WITH_TESTING)
|
||||||
|
find_package(CMockery REQUIRED)
|
||||||
|
include(AddCMockeryTest)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif (WITH_TESTING)
|
||||||
|
|
||||||
|
|
||||||
|
message(STATUS "********************************************")
|
||||||
|
message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
||||||
|
|
||||||
|
message(STATUS "zlib support: ${WITH_LIBZ}")
|
||||||
|
message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
|
||||||
|
message(STATUS "SSH-1 support: ${WITH_SSH1}")
|
||||||
|
message(STATUS "SFTP support: ${WITH_SFTP}")
|
||||||
|
message(STATUS "Server support : ${WITH_SERVER}")
|
||||||
|
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
|
||||||
|
message(STATUS "Unit testing: ${WITH_TESTING}")
|
||||||
|
message(STATUS "Client code Unit testing: ${WITH_CLIENT_TESTING}")
|
||||||
|
if (WITH_INTERNAL_DOC)
|
||||||
|
message(STATUS "Internal documentation generation")
|
||||||
|
else (WITH_INTERNAL_DOC)
|
||||||
|
message(STATUS "Public API documentation generation")
|
||||||
|
endif (WITH_INTERNAL_DOC)
|
||||||
|
message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
|
||||||
|
message(STATUS "********************************************")
|
||||||
|
|
||||||
53
CPackConfig.cmake
Normal file
53
CPackConfig.cmake
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# 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 "5")
|
||||||
|
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}")
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(CPACK_GENERATOR "ZIP")
|
||||||
|
|
||||||
|
### nsis generator
|
||||||
|
find_package(NSIS)
|
||||||
|
if (NSIS_MAKE)
|
||||||
|
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
|
||||||
|
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||||
|
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||||
|
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||||
|
endif (NSIS_MAKE)
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "libssh")
|
||||||
|
|
||||||
|
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)
|
||||||
9
CTestConfig.cmake
Normal file
9
CTestConfig.cmake
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
set(UPDATE_TYPE "true")
|
||||||
|
|
||||||
|
set(CTEST_PROJECT_NAME "libssh")
|
||||||
|
set(CTEST_NIGHTLY_START_TIME "01:00:00 CET")
|
||||||
|
|
||||||
|
set(CTEST_DROP_METHOD "http")
|
||||||
|
set(CTEST_DROP_SITE "test.libssh.org")
|
||||||
|
set(CTEST_DROP_LOCATION "/submit.php?project=libssh")
|
||||||
|
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||||
392
ChangeLog
392
ChangeLog
@@ -1,80 +1,320 @@
|
|||||||
libssh-0.11-dev
|
ChangeLog
|
||||||
-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.
|
|
||||||
|
|
||||||
5th march 2004 : libssh-0.1
|
version 0.5.2 (released 2011-09-17)
|
||||||
-Begining of sftp subsystem implementation. It's stable enough to be used :)
|
* Increased window size x10.
|
||||||
-some cleanup into channels implementation
|
* Fixed SSHv1.
|
||||||
-Now every channel functions is called by its CHANNEL handler. no any way to play again with numbers.
|
* Fixed bugged lists.
|
||||||
-added channel_poll() and channel_read(). Now, it's possible to manipulate channel streams only with channel_read() and channel_write(),
|
* Fixed use-after-free + inconsistent callbacks call in poll.
|
||||||
with help of channel_poll().
|
* Fixed scp documentation.
|
||||||
-changed the client so it uses the new channel_poll and channel_read interface
|
* Fixed possible infinite loop in channel_read().
|
||||||
-small use-after-free bug with channels resolved, and a noninitialised data of SIGNATURE struct.
|
* Fixed handling of short reads of sftp_async_read().
|
||||||
-changed stupidities in lot of function names.
|
* Fixed handling request service timeout in blocking mode.
|
||||||
-removed a debug output file opened by default.
|
* Fixed ssh_auth_list() documentation.
|
||||||
-Added API.txt, the libssh programmer handbook. (I hate documentation)
|
* Fixed incorrect return values in ssh_channel_write().
|
||||||
-Various bug fixes from Nick Zitzmann. Thank to him, libssh now runs under macosX !
|
* Fixed an infinite loop in the termination callback.
|
||||||
-Developed a cryptographic structure for handling protocols. Adding a custom-based cipher should be the story of thirty
|
* Fixed handling of SSH_AGAIN in channel_open().
|
||||||
minutes. It now supports aes-256,aes-192,aes-128 and blowfish-128 !
|
* Fixed "status -5 inflating zlib packet"
|
||||||
-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.
|
|
||||||
|
|
||||||
10th october 2003 : libssh-0.0.4
|
version 0.5.1 (released 2011-08-09)
|
||||||
-some terminal code (eof handling) added
|
* Added checks for NULL pointers in string.c.
|
||||||
-channels bugfix (it still needs some tweaking though)
|
* Set the channel max packet size to 32768.
|
||||||
-zlib support
|
* Don't (de)compress empty buffers.
|
||||||
-added a wrapper.c file. The goal is to provide a similar API to every cryptographic functions. bignums and sha/md5 are wrapped now.
|
* Fixed ssh_scp_write so it works when doing recursive copy.
|
||||||
-more work than it first looks.
|
* Fixed another source of endless wait.
|
||||||
-Support for other crypto libs planed (lighter libs)
|
* Fixed an endless loop in case of a channel_open error.
|
||||||
-Fixed stupid select() bug.
|
* Fixed session timeout handling.
|
||||||
-libssh now compiles and links with openssl 0.9.6 (but you're advised to upgrade)
|
* Fixed ssh_channel_from_local() loop.
|
||||||
-RSA pubkey authentication code now works !
|
* Fixed permissions of scp example when we copy a file.
|
||||||
|
* Workaround ssh_get_user_home_dir on LDAP users.
|
||||||
|
* Added pkg-config support for libssh_threads.
|
||||||
|
* Fixed compilation without server and sftp modes.
|
||||||
|
* Fix static .lib overwriting on Windows.
|
||||||
|
|
||||||
15th september 2003 : libssh-0.0.3
|
version 0.5.0 (released 2011-06-01)
|
||||||
-added install target in makefile
|
* Added ssh_ prefix to all functions.
|
||||||
-some cleanup in headers files and source code
|
* Added complete Windows support.
|
||||||
-change default banner and project name to libssh.
|
* Added improved server support.
|
||||||
-new file auth.c to support more and more authentication ways
|
* Added unit tests for a lot of functions.
|
||||||
-bugfix(read offbyone) in send_kex
|
* Added asynchronous service request.
|
||||||
-a base64 parser. don't read the source, it's awful. pure 0xbadc0de.
|
* Added a multiplatform ssh_getpass() function.
|
||||||
-changed the client filename to "ssh". logic isn't it ?
|
* Added a tutorial.
|
||||||
-dss publickey authentication ! still need to wait for the rsa one
|
* Added a lot of documentation.
|
||||||
-bugfix in packet.c : now packet are completely read (and read blocks if waiting the packet)
|
* Fixed a lot of bugs.
|
||||||
-new misc.c contains misc functions
|
* Fixed several memory leaks.
|
||||||
|
|
||||||
3rd september 2003: libssh-0.0.2
|
version 0.4.8 (released 2011-01-15)
|
||||||
initial release.
|
* Fixed memory leaks in session signing.
|
||||||
-client supports both ssh and dss hostkey verification, but doesn't compare
|
* Fixed memory leak in ssh_print_hexa.
|
||||||
them to openssh's files. (~/.ssh/known_hosts)
|
* Fixed problem with ssh_connect w/ timeout and fd > 1024.
|
||||||
-the only supported authentication method is password.
|
* Fixed some warnings on OS/2.
|
||||||
-compiles on linux and openbsd. freebsd and netbsd should work, too
|
* Fixed installation path for OS/2.
|
||||||
-Lot of work which hasn't been discussed here.
|
|
||||||
|
version 0.4.7 (released 2010-12-28)
|
||||||
|
* Fixed a possible memory leak in ssh_get_user_home().
|
||||||
|
* Fixed a memory leak in sftp_xstat.
|
||||||
|
* Fixed uninitialized fd->revents member.
|
||||||
|
* Fixed timout value in ssh_channel_accept().
|
||||||
|
* Fixed length checks in ssh_analyze_banner().
|
||||||
|
* Fixed a possible data overread and crash bug.
|
||||||
|
* Fixed setting max_fd which breaks ssh_select().
|
||||||
|
* Fixed some pedantic build warnings.
|
||||||
|
* Fixed a memory leak with session->bindaddr.
|
||||||
|
|
||||||
|
version 0.4.6 (released 2010-09-03)
|
||||||
|
* Added a cleanup function to free the ws2_32 library.
|
||||||
|
* Fixed build with gcc 3.4.
|
||||||
|
* Fixed the Windows build on Vista and newer.
|
||||||
|
* Fixed the usage of WSAPoll() on Windows.
|
||||||
|
* Fixed "@deprecated" in doxygen
|
||||||
|
* Fixed some mingw warnings.
|
||||||
|
* Fixed handling of opened channels.
|
||||||
|
* Fixed keepalive problem on older openssh servers.
|
||||||
|
* Fixed testing for big endian on Windows.
|
||||||
|
* Fixed the Windows preprocessor macros and defines.
|
||||||
|
|
||||||
|
version 0.4.5 (released 2010-07-13)
|
||||||
|
* Added option to bind a client to an ip address.
|
||||||
|
* Fixed the ssh socket polling function.
|
||||||
|
* Fixed Windows related bugs in bsd_poll().
|
||||||
|
* Fixed serveral build warnings.
|
||||||
|
|
||||||
|
version 0.4.4 (released 2010-06-01)
|
||||||
|
* Fixed a bug in the expand function for escape sequences.
|
||||||
|
* Fixed a bug in the tilde expand function.
|
||||||
|
* Fixed a bug in setting the options.
|
||||||
|
|
||||||
|
version 0.4.3 (released 2010-05-18)
|
||||||
|
* Added global/keepalive responses.
|
||||||
|
* Added runtime detection of WSAPoll().
|
||||||
|
* Added a select(2) based poll-emulation if poll(2) is not available.
|
||||||
|
* Added a function to expand an escaped string.
|
||||||
|
* Added a function to expand the tilde from a path.
|
||||||
|
* Added a proxycommand support.
|
||||||
|
* Added ssh_privatekey_type public function
|
||||||
|
* Added the possibility to define _OPENSSL_DIR and _ZLIB_DIR.
|
||||||
|
* Fixed sftp_chown.
|
||||||
|
* Fixed sftp_rename on protocol version 3.
|
||||||
|
* Fixed a blocking bug in channel_poll.
|
||||||
|
* Fixed config parsing wich has overwritten user specified values.
|
||||||
|
* Fixed hashed [host]:port format in knownhosts
|
||||||
|
* Fixed Windows build.
|
||||||
|
* Fixed doublefree happening after a negociation error.
|
||||||
|
* Fixed aes*-ctr with <= OpenSSL 0.9.7b.
|
||||||
|
* Fixed some documentation.
|
||||||
|
* Fixed exec example which has broken read usage.
|
||||||
|
* Fixed broken algorithm choice for server.
|
||||||
|
* Fixed a typo that we don't export all symbols.
|
||||||
|
* Removed the unneeded dependency to doxygen.
|
||||||
|
* Build examples only on the Linux plattform.
|
||||||
|
|
||||||
|
version 0.4.2 (released 2010-03-15)
|
||||||
|
* Added owner and group information in sftp attributes.
|
||||||
|
* Added missing SSH_OPTIONS_FD option.
|
||||||
|
* Added printout of owner and group in the sftp example.
|
||||||
|
* Added a prepend function for ssh_list.
|
||||||
|
* Added send back replies to openssh's keepalives.
|
||||||
|
* Fixed documentation in scp code
|
||||||
|
* Fixed longname parsing, this only workings with readdir.
|
||||||
|
* Fixed and added support for several identity files.
|
||||||
|
* Fixed sftp_parse_longname() on Windows.
|
||||||
|
* Fixed a race condition bug in ssh_scp_close()
|
||||||
|
* Remove config support for SSHv1 Cipher variable.
|
||||||
|
* Rename ssh_list_add to ssh_list_append.
|
||||||
|
* Rename ssh_list_get_head to ssh_list_pop_head
|
||||||
|
|
||||||
|
version 0.4.1 (released 2010-02-13)
|
||||||
|
* Added support for aes128-ctr, aes192-ctr and aes256-ctr encryption.
|
||||||
|
* Added an example for exec.
|
||||||
|
* Added private key type detection feature in privatekey_from_file().
|
||||||
|
* Fixed zlib compression fallback.
|
||||||
|
* Fixed kex bug that client preference should be prioritary
|
||||||
|
* Fixed known_hosts file set by the user.
|
||||||
|
* Fixed a memleak in channel_accept().
|
||||||
|
* Fixed underflow when leave_function() are unbalanced
|
||||||
|
* Fixed memory corruption in handle_channel_request_open().
|
||||||
|
* Fixed closing of a file handle case of errors in privatekey_from_file().
|
||||||
|
* Fixed ssh_get_user_home_dir() to be thread safe.
|
||||||
|
* Fixed the doxygen documentation.
|
||||||
|
|
||||||
|
version 0.4.0 (released 2009-12-10)
|
||||||
|
* Added scp support.
|
||||||
|
* Added support for sending signals (RFC 4254, section 6.9).
|
||||||
|
* Added MSVC support.
|
||||||
|
* Added support for ~/.ssh/config.
|
||||||
|
* Added sftp extension support.
|
||||||
|
* Added X11 forwarding support for client.
|
||||||
|
* Added forward listening.
|
||||||
|
* Added support for openssh extensions (statvfs, fstatvfs).
|
||||||
|
* Added a cleaned up interface for setting options.
|
||||||
|
* Added a generic way to handle sockets asynchronously.
|
||||||
|
* Added logging of the sftp flags used to open a file.
|
||||||
|
* Added full poll() support and poll-emulation for win32.
|
||||||
|
* Added missing 64bit functions in sftp.
|
||||||
|
* Added support for ~/ and SSH_DIR/ in filenames instead of %s/.
|
||||||
|
* Fixed Fix channel_get_exit_status bug.
|
||||||
|
* Fixed calltrace logging to make it optional.
|
||||||
|
* Fixed compilation on Solaris.
|
||||||
|
* Fixed resolving of ip addresses.
|
||||||
|
* Fixed libssh compilation without server support.
|
||||||
|
* Fixed possible memory corruptions (ticket #14).
|
||||||
|
|
||||||
|
version 0.3.4 (released 2009-09-14)
|
||||||
|
* Added ssh_basename and ssh_dirname.
|
||||||
|
* Added a portable ssh_mkdir function.
|
||||||
|
* Added a sftp_tell64() function.
|
||||||
|
* Added missing NULL pointer checks to crypt_set_algorithms_server.
|
||||||
|
* Fixed ssh_write_knownhost if ~/.ssh doesn't exist.
|
||||||
|
* Fixed a possible integer overflow in buffer_get_data().
|
||||||
|
* Fixed possible security bug in packet_decrypt().
|
||||||
|
* Fixed a possible stack overflow in agent code.
|
||||||
|
|
||||||
|
version 0.3.3 (released 2009-08-18)
|
||||||
|
* Fixed double free pointer crash in dsa_public_to_string.
|
||||||
|
* Fixed channel_get_exit_status bug.
|
||||||
|
* Fixed ssh_finalize which didn't clear the flag.
|
||||||
|
* Fixed memory leak introduced by previous bugfix.
|
||||||
|
* Fixed channel_poll broken when delayed EOF recvd.
|
||||||
|
* Fixed stupid "can't parse known host key" bug.
|
||||||
|
* Fixed possible memory corruption (ticket #14).
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
version 0.3.1 (released 2009-07-14)
|
||||||
|
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||||
|
* Fixed compilation of SSHv1.
|
||||||
|
* Fixed several memory leaks.
|
||||||
|
* Fixed possible infinite loops.
|
||||||
|
* Fixed a possible crash bug.
|
||||||
|
* Fixed build warnings.
|
||||||
|
* Fixed cmake on BSD.
|
||||||
|
version 0.3.1 (released 2009-07-14)
|
||||||
|
* Added return code SSH_SERVER_FILE_NOT_FOUND.
|
||||||
|
* Fixed compilation of SSHv1.
|
||||||
|
* Fixed several memory leaks.
|
||||||
|
* Fixed possible infinite loops.
|
||||||
|
* Fixed a possible crash bug.
|
||||||
|
* Fixed build warnings.
|
||||||
|
* Fixed cmake on BSD.
|
||||||
|
|
||||||
|
version 0.3 (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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
158
ConfigureChecks.cmake
Normal file
158
ConfigureChecks.cmake
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
include(CheckIncludeFile)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(CheckLibraryExists)
|
||||||
|
include(CheckTypeSize)
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
include(TestBigEndian)
|
||||||
|
|
||||||
|
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})
|
||||||
|
|
||||||
|
function(COMPILER_DUMPVERSION _OUTPUT_VERSION)
|
||||||
|
# Remove whitespaces from the argument.
|
||||||
|
# This is needed for CC="ccache gcc" cmake ..
|
||||||
|
string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion
|
||||||
|
OUTPUT_VARIABLE _COMPILER_VERSION
|
||||||
|
)
|
||||||
|
|
||||||
|
string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
|
||||||
|
_COMPILER_VERSION "${_COMPILER_VERSION}")
|
||||||
|
|
||||||
|
set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||||
|
compiler_dumpversion(GNUCC_VERSION)
|
||||||
|
if (NOT GNUCC_VERSION EQUAL 34)
|
||||||
|
check_c_compiler_flag("-fvisibility=hidden" WITH_VISIBILITY_HIDDEN)
|
||||||
|
endif (NOT GNUCC_VERSION EQUAL 34)
|
||||||
|
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||||
|
|
||||||
|
# HEADER FILES
|
||||||
|
check_include_file(argp.h HAVE_ARGP_H)
|
||||||
|
check_include_file(pty.h HAVE_PTY_H)
|
||||||
|
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
check_include_file(wspiapi.h HAVE_WSPIAPI_H)
|
||||||
|
if (NOT HAVE_WSPIAPI_H)
|
||||||
|
message(STATUS "WARNING: Without wspiapi.h, this build will only work on Windows XP and newer versions")
|
||||||
|
endif (NOT HAVE_WSPIAPI_H)
|
||||||
|
check_include_file(ws2tcpip.h HAVE_WS2TCPIP_H)
|
||||||
|
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
|
||||||
|
set(HAVE_GETADDRINFO TRUE)
|
||||||
|
set(HAVE_GETHOSTBYNAME TRUE)
|
||||||
|
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
|
||||||
|
|
||||||
|
set(HAVE_SELECT TRUE)
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||||
|
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||||
|
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||||
|
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
|
||||||
|
|
||||||
|
if (CMAKE_HAVE_PTHREAD_H)
|
||||||
|
set(HAVE_PTHREAD_H 1)
|
||||||
|
endif (CMAKE_HAVE_PTHREAD_H)
|
||||||
|
|
||||||
|
# FUNCTIONS
|
||||||
|
|
||||||
|
check_function_exists(strncpy HAVE_STRNCPY)
|
||||||
|
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||||
|
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
|
||||||
|
check_function_exists(_vsnprintf HAVE__VSNPRINTF)
|
||||||
|
check_function_exists(_snprintf HAVE__SNPRINTF)
|
||||||
|
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
if (NOT LINUX)
|
||||||
|
# libsocket (Solaris)
|
||||||
|
check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET)
|
||||||
|
if (HAVE_LIBSOCKET)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} socket)
|
||||||
|
endif (HAVE_LIBSOCKET)
|
||||||
|
|
||||||
|
# libresolv
|
||||||
|
check_library_exists(resolv hstrerror "" HAVE_LIBRESOLV)
|
||||||
|
if (HAVE_LIBRESOLV)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} resolv)
|
||||||
|
endif (HAVE_LIBRESOLV)
|
||||||
|
|
||||||
|
# libnsl/inet_pton (Solaris)
|
||||||
|
check_library_exists(nsl inet_pton "" HAVE_LIBNSL)
|
||||||
|
if (HAVE_LIBNSL)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} nsl)
|
||||||
|
endif (HAVE_LIBNSL)
|
||||||
|
|
||||||
|
# librt
|
||||||
|
check_library_exists(rt nanosleep "" HAVE_LIBRT)
|
||||||
|
endif (NOT LINUX)
|
||||||
|
|
||||||
|
check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
|
||||||
|
if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
|
||||||
|
endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
|
||||||
|
|
||||||
|
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
|
||||||
|
check_function_exists(poll HAVE_POLL)
|
||||||
|
check_function_exists(select HAVE_SELECT)
|
||||||
|
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
|
||||||
|
check_function_exists(regcomp HAVE_REGCOMP)
|
||||||
|
check_function_exists(ntohll HAVE_NTOHLL)
|
||||||
|
endif (UNIX)
|
||||||
|
|
||||||
|
set(LIBSSH_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "libssh required system libraries")
|
||||||
|
|
||||||
|
# LIBRARIES
|
||||||
|
if (OPENSSL_FOUND)
|
||||||
|
set(HAVE_LIBCRYPTO 1)
|
||||||
|
endif (OPENSSL_FOUND)
|
||||||
|
|
||||||
|
if (GCRYPT_FOUND)
|
||||||
|
set(HAVE_LIBGCRYPT 1)
|
||||||
|
endif (GCRYPT_FOUND)
|
||||||
|
|
||||||
|
if (ZLIB_LIBRARY)
|
||||||
|
set(HAVE_LIBZ 1)
|
||||||
|
endif (ZLIB_LIBRARY)
|
||||||
|
|
||||||
|
if (CMAKE_HAVE_THREADS_LIBRARY)
|
||||||
|
if (CMAKE_USE_PTHREADS_INIT)
|
||||||
|
set(HAVE_PTHREAD 1)
|
||||||
|
endif (CMAKE_USE_PTHREADS_INIT)
|
||||||
|
endif (CMAKE_HAVE_THREADS_LIBRARY)
|
||||||
|
|
||||||
|
# OPTIONS
|
||||||
|
if (WITH_DEBUG_CRYPTO)
|
||||||
|
set(DEBUG_CRYPTO 1)
|
||||||
|
endif (WITH_DEBUG_CRYPTO)
|
||||||
|
|
||||||
|
if (WITH_DEBUG_CALLTRACE)
|
||||||
|
set(DEBUG_CALLTRACE 1)
|
||||||
|
endif (WITH_DEBUG_CALLTRACE)
|
||||||
|
|
||||||
|
# ENDIAN
|
||||||
|
if (NOT WIN32)
|
||||||
|
test_big_endian(WORDS_BIGENDIAN)
|
||||||
|
endif (NOT WIN32)
|
||||||
21
DefineOptions.cmake
Normal file
21
DefineOptions.cmake
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
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 debug output" OFF)
|
||||||
|
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
|
||||||
|
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
|
||||||
|
option(WITH_PCAP "Compile with Pcap generation support" ON)
|
||||||
|
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
|
||||||
|
option(WITH_TESTING "Build with unit tests" OFF)
|
||||||
|
option(WITH_CLIENT_TESTING "Build with client tests; requires a running sshd" OFF)
|
||||||
|
option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
|
||||||
|
|
||||||
|
if(WITH_BENCHMARKS)
|
||||||
|
set(WITH_TESTING ON)
|
||||||
|
endif(WITH_BENCHMARKS)
|
||||||
|
|
||||||
|
if (WITH_TESTING)
|
||||||
|
set(WITH_STATIC_LIB ON)
|
||||||
|
endif (WITH_TESTING)
|
||||||
260
INSTALL
260
INSTALL
@@ -1,236 +1,80 @@
|
|||||||
Installation Instructions
|
# How to build from source
|
||||||
*************************
|
|
||||||
|
|
||||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
## Requirements
|
||||||
Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is free documentation; the Free Software Foundation gives
|
### Common requirements
|
||||||
unlimited permission to copy, distribute and modify it.
|
|
||||||
|
|
||||||
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
|
optional:
|
||||||
various system-dependent variables used during compilation. It uses
|
- [libz](http://www.zlib.net) >= 1.2
|
||||||
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').
|
|
||||||
|
|
||||||
It can also use an optional file (typically called `config.cache'
|
Note that these version numbers are version we know works correctly. If you
|
||||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
build and run libssh successfully with an older version, please let us know.
|
||||||
the results of its tests to speed up reconfiguring. (Caching is
|
|
||||||
disabled by default to prevent problems with accidental use of stale
|
|
||||||
cache files.)
|
|
||||||
|
|
||||||
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
|
## Building
|
||||||
`configure' by a program called `autoconf'. You only need
|
First, you need to configure the compilation, using CMake. Go inside the
|
||||||
`configure.ac' if you want to change it or regenerate `configure' using
|
`build` dir. Create it if it doesn't exist.
|
||||||
a newer version of `autoconf'.
|
|
||||||
|
|
||||||
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
|
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
`./configure' to configure the package for your system. If you're
|
make
|
||||||
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.
|
|
||||||
|
|
||||||
Running `configure' takes awhile. While running, it prints some
|
### CMake standard options
|
||||||
messages telling which features it is checking for.
|
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
|
### CMake options defined for libssh
|
||||||
the package.
|
|
||||||
|
|
||||||
4. Type `make install' to install the programs and any data files and
|
Options are defined in the following files:
|
||||||
documentation.
|
|
||||||
|
|
||||||
5. You can remove the program binaries and object files from the
|
- DefineOptions.cmake
|
||||||
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.
|
|
||||||
|
|
||||||
Compilers and Options
|
They can be changed with the -D option:
|
||||||
=====================
|
|
||||||
|
|
||||||
Some systems require unusual options for compilation or linking that the
|
`cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DWITH_LIBZ=OFF ..`
|
||||||
`configure' script does not know about. Run `./configure --help' for
|
|
||||||
details on some of the pertinent environment variables.
|
|
||||||
|
|
||||||
You can give `configure' initial values for configuration parameters
|
### Browsing/editing CMake options
|
||||||
by setting variables in the command line or in the environment. Here
|
|
||||||
is an example:
|
|
||||||
|
|
||||||
./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
|
If you want to install libssh after compilation run:
|
||||||
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 have to use a `make' that does not support the `VPATH'
|
make install
|
||||||
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.
|
|
||||||
|
|
||||||
Installation Names
|
## Running
|
||||||
==================
|
|
||||||
|
|
||||||
By default, `make install' installs the package's commands under
|
The libssh binary can be found in the `build/libssh` directory.
|
||||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
You can use `build/examples/samplessh` which is a sample client to
|
||||||
can specify an installation prefix other than `/usr/local' by giving
|
test libssh on UNIX.
|
||||||
`configure' the option `--prefix=PREFIX'.
|
|
||||||
|
|
||||||
You can specify separate installation prefixes for
|
## About this document
|
||||||
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.
|
|
||||||
|
|
||||||
In addition, if you use an unusual directory layout you can give
|
This document is written using [Markdown][] syntax, making it possible to
|
||||||
options like `--bindir=DIR' to specify different values for particular
|
provide usable information in both plain text and HTML format. Whenever
|
||||||
kinds of files. Run `configure --help' for a list of the directories
|
modifying this document please use [Markdown][] syntax.
|
||||||
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.
|
|
||||||
|
|
||||||
|
[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
|
|
||||||
72
README
72
README
@@ -1,14 +1,14 @@
|
|||||||
The libSSH and its client
|
libssh: the SSH library
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
-Aris Adamantiadis
|
|
||||||
|
|
||||||
1* Why ?
|
1* Why ?
|
||||||
-_-_-_-_-_
|
-_-_-_-_-_
|
||||||
|
|
||||||
Why not ? :) I've began to work on my own implementation of the ssh protocol
|
Why not ? :) I've began to work on my own implementation of the ssh protocol
|
||||||
because i didn't like the currently public ones.
|
because i didn't like the currently public ones.
|
||||||
Not any allow you to import and use the functions as a library, and so i
|
Not any allowed you to import and use the functions as a powerful library,
|
||||||
worked on a library-based SSH implementation.
|
and so i worked on a library-based SSH implementation which was non-existing
|
||||||
|
in the free and open source software world.
|
||||||
|
|
||||||
|
|
||||||
2* How/Who ?
|
2* How/Who ?
|
||||||
@@ -16,24 +16,56 @@ worked on a library-based SSH implementation.
|
|||||||
|
|
||||||
If you downloaded this file, you must know what it is : a library for
|
If you downloaded this file, you must know what it is : a library for
|
||||||
accessing ssh client services through C libraries calls in a simple manner.
|
accessing ssh client services through C libraries calls in a simple manner.
|
||||||
The client is there as a programming example and isn't at all doing its job
|
|
||||||
correctly (doesn't verify public key hashes with the ones in ~/.ssh/
|
|
||||||
and doesn't handle TERM - yet)
|
|
||||||
Everybody can use this software under the terms of the LGPL - see the COPYING
|
Everybody can use this software under the terms of the LGPL - see the COPYING
|
||||||
file
|
file
|
||||||
|
|
||||||
3* What ?
|
If you ask yourself how to compile libssh, please read INSTALL before anything.
|
||||||
-_-_-_-_-_
|
|
||||||
|
|
||||||
The SSH library features :
|
3* Where ?
|
||||||
-Full C library functions for manipulating a client-side SSH connection
|
|
||||||
-Fully configurable sessions
|
|
||||||
-Support for AES-128,AES-192,AES-256,blowfish, in cbc mode
|
|
||||||
-use multiple SSH connections in a same process, at same time.
|
|
||||||
-usable SFTP implementation
|
|
||||||
-Public key and password authentication
|
|
||||||
|
|
||||||
4* Where ?
|
|
||||||
-_-_-_-_-_-_
|
-_-_-_-_-_-_
|
||||||
|
|
||||||
http://0xbadc0de.be/?part=libssh
|
http://www.libssh.org
|
||||||
|
|
||||||
|
4* API Changes !
|
||||||
|
-_-_-_-_-_-_-_-_-_
|
||||||
|
|
||||||
|
Changes between 0.4 and 0.5
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
We use the ssh_ prefix as namespace for every function now. There is a legacy.h
|
||||||
|
which could be used to get the old function names.
|
||||||
|
|
||||||
|
Changes between 0.3 and 0.4
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
We changed libssh to be typesafe now:
|
||||||
|
|
||||||
|
SSH_SESSION *session -> ssh_session session
|
||||||
|
SFTP_SESSION *sftp -> sftp_session sftp
|
||||||
|
CHANNEL *channel -> ssh_channel channel
|
||||||
|
STRING *string -> ssh_string string
|
||||||
|
...
|
||||||
|
|
||||||
|
The options structure has been removed and there is a new function. This
|
||||||
|
function can set all available options now. You can find the enum in the
|
||||||
|
header file and it is documented. Example:
|
||||||
|
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||||
|
|
||||||
|
5* Copyright policy
|
||||||
|
-_-_-_-_-_-_-_-_-_-_
|
||||||
|
|
||||||
|
The developers of libssh have a policy of asking for contributions to be made
|
||||||
|
under the personal copyright of the contributor, instead of a corporate
|
||||||
|
copyright.
|
||||||
|
|
||||||
|
There are some reasons for the establishment of this policy:
|
||||||
|
|
||||||
|
* Individual copyrights make copyright registration in the US a simpler
|
||||||
|
process.
|
||||||
|
* If libssh is copyrighted by individuals rather than corporations,
|
||||||
|
decisions regarding enforcement and protection of copyright will, more
|
||||||
|
likely, be made in the interests of the project, and not in the interests
|
||||||
|
of any corporation’s shareholders.
|
||||||
|
* If we ever need to relicense a portion of the code contacting individuals
|
||||||
|
for permission to do so is much easier than contacting a company.
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
aclocal
|
|
||||||
libtoolize --force --copy
|
|
||||||
autoheader
|
|
||||||
autoconf
|
|
||||||
automake --add-missing --copy --gnu
|
|
||||||
./configure $@
|
|
||||||
197
build/build_make.sh
Executable file
197
build/build_make.sh
Executable file
@@ -0,0 +1,197 @@
|
|||||||
|
#!/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() {
|
||||||
|
if [ -n "${CMAKEDIR}" ]; then
|
||||||
|
${CMAKEDIR}/bin/cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||||
|
else
|
||||||
|
cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function compile() {
|
||||||
|
if [ -f /proc/cpuinfo ]; then
|
||||||
|
CPUCOUNT=$(grep -c processor /proc/cpuinfo)
|
||||||
|
elif test `uname` = "SunOS" ; then
|
||||||
|
CPUCOUNT=$(psrinfo -p)
|
||||||
|
else
|
||||||
|
CPUCOUNT="1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${CPUCOUNT}" -gt "1" ]; then
|
||||||
|
${MAKE} -j${CPUCOUNT} $1 || cleanup_and_exit $?
|
||||||
|
else
|
||||||
|
${MAKE} $1 || exit $?
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean_build_dir() {
|
||||||
|
find ! -path "*.svn*" ! -name "*.bat" ! -name "*.sh" ! -name "." -print0 | xargs -0 rm -rf
|
||||||
|
}
|
||||||
|
|
||||||
|
function usage () {
|
||||||
|
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make
|
||||||
|
(gmake|make)|--ccompiler (gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withssh1|--withserver]"
|
||||||
|
cleanup_and_exit
|
||||||
|
}
|
||||||
|
|
||||||
|
cd ${BUILDDIR}
|
||||||
|
|
||||||
|
# the default CMake options:
|
||||||
|
OPTIONS="--graphviz=${BUILDDIR}/libssh.dot"
|
||||||
|
|
||||||
|
# the default 'make' utility:
|
||||||
|
MAKE="make"
|
||||||
|
|
||||||
|
while test -n "$1"; do
|
||||||
|
PARAM="$1"
|
||||||
|
ARG="$2"
|
||||||
|
shift
|
||||||
|
case ${PARAM} in
|
||||||
|
*-*=*)
|
||||||
|
ARG=${PARAM#*=}
|
||||||
|
PARAM=${PARAM%%=*}
|
||||||
|
set -- "----noarg=${PARAM}" "$@"
|
||||||
|
esac
|
||||||
|
case ${PARAM} in
|
||||||
|
*-help|-h)
|
||||||
|
#echo_help
|
||||||
|
usage
|
||||||
|
cleanup_and_exit
|
||||||
|
;;
|
||||||
|
*-build)
|
||||||
|
DOMAKE="1"
|
||||||
|
BUILD_TYPE="${ARG}"
|
||||||
|
test -n "${BUILD_TYPE}" && shift
|
||||||
|
;;
|
||||||
|
*-clean)
|
||||||
|
clean_build_dir
|
||||||
|
cleanup_and_exit
|
||||||
|
;;
|
||||||
|
*-clang)
|
||||||
|
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
|
||||||
|
;;
|
||||||
|
*-verbose)
|
||||||
|
DOVERBOSE="1"
|
||||||
|
;;
|
||||||
|
*-memtest)
|
||||||
|
OPTIONS="${OPTIONS} -DMEM_NULL_TESTS=ON"
|
||||||
|
;;
|
||||||
|
*-libsuffix)
|
||||||
|
OPTIONS="${OPTIONS} -DLIB_SUFFIX=${ARG}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*-prefix)
|
||||||
|
OPTIONS="${OPTIONS} -DCMAKE_INSTALL_PREFIX=${ARG}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*-sysconfdir)
|
||||||
|
OPTIONS="${OPTIONS} -DSYSCONF_INSTALL_DIR=${ARG}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*-cmakedir)
|
||||||
|
CMAKEDIR="${ARG}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*-make)
|
||||||
|
MAKE="${ARG}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*-ccompiler)
|
||||||
|
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=${ARG}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*-withstaticlib)
|
||||||
|
OPTIONS="${OPTIONS} -DWITH_STATIC_LIB=ON"
|
||||||
|
;;
|
||||||
|
*-unittesting)
|
||||||
|
OPTIONS="${OPTIONS} -DWITH_TESTING=ON"
|
||||||
|
;;
|
||||||
|
*-clientunittesting)
|
||||||
|
OPTIONS="${OPTIONS} -DWITH_CLIENT_TESTING=ON"
|
||||||
|
;;
|
||||||
|
*-withssh1)
|
||||||
|
OPTIONS="${OPTIONS} -DWITH_SSH1=ON"
|
||||||
|
;;
|
||||||
|
*-withserver)
|
||||||
|
OPTIONS="${OPTIONS} -DWITH_SERVER=ON"
|
||||||
|
;;
|
||||||
|
----noarg)
|
||||||
|
echo "$ARG does not take an argument"
|
||||||
|
cleanup_and_exit
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo Unknown Option "$PARAM". Exit.
|
||||||
|
cleanup_and_exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${DOMAKE}" == "1" ]; then
|
||||||
|
OPTIONS="${OPTIONS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${DOVERBOSE}" ]; then
|
||||||
|
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=1"
|
||||||
|
else
|
||||||
|
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -f "${BUILDDIR}/.build.log" && rm -f ${BUILDDIR}/.build.log
|
||||||
|
touch ${BUILDDIR}/.build.log
|
||||||
|
# log everything from here to .build.log
|
||||||
|
exec 1> >(exec -a 'build logging tee' tee -a ${BUILDDIR}/.build.log) 2>&1
|
||||||
|
echo "${HOST} started build at $(date)."
|
||||||
|
echo
|
||||||
|
|
||||||
|
configure ${OPTIONS} "$@"
|
||||||
|
|
||||||
|
if [ -n "${DOMAKE}" ]; then
|
||||||
|
test -n "${DOVERBOSE}" && compile VERBOSE=1 || compile
|
||||||
|
fi
|
||||||
|
|
||||||
|
DOT=$(which dot 2>/dev/null)
|
||||||
|
if [ -n "${DOT}" ]; then
|
||||||
|
${DOT} -Tpng -o${BUILDDIR}/libssh.png ${BUILDDIR}/libssh.dot
|
||||||
|
${DOT} -Tsvg -o${BUILDDIR}/libssh.svg ${BUILDDIR}/libssh.dot
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec >&0 2>&0 # so that the logging tee finishes
|
||||||
|
sleep 1 # wait till tee terminates
|
||||||
|
|
||||||
|
cleanup_and_exit 0
|
||||||
23
cmake/Modules/AddCMockeryTest.cmake
Normal file
23
cmake/Modules/AddCMockeryTest.cmake
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# - ADD_CHECK_TEST(test_name test_source linklib1 ... linklibN)
|
||||||
|
|
||||||
|
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
||||||
|
# Copyright (c) 2007-2010 Andreas Schneider <asn@cynapses.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
|
||||||
|
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||||
|
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||||
|
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
|
||||||
|
|
||||||
|
function (ADD_CMOCKERY_TEST _testName _testSource)
|
||||||
|
add_executable(${_testName} ${_testSource})
|
||||||
|
target_link_libraries(${_testName} ${ARGN})
|
||||||
|
add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName})
|
||||||
|
endfunction (ADD_CMOCKERY_TEST)
|
||||||
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)
|
||||||
71
cmake/Modules/DefineCompilerFlags.cmake
Normal file
71
cmake/Modules/DefineCompilerFlags.cmake
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# define system dependent compiler flags
|
||||||
|
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
include(MacroCheckCCompilerFlagSSP)
|
||||||
|
|
||||||
|
if (UNIX AND NOT WIN32)
|
||||||
|
#
|
||||||
|
# Define GNUCC compiler flags
|
||||||
|
#
|
||||||
|
if (${CMAKE_C_COMPILER_ID} MATCHES GNU)
|
||||||
|
# add -Wconversion ?
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
|
||||||
|
|
||||||
|
# with -fPIC
|
||||||
|
check_c_compiler_flag("-fPIC" WITH_FPIC)
|
||||||
|
if (WITH_FPIC)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||||
|
endif (WITH_FPIC)
|
||||||
|
|
||||||
|
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||||
|
if (WITH_STACK_PROTECTOR)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
|
||||||
|
endif (WITH_STACK_PROTECTOR)
|
||||||
|
|
||||||
|
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
|
||||||
|
if (WITH_FORTIFY_SOURCE)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2")
|
||||||
|
endif (WITH_FORTIFY_SOURCE)
|
||||||
|
endif (${CMAKE_C_COMPILER_ID} MATCHES GNU)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check for large filesystem support
|
||||||
|
#
|
||||||
|
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
|
||||||
|
)
|
||||||
|
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||||
|
if (_lfs_CFLAGS)
|
||||||
|
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}")
|
||||||
|
endif (_lfs_CFLAGS)
|
||||||
|
|
||||||
|
endif (UNIX AND NOT WIN32)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# Use secure functions by defaualt and suppress warnings about
|
||||||
|
#"deprecated" functions
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
||||||
|
endif (MSVC)
|
||||||
104
cmake/Modules/DefineInstallationPaths.cmake
Normal file
104
cmake/Modules/DefineInstallationPaths.cmake
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
if (WIN32)
|
||||||
|
# Same same
|
||||||
|
set(BIN_INSTALL_DIR "bin" 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 "-")
|
||||||
|
elseif (UNIX OR OS2)
|
||||||
|
IF (NOT APPLICATION_NAME)
|
||||||
|
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
|
||||||
|
SET(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
|
ENDIF (NOT APPLICATION_NAME)
|
||||||
|
|
||||||
|
# Suffix for Linux
|
||||||
|
SET(LIB_SUFFIX
|
||||||
|
CACHE STRING "Define suffix of directory name (32/64)"
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(EXEC_INSTALL_PREFIX
|
||||||
|
"${CMAKE_INSTALL_PREFIX}"
|
||||||
|
CACHE PATH "Base directory for executables and libraries"
|
||||||
|
)
|
||||||
|
SET(SHARE_INSTALL_PREFIX
|
||||||
|
"${CMAKE_INSTALL_PREFIX}/share"
|
||||||
|
CACHE PATH "Base directory for files which go to share/"
|
||||||
|
)
|
||||||
|
SET(DATA_INSTALL_PREFIX
|
||||||
|
"${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}"
|
||||||
|
CACHE PATH "The parent directory where applications can install their data")
|
||||||
|
|
||||||
|
# The following are directories where stuff will be installed to
|
||||||
|
SET(BIN_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/bin"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)"
|
||||||
|
)
|
||||||
|
SET(SBIN_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/sbin"
|
||||||
|
CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)"
|
||||||
|
)
|
||||||
|
SET(LIB_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}"
|
||||||
|
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)"
|
||||||
|
)
|
||||||
|
SET(LIBEXEC_INSTALL_DIR
|
||||||
|
"${EXEC_INSTALL_PREFIX}/libexec"
|
||||||
|
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
|
||||||
|
)
|
||||||
|
SET(PLUGIN_INSTALL_DIR
|
||||||
|
"${LIB_INSTALL_DIR}/${APPLICATION_NAME}"
|
||||||
|
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})"
|
||||||
|
)
|
||||||
|
SET(INCLUDE_INSTALL_DIR
|
||||||
|
"${CMAKE_INSTALL_PREFIX}/include"
|
||||||
|
CACHE PATH "The subdirectory to the header prefix (default prefix/include)"
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(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 ()
|
||||||
28
cmake/Modules/DefinePlatformDefaults.cmake
Normal file
28
cmake/Modules/DefinePlatformDefaults.cmake
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Set system vars
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
set(LINUX TRUE)
|
||||||
|
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
set(FREEBSD TRUE)
|
||||||
|
set(BSD TRUE)
|
||||||
|
endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||||
|
set(OPENBSD TRUE)
|
||||||
|
set(BSD TRUE)
|
||||||
|
endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||||
|
set(NETBSD TRUE)
|
||||||
|
set(BSD TRUE)
|
||||||
|
endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||||
|
set(SOLARIS TRUE)
|
||||||
|
endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||||
|
set(OS2 TRUE)
|
||||||
|
endif (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||||
60
cmake/Modules/FindArgp.cmake
Normal file
60
cmake/Modules/FindArgp.cmake
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# - Try to find Argp
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# ARGP_FOUND - system has Argp
|
||||||
|
# ARGP_INCLUDE_DIRS - the Argp include directory
|
||||||
|
# ARGP_LIBRARIES - Link these to use Argp
|
||||||
|
# ARGP_DEFINITIONS - Compiler switches required for using Argp
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Andreas Schneider <asn@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 (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
|
||||||
|
# in cache already
|
||||||
|
set(ARGP_FOUND TRUE)
|
||||||
|
else (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
find_path(ARGP_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
argp.h
|
||||||
|
PATHS
|
||||||
|
/usr/include
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(ARGP_LIBRARY
|
||||||
|
NAMES
|
||||||
|
argp
|
||||||
|
PATHS
|
||||||
|
/usr/lib
|
||||||
|
/usr/local/lib
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
set(ARGP_INCLUDE_DIRS
|
||||||
|
${ARGP_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (ARGP_LIBRARY)
|
||||||
|
set(ARGP_LIBRARIES
|
||||||
|
${ARGP_LIBRARIES}
|
||||||
|
${ARGP_LIBRARY}
|
||||||
|
)
|
||||||
|
endif (ARGP_LIBRARY)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Argp DEFAULT_MSG ARGP_LIBRARIES ARGP_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
# show the ARGP_INCLUDE_DIRS and ARGP_LIBRARIES variables only in the advanced view
|
||||||
|
mark_as_advanced(ARGP_INCLUDE_DIRS ARGP_LIBRARIES)
|
||||||
|
|
||||||
|
endif (ARGP_LIBRARIES AND ARGP_INCLUDE_DIRS)
|
||||||
|
|
||||||
63
cmake/Modules/FindCMockery.cmake
Normal file
63
cmake/Modules/FindCMockery.cmake
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# - Try to find CMockery
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# CMOCKERY_FOUND - system has CMockery
|
||||||
|
# CMOCKERY_INCLUDE_DIRS - the CMockery include directory
|
||||||
|
# CMOCKERY_LIBRARIES - Link these to use CMockery
|
||||||
|
# CMOCKERY_DEFINITIONS - Compiler switches required for using CMockery
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.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 (CMOCKERY_LIBRARIES AND CMOCKERY_INCLUDE_DIRS)
|
||||||
|
# in cache already
|
||||||
|
set(CMOCKERY_FOUND TRUE)
|
||||||
|
else (CMOCKERY_LIBRARIES AND CMOCKERY_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
find_path(CMOCKERY_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
google/cmockery.h
|
||||||
|
PATHS
|
||||||
|
${_CMOCKERY_DIR}/include
|
||||||
|
/usr/include
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
$ENV{PROGRAMFILES}/cmockery/include
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(CMOCKERY_LIBRARY
|
||||||
|
NAMES
|
||||||
|
cmockery
|
||||||
|
PATHS
|
||||||
|
${_CMOCKERY_DIR}/lib
|
||||||
|
/usr/lib
|
||||||
|
/usr/local/lib
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
$ENV{PROGRAMFILES}/cmockery/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMOCKERY_INCLUDE_DIRS
|
||||||
|
${CMOCKERY_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (CMOCKERY_LIBRARY)
|
||||||
|
set(CMOCKERY_LIBRARIES
|
||||||
|
${CMOCKERY_LIBRARIES}
|
||||||
|
${CMOCKERY_LIBRARY}
|
||||||
|
)
|
||||||
|
endif (CMOCKERY_LIBRARY)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(CMockery DEFAULT_MSG CMOCKERY_LIBRARIES CMOCKERY_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
# show the CMOCKERY_INCLUDE_DIRS and CMOCKERY_LIBRARIES variables only in the advanced view
|
||||||
|
mark_as_advanced(CMOCKERY_INCLUDE_DIRS CMOCKERY_LIBRARIES)
|
||||||
|
|
||||||
|
endif (CMOCKERY_LIBRARIES AND CMOCKERY_INCLUDE_DIRS)
|
||||||
70
cmake/Modules/FindGCrypt.cmake
Normal file
70
cmake/Modules/FindGCrypt.cmake
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# - 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-2011 Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
#
|
||||||
|
|
||||||
|
if (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
|
||||||
|
# in cache already
|
||||||
|
# set(GCRYPT_FOUND TRUE)
|
||||||
|
else (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
set(_GCRYPT_ROOT_PATHS
|
||||||
|
"$ENV{PROGRAMFILES}/libgcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_path(GCRYPT_ROOT_DIR
|
||||||
|
NAMES
|
||||||
|
include/gcrypt.h
|
||||||
|
PATHS
|
||||||
|
${_GCRYPT_ROOT_PATHS}
|
||||||
|
)
|
||||||
|
mark_as_advanced(ZLIB_ROOT_DIR)
|
||||||
|
|
||||||
|
find_path(GCRYPT_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
gcrypt.h
|
||||||
|
PATHS
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
/usr/lib/sfw/include
|
||||||
|
${GCRYPT_ROOT_DIR}/include
|
||||||
|
)
|
||||||
|
set(GCRYPT_INCLUDE_DIRS ${GCRYPT_INCLUDE_DIR})
|
||||||
|
|
||||||
|
find_library(GCRYPT_LIBRARY
|
||||||
|
NAMES
|
||||||
|
gcrypt
|
||||||
|
gcrypt11
|
||||||
|
libgcrypt-11
|
||||||
|
PATHS
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
/usr/sfw/lib/64
|
||||||
|
/usr/sfw/lib
|
||||||
|
${GCRYPT_ROOT_DIR}/lib
|
||||||
|
)
|
||||||
|
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(GCrypt DEFAULT_MSG GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
# 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)
|
||||||
39
cmake/Modules/FindNSIS.cmake
Normal file
39
cmake/Modules/FindNSIS.cmake
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# - Try to find NSIS
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# NSIS_ROOT_DIR - Set this variable to the root installation of ZLIB
|
||||||
|
#
|
||||||
|
# Read-Only variables:
|
||||||
|
# NSIS_FOUND - system has NSIS
|
||||||
|
# NSIS_MAKE - NSIS creator executable
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright (c) 2010-2011 Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
#
|
||||||
|
|
||||||
|
set(_NSIS_ROOT_PATHS
|
||||||
|
C:/NSIS/Bin
|
||||||
|
"$ENV{PROGRAMFILES}/NSIS"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_program(NSIS_MAKE
|
||||||
|
NAMES
|
||||||
|
makensis
|
||||||
|
PATHS
|
||||||
|
${NSIS_ROOT_PATH}
|
||||||
|
${NSIS_ROOT_PATH}/Bin
|
||||||
|
${_NSIS_ROOT_PATHS}
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE)
|
||||||
|
|
||||||
|
mark_as_advanced(NSIS_MAKE)
|
||||||
208
cmake/Modules/FindOpenSSL.cmake
Normal file
208
cmake/Modules/FindOpenSSL.cmake
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
# - Try to find OpenSSL
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
|
||||||
|
#
|
||||||
|
# Read-Only variables:
|
||||||
|
# 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) 2006-2009 Kitware, Inc.
|
||||||
|
# Copyright (c) 2006 Alexander Neundorf <neundorf@kde.org>
|
||||||
|
# Copyright (c) 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||||
|
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
#
|
||||||
|
|
||||||
|
if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||||
|
# in cache already
|
||||||
|
set(OPENSSL_FOUND TRUE)
|
||||||
|
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
find_package(PkgConfig)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(_OPENSSL openssl)
|
||||||
|
endif (PKG_CONFIG_FOUND)
|
||||||
|
endif (UNIX)
|
||||||
|
|
||||||
|
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||||
|
set(_OPENSSL_ROOT_HINTS
|
||||||
|
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||||
|
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_OPENSSL_ROOT_PATHS
|
||||||
|
"C:/OpenSSL/"
|
||||||
|
"C:/OpenSSL-Win32/"
|
||||||
|
"C:/OpenSSL-Win64/"
|
||||||
|
"$ENV{PROGRAMFILES}/OpenSSL"
|
||||||
|
"$ENV{PROGRAMFILES}/OpenSSL-Win32"
|
||||||
|
"$ENV{PROGRAMFILES}/OpenSSL-Win64"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_path(OPENSSL_ROOT_DIR
|
||||||
|
NAMES
|
||||||
|
include/openssl/ssl.h
|
||||||
|
HINTS
|
||||||
|
${_OPENSSL_ROOT_HINTS}
|
||||||
|
PATHS
|
||||||
|
${_OPENSSL_ROOT_PATHS}
|
||||||
|
)
|
||||||
|
mark_as_advanced(OPENSSL_ROOT_DIR)
|
||||||
|
|
||||||
|
find_path(OPENSSL_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
openssl/ssl.h
|
||||||
|
PATHS
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
/usr/lib/sfw/include
|
||||||
|
${OPENSSL_ROOT_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
||||||
|
mark_as_advanced(OPENSSL_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
if (WIN32 AND NOT CYGWIN)
|
||||||
|
# MINGW should go here too
|
||||||
|
if (MSVC)
|
||||||
|
# /MD and /MDd are the standard values - if someone wants to use
|
||||||
|
# others, the libnames have to change here too
|
||||||
|
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
|
||||||
|
# TODO: handle /MT and static lib
|
||||||
|
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
|
||||||
|
# * MD for dynamic-release
|
||||||
|
# * MDd for dynamic-debug
|
||||||
|
# * MT for static-release
|
||||||
|
# * MTd for static-debug
|
||||||
|
|
||||||
|
# Implementation details:
|
||||||
|
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
|
||||||
|
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||||
|
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||||
|
find_library(LIB_EAY_DEBUG
|
||||||
|
NAMES
|
||||||
|
libeay32MDd
|
||||||
|
libeay32
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib/VC
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(LIB_EAY_RELEASE
|
||||||
|
NAMES
|
||||||
|
libeay32MD
|
||||||
|
libeay32
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib/VC
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SSL_EAY_DEBUG
|
||||||
|
NAMES
|
||||||
|
ssleay32MDd
|
||||||
|
ssleay32
|
||||||
|
ssl
|
||||||
|
PATHS ${OPENSSL_ROOT_DIR}/lib/VC
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SSL_EAY_RELEASE
|
||||||
|
NAMES
|
||||||
|
ssleay32MD
|
||||||
|
ssleay32
|
||||||
|
ssl
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib/VC
|
||||||
|
)
|
||||||
|
|
||||||
|
if (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||||
|
set(OPENSSL_LIBRARIES
|
||||||
|
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
|
||||||
|
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
|
||||||
|
)
|
||||||
|
else (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||||
|
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||||
|
endif (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
|
||||||
|
|
||||||
|
mark_as_advanced(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
||||||
|
mark_as_advanced(LIB_EAY_DEBUG LIB_EAY_RELEASE)
|
||||||
|
elseif (MINGW)
|
||||||
|
# same player, for MingW
|
||||||
|
find_library(LIB_EAY
|
||||||
|
NAMES
|
||||||
|
libeay32
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib/MinGW
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SSL_EAY
|
||||||
|
NAMES
|
||||||
|
ssleay32
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib/MinGW
|
||||||
|
)
|
||||||
|
|
||||||
|
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||||
|
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
|
||||||
|
else(MSVC)
|
||||||
|
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
|
||||||
|
find_library(LIB_EAY
|
||||||
|
NAMES
|
||||||
|
libeay32
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SSL_EAY
|
||||||
|
NAMES
|
||||||
|
ssleay32
|
||||||
|
PATHS
|
||||||
|
${OPENSSL_ROOT_DIR}/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||||
|
set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY})
|
||||||
|
endif(MSVC)
|
||||||
|
else (WIN32 AND NOT CYGWIN)
|
||||||
|
find_library(OPENSSL_SSL_LIBRARIES
|
||||||
|
NAMES
|
||||||
|
ssl
|
||||||
|
ssleay32
|
||||||
|
ssleay32MD
|
||||||
|
PATHS
|
||||||
|
${_OPENSSL_LIBDIR}
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
/usr/sfw/lib/64
|
||||||
|
/usr/sfw/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(OPENSSL_CRYPTO_LIBRARIES
|
||||||
|
NAMES
|
||||||
|
crypto
|
||||||
|
PATHS
|
||||||
|
${_OPENSSL_LIBDIR}
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
/usr/sfw/lib/64
|
||||||
|
/usr/sfw/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
mark_as_advanced(OPENSSL_CRYPTO_LIBRARIES OPENSSL_SSL_LIBRARIES)
|
||||||
|
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
||||||
|
endif (WIN32 AND NOT CYGWIN)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(OpenSSL DEFAULT_MSG OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
endif (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||||
119
cmake/Modules/FindZLIB.cmake
Normal file
119
cmake/Modules/FindZLIB.cmake
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# - Try to find ZLIB
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# ZLIB_ROOT_DIR - Set this variable to the root installation of ZLIB
|
||||||
|
#
|
||||||
|
# Read-Only variables:
|
||||||
|
# ZLIB_FOUND - system has ZLIB
|
||||||
|
# ZLIB_INCLUDE_DIRS - the ZLIB include directory
|
||||||
|
# ZLIB_LIBRARIES - Link these to use ZLIB
|
||||||
|
#
|
||||||
|
# ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
|
||||||
|
# ZLIB_VERSION_MAJOR - The major version of zlib
|
||||||
|
# ZLIB_VERSION_MINOR - The minor version of zlib
|
||||||
|
# ZLIB_VERSION_PATCH - The patch version of zlib
|
||||||
|
# ZLIB_VERSION_TWEAK - The tweak version of zlib
|
||||||
|
#
|
||||||
|
# The following variable are provided for backward compatibility
|
||||||
|
#
|
||||||
|
# ZLIB_MAJOR_VERSION - The major version of zlib
|
||||||
|
# ZLIB_MINOR_VERSION - The minor version of zlib
|
||||||
|
# ZLIB_PATCH_VERSION - The patch version of zlib
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright (c) 2001-2009 Kitware, Inc.
|
||||||
|
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
#
|
||||||
|
|
||||||
|
if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||||
|
# in cache already
|
||||||
|
set(ZLIB_FOUND TRUE)
|
||||||
|
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
set(_ZLIB_ROOT_HINTS
|
||||||
|
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/include"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_ZLIB_ROOT_PATHS
|
||||||
|
"$ENV{PROGRAMFILES}/zlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_path(ZLIB_ROOT_DIR
|
||||||
|
NAMES
|
||||||
|
include/zlib.h
|
||||||
|
HINTS
|
||||||
|
${_ZLIB_ROOT_HINTS}
|
||||||
|
PATHS
|
||||||
|
${_ZLIB_ROOT_PATHS}
|
||||||
|
)
|
||||||
|
mark_as_advanced(ZLIB_ROOT_DIR)
|
||||||
|
|
||||||
|
# check for header file
|
||||||
|
find_path(ZLIB_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
zlib.h
|
||||||
|
PATHS
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
/usr/lib/sfw/include
|
||||||
|
${ZLIB_ROOT_DIR}/include
|
||||||
|
)
|
||||||
|
mark_as_advanced(ZLIB_INCLUDE_DIR)
|
||||||
|
|
||||||
|
# check version number
|
||||||
|
if (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
|
||||||
|
file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$")
|
||||||
|
|
||||||
|
string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}")
|
||||||
|
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}")
|
||||||
|
string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}")
|
||||||
|
|
||||||
|
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}")
|
||||||
|
|
||||||
|
# only append a TWEAK version if it exists:
|
||||||
|
set(ZLIB_VERSION_TWEAK "")
|
||||||
|
if ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
|
||||||
|
set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
|
||||||
|
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}")
|
||||||
|
endif ("${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
|
||||||
|
|
||||||
|
set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
|
||||||
|
set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
|
||||||
|
set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
|
||||||
|
endif (ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
|
||||||
|
|
||||||
|
find_library(ZLIB_LIBRARY
|
||||||
|
NAMES
|
||||||
|
z
|
||||||
|
zdll
|
||||||
|
zlib
|
||||||
|
zlib1
|
||||||
|
PATHS
|
||||||
|
/usr/local/lib
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
/usr/sfw/lib/64
|
||||||
|
/usr/sfw/lib
|
||||||
|
${ZLIB_ROOT_DIR}/lib
|
||||||
|
)
|
||||||
|
mark_as_advanced(ZLIB_LIBRARY)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(ZLIB DEFAULT_MSG ZLIB_INCLUDE_DIR ZLIB_LIBRARY)
|
||||||
|
#find_package_handle_standard_args(ZLIB REQUIRED_VARS ZLIB_INCLUDE_DIR ZLIB_LIBRARY
|
||||||
|
# VERSION_VAR ZLIB_VERSION_STRING)
|
||||||
|
|
||||||
|
if (ZLIB_FOUND)
|
||||||
|
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
|
||||||
|
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
|
||||||
|
endif (ZLIB_FOUND)
|
||||||
|
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)
|
||||||
|
|
||||||
26
cmake/Modules/MacroCheckCCompilerFlagSSP.cmake
Normal file
26
cmake/Modules/MacroCheckCCompilerFlagSSP.cmake
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# - Check whether the C compiler supports a given flag in the
|
||||||
|
# context of a stack checking compiler option.
|
||||||
|
# CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE)
|
||||||
|
#
|
||||||
|
# FLAG - the compiler flag
|
||||||
|
# VARIABLE - variable to store the result
|
||||||
|
#
|
||||||
|
# This actually calls the check_c_source_compiles macro.
|
||||||
|
# See help for CheckCSourceCompiles for a listing of variables
|
||||||
|
# that can modify the build.
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
INCLUDE(CheckCSourceCompiles)
|
||||||
|
|
||||||
|
MACRO (CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
|
||||||
|
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
|
||||||
|
SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
|
||||||
|
CHECK_C_SOURCE_COMPILES("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
|
||||||
|
SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
|
||||||
|
ENDMACRO (CHECK_C_COMPILER_FLAG_SSP)
|
||||||
|
|
||||||
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)
|
||||||
100
cmake/Modules/UseDoxygen.cmake
Normal file
100
cmake/Modules/UseDoxygen.cmake
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# - Run Doxygen
|
||||||
|
#
|
||||||
|
# Adds a doxygen target that runs doxygen to generate the html
|
||||||
|
# and optionally the LaTeX API documentation.
|
||||||
|
# The doxygen target is added to the doc target as dependency.
|
||||||
|
# i.e.: the API documentation is built with:
|
||||||
|
# make doc
|
||||||
|
#
|
||||||
|
# USAGE: INCLUDE IN PROJECT
|
||||||
|
#
|
||||||
|
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
# include(UseDoxygen)
|
||||||
|
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Variables you may define are:
|
||||||
|
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. Defaults to "doc".
|
||||||
|
#
|
||||||
|
# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is stored. Defaults to "latex".
|
||||||
|
#
|
||||||
|
# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is stored. Defaults to "html".
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009-2010 Tobias Rautenkranz <tobias@rautenkranz.ch>
|
||||||
|
# Copyright (c) 2010 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
macro(usedoxygen_set_default name value)
|
||||||
|
if(NOT DEFINED "${name}")
|
||||||
|
set("${name}" "${value}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
find_package(Doxygen)
|
||||||
|
|
||||||
|
if(DOXYGEN_FOUND)
|
||||||
|
find_file(DOXYFILE_IN
|
||||||
|
NAMES
|
||||||
|
doxy.config.in
|
||||||
|
PATHS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_ROOT}/Modules/
|
||||||
|
NO_DEFAULT_PATH)
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
|
||||||
|
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
|
||||||
|
|
||||||
|
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
usedoxygen_set_default(DOXYFILE_HTML_DIR "html")
|
||||||
|
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY
|
||||||
|
ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
|
||||||
|
|
||||||
|
set(DOXYFILE_LATEX FALSE)
|
||||||
|
set(DOXYFILE_PDFLATEX FALSE)
|
||||||
|
set(DOXYFILE_DOT FALSE)
|
||||||
|
|
||||||
|
find_package(LATEX)
|
||||||
|
if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
|
||||||
|
set(DOXYFILE_LATEX TRUE)
|
||||||
|
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex")
|
||||||
|
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY
|
||||||
|
ADDITIONAL_MAKE_CLEAN_FILES
|
||||||
|
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||||
|
|
||||||
|
if(PDFLATEX_COMPILER)
|
||||||
|
set(DOXYFILE_PDFLATEX TRUE)
|
||||||
|
endif()
|
||||||
|
if(DOXYGEN_DOT_EXECUTABLE)
|
||||||
|
set(DOXYFILE_DOT TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(TARGET doxygen
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||||
|
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(${DOXYFILE_IN} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||||
|
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||||
|
add_custom_target(doxygen-trac ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_target_property(DOC_TARGET doc TYPE)
|
||||||
|
if(NOT DOC_TARGET)
|
||||||
|
add_custom_target(doc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_dependencies(doc doxygen)
|
||||||
|
endif()
|
||||||
128
config.h.cmake
Normal file
128
config.h.cmake
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/* 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 <argp.h> header file. */
|
||||||
|
#cmakedefine HAVE_ARGP_H 1
|
||||||
|
|
||||||
|
/* 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 <wspiapi.h> header file. */
|
||||||
|
#cmakedefine HAVE_WSPIAPI_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
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pthread.h> header file. */
|
||||||
|
#cmakedefine HAVE_PTHREAD_H 1
|
||||||
|
|
||||||
|
|
||||||
|
/*************************** FUNCTIONS ***************************/
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `snprintf' function. */
|
||||||
|
#cmakedefine HAVE_SNPRINTF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_snprintf' function. */
|
||||||
|
#cmakedefine HAVE__SNPRINTF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_snprintf_s' function. */
|
||||||
|
#cmakedefine HAVE__SNPRINTF_S 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vsnprintf' function. */
|
||||||
|
#cmakedefine HAVE_VSNPRINTF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_vsnprintf' function. */
|
||||||
|
#cmakedefine HAVE__VSNPRINTF 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||||
|
#cmakedefine HAVE__VSNPRINTF_S 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strncpy' function. */
|
||||||
|
#cmakedefine HAVE_STRNCPY 1
|
||||||
|
|
||||||
|
/* 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 `poll' function. */
|
||||||
|
#cmakedefine HAVE_POLL 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `select' function. */
|
||||||
|
#cmakedefine HAVE_SELECT 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `regcomp' function. */
|
||||||
|
#cmakedefine HAVE_REGCOMP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `clock_gettime' function. */
|
||||||
|
#cmakedefine HAVE_CLOCK_GETTIME 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `ntohll' function. */
|
||||||
|
#cmakedefine HAVE_NTOHLL 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
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
|
#cmakedefine HAVE_PTHREAD 1
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** OPTIONS ****************************/
|
||||||
|
|
||||||
|
/* Define to 1 if you want to enable ZLIB */
|
||||||
|
#cmakedefine WITH_LIBZ 1
|
||||||
|
|
||||||
|
/* Define to 1 if you want to enable SFTP */
|
||||||
|
#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 to 1 if you want to enable pcap output support (experimental) */
|
||||||
|
#cmakedefine WITH_PCAP 1
|
||||||
|
|
||||||
|
/* Define to 1 if you want to enable calltrace debug output */
|
||||||
|
#cmakedefine DEBUG_CALLTRACE 1
|
||||||
|
|
||||||
|
/*************************** ENDIAN *****************************/
|
||||||
|
|
||||||
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||||
|
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||||
|
#cmakedefine WORDS_BIGENDIAN 1
|
||||||
@@ -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
|
|
||||||
886
doc/API.html
886
doc/API.html
@@ -1,886 +0,0 @@
|
|||||||
<!DOCTYPE HTML SYSTEM>
|
|
||||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Libssh's Documentation
|
|
||||||
</title>
|
|
||||||
<link href="style.css" rel="stylesheet" type="text/css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<div id="titre">
|
|
||||||
<div align="center">
|
|
||||||
LIBSSH API GUIDE <br>
|
|
||||||
Or everything you ever wanted to know about a simple and fast ssh library.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2> 0 Introduction</h2>
|
|
||||||
|
|
||||||
<div class="tout">
|
|
||||||
Before inserting ssh hooks into your programs, you must know some basics about
|
|
||||||
the ssh protocol, and understand why the ssh library must implement them. <br>
|
|
||||||
Lot of the protocols specifications are hidden by the ssh library API (of
|
|
||||||
course !) but some still needs an attention from the end-user programmer.<br>
|
|
||||||
Note that libssh is still an alpha product, and the API may vary from one
|
|
||||||
version to another. The only guess I can make is that the API won't radically
|
|
||||||
change. <br>
|
|
||||||
The SSH protocol was designed for some goals which I resume here : <br>
|
|
||||||
-Privacy of data<br>
|
|
||||||
-Security<br>
|
|
||||||
-Authentication of the server<br>
|
|
||||||
-Authentication of the client.<br>
|
|
||||||
The client MUST be sure who's speaking to before entering into any
|
|
||||||
authentication way. That's where the end programmer must ensure the given
|
|
||||||
fingerprints *are* from the legitimate server. A ssh connection must follow
|
|
||||||
the following steps:<br>
|
|
||||||
<br>
|
|
||||||
1- Before connecting the socket, you can set up if you wish one or other
|
|
||||||
server public key authentication ie. DSA or RSA.
|
|
||||||
You can choose cryptographic algorithms you trust and compression algorithms
|
|
||||||
if any.<br>
|
|
||||||
2- The connection is made. A secure handshake is made, and resulting from it,
|
|
||||||
a public key from the server is gained.
|
|
||||||
You MUST verify that the public key is legitimate.<br>
|
|
||||||
3- The client must authenticate : the two implemented ways are password, and
|
|
||||||
public keys (from dsa and rsa key-pairs generated by openssh). It is
|
|
||||||
harmless to authenticate to a fake server with these keys because the
|
|
||||||
protocol ensures the data you sign can't be used twice. It just avoids
|
|
||||||
man-in-the-middle attacks.<br>
|
|
||||||
4- Now that the user has been authenticated, you must open one or several
|
|
||||||
channels. channels are different subways for information into a single ssh
|
|
||||||
connection. Each channel has a standard stream (stdout) and an error
|
|
||||||
stream (stderr). You can theoretically open an infinity of channel.<br>
|
|
||||||
5- With the channel you opened, you can do several things :<br>
|
|
||||||
-Open a shell. You may want to request a pseudo virtual terminal before <br>
|
|
||||||
-Execute a command. The virtual terminal is usable, too<br>
|
|
||||||
-Invoke the sftp subsystem. (look at chapter 6)<br>
|
|
||||||
-invoke your own subsystem. This is out the scope of this
|
|
||||||
document but it is easy to do.<br>
|
|
||||||
6- When everything is finished, just close the channels, and then the
|
|
||||||
connection.<br>
|
|
||||||
<br>
|
|
||||||
At every place, a function which returns an error code (typically -1 for int
|
|
||||||
values, NULL for pointers) also sets an error message and an error code.
|
|
||||||
I high-lined the main steps, now that's you to follow them :)
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
<h2> 1- Setting the options </h2>
|
|
||||||
<div class="tout">
|
|
||||||
The options mechanism will change during updates of the library, but the
|
|
||||||
functions which exists now will certainly be kept.
|
|
||||||
<br><br>
|
|
||||||
The ssh system needs to know the preferences of the user, the trust into one
|
|
||||||
or another algorithm and such. More important informations have to be given
|
|
||||||
before connecting : the host name of the server, the port (if non default),
|
|
||||||
the binding address, the default username, ... <br>
|
|
||||||
The options structure is given to a ssh_connect function, then this option
|
|
||||||
structure is used again and again by the ssh implementation. you shall not
|
|
||||||
free it manually, and you shall not share it with multiple sessions.<br>
|
|
||||||
Two ways are given for setting the options : the easy one (of course !) and
|
|
||||||
the long-but-accurate one.<br><br>
|
|
||||||
</div>
|
|
||||||
<h3>a) the easy way</h3><br>
|
|
||||||
<div class="tout">
|
|
||||||
Lot of ssh options in fact come from the command line of the program... <br>
|
|
||||||
you could parse them and then use the long way for every argument, but libssh
|
|
||||||
has a mechanism to do that for you, automatically.<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
SSH_OPTIONS *ssh_getopt(int *argcptr, char **argv);
|
|
||||||
</div>
|
|
||||||
this function will return you a new options pointer based on the arguments
|
|
||||||
you give in parameters. <br> better, they clean the argv array from used parameters
|
|
||||||
so you can use them after in your own program<br>
|
|
||||||
<div class="ex">
|
|
||||||
int main(int argc, char **argv){<br>
|
|
||||||
SSH_OPTIONS *opt;<br>
|
|
||||||
opt=ssh_getopt(&argc, argv);<br>
|
|
||||||
if(!opt){<br>
|
|
||||||
...<br>
|
|
||||||
}<br>
|
|
||||||
</div>
|
|
||||||
the function will return NULL if some problem is appearing.<br>
|
|
||||||
As a matter of portability for you own programs, the hostname isn't always<br>
|
|
||||||
the first argument from the command line, so the single arguments (not
|
|
||||||
preceded by a -something) won't be parsed.<br>
|
|
||||||
<div class="ex">
|
|
||||||
example: <br>
|
|
||||||
user@host:~$ myssh -u aris localhost <br>
|
|
||||||
-u aris will be caught, localhost will not.<br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
cfr the options_set_user() function in the next part for more informations
|
|
||||||
about it.<br>
|
|
||||||
</div>
|
|
||||||
<h3>b) the long way</h3>
|
|
||||||
<div class="tout">
|
|
||||||
<div class="prot">
|
|
||||||
SSH_OPTIONS *options_new();
|
|
||||||
</div>
|
|
||||||
This function returns an empty but initialized option structure pointer.<br>
|
|
||||||
The structure is freed by ssh_disconnect described later, so don't use the
|
|
||||||
existing function options_free() (it's an internal function).<br>
|
|
||||||
So : use it only for <b>one</b> ssh_connect(), <b>never</b> free it.<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
SSH_OPTIONS *options_copy(SSH_OPTIONS *opt);
|
|
||||||
</div>
|
|
||||||
If you need to replicate an option object before using it, use this function.
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
The following functions are all of the following form : <br>
|
|
||||||
<div class="prot">
|
|
||||||
int options_set_something(SSH_OPTIONS *opt, something);
|
|
||||||
</div>
|
|
||||||
the something parameters are always internaly copied, so you don't have to
|
|
||||||
strdup them.<br>
|
|
||||||
some return eather 0 or -1, in which case an error message appears in the
|
|
||||||
error functions, others never fail (return void)<br>
|
|
||||||
the error codes and descriptions for these functions are recoverable throught <i>ssh_get_error(NULL);</i>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
int options_set_wanted_method(SSH_OPTIONS *opt,int method, char *list);
|
|
||||||
</div>
|
|
||||||
Passing an option structure, a ssh macro for the method, and a list of allowed
|
|
||||||
parameters indicates libssh you want to use these.<br>
|
|
||||||
The macros are :<br>
|
|
||||||
KEX_ALGO<br>
|
|
||||||
KEX_HOSTKEY Server public key type expected<br>
|
|
||||||
KEX_CRYPT_C_S 2 Cryptographic algorithm client->server<br>
|
|
||||||
KEX_CRYPT_S_C 3 Cryptographic algorithm server->client<br>
|
|
||||||
KEX_MAC_C_S 4<br>
|
|
||||||
KEX_MAC_S_C 5<br>
|
|
||||||
KEX_COMP_C_S 6 Compression method for the stream ("zlib" or "none"), client to server<br>
|
|
||||||
KEX_COMP_S_C 7 Compression method for the stream ("zlib" or "none"), server to client<br>
|
|
||||||
KEX_LANG_C_S 8<br>
|
|
||||||
KEX_LANG_S_C 9<br>
|
|
||||||
<br>
|
|
||||||
Currently, only KEX_HOSTKEY and ,KEX_CRYPT_C_S,S_C, KEX_COMP_C_S and S_C work
|
|
||||||
as expected. the list is a comma separated string of prefered
|
|
||||||
algorithms/methods, in order of preference.<br>
|
|
||||||
<br>
|
|
||||||
<div class="ex">
|
|
||||||
example : this sets the ssh stream to be compressed in client->server mode only
|
|
||||||
<br>
|
|
||||||
|
|
||||||
ret = option_set_wanted_method(options,KEX_COMP_C_S,"zlib");
|
|
||||||
</div>
|
|
||||||
<div class="ex">
|
|
||||||
example: this will set the cryptographic algorithms wanted from server to
|
|
||||||
client to aes128-cbc and then aes192-cbc if the first one isn't supported by
|
|
||||||
server:<br>
|
|
||||||
ret = option_set_wanted_method(options,KEX_CRYPT_S_C,"aes128-cbc,aes192-cbc");
|
|
||||||
</div>
|
|
||||||
<div class="ex">
|
|
||||||
if you prefer getting the Dss key from a server instead of rsa, but you still
|
|
||||||
accept rsa if dss isn't available :<br>
|
|
||||||
options_set_wanted_method(options,KEX_HOSTKEY,"ssh-dss,ssh-rsa");
|
|
||||||
</div>
|
|
||||||
return value: <br>0 if the option is valid, -1 else.<br> An error is set in that case.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_port(SSH_OPTIONS *opt, unsigned int port);
|
|
||||||
</div>
|
|
||||||
this function sets the server port.
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_host(SSH_OPTIONS *opt, const char *hostname);
|
|
||||||
</div>
|
|
||||||
this function sets the hostname of the server. It also supports
|
|
||||||
"user@hostname" syntax in which case the user options is set too.
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_fd(SSH_OPTIONS *opt, int fd);
|
|
||||||
</div>
|
|
||||||
permits you to specify an opened file descriptor you've opened yourself.
|
|
||||||
<br>
|
|
||||||
It's a good way of bypassing the internal FD opening in libssh, but there are things you should take care of : <br>
|
|
||||||
-The file descriptor should be returned to libssh without nonblocking settings<br>
|
|
||||||
-If you wish to use <i>is_server_known()</i> You should also set <i>options_set_host</i>... Otherwise libssh won't have any mean of certifying the server is known or not.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_bindaddr(SSH_OPTIONS *opt, char *bindaddr);
|
|
||||||
</div>
|
|
||||||
this function allows you to set the binding address, in case your computer has
|
|
||||||
multiple IP or interfaces. it supports both hostnames and IP's
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_username(SSH_OPTIONS *opt,char *username);
|
|
||||||
</div>
|
|
||||||
sets username for authenticating in this session.
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
void option_set_timeout(SSH_OPTIONS *opt,long seconds, long usec);
|
|
||||||
</div>
|
|
||||||
sets the timeout for connecting to the socket. It does not include a timeout for the name resolving or handshake.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_ssh_dir(SSH_OPTIONS *opt, char *dir);
|
|
||||||
</div>
|
|
||||||
this function sets the .ssh/ directory used by libssh. You may use a %s
|
|
||||||
which will be replaced by the home directory of the user.
|
|
||||||
NEVER accept parameters others than the user's one, they may contain
|
|
||||||
format strings which are a security hole if a malicious agent gives it.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_known_hosts_file(SSH_OPTIONS *opt, char *dir);
|
|
||||||
</div>
|
|
||||||
same than <i>options_set_ssh_dir()</i> for known_hosts file.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_identity(SSH_OPTIONS *opt, char *identity);
|
|
||||||
</div>
|
|
||||||
same than upper for the identity file (they come by pair, the one asked is the file without the .pub suffix)
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void options_set_status_callback(SSH_OPTIONS *opt, void (*callback)(void *arg, float status), void *arg);
|
|
||||||
</div>
|
|
||||||
Because more and more developpers use libssh with GUI, I've added this function to make the ssh_connect function more
|
|
||||||
interactive. This permits to set a callback of the form
|
|
||||||
<div class="prot">void function(void *userarg, float status);</div> with status going from 0 to 1 during ssh_connect. The callback won't ever be called after the connection is made.
|
|
||||||
<br><br>
|
|
||||||
</div>
|
|
||||||
<h2>
|
|
||||||
2- Connecting the ssh server
|
|
||||||
</H2>
|
|
||||||
<div class="tout">
|
|
||||||
The API provides an abstract data type, SSH_SESSION, which describes the
|
|
||||||
connection to one particular server. You can make several connections to
|
|
||||||
different servers under the same process because of this structure.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
SSH_SESSION *ssh_connect(SSH_OPTIONS *options);
|
|
||||||
</div>
|
|
||||||
This function returns a handle on the newly connection. This function expects
|
|
||||||
to have a pre-set options structure.
|
|
||||||
<br>
|
|
||||||
It returns NULL in case of error, in which case you can look at error messages
|
|
||||||
for more informations.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void ssh_disconnect(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
This function sends a polite disconnect message, and does clean the session.<br>
|
|
||||||
This is the proper way of finishing a ssh connection.<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_get_pubkey_hash(SSH_SESSION *session, char hash[MD5_DIGEST_LEN]);
|
|
||||||
</div>
|
|
||||||
This function places the MD5 hash of the server public key into the hash array.<br>
|
|
||||||
It's IMPORTANT to verify it matches the previous known value. One server always
|
|
||||||
have the same hash. No other server/attacker can emulate it (or it'd be caught
|
|
||||||
by the public key verification procedure automatically made by libssh).
|
|
||||||
<br>
|
|
||||||
You can skip this step if you correctly handle <i>is_server_known()</i>
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_is_server_known(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Checks the user's known host file to look for a previous connection to the specified server. Return values:<br>
|
|
||||||
SSH_SERVER_KNOWN_OK : the host is known and the key has not changed<br>
|
|
||||||
SSH_SERVER_KNOWN_CHANGED : The host's key has changed. Either you are under
|
|
||||||
an active attack or the key changed. The API doesn't give any way to modify the key in known hosts yet. I Urge end developers to WARN the user about the possibility of an attack.<br>
|
|
||||||
SSH_SERVER_FOUND_OTHER: The host gave us a public key of one type, which does
|
|
||||||
not exist yet in our known host file, but there is an other type of key which is know.<br>
|
|
||||||
IE server sent a DSA key and we had a RSA key.<br>
|
|
||||||
Be carreful it's a possible attack (coder should use option_set_wanted_method() to specify
|
|
||||||
which key to use).<br>
|
|
||||||
SSH_SERVER_NOT_KNOWN: the server is unknown in known hosts. Possible reasons :
|
|
||||||
case not matching, alias, ... In any case the user MUST confirm the Md5 hash is correct.<br>
|
|
||||||
SSH_SERVER_ERROR : Some error happened while opening known host file.<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_write_knownhost(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
write the current connected host as known in the known host file. returns a negative value if something went wrong. You generaly use it when ssh_is_server_known returned SSH_SERVER_NOT_KNOWN.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int pubkey_get_hash(SSH_SESSION *session,char hash[MD5_DIGEST_LEN]);
|
|
||||||
</div>
|
|
||||||
deprecated but left for binary compatibility (will be removed in newer versions).
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>3- Authenticating to server</h2>
|
|
||||||
<div class="tout">
|
|
||||||
The ssh library supports the two most used authentication methods from SSH.
|
|
||||||
In every function, there is a "username" argument. If null is given instead,
|
|
||||||
the server will use the default username (which is guessed from what you gave
|
|
||||||
to options_set_user or options_set_hostname or even the local user running the code).
|
|
||||||
<br>
|
|
||||||
|
|
||||||
Authentication methods :<br>
|
|
||||||
<h3>A) Public keys</h3><br>
|
|
||||||
The public key is the only method which does not compromise your key if the
|
|
||||||
remote host has been compromised (the server can't do anything more than
|
|
||||||
getting your public key). This is not the case of a password authentication
|
|
||||||
(the server can get your plaintext password).<br>
|
|
||||||
Libssh is obviously fully compatible with the openssh public and private keys.<br>
|
|
||||||
The things go this way : you scan a list of files which contain public keys.<br>
|
|
||||||
For each key, you send it to ssh server until the server acknowledges a key
|
|
||||||
(a key it knows). Then, you get the private key for this key and send a
|
|
||||||
message proving you own that private key.<br>
|
|
||||||
Here again, two ways for the public key authentication... the easy and the
|
|
||||||
complicated one.<br>
|
|
||||||
<br>
|
|
||||||
<h4> easy way:</h4>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_autopubkey(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
This function will try the most common places for finding the public and
|
|
||||||
private keys (your home directory) or eventualy the identity files asked by
|
|
||||||
the <i>options_set_identity()</i> function.<br>
|
|
||||||
The return values are :<br>
|
|
||||||
SSH_AUTH_ERROR : some serious error happened during authentication<br>
|
|
||||||
SSH_AUTH_DENIED : no key matched<br>
|
|
||||||
SSH_AUTH_SUCCESS : you are now authenticated<br>
|
|
||||||
SSH_AUTH_PARTIAL : some key matched but you still have to give an other mean
|
|
||||||
of authentication (like password).<br>
|
|
||||||
<br>
|
|
||||||
<h4> peanful way:</h4>
|
|
||||||
there are three steps : you get a public key, you ask the server if the key
|
|
||||||
matches a known one, if true, you get the private key and authenticate with
|
|
||||||
it.<br>
|
|
||||||
<div class="prot">
|
|
||||||
STRING *publickey_from_file(char *filename,int *_type);
|
|
||||||
</div>
|
|
||||||
will return an handle on a public key. if you give a pointer to an int,
|
|
||||||
a symbolic value will be placed there. Do it because you need it in next
|
|
||||||
step.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,
|
|
||||||
int type, STRING *publickey);
|
|
||||||
</div>
|
|
||||||
this function will offer a public key to the server. SSH_AUTH_SUCCESS is
|
|
||||||
returned if the key is accepted (in which case you'll want to get the
|
|
||||||
private key), SSH_AUTH_DENIED otherwise.<br>
|
|
||||||
Still watch for SSH_AUTH_ERROR as connection problems might happen.
|
|
||||||
<br>
|
|
||||||
in case of SSH_AUTH_SUCCESS,
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,
|
|
||||||
int type,char *passphrase);
|
|
||||||
</div>
|
|
||||||
will get the privatekey from the filename previously set by
|
|
||||||
publickey_from_next_file(). You can call it with a passphrase for
|
|
||||||
unlocking the key. If passphrase==NULL, the default prompt will be used.<br>
|
|
||||||
The function returns NULL if the private key wasn't opened
|
|
||||||
(ie bad passphrase or missing file).<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_pubkey(SSH_SESSION *session, char *username,
|
|
||||||
STRING *publickey, PRIVATE_KEY *privatekey);
|
|
||||||
</div>
|
|
||||||
Will try to authenticate using the public and private key. It shall return
|
|
||||||
SSH_AUTH_SUCCESS if you are authenticated, SSH_AUTH_ERROR, SSH_AUTH_DENIED or
|
|
||||||
SSH_AUTH_PARTIAL depending of return condition.<br>
|
|
||||||
|
|
||||||
each public key (of type STRING) must be freed with the libc "free" function.<br>
|
|
||||||
The private key must be freed with private_key_free(PRIVATE_KEY *) which
|
|
||||||
will clean the memory before (don't worry about passphrase leaking).<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<h3> B) Password</h3><br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_password(SSH_SESSION *session,char *username,char *password);
|
|
||||||
</div>
|
|
||||||
Will return SSH_AUTH_SUCCESS if the password matched, one of other constants
|
|
||||||
otherwise. It's your work to ask the password and to free it in a secure
|
|
||||||
manner.<br><br>
|
|
||||||
|
|
||||||
<h3> C) Keyboard-interactive</h3><br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_kbdint(SSH_SESSION *session, char *user, char *submethods);
|
|
||||||
</div>
|
|
||||||
This is the main keyboard-interactive function. It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL, SSH_AUTH_ERROR depending on the result of the request.<br>
|
|
||||||
The keyboard-interactive authentication method of SSH2 is a feature which permits the server to ask a certain number of questions in an interactive manner to the client, until it decides to accept or deny the login.<br>
|
|
||||||
To begin, you call this function (you can omit user if it was set previously and omit submethods - instead you know what you do - just put them to NULL) and store the answer.
|
|
||||||
If the answer is SSH_AUTH_INFO, it means the server has sent a few questions to ask your user, which you can retrieve with the following functions. Then, set the answers and call back ssh_userauth_kbdint with same arguments. It may again ask a few other questions etc. until you get an other SSH_AUTH code than SSH_AUTH_INFO.<br>
|
|
||||||
Few remarks :<br>
|
|
||||||
-Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.<br>
|
|
||||||
-The server can send an empty question set (this is the default behavior on my system) after you have sent the answers to the first questions.
|
|
||||||
you must still parse the answer, it might contain some message from the server saying hello or such things. Just call ssh_userauth_kbdint() once more<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_kbdint_getnprompts(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
After you called ssh_userauth_kbdint and got SSH_AUTH_INFO, the session contains a few questions (or prompts) from the server. This function returns the number of prompts and answers.<br>
|
|
||||||
It could be zero, in which case you must act as said previously.<br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
char *ssh_userauth_kbdint_getname(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
this functions returns the "name" of the message block. The meaning is explained later.<br>
|
|
||||||
This function returns a pointer that stays valid until the next ssh_userauth_kbdint() call and must not be freed.<br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
char *ssh_userauth_kbdint_getinstruction(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
this functions returns the "instruction" of the message block. The meaning is explained later.<br>
|
|
||||||
This function returns a pointer that stays valid until the next ssh_userauth_kbdint() call and must not be freed.<br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
char *ssh_userauth_kbdint_getprompt(SSH_SESSION *session,int i, char *echo);
|
|
||||||
</div>
|
|
||||||
This functions returns a pointer to the nth prompt. The character pointed by echo, if different from null, will contain a boolean value after the call, which means that the user prompt must be echoed or not.<br>
|
|
||||||
zero means that the echo is Off (like for a password prompt).<br>
|
|
||||||
any other value means the echo is on.<br>
|
|
||||||
This function returns a pointer that stays valid until the next ssh_userauth_kbdint() call and must not be freed.<br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
void ssh_userauth_kbdint_setanswer(SSH_SESSION *session, unsigned int i, char *a
|
|
||||||
nswer);
|
|
||||||
</div>
|
|
||||||
This function sets the ith answer. The string you give will be duplicated, and this copy will be discarded once it is no longer necessary.<br>
|
|
||||||
care must be taken so you discard the content of the original string after this function call.<br>
|
|
||||||
|
|
||||||
<h3> A little note about how to use the informations from keyboard-interactive authentication</h3>
|
|
||||||
<br>
|
|
||||||
The words from the original drafts explain everything
|
|
||||||
<div class="prot">
|
|
||||||
3.3 User Interface
|
|
||||||
|
|
||||||
Upon receiving a request message, the client SHOULD prompt the user
|
|
||||||
as follows:<br>
|
|
||||||
A command line interface (CLI) client SHOULD print the name and
|
|
||||||
instruction (if non-empty), adding newlines. Then for each prompt in
|
|
||||||
turn, the client SHOULD display the prompt and read the user input.<br>
|
|
||||||
<br>
|
|
||||||
A graphical user interface (GUI) client has many choices on how to
|
|
||||||
prompt the user. One possibility is to use the name field (possibly
|
|
||||||
prefixed with the application's name) as the title of a dialog window
|
|
||||||
in which the prompt(s) are presented. In that dialog window, the
|
|
||||||
instruction field would be a text message, and the prompts would be
|
|
||||||
labels for text entry fields. All fields SHOULD be presented to the
|
|
||||||
user, for example an implementation SHOULD NOT discard the name field
|
|
||||||
because its windows lack titles; it SHOULD instead find another way
|
|
||||||
to display this information. If prompts are presented in a dialog
|
|
||||||
window, then the client SHOULD NOT present each prompt in a separate
|
|
||||||
window.<br>
|
|
||||||
<br>
|
|
||||||
All clients MUST properly handle an instruction field with embedded
|
|
||||||
newlines. They SHOULD also be able to display at least 30 characters
|
|
||||||
for the name and prompts. If the server presents names or prompts
|
|
||||||
longer than 30 characters, the client MAY truncate these fields to
|
|
||||||
the length it can display. If the client does truncate any fields,
|
|
||||||
there MUST be an obvious indication that such truncation has occured.<br>
|
|
||||||
The instruction field SHOULD NOT be truncated.<br>
|
|
||||||
Clients SHOULD use control character filtering as discussed in
|
|
||||||
[SSH-ARCH] to avoid attacks by including terminal control characters
|
|
||||||
in the fields to be displayed.<br>
|
|
||||||
<br>
|
|
||||||
For each prompt, the corresponding echo field indicates whether or
|
|
||||||
not the user input should be echoed as characters are typed. Clients
|
|
||||||
SHOULD correctly echo/mask user input for each prompt independently
|
|
||||||
of other prompts in the request message. If a client does not honor
|
|
||||||
the echo field for whatever reason, then the client MUST err on the
|
|
||||||
side of masking input. A GUI client might like to have a checkbox
|
|
||||||
toggling echo/mask. Clients SHOULD NOT add any additional characters
|
|
||||||
to the prompt such as ": " (colon-space); the server is responsible
|
|
||||||
for supplying all text to be displayed to the user. Clients MUST
|
|
||||||
also accept empty responses from the user and pass them on as empty
|
|
||||||
strings.<br>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<h3> D) "none"</h3><br>
|
|
||||||
In fact this mode only serve to get the list of supported authentications.<br>
|
|
||||||
however, it also serves to get the banner message from the server, if any.<br>
|
|
||||||
You should firstly try this method, at least for getting the banner, then to enter if there is no password at all.<br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_userauth_none(SSH_SESSION *session, char *username);
|
|
||||||
</div>
|
|
||||||
if the account has no password (and the server is configured to let you
|
|
||||||
pass), the function might answer SSH_AUTH_SUCCESS. That's why
|
|
||||||
ssh_auth_autopubkey already calls it for you.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
char *ssh_get_issue_banner(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
if during authentication, the server has given a banner, you can get it
|
|
||||||
this way. the function returns NULL if no banner exists, and you have to
|
|
||||||
free the returned pointer.<br><br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>4- Opening a channel</h2>
|
|
||||||
<div class="tout">
|
|
||||||
Maybe you want to use the sftp subsystem : all this is done for you, you
|
|
||||||
better read at the end of the paper how to use the sftp functions.<br>
|
|
||||||
You probably want to open one or more shells, or call one or more programs.<br>
|
|
||||||
|
|
||||||
So you need a channel.<br>
|
|
||||||
<div class="prot">
|
|
||||||
CHANNEL *channel;
|
|
||||||
</div>
|
|
||||||
This is an handler to a channel object. it describes your channel.
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
CHANNEL *channel_open_session(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
This will open a channel for use into a session (which can be used for executing
|
|
||||||
a command or a shell. Not for tcp forwarding).<br>
|
|
||||||
The function returns NULL if for a reason or another the channel can't be
|
|
||||||
opened.<br>
|
|
||||||
<i>
|
|
||||||
CHANNEL *open_session_channel(...)</i> is deprecated and should not be used in future
|
|
||||||
applications.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
CHANNEL *channel_open_forward(SSH_SESSION *session, char *remotehost,
|
|
||||||
int remoteport, char *sourcehost, int localport);
|
|
||||||
</div>
|
|
||||||
Ask the server to tunnel a TCP connection. The server will connect to
|
|
||||||
remotehost:remoteport and libssh will return an handle to the channel if it is allowed.<br>
|
|
||||||
Otherwise, NULL will be returned. sourcehost and localport are generaly
|
|
||||||
used in message debugging purpose and have no effect on the result.<br>
|
|
||||||
<br>
|
|
||||||
When you've finished with your channel, you may send an EOF message and
|
|
||||||
then close it :<br>
|
|
||||||
<div class="prot">
|
|
||||||
void channel_send_eof(CHANNEL *channel);
|
|
||||||
</div>
|
|
||||||
sends an end of file into channel. It doesn't close the channel and you can still read it.<br><br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
void channel_free(CHANNEL *channel);
|
|
||||||
</div>
|
|
||||||
closes and destroy the channel.
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
void channel_close(CHANNEL *channel);
|
|
||||||
</div>
|
|
||||||
sends an EOF and close the channel. (if you don't know what to do, use channel_free). It doesn't free the channel.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<h2>5- The shell</h2>
|
|
||||||
<div class="tout">
|
|
||||||
<div class="prot">
|
|
||||||
int channel_request_env(CHANNEL *channel, char *name, char *value);
|
|
||||||
</div>
|
|
||||||
Ask the server to set the "name" environment variable to "value". For security
|
|
||||||
reasons, some variables won't be accepted by the server. It returns 0 otherwise.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_request_pty(CHANNEL *channel);
|
|
||||||
</div>
|
|
||||||
ask the server to allocate a pseudo terminal for the current channel.<br>
|
|
||||||
the function returns 0 on success.<br><br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
int channel_request_pty_size(CHANNEL *channel, char *terminal, int cols, int rows);
|
|
||||||
</div>
|
|
||||||
ask the server to allocate a pty. The terminal parameter is the type of pty
|
|
||||||
(vt100,xterm,...), cols and rows are the size of the new terminal (80x24 by example).<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_change_pty_size(CHANNEL *channel, int cols,int rows);
|
|
||||||
</div>
|
|
||||||
changes the window size (terminal) of the current session;<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_request_shell(CHANNEL *channel);
|
|
||||||
</div>
|
|
||||||
This function requests a shell. After its success, a shell is running at the other side of the channel.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_request_exec(CHANNEL *channel, char *cmd);
|
|
||||||
</div>
|
|
||||||
run a shell command without an interactive shell, ie $SHELL -c "command".<br>
|
|
||||||
returns 0 on success.<br><br>
|
|
||||||
|
|
||||||
You might ask the server to open a subsystem for you. this is done this way :
|
|
||||||
<div class="prot">
|
|
||||||
int channel_request_subsystem(CHANNEL *channel, char *subsystem);
|
|
||||||
</div>
|
|
||||||
There are some functions used to manipulate the channels :
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_write(CHANNEL *channel,void *data,int len);
|
|
||||||
</div>
|
|
||||||
writes len bytes of data into the channel. It returns the number of bytes written. The current implementation is a blocking write
|
|
||||||
of the complete data buffer, but it may vary.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr);
|
|
||||||
</div>
|
|
||||||
It makes a blocking read on the channel, of "bytes" bytes and returns the
|
|
||||||
result into an allocated buffer you passed in. (with <i>buffer_new()</i>).<br>
|
|
||||||
it will read on stderr, if is_stderr is set.<br>
|
|
||||||
The function might read less bytes than "bytes" variable if an End of File
|
|
||||||
happened. Otherwise, the function will always block reading until "bytes"
|
|
||||||
bytes are read.<br>
|
|
||||||
with "bytes"=0, <i>channel_read()</i> will read the current state of the read buffer, but will read at least one byte (and block if nothing is available, except EOF case).<br>
|
|
||||||
|
|
||||||
You don't need to free and allocate a new buffer each time you call this function, just pass the same object each time.<br>
|
|
||||||
look at the <i>buffer_</i> functions further for the correct way of retrieving the data.<br><br>
|
|
||||||
|
|
||||||
<div class="prot">
|
|
||||||
int channel_read_nonblocking (CHANNEL *channel, char *dest, int len, int is_stderr);
|
|
||||||
</div>
|
|
||||||
Non-blocking read on channel, at most len bytes of data are read. Returns 0 if EOF or if no data available.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_is_open(CHANNEL *channel);
|
|
||||||
</div>
|
|
||||||
returns 0 if the channel has been closed by remote host, something else otherwise.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int channel_poll(CHANNEL *channel, int is_stderr);
|
|
||||||
</div>
|
|
||||||
This nonblocking function returns the number of bytes immediatly available for
|
|
||||||
reading on the channel and stdin/stderr.<br><br>
|
|
||||||
|
|
||||||
More interesting, if you are going to do channel multiplexing, this function
|
|
||||||
is for you :<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int ssh_select(CHANNEL **channels,CHANNEL **outchannels, int maxfd,
|
|
||||||
fd_set *readfds, struct timeval *timeout);
|
|
||||||
</div>
|
|
||||||
channels is an array of channel pointers, finished by a NULL pointer.<br>
|
|
||||||
It can be used ever and ever, as it is never written.<br>
|
|
||||||
outchannels is an array of size at least greater or equal to "channels".<br>
|
|
||||||
It hasn't to be initialized.<br>
|
|
||||||
maxfd is the maximum file descriptor from your own filedescriptors.<br>
|
|
||||||
readfds is a pointer to a fd_set structure, like in the original
|
|
||||||
select implementation (man select).<br>
|
|
||||||
the struct timeval *timeout has the same meaning than in
|
|
||||||
select(2) (man select).<br>
|
|
||||||
|
|
||||||
There is no support for writing or special events as in <i>select(2)</i> yet.<br>
|
|
||||||
The function returns -1 if an error occured, or SSH_EINTR if select was interrupted by a syscall. This is not an error, you may restart the function.<br>
|
|
||||||
<b>note about signals:</b> libssh is not threadsafe, and most functions are not
|
|
||||||
reetrant when using the same data structures : it means you *cannot* do anything
|
|
||||||
with a channel from a ssh session passed to <i>ssh_select</i> during a signal.
|
|
||||||
<br>take a look at sample.c on how to bypass that limitation.<br>
|
|
||||||
the function works this way : it returns in the readfds the filedescriptors which have data ready for reading (the given filedescriptors have a greatest priority).<br>
|
|
||||||
Then, if no file descriptor can be read, the function looks for every
|
|
||||||
channel from the array to get a channel with data bufferized. If nothing is
|
|
||||||
available, it waits for activity on any channel/file descriptor and returns
|
|
||||||
immediatly, or waits until timeout.<br>
|
|
||||||
You will find the channels that can be read in the outchannels array (finished by NULL) and the filedescriptors in your fd_set (man FD_ISSET).<br>
|
|
||||||
this is the "heart" of your main loop.<br>
|
|
||||||
<br>
|
|
||||||
<h3>The BUFFER object.</h3>
|
|
||||||
Reading is done through the BUFFER object. here is the public interface :
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
BUFFER *buffer_new();
|
|
||||||
</div>
|
|
||||||
creates a buffer object.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void *buffer_get(BUFFER *buffer);
|
|
||||||
</div>
|
|
||||||
returns a pointer to the begining of buffer.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int buffer_get_len(BUFFER *buffer);
|
|
||||||
</div>
|
|
||||||
returns buffer's data size.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void buffer_free(BUFFER *buffer);
|
|
||||||
</div>
|
|
||||||
destoys the buffer.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
How to use the buffer system when you've read something:<br>
|
|
||||||
I've seen people doing such code:<br>
|
|
||||||
<div class="prot">
|
|
||||||
char buffer[256];<br>
|
|
||||||
channel_read(channel,buf,1234,0);<br>
|
|
||||||
strcpy(buffer,buf.data);<br>
|
|
||||||
</div>
|
|
||||||
The correct way of doing this:
|
|
||||||
<div class="prot">
|
|
||||||
char buffer[256];<br>
|
|
||||||
int i;<br>
|
|
||||||
i=channel_read(channel,buf,1234,0);<br>
|
|
||||||
if(i<=0)<br>
|
|
||||||
go_out()...<br>
|
|
||||||
if(i>=256)<br>
|
|
||||||
i=255;<br>
|
|
||||||
memcpy(buffer,buffer_get(buf),i);<br>
|
|
||||||
buffer[i]=0;
|
|
||||||
</div>
|
|
||||||
Do not expect the buffer to be null-terminated. Don't access the internal structure of buffer. Check the sizes before copying.<br>
|
|
||||||
</div>
|
|
||||||
<h2>6- The SFTP subsystem</h2>
|
|
||||||
<div class="tout">
|
|
||||||
SFTP is a secure implementation of a file transfer protocol. The current
|
|
||||||
implemented version is 3. All functions aren't implemented yet but the most
|
|
||||||
important are.<br>
|
|
||||||
<br>
|
|
||||||
<h3>A) Opening the session</h3>
|
|
||||||
<div class="prot">
|
|
||||||
SFTP_SESSION *sftp_new(SSH_SESSION *session);
|
|
||||||
int sftp_init(SFTP_SESSION *sftp);
|
|
||||||
</div>
|
|
||||||
The former returns a SFTP_SESSION handle. It returns NULL if things didn't
|
|
||||||
work as expected.<br>
|
|
||||||
sftp_init makes some initialisation work. It returns 0 if things went right.
|
|
||||||
Both of them must be called.<br>
|
|
||||||
<h3>B) Opening and reading a directory</h3>
|
|
||||||
<div class="prot">
|
|
||||||
SFTP_DIR *sftp_opendir(SFTP_SESSION *session, char *path);
|
|
||||||
</div>
|
|
||||||
opens a directory for file listing. Returns NULL in error case.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
SFTP_ATTRIBUTES *sftp_readdir(SFTP_SESSION *session, SFTP_DIR *dir);
|
|
||||||
</div>
|
|
||||||
This function reads one file attribute from an opened directory. It
|
|
||||||
returns NULL if the directory is EOF, or if something wrong happened.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_dir_eof(SFTP_DIR *dir);
|
|
||||||
</div>
|
|
||||||
When a <i>sftp_readdir()</i> returned NULL, you can use this function to
|
|
||||||
tell if an EOF occured. the function returns 0 if no EOF occured.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void sftp_attributes_free(SFTP_ATTRIBUTES *file);
|
|
||||||
</div>
|
|
||||||
You have to free any SFTP_ATTRIBUTE structure given by an other function
|
|
||||||
with it.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_dir_close(SFTP_DIR *dir);
|
|
||||||
</div>
|
|
||||||
closes an opened directory. returns 0 when no error occured.
|
|
||||||
<br><br>
|
|
||||||
<h3>C) Opening, reading, writing files</h3>
|
|
||||||
<div class="prot">
|
|
||||||
SFTP_FILE *sftp_open(SFTP_SESSION *session, char *file, int access,
|
|
||||||
SFTP_ATTRIBUTES *attr);
|
|
||||||
</div>
|
|
||||||
Opens a file. The access flags are the same than the stdio flags.<br>
|
|
||||||
see open(2) for more details.<br>
|
|
||||||
attr are the wanted attributes for the new file. If you supply NULL,
|
|
||||||
default values will be used.<br>
|
|
||||||
rem: more work is going on parsing/making the attributes structure
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_read(SFTP_FILE *file, void *dest, int len);
|
|
||||||
</div>
|
|
||||||
read on a file. Works as the fread() function. It is blocking by default but you can change the default behaviour with <i>sftp_file_set_nonblocking()</i>.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void sftp_file_set_nonblocking(SFTP_FILE *file);
|
|
||||||
</div>
|
|
||||||
sets the file non blocking. reads on this file won't ever block. You can't detect end of files this way.<br>
|
|
||||||
*** TODO more work going there for EOF ****
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void sftp_file_set_blocking(SFTP_FILE *file);
|
|
||||||
</div>
|
|
||||||
restore the default setting of sftp_read.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_write(SFTP_FILE *file, void *source, int len);
|
|
||||||
</div>
|
|
||||||
works as fwrite() function. It is a blocking write.<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
void sftp_seek(SFTP_FILE *file, int new_offset);
|
|
||||||
</div>
|
|
||||||
seek into the file for reading/writing at an other place.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
unsigned long sftp_tell(SFTP_FILE *file);
|
|
||||||
</div>
|
|
||||||
returns the current offset (both writing and reading) into the opened file.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
void sftp_rewind(SFTP_FILE *file);
|
|
||||||
</div>
|
|
||||||
same as sftp_seek(file,0);
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_file_close(SFTP_FILE *file);
|
|
||||||
</div>
|
|
||||||
closes a file handle. returns 0 in no error case.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_rm(SFTP_SESSION *sftp, char *file);
|
|
||||||
</div>
|
|
||||||
deletes a file.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_rmdir(SFTP_SESSION *sftp, char *directory);
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
deletes a directory.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_mkdir(SFTP_SESSION *sftp, char *directory, SFTP_ATTRIBUTES *attr);
|
|
||||||
</div>
|
|
||||||
makes a directory, with the given attributes. You can't pass NULL for attr and hope it works.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_rename(SFTP_SESSION *sftp, char *original, char *newname);
|
|
||||||
</div>
|
|
||||||
changes the name of a file or directory.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
int sftp_setstat(SFTP_SESSION *sftp, char *file, SFTP_ATTRIBUTES *attr);
|
|
||||||
</div>
|
|
||||||
changes the attributes of a file or directory.
|
|
||||||
<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
char *sftp_canonicalize_path(SFTP_SESSION *sftp, char *path);
|
|
||||||
</div>
|
|
||||||
gives the canonicalized form of some path. You have to
|
|
||||||
free the pointer given in return.<br>
|
|
||||||
(returns NULL if error).
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
(a function to make proper SFTP_ATTRIBUTES structures is on the way )
|
|
||||||
|
|
||||||
<h3>D) Closing the session</h3>
|
|
||||||
<div class="prot">
|
|
||||||
void sftp_free(SFTP_SESSION *sftp);
|
|
||||||
</div>
|
|
||||||
it closes the sftp channel and subsystem.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>7- Handling the errors</h2>
|
|
||||||
<div class="tout">
|
|
||||||
When some function returns an error code, it's allways possible to get an
|
|
||||||
english message describing the problem. the function ssh_get_error()
|
|
||||||
returns a pointer to the static error buffer.<br>
|
|
||||||
ssh_error_code() returns the error code number. it's declared as an enum:<br>
|
|
||||||
SSH_NO_ERROR, SSH_REQUEST_DENIED, SSH_INVALID_REQUEST, SSH_CONNECTION_LOST,
|
|
||||||
SSH_FATAL, SSH_INVALID_DATA.<br><br>
|
|
||||||
SSH_REQUEST_DENIED means the ssh server refused your request but the situation is
|
|
||||||
recoverable. the others mean something happened to the connection (some
|
|
||||||
encryption problems, server problems, library bug, ...).<br>
|
|
||||||
SSH_INVALID_REQUEST means the library got some garbage from server. (But might be
|
|
||||||
recoverable).<br>
|
|
||||||
SSH_FATAL means the connection has an important problem and isn't probably
|
|
||||||
recoverable.<br>
|
|
||||||
<br>
|
|
||||||
Most of time, the error returned are SSH_FATAL, but some functions (generaly the
|
|
||||||
<i>ssh_request_*</i> ones) may fail because of server denying request. In these cases, SSH_REQUEST_DENIED is returned.<br><br>
|
|
||||||
|
|
||||||
You'll see in the prototype SSH_SESSION *session. That's because for thread
|
|
||||||
safety, error messages that can be attached to a session aren't static
|
|
||||||
anymore. So, any error that could happen during ssh_getopt(), options_* or
|
|
||||||
ssh_connect() will be retreavable giving NULL as argument.<br>
|
|
||||||
<br>
|
|
||||||
<div class="prot">
|
|
||||||
char *ssh_get_error(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
returns a pointer to a static message error from the given session. No
|
|
||||||
message freeing is needed.<br><br>
|
|
||||||
<div class="prot">
|
|
||||||
enum ssh_error ssh_get_error_code(SSH_SESSION *session);
|
|
||||||
</div>
|
|
||||||
returns the error code that last happened along with the message.
|
|
||||||
<br><br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>8- Final word</h2>
|
|
||||||
<div class="tout">
|
|
||||||
I made this library because nothing in the Open source or free software community was existing yet. This project is a very personnal one as it's the first "useful" thing I ever wrote.
|
|
||||||
I hope it fits your needs, but remember the experimental state of libssh : if
|
|
||||||
something doesn't work, please mail me. If something lacks, please ask for it.
|
|
||||||
If something stinks, please write a patch and send it !
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
5
doc/CMakeLists.txt
Normal file
5
doc/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Build the documentation
|
||||||
|
#
|
||||||
|
include(UseDoxygen OPTIONAL)
|
||||||
|
|
||||||
1
doc/TracFooter.html
Normal file
1
doc/TracFooter.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<!-- Doxygen TracFooter -->
|
||||||
4
doc/TracHeader.html
Normal file
4
doc/TracHeader.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<!-- Doxygen TracHeader -->
|
||||||
|
<style>@import url(/chrome/site/doxygen.css);</style>
|
||||||
|
<style>@import url(/chrome/site/tabs.css);</style>
|
||||||
|
<!-- /Doxygen TracHeader -->
|
||||||
373
doc/authentication.dox
Normal file
373
doc/authentication.dox
Normal file
@@ -0,0 +1,373 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_authentication Chapter 2: A deeper insight on authentication
|
||||||
|
@section authentication_details A deeper insight on authentication
|
||||||
|
|
||||||
|
In our guided tour, we merely mentioned that the user needed to authenticate.
|
||||||
|
We didn't explain much in detail how that was supposed to happen.
|
||||||
|
This chapter explains better the four authentication methods: with public keys,
|
||||||
|
with a password, with challenges and responses (keyboard-interactive), and with
|
||||||
|
no authentication at all.
|
||||||
|
|
||||||
|
If your software is supposed to connect to an arbitrary server, then you
|
||||||
|
might need to support all authentication methods. If your software will
|
||||||
|
connect only to a given server, then it might be enough for your software
|
||||||
|
to support only the authentication methods used by that server. If you are
|
||||||
|
the administrator of the server, it might be your call to choose those
|
||||||
|
authentication methods.
|
||||||
|
|
||||||
|
It is not the purpose of this document to review in detail the advantages
|
||||||
|
and drawbacks of each authentication method. You are therefore invited
|
||||||
|
to read the abundant documentation on this topic to fully understand the
|
||||||
|
advantages and security risks linked to each method.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection pubkeys Authenticating with public keys
|
||||||
|
|
||||||
|
libssh is fully compatible with the openssh public and private keys. You
|
||||||
|
can either use the automatic public key authentication method provided by
|
||||||
|
libssh, or roll your own using the public key functions.
|
||||||
|
|
||||||
|
The process of authenticating by public key to a server is the following:
|
||||||
|
- you scan a list of files that contain public keys. each key is sent to
|
||||||
|
the SSH server, until the server acknowledges a key (a key it knows can be
|
||||||
|
used to authenticate the user).
|
||||||
|
- then, you retrieve the private key for this key and send a message
|
||||||
|
proving that you know that private key.
|
||||||
|
|
||||||
|
The function ssh_userauth_autopubkey() does this using the available keys in
|
||||||
|
"~/.ssh/". The return values are the following:
|
||||||
|
- SSH_AUTH_ERROR: some serious error happened during authentication
|
||||||
|
- SSH_AUTH_DENIED: no key matched
|
||||||
|
- SSH_AUTH_SUCCESS: you are now authenticated
|
||||||
|
- SSH_AUTH_PARTIAL: some key matched but you still have to provide an other
|
||||||
|
mean of authentication (like a password).
|
||||||
|
|
||||||
|
The ssh_userauth_autopubkey() function also tries to authenticate using the
|
||||||
|
SSH agent, if you have one running, or the "none" method otherwise.
|
||||||
|
|
||||||
|
If you wish to authenticate with public key by your own, follow these steps:
|
||||||
|
- Retrieve the public key in a ssh_string using publickey_from_file().
|
||||||
|
- Offer the public key to the SSH server using ssh_userauth_offer_pubkey().
|
||||||
|
If the return value is SSH_AUTH_SUCCESS, the SSH server accepts to
|
||||||
|
authenticate using the public key and you can go to the next step.
|
||||||
|
- Retrieve the private key, using the privatekey_from_file() function. If
|
||||||
|
a passphrase is needed, either the passphrase specified as argument or
|
||||||
|
a callback (see callbacks section) will be used.
|
||||||
|
- Authenticate using ssh_userauth_pubkey() with your public key string
|
||||||
|
and private key.
|
||||||
|
- Do not forget cleaning up memory using string_free() and privatekey_free().
|
||||||
|
|
||||||
|
Here is a minimalistic example of public key authentication:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int authenticate_pubkey(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_userauth_autopubkey(session, NULL);
|
||||||
|
|
||||||
|
if (rc == SSH_AUTH_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Authentication failed: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see ssh_userauth_autopubkey
|
||||||
|
@see ssh_userauth_offer_pubkey
|
||||||
|
@see ssh_userauth_pubkey
|
||||||
|
@see publickey_from_file
|
||||||
|
@see publickey_from_privatekey
|
||||||
|
@see string_free
|
||||||
|
@see privatekey_from_file
|
||||||
|
@see privatekey_free
|
||||||
|
|
||||||
|
|
||||||
|
@subsection password Authenticating with a password
|
||||||
|
|
||||||
|
The function ssh_userauth_password() serves the purpose of authenticating
|
||||||
|
using a password. It will return SSH_AUTH_SUCCESS if the password worked,
|
||||||
|
or one of other constants otherwise. It's your work to ask the password
|
||||||
|
and to deallocate it in a secure manner.
|
||||||
|
|
||||||
|
If your server complains that the password is wrong, but you can still
|
||||||
|
authenticate using openssh's client (issuing password), it's probably
|
||||||
|
because openssh only accept keyboard-interactive. Switch to
|
||||||
|
keyboard-interactive authentication, or try to configure plain text passwords
|
||||||
|
on the SSH server.
|
||||||
|
|
||||||
|
Here is a small example of password authentication:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int authenticate_password(ssh_session session)
|
||||||
|
{
|
||||||
|
char *password;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
password = getpass("Enter your password: ");
|
||||||
|
rc = ssh_userauth_password(session, NULL, password);
|
||||||
|
if (rc == SSH_AUTH_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Authentication failed: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see ssh_userauth_password
|
||||||
|
|
||||||
|
|
||||||
|
@subsection keyb_int The keyboard-interactive authentication method
|
||||||
|
|
||||||
|
The keyboard-interactive method is, as its name tells, interactive. The
|
||||||
|
server will issue one or more challenges that the user has to answer,
|
||||||
|
until the server takes an authentication decision.
|
||||||
|
|
||||||
|
ssh_userauth_kbdint() is the the main keyboard-interactive function.
|
||||||
|
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
|
||||||
|
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
|
||||||
|
|
||||||
|
The keyboard-interactive authentication method of SSH2 is a feature that
|
||||||
|
permits the server to ask a certain number of questions in an interactive
|
||||||
|
manner to the client, until it decides to accept or deny the login.
|
||||||
|
|
||||||
|
To begin, you call ssh_userauth_kbdint() (just set user and submethods to
|
||||||
|
NULL) and store the answer.
|
||||||
|
|
||||||
|
If the answer is SSH_AUTH_INFO, it means that the server has sent a few
|
||||||
|
questions that you should ask the user. You can retrieve these questions
|
||||||
|
with the following functions: ssh_userauth_kbdint_getnprompts(),
|
||||||
|
ssh_userauth_kbdint_getname(), ssh_userauth_kbdint_getinstruction(), and
|
||||||
|
ssh_userauth_kbdint_getprompt().
|
||||||
|
|
||||||
|
Set the answer for each question in the challenge using
|
||||||
|
ssh_userauth_kbdint_setanswer().
|
||||||
|
|
||||||
|
Then, call again ssh_userauth_kbdint() and start the process again until
|
||||||
|
these functions returns something else than SSH_AUTH_INFO.
|
||||||
|
|
||||||
|
Here are a few remarks:
|
||||||
|
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
|
||||||
|
- The server can send an empty question set (this is the default behavior
|
||||||
|
on my system) after you have sent the answers to the first questions.
|
||||||
|
You must still parse the answer, it might contain some
|
||||||
|
message from the server saying hello or such things. Just call
|
||||||
|
ssh_userauth_kbdint() until needed.
|
||||||
|
- The meaning of "name", "prompt", "instruction" may be a little
|
||||||
|
confusing. An explanation is given in the RFC section that follows.
|
||||||
|
|
||||||
|
Here is a little note about how to use the information from
|
||||||
|
keyboard-interactive authentication, coming from the RFC itself (rfc4256):
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
|
||||||
|
3.3 User Interface Upon receiving a request message, the client SHOULD
|
||||||
|
prompt the user as follows: A command line interface (CLI) client SHOULD
|
||||||
|
print the name and instruction (if non-empty), adding newlines. Then for
|
||||||
|
each prompt in turn, the client SHOULD display the prompt and read the
|
||||||
|
user input.
|
||||||
|
|
||||||
|
A graphical user interface (GUI) client has many choices on how to prompt
|
||||||
|
the user. One possibility is to use the name field (possibly prefixed
|
||||||
|
with the application's name) as the title of a dialog window in which
|
||||||
|
the prompt(s) are presented. In that dialog window, the instruction field
|
||||||
|
would be a text message, and the prompts would be labels for text entry
|
||||||
|
fields. All fields SHOULD be presented to the user, for example an
|
||||||
|
implementation SHOULD NOT discard the name field because its windows lack
|
||||||
|
titles; it SHOULD instead find another way to display this information. If
|
||||||
|
prompts are presented in a dialog window, then the client SHOULD NOT
|
||||||
|
present each prompt in a separate window.
|
||||||
|
|
||||||
|
All clients MUST properly handle an instruction field with embedded
|
||||||
|
newlines. They SHOULD also be able to display at least 30 characters for
|
||||||
|
the name and prompts. If the server presents names or prompts longer than 30
|
||||||
|
characters, the client MAY truncate these fields to the length it can
|
||||||
|
display. If the client does truncate any fields, there MUST be an obvious
|
||||||
|
indication that such truncation has occured.
|
||||||
|
|
||||||
|
The instruction field SHOULD NOT be truncated. Clients SHOULD use control
|
||||||
|
character filtering as discussed in [SSH-ARCH] to avoid attacks by
|
||||||
|
including terminal control characters in the fields to be displayed.
|
||||||
|
|
||||||
|
For each prompt, the corresponding echo field indicates whether or not
|
||||||
|
the user input should be echoed as characters are typed. Clients SHOULD
|
||||||
|
correctly echo/mask user input for each prompt independently of other
|
||||||
|
prompts in the request message. If a client does not honor the echo field
|
||||||
|
for whatever reason, then the client MUST err on the side of
|
||||||
|
masking input. A GUI client might like to have a checkbox toggling
|
||||||
|
echo/mask. Clients SHOULD NOT add any additional characters to the prompt
|
||||||
|
such as ": " (colon-space); the server is responsible for supplying all
|
||||||
|
text to be displayed to the user. Clients MUST also accept empty responses
|
||||||
|
from the user and pass them on as empty strings.
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
The following example shows how to perform keyboard-interactive authentication:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int authenticate_kbdint(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_userauth_kbdint(session, NULL, NULL);
|
||||||
|
while (rc == SSH_AUTH_INFO)
|
||||||
|
{
|
||||||
|
const char *name, *instruction;
|
||||||
|
int nprompts, iprompt;
|
||||||
|
|
||||||
|
name = ssh_userauth_kbdint_getname(session);
|
||||||
|
instruction = ssh_userauth_kbdint_getinstruction(session);
|
||||||
|
nprompts = ssh_userauth_kbdint_getnprompts(session);
|
||||||
|
|
||||||
|
if (strlen(name) > 0)
|
||||||
|
printf("%s\n", name);
|
||||||
|
if (strlen(instruction) > 0)
|
||||||
|
printf("%s\n", instruction);
|
||||||
|
for (iprompt = 0; iprompt < nprompts; iprompt++)
|
||||||
|
{
|
||||||
|
const char *prompt;
|
||||||
|
char echo;
|
||||||
|
|
||||||
|
prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo);
|
||||||
|
if (echo)
|
||||||
|
{
|
||||||
|
char buffer[128], *ptr;
|
||||||
|
|
||||||
|
printf("%s", prompt);
|
||||||
|
if (fgets(buffer, sizeof(buffer), stdin) == NULL)
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
buffer[sizeof(buffer) - 1] = '\0';
|
||||||
|
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||||
|
*ptr = '\0';
|
||||||
|
if (ssh_userauth_kbdint_setanswer(session, iprompt, buffer) < 0)
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
memset(buffer, 0, strlen(buffer));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = getpass(prompt);
|
||||||
|
if (ssh_userauth_kbdint_setanswer(session, iprompt, ptr) < 0)
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = ssh_userauth_kbdint(session, NULL, NULL);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see ssh_userauth_kbdint()
|
||||||
|
@see ssh_userauth_kbdint_getnprompts
|
||||||
|
@see ssh_userauth_kbdint_getname
|
||||||
|
@see ssh_userauth_kbdint_getinstruction
|
||||||
|
@see ssh_userauth_kbdint_getprompt
|
||||||
|
@see ssh_userauth_kbdint_setanswer()
|
||||||
|
|
||||||
|
|
||||||
|
@subsection none Authenticating with "none" method
|
||||||
|
|
||||||
|
The primary purpose of the "none" method is to get authenticated **without**
|
||||||
|
any credential. Don't do that, use one of the other authentication methods,
|
||||||
|
unless you really want to grant anonymous access.
|
||||||
|
|
||||||
|
If the account has no password, and if the server is configured to let you
|
||||||
|
pass, ssh_userauth_none() might answer SSH_AUTH_SUCCESS.
|
||||||
|
|
||||||
|
The following example shows how to perform "none" authentication:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int authenticate_kbdint(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_userauth_none(session, NULL, NULL);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@subsection auth_list Getting the list of supported authentications
|
||||||
|
|
||||||
|
You are not meant to choose a given authentication method, you can
|
||||||
|
let the server tell you which methods are available. Once you know them,
|
||||||
|
you try them one after the other.
|
||||||
|
|
||||||
|
The following example shows how to get the list of available authentication
|
||||||
|
methods with ssh_userauth_list() and how to use the result:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int test_several_auth_methods(ssh_session session)
|
||||||
|
{
|
||||||
|
int method, rc;
|
||||||
|
|
||||||
|
method = ssh_userauth_list(session, NULL);
|
||||||
|
|
||||||
|
if (method & SSH_AUTH_METHOD_NONE)
|
||||||
|
{ // For the source code of function authenticate_none(),
|
||||||
|
// refer to the corresponding example
|
||||||
|
rc = authenticate_none(session);
|
||||||
|
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||||
|
}
|
||||||
|
if (method & SSH_AUTH_METHOD_PUBLICKEY)
|
||||||
|
{ // For the source code of function authenticate_pubkey(),
|
||||||
|
// refer to the corresponding example
|
||||||
|
rc = authenticate_pubkey(session);
|
||||||
|
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||||
|
}
|
||||||
|
if (method & SSH_AUTH_METHOD_INTERACTIVE)
|
||||||
|
{ // For the source code of function authenticate_kbdint(),
|
||||||
|
// refer to the corresponding example
|
||||||
|
rc = authenticate_kbdint(session);
|
||||||
|
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||||
|
}
|
||||||
|
if (method & SSH_AUTH_METHOD_PASSWORD)
|
||||||
|
{ // For the source code of function authenticate_password(),
|
||||||
|
// refer to the corresponding example
|
||||||
|
rc = authenticate_password(session);
|
||||||
|
if (rc == SSH_AUTH_SUCCESS) return rc;
|
||||||
|
}
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection banner Getting the banner
|
||||||
|
|
||||||
|
The SSH server might send a banner, which you can retrieve with
|
||||||
|
ssh_get_issue_banner(), then display to the user.
|
||||||
|
|
||||||
|
The following example shows how to retrieve and dispose the issue banner:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int display_banner(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *banner;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*** Does not work without calling ssh_userauth_none() first ***
|
||||||
|
*** That will be fixed ***
|
||||||
|
*/
|
||||||
|
rc = ssh_userauth_none(session, NULL);
|
||||||
|
if (rc == SSH_AUTH_ERROR)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
banner = ssh_get_issue_banner(session);
|
||||||
|
if (banner)
|
||||||
|
{
|
||||||
|
printf("%s\n", banner);
|
||||||
|
free(banner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
94
doc/command.dox
Normal file
94
doc/command.dox
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_command Chapter 4: Passing a remote command
|
||||||
|
@section remote_command Passing a remote command
|
||||||
|
|
||||||
|
Previous chapter has shown how to open a full shell session, with an attached
|
||||||
|
terminal or not. If you only need to execute a command on the remote end,
|
||||||
|
you don't need all that complexity.
|
||||||
|
|
||||||
|
The method described here is suited for executing only one remote command.
|
||||||
|
If you need to issue several commands in a row, you should consider using
|
||||||
|
a non-interactive remote shell, as explained in previous chapter.
|
||||||
|
|
||||||
|
@see shell
|
||||||
|
|
||||||
|
|
||||||
|
@subsection exec_remote Executing a remote command
|
||||||
|
|
||||||
|
The first steps for executing a remote command are identical to those
|
||||||
|
for opening remote shells. You first need a SSH channel, and then
|
||||||
|
a SSH session that uses this channel:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int show_remote_files(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_channel channel;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
channel = ssh_channel_new(session);
|
||||||
|
if (channel == NULL) return SSH_ERROR;
|
||||||
|
|
||||||
|
rc = ssh_channel_open_session(channel);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Once a session is open, you can start the remote command with
|
||||||
|
ssh_channel_request_exec():
|
||||||
|
|
||||||
|
@code
|
||||||
|
rc = ssh_channel_request_exec(channel, "ls -l");
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If the remote command displays data, you get them with ssh_channel_read().
|
||||||
|
This function returns the number of bytes read. If there is no more
|
||||||
|
data to read on the channel, this function returns 0, and you can go to next step.
|
||||||
|
If an error has been encountered, it returns a negative value:
|
||||||
|
|
||||||
|
@code
|
||||||
|
char buffer[256];
|
||||||
|
unsigned int nbytes;
|
||||||
|
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
while (nbytes > 0)
|
||||||
|
{
|
||||||
|
if (fwrite(buffer, 1, nbytes, stdout) != nbytes)
|
||||||
|
{
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes < 0)
|
||||||
|
{
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Once you read the result of the remote command, you send an
|
||||||
|
end-of-file to the channel, close it, and free the memory
|
||||||
|
that it used:
|
||||||
|
|
||||||
|
@code
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Doxyfile 1.5.2
|
# Doxyfile 1.6.1
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project
|
# doxygen (www.doxygen.org) for a project
|
||||||
@@ -14,31 +14,31 @@
|
|||||||
# Project related configuration options
|
# Project related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# This tag specifies the encoding used for all characters in the config file that
|
# This tag specifies the encoding used for all characters in the config file
|
||||||
# follow. The default is UTF-8 which is also the encoding used for all text before
|
# that follow. The default is UTF-8 which is also the encoding used for all
|
||||||
# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
|
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
||||||
# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
|
# iconv built into libc) for the transcoding. See
|
||||||
# possible encodings.
|
# http://www.gnu.org/software/libiconv for the list of possible encodings.
|
||||||
|
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
|
||||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
||||||
# by quotes) that should identify the project.
|
# by quotes) that should identify the project.
|
||||||
|
|
||||||
PROJECT_NAME = libssh
|
PROJECT_NAME = @APPLICATION_NAME@
|
||||||
|
|
||||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.2.1-svn
|
PROJECT_NUMBER = @APPLICATION_VERSION@
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
# If a relative path is entered, it will be relative to the location
|
# If a relative path is entered, it will be relative to the location
|
||||||
# where doxygen was started. If left blank the current directory will be used.
|
# where doxygen was started. If left blank the current directory will be used.
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = doxygen/
|
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@
|
||||||
|
|
||||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||||
@@ -54,10 +54,11 @@ CREATE_SUBDIRS = NO
|
|||||||
# information to generate all constant output in the proper language.
|
# information to generate all constant output in the proper language.
|
||||||
# The default language is English, other supported languages are:
|
# The default language is English, other supported languages are:
|
||||||
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
|
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
|
||||||
# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
|
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
|
||||||
# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
|
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
|
||||||
# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
|
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
|
||||||
# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
|
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
|
||||||
|
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
|
||||||
|
|
||||||
OUTPUT_LANGUAGE = English
|
OUTPUT_LANGUAGE = English
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ FULL_PATH_NAMES = YES
|
|||||||
# If left blank the directory from which doxygen is run is used as the
|
# If left blank the directory from which doxygen is run is used as the
|
||||||
# path to strip.
|
# path to strip.
|
||||||
|
|
||||||
STRIP_FROM_PATH =
|
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@
|
||||||
|
|
||||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
||||||
# the path mentioned in the documentation of a class, which tells
|
# the path mentioned in the documentation of a class, which tells
|
||||||
@@ -132,7 +133,7 @@ STRIP_FROM_PATH =
|
|||||||
# definition is used. Otherwise one should specify the include paths that
|
# definition is used. Otherwise one should specify the include paths that
|
||||||
# are normally passed to the compiler using the -I flag.
|
# are normally passed to the compiler using the -I flag.
|
||||||
|
|
||||||
STRIP_FROM_INC_PATH =
|
STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@
|
||||||
|
|
||||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
|
||||||
# (but less readable) file names. This can be useful is your file systems
|
# (but less readable) file names. This can be useful is your file systems
|
||||||
@@ -143,10 +144,18 @@ SHORT_NAMES = NO
|
|||||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
||||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||||
# comment as the brief description. If set to NO, the JavaDoc
|
# comment as the brief description. If set to NO, the JavaDoc
|
||||||
# comments will behave just like the Qt-style comments (thus requiring an
|
# comments will behave just like regular Qt-style comments
|
||||||
# explicit @brief command for a brief description.
|
# (thus requiring an explicit @brief command for a brief description.)
|
||||||
|
|
||||||
JAVADOC_AUTOBRIEF = NO
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
|
||||||
|
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
|
||||||
|
# interpret the first line (until the first dot) of a Qt-style
|
||||||
|
# comment as the brief description. If set to NO, the comments
|
||||||
|
# will behave just like regular Qt-style comments (thus requiring
|
||||||
|
# an explicit \brief command for a brief description.)
|
||||||
|
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
|
||||||
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
||||||
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
||||||
@@ -156,13 +165,6 @@ JAVADOC_AUTOBRIEF = NO
|
|||||||
|
|
||||||
MULTILINE_CPP_IS_BRIEF = NO
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
|
||||||
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
|
|
||||||
# will output the detailed description near the top, like JavaDoc.
|
|
||||||
# If set to NO, the detailed description appears after the member
|
|
||||||
# documentation.
|
|
||||||
|
|
||||||
DETAILS_AT_TOP = NO
|
|
||||||
|
|
||||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||||
# member inherits the documentation from any documented member that it
|
# member inherits the documentation from any documented member that it
|
||||||
# re-implements.
|
# re-implements.
|
||||||
@@ -178,7 +180,7 @@ SEPARATE_MEMBER_PAGES = NO
|
|||||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
||||||
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
||||||
|
|
||||||
TAB_SIZE = 8
|
TAB_SIZE = 2
|
||||||
|
|
||||||
# This tag can be used to specify a number of aliases that acts
|
# This tag can be used to specify a number of aliases that acts
|
||||||
# as commands in the documentation. An alias has the form "name=value".
|
# as commands in the documentation. An alias has the form "name=value".
|
||||||
@@ -197,14 +199,37 @@ ALIASES =
|
|||||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
|
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
|
||||||
# sources only. Doxygen will then generate output that is more tailored for Java.
|
# sources only. Doxygen will then generate output that is more tailored for
|
||||||
# For instance, namespaces will be presented as packages, qualified scopes
|
# Java. For instance, namespaces will be presented as packages, qualified
|
||||||
# will look different, etc.
|
# scopes will look different, etc.
|
||||||
|
|
||||||
OPTIMIZE_OUTPUT_JAVA = NO
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
|
||||||
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
|
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
|
||||||
# include (a tag file for) the STL sources as input, then you should
|
# sources only. Doxygen will then generate output that is more tailored for
|
||||||
|
# Fortran.
|
||||||
|
|
||||||
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
|
||||||
|
# sources. Doxygen will then generate output that is tailored for
|
||||||
|
# VHDL.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
|
||||||
|
# Doxygen selects the parser to use depending on the extension of the files it parses.
|
||||||
|
# With this tag you can assign which parser to use for a given extension.
|
||||||
|
# Doxygen has a built-in mapping, but you can override or extend it using this tag.
|
||||||
|
# The format is ext=language, where ext is a file extension, and language is one of
|
||||||
|
# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
|
||||||
|
# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
|
||||||
|
# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||||
|
# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
|
||||||
|
|
||||||
|
EXTENSION_MAPPING =
|
||||||
|
|
||||||
|
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
|
||||||
|
# to include (a tag file for) the STL sources as input, then you should
|
||||||
# set this tag to YES in order to let doxygen match functions declarations and
|
# set this tag to YES in order to let doxygen match functions declarations and
|
||||||
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
|
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
|
||||||
# func(std::string) {}). This also make the inheritance and collaboration
|
# func(std::string) {}). This also make the inheritance and collaboration
|
||||||
@@ -217,6 +242,21 @@ BUILTIN_STL_SUPPORT = NO
|
|||||||
|
|
||||||
CPP_CLI_SUPPORT = NO
|
CPP_CLI_SUPPORT = NO
|
||||||
|
|
||||||
|
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
|
||||||
|
# Doxygen will parse them like normal C++ but will assume all classes use public
|
||||||
|
# instead of private inheritance when no explicit protection keyword is present.
|
||||||
|
|
||||||
|
SIP_SUPPORT = NO
|
||||||
|
|
||||||
|
# For Microsoft's IDL there are propget and propput attributes to indicate getter
|
||||||
|
# and setter methods for a property. Setting this option to YES (the default)
|
||||||
|
# will make doxygen to replace the get and set methods by a property in the
|
||||||
|
# documentation. This will only work if the methods are indeed getting or
|
||||||
|
# setting a simple type. If this is not the case, or you want to show the
|
||||||
|
# methods anyway, you should set this option to NO.
|
||||||
|
|
||||||
|
IDL_PROPERTY_SUPPORT = YES
|
||||||
|
|
||||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||||
# tag is set to YES, then doxygen will reuse the documentation of the first
|
# tag is set to YES, then doxygen will reuse the documentation of the first
|
||||||
# member in the group (if any) for the other members of the group. By default
|
# member in the group (if any) for the other members of the group. By default
|
||||||
@@ -232,6 +272,32 @@ DISTRIBUTE_GROUP_DOC = NO
|
|||||||
|
|
||||||
SUBGROUPING = YES
|
SUBGROUPING = YES
|
||||||
|
|
||||||
|
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
|
||||||
|
# is documented as struct, union, or enum with the name of the typedef. So
|
||||||
|
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
|
||||||
|
# with name TypeT. When disabled the typedef will appear as a member of a file,
|
||||||
|
# namespace, or class. And the struct will be named TypeS. This can typically
|
||||||
|
# be useful for C code in case the coding convention dictates that all compound
|
||||||
|
# types are typedef'ed and only the typedef is referenced, never the tag name.
|
||||||
|
|
||||||
|
TYPEDEF_HIDES_STRUCT = YES
|
||||||
|
|
||||||
|
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
|
||||||
|
# determine which symbols to keep in memory and which to flush to disk.
|
||||||
|
# When the cache is full, less often used symbols will be written to disk.
|
||||||
|
# For small to medium size projects (<1000 input files) the default value is
|
||||||
|
# probably good enough. For larger projects a too small cache size can cause
|
||||||
|
# doxygen to be busy swapping symbols to and from disk most of the time
|
||||||
|
# causing a significant performance penality.
|
||||||
|
# If the system has enough physical memory increasing the cache will improve the
|
||||||
|
# performance by keeping more symbols in memory. Note that the value works on
|
||||||
|
# a logarithmic scale so increasing the size by one will rougly double the
|
||||||
|
# memory usage. The cache size is given by this formula:
|
||||||
|
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
|
||||||
|
# corresponding to a cache size of 2^16 = 65536 symbols
|
||||||
|
|
||||||
|
SYMBOL_CACHE_SIZE = 0
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Build related configuration options
|
# Build related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -266,6 +332,14 @@ EXTRACT_LOCAL_CLASSES = NO
|
|||||||
|
|
||||||
EXTRACT_LOCAL_METHODS = NO
|
EXTRACT_LOCAL_METHODS = NO
|
||||||
|
|
||||||
|
# If this flag is set to YES, the members of anonymous namespaces will be
|
||||||
|
# extracted and appear in the documentation as a namespace called
|
||||||
|
# 'anonymous_namespace{file}', where file will be replaced with the base
|
||||||
|
# name of the file that contains the anonymous namespace. By default
|
||||||
|
# anonymous namespace are hidden.
|
||||||
|
|
||||||
|
EXTRACT_ANON_NSPACES = NO
|
||||||
|
|
||||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||||
# undocumented members of documented classes, files or namespaces.
|
# undocumented members of documented classes, files or namespaces.
|
||||||
# If set to NO (the default) these members will be included in the
|
# If set to NO (the default) these members will be included in the
|
||||||
@@ -300,7 +374,7 @@ HIDE_IN_BODY_DOCS = NO
|
|||||||
# to NO (the default) then the documentation will be excluded.
|
# to NO (the default) then the documentation will be excluded.
|
||||||
# Set it to YES to include the internal documentation.
|
# Set it to YES to include the internal documentation.
|
||||||
|
|
||||||
INTERNAL_DOCS = NO
|
INTERNAL_DOCS = @CMAKE_INTERNAL_DOC@
|
||||||
|
|
||||||
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
|
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
|
||||||
# file names in lower-case letters. If set to YES upper-case letters are also
|
# file names in lower-case letters. If set to YES upper-case letters are also
|
||||||
@@ -341,6 +415,16 @@ SORT_MEMBER_DOCS = YES
|
|||||||
|
|
||||||
SORT_BRIEF_DOCS = YES
|
SORT_BRIEF_DOCS = YES
|
||||||
|
|
||||||
|
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
|
||||||
|
|
||||||
|
SORT_MEMBERS_CTORS_1ST = NO
|
||||||
|
|
||||||
|
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
|
||||||
|
# hierarchy of group names into alphabetical order. If set to NO (the default)
|
||||||
|
# the group names will appear in their defined order.
|
||||||
|
|
||||||
|
SORT_GROUP_NAMES = NO
|
||||||
|
|
||||||
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
|
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
|
||||||
# sorted by fully-qualified names, including namespaces. If set to
|
# sorted by fully-qualified names, including namespaces. If set to
|
||||||
# NO (the default), the class list will be sorted only by class name,
|
# NO (the default), the class list will be sorted only by class name,
|
||||||
@@ -402,9 +486,22 @@ SHOW_USED_FILES = YES
|
|||||||
|
|
||||||
SHOW_DIRECTORIES = NO
|
SHOW_DIRECTORIES = NO
|
||||||
|
|
||||||
|
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
|
||||||
|
# This will remove the Files entry from the Quick Index and from the
|
||||||
|
# Folder Tree View (if specified). The default is YES.
|
||||||
|
|
||||||
|
SHOW_FILES = YES
|
||||||
|
|
||||||
|
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
|
||||||
|
# Namespaces page.
|
||||||
|
# This will remove the Namespaces entry from the Quick Index
|
||||||
|
# and from the Folder Tree View (if specified). The default is YES.
|
||||||
|
|
||||||
|
SHOW_NAMESPACES = YES
|
||||||
|
|
||||||
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
||||||
# doxygen should invoke to get the current version for each file (typically from the
|
# doxygen should invoke to get the current version for each file (typically from
|
||||||
# version control system). Doxygen will invoke the program by executing (via
|
# the version control system). Doxygen will invoke the program by executing (via
|
||||||
# popen()) the command <command> <input-file>, where <command> is the value of
|
# popen()) the command <command> <input-file>, where <command> is the value of
|
||||||
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
|
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
|
||||||
# provided by doxygen. Whatever the program writes to standard output
|
# provided by doxygen. Whatever the program writes to standard output
|
||||||
@@ -412,6 +509,15 @@ SHOW_DIRECTORIES = NO
|
|||||||
|
|
||||||
FILE_VERSION_FILTER =
|
FILE_VERSION_FILTER =
|
||||||
|
|
||||||
|
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
|
||||||
|
# doxygen. The layout file controls the global structure of the generated output files
|
||||||
|
# in an output format independent way. The create the layout file that represents
|
||||||
|
# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
|
||||||
|
# file name after the option, if omitted DoxygenLayout.xml will be used as the name
|
||||||
|
# of the layout file.
|
||||||
|
|
||||||
|
LAYOUT_FILE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to warning and progress messages
|
# configuration options related to warning and progress messages
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -472,13 +578,15 @@ WARN_LOGFILE =
|
|||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# with spaces.
|
||||||
|
|
||||||
INPUT = include/ \
|
INPUT = @CMAKE_SOURCE_DIR@/include/libssh \
|
||||||
libssh/
|
@CMAKE_SOURCE_DIR@/src \
|
||||||
|
@CMAKE_SOURCE_DIR@/doc
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files that
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||||
# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
|
# also the default input encoding. Doxygen uses libiconv (or the iconv built
|
||||||
# See http://www.gnu.org/software/libiconv for the list of possible encodings.
|
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
|
||||||
|
# the list of possible encodings.
|
||||||
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
|
|
||||||
@@ -487,12 +595,14 @@ INPUT_ENCODING = UTF-8
|
|||||||
# and *.h) to filter out the source-files in the directories. If left
|
# and *.h) to filter out the source-files in the directories. If left
|
||||||
# blank the following patterns are tested:
|
# blank the following patterns are tested:
|
||||||
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
|
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
|
||||||
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
|
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
|
||||||
|
|
||||||
FILE_PATTERNS = *.c \
|
FILE_PATTERNS = *.cpp \
|
||||||
*.cc \
|
*.cc \
|
||||||
*.cpp \
|
*.c \
|
||||||
*.h \
|
*.h \
|
||||||
|
*.hh \
|
||||||
|
*.hpp \
|
||||||
*.dox
|
*.dox
|
||||||
|
|
||||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
||||||
@@ -519,12 +629,16 @@ EXCLUDE_SYMLINKS = NO
|
|||||||
# against the file with absolute path, so to exclude all test directories
|
# against the file with absolute path, so to exclude all test directories
|
||||||
# for example use the pattern */test/*
|
# for example use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_PATTERNS =
|
EXCLUDE_PATTERNS = */.git/* \
|
||||||
|
*/.svn/* \
|
||||||
|
*/cmake/* \
|
||||||
|
*/build/*
|
||||||
|
|
||||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||||
# (namespaces, classes, functions, etc.) that should be excluded from the output.
|
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||||
# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
|
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||||
# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
|
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||||
|
# AClass::ANamespace, ANamespace::*Test
|
||||||
|
|
||||||
EXCLUDE_SYMBOLS =
|
EXCLUDE_SYMBOLS =
|
||||||
|
|
||||||
@@ -532,21 +646,27 @@ EXCLUDE_SYMBOLS =
|
|||||||
# directories that contain example code fragments that are included (see
|
# directories that contain example code fragments that are included (see
|
||||||
# the \include command).
|
# the \include command).
|
||||||
|
|
||||||
EXAMPLE_PATH =
|
EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/examples
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||||
# and *.h) to filter out the source-files in the directories. If left
|
# and *.h) to filter out the source-files in the directories. If left
|
||||||
# blank all files are included.
|
# blank all files are included.
|
||||||
|
|
||||||
EXAMPLE_PATTERNS = *
|
EXAMPLE_PATTERNS = *.c \
|
||||||
|
*.h \
|
||||||
|
INSTALL \
|
||||||
|
DEPENDENCIES \
|
||||||
|
CHANGELOG \
|
||||||
|
LICENSE \
|
||||||
|
LGPL
|
||||||
|
|
||||||
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
||||||
# searched for input files to be used with the \include or \dontinclude
|
# searched for input files to be used with the \include or \dontinclude
|
||||||
# commands irrespective of the value of the RECURSIVE tag.
|
# commands irrespective of the value of the RECURSIVE tag.
|
||||||
# Possible values are YES and NO. If left blank NO is used.
|
# Possible values are YES and NO. If left blank NO is used.
|
||||||
|
|
||||||
EXAMPLE_RECURSIVE = NO
|
EXAMPLE_RECURSIVE = YES
|
||||||
|
|
||||||
# The IMAGE_PATH tag can be used to specify one or more files or
|
# The IMAGE_PATH tag can be used to specify one or more files or
|
||||||
# directories that contain image that are included in the documentation (see
|
# directories that contain image that are included in the documentation (see
|
||||||
@@ -559,14 +679,17 @@ IMAGE_PATH =
|
|||||||
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
||||||
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
||||||
# input file. Doxygen will then use the output that the filter program writes
|
# input file. Doxygen will then use the output that the filter program writes
|
||||||
# to standard output. If FILTER_PATTERNS is specified, this tag will be
|
# to standard output.
|
||||||
|
# If FILTER_PATTERNS is specified, this tag will be
|
||||||
# ignored.
|
# ignored.
|
||||||
|
|
||||||
INPUT_FILTER =
|
INPUT_FILTER =
|
||||||
|
|
||||||
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
||||||
# basis. Doxygen will compare the file name with each pattern and apply the
|
# basis.
|
||||||
# filter if there is a match. The filters are a list of the form:
|
# Doxygen will compare the file name with each pattern and apply the
|
||||||
|
# filter if there is a match.
|
||||||
|
# The filters are a list of the form:
|
||||||
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
|
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
|
||||||
# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
|
# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
|
||||||
# is applied to all files.
|
# is applied to all files.
|
||||||
@@ -601,13 +724,13 @@ INLINE_SOURCES = NO
|
|||||||
|
|
||||||
STRIP_CODE_COMMENTS = YES
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
|
||||||
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
|
# If the REFERENCED_BY_RELATION tag is set to YES
|
||||||
# then for each documented function all documented
|
# then for each documented function all documented
|
||||||
# functions referencing it will be listed.
|
# functions referencing it will be listed.
|
||||||
|
|
||||||
REFERENCED_BY_RELATION = YES
|
REFERENCED_BY_RELATION = YES
|
||||||
|
|
||||||
# If the REFERENCES_RELATION tag is set to YES (the default)
|
# If the REFERENCES_RELATION tag is set to YES
|
||||||
# then for each documented function all documented entities
|
# then for each documented function all documented entities
|
||||||
# called/used by that function will be listed.
|
# called/used by that function will be listed.
|
||||||
|
|
||||||
@@ -616,7 +739,8 @@ REFERENCES_RELATION = YES
|
|||||||
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
|
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
|
||||||
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
|
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
|
||||||
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
|
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
|
||||||
# link to the source code. Otherwise they will link to the documentstion.
|
# link to the source code.
|
||||||
|
# Otherwise they will link to the documentation.
|
||||||
|
|
||||||
REFERENCES_LINK_SOURCE = YES
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
|
||||||
@@ -648,7 +772,7 @@ ALPHABETICAL_INDEX = YES
|
|||||||
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
||||||
# in which this list will be split (can be a number in the range [1..20])
|
# in which this list will be split (can be a number in the range [1..20])
|
||||||
|
|
||||||
COLS_IN_ALPHA_INDEX = 5
|
COLS_IN_ALPHA_INDEX = 2
|
||||||
|
|
||||||
# In case all classes in a project start with a common prefix, all
|
# In case all classes in a project start with a common prefix, all
|
||||||
# classes will be put under the same header in the alphabetical index.
|
# classes will be put under the same header in the alphabetical index.
|
||||||
@@ -690,6 +814,11 @@ HTML_HEADER =
|
|||||||
|
|
||||||
HTML_FOOTER =
|
HTML_FOOTER =
|
||||||
|
|
||||||
|
# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
|
||||||
|
# documentation will contain the timesstamp.
|
||||||
|
|
||||||
|
HTML_TIMESTAMP = NO
|
||||||
|
|
||||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
||||||
# style sheet that is used by each HTML page. It can be used to
|
# style sheet that is used by each HTML page. It can be used to
|
||||||
# fine-tune the look of the HTML output. If the tag is left blank doxygen
|
# fine-tune the look of the HTML output. If the tag is left blank doxygen
|
||||||
@@ -705,9 +834,43 @@ HTML_STYLESHEET =
|
|||||||
|
|
||||||
HTML_ALIGN_MEMBERS = YES
|
HTML_ALIGN_MEMBERS = YES
|
||||||
|
|
||||||
|
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||||
|
# documentation will contain sections that can be hidden and shown after the
|
||||||
|
# page has loaded. For this to work a browser that supports
|
||||||
|
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
|
||||||
|
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
|
||||||
|
|
||||||
|
HTML_DYNAMIC_SECTIONS = NO
|
||||||
|
|
||||||
|
# If the GENERATE_DOCSET tag is set to YES, additional index files
|
||||||
|
# will be generated that can be used as input for Apple's Xcode 3
|
||||||
|
# integrated development environment, introduced with OSX 10.5 (Leopard).
|
||||||
|
# To create a documentation set, doxygen will generate a Makefile in the
|
||||||
|
# HTML output directory. Running make will produce the docset in that
|
||||||
|
# directory and running "make install" will install the docset in
|
||||||
|
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
|
||||||
|
# it at startup.
|
||||||
|
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
|
||||||
|
|
||||||
|
GENERATE_DOCSET = NO
|
||||||
|
|
||||||
|
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
|
||||||
|
# feed. A documentation feed provides an umbrella under which multiple
|
||||||
|
# documentation sets from a single provider (such as a company or product suite)
|
||||||
|
# can be grouped.
|
||||||
|
|
||||||
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
|
||||||
|
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
|
||||||
|
# should uniquely identify the documentation set bundle. This should be a
|
||||||
|
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
|
||||||
|
# will append .docset to the name.
|
||||||
|
|
||||||
|
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||||
# will be generated that can be used as input for tools like the
|
# will be generated that can be used as input for tools like the
|
||||||
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
|
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
|
||||||
# of the generated HTML documentation.
|
# of the generated HTML documentation.
|
||||||
|
|
||||||
GENERATE_HTMLHELP = NO
|
GENERATE_HTMLHELP = NO
|
||||||
@@ -732,6 +895,12 @@ HHC_LOCATION =
|
|||||||
|
|
||||||
GENERATE_CHI = NO
|
GENERATE_CHI = NO
|
||||||
|
|
||||||
|
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
|
||||||
|
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
|
||||||
|
# content.
|
||||||
|
|
||||||
|
CHM_INDEX_ENCODING =
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
|
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
|
||||||
# controls whether a binary table of contents is generated (YES) or a
|
# controls whether a binary table of contents is generated (YES) or a
|
||||||
# normal table of contents (NO) in the .chm file.
|
# normal table of contents (NO) in the .chm file.
|
||||||
@@ -743,6 +912,55 @@ BINARY_TOC = NO
|
|||||||
|
|
||||||
TOC_EXPAND = NO
|
TOC_EXPAND = NO
|
||||||
|
|
||||||
|
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
|
||||||
|
# are set, an additional index file will be generated that can be used as input for
|
||||||
|
# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
|
||||||
|
# HTML documentation.
|
||||||
|
|
||||||
|
GENERATE_QHP = NO
|
||||||
|
|
||||||
|
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
|
||||||
|
# be used to specify the file name of the resulting .qch file.
|
||||||
|
# The path specified is relative to the HTML output folder.
|
||||||
|
|
||||||
|
QCH_FILE =
|
||||||
|
|
||||||
|
# The QHP_NAMESPACE tag specifies the namespace to use when generating
|
||||||
|
# Qt Help Project output. For more information please see
|
||||||
|
# http://doc.trolltech.com/qthelpproject.html#namespace
|
||||||
|
|
||||||
|
QHP_NAMESPACE =
|
||||||
|
|
||||||
|
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
|
||||||
|
# Qt Help Project output. For more information please see
|
||||||
|
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
|
||||||
|
|
||||||
|
QHP_VIRTUAL_FOLDER = doc
|
||||||
|
|
||||||
|
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
|
||||||
|
# For more information please see
|
||||||
|
# http://doc.trolltech.com/qthelpproject.html#custom-filters
|
||||||
|
|
||||||
|
QHP_CUST_FILTER_NAME =
|
||||||
|
|
||||||
|
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
|
||||||
|
# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
|
||||||
|
|
||||||
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
|
||||||
|
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
|
||||||
|
# filter section matches.
|
||||||
|
# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
|
||||||
|
|
||||||
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
|
||||||
|
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
|
||||||
|
# be used to specify the location of Qt's qhelpgenerator.
|
||||||
|
# If non-empty doxygen will try to run qhelpgenerator on the generated
|
||||||
|
# .qhp file.
|
||||||
|
|
||||||
|
QHG_LOCATION =
|
||||||
|
|
||||||
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
||||||
# top of each HTML page. The value NO (the default) enables the index and
|
# top of each HTML page. The value NO (the default) enables the index and
|
||||||
# the value YES disables it.
|
# the value YES disables it.
|
||||||
@@ -754,21 +972,42 @@ DISABLE_INDEX = NO
|
|||||||
|
|
||||||
ENUM_VALUES_PER_LINE = 4
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
|
||||||
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
|
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
|
||||||
# generated containing a tree-like index structure (just like the one that
|
# structure should be generated to display hierarchical information.
|
||||||
|
# If the tag value is set to YES, a side panel will be generated
|
||||||
|
# containing a tree-like index structure (just like the one that
|
||||||
# is generated for HTML Help). For this to work a browser that supports
|
# is generated for HTML Help). For this to work a browser that supports
|
||||||
# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
|
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
|
||||||
# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
|
# Windows users are probably better off using the HTML help feature.
|
||||||
# probably better off using the HTML help feature.
|
|
||||||
|
|
||||||
GENERATE_TREEVIEW = NO
|
GENERATE_TREEVIEW = NO
|
||||||
|
|
||||||
|
# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
|
||||||
|
# and Class Hierarchy pages using a tree view instead of an ordered list.
|
||||||
|
|
||||||
|
USE_INLINE_TREES = NO
|
||||||
|
|
||||||
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
|
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
|
||||||
# used to set the initial width (in pixels) of the frame in which the tree
|
# used to set the initial width (in pixels) of the frame in which the tree
|
||||||
# is shown.
|
# is shown.
|
||||||
|
|
||||||
TREEVIEW_WIDTH = 250
|
TREEVIEW_WIDTH = 250
|
||||||
|
|
||||||
|
# Use this tag to change the font size of Latex formulas included
|
||||||
|
# as images in the HTML documentation. The default is 10. Note that
|
||||||
|
# when you change the font size after a successful doxygen run you need
|
||||||
|
# to manually remove any form_*.png images from the HTML output directory
|
||||||
|
# to force them to be regenerated.
|
||||||
|
|
||||||
|
FORMULA_FONTSIZE = 10
|
||||||
|
|
||||||
|
# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
|
||||||
|
# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
|
||||||
|
# there is already a search function so this one should typically
|
||||||
|
# be disabled.
|
||||||
|
|
||||||
|
SEARCHENGINE = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the LaTeX output
|
# configuration options related to the LaTeX output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -776,7 +1015,7 @@ TREEVIEW_WIDTH = 250
|
|||||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||||
# generate Latex output.
|
# generate Latex output.
|
||||||
|
|
||||||
GENERATE_LATEX = YES
|
GENERATE_LATEX = @DOXYFILE_LATEX@
|
||||||
|
|
||||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||||
@@ -787,13 +1026,13 @@ LATEX_OUTPUT = latex
|
|||||||
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
# invoked. If left blank `latex' will be used as the default command name.
|
# invoked. If left blank `latex' will be used as the default command name.
|
||||||
|
|
||||||
LATEX_CMD_NAME = latex
|
LATEX_CMD_NAME = @LATEX_COMPILER@
|
||||||
|
|
||||||
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
|
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
|
||||||
# generate index for LaTeX. If left blank `makeindex' will be used as the
|
# generate index for LaTeX. If left blank `makeindex' will be used as the
|
||||||
# default command name.
|
# default command name.
|
||||||
|
|
||||||
MAKEINDEX_CMD_NAME = makeindex
|
MAKEINDEX_CMD_NAME = @MAKEINDEX_COMPILER@
|
||||||
|
|
||||||
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
||||||
# LaTeX documents. This may be useful for small projects and may help to
|
# LaTeX documents. This may be useful for small projects and may help to
|
||||||
@@ -805,7 +1044,7 @@ COMPACT_LATEX = NO
|
|||||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||||
# executive. If left blank a4wide will be used.
|
# executive. If left blank a4wide will be used.
|
||||||
|
|
||||||
PAPER_TYPE = a4wide
|
PAPER_TYPE = a4
|
||||||
|
|
||||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
||||||
# packages that should be included in the LaTeX output.
|
# packages that should be included in the LaTeX output.
|
||||||
@@ -837,7 +1076,7 @@ USE_PDFLATEX = YES
|
|||||||
# running if errors occur, instead of asking the user for help.
|
# running if errors occur, instead of asking the user for help.
|
||||||
# This option is also used when generating formulas in HTML.
|
# This option is also used when generating formulas in HTML.
|
||||||
|
|
||||||
LATEX_BATCHMODE = NO
|
LATEX_BATCHMODE = YES
|
||||||
|
|
||||||
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
||||||
# include the index chapters (such as File Index, Compound Index, etc.)
|
# include the index chapters (such as File Index, Compound Index, etc.)
|
||||||
@@ -845,6 +1084,10 @@ LATEX_BATCHMODE = NO
|
|||||||
|
|
||||||
LATEX_HIDE_INDICES = NO
|
LATEX_HIDE_INDICES = NO
|
||||||
|
|
||||||
|
# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
|
||||||
|
|
||||||
|
LATEX_SOURCE_CODE = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the RTF output
|
# configuration options related to the RTF output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -981,8 +1224,10 @@ GENERATE_PERLMOD = NO
|
|||||||
PERLMOD_LATEX = NO
|
PERLMOD_LATEX = NO
|
||||||
|
|
||||||
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
|
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
|
||||||
# nicely formatted so it can be parsed by a human reader. This is useful
|
# nicely formatted so it can be parsed by a human reader.
|
||||||
# if you want to understand what is going on. On the other hand, if this
|
# This is useful
|
||||||
|
# if you want to understand what is going on.
|
||||||
|
# On the other hand, if this
|
||||||
# tag is set to NO the size of the Perl module output will be much smaller
|
# tag is set to NO the size of the Perl module output will be much smaller
|
||||||
# and Perl will parse it just the same.
|
# and Perl will parse it just the same.
|
||||||
|
|
||||||
@@ -1010,7 +1255,7 @@ ENABLE_PREPROCESSING = YES
|
|||||||
# compilation will be performed. Macro expansion can be done in a controlled
|
# compilation will be performed. Macro expansion can be done in a controlled
|
||||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||||
|
|
||||||
MACRO_EXPANSION = NO
|
MACRO_EXPANSION = YES
|
||||||
|
|
||||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||||
# then the macro expansion is limited to the macros specified with the
|
# then the macro expansion is limited to the macros specified with the
|
||||||
@@ -1069,9 +1314,11 @@ SKIP_FUNCTION_MACROS = YES
|
|||||||
# Optionally an initial location of the external documentation
|
# Optionally an initial location of the external documentation
|
||||||
# can be added for each tagfile. The format of a tag file without
|
# can be added for each tagfile. The format of a tag file without
|
||||||
# this location is as follows:
|
# this location is as follows:
|
||||||
# TAGFILES = file1 file2 ...
|
#
|
||||||
|
# TAGFILES = file1 file2 ...
|
||||||
# Adding location for the tag files is done as follows:
|
# Adding location for the tag files is done as follows:
|
||||||
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
#
|
||||||
|
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
||||||
# where "loc1" and "loc2" can be relative or absolute paths or
|
# where "loc1" and "loc2" can be relative or absolute paths or
|
||||||
# URLs. If a location is present for each tag, the installdox tool
|
# URLs. If a location is present for each tag, the installdox tool
|
||||||
# does not have to be run to correct the links.
|
# does not have to be run to correct the links.
|
||||||
@@ -1085,13 +1332,13 @@ TAGFILES =
|
|||||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
||||||
# a tag file that is based on the input files it reads.
|
# a tag file that is based on the input files it reads.
|
||||||
|
|
||||||
GENERATE_TAGFILE =
|
GENERATE_TAGFILE = @CMAKE_CURRENT_BINARY_DIR@/html/@PROJECT_NAME@.TAGFILE
|
||||||
|
|
||||||
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
||||||
# in the class index. If set to NO only the inherited external classes
|
# in the class index. If set to NO only the inherited external classes
|
||||||
# will be listed.
|
# will be listed.
|
||||||
|
|
||||||
ALLEXTERNALS = NO
|
ALLEXTERNALS = YES
|
||||||
|
|
||||||
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
|
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
|
||||||
# in the modules index. If set to NO, only the current project's groups will
|
# in the modules index. If set to NO, only the current project's groups will
|
||||||
@@ -1118,10 +1365,11 @@ PERL_PATH = /usr/bin/perl
|
|||||||
CLASS_DIAGRAMS = NO
|
CLASS_DIAGRAMS = NO
|
||||||
|
|
||||||
# You can define message sequence charts within doxygen comments using the \msc
|
# You can define message sequence charts within doxygen comments using the \msc
|
||||||
# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
|
# command. Doxygen will then run the mscgen tool (see
|
||||||
# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
|
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
|
||||||
# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
|
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||||
# be found in the default search path.
|
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||||
|
# default search path.
|
||||||
|
|
||||||
MSCGEN_PATH =
|
MSCGEN_PATH =
|
||||||
|
|
||||||
@@ -1136,7 +1384,30 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||||
# have no effect if this option is set to NO (the default)
|
# have no effect if this option is set to NO (the default)
|
||||||
|
|
||||||
HAVE_DOT = NO
|
HAVE_DOT = @DOXYGEN_DOT_FOUND@
|
||||||
|
|
||||||
|
# By default doxygen will write a font called FreeSans.ttf to the output
|
||||||
|
# directory and reference it in all dot files that doxygen generates. This
|
||||||
|
# font does not include all possible unicode characters however, so when you need
|
||||||
|
# these (or just want a differently looking font) you can specify the font name
|
||||||
|
# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
|
||||||
|
# which can be done by putting it in a standard location or by setting the
|
||||||
|
# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
|
||||||
|
# containing the font.
|
||||||
|
|
||||||
|
DOT_FONTNAME = FreeSans
|
||||||
|
|
||||||
|
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
|
||||||
|
# The default size is 10pt.
|
||||||
|
|
||||||
|
DOT_FONTSIZE = 10
|
||||||
|
|
||||||
|
# By default doxygen will tell dot to use the output directory to look for the
|
||||||
|
# FreeSans.ttf font (which doxygen will put there itself). If you specify a
|
||||||
|
# different font using DOT_FONTNAME you can set the path where dot
|
||||||
|
# can find it using this tag.
|
||||||
|
|
||||||
|
DOT_FONTPATH =
|
||||||
|
|
||||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||||
# will generate a graph for each documented class showing the direct and
|
# will generate a graph for each documented class showing the direct and
|
||||||
@@ -1166,14 +1437,14 @@ UML_LOOK = NO
|
|||||||
# If set to YES, the inheritance and collaboration graphs will show the
|
# If set to YES, the inheritance and collaboration graphs will show the
|
||||||
# relations between templates and their instances.
|
# relations between templates and their instances.
|
||||||
|
|
||||||
TEMPLATE_RELATIONS = NO
|
TEMPLATE_RELATIONS = YES
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
|
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
|
||||||
# tags are set to YES then doxygen will generate a graph for each documented
|
# tags are set to YES then doxygen will generate a graph for each documented
|
||||||
# file showing the direct and indirect include dependencies of the file with
|
# file showing the direct and indirect include dependencies of the file with
|
||||||
# other documented files.
|
# other documented files.
|
||||||
|
|
||||||
INCLUDE_GRAPH = YES
|
INCLUDE_GRAPH = NO
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
|
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
|
||||||
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
|
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
|
||||||
@@ -1182,19 +1453,19 @@ INCLUDE_GRAPH = YES
|
|||||||
|
|
||||||
INCLUDED_BY_GRAPH = YES
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
|
||||||
# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
|
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
|
||||||
# generate a call dependency graph for every global function or class method.
|
# doxygen will generate a call dependency graph for every global function
|
||||||
# Note that enabling this option will significantly increase the time of a run.
|
# or class method. Note that enabling this option will significantly increase
|
||||||
# So in most cases it will be better to enable call graphs for selected
|
# the time of a run. So in most cases it will be better to enable call graphs
|
||||||
# functions only using the \callgraph command.
|
# for selected functions only using the \callgraph command.
|
||||||
|
|
||||||
CALL_GRAPH = NO
|
CALL_GRAPH = NO
|
||||||
|
|
||||||
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will
|
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
|
||||||
# generate a caller dependency graph for every global function or class method.
|
# doxygen will generate a caller dependency graph for every global function
|
||||||
# Note that enabling this option will significantly increase the time of a run.
|
# or class method. Note that enabling this option will significantly increase
|
||||||
# So in most cases it will be better to enable caller graphs for selected
|
# the time of a run. So in most cases it will be better to enable caller
|
||||||
# functions only using the \callergraph command.
|
# graphs for selected functions only using the \callergraph command.
|
||||||
|
|
||||||
CALLER_GRAPH = NO
|
CALLER_GRAPH = NO
|
||||||
|
|
||||||
@@ -1219,7 +1490,7 @@ DOT_IMAGE_FORMAT = png
|
|||||||
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
||||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||||
|
|
||||||
DOT_PATH =
|
DOT_PATH = @DOXYGEN_DOT_EXECUTABLE_PATH@
|
||||||
|
|
||||||
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain dot files that are included in the documentation (see the
|
# contain dot files that are included in the documentation (see the
|
||||||
@@ -1227,19 +1498,31 @@ DOT_PATH =
|
|||||||
|
|
||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
|
|
||||||
# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
|
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
|
||||||
# nodes that will be shown in the graph. If the number of nodes in a graph
|
# nodes that will be shown in the graph. If the number of nodes in a graph
|
||||||
# becomes larger than this value, doxygen will truncate the graph, which is
|
# becomes larger than this value, doxygen will truncate the graph, which is
|
||||||
# visualized by representing a node as a red box. Note that doxygen will always
|
# visualized by representing a node as a red box. Note that doxygen if the
|
||||||
# show the root nodes and its direct children regardless of this setting.
|
# number of direct children of the root node in a graph is already larger than
|
||||||
|
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
|
||||||
|
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
|
||||||
|
|
||||||
DOT_GRAPH_MAX_NODES = 50
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
|
||||||
|
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
|
||||||
|
# graphs generated by dot. A depth value of 3 means that only nodes reachable
|
||||||
|
# from the root by following a path via at most 3 edges will be shown. Nodes
|
||||||
|
# that lay further from the root node will be omitted. Note that setting this
|
||||||
|
# option to 1 or 2 may greatly reduce the computation time needed for large
|
||||||
|
# code bases. Also note that the size of a graph can be further restricted by
|
||||||
|
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
|
||||||
|
|
||||||
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
|
||||||
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
||||||
# background. This is disabled by default, which results in a white background.
|
# background. This is disabled by default, because dot on Windows does not
|
||||||
# Warning: Depending on the platform used, enabling this option may lead to
|
# seem to support this out of the box. Warning: Depending on the platform used,
|
||||||
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
|
# enabling this option may lead to badly anti-aliased labels on the edges of
|
||||||
# read).
|
# a graph (i.e. they become hard to read).
|
||||||
|
|
||||||
DOT_TRANSPARENT = NO
|
DOT_TRANSPARENT = NO
|
||||||
|
|
||||||
@@ -1248,7 +1531,7 @@ DOT_TRANSPARENT = NO
|
|||||||
# makes dot run faster, but since only newer versions of dot (>1.8.10)
|
# makes dot run faster, but since only newer versions of dot (>1.8.10)
|
||||||
# support this, this feature is disabled by default.
|
# support this, this feature is disabled by default.
|
||||||
|
|
||||||
DOT_MULTI_TARGETS = NO
|
DOT_MULTI_TARGETS = YES
|
||||||
|
|
||||||
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
|
||||||
# generate a legend page explaining the meaning of the various boxes and
|
# generate a legend page explaining the meaning of the various boxes and
|
||||||
@@ -1261,12 +1544,3 @@ GENERATE_LEGEND = YES
|
|||||||
# the various graphs.
|
# the various graphs.
|
||||||
|
|
||||||
DOT_CLEANUP = YES
|
DOT_CLEANUP = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Configuration::additions related to the search engine
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# The SEARCHENGINE tag specifies whether or not a search engine should be
|
|
||||||
# used. If set to NO the values of all tags below this one will be ignored.
|
|
||||||
|
|
||||||
SEARCHENGINE = NO
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Doxyfile 1.5.2
|
# Doxyfile 1.6.1
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project
|
# doxygen (www.doxygen.org) for a project
|
||||||
@@ -14,31 +14,31 @@
|
|||||||
# Project related configuration options
|
# Project related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# This tag specifies the encoding used for all characters in the config file that
|
# This tag specifies the encoding used for all characters in the config file
|
||||||
# follow. The default is UTF-8 which is also the encoding used for all text before
|
# that follow. The default is UTF-8 which is also the encoding used for all
|
||||||
# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
|
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
||||||
# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
|
# iconv built into libc) for the transcoding. See
|
||||||
# possible encodings.
|
# http://www.gnu.org/software/libiconv for the list of possible encodings.
|
||||||
|
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
|
||||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
||||||
# by quotes) that should identify the project.
|
# by quotes) that should identify the project.
|
||||||
|
|
||||||
PROJECT_NAME = libssh
|
PROJECT_NAME = @APPLICATION_NAME@
|
||||||
|
|
||||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.2.1-svn
|
PROJECT_NUMBER = @APPLICATION_VERSION@
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
# If a relative path is entered, it will be relative to the location
|
# If a relative path is entered, it will be relative to the location
|
||||||
# where doxygen was started. If left blank the current directory will be used.
|
# where doxygen was started. If left blank the current directory will be used.
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = doxygen/
|
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@
|
||||||
|
|
||||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||||
@@ -54,10 +54,11 @@ CREATE_SUBDIRS = NO
|
|||||||
# information to generate all constant output in the proper language.
|
# information to generate all constant output in the proper language.
|
||||||
# The default language is English, other supported languages are:
|
# The default language is English, other supported languages are:
|
||||||
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
|
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
|
||||||
# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
|
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
|
||||||
# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
|
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
|
||||||
# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
|
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
|
||||||
# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
|
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
|
||||||
|
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
|
||||||
|
|
||||||
OUTPUT_LANGUAGE = English
|
OUTPUT_LANGUAGE = English
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ FULL_PATH_NAMES = YES
|
|||||||
# If left blank the directory from which doxygen is run is used as the
|
# If left blank the directory from which doxygen is run is used as the
|
||||||
# path to strip.
|
# path to strip.
|
||||||
|
|
||||||
STRIP_FROM_PATH =
|
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@
|
||||||
|
|
||||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
||||||
# the path mentioned in the documentation of a class, which tells
|
# the path mentioned in the documentation of a class, which tells
|
||||||
@@ -132,7 +133,7 @@ STRIP_FROM_PATH =
|
|||||||
# definition is used. Otherwise one should specify the include paths that
|
# definition is used. Otherwise one should specify the include paths that
|
||||||
# are normally passed to the compiler using the -I flag.
|
# are normally passed to the compiler using the -I flag.
|
||||||
|
|
||||||
STRIP_FROM_INC_PATH =
|
STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@
|
||||||
|
|
||||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
|
||||||
# (but less readable) file names. This can be useful is your file systems
|
# (but less readable) file names. This can be useful is your file systems
|
||||||
@@ -143,10 +144,18 @@ SHORT_NAMES = NO
|
|||||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
||||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||||
# comment as the brief description. If set to NO, the JavaDoc
|
# comment as the brief description. If set to NO, the JavaDoc
|
||||||
# comments will behave just like the Qt-style comments (thus requiring an
|
# comments will behave just like regular Qt-style comments
|
||||||
# explicit @brief command for a brief description.
|
# (thus requiring an explicit @brief command for a brief description.)
|
||||||
|
|
||||||
JAVADOC_AUTOBRIEF = NO
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
|
||||||
|
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
|
||||||
|
# interpret the first line (until the first dot) of a Qt-style
|
||||||
|
# comment as the brief description. If set to NO, the comments
|
||||||
|
# will behave just like regular Qt-style comments (thus requiring
|
||||||
|
# an explicit \brief command for a brief description.)
|
||||||
|
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
|
||||||
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
||||||
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
||||||
@@ -156,13 +165,6 @@ JAVADOC_AUTOBRIEF = NO
|
|||||||
|
|
||||||
MULTILINE_CPP_IS_BRIEF = NO
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
|
||||||
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
|
|
||||||
# will output the detailed description near the top, like JavaDoc.
|
|
||||||
# If set to NO, the detailed description appears after the member
|
|
||||||
# documentation.
|
|
||||||
|
|
||||||
DETAILS_AT_TOP = NO
|
|
||||||
|
|
||||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||||
# member inherits the documentation from any documented member that it
|
# member inherits the documentation from any documented member that it
|
||||||
# re-implements.
|
# re-implements.
|
||||||
@@ -178,7 +180,7 @@ SEPARATE_MEMBER_PAGES = NO
|
|||||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
||||||
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
||||||
|
|
||||||
TAB_SIZE = 8
|
TAB_SIZE = 2
|
||||||
|
|
||||||
# This tag can be used to specify a number of aliases that acts
|
# This tag can be used to specify a number of aliases that acts
|
||||||
# as commands in the documentation. An alias has the form "name=value".
|
# as commands in the documentation. An alias has the form "name=value".
|
||||||
@@ -197,14 +199,37 @@ ALIASES =
|
|||||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
|
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
|
||||||
# sources only. Doxygen will then generate output that is more tailored for Java.
|
# sources only. Doxygen will then generate output that is more tailored for
|
||||||
# For instance, namespaces will be presented as packages, qualified scopes
|
# Java. For instance, namespaces will be presented as packages, qualified
|
||||||
# will look different, etc.
|
# scopes will look different, etc.
|
||||||
|
|
||||||
OPTIMIZE_OUTPUT_JAVA = NO
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
|
||||||
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
|
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
|
||||||
# include (a tag file for) the STL sources as input, then you should
|
# sources only. Doxygen will then generate output that is more tailored for
|
||||||
|
# Fortran.
|
||||||
|
|
||||||
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
|
||||||
|
# sources. Doxygen will then generate output that is tailored for
|
||||||
|
# VHDL.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
|
||||||
|
# Doxygen selects the parser to use depending on the extension of the files it parses.
|
||||||
|
# With this tag you can assign which parser to use for a given extension.
|
||||||
|
# Doxygen has a built-in mapping, but you can override or extend it using this tag.
|
||||||
|
# The format is ext=language, where ext is a file extension, and language is one of
|
||||||
|
# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
|
||||||
|
# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
|
||||||
|
# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||||
|
# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
|
||||||
|
|
||||||
|
EXTENSION_MAPPING =
|
||||||
|
|
||||||
|
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
|
||||||
|
# to include (a tag file for) the STL sources as input, then you should
|
||||||
# set this tag to YES in order to let doxygen match functions declarations and
|
# set this tag to YES in order to let doxygen match functions declarations and
|
||||||
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
|
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
|
||||||
# func(std::string) {}). This also make the inheritance and collaboration
|
# func(std::string) {}). This also make the inheritance and collaboration
|
||||||
@@ -217,6 +242,21 @@ BUILTIN_STL_SUPPORT = NO
|
|||||||
|
|
||||||
CPP_CLI_SUPPORT = NO
|
CPP_CLI_SUPPORT = NO
|
||||||
|
|
||||||
|
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
|
||||||
|
# Doxygen will parse them like normal C++ but will assume all classes use public
|
||||||
|
# instead of private inheritance when no explicit protection keyword is present.
|
||||||
|
|
||||||
|
SIP_SUPPORT = NO
|
||||||
|
|
||||||
|
# For Microsoft's IDL there are propget and propput attributes to indicate getter
|
||||||
|
# and setter methods for a property. Setting this option to YES (the default)
|
||||||
|
# will make doxygen to replace the get and set methods by a property in the
|
||||||
|
# documentation. This will only work if the methods are indeed getting or
|
||||||
|
# setting a simple type. If this is not the case, or you want to show the
|
||||||
|
# methods anyway, you should set this option to NO.
|
||||||
|
|
||||||
|
IDL_PROPERTY_SUPPORT = YES
|
||||||
|
|
||||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||||
# tag is set to YES, then doxygen will reuse the documentation of the first
|
# tag is set to YES, then doxygen will reuse the documentation of the first
|
||||||
# member in the group (if any) for the other members of the group. By default
|
# member in the group (if any) for the other members of the group. By default
|
||||||
@@ -232,6 +272,32 @@ DISTRIBUTE_GROUP_DOC = NO
|
|||||||
|
|
||||||
SUBGROUPING = YES
|
SUBGROUPING = YES
|
||||||
|
|
||||||
|
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
|
||||||
|
# is documented as struct, union, or enum with the name of the typedef. So
|
||||||
|
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
|
||||||
|
# with name TypeT. When disabled the typedef will appear as a member of a file,
|
||||||
|
# namespace, or class. And the struct will be named TypeS. This can typically
|
||||||
|
# be useful for C code in case the coding convention dictates that all compound
|
||||||
|
# types are typedef'ed and only the typedef is referenced, never the tag name.
|
||||||
|
|
||||||
|
TYPEDEF_HIDES_STRUCT = YES
|
||||||
|
|
||||||
|
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
|
||||||
|
# determine which symbols to keep in memory and which to flush to disk.
|
||||||
|
# When the cache is full, less often used symbols will be written to disk.
|
||||||
|
# For small to medium size projects (<1000 input files) the default value is
|
||||||
|
# probably good enough. For larger projects a too small cache size can cause
|
||||||
|
# doxygen to be busy swapping symbols to and from disk most of the time
|
||||||
|
# causing a significant performance penality.
|
||||||
|
# If the system has enough physical memory increasing the cache will improve the
|
||||||
|
# performance by keeping more symbols in memory. Note that the value works on
|
||||||
|
# a logarithmic scale so increasing the size by one will rougly double the
|
||||||
|
# memory usage. The cache size is given by this formula:
|
||||||
|
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
|
||||||
|
# corresponding to a cache size of 2^16 = 65536 symbols
|
||||||
|
|
||||||
|
SYMBOL_CACHE_SIZE = 0
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Build related configuration options
|
# Build related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -241,7 +307,7 @@ SUBGROUPING = YES
|
|||||||
# Private class members and static file members will be hidden unless
|
# Private class members and static file members will be hidden unless
|
||||||
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
|
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
|
||||||
|
|
||||||
EXTRACT_ALL = YES
|
EXTRACT_ALL = NO
|
||||||
|
|
||||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
||||||
# will be included in the documentation.
|
# will be included in the documentation.
|
||||||
@@ -266,6 +332,14 @@ EXTRACT_LOCAL_CLASSES = NO
|
|||||||
|
|
||||||
EXTRACT_LOCAL_METHODS = NO
|
EXTRACT_LOCAL_METHODS = NO
|
||||||
|
|
||||||
|
# If this flag is set to YES, the members of anonymous namespaces will be
|
||||||
|
# extracted and appear in the documentation as a namespace called
|
||||||
|
# 'anonymous_namespace{file}', where file will be replaced with the base
|
||||||
|
# name of the file that contains the anonymous namespace. By default
|
||||||
|
# anonymous namespace are hidden.
|
||||||
|
|
||||||
|
EXTRACT_ANON_NSPACES = NO
|
||||||
|
|
||||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||||
# undocumented members of documented classes, files or namespaces.
|
# undocumented members of documented classes, files or namespaces.
|
||||||
# If set to NO (the default) these members will be included in the
|
# If set to NO (the default) these members will be included in the
|
||||||
@@ -300,7 +374,7 @@ HIDE_IN_BODY_DOCS = NO
|
|||||||
# to NO (the default) then the documentation will be excluded.
|
# to NO (the default) then the documentation will be excluded.
|
||||||
# Set it to YES to include the internal documentation.
|
# Set it to YES to include the internal documentation.
|
||||||
|
|
||||||
INTERNAL_DOCS = YES
|
INTERNAL_DOCS = @CMAKE_INTERNAL_DOC@
|
||||||
|
|
||||||
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
|
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
|
||||||
# file names in lower-case letters. If set to YES upper-case letters are also
|
# file names in lower-case letters. If set to YES upper-case letters are also
|
||||||
@@ -341,6 +415,16 @@ SORT_MEMBER_DOCS = YES
|
|||||||
|
|
||||||
SORT_BRIEF_DOCS = YES
|
SORT_BRIEF_DOCS = YES
|
||||||
|
|
||||||
|
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
|
||||||
|
|
||||||
|
SORT_MEMBERS_CTORS_1ST = NO
|
||||||
|
|
||||||
|
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
|
||||||
|
# hierarchy of group names into alphabetical order. If set to NO (the default)
|
||||||
|
# the group names will appear in their defined order.
|
||||||
|
|
||||||
|
SORT_GROUP_NAMES = NO
|
||||||
|
|
||||||
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
|
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
|
||||||
# sorted by fully-qualified names, including namespaces. If set to
|
# sorted by fully-qualified names, including namespaces. If set to
|
||||||
# NO (the default), the class list will be sorted only by class name,
|
# NO (the default), the class list will be sorted only by class name,
|
||||||
@@ -402,9 +486,22 @@ SHOW_USED_FILES = YES
|
|||||||
|
|
||||||
SHOW_DIRECTORIES = NO
|
SHOW_DIRECTORIES = NO
|
||||||
|
|
||||||
|
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
|
||||||
|
# This will remove the Files entry from the Quick Index and from the
|
||||||
|
# Folder Tree View (if specified). The default is YES.
|
||||||
|
|
||||||
|
SHOW_FILES = YES
|
||||||
|
|
||||||
|
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
|
||||||
|
# Namespaces page.
|
||||||
|
# This will remove the Namespaces entry from the Quick Index
|
||||||
|
# and from the Folder Tree View (if specified). The default is YES.
|
||||||
|
|
||||||
|
SHOW_NAMESPACES = YES
|
||||||
|
|
||||||
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
||||||
# doxygen should invoke to get the current version for each file (typically from the
|
# doxygen should invoke to get the current version for each file (typically from
|
||||||
# version control system). Doxygen will invoke the program by executing (via
|
# the version control system). Doxygen will invoke the program by executing (via
|
||||||
# popen()) the command <command> <input-file>, where <command> is the value of
|
# popen()) the command <command> <input-file>, where <command> is the value of
|
||||||
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
|
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
|
||||||
# provided by doxygen. Whatever the program writes to standard output
|
# provided by doxygen. Whatever the program writes to standard output
|
||||||
@@ -412,6 +509,15 @@ SHOW_DIRECTORIES = NO
|
|||||||
|
|
||||||
FILE_VERSION_FILTER =
|
FILE_VERSION_FILTER =
|
||||||
|
|
||||||
|
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
|
||||||
|
# doxygen. The layout file controls the global structure of the generated output files
|
||||||
|
# in an output format independent way. The create the layout file that represents
|
||||||
|
# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
|
||||||
|
# file name after the option, if omitted DoxygenLayout.xml will be used as the name
|
||||||
|
# of the layout file.
|
||||||
|
|
||||||
|
LAYOUT_FILE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to warning and progress messages
|
# configuration options related to warning and progress messages
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -472,13 +578,15 @@ WARN_LOGFILE =
|
|||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# with spaces.
|
||||||
|
|
||||||
INPUT = include/ \
|
INPUT = @CMAKE_SOURCE_DIR@/include \
|
||||||
libssh/
|
@CMAKE_SOURCE_DIR@/libssh \
|
||||||
|
@CMAKE_SOURCE_DIR@/doc
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files that
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||||
# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
|
# also the default input encoding. Doxygen uses libiconv (or the iconv built
|
||||||
# See http://www.gnu.org/software/libiconv for the list of possible encodings.
|
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
|
||||||
|
# the list of possible encodings.
|
||||||
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
|
|
||||||
@@ -487,12 +595,14 @@ INPUT_ENCODING = UTF-8
|
|||||||
# and *.h) to filter out the source-files in the directories. If left
|
# and *.h) to filter out the source-files in the directories. If left
|
||||||
# blank the following patterns are tested:
|
# blank the following patterns are tested:
|
||||||
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
|
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
|
||||||
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
|
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
|
||||||
|
|
||||||
FILE_PATTERNS = *.c \
|
FILE_PATTERNS = *.cpp \
|
||||||
*.cc \
|
*.cc \
|
||||||
*.cpp \
|
*.c \
|
||||||
*.h \
|
*.h \
|
||||||
|
*.hh \
|
||||||
|
*.hpp \
|
||||||
*.dox
|
*.dox
|
||||||
|
|
||||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
||||||
@@ -519,12 +629,16 @@ EXCLUDE_SYMLINKS = NO
|
|||||||
# against the file with absolute path, so to exclude all test directories
|
# against the file with absolute path, so to exclude all test directories
|
||||||
# for example use the pattern */test/*
|
# for example use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_PATTERNS =
|
EXCLUDE_PATTERNS = */.git/* \
|
||||||
|
*/.svn/* \
|
||||||
|
*/cmake/* \
|
||||||
|
*/build/*
|
||||||
|
|
||||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||||
# (namespaces, classes, functions, etc.) that should be excluded from the output.
|
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||||
# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
|
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||||
# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
|
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||||
|
# AClass::ANamespace, ANamespace::*Test
|
||||||
|
|
||||||
EXCLUDE_SYMBOLS =
|
EXCLUDE_SYMBOLS =
|
||||||
|
|
||||||
@@ -532,21 +646,27 @@ EXCLUDE_SYMBOLS =
|
|||||||
# directories that contain example code fragments that are included (see
|
# directories that contain example code fragments that are included (see
|
||||||
# the \include command).
|
# the \include command).
|
||||||
|
|
||||||
EXAMPLE_PATH =
|
EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/examples
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||||
# and *.h) to filter out the source-files in the directories. If left
|
# and *.h) to filter out the source-files in the directories. If left
|
||||||
# blank all files are included.
|
# blank all files are included.
|
||||||
|
|
||||||
EXAMPLE_PATTERNS = *
|
EXAMPLE_PATTERNS = *.c \
|
||||||
|
*.h \
|
||||||
|
INSTALL \
|
||||||
|
DEPENDENCIES \
|
||||||
|
CHANGELOG \
|
||||||
|
LICENSE \
|
||||||
|
LGPL
|
||||||
|
|
||||||
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
||||||
# searched for input files to be used with the \include or \dontinclude
|
# searched for input files to be used with the \include or \dontinclude
|
||||||
# commands irrespective of the value of the RECURSIVE tag.
|
# commands irrespective of the value of the RECURSIVE tag.
|
||||||
# Possible values are YES and NO. If left blank NO is used.
|
# Possible values are YES and NO. If left blank NO is used.
|
||||||
|
|
||||||
EXAMPLE_RECURSIVE = NO
|
EXAMPLE_RECURSIVE = YES
|
||||||
|
|
||||||
# The IMAGE_PATH tag can be used to specify one or more files or
|
# The IMAGE_PATH tag can be used to specify one or more files or
|
||||||
# directories that contain image that are included in the documentation (see
|
# directories that contain image that are included in the documentation (see
|
||||||
@@ -559,14 +679,17 @@ IMAGE_PATH =
|
|||||||
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
||||||
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
||||||
# input file. Doxygen will then use the output that the filter program writes
|
# input file. Doxygen will then use the output that the filter program writes
|
||||||
# to standard output. If FILTER_PATTERNS is specified, this tag will be
|
# to standard output.
|
||||||
|
# If FILTER_PATTERNS is specified, this tag will be
|
||||||
# ignored.
|
# ignored.
|
||||||
|
|
||||||
INPUT_FILTER =
|
INPUT_FILTER =
|
||||||
|
|
||||||
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
||||||
# basis. Doxygen will compare the file name with each pattern and apply the
|
# basis.
|
||||||
# filter if there is a match. The filters are a list of the form:
|
# Doxygen will compare the file name with each pattern and apply the
|
||||||
|
# filter if there is a match.
|
||||||
|
# The filters are a list of the form:
|
||||||
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
|
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
|
||||||
# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
|
# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
|
||||||
# is applied to all files.
|
# is applied to all files.
|
||||||
@@ -588,7 +711,7 @@ FILTER_SOURCE_FILES = NO
|
|||||||
# Note: To get rid of all source code in the generated output, make sure also
|
# Note: To get rid of all source code in the generated output, make sure also
|
||||||
# VERBATIM_HEADERS is set to NO.
|
# VERBATIM_HEADERS is set to NO.
|
||||||
|
|
||||||
SOURCE_BROWSER = YES
|
SOURCE_BROWSER = NO
|
||||||
|
|
||||||
# Setting the INLINE_SOURCES tag to YES will include the body
|
# Setting the INLINE_SOURCES tag to YES will include the body
|
||||||
# of functions and classes directly in the documentation.
|
# of functions and classes directly in the documentation.
|
||||||
@@ -601,13 +724,13 @@ INLINE_SOURCES = NO
|
|||||||
|
|
||||||
STRIP_CODE_COMMENTS = YES
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
|
||||||
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
|
# If the REFERENCED_BY_RELATION tag is set to YES
|
||||||
# then for each documented function all documented
|
# then for each documented function all documented
|
||||||
# functions referencing it will be listed.
|
# functions referencing it will be listed.
|
||||||
|
|
||||||
REFERENCED_BY_RELATION = YES
|
REFERENCED_BY_RELATION = YES
|
||||||
|
|
||||||
# If the REFERENCES_RELATION tag is set to YES (the default)
|
# If the REFERENCES_RELATION tag is set to YES
|
||||||
# then for each documented function all documented entities
|
# then for each documented function all documented entities
|
||||||
# called/used by that function will be listed.
|
# called/used by that function will be listed.
|
||||||
|
|
||||||
@@ -616,7 +739,8 @@ REFERENCES_RELATION = YES
|
|||||||
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
|
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
|
||||||
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
|
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
|
||||||
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
|
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
|
||||||
# link to the source code. Otherwise they will link to the documentstion.
|
# link to the source code.
|
||||||
|
# Otherwise they will link to the documentation.
|
||||||
|
|
||||||
REFERENCES_LINK_SOURCE = YES
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
|
||||||
@@ -648,7 +772,7 @@ ALPHABETICAL_INDEX = YES
|
|||||||
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
||||||
# in which this list will be split (can be a number in the range [1..20])
|
# in which this list will be split (can be a number in the range [1..20])
|
||||||
|
|
||||||
COLS_IN_ALPHA_INDEX = 5
|
COLS_IN_ALPHA_INDEX = 2
|
||||||
|
|
||||||
# In case all classes in a project start with a common prefix, all
|
# In case all classes in a project start with a common prefix, all
|
||||||
# classes will be put under the same header in the alphabetical index.
|
# classes will be put under the same header in the alphabetical index.
|
||||||
@@ -670,7 +794,7 @@ GENERATE_HTML = YES
|
|||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||||
# put in front of it. If left blank `html' will be used as the default path.
|
# put in front of it. If left blank `html' will be used as the default path.
|
||||||
|
|
||||||
HTML_OUTPUT = html
|
HTML_OUTPUT = trac
|
||||||
|
|
||||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
|
||||||
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
|
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
|
||||||
@@ -682,13 +806,18 @@ HTML_FILE_EXTENSION = .html
|
|||||||
# each generated HTML page. If it is left blank doxygen will generate a
|
# each generated HTML page. If it is left blank doxygen will generate a
|
||||||
# standard header.
|
# standard header.
|
||||||
|
|
||||||
HTML_HEADER =
|
HTML_HEADER = @CMAKE_CURRENT_SOURCE_DIR@/TracHeader.html
|
||||||
|
|
||||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
||||||
# each generated HTML page. If it is left blank doxygen will generate a
|
# each generated HTML page. If it is left blank doxygen will generate a
|
||||||
# standard footer.
|
# standard footer.
|
||||||
|
|
||||||
HTML_FOOTER =
|
HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/TracFooter.html
|
||||||
|
|
||||||
|
# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
|
||||||
|
# documentation will contain the timesstamp.
|
||||||
|
|
||||||
|
HTML_TIMESTAMP = NO
|
||||||
|
|
||||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
||||||
# style sheet that is used by each HTML page. It can be used to
|
# style sheet that is used by each HTML page. It can be used to
|
||||||
@@ -705,9 +834,43 @@ HTML_STYLESHEET =
|
|||||||
|
|
||||||
HTML_ALIGN_MEMBERS = YES
|
HTML_ALIGN_MEMBERS = YES
|
||||||
|
|
||||||
|
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||||
|
# documentation will contain sections that can be hidden and shown after the
|
||||||
|
# page has loaded. For this to work a browser that supports
|
||||||
|
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
|
||||||
|
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
|
||||||
|
|
||||||
|
HTML_DYNAMIC_SECTIONS = NO
|
||||||
|
|
||||||
|
# If the GENERATE_DOCSET tag is set to YES, additional index files
|
||||||
|
# will be generated that can be used as input for Apple's Xcode 3
|
||||||
|
# integrated development environment, introduced with OSX 10.5 (Leopard).
|
||||||
|
# To create a documentation set, doxygen will generate a Makefile in the
|
||||||
|
# HTML output directory. Running make will produce the docset in that
|
||||||
|
# directory and running "make install" will install the docset in
|
||||||
|
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
|
||||||
|
# it at startup.
|
||||||
|
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
|
||||||
|
|
||||||
|
GENERATE_DOCSET = NO
|
||||||
|
|
||||||
|
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
|
||||||
|
# feed. A documentation feed provides an umbrella under which multiple
|
||||||
|
# documentation sets from a single provider (such as a company or product suite)
|
||||||
|
# can be grouped.
|
||||||
|
|
||||||
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
|
||||||
|
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
|
||||||
|
# should uniquely identify the documentation set bundle. This should be a
|
||||||
|
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
|
||||||
|
# will append .docset to the name.
|
||||||
|
|
||||||
|
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||||
# will be generated that can be used as input for tools like the
|
# will be generated that can be used as input for tools like the
|
||||||
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
|
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
|
||||||
# of the generated HTML documentation.
|
# of the generated HTML documentation.
|
||||||
|
|
||||||
GENERATE_HTMLHELP = NO
|
GENERATE_HTMLHELP = NO
|
||||||
@@ -732,6 +895,12 @@ HHC_LOCATION =
|
|||||||
|
|
||||||
GENERATE_CHI = NO
|
GENERATE_CHI = NO
|
||||||
|
|
||||||
|
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
|
||||||
|
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
|
||||||
|
# content.
|
||||||
|
|
||||||
|
CHM_INDEX_ENCODING =
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
|
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
|
||||||
# controls whether a binary table of contents is generated (YES) or a
|
# controls whether a binary table of contents is generated (YES) or a
|
||||||
# normal table of contents (NO) in the .chm file.
|
# normal table of contents (NO) in the .chm file.
|
||||||
@@ -743,6 +912,55 @@ BINARY_TOC = NO
|
|||||||
|
|
||||||
TOC_EXPAND = NO
|
TOC_EXPAND = NO
|
||||||
|
|
||||||
|
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
|
||||||
|
# are set, an additional index file will be generated that can be used as input for
|
||||||
|
# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
|
||||||
|
# HTML documentation.
|
||||||
|
|
||||||
|
GENERATE_QHP = NO
|
||||||
|
|
||||||
|
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
|
||||||
|
# be used to specify the file name of the resulting .qch file.
|
||||||
|
# The path specified is relative to the HTML output folder.
|
||||||
|
|
||||||
|
QCH_FILE =
|
||||||
|
|
||||||
|
# The QHP_NAMESPACE tag specifies the namespace to use when generating
|
||||||
|
# Qt Help Project output. For more information please see
|
||||||
|
# http://doc.trolltech.com/qthelpproject.html#namespace
|
||||||
|
|
||||||
|
QHP_NAMESPACE =
|
||||||
|
|
||||||
|
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
|
||||||
|
# Qt Help Project output. For more information please see
|
||||||
|
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
|
||||||
|
|
||||||
|
QHP_VIRTUAL_FOLDER = doc
|
||||||
|
|
||||||
|
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
|
||||||
|
# For more information please see
|
||||||
|
# http://doc.trolltech.com/qthelpproject.html#custom-filters
|
||||||
|
|
||||||
|
QHP_CUST_FILTER_NAME =
|
||||||
|
|
||||||
|
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
|
||||||
|
# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
|
||||||
|
|
||||||
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
|
||||||
|
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
|
||||||
|
# filter section matches.
|
||||||
|
# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
|
||||||
|
|
||||||
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
|
||||||
|
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
|
||||||
|
# be used to specify the location of Qt's qhelpgenerator.
|
||||||
|
# If non-empty doxygen will try to run qhelpgenerator on the generated
|
||||||
|
# .qhp file.
|
||||||
|
|
||||||
|
QHG_LOCATION =
|
||||||
|
|
||||||
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
||||||
# top of each HTML page. The value NO (the default) enables the index and
|
# top of each HTML page. The value NO (the default) enables the index and
|
||||||
# the value YES disables it.
|
# the value YES disables it.
|
||||||
@@ -754,21 +972,42 @@ DISABLE_INDEX = NO
|
|||||||
|
|
||||||
ENUM_VALUES_PER_LINE = 4
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
|
||||||
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
|
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
|
||||||
# generated containing a tree-like index structure (just like the one that
|
# structure should be generated to display hierarchical information.
|
||||||
|
# If the tag value is set to YES, a side panel will be generated
|
||||||
|
# containing a tree-like index structure (just like the one that
|
||||||
# is generated for HTML Help). For this to work a browser that supports
|
# is generated for HTML Help). For this to work a browser that supports
|
||||||
# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
|
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
|
||||||
# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
|
# Windows users are probably better off using the HTML help feature.
|
||||||
# probably better off using the HTML help feature.
|
|
||||||
|
|
||||||
GENERATE_TREEVIEW = NO
|
GENERATE_TREEVIEW = NO
|
||||||
|
|
||||||
|
# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
|
||||||
|
# and Class Hierarchy pages using a tree view instead of an ordered list.
|
||||||
|
|
||||||
|
USE_INLINE_TREES = NO
|
||||||
|
|
||||||
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
|
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
|
||||||
# used to set the initial width (in pixels) of the frame in which the tree
|
# used to set the initial width (in pixels) of the frame in which the tree
|
||||||
# is shown.
|
# is shown.
|
||||||
|
|
||||||
TREEVIEW_WIDTH = 250
|
TREEVIEW_WIDTH = 250
|
||||||
|
|
||||||
|
# Use this tag to change the font size of Latex formulas included
|
||||||
|
# as images in the HTML documentation. The default is 10. Note that
|
||||||
|
# when you change the font size after a successful doxygen run you need
|
||||||
|
# to manually remove any form_*.png images from the HTML output directory
|
||||||
|
# to force them to be regenerated.
|
||||||
|
|
||||||
|
FORMULA_FONTSIZE = 10
|
||||||
|
|
||||||
|
# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
|
||||||
|
# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
|
||||||
|
# there is already a search function so this one should typically
|
||||||
|
# be disabled.
|
||||||
|
|
||||||
|
SEARCHENGINE = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the LaTeX output
|
# configuration options related to the LaTeX output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -776,7 +1015,7 @@ TREEVIEW_WIDTH = 250
|
|||||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||||
# generate Latex output.
|
# generate Latex output.
|
||||||
|
|
||||||
GENERATE_LATEX = YES
|
GENERATE_LATEX = NO
|
||||||
|
|
||||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||||
@@ -787,13 +1026,13 @@ LATEX_OUTPUT = latex
|
|||||||
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
# invoked. If left blank `latex' will be used as the default command name.
|
# invoked. If left blank `latex' will be used as the default command name.
|
||||||
|
|
||||||
LATEX_CMD_NAME = latex
|
LATEX_CMD_NAME =
|
||||||
|
|
||||||
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
|
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
|
||||||
# generate index for LaTeX. If left blank `makeindex' will be used as the
|
# generate index for LaTeX. If left blank `makeindex' will be used as the
|
||||||
# default command name.
|
# default command name.
|
||||||
|
|
||||||
MAKEINDEX_CMD_NAME = makeindex
|
MAKEINDEX_CMD_NAME =
|
||||||
|
|
||||||
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
||||||
# LaTeX documents. This may be useful for small projects and may help to
|
# LaTeX documents. This may be useful for small projects and may help to
|
||||||
@@ -805,7 +1044,7 @@ COMPACT_LATEX = NO
|
|||||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||||
# executive. If left blank a4wide will be used.
|
# executive. If left blank a4wide will be used.
|
||||||
|
|
||||||
PAPER_TYPE = a4wide
|
PAPER_TYPE = a4
|
||||||
|
|
||||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
||||||
# packages that should be included in the LaTeX output.
|
# packages that should be included in the LaTeX output.
|
||||||
@@ -837,7 +1076,7 @@ USE_PDFLATEX = YES
|
|||||||
# running if errors occur, instead of asking the user for help.
|
# running if errors occur, instead of asking the user for help.
|
||||||
# This option is also used when generating formulas in HTML.
|
# This option is also used when generating formulas in HTML.
|
||||||
|
|
||||||
LATEX_BATCHMODE = NO
|
LATEX_BATCHMODE = YES
|
||||||
|
|
||||||
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
||||||
# include the index chapters (such as File Index, Compound Index, etc.)
|
# include the index chapters (such as File Index, Compound Index, etc.)
|
||||||
@@ -845,6 +1084,10 @@ LATEX_BATCHMODE = NO
|
|||||||
|
|
||||||
LATEX_HIDE_INDICES = NO
|
LATEX_HIDE_INDICES = NO
|
||||||
|
|
||||||
|
# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
|
||||||
|
|
||||||
|
LATEX_SOURCE_CODE = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the RTF output
|
# configuration options related to the RTF output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -894,7 +1137,7 @@ RTF_EXTENSIONS_FILE =
|
|||||||
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
|
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
|
||||||
# generate man pages
|
# generate man pages
|
||||||
|
|
||||||
GENERATE_MAN = NO
|
GENERATE_MAN = YES
|
||||||
|
|
||||||
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
|
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||||
@@ -981,8 +1224,10 @@ GENERATE_PERLMOD = NO
|
|||||||
PERLMOD_LATEX = NO
|
PERLMOD_LATEX = NO
|
||||||
|
|
||||||
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
|
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
|
||||||
# nicely formatted so it can be parsed by a human reader. This is useful
|
# nicely formatted so it can be parsed by a human reader.
|
||||||
# if you want to understand what is going on. On the other hand, if this
|
# This is useful
|
||||||
|
# if you want to understand what is going on.
|
||||||
|
# On the other hand, if this
|
||||||
# tag is set to NO the size of the Perl module output will be much smaller
|
# tag is set to NO the size of the Perl module output will be much smaller
|
||||||
# and Perl will parse it just the same.
|
# and Perl will parse it just the same.
|
||||||
|
|
||||||
@@ -1010,7 +1255,7 @@ ENABLE_PREPROCESSING = YES
|
|||||||
# compilation will be performed. Macro expansion can be done in a controlled
|
# compilation will be performed. Macro expansion can be done in a controlled
|
||||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||||
|
|
||||||
MACRO_EXPANSION = NO
|
MACRO_EXPANSION = YES
|
||||||
|
|
||||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||||
# then the macro expansion is limited to the macros specified with the
|
# then the macro expansion is limited to the macros specified with the
|
||||||
@@ -1069,9 +1314,11 @@ SKIP_FUNCTION_MACROS = YES
|
|||||||
# Optionally an initial location of the external documentation
|
# Optionally an initial location of the external documentation
|
||||||
# can be added for each tagfile. The format of a tag file without
|
# can be added for each tagfile. The format of a tag file without
|
||||||
# this location is as follows:
|
# this location is as follows:
|
||||||
# TAGFILES = file1 file2 ...
|
#
|
||||||
|
# TAGFILES = file1 file2 ...
|
||||||
# Adding location for the tag files is done as follows:
|
# Adding location for the tag files is done as follows:
|
||||||
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
#
|
||||||
|
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
||||||
# where "loc1" and "loc2" can be relative or absolute paths or
|
# where "loc1" and "loc2" can be relative or absolute paths or
|
||||||
# URLs. If a location is present for each tag, the installdox tool
|
# URLs. If a location is present for each tag, the installdox tool
|
||||||
# does not have to be run to correct the links.
|
# does not have to be run to correct the links.
|
||||||
@@ -1085,13 +1332,13 @@ TAGFILES =
|
|||||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
||||||
# a tag file that is based on the input files it reads.
|
# a tag file that is based on the input files it reads.
|
||||||
|
|
||||||
GENERATE_TAGFILE =
|
GENERATE_TAGFILE = @CMAKE_CURRENT_BINARY_DIR@/trac/@PROJECT_NAME@.TAGFILE
|
||||||
|
|
||||||
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
||||||
# in the class index. If set to NO only the inherited external classes
|
# in the class index. If set to NO only the inherited external classes
|
||||||
# will be listed.
|
# will be listed.
|
||||||
|
|
||||||
ALLEXTERNALS = NO
|
ALLEXTERNALS = YES
|
||||||
|
|
||||||
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
|
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
|
||||||
# in the modules index. If set to NO, only the current project's groups will
|
# in the modules index. If set to NO, only the current project's groups will
|
||||||
@@ -1118,10 +1365,11 @@ PERL_PATH = /usr/bin/perl
|
|||||||
CLASS_DIAGRAMS = NO
|
CLASS_DIAGRAMS = NO
|
||||||
|
|
||||||
# You can define message sequence charts within doxygen comments using the \msc
|
# You can define message sequence charts within doxygen comments using the \msc
|
||||||
# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
|
# command. Doxygen will then run the mscgen tool (see
|
||||||
# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
|
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
|
||||||
# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
|
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||||
# be found in the default search path.
|
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||||
|
# default search path.
|
||||||
|
|
||||||
MSCGEN_PATH =
|
MSCGEN_PATH =
|
||||||
|
|
||||||
@@ -1136,7 +1384,30 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||||
# have no effect if this option is set to NO (the default)
|
# have no effect if this option is set to NO (the default)
|
||||||
|
|
||||||
HAVE_DOT = NO
|
HAVE_DOT = @DOXYGEN_DOT_FOUND@
|
||||||
|
|
||||||
|
# By default doxygen will write a font called FreeSans.ttf to the output
|
||||||
|
# directory and reference it in all dot files that doxygen generates. This
|
||||||
|
# font does not include all possible unicode characters however, so when you need
|
||||||
|
# these (or just want a differently looking font) you can specify the font name
|
||||||
|
# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
|
||||||
|
# which can be done by putting it in a standard location or by setting the
|
||||||
|
# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
|
||||||
|
# containing the font.
|
||||||
|
|
||||||
|
DOT_FONTNAME = FreeSans
|
||||||
|
|
||||||
|
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
|
||||||
|
# The default size is 10pt.
|
||||||
|
|
||||||
|
DOT_FONTSIZE = 10
|
||||||
|
|
||||||
|
# By default doxygen will tell dot to use the output directory to look for the
|
||||||
|
# FreeSans.ttf font (which doxygen will put there itself). If you specify a
|
||||||
|
# different font using DOT_FONTNAME you can set the path where dot
|
||||||
|
# can find it using this tag.
|
||||||
|
|
||||||
|
DOT_FONTPATH =
|
||||||
|
|
||||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||||
# will generate a graph for each documented class showing the direct and
|
# will generate a graph for each documented class showing the direct and
|
||||||
@@ -1166,14 +1437,14 @@ UML_LOOK = NO
|
|||||||
# If set to YES, the inheritance and collaboration graphs will show the
|
# If set to YES, the inheritance and collaboration graphs will show the
|
||||||
# relations between templates and their instances.
|
# relations between templates and their instances.
|
||||||
|
|
||||||
TEMPLATE_RELATIONS = NO
|
TEMPLATE_RELATIONS = YES
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
|
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
|
||||||
# tags are set to YES then doxygen will generate a graph for each documented
|
# tags are set to YES then doxygen will generate a graph for each documented
|
||||||
# file showing the direct and indirect include dependencies of the file with
|
# file showing the direct and indirect include dependencies of the file with
|
||||||
# other documented files.
|
# other documented files.
|
||||||
|
|
||||||
INCLUDE_GRAPH = YES
|
INCLUDE_GRAPH = NO
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
|
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
|
||||||
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
|
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
|
||||||
@@ -1182,19 +1453,19 @@ INCLUDE_GRAPH = YES
|
|||||||
|
|
||||||
INCLUDED_BY_GRAPH = YES
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
|
||||||
# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
|
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
|
||||||
# generate a call dependency graph for every global function or class method.
|
# doxygen will generate a call dependency graph for every global function
|
||||||
# Note that enabling this option will significantly increase the time of a run.
|
# or class method. Note that enabling this option will significantly increase
|
||||||
# So in most cases it will be better to enable call graphs for selected
|
# the time of a run. So in most cases it will be better to enable call graphs
|
||||||
# functions only using the \callgraph command.
|
# for selected functions only using the \callgraph command.
|
||||||
|
|
||||||
CALL_GRAPH = NO
|
CALL_GRAPH = NO
|
||||||
|
|
||||||
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will
|
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
|
||||||
# generate a caller dependency graph for every global function or class method.
|
# doxygen will generate a caller dependency graph for every global function
|
||||||
# Note that enabling this option will significantly increase the time of a run.
|
# or class method. Note that enabling this option will significantly increase
|
||||||
# So in most cases it will be better to enable caller graphs for selected
|
# the time of a run. So in most cases it will be better to enable caller
|
||||||
# functions only using the \callergraph command.
|
# graphs for selected functions only using the \callergraph command.
|
||||||
|
|
||||||
CALLER_GRAPH = NO
|
CALLER_GRAPH = NO
|
||||||
|
|
||||||
@@ -1219,7 +1490,7 @@ DOT_IMAGE_FORMAT = png
|
|||||||
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
||||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||||
|
|
||||||
DOT_PATH =
|
DOT_PATH = @DOXYGEN_DOT_EXECUTABLE_PATH@
|
||||||
|
|
||||||
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain dot files that are included in the documentation (see the
|
# contain dot files that are included in the documentation (see the
|
||||||
@@ -1227,19 +1498,31 @@ DOT_PATH =
|
|||||||
|
|
||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
|
|
||||||
# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
|
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
|
||||||
# nodes that will be shown in the graph. If the number of nodes in a graph
|
# nodes that will be shown in the graph. If the number of nodes in a graph
|
||||||
# becomes larger than this value, doxygen will truncate the graph, which is
|
# becomes larger than this value, doxygen will truncate the graph, which is
|
||||||
# visualized by representing a node as a red box. Note that doxygen will always
|
# visualized by representing a node as a red box. Note that doxygen if the
|
||||||
# show the root nodes and its direct children regardless of this setting.
|
# number of direct children of the root node in a graph is already larger than
|
||||||
|
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
|
||||||
|
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
|
||||||
|
|
||||||
DOT_GRAPH_MAX_NODES = 50
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
|
||||||
|
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
|
||||||
|
# graphs generated by dot. A depth value of 3 means that only nodes reachable
|
||||||
|
# from the root by following a path via at most 3 edges will be shown. Nodes
|
||||||
|
# that lay further from the root node will be omitted. Note that setting this
|
||||||
|
# option to 1 or 2 may greatly reduce the computation time needed for large
|
||||||
|
# code bases. Also note that the size of a graph can be further restricted by
|
||||||
|
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
|
||||||
|
|
||||||
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
|
||||||
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
||||||
# background. This is disabled by default, which results in a white background.
|
# background. This is disabled by default, because dot on Windows does not
|
||||||
# Warning: Depending on the platform used, enabling this option may lead to
|
# seem to support this out of the box. Warning: Depending on the platform used,
|
||||||
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
|
# enabling this option may lead to badly anti-aliased labels on the edges of
|
||||||
# read).
|
# a graph (i.e. they become hard to read).
|
||||||
|
|
||||||
DOT_TRANSPARENT = NO
|
DOT_TRANSPARENT = NO
|
||||||
|
|
||||||
@@ -1248,7 +1531,7 @@ DOT_TRANSPARENT = NO
|
|||||||
# makes dot run faster, but since only newer versions of dot (>1.8.10)
|
# makes dot run faster, but since only newer versions of dot (>1.8.10)
|
||||||
# support this, this feature is disabled by default.
|
# support this, this feature is disabled by default.
|
||||||
|
|
||||||
DOT_MULTI_TARGETS = NO
|
DOT_MULTI_TARGETS = YES
|
||||||
|
|
||||||
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
|
||||||
# generate a legend page explaining the meaning of the various boxes and
|
# generate a legend page explaining the meaning of the various boxes and
|
||||||
@@ -1261,12 +1544,3 @@ GENERATE_LEGEND = YES
|
|||||||
# the various graphs.
|
# the various graphs.
|
||||||
|
|
||||||
DOT_CLEANUP = YES
|
DOT_CLEANUP = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Configuration::additions related to the search engine
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# The SEARCHENGINE tag specifies whether or not a search engine should be
|
|
||||||
# used. If set to NO the values of all tags below this one will be ignored.
|
|
||||||
|
|
||||||
SEARCHENGINE = NO
|
|
||||||
221
doc/forwarding.dox
Normal file
221
doc/forwarding.dox
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_forwarding Chapter 7: Forwarding connections (tunnel)
|
||||||
|
@section forwarding_connections Forwarding connections
|
||||||
|
|
||||||
|
Port forwarding comes in SSH protocol in two different flavours:
|
||||||
|
direct or reverse port forwarding. Direct port forwarding is also
|
||||||
|
named local port forwardind, and reverse port forwarding is also called
|
||||||
|
remote port forwarding. SSH also allows X11 tunnels.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@subsection forwarding_direct Direct port forwarding
|
||||||
|
|
||||||
|
Direct port forwarding is from client to server. The client opens a tunnel,
|
||||||
|
and forwards whatever data to the server. Then, the server connects to an
|
||||||
|
end point. The end point can reside on another machine or on the SSH
|
||||||
|
server itself.
|
||||||
|
|
||||||
|
Example of use of direct port forwarding:
|
||||||
|
@verbatim
|
||||||
|
Mail client application Google Mail
|
||||||
|
| ^
|
||||||
|
5555 (arbitrary) |
|
||||||
|
| 143 (IMAP2)
|
||||||
|
V |
|
||||||
|
SSH client =====> SSH server
|
||||||
|
|
||||||
|
Legend:
|
||||||
|
--P-->: port connexion through port P
|
||||||
|
=====>: SSH tunnel
|
||||||
|
@endverbatim
|
||||||
|
A mail client connects to port 5555 of a client. An encrypted tunnel is
|
||||||
|
established to the server. The server connects to port 143 of Google Mail (the
|
||||||
|
end point). Now the local mail client can retreive mail.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection forwarding_reverse Reverse port forwarding
|
||||||
|
|
||||||
|
The reverse forwarding is slightly different. It goes from server to client,
|
||||||
|
even though the client has the initiative of establishing the tunnel.
|
||||||
|
Once the tunnel is established, the server will listen on a port. Whenever
|
||||||
|
a connection to this port is made, the server forwards the data to the client.
|
||||||
|
|
||||||
|
Example of use of reverse port forwarding:
|
||||||
|
@verbatim
|
||||||
|
Local mail server Mail client application
|
||||||
|
^ |
|
||||||
|
| 5555 (arbitrary)
|
||||||
|
143 (IMAP2) |
|
||||||
|
| V
|
||||||
|
SSH client <===== SSH server
|
||||||
|
|
||||||
|
Legend:
|
||||||
|
--P-->: port connexion through port P
|
||||||
|
=====>: SSH tunnel
|
||||||
|
@endverbatim
|
||||||
|
In this example, the SSH client establishes the tunnel,
|
||||||
|
but it is used to forward the connections established at
|
||||||
|
the server to the client.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection forwarding_x11 X11 tunnels
|
||||||
|
|
||||||
|
X11 tunnels allow a remote application to display locally.
|
||||||
|
|
||||||
|
Example of use of X11 tunnels:
|
||||||
|
@verbatim
|
||||||
|
Local display Graphical application
|
||||||
|
(X11 server) (X11 client)
|
||||||
|
^ |
|
||||||
|
| V
|
||||||
|
SSH client <===== SSH server
|
||||||
|
|
||||||
|
Legend:
|
||||||
|
----->: X11 connection through X11 display number
|
||||||
|
=====>: SSH tunnel
|
||||||
|
@endverbatim
|
||||||
|
The SSH tunnel is established by the client.
|
||||||
|
|
||||||
|
How to establish X11 tunnels with libssh has already been described in
|
||||||
|
this tutorial.
|
||||||
|
|
||||||
|
@see x11
|
||||||
|
|
||||||
|
|
||||||
|
@subsection libssh_direct Doing direct port forwarding with libssh
|
||||||
|
|
||||||
|
To do direct port forwarding, call function channel_open_forward():
|
||||||
|
- you need a separate channel for the tunnel as first parameter;
|
||||||
|
- second and third parameters are the remote endpoint;
|
||||||
|
- fourth and fifth parameters are sent to the remote server
|
||||||
|
so that they can be logged on that server.
|
||||||
|
|
||||||
|
If you don't plan to forward the data you will receive to any local port,
|
||||||
|
just put fake values like "localhost" and 5555 as your local host and port.
|
||||||
|
|
||||||
|
The example below shows how to open a direct channel that would be
|
||||||
|
used to retrieve google's home page from the remote SSH server.
|
||||||
|
|
||||||
|
@code
|
||||||
|
int direct_forwarding(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_channel forwarding_channel;
|
||||||
|
int rc;
|
||||||
|
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
|
||||||
|
int nbytes, nwritten;
|
||||||
|
|
||||||
|
forwarding_channel = ssh_channel_new(session);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = channel_open_forward(forwarding_channel,
|
||||||
|
"www.google.com", 80,
|
||||||
|
"localhost", 5555);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
ssh_channel_free(forwarding_channel);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes = strlen(http_get);
|
||||||
|
nwritten = channel_write(forwarding_channel, http_get, nbytes);
|
||||||
|
if (nbytes != nwritten)
|
||||||
|
{
|
||||||
|
ssh_channel_free(forwarding_channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_channel_free(forwarding_channel);
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The data sent by Google can be retrieved for example with ssh_select()
|
||||||
|
and ssh_channel_read(). Goggle's home page can then be displayed on the
|
||||||
|
local SSH client, saved into a local file, made available on a local port,
|
||||||
|
or whatever use you have for it.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection libssh_reverse Doing reverse port forwarding with libssh
|
||||||
|
|
||||||
|
To do reverse port forwarding, call ssh_channel_forward_listen(),
|
||||||
|
then ssh_channel_forward_accept().
|
||||||
|
|
||||||
|
When you call ssh_channel_forward_listen(), you can let the remote server
|
||||||
|
chose the non-priviledged port it should listen to. Otherwise, you can chose
|
||||||
|
your own priviledged or non-priviledged port. Beware that you should have
|
||||||
|
administrative priviledges on the remote server to open a priviledged port
|
||||||
|
(port number < 1024).
|
||||||
|
|
||||||
|
Below is an example of a very rough web server waiting for connections on port
|
||||||
|
8080 of remote SSH server. The incoming connections are passed to the
|
||||||
|
local libssh application, which handles them:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int web_server(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
ssh_channel channel;
|
||||||
|
char buffer[256];
|
||||||
|
int nbytes, nwritten;
|
||||||
|
char *helloworld = ""
|
||||||
|
"HTTP/1.1 200 OK\n"
|
||||||
|
"Content-Type: text/html\n"
|
||||||
|
"Content-Length: 113\n"
|
||||||
|
"\n"
|
||||||
|
"<html>\n"
|
||||||
|
" <head>\n"
|
||||||
|
" <title>Hello, World!</title>\n"
|
||||||
|
" </head>\n"
|
||||||
|
" <body>\n"
|
||||||
|
" <h1>Hello, World!</h1>\n"
|
||||||
|
" </body>\n"
|
||||||
|
"</html>\n";
|
||||||
|
|
||||||
|
rc = ssh_channel_forward_listen(session, NULL, 8080, NULL);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening remote port: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = ssh_channel_forward_accept(session, 60000);
|
||||||
|
if (channel == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error waiting for incoming connection: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
if (nbytes < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error reading incoming data: %s\n", ssh_get_error(session));
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
if (strncmp(buffer, "GET /", 5)) continue;
|
||||||
|
|
||||||
|
nbytes = strlen(helloworld);
|
||||||
|
nwritten = ssh_channel_write(channel, helloworld, nbytes);
|
||||||
|
if (nwritten != nbytes)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error sending answer: %s\n", ssh_get_error(session));
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
printf("Sent answer\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
455
doc/guided_tour.dox
Normal file
455
doc/guided_tour.dox
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_guided_tour Chapter 1: A typical SSH session
|
||||||
|
@section ssh_session A typical SSH session
|
||||||
|
|
||||||
|
A SSH session goes through the following steps:
|
||||||
|
|
||||||
|
- Before connecting to the server, you can set up if you wish one or other
|
||||||
|
server public key authentication, i.e. DSA or RSA. You can choose
|
||||||
|
cryptographic algorithms you trust and compression algorithms if any. You
|
||||||
|
must of course set up the hostname.
|
||||||
|
|
||||||
|
- The connection is established. A secure handshake is made, and resulting from
|
||||||
|
it, a public key from the server is gained. You MUST verify that the public
|
||||||
|
key is legitimate, using for instance the MD5 fingerprint or the known hosts
|
||||||
|
file.
|
||||||
|
|
||||||
|
- The client must authenticate: the classical ways are password, or
|
||||||
|
public keys (from dsa and rsa key-pairs generated by openssh).
|
||||||
|
If a SSH agent is running, it is possible to use it.
|
||||||
|
|
||||||
|
- Now that the user has been authenticated, you must open one or several
|
||||||
|
channels. Channels are different subways for information into a single ssh
|
||||||
|
connection. Each channel has a standard stream (stdout) and an error stream
|
||||||
|
(stderr). You can theoretically open an infinity of channels.
|
||||||
|
|
||||||
|
- With the channel you opened, you can do several things:
|
||||||
|
- Execute a single command.
|
||||||
|
- Open a shell. You may want to request a pseudo-terminal before.
|
||||||
|
- Invoke the sftp subsystem to transfer files.
|
||||||
|
- Invoke the scp subsystem to transfer files.
|
||||||
|
- Invoke your own subsystem. This is outside the scope of this document,
|
||||||
|
but can be done.
|
||||||
|
|
||||||
|
- When everything is finished, just close the channels, and then the connection.
|
||||||
|
|
||||||
|
The sftp and scp subsystems use channels, but libssh hides them to
|
||||||
|
the programmer. If you want to use those subsystems, instead of a channel,
|
||||||
|
you'll usually open a "sftp session" or a "scp session".
|
||||||
|
|
||||||
|
|
||||||
|
@subsection setup Creating the session and setting options
|
||||||
|
|
||||||
|
The most important object in a SSH connection is the SSH session. In order
|
||||||
|
to allocate a new SSH session, you use ssh_new(). Don't forget to
|
||||||
|
always verify that the allocation successed.
|
||||||
|
@code
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
ssh_session my_ssh_session = ssh_new();
|
||||||
|
if (my_ssh_session == NULL)
|
||||||
|
exit(-1);
|
||||||
|
...
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
libssh follows the allocate-it-deallocate-it pattern. Each object that you allocate
|
||||||
|
using xxxxx_new() must be deallocated using xxxxx_free(). In this case, ssh_new()
|
||||||
|
does the allocation and ssh_free() does the contrary.
|
||||||
|
|
||||||
|
The ssh_options_set() function sets the options of the session. The most important options are:
|
||||||
|
- SSH_OPTIONS_HOST: the name of the host you want to connect to
|
||||||
|
- SSH_OPTIONS_PORT: the used port (default is port 22)
|
||||||
|
- SSH_OPTIONS_USER: the system user under which you want to connect
|
||||||
|
- SSH_OPTIONS_LOG_VERBOSITY: the quantity of messages that are printed
|
||||||
|
|
||||||
|
The complete list of options can be found in the documentation of ssh_options_set().
|
||||||
|
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
|
||||||
|
the local username of your account will be used.
|
||||||
|
|
||||||
|
Here is a small example of how to use it:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
ssh_session my_ssh_session;
|
||||||
|
int verbosity = SSH_LOG_PROTOCOL;
|
||||||
|
int port = 22;
|
||||||
|
|
||||||
|
my_ssh_session = ssh_new();
|
||||||
|
if (my_ssh_session == NULL)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
|
||||||
|
ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||||
|
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Please notice that all parameters are passed to ssh_options_set() as pointers,
|
||||||
|
even if you need to set an integer value.
|
||||||
|
|
||||||
|
@see ssh_new
|
||||||
|
@see ssh_free
|
||||||
|
@see ssh_options_set
|
||||||
|
@see ssh_options_parse_config
|
||||||
|
@see ssh_options_copy
|
||||||
|
@see ssh_options_getopt
|
||||||
|
|
||||||
|
|
||||||
|
@subsection connect Connecting to the server
|
||||||
|
|
||||||
|
Once all settings have been made, you can connect using ssh_connect(). That
|
||||||
|
function will return SSH_OK if the connection worked, SSH_ERROR otherwise.
|
||||||
|
|
||||||
|
You can get the English error string with ssh_get_error() in order to show the
|
||||||
|
user what went wrong. Then, use ssh_disconnect() when you want to stop
|
||||||
|
the session.
|
||||||
|
|
||||||
|
Here's an example:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
ssh_session my_ssh_session;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
my_ssh_session = ssh_new();
|
||||||
|
if (my_ssh_session == NULL)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
|
||||||
|
|
||||||
|
rc = ssh_connect(my_ssh_session);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error connecting to localhost: %s\n",
|
||||||
|
ssh_get_error(my_ssh_session));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_disconnect(my_ssh_session);
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection serverauth Authenticating the server
|
||||||
|
|
||||||
|
Once you're connected, the following step is mandatory: you must check that the server
|
||||||
|
you just connected to is known and safe to use (remember, SSH is about security and
|
||||||
|
authentication).
|
||||||
|
|
||||||
|
There are two ways of doing this:
|
||||||
|
- The first way (recommended) is to use the ssh_is_server_known()
|
||||||
|
function. This function will look into the known host file
|
||||||
|
(~/.ssh/known_hosts on UNIX), look for the server hostname's pattern,
|
||||||
|
and determine whether this host is present or not in the list.
|
||||||
|
- The second way is to use ssh_get_pubkey_hash() to get a binary version
|
||||||
|
of the public key hash value. You can then use your own database to check
|
||||||
|
if this public key is known and secure.
|
||||||
|
|
||||||
|
You can also use the ssh_get_pubkey_hash() to show the public key hash
|
||||||
|
value to the user, in case he knows what the public key hash value is
|
||||||
|
(some paranoid people write their public key hash values on paper before
|
||||||
|
going abroad, just in case ...).
|
||||||
|
|
||||||
|
If the remote host is being used to for the first time, you can ask the user whether
|
||||||
|
he/she trusts it. Once he/she concluded that the host is valid and worth being
|
||||||
|
added in the known hosts file, you use ssh_write_knownhost() to register it in
|
||||||
|
the known hosts file, or any other way if you use your own database.
|
||||||
|
|
||||||
|
The following example is part of the examples suite available in the
|
||||||
|
examples/ directory:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int verify_knownhost(ssh_session session)
|
||||||
|
{
|
||||||
|
int state, hlen;
|
||||||
|
unsigned char *hash = NULL;
|
||||||
|
char *hexa;
|
||||||
|
char buf[10];
|
||||||
|
|
||||||
|
state = ssh_is_server_known(session);
|
||||||
|
|
||||||
|
hlen = ssh_get_pubkey_hash(session, &hash);
|
||||||
|
if (hlen < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case SSH_SERVER_KNOWN_OK:
|
||||||
|
break; /* ok */
|
||||||
|
|
||||||
|
case SSH_SERVER_KNOWN_CHANGED:
|
||||||
|
fprintf(stderr, "Host key for server changed: it is now:\n");
|
||||||
|
ssh_print_hexa("Public key hash", hash, hlen);
|
||||||
|
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
||||||
|
free(hash);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case SSH_SERVER_FOUND_OTHER:
|
||||||
|
fprintf(stderr, "The host key for this server was not found but an other"
|
||||||
|
"type of key exists.\n");
|
||||||
|
fprintf(stderr, "An attacker might change the default server key to"
|
||||||
|
"confuse your client into thinking the key does not exist\n");
|
||||||
|
free(hash);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case SSH_SERVER_FILE_NOT_FOUND:
|
||||||
|
fprintf(stderr, "Could not find known host file.\n");
|
||||||
|
fprintf(stderr, "If you accept the host key here, the file will be"
|
||||||
|
"automatically created.\n");
|
||||||
|
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
||||||
|
|
||||||
|
case SSH_SERVER_NOT_KNOWN:
|
||||||
|
hexa = ssh_get_hexa(hash, hlen);
|
||||||
|
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
||||||
|
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||||
|
free(hexa);
|
||||||
|
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (strncasecmp(buf, "yes", 3) != 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ssh_write_knownhost(session) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error %s\n", strerror(errno));
|
||||||
|
free(hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSH_SERVER_ERROR:
|
||||||
|
fprintf(stderr, "Error %s", ssh_get_error(session));
|
||||||
|
free(hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(hash);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see ssh_connect
|
||||||
|
@see ssh_disconnect
|
||||||
|
@see ssh_get_error
|
||||||
|
@see ssh_get_error_code
|
||||||
|
@see ssh_get_pubkey_hash
|
||||||
|
@see ssh_is_server_known
|
||||||
|
@see ssh_write_knownhost
|
||||||
|
|
||||||
|
|
||||||
|
@subsection auth Authenticating the user
|
||||||
|
|
||||||
|
The authentication process is the way a service provider can identify a
|
||||||
|
user and verify his/her identity. The authorization process is about enabling
|
||||||
|
the authenticated user the access to ressources. In SSH, the two concepts
|
||||||
|
are linked. After authentication, the server can grant the user access to
|
||||||
|
several ressources such as port forwarding, shell, sftp subsystem, and so on.
|
||||||
|
|
||||||
|
libssh supports several methods of authentication:
|
||||||
|
- "none" method. This method allows to get the available authentications
|
||||||
|
methods. It also gives the server a chance to authenticate the user with
|
||||||
|
just his/her login. Some very old hardware uses this feature to fallback
|
||||||
|
the user on a "telnet over SSH" style of login.
|
||||||
|
- password method. A password is sent to the server, which accepts it or not.
|
||||||
|
- keyboard-interactive method. The server sends several challenges to the
|
||||||
|
user, who must answer correctly. This makes possible the authentication
|
||||||
|
via a codebook for instance ("give code at 23:R on page 3").
|
||||||
|
- public key method. The host knows the public key of the user, and the
|
||||||
|
user must prove he knows the associated private key. This can be done
|
||||||
|
manually, or delegated to the SSH agent as we'll see later.
|
||||||
|
|
||||||
|
All these methods can be combined. You can for instance force the user to
|
||||||
|
authenticate with at least two of the authentication methods. In that case,
|
||||||
|
one speaks of "Partial authentication". A partial authentication is a
|
||||||
|
response from authentication functions stating that your credential was
|
||||||
|
accepted, but yet another one is required to get in.
|
||||||
|
|
||||||
|
The example below shows an authentication with password:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
ssh_session my_ssh_session;
|
||||||
|
int rc;
|
||||||
|
char *password;
|
||||||
|
|
||||||
|
// Open session and set options
|
||||||
|
my_ssh_session = ssh_new();
|
||||||
|
if (my_ssh_session == NULL)
|
||||||
|
exit(-1);
|
||||||
|
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
|
||||||
|
|
||||||
|
// Connect to server
|
||||||
|
rc = ssh_connect(my_ssh_session);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error connecting to localhost: %s\n",
|
||||||
|
ssh_get_error(my_ssh_session));
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the server's identity
|
||||||
|
// For the source code of verify_knowhost(), check previous example
|
||||||
|
if (verify_knownhost(my_ssh_session) < 0)
|
||||||
|
{
|
||||||
|
ssh_disconnect(my_ssh_session);
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authenticate ourselves
|
||||||
|
password = getpass("Password: ");
|
||||||
|
rc = ssh_userauth_password(my_ssh_session, NULL, password);
|
||||||
|
if (rc != SSH_AUTH_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error authenticating with password: %s\n",
|
||||||
|
ssh_get_error(my_ssh_session));
|
||||||
|
ssh_disconnect(my_ssh_session);
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_disconnect(my_ssh_session);
|
||||||
|
ssh_free(my_ssh_session);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see @ref authentication_details
|
||||||
|
|
||||||
|
|
||||||
|
@subsection using_ssh Doing something
|
||||||
|
|
||||||
|
At this point, the authenticity of both server and client is established.
|
||||||
|
Time has come to take advantage of the many possibilities offered by the SSH
|
||||||
|
protocol: execute a remote command, open remote shells, transfer files,
|
||||||
|
forward ports, etc.
|
||||||
|
|
||||||
|
The example below shows how to execute a remote command:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int show_remote_processes(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_channel channel;
|
||||||
|
int rc;
|
||||||
|
char buffer[256];
|
||||||
|
unsigned int nbytes;
|
||||||
|
|
||||||
|
channel = ssh_channel_new(session);
|
||||||
|
if (channel == NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
|
||||||
|
rc = ssh_channel_open_session(channel);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_channel_request_exec(channel, "ps aux");
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
while (nbytes > 0)
|
||||||
|
{
|
||||||
|
if (write(1, buffer, nbytes) != nbytes)
|
||||||
|
{
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes < 0)
|
||||||
|
{
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see @ref opening_shell
|
||||||
|
@see @ref remote_command
|
||||||
|
@see @ref sftp_subsystem
|
||||||
|
@see @ref scp_subsystem
|
||||||
|
|
||||||
|
|
||||||
|
@subsection errors Handling the errors
|
||||||
|
|
||||||
|
All the libssh functions which return an error value also set an English error message
|
||||||
|
describing the problem.
|
||||||
|
|
||||||
|
Error values are typically SSH_ERROR for integer values, or NULL for pointers.
|
||||||
|
|
||||||
|
The function ssh_get_error() returns a pointer to the static error message.
|
||||||
|
|
||||||
|
ssh_error_code() returns the error code number : SSH_NO_ERROR,
|
||||||
|
SSH_REQUEST_DENIED, SSH_INVALID_REQUEST, SSH_CONNECTION_LOST, SSH_FATAL,
|
||||||
|
or SSH_INVALID_DATA. SSH_REQUEST_DENIED means the ssh server refused your
|
||||||
|
request, but the situation is recoverable. The others mean something happened
|
||||||
|
to the connection (some encryption problems, server problems, ...).
|
||||||
|
SSH_INVALID_REQUEST means the library got some garbage from server, but
|
||||||
|
might be recoverable. SSH_FATAL means the connection has an important
|
||||||
|
problem and isn't probably recoverable.
|
||||||
|
|
||||||
|
Most of time, the error returned are SSH_FATAL, but some functions
|
||||||
|
(generaly the ssh_request_xxx ones) may fail because of server denying request.
|
||||||
|
In these cases, SSH_REQUEST_DENIED is returned.
|
||||||
|
|
||||||
|
ssh_get_error() and ssh_get_error_code() take a ssh_session as a parameter.
|
||||||
|
That's for thread safety, error messages that can be attached to a session
|
||||||
|
aren't static anymore. Any error that happens during ssh_options_xxx()
|
||||||
|
or ssh_connect() (i.e., outside of any session) can be retrieved by
|
||||||
|
giving NULL as argument.
|
||||||
|
|
||||||
|
The SFTP subsystem has its own error codes, in addition to libssh ones.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
50
doc/introduction.dox
Normal file
50
doc/introduction.dox
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutorial The Tutorial
|
||||||
|
@section introduction Introduction
|
||||||
|
|
||||||
|
libssh is a C library that enables you to write a program that uses the
|
||||||
|
SSH protocol. With it, you can remotely execute programs, transfer
|
||||||
|
files, or use a secure and transparent tunnel for your remote programs.
|
||||||
|
The SSH protocol is encrypted, ensures data integrity, and provides strong
|
||||||
|
means of authenticating both the server of the client. The library hides
|
||||||
|
a lot of technical details from the SSH protocol, but this does not
|
||||||
|
mean that you should not try to know about and understand these details.
|
||||||
|
|
||||||
|
libssh is a Free Software / Open Source project. The libssh library
|
||||||
|
is distributed under LGPL license. The libssh project has nothing to do with
|
||||||
|
"libssh2", which is a completly different and independant project.
|
||||||
|
|
||||||
|
libssh can run on top of either libgcrypt (http://directory.fsf.org/project/libgcrypt/)
|
||||||
|
or libcrypto (http://www.openssl.org/docs/crypto/crypto.html), two general-purpose
|
||||||
|
cryptographic libraries.
|
||||||
|
|
||||||
|
This tutorial concentrates for its main part on the "client" side of libssh.
|
||||||
|
To learn how to accept incoming SSH connexions (how to write a SSH server),
|
||||||
|
you'll have to jump to the end of this document.
|
||||||
|
|
||||||
|
This tutorial describes libssh version 0.5.0. This version is a little different
|
||||||
|
from the 0.4.X series. However, the examples should work with
|
||||||
|
little changes on versions like 0.4.2 and later.
|
||||||
|
|
||||||
|
|
||||||
|
Table of contents:
|
||||||
|
|
||||||
|
@subpage libssh_tutor_guided_tour
|
||||||
|
|
||||||
|
@subpage libssh_tutor_authentication
|
||||||
|
|
||||||
|
@subpage libssh_tutor_shell
|
||||||
|
|
||||||
|
@subpage libssh_tutor_command
|
||||||
|
|
||||||
|
@subpage libssh_tutor_sftp
|
||||||
|
|
||||||
|
@subpage libssh_tutor_scp
|
||||||
|
|
||||||
|
@subpage libssh_tutor_forwarding
|
||||||
|
|
||||||
|
@subpage libssh_tutor_threads
|
||||||
|
|
||||||
|
@subpage libssh_tutor_todo
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -1,385 +0,0 @@
|
|||||||
The new libssh 0.2 API
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Version 1
|
|
||||||
|
|
||||||
A. Introduction
|
|
||||||
---------------
|
|
||||||
|
|
||||||
With the time from the first release of libssh, I have received lots of
|
|
||||||
comments about the current API. Myself, I found it quite limiting when doing
|
|
||||||
my first libssh-server drafts. Thus, I am moving to a stronger API.
|
|
||||||
This API must still be simple. I am not introducing complex changes. An API
|
|
||||||
well designed must hide the implementation details. Implementation can change
|
|
||||||
easily within bugfixes - but API cannot change each release.
|
|
||||||
|
|
||||||
To the people already using libssh 0.11 : sorry. Once I have the complete API
|
|
||||||
redesigned, I will write a migration paper. It won't be too hard normally.
|
|
||||||
|
|
||||||
Here are the things that were lacking in the previous API and *must* change:
|
|
||||||
|
|
||||||
* A non-blocking mode connection type
|
|
||||||
* Functions to relegate File descriptor listening to Calling functions and to
|
|
||||||
the programmer. (I'll explain later).
|
|
||||||
* Along with that, good buffering system (well, it's not an API but).
|
|
||||||
* Leave the "functions returns a pointer when it works and NULL when it does
|
|
||||||
not work". It gives serious problems to implement bindings (A C++
|
|
||||||
constructor should not fail and should not depend on a network thing
|
|
||||||
* Make the Session structure an abstract structure that can work with both
|
|
||||||
client and *servers*. That mean we should have a Server object which listen
|
|
||||||
to clients on a bound port, does the different handshakes and return a
|
|
||||||
session.
|
|
||||||
Since C is not per se an Object language, I won't use inheritance between
|
|
||||||
objects.
|
|
||||||
* This same server thing must provide the reverse capabilities than the
|
|
||||||
client. That is, accept the handshake, in a nonblocking way. Accept channel
|
|
||||||
requests, or send them to the controller program.
|
|
||||||
* Support for program forking : Imagine you have a Ssh server object. You
|
|
||||||
accept a connection and receive a session, then you receive a channel. You
|
|
||||||
may want to keep the good old days fork() tricks. Libssh will give a way to
|
|
||||||
destroy handlers from sessions which belong to an other process without
|
|
||||||
disturbing the session.
|
|
||||||
* So often I received the comment back saying that it was not clear why a
|
|
||||||
session or a channel was terminated. This is over.
|
|
||||||
* And of course I received lot of mails about the fact I'm doing namespace
|
|
||||||
polution. this will be resolved this time.
|
|
||||||
So, please read this draft not as a formal documentation but like a roadmap of
|
|
||||||
things that each kind of object must do.
|
|
||||||
|
|
||||||
B. Description of objects and functions
|
|
||||||
|
|
||||||
Initialization and finalization
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Initialization is for now called automatically, so you don't have to take care
|
|
||||||
of that.
|
|
||||||
As for finalization, we need to finalize the underlying cryptographic library
|
|
||||||
(either OpenSSL or libgcrypt). Be sure that you call ssh_finalize when this
|
|
||||||
library won't be used anymore, even by other libraries (i.e. if you use libssh
|
|
||||||
and another library that uses OpenSSL, call ssh_finalize when any function of
|
|
||||||
both these libraries won't be called).
|
|
||||||
If you trust your operating system to clean up the mess after a process
|
|
||||||
terminates, you can skip this call.
|
|
||||||
|
|
||||||
Options structure
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
struct ssh_options *ssh_options_new()
|
|
||||||
|
|
||||||
ssh_options_getopt(options, *argc, argv)
|
|
||||||
|
|
||||||
ssh_options_copy(options)
|
|
||||||
|
|
||||||
char ** ssh_options_get_supported_algos(options,type)
|
|
||||||
returns a list of the algos supported by libssh, type being one of
|
|
||||||
SSH_HOSTKEYS, SSH_KEX, SSH_CRYPT, SSH_MAC, SSH_COMP, SSH_LANG
|
|
||||||
|
|
||||||
ssh_options_set_wanted_algos(options,type, char *list)
|
|
||||||
list being comma-separated list of algos, and type being the upper constants
|
|
||||||
but with _C_S or _S_V added to them.
|
|
||||||
|
|
||||||
ssh_options_set_port(options, port)
|
|
||||||
|
|
||||||
ssh_options_set_host(options, host)
|
|
||||||
|
|
||||||
ssh_options_set_fd(options, fd)
|
|
||||||
|
|
||||||
ssh_options_set_bind(options, bindaddr, port)
|
|
||||||
this options sets the address to bind for a client *or* a server. a port of
|
|
||||||
zero means whatever port is free (what most clients want).
|
|
||||||
|
|
||||||
ssh_options_set_username(options, username)
|
|
||||||
|
|
||||||
ssh_options_set_connect_timeout(options, seconds, usec)
|
|
||||||
|
|
||||||
ssh_options_set_ssh_dir(options, dir)
|
|
||||||
ssh_options_set_known_hosts_file(options, file)
|
|
||||||
ssh_options_set_identity(options, file)
|
|
||||||
|
|
||||||
ssh_options_set_banner(options, banner)
|
|
||||||
ssh_options_allow_ssh1(options, bool allow)
|
|
||||||
ssh_options_allow_ssh2(options, bool allow)
|
|
||||||
|
|
||||||
options_set_status_callback has moved into ssh_* functions.
|
|
||||||
|
|
||||||
ssh_session Structure
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This session structure represents a ssh socket to a server *or* a client.
|
|
||||||
|
|
||||||
ssh_session *ssh_new()
|
|
||||||
|
|
||||||
ssh_set_options(ssh_session,ssh_options)
|
|
||||||
|
|
||||||
ssh_connect(session);
|
|
||||||
it will return some status describing at which point of the connection it is,
|
|
||||||
or an error code. If the connection method is non-blocking, the function
|
|
||||||
will be called more than once, though the return value SSH_AGAIN.
|
|
||||||
|
|
||||||
ssh_set_blocking(session, bool blocking)
|
|
||||||
set blocking mode or non blocking mode.
|
|
||||||
|
|
||||||
ssh_get_fd(session)
|
|
||||||
get the currently used connection file descriptor or equivalent (windows)
|
|
||||||
|
|
||||||
ssh_set_fd_toread(session)
|
|
||||||
ssh_set_fd_towrite(session)
|
|
||||||
ssh_set_fd_except(session)
|
|
||||||
Serve to notify the library that data is actualy available to be read on the
|
|
||||||
file descriptor socket. why ? because on most platforms select can't be done
|
|
||||||
twice on the same socket when the first reported data to read or to write
|
|
||||||
|
|
||||||
ssh_get_status(session)
|
|
||||||
Returns the current status bitmask : connection Open or closed, data
|
|
||||||
pending to read or not (even if connection closed), connection closed on
|
|
||||||
error or on an exit message
|
|
||||||
|
|
||||||
ssh_get_disconnect_message(session)
|
|
||||||
Returns the connection disconnect error/exit message
|
|
||||||
|
|
||||||
ssh_get_pubkey_hash(session, hash)
|
|
||||||
get the public key hash from the server.
|
|
||||||
|
|
||||||
ssh_is_server_known(session)
|
|
||||||
ssh_write_knownhost(session)
|
|
||||||
these 2 functions will be kept
|
|
||||||
|
|
||||||
ssh_disconnect(session)
|
|
||||||
standard disconnect
|
|
||||||
|
|
||||||
ssh_disconnect_error(session,error code, message)
|
|
||||||
disconnect with a message
|
|
||||||
|
|
||||||
ssh_set_username(session)
|
|
||||||
set the user name to log in
|
|
||||||
|
|
||||||
ssh_userauth_* functions will be kept as they are now, excepted the fact that
|
|
||||||
the username field will disapear.
|
|
||||||
the public key mechanism may get some more functions, like retrieving a public
|
|
||||||
key from a private key and authenticating without a public key.
|
|
||||||
|
|
||||||
ssh_get_issue_banner(session)
|
|
||||||
get the issue banner from the server, that is the welcome message.
|
|
||||||
|
|
||||||
ssh_silent_free(session)
|
|
||||||
This function silently free all data structures used by the session and
|
|
||||||
closes the socket. It may be used for instance when the process forked and
|
|
||||||
doesn't want to keep track of this session. This is obviously not possible to
|
|
||||||
do with separate channels.
|
|
||||||
|
|
||||||
The channel_struct structure
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The channels will change a bit. the constructor thing will change, and the way
|
|
||||||
to multiplex different connections will change too. channel functions will be
|
|
||||||
prefixed with "ssh_"
|
|
||||||
|
|
||||||
struct channel_struct *ssh_channel_new()
|
|
||||||
|
|
||||||
ssh_channel_open_session(channel)
|
|
||||||
will return if the channel allocation failed or not.
|
|
||||||
|
|
||||||
ssh_channel_open_forward(channel, ...) won't change. it will report an error if
|
|
||||||
the channel allocation failed.
|
|
||||||
|
|
||||||
ssh_channel_send_eof(channel)
|
|
||||||
send EOF
|
|
||||||
ssh_channel_close(channel)
|
|
||||||
closes a channel but doesn't destroy it. you may read unread data still in
|
|
||||||
the buffer. Once you closed the buffer, the other party can't send you data,
|
|
||||||
while it could still do it if you only sent an EOF.
|
|
||||||
ssh_channel_is_closed(channel)
|
|
||||||
returns true if the channel was closed at one of both sides. a closed chan
|
|
||||||
may still have data to read, if you closed yourself the connection. otherwise
|
|
||||||
(you didn't close it) the closed notification only comes when you read the
|
|
||||||
last buffer byte, or when trying to write into the channel (the SIGPIPE-like
|
|
||||||
behaviour).
|
|
||||||
|
|
||||||
ssh_channel_is_eof(channel)
|
|
||||||
reports if the other side has sent an EOF. This functions returns FALSE if
|
|
||||||
there is still data to read. A closed channel is always EOF.
|
|
||||||
ssh_channel_free(channel)
|
|
||||||
completely free the channel. closes it before if it was not done.
|
|
||||||
|
|
||||||
ssh_channel_request_env(channel, name, value)
|
|
||||||
set an environment variable.
|
|
||||||
|
|
||||||
ssh_channel_request_pty(channel)
|
|
||||||
ssh_channel_request_pty_size()
|
|
||||||
ssh_channel_change_pty_size()
|
|
||||||
ssh_channel_request_shell()
|
|
||||||
ssh_channel_request_exec()
|
|
||||||
ssh_channel_request_subsystem()
|
|
||||||
These functions won't change.
|
|
||||||
|
|
||||||
int ssh_channel_write(channel,data, len,stderr)
|
|
||||||
Depending on the blocking/non blocking mode of the channel, the behaviour may
|
|
||||||
change.
|
|
||||||
stderr is the extended buffer. It's generaly only a server->client stream.
|
|
||||||
|
|
||||||
ssh_channel_set_blocking(bool blocking)
|
|
||||||
|
|
||||||
int ssh_channel_read(channel, buffer, maxlen, is_stderr)
|
|
||||||
the behaviour will be this one:
|
|
||||||
-if the chan is in non blocking mode, it will poll what's available to read
|
|
||||||
and return this. otherwise (nothing to read) it will return 0.
|
|
||||||
-if the chan is blocking, it will block until at least one byte is
|
|
||||||
available.
|
|
||||||
ssh_channel_nonblocking disapears for the later reason.
|
|
||||||
|
|
||||||
int channel_poll(channel, is_stderr)
|
|
||||||
polls the network and reports the number of bytes ready to be read in the
|
|
||||||
chan.
|
|
||||||
|
|
||||||
ssh_session ssh_channel_get_session(channel)
|
|
||||||
returns the session pointer associated to the channel, for simplicity
|
|
||||||
reasons.
|
|
||||||
|
|
||||||
int ssh_channel_select(CHANNELS *readchans, CHANNELS *writechans, CHANNELS
|
|
||||||
*exceptchans, struct timeval *timeout)
|
|
||||||
This function won't work the same way ssh_select did.
|
|
||||||
I removed the custom file descriptor thing for 2 reasons:
|
|
||||||
1- it's not windows compliant. D'ouh !
|
|
||||||
2- most programmers won't want to depend on libssh for socket multiplexing.
|
|
||||||
that's why i let the programmer poll the fds himself and then use
|
|
||||||
ssh_set_fd_toread, towrite or except. Then, he may use ssh_channel_select
|
|
||||||
with a NULL timeout to poll which channels have something to read, write or
|
|
||||||
error report.
|
|
||||||
Here is how it's going to work. The coder sets 3 different arrays with the
|
|
||||||
channels he wants to select(), the last entry being a NULL pointer. The
|
|
||||||
function will first poll them and return the chans that must be
|
|
||||||
read/write/excepted. If nothing has this state, the function will select()
|
|
||||||
using the timeout.
|
|
||||||
The function will return 0 if everything is ok, SSH_TIMEOUT or SSH_EINTR if
|
|
||||||
the select was interrupted by a signal. It is dangerous to execute any
|
|
||||||
channel-related functions into signal handlers. they should set a flag that
|
|
||||||
you read into your loop. this "trap" (SSH_EINTR) will permit you to catch
|
|
||||||
them faster and make your program responsive and look fast.
|
|
||||||
the function will return -1 if a serious problem happens.
|
|
||||||
|
|
||||||
|
|
||||||
Error handling
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
when an error happens, the programmer can get the error code and description
|
|
||||||
with ssh_get_error(session). the creation of a failess constructor for
|
|
||||||
ssh_session was needed for this reason.
|
|
||||||
|
|
||||||
ssh_get_error_code(session) will return an error code into this subset:
|
|
||||||
SSH_NO_ERROR : no error :)
|
|
||||||
SSH_REQUEST_DENIED : you request for a functionality or a service that is not
|
|
||||||
allowed. The session can continue.
|
|
||||||
SSH_FATAL : Unrecoverable error. The session can't continue and you should
|
|
||||||
disconnect the session. It includes the connection being cut without a
|
|
||||||
disconnect() message.
|
|
||||||
If a disconnect() message or the channel was closed, a read on such a channel
|
|
||||||
won't produce an error. otherwise it will return -1 with a SSH_FATAL error
|
|
||||||
code.
|
|
||||||
|
|
||||||
Server socket binding
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
It is not possible to bind a socket for ssh with a SSH_SESSION type, because a
|
|
||||||
single bound port may lead to multiple ssh connections. That's why the
|
|
||||||
SSH_BIND structure must be created. It uses options from the SSH_OPTIONS
|
|
||||||
structure.
|
|
||||||
|
|
||||||
SSH_BIND *ssh_bind_new()
|
|
||||||
creates a structure
|
|
||||||
ssh_bind_set_options(bind, options)
|
|
||||||
set the option structure
|
|
||||||
int ssh_bind_listen(bind)
|
|
||||||
bind and listen to the port. This call is not blocking. if some error
|
|
||||||
happens, it returns -1 and the error code can be found with perror().
|
|
||||||
|
|
||||||
ssh_bind_set_blocking(bind, bool blocking)
|
|
||||||
should ssh_bind_accept() block or not.
|
|
||||||
|
|
||||||
int ssh_bind_get_fd(bind)
|
|
||||||
return the bound file descriptor, that is the listener socket. you may put it
|
|
||||||
into a select() in your code to detect a connection attempt.
|
|
||||||
|
|
||||||
ssh_bind_set_fd_toaccept(bind)
|
|
||||||
say that the listener socket has a connection to accept (to avoid
|
|
||||||
ssh_bind_accept() to do a select on it).
|
|
||||||
|
|
||||||
SSH_SESSION *ssh_bind_accept(bind)
|
|
||||||
return a server handle to a ssh session. if the mode is blocking, the
|
|
||||||
function will always return a pointer to a session. if the mode is not
|
|
||||||
blocking, the function can return NULL if there is no connection to accept.
|
|
||||||
|
|
||||||
This SSH_SESSION handle must then pass through the functions explained above.
|
|
||||||
|
|
||||||
|
|
||||||
*server functions *
|
|
||||||
|
|
||||||
int ssh_accept(session)
|
|
||||||
when a new connection is accepted, the handshake must be done. this function
|
|
||||||
will do the banner handshake and the key exchange.
|
|
||||||
it will return SSH_AGAIN if the session mode is non blocking, and the
|
|
||||||
function must be called again until an error occurs or the kex is done.
|
|
||||||
|
|
||||||
Here, I had a few choises about *how* to implement the message parsing as a
|
|
||||||
server. There are multiple ways to do it, one being callbacks and one being
|
|
||||||
"Message" reading, parsing and then choice going to the user to use it and
|
|
||||||
answer. I've choosen the latter because i believe it's the stronger method.
|
|
||||||
A ssh server can receive 30 different kind of messages having to be dealt by
|
|
||||||
the high level routines, like channel request_shell or authentication. Having
|
|
||||||
a callback for all of them would produce a huge kludge of callbacks, with
|
|
||||||
no relations on when there were called etc.
|
|
||||||
A message based parsing allows the user to filtrate the messages he's
|
|
||||||
interested into and to use a default answer for the others. Then, the callback
|
|
||||||
thing is still possible to handle through a simple message code/callback
|
|
||||||
function array.
|
|
||||||
|
|
||||||
I did not define yet what it would look like, but i'm sure there will be a
|
|
||||||
SSH_MESSAGE (they won't have a 1/1 correspondance with ssh packets) which will
|
|
||||||
be read through
|
|
||||||
SSH_MESSAGE *ssh_server_read_message(session).
|
|
||||||
with all of the non-blocking stuff in head like returning NULL if the message
|
|
||||||
is not full.
|
|
||||||
Then, the message can be parsed, ie
|
|
||||||
int ssh_message_get_code(message)
|
|
||||||
which will return SSH_MESSAGE_AUTH
|
|
||||||
then
|
|
||||||
int ssh_message_get_subcode(message)
|
|
||||||
which then will returh SSH_MESSAGE_AUTH_PASSWORD or _NONE or _PUBKEY etc.
|
|
||||||
|
|
||||||
Then, once the message was parsed, the message will have to be answered, ie
|
|
||||||
with the generic functions like
|
|
||||||
ssh_message_accept(message) which says 'Ok your request is accepted' or
|
|
||||||
ssh_message_deny(message) which says 'Your request is refused'.
|
|
||||||
|
|
||||||
There would be specific message answer functions for some kind of messages
|
|
||||||
like the authentication one. you may want to reply that the authentication is
|
|
||||||
Partial rather than denied, and that you still accept some kind of auths, like
|
|
||||||
ssh_message_auth_reply(message,SSH_AUTH_PARTIAL,SSH_AUTH_PASSWORD |
|
|
||||||
SSH_AUTH_PUBKEY | SSH_AUTH_KEYBINT);
|
|
||||||
|
|
||||||
I won't let the user have to deal with the channels himself. When a channel is
|
|
||||||
going to be created by the remote size, a message will come asking to open a
|
|
||||||
channel. the programmer can either deny or accept, in which case a CHANNEL
|
|
||||||
object will be created and returned to the programmer. then, all standard
|
|
||||||
channel functions will run.
|
|
||||||
|
|
||||||
C. Change log of this document
|
|
||||||
|
|
||||||
3. Add paragraph about initalization and finalization.
|
|
||||||
|
|
||||||
2. ssh_options_set_username finaly is kept into the options, because it can be
|
|
||||||
set by ssh_options_getopt()
|
|
||||||
|
|
||||||
1. first release
|
|
||||||
|
|
||||||
D. End notes
|
|
||||||
|
|
||||||
I think libssh must have a very simple to use, powerful and exhaustive API. It
|
|
||||||
must have no design flaw either.
|
|
||||||
While I got some good experience at the SSH protocol, I've never writen
|
|
||||||
more-than-100 lines programs than use libssh and I don't really know the
|
|
||||||
problems of the library. I'd like people who don't understand some detail into
|
|
||||||
the API I describe here, who have comments or opinions about it to write me
|
|
||||||
the soonest possible to limit the damages if I made something the completely
|
|
||||||
wrong way.
|
|
||||||
Thanks for your patience.
|
|
||||||
|
|
||||||
24
doc/linking.dox
Normal file
24
doc/linking.dox
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
@page libssh_linking The Linking HowTo
|
||||||
|
|
||||||
|
@section dynamic Dynamic Linking
|
||||||
|
|
||||||
|
On UNIX and Windows systems its the same, you need at least the libssh.h
|
||||||
|
header file and the libssh shared library.
|
||||||
|
|
||||||
|
@section static Static Linking
|
||||||
|
|
||||||
|
@warning <b>The libssh library is licensed under the LGPL! Make sure you
|
||||||
|
understand what this means to your codebase if you want to distribute
|
||||||
|
binaries and link statically against LGPL code!</b>
|
||||||
|
|
||||||
|
On UNIX systems linking against the static version of the library is the
|
||||||
|
same as linking against the shared library. Both have the same name. Some
|
||||||
|
build system require to use the full path to the static library.
|
||||||
|
|
||||||
|
On Windows you need to define LIBSSH_STATIC in the compiler command
|
||||||
|
line. This is required cause the dynamic library needs to specify the
|
||||||
|
dllimport attribute.
|
||||||
|
|
||||||
|
*/
|
||||||
124
doc/mainpage.dox
Normal file
124
doc/mainpage.dox
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
@mainpage
|
||||||
|
|
||||||
|
This is the online reference for developing with the libssh library. It
|
||||||
|
documents the libssh C API and the C++ wrapper.
|
||||||
|
|
||||||
|
@section main-linking Linking
|
||||||
|
|
||||||
|
We created a small howto how to link libssh against your application, read
|
||||||
|
@subpage libssh_linking.
|
||||||
|
|
||||||
|
@section main-tutorial Tutorial
|
||||||
|
|
||||||
|
You should start by reading @subpage libssh_tutorial, then reading the documentation of
|
||||||
|
the interesting functions as you go.
|
||||||
|
|
||||||
|
@section main-features Features
|
||||||
|
|
||||||
|
The libssh library provides:
|
||||||
|
|
||||||
|
- Full C library functions for manipulating a client-side SSH connection
|
||||||
|
- SSH2 and SSH1 protocol compliant
|
||||||
|
- Fully configurable sessions
|
||||||
|
- Server support
|
||||||
|
- SSH agent authentication support
|
||||||
|
- Support for AES-128, AES-192, AES-256, Blowfish, 3DES in CBC mode, and AES in CTR mode
|
||||||
|
- Supports OpenSSL and GCrypt
|
||||||
|
- Use multiple SSH connections in a same process, at same time
|
||||||
|
- Use multiple channels in the same connection
|
||||||
|
- Thread safety when using different sessions at same time
|
||||||
|
- POSIX-like SFTP (Secure File Transfer) implementation with openssh extension support
|
||||||
|
- SCP implementation
|
||||||
|
- Large file system support (files bigger than 4GB)
|
||||||
|
- RSA and DSS server public key supported
|
||||||
|
- Compression support (with zlib)
|
||||||
|
- Public key (RSA and DSS), password and keyboard-interactive authentication
|
||||||
|
- Full poll()/WSAPoll() support and a poll-emulation for Win32.
|
||||||
|
- Runs and tested under x86_64, x86, ARM, Sparc32, PPC under Linux, BSD, MacOSX, Solaris and Windows
|
||||||
|
|
||||||
|
@section main-copyright Copyright Policy
|
||||||
|
|
||||||
|
The developers of libssh have a policy of asking for contributions to be made
|
||||||
|
under the personal copyright of the contributor, instead of a corporate
|
||||||
|
copyright.
|
||||||
|
|
||||||
|
There are some reasons for the establishment of this policy:
|
||||||
|
|
||||||
|
@li Individual copyrights make copyright registration in the US a simpler
|
||||||
|
process.
|
||||||
|
@li If libssh is copyrighted by individuals rather than corporations,
|
||||||
|
decisions regarding enforcement and protection of copyright will, more
|
||||||
|
likely, be made in the interests of the project, and not in the interests
|
||||||
|
of any corporation’s shareholders.
|
||||||
|
@li If we ever need to relicense a portion of the code contacting individuals
|
||||||
|
for permission to do so is much easier than contacting a company.
|
||||||
|
|
||||||
|
@section main-rfc Internet standard
|
||||||
|
|
||||||
|
@subsection main-rfc-secsh Secure Shell (SSH)
|
||||||
|
|
||||||
|
The following RFC documents described SSH-2 protcol as an Internet standard.
|
||||||
|
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
|
||||||
|
The Secure Shell (SSH) Protocol Assigned Numbers
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
|
||||||
|
The Secure Shell (SSH) Protocol Architecture
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
|
||||||
|
The Secure Shell (SSH) Authentication Protocol
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
|
||||||
|
The Secure Shell (SSH) Transport Layer Protocol
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
|
||||||
|
The Secure Shell (SSH) Connection Protocol
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
|
||||||
|
Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
|
||||||
|
Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
|
||||||
|
The Secure Shell (SSH) Session Channel Break Extension
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
|
||||||
|
The Secure Shell (SSH) Transport Layer Encryption Modes
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
|
||||||
|
Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
|
||||||
|
|
||||||
|
It was later modified and expanded by the following RFCs.
|
||||||
|
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
|
||||||
|
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
|
||||||
|
Protocol
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
|
||||||
|
RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
|
||||||
|
Generic Security Service Application Program Interface (GSS-API)
|
||||||
|
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
||||||
|
The Secure Shell (SSH) Public Key File Format
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
||||||
|
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
||||||
|
|
||||||
|
Interesting cryptography documents:
|
||||||
|
|
||||||
|
- <a href="http://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
|
||||||
|
|
||||||
|
@subsection main-rfc-sftp Secure Shell File Transfer Protocol (SFTP)
|
||||||
|
|
||||||
|
The protocol is not an Internet standard but it is still widely implemented.
|
||||||
|
OpenSSH and most other implementation implement Version 3 of the protocol. We
|
||||||
|
do the same in libssh.
|
||||||
|
|
||||||
|
- <a href="http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
|
||||||
|
draft-ietf-secsh-filexfer-02.txt</a>,
|
||||||
|
SSH File Transfer Protocol
|
||||||
|
|
||||||
|
@subsection main-rfc-extensions Secure Shell Extensions
|
||||||
|
|
||||||
|
The OpenSSH project has defined some extensions to the protocol. We support some of
|
||||||
|
them like the statvfs calls in SFTP or the ssh-agent.
|
||||||
|
|
||||||
|
- <a href="http://api.libssh.org/rfc/PROTOCOL" target="_blank">
|
||||||
|
OpenSSH's deviations and extensions</a>
|
||||||
|
- <a href="http://api.libssh.org/rfc/PROTOCOL.agent" target="_blank">
|
||||||
|
OpenSSH's ssh-agent</a>
|
||||||
|
|
||||||
|
*/
|
||||||
257
doc/scp.dox
Normal file
257
doc/scp.dox
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_scp Chapter 6: The SCP subsystem
|
||||||
|
@section scp_subsystem The SCP subsystem
|
||||||
|
|
||||||
|
The SCP subsystem has far less functionnality than the SFTP subsystem.
|
||||||
|
However, if you only need to copy files from and to the remote system,
|
||||||
|
it does its job.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection scp_session Opening and closing a SCP session
|
||||||
|
|
||||||
|
Like in the SFTP subsystem, you don't handle the SSH channels directly.
|
||||||
|
Instead, you open a "SCP session".
|
||||||
|
|
||||||
|
When you open your SCP session, you have to choose between read or write mode.
|
||||||
|
You can't do both in the same session. So you specify either SSH_SCP_READ or
|
||||||
|
SSH_SCP_WRITE as the second parameter of function ssh_scp_new().
|
||||||
|
|
||||||
|
Another important mode flag for opening your SCP session is SSH_SCP_RECURSIVE.
|
||||||
|
When you use SSH_SCP_RECURSIVE, you declare that you are willing to emulate
|
||||||
|
the behaviour of "scp -r" command in your program, no matter it is for
|
||||||
|
reading or for writing.
|
||||||
|
|
||||||
|
Once your session is created, you initialize it with ssh_scp_init(). When
|
||||||
|
you have finished transferring files, you terminate the SCP connection with
|
||||||
|
ssh_scp_close(). Finally, you can dispose the SCP connection with
|
||||||
|
ssh_scp_free().
|
||||||
|
|
||||||
|
The example below does the maintenance work to open a SCP connection for writing in
|
||||||
|
recursive mode:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int scp_write(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_scp scp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
scp = ssh_scp_new
|
||||||
|
(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
|
||||||
|
if (scp == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error allocating scp session: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_scp_init(scp);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error initializing scp session: %s\n", ssh_get_error(session));
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_scp_close(scp);
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The example below shows how to open a connection to read a single file:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int scp_read(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_scp scp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
scp = ssh_scp_new
|
||||||
|
(session, SSH_SCP_READ, "helloworld/helloworld.txt");
|
||||||
|
if (scp == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error allocating scp session: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_scp_init(scp);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error initializing scp session: %s\n", ssh_get_error(session));
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_scp_close(scp);
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection scp_write Creating files and directories
|
||||||
|
|
||||||
|
You create directories with ssh_scp_push_directory(). In recursive mode,
|
||||||
|
you are placed in this directory once it is created. If the directory
|
||||||
|
already exists and if you are in recursive mode, you simply enter that
|
||||||
|
directory.
|
||||||
|
|
||||||
|
Creating files is done in two steps. First, you prepare the writing with
|
||||||
|
ssh_scp_push_file(). Then, you write the data with ssh_scp_write().
|
||||||
|
The length of the data to write must be identical between both function calls.
|
||||||
|
There's no need to "open" nor "close" the file, this is done automatically
|
||||||
|
on the remote end. If the file already exists, it is overwritten and truncated.
|
||||||
|
|
||||||
|
The following example creates a new directory named "helloworld/", then creates
|
||||||
|
a file named "helloworld.txt" in that directory:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int scp_helloworld(ssh_session session, ssh_scp scp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
const char *helloworld = "Hello, world!\n";
|
||||||
|
int length = strlen(helloworld);
|
||||||
|
|
||||||
|
rc = ssh_scp_push_directory(scp, "helloworld", S_IRWXU);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't create remote directory: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_scp_push_file
|
||||||
|
(scp, "helloworld.txt", length, S_IRUSR | S_IWUSR);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't open remote file: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_scp_write(scp, helloworld, length);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't write to remote file: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection scp_recursive_write Copying full directory trees to the remote server
|
||||||
|
|
||||||
|
Let's say you want to copy the following tree of files to the remote site:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
+-- file1
|
||||||
|
+-- B --+
|
||||||
|
| +-- file2
|
||||||
|
-- A --+
|
||||||
|
| +-- file3
|
||||||
|
+-- C --+
|
||||||
|
+-- file4
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
You would do it that way:
|
||||||
|
- open the session in recursive mode
|
||||||
|
- enter directory A
|
||||||
|
- enter its subdirectory B
|
||||||
|
- create file1 in B
|
||||||
|
- create file2 in B
|
||||||
|
- leave directory B
|
||||||
|
- enter subdirectory C
|
||||||
|
- create file3 in C
|
||||||
|
- create file4 in C
|
||||||
|
- leave directory C
|
||||||
|
- leave directory A
|
||||||
|
|
||||||
|
To leave a directory, call ssh_scp_leave_directory().
|
||||||
|
|
||||||
|
|
||||||
|
@subsection scp_read Reading files and directories
|
||||||
|
|
||||||
|
|
||||||
|
To receive files, you pull requests from the other side with ssh_scp_pull_request().
|
||||||
|
If this function returns SSH_SCP_REQUEST_NEWFILE, then you must get ready for
|
||||||
|
the reception. You can get the size of the data to receive with ssh_scp_request_get_size()
|
||||||
|
and allocate a buffer accordingly. When you are ready, you accept the request with
|
||||||
|
ssh_scp_accept_request(), then read the data with ssh_scp_read().
|
||||||
|
|
||||||
|
The following example receives a single file. The name of the file to
|
||||||
|
receive has been given earlier, when the scp session was opened:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int scp_receive(ssh_session session, ssh_scp scp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int size, mode;
|
||||||
|
char *filename, *buffer;
|
||||||
|
|
||||||
|
rc = ssh_scp_pull_request(scp);
|
||||||
|
if (rc != SSH_SCP_REQUEST_NEWFILE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error receiving information about file: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = ssh_scp_request_get_size(scp);
|
||||||
|
filename = strdup(ssh_scp_request_get_filename(scp));
|
||||||
|
mode = ssh_scp_request_get_permissions(scp);
|
||||||
|
printf("Receiving file %s, size %d, permisssions 0%o\n", filename, size, mode);
|
||||||
|
free(filename);
|
||||||
|
|
||||||
|
buffer = malloc(size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Memory allocation error\n");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_scp_accept_request(scp);
|
||||||
|
rc = ssh_scp_read(scp, buffer, size);
|
||||||
|
if (rc == SSH_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(session));
|
||||||
|
free(buffer);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
printf("Done\n");
|
||||||
|
|
||||||
|
write(1, buffer, size);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
rc = ssh_scp_pull_request(scp);
|
||||||
|
if (rc != SSH_SCP_REQUEST_EOF)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unexpected request: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
In this example, since we just requested a single file, we expect ssh_scp_request()
|
||||||
|
to return SSH_SCP_REQUEST_NEWFILE first, then SSH_SCP_REQUEST_EOF. That's quite a
|
||||||
|
naive approach; for example, the remote server might send a warning as well
|
||||||
|
(return code SSH_SCP_REQUEST_WARNING) and the example would fail. A more comprehensive
|
||||||
|
reception program would receive the requests in a loop and analyze them carefully
|
||||||
|
until SSH_SCP_REQUEST_EOF has been received.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection scp_recursive_read Receiving full directory trees from the remote server
|
||||||
|
|
||||||
|
If you opened the SCP session in recursive mode, the remote end will be
|
||||||
|
telling you when to change directory.
|
||||||
|
|
||||||
|
In that case, when ssh_scp_pull_request() answers
|
||||||
|
SSH_SCP_REQUEST_NEWDIRECTORY, you should make that local directory (if
|
||||||
|
it does not exist yet) and enter it. When ssh_scp_pull_request() answers
|
||||||
|
SSH_SCP_REQUEST_ENDDIRECTORY, you should leave the current directory.
|
||||||
|
|
||||||
|
*/
|
||||||
395
doc/sftp.dox
Normal file
395
doc/sftp.dox
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_sftp Chapter 5: The SFTP subsystem
|
||||||
|
@section sftp_subsystem The SFTP subsystem
|
||||||
|
|
||||||
|
SFTP stands for "Secure File Transfer Protocol". It enables you to safely
|
||||||
|
transfer files between the local and the remote computer. It reminds a lot
|
||||||
|
of the old FTP protocol.
|
||||||
|
|
||||||
|
SFTP is a rich protocol. It lets you do over the network almost everything
|
||||||
|
that you can do with local files:
|
||||||
|
- send files
|
||||||
|
- modify only a portion of a file
|
||||||
|
- receive files
|
||||||
|
- receive only a portion of a file
|
||||||
|
- get file owner and group
|
||||||
|
- get file permissions
|
||||||
|
- set file owner and group
|
||||||
|
- set file permissions
|
||||||
|
- remove files
|
||||||
|
- rename files
|
||||||
|
- create a directory
|
||||||
|
- remove a directory
|
||||||
|
- retrieve the list of files in a directory
|
||||||
|
- get the target of a symbolic link
|
||||||
|
- create symbolic links
|
||||||
|
- get information about mounted filesystems.
|
||||||
|
|
||||||
|
The current implemented version of the SFTP protocol is version 3. All functions
|
||||||
|
aren't implemented yet, but the most important are.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection sftp_session Opening and closing a SFTP session
|
||||||
|
|
||||||
|
Unlike with remote shells and remote commands, when you use the SFTP subsystem,
|
||||||
|
you don't handle directly the SSH channels. Instead, you open a "SFTP session".
|
||||||
|
|
||||||
|
The function sftp_new() creates a new SFTP session. The function sftp_init()
|
||||||
|
initializes it. The function sftp_free() deletes it.
|
||||||
|
|
||||||
|
As you see, all the SFTP-related functions start with the "sftp_" prefix
|
||||||
|
instead of the usual "ssh_" prefix.
|
||||||
|
|
||||||
|
The example below shows how to use these functions:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/sftp.h>
|
||||||
|
|
||||||
|
int sftp_helloworld(ssh_session session)
|
||||||
|
{
|
||||||
|
sftp_session sftp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
sftp = sftp_new(session);
|
||||||
|
if (sftp == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error allocating SFTP session: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sftp_init(sftp);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error initializing SFTP session: %s.\n", sftp_get_error(sftp));
|
||||||
|
sftp_free(sftp);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
sftp_free(sftp);
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection sftp_errors Analyzing SFTP errors
|
||||||
|
|
||||||
|
In case of a problem, the function sftp_get_error() returns a SFTP-specific
|
||||||
|
error number, in addition to the regular SSH error number returned by
|
||||||
|
ssh_get_error_number().
|
||||||
|
|
||||||
|
Possible errors are:
|
||||||
|
- SSH_FX_OK: no error
|
||||||
|
- SSH_FX_EOF: end-of-file encountered
|
||||||
|
- SSH_FX_NO_SUCH_FILE: file does not exist
|
||||||
|
- SSH_FX_PERMISSION_DENIED: permission denied
|
||||||
|
- SSH_FX_FAILURE: generic failure
|
||||||
|
- SSH_FX_BAD_MESSAGE: garbage received from server
|
||||||
|
- SSH_FX_NO_CONNECTION: no connection has been set up
|
||||||
|
- SSH_FX_CONNECTION_LOST: there was a connection, but we lost it
|
||||||
|
- SSH_FX_OP_UNSUPPORTED: operation not supported by libssh yet
|
||||||
|
- SSH_FX_INVALID_HANDLE: invalid file handle
|
||||||
|
- SSH_FX_NO_SUCH_PATH: no such file or directory path exists
|
||||||
|
- SSH_FX_FILE_ALREADY_EXISTS: an attempt to create an already existing file or directory has been made
|
||||||
|
- SSH_FX_WRITE_PROTECT: write-protected filesystem
|
||||||
|
- SSH_FX_NO_MEDIA: no media was in remote drive
|
||||||
|
|
||||||
|
|
||||||
|
@subsection sftp_mkdir Creating a directory
|
||||||
|
|
||||||
|
The function sftp_mkdir() tahes the "SFTP session" we juste created as
|
||||||
|
its first argument. It also needs the name of the file to create, and the
|
||||||
|
desired permissions. The permissions are the same as for the usual mkdir()
|
||||||
|
function. To get a comprehensive list of the available permissions, use the
|
||||||
|
"man 2 stat" command. The desired permissions are combined with the remote
|
||||||
|
user's mask to determine the effective permissions.
|
||||||
|
|
||||||
|
The code below creates a directory named "helloworld" in the current directory that
|
||||||
|
can be read and written only by its owner:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/sftp.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int sftp_helloworld(ssh_session session, sftp_session sftp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = sftp_mkdir(sftp, "helloworld", S_IRWXU);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
if (sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't create directory: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Unlike its equivalent in the SCP subsystem, this function does NOT change the
|
||||||
|
current directory to the newly created subdirectory.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection sftp_write Copying a file to the remote computer
|
||||||
|
|
||||||
|
You handle the contents of a remote file just like you would do with a
|
||||||
|
local file: you open the file in a given mode, move the file pointer in it,
|
||||||
|
read or write data, and close the file.
|
||||||
|
|
||||||
|
The sftp_open() function is very similar to the regular open() function,
|
||||||
|
excepted that it returns a file handle of type sftp_file. This file handle
|
||||||
|
is then used by the other file manipulation functions and remains valid
|
||||||
|
until you close the remote file with sftp_close().
|
||||||
|
|
||||||
|
The example below creates a new file named "helloworld.txt" in the
|
||||||
|
newly created "helloworld" directory. If the file already exists, it will
|
||||||
|
be truncated. It then writes the famous "Hello, World!" sentence to the
|
||||||
|
file, followed by a new line character. Finally, the file is closed:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/sftp.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
int sftp_helloworld(ssh_session session, sftp_session sftp)
|
||||||
|
{
|
||||||
|
int access_type = O_WRONLY | O_CREAT | O_TRUNC;
|
||||||
|
sftp_file file;
|
||||||
|
const char *helloworld = "Hello, World!\n";
|
||||||
|
int length = strlen(helloworld);
|
||||||
|
int rc, nwritten;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
file = sftp_open(sftp, "helloworld/helloworld.txt", access_type, S_IRWXU);
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't open file for writing: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nwritten = sftp_write(file, helloworld, length);
|
||||||
|
if (nwritten != length)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't write data to file: %s\n", ssh_get_error(session));
|
||||||
|
sftp_close(file);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sftp_close(file);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't close the written file: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection sftp_read Reading a file from the remote computer
|
||||||
|
|
||||||
|
The nice thing with reading a file over the network through SFTP is that it
|
||||||
|
can be done both in a synchronous way or an asynchronous way. If you read the file
|
||||||
|
asynchronously, your program can do something else while it waits for the
|
||||||
|
results to come.
|
||||||
|
|
||||||
|
Synchronous read is done with sftp_read().
|
||||||
|
|
||||||
|
The following example prints the contents of remote file "/etc/profile". For
|
||||||
|
each 1024 bytes of information read, it waits until the end of the read operation:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int sftp_read_sync(ssh_session session, sftp_session sftp)
|
||||||
|
{
|
||||||
|
int access_type;
|
||||||
|
sftp_file file;
|
||||||
|
char buffer[1024];
|
||||||
|
int nbytes, rc;
|
||||||
|
|
||||||
|
access_type = O_RDONLY;
|
||||||
|
file = sftp_open(sftp, "/etc/profile", access_type, 0);
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't open file for reading: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
||||||
|
while (nbytes > 0)
|
||||||
|
{
|
||||||
|
if (write(1, buffer, nbytes) != nbytes)
|
||||||
|
{
|
||||||
|
sftp_close(file);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error while reading file: %s\n", ssh_get_error(session));
|
||||||
|
sftp_close(file);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sftp_close(file);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't close the read file: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Asynchronous read is done in two steps, first sftp_async_read_begin(), which
|
||||||
|
returns a "request handle", and then sftp_async_read(), which uses that request handle.
|
||||||
|
If the file has been opened in nonblocking mode, then sftp_async_read()
|
||||||
|
might return SSH_AGAIN, which means that the request hasn't completed yet
|
||||||
|
and that the function should be called again later on. Otherwise,
|
||||||
|
sftp_async_read() waits for the data to come. To open a file in nonblocking mode,
|
||||||
|
call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode.
|
||||||
|
|
||||||
|
The example below reads a very big file in asynchronous, nonblocking, mode. Each
|
||||||
|
time the data are not ready yet, a counter is incrementer.
|
||||||
|
|
||||||
|
@code
|
||||||
|
int sftp_read_async(ssh_session session, sftp_session sftp)
|
||||||
|
{
|
||||||
|
int access_type;
|
||||||
|
sftp_file file;
|
||||||
|
char buffer[1024];
|
||||||
|
int async_request;
|
||||||
|
int nbytes;
|
||||||
|
long counter;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
access_type = O_RDONLY;
|
||||||
|
file = sftp_open(sftp, "some_very_big_file", access_type, 0);
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't open file for reading: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
sftp_file_set_nonblocking(file);
|
||||||
|
|
||||||
|
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
||||||
|
counter = 0L;
|
||||||
|
usleep(10000);
|
||||||
|
if (async_request >= 0)
|
||||||
|
nbytes = sftp_async_read(file, buffer, sizeof(buffer), async_request);
|
||||||
|
else nbytes = -1;
|
||||||
|
while (nbytes > 0 || nbytes == SSH_AGAIN)
|
||||||
|
{
|
||||||
|
if (nbytes > 0)
|
||||||
|
{
|
||||||
|
write(1, buffer, nbytes);
|
||||||
|
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
||||||
|
}
|
||||||
|
else counter++;
|
||||||
|
usleep(10000);
|
||||||
|
if (async_request >= 0)
|
||||||
|
nbytes = sftp_async_read(file, buffer, sizeof(buffer), async_request);
|
||||||
|
else nbytes = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error while reading file: %s\n", ssh_get_error(session));
|
||||||
|
sftp_close(file);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("The counter has reached value: %ld\n", counter);
|
||||||
|
|
||||||
|
rc = sftp_close(file);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't close the read file: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@subsection sftp_ls Listing the contents of a directory
|
||||||
|
|
||||||
|
The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(),
|
||||||
|
and sftp_closedir() enable to list the contents of a directory.
|
||||||
|
They use a new handle_type, "sftp_dir", which gives access to the
|
||||||
|
directory being read.
|
||||||
|
|
||||||
|
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
|
||||||
|
to a structure with informations about a directory entry:
|
||||||
|
- name: the name of the file or directory
|
||||||
|
- size: its size in bytes
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
sftp_readdir() might return NULL under two conditions:
|
||||||
|
- when the end of the directory has been met
|
||||||
|
- when an error occured
|
||||||
|
|
||||||
|
To tell the difference, call sftp_dir_eof().
|
||||||
|
|
||||||
|
The attributes must be freed with sftp_attributes_free() when no longer
|
||||||
|
needed.
|
||||||
|
|
||||||
|
The following example reads the contents of some remote directory:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int sftp_list_dir(ssh_session session, sftp_session sftp)
|
||||||
|
{
|
||||||
|
sftp_dir dir;
|
||||||
|
sftp_attributes attributes;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dir = sftp_opendir(sftp, "/var/log");
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Directory not opened: %s\n", ssh_get_error(session));
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Name Size Perms Owner\tGroup\n");
|
||||||
|
|
||||||
|
while ((attributes = sftp_readdir(sftp, dir)) != NULL)
|
||||||
|
{
|
||||||
|
printf("%-22s %10llu %.8o %s(%d)\t%s(%d)\n",
|
||||||
|
attributes->name,
|
||||||
|
(long long unsigned int) attributes->size,
|
||||||
|
attributes->permissions,
|
||||||
|
attributes->owner,
|
||||||
|
attributes->uid,
|
||||||
|
attributes->group,
|
||||||
|
attributes->gid);
|
||||||
|
|
||||||
|
sftp_attributes_free(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sftp_dir_eof(dir))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't list directory: %s\n", ssh_get_error(session));
|
||||||
|
sftp_closedir(dir);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sftp_closedir(dir);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't close directory: %s\n", ssh_get_error(session));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
361
doc/shell.dox
Normal file
361
doc/shell.dox
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_shell Chapter 3: Opening a remote shell
|
||||||
|
@section opening_shell Opening a remote shell
|
||||||
|
|
||||||
|
We already mentioned that a single SSH connection can be shared
|
||||||
|
between several "channels". Channels can be used for different purposes.
|
||||||
|
|
||||||
|
This chapter shows how to open one of these channels, and how to use it to
|
||||||
|
start a command interpreter on a remote computer.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection open_channel Opening and closing a channel
|
||||||
|
|
||||||
|
The ssh_channel_new() function creates a channel. It returns the channel as
|
||||||
|
a variable of type ssh_channel.
|
||||||
|
|
||||||
|
Once you have this channel, you open a SSH session that uses it with
|
||||||
|
ssh_channel_open_session().
|
||||||
|
|
||||||
|
Once you don't need the channel anymore, you can send an end-of-file
|
||||||
|
to it with ssh_channel_close(). At this point, you can destroy the channel
|
||||||
|
with ssh_channel_free().
|
||||||
|
|
||||||
|
The code sample below achieves these tasks:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int shell_session(ssh_session session)
|
||||||
|
{
|
||||||
|
ssh_channel channel;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
channel = ssh_channel_new(session);
|
||||||
|
if (channel == NULL)
|
||||||
|
return SSH_ERROR;
|
||||||
|
|
||||||
|
rc = ssh_channel_open_session(channel);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
{
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection interactive Interactive and non-interactive sessions
|
||||||
|
|
||||||
|
A "shell" is a command interpreter. It is said to be "interactive"
|
||||||
|
if there is a human user typing the commands, one after the
|
||||||
|
other. The contrary, a non-interactive shell, is similar to
|
||||||
|
the execution of commands in the background: there is no attached
|
||||||
|
terminal.
|
||||||
|
|
||||||
|
If you plan using an interactive shell, you need to create a
|
||||||
|
pseud-terminal on the remote side. A remote terminal is usually referred
|
||||||
|
to as a "pty", for "pseudo-teletype". The remote processes won't see the
|
||||||
|
difference with a real text-oriented terminal.
|
||||||
|
|
||||||
|
If needed, you request the pty with the function ssh_channel_request_pty().
|
||||||
|
Then you define its dimensions (number of rows and columns)
|
||||||
|
with ssh_channel_change_pty_size().
|
||||||
|
|
||||||
|
Be your session interactive or not, the next step is to request a
|
||||||
|
shell with ssh_channel_request_shell().
|
||||||
|
|
||||||
|
@code
|
||||||
|
int interactive_shell_session(ssh_channel channel)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_pty(channel);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_change_pty_size(channel, 80, 24);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_shell(channel);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection read_data Displaying the data sent by the remote computer
|
||||||
|
|
||||||
|
In your program, you will usually need to receive all the data "displayed"
|
||||||
|
into the remote pty. You will usually analyse, log, or display this data.
|
||||||
|
|
||||||
|
ssh_channel_read() and ssh_channel_read_nonblocking() are the simplest
|
||||||
|
way to read data from a channel. If you only need to read from a single
|
||||||
|
channel, they should be enough.
|
||||||
|
|
||||||
|
The example below shows how to wait for remote data using ssh_channel_read():
|
||||||
|
|
||||||
|
@code
|
||||||
|
int interactive_shell_session(ssh_channel channel)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char buffer[256];
|
||||||
|
int nbytes;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_pty(channel);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_change_pty_size(channel, 80, 24);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_shell(channel);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
while (ssh_channel_is_open(channel) &&
|
||||||
|
!ssh_channel_is_eof(channel))
|
||||||
|
{
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
if (nbytes < 0)
|
||||||
|
return SSH_ERROR;
|
||||||
|
|
||||||
|
if (nbytes > 0)
|
||||||
|
write(1, buffer, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Unlike ssh_channel_read(), ssh_channel_read_nonblocking() never waits for
|
||||||
|
remote data to be ready. It returns immediately.
|
||||||
|
|
||||||
|
If you plan to use ssh_channel_read_nonblocking() repeatedly in a loop,
|
||||||
|
you should use a "passive wait" function like usleep(3) in the same
|
||||||
|
loop. Otherwise, your program will consume all the CPU time, and your
|
||||||
|
computer might become unresponsive.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection write_data Sending user input to the remote computer
|
||||||
|
|
||||||
|
User's input is sent to the remote site with ssh_channel_write().
|
||||||
|
|
||||||
|
The following example shows how to combine a nonblocking read from a SSH
|
||||||
|
channel with a nonblocking read from the keyboard. The local input is then
|
||||||
|
sent to the remote computer:
|
||||||
|
|
||||||
|
@code
|
||||||
|
/* Under Linux, this function determines whether a key has been pressed.
|
||||||
|
Under Windows, it is a standard function, so you need not redefine it.
|
||||||
|
*/
|
||||||
|
int kbhit()
|
||||||
|
{
|
||||||
|
struct timeval tv = { 0L, 0L };
|
||||||
|
fd_set fds;
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(0, &fds);
|
||||||
|
|
||||||
|
return select(1, &fds, NULL, NULL, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A very simple terminal emulator:
|
||||||
|
- print data received from the remote computer
|
||||||
|
- send keyboard input to the remote computer
|
||||||
|
*/
|
||||||
|
int interactive_shell_session(ssh_channel channel)
|
||||||
|
{
|
||||||
|
/* Session and terminal initialization skipped */
|
||||||
|
...
|
||||||
|
|
||||||
|
char buffer[256];
|
||||||
|
int nbytes, nwritten;
|
||||||
|
|
||||||
|
while (ssh_channel_is_open(channel) &&
|
||||||
|
!ssh_channel_is_eof(channel))
|
||||||
|
{
|
||||||
|
nbytes = ssh_channel_read_nonblocking(channel, buffer, sizeof(buffer), 0);
|
||||||
|
if (nbytes < 0) return SSH_ERROR;
|
||||||
|
if (nbytes > 0)
|
||||||
|
{
|
||||||
|
nwritten = write(1, buffer, nbytes);
|
||||||
|
if (nwritten != nbytes) return SSH_ERROR;
|
||||||
|
|
||||||
|
if (!kbhit())
|
||||||
|
{
|
||||||
|
usleep(50000L); // 0.05 second
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes = read(0, buffer, sizeof(buffer));
|
||||||
|
if (nbytes < 0) return SSH_ERROR;
|
||||||
|
if (nbytes > 0)
|
||||||
|
{
|
||||||
|
nwritten = ssh_channel_write(channel, buffer, nbytes);
|
||||||
|
if (nwritten != nbytes) return SSH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Of course, this is a poor terminal emulator, since the echo from the keys
|
||||||
|
pressed should not be done locally, but should be done by the remote side.
|
||||||
|
Also, user's input should not be sent once "Enter" key is pressed, but
|
||||||
|
immediately after each key is pressed. This can be accomplished
|
||||||
|
by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
|
||||||
|
cfmakeraw() is a standard function under Linux, on other systems you can
|
||||||
|
recode it with:
|
||||||
|
|
||||||
|
@code
|
||||||
|
static void cfmakeraw(struct termios *termios_p)
|
||||||
|
{
|
||||||
|
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||||
|
termios_p->c_oflag &= ~OPOST;
|
||||||
|
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||||
|
termios_p->c_cflag &= ~(CSIZE|PARENB);
|
||||||
|
termios_p->c_cflag |= CS8;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If you are not using a local terminal, but some kind of graphical
|
||||||
|
environment, the solution to this kind of "echo" problems will be different.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection select_loop A more elaborate way to get the remote data
|
||||||
|
|
||||||
|
*** Warning: ssh_select() and ssh_channel_select() are not relevant anymore,
|
||||||
|
since libssh is about to provide an easier system for asynchronous
|
||||||
|
communications. This subsection should be removed then. ***
|
||||||
|
|
||||||
|
ssh_channel_read() and ssh_channel_read_nonblocking() functions are simple,
|
||||||
|
but they are not adapted when you expect data from more than one SSH channel,
|
||||||
|
or from other file descriptors. Last example showed how getting data from
|
||||||
|
the standard input (the keyboard) at the same time as data from the SSH
|
||||||
|
channel was complicated. The functions ssh_select() and ssh_channel_select()
|
||||||
|
provide a more elegant way to wait for data coming from many sources.
|
||||||
|
|
||||||
|
The functions ssh_select() and ssh_channel_select() remind of the standard
|
||||||
|
UNIX select(2) function. The idea is to wait for "something" to happen:
|
||||||
|
incoming data to be read, outcoming data to block, or an exception to
|
||||||
|
occur. Both these functions do a "passive wait", i.e. you can safely use
|
||||||
|
them repeatedly in a loop, it will not consume exaggerate processor time
|
||||||
|
and make your computer unresponsive. It is quite common to use these
|
||||||
|
functions in your application's main loop.
|
||||||
|
|
||||||
|
The difference between ssh_select() and ssh_channel_select() is that
|
||||||
|
ssh_channel_select() is simpler, but allows you only to watch SSH channels.
|
||||||
|
ssh_select() is more complete and enables watching regular file descriptors
|
||||||
|
as well, in the same function call.
|
||||||
|
|
||||||
|
Below is an example of a function that waits both for remote SSH data to come,
|
||||||
|
as well as standard input from the keyboard:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int interactive_shell_session(ssh_session session, ssh_channel channel)
|
||||||
|
{
|
||||||
|
/* Session and terminal initialization skipped */
|
||||||
|
...
|
||||||
|
|
||||||
|
char buffer[256];
|
||||||
|
int nbytes, nwritten;
|
||||||
|
|
||||||
|
while (ssh_channel_is_open(channel) &&
|
||||||
|
!ssh_channel_is_eof(channel))
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
ssh_channel in_channels[2], out_channels[2];
|
||||||
|
fd_set fds;
|
||||||
|
int maxfd;
|
||||||
|
|
||||||
|
timeout.tv_sec = 30;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
in_channels[0] = channel;
|
||||||
|
in_channels[1] = NULL;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(0, &fds);
|
||||||
|
FD_SET(ssh_get_fd(session), &fds);
|
||||||
|
maxfd = ssh_get_fd(session) + 1;
|
||||||
|
|
||||||
|
ssh_select(in_channels, out_channels, maxfd, &fds, &timeout);
|
||||||
|
|
||||||
|
if (out_channels[0] != NULL)
|
||||||
|
{
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
if (nbytes < 0) return SSH_ERROR;
|
||||||
|
if (nbytes > 0)
|
||||||
|
{
|
||||||
|
nwritten = write(1, buffer, nbytes);
|
||||||
|
if (nwritten != nbytes) return SSH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(0, &fds))
|
||||||
|
{
|
||||||
|
nbytes = read(0, buffer, sizeof(buffer));
|
||||||
|
if (nbytes < 0) return SSH_ERROR;
|
||||||
|
if (nbytes > 0)
|
||||||
|
{
|
||||||
|
nwritten = ssh_channel_write(channel, buffer, nbytes);
|
||||||
|
if (nbytes != nwritten) return SSH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection x11 Using graphical applications on the remote side
|
||||||
|
|
||||||
|
If your remote application is graphical, you can forward the X11 protocol to
|
||||||
|
your local computer.
|
||||||
|
|
||||||
|
To do that, you first declare that you accept X11 connections with
|
||||||
|
ssh_channel_accept_x11(). Then you create the forwarding tunnel for
|
||||||
|
the X11 protocol with ssh_channel_request_x11().
|
||||||
|
|
||||||
|
The following code performs channel initialization and shell session
|
||||||
|
opening, and handles a parallel X11 connection:
|
||||||
|
|
||||||
|
@code
|
||||||
|
int interactive_shell_session(ssh_channel channel)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
ssh_channel x11channel;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_pty(channel);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_change_pty_size(channel, 80, 24);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_x11(channel, 0, NULL, NULL, 0);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
rc = ssh_channel_request_shell(channel);
|
||||||
|
if (rc != SSH_OK) return rc;
|
||||||
|
|
||||||
|
/* Read the data sent by the remote computer here */
|
||||||
|
...
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Don't forget to set the $DISPLAY environment variable on the remote
|
||||||
|
side, or the remote applications won't try using the X11 tunnel:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ export DISPLAY=:0
|
||||||
|
$ xclock &
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
184
doc/style.css
184
doc/style.css
@@ -1,184 +0,0 @@
|
|||||||
|
|
||||||
body {
|
|
||||||
background-color:#ddf;
|
|
||||||
/*background-image:url(../back6.jpg);*/
|
|
||||||
margin:10px 10px 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:80%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-align:left;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:100%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-align:left;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:80%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-align:left;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:80%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-align:left;
|
|
||||||
margin-left:0px;
|
|
||||||
margin-right:0px;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:80%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-align:left;
|
|
||||||
margin-left:0px;
|
|
||||||
margin-right:0px;
|
|
||||||
}
|
|
||||||
a:link {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:100%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-decoration:underline;
|
|
||||||
}
|
|
||||||
a:visited {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:100%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-decoration:underline;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:100%;
|
|
||||||
color:black;
|
|
||||||
background-color:transparent;
|
|
||||||
text-decoration:underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-color:transparent;
|
|
||||||
border-style:solid;
|
|
||||||
border-width:1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
font-family:verdana, sans-serif;
|
|
||||||
font-size:80%;
|
|
||||||
color:black;
|
|
||||||
text-align:left;
|
|
||||||
background-color:transparent;
|
|
||||||
border-color:transparent;
|
|
||||||
border-style:solid;
|
|
||||||
border-width:1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tout {
|
|
||||||
margin: 5px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 2px solid #aac;
|
|
||||||
background: #eef;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prot {
|
|
||||||
border-style:solid;
|
|
||||||
border-width:2px;
|
|
||||||
border-color:#88F;
|
|
||||||
padding: 4px;
|
|
||||||
background-color:#cce;
|
|
||||||
margin: 5px 5px 5px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ex {
|
|
||||||
border-style:solid;
|
|
||||||
border-width:2px;
|
|
||||||
border-color:#aaF;
|
|
||||||
padding: 4px;
|
|
||||||
background-color:#dde;
|
|
||||||
margin: 5px 5px 5px 5px;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
border-style:solid;
|
|
||||||
border-width:3px;
|
|
||||||
border-color:#66F;
|
|
||||||
padding: 4px;
|
|
||||||
background-color:#aac;
|
|
||||||
margin: 15px 5px 20px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#titre {
|
|
||||||
margin: 5px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 5px solid #aac;
|
|
||||||
background: #eef;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gauche {
|
|
||||||
float:left;
|
|
||||||
margin: 5px;
|
|
||||||
padding: 4px;
|
|
||||||
border: 5px solid #aac;
|
|
||||||
background: #bbf;
|
|
||||||
width: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#droite {
|
|
||||||
position: relative;
|
|
||||||
top:5px;
|
|
||||||
left:165px;
|
|
||||||
margin: 5px 170px 5px 5px;
|
|
||||||
padding: 10px;
|
|
||||||
border: 5px solid #aac;
|
|
||||||
background: #bbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* boutons */
|
|
||||||
|
|
||||||
a.bouton:link{
|
|
||||||
width:128px;
|
|
||||||
height:34px;
|
|
||||||
text-decoration:none;
|
|
||||||
color:#aaa;
|
|
||||||
text-align:center;
|
|
||||||
font-weight:bold;
|
|
||||||
/*background-color:#444;*/
|
|
||||||
background-image:url(noclicked.png);
|
|
||||||
}
|
|
||||||
|
|
||||||
a.bouton:visited{
|
|
||||||
width:128px;
|
|
||||||
height:34px;
|
|
||||||
text-decoration:none;
|
|
||||||
color:#aaa;
|
|
||||||
text-align:center;
|
|
||||||
font-weight:bold;
|
|
||||||
/*background-color:#444;*/
|
|
||||||
background-image:url(noclicked.png);
|
|
||||||
}
|
|
||||||
|
|
||||||
a.bouton:hover{
|
|
||||||
width:128px;
|
|
||||||
height:34px;
|
|
||||||
text-decoration:none;
|
|
||||||
color:white;
|
|
||||||
text-align:center;
|
|
||||||
font-weight:bold;
|
|
||||||
/*background-color:#888;*/
|
|
||||||
background-image:url(clicked.png);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bouton{
|
|
||||||
text-align:center;
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
14
doc/tbd.dox
Normal file
14
doc/tbd.dox
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_todo To be done
|
||||||
|
|
||||||
|
*** To be written ***
|
||||||
|
|
||||||
|
@section sshd Writing a libssh-based server
|
||||||
|
|
||||||
|
*** To be written ***
|
||||||
|
|
||||||
|
@section cpp The libssh C++ wrapper
|
||||||
|
|
||||||
|
*** To be written ***
|
||||||
|
|
||||||
|
*/
|
||||||
65
doc/threading.dox
Normal file
65
doc/threading.dox
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
@page libssh_tutor_threads Chapter 8: Threads with libssh
|
||||||
|
@section threads_with_libssh How to use libssh with threads
|
||||||
|
|
||||||
|
libssh may be used in multithreaded applications, but under several conditions :
|
||||||
|
- Threading must be initialized during the initialization of libssh. This
|
||||||
|
initialization must be done outside of any threading context.
|
||||||
|
- If pthreads is being used by your application (or your framework's backend),
|
||||||
|
you must link with libssh_threads_pthread dynamic library and initialize
|
||||||
|
threading with the ssh_threads_pthreads threading object.
|
||||||
|
- If an other threading library is being used by your application, you must
|
||||||
|
implement all the methods of the ssh_threads_callbacks_struct structure
|
||||||
|
and initialize libssh with it.
|
||||||
|
- At all times, you may use different sessions inside threads, make parallel
|
||||||
|
connections, read/write on different sessions and so on. You can use a
|
||||||
|
single session in several channels at the same time. This will lead to
|
||||||
|
internal state corruption. This limitation is being worked out and will
|
||||||
|
maybe disappear later.
|
||||||
|
|
||||||
|
@subsection threads_init Initialization of threads
|
||||||
|
|
||||||
|
To initialize threading, you must first select the threading model you want to
|
||||||
|
use, using ssh_threads_set_callbacks(), then call ssh_init().
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/callbacks.h>
|
||||||
|
...
|
||||||
|
ssh_threads_set_callbacks(ssh_threads_noop);
|
||||||
|
ssh_init();
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
ssh_threads_noop is the threading structure that does nothing. It's the
|
||||||
|
threading callbacks being used by default when you're not using threading.
|
||||||
|
|
||||||
|
@subsection threads_pthread Using libpthread with libssh
|
||||||
|
|
||||||
|
If your application is using libpthread, you may simply use the libpthread
|
||||||
|
threading backend:
|
||||||
|
|
||||||
|
@code
|
||||||
|
#include <libssh/callbacks.h>
|
||||||
|
...
|
||||||
|
ssh_threads_set_callbacks(ssh_threads_pthread);
|
||||||
|
ssh_init();
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
However, you must be sure to link with the library ssh_threads_pthread. If
|
||||||
|
you're using gcc, you must use the commandline
|
||||||
|
@code
|
||||||
|
gcc -o output input.c -lssh -lssh_threads_pthread
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsection threads_other Using another threading library
|
||||||
|
|
||||||
|
You must find your way in the ssh_threads_callbacks_struct structure. You must
|
||||||
|
implement the following methods :
|
||||||
|
- mutex_lock
|
||||||
|
- mutex_unlock
|
||||||
|
- mutex_init
|
||||||
|
- mutex_destroy
|
||||||
|
- thread_id
|
||||||
|
|
||||||
|
Good luck !
|
||||||
|
*/
|
||||||
48
examples/CMakeLists.txt
Normal file
48
examples/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
project(libssh-examples C CXX)
|
||||||
|
|
||||||
|
set(examples_SRCS
|
||||||
|
authentication.c
|
||||||
|
knownhosts.c
|
||||||
|
connect_ssh.c
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||||
|
${CMAKE_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (LINUX)
|
||||||
|
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
||||||
|
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
add_executable(scp_download scp_download.c ${examples_SRCS})
|
||||||
|
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
add_executable(samplessh sample.c ${examples_SRCS})
|
||||||
|
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
||||||
|
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
if (WITH_SFTP)
|
||||||
|
add_executable(samplesftp samplesftp.c ${examples_SRCS})
|
||||||
|
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
endif (WITH_SFTP)
|
||||||
|
|
||||||
|
if (WITH_SERVER)
|
||||||
|
add_executable(samplesshd samplesshd.c)
|
||||||
|
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
endif (WITH_SERVER)
|
||||||
|
endif (LINUX)
|
||||||
|
|
||||||
|
add_executable(exec exec.c ${examples_SRCS})
|
||||||
|
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
add_executable(senddata senddata.c ${examples_SRCS})
|
||||||
|
target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
add_executable(libsshpp libsshpp.cpp)
|
||||||
|
target_link_libraries(libsshpp ${LIBSSH_SHARED_LIBRARY})
|
||||||
|
|
||||||
|
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
|
||||||
|
target_link_libraries(libsshpp_noexcept ${LIBSSH_SHARED_LIBRARY})
|
||||||
164
examples/authentication.c
Normal file
164
examples/authentication.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* authentication.c
|
||||||
|
* This file contains an example of how to do an authentication to a
|
||||||
|
* SSH server using libssh
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2003-2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
|
||||||
|
int authenticate_kbdint(ssh_session session, const char *password) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = ssh_userauth_kbdint(session, NULL, NULL);
|
||||||
|
while (err == SSH_AUTH_INFO) {
|
||||||
|
const char *instruction;
|
||||||
|
const char *name;
|
||||||
|
char buffer[128];
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
name = ssh_userauth_kbdint_getname(session);
|
||||||
|
instruction = ssh_userauth_kbdint_getinstruction(session);
|
||||||
|
n = ssh_userauth_kbdint_getnprompts(session);
|
||||||
|
|
||||||
|
if (name && strlen(name) > 0) {
|
||||||
|
printf("%s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instruction && strlen(instruction) > 0) {
|
||||||
|
printf("%s\n", instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
const char *answer;
|
||||||
|
const char *prompt;
|
||||||
|
char echo;
|
||||||
|
|
||||||
|
prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
|
||||||
|
if (prompt == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (echo) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
printf("%s", prompt);
|
||||||
|
|
||||||
|
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[sizeof(buffer) - 1] = '\0';
|
||||||
|
if ((p = strchr(buffer, '\n'))) {
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh_userauth_kbdint_setanswer(session, i, buffer) < 0) {
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0, strlen(buffer));
|
||||||
|
} else {
|
||||||
|
if (password && strstr(prompt, "Password:")) {
|
||||||
|
answer = password;
|
||||||
|
} else {
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
|
if (ssh_getpass(prompt, buffer, sizeof(buffer), 0, 0) < 0) {
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
answer = buffer;
|
||||||
|
}
|
||||||
|
if (ssh_userauth_kbdint_setanswer(session, i, answer) < 0) {
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err=ssh_userauth_kbdint(session,NULL,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error(ssh_session session){
|
||||||
|
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
int authenticate_console(ssh_session session){
|
||||||
|
int rc;
|
||||||
|
int method;
|
||||||
|
char password[128] = {0};
|
||||||
|
char *banner;
|
||||||
|
|
||||||
|
// Try to authenticate
|
||||||
|
rc = ssh_userauth_none(session, NULL);
|
||||||
|
if (rc == SSH_AUTH_ERROR) {
|
||||||
|
error(session);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
method = ssh_auth_list(session);
|
||||||
|
while (rc != SSH_AUTH_SUCCESS) {
|
||||||
|
// Try to authenticate with public key first
|
||||||
|
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
|
||||||
|
rc = ssh_userauth_autopubkey(session, NULL);
|
||||||
|
if (rc == SSH_AUTH_ERROR) {
|
||||||
|
error(session);
|
||||||
|
return rc;
|
||||||
|
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to authenticate with keyboard interactive";
|
||||||
|
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
|
||||||
|
rc = authenticate_kbdint(session, NULL);
|
||||||
|
if (rc == SSH_AUTH_ERROR) {
|
||||||
|
error(session);
|
||||||
|
return rc;
|
||||||
|
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to authenticate with password
|
||||||
|
if (method & SSH_AUTH_METHOD_PASSWORD) {
|
||||||
|
rc = ssh_userauth_password(session, NULL, password);
|
||||||
|
if (rc == SSH_AUTH_ERROR) {
|
||||||
|
error(session);
|
||||||
|
return rc;
|
||||||
|
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
banner = ssh_get_issue_banner(session);
|
||||||
|
if (banner) {
|
||||||
|
printf("%s\n",banner);
|
||||||
|
ssh_string_free_char(banner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
67
examples/connect_ssh.c
Normal file
67
examples/connect_ssh.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* connect_ssh.c
|
||||||
|
* This file contains an example of how to connect to a
|
||||||
|
* SSH server using libssh
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
ssh_session connect_ssh(const char *host, const char *user,int verbosity){
|
||||||
|
ssh_session session;
|
||||||
|
int auth=0;
|
||||||
|
|
||||||
|
session=ssh_new();
|
||||||
|
if (session == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user != NULL){
|
||||||
|
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
|
||||||
|
ssh_free(session);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
|
||||||
|
ssh_free(session);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||||
|
if(ssh_connect(session)){
|
||||||
|
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(verify_knownhost(session)<0){
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
auth=authenticate_console(session);
|
||||||
|
if(auth==SSH_AUTH_SUCCESS){
|
||||||
|
return session;
|
||||||
|
} else if(auth==SSH_AUTH_DENIED){
|
||||||
|
fprintf(stderr,"Authentication failed\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"Error while authenticating : %s\n",ssh_get_error(session));
|
||||||
|
}
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
22
examples/examples_common.h
Normal file
22
examples/examples_common.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
#ifndef EXAMPLES_COMMON_H_
|
||||||
|
#define EXAMPLES_COMMON_H_
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
int authenticate_console(ssh_session session);
|
||||||
|
int authenticate_kbdint(ssh_session session, const char *password);
|
||||||
|
int verify_knownhost(ssh_session session);
|
||||||
|
ssh_session connect_ssh(const char *hostname, const char *user, int verbosity);
|
||||||
|
|
||||||
|
#endif /* EXAMPLES_COMMON_H_ */
|
||||||
66
examples/exec.c
Normal file
66
examples/exec.c
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* simple exec example */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
ssh_session session;
|
||||||
|
ssh_channel channel;
|
||||||
|
char buffer[256];
|
||||||
|
int nbytes;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
session = connect_ssh("localhost", NULL, 0);
|
||||||
|
if (session == NULL) {
|
||||||
|
ssh_finalize();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = ssh_channel_new(session);;
|
||||||
|
if (channel == NULL) {
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
ssh_finalize();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_channel_open_session(channel);
|
||||||
|
if (rc < 0) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_channel_request_exec(channel, "lsof");
|
||||||
|
if (rc < 0) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
while (nbytes > 0) {
|
||||||
|
if (fwrite(buffer, 1, nbytes, stdout) != (unsigned int) nbytes) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes < 0) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
ssh_finalize();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
failed:
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
ssh_finalize();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
98
examples/knownhosts.c
Normal file
98
examples/knownhosts.c
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* knownhosts.c
|
||||||
|
* This file contains an example of how verify the identity of a
|
||||||
|
* SSH server using libssh
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2003-2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int verify_knownhost(ssh_session session){
|
||||||
|
char *hexa;
|
||||||
|
int state;
|
||||||
|
char buf[10];
|
||||||
|
unsigned char *hash = NULL;
|
||||||
|
int hlen;
|
||||||
|
|
||||||
|
state=ssh_is_server_known(session);
|
||||||
|
|
||||||
|
hlen = ssh_get_pubkey_hash(session, &hash);
|
||||||
|
if (hlen < 0) {
|
||||||
|
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_print_hexa("Public key hash",hash, hlen);
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||||
|
return -1;
|
||||||
|
case SSH_SERVER_FOUND_OTHER:
|
||||||
|
fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
|
||||||
|
fprintf(stderr,"An attacker might change the default server key to confuse your client"
|
||||||
|
"into thinking the key does not exist\n"
|
||||||
|
"We advise you to rerun the client with -d or -r for more safety.\n");
|
||||||
|
return -1;
|
||||||
|
case SSH_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 behavior */
|
||||||
|
case SSH_SERVER_NOT_KNOWN:
|
||||||
|
hexa = ssh_get_hexa(hash, hlen);
|
||||||
|
fprintf(stderr,"The server is unknown. Do you trust the host key ?\n");
|
||||||
|
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||||
|
ssh_string_free_char(hexa);
|
||||||
|
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(strncasecmp(buf,"yes",3)!=0){
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
|
||||||
|
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(strncasecmp(buf,"yes",3)==0){
|
||||||
|
if (ssh_write_knownhost(session) < 0) {
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
fprintf(stderr, "error %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSH_SERVER_ERROR:
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
fprintf(stderr,"%s",ssh_get_error(session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
304
examples/libssh_scp.c
Normal file
304
examples/libssh_scp.c
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
/* libssh_scp.c
|
||||||
|
* Sample implementation of a SCP client
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
|
||||||
|
char **sources;
|
||||||
|
int nsources;
|
||||||
|
char *destination;
|
||||||
|
int verbosity=0;
|
||||||
|
|
||||||
|
struct location {
|
||||||
|
int is_ssh;
|
||||||
|
char *user;
|
||||||
|
char *host;
|
||||||
|
char *path;
|
||||||
|
ssh_session session;
|
||||||
|
ssh_scp scp;
|
||||||
|
FILE *file;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
READ,
|
||||||
|
WRITE
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usage(const char *argv0){
|
||||||
|
fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n"
|
||||||
|
" [[user@]host2:]destination\n"
|
||||||
|
"sample scp client - libssh-%s\n",
|
||||||
|
// "Options :\n",
|
||||||
|
// " -r : use RSA to verify host public key\n",
|
||||||
|
argv0,
|
||||||
|
ssh_version(0));
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opts(int argc, char **argv){
|
||||||
|
int i;
|
||||||
|
while((i=getopt(argc,argv,"v"))!=-1){
|
||||||
|
switch(i){
|
||||||
|
case 'v':
|
||||||
|
verbosity++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"unknown option %c\n",optopt);
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nsources=argc-optind-1;
|
||||||
|
if(nsources < 1){
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sources=malloc((nsources + 1) * sizeof(char *));
|
||||||
|
if(sources == NULL)
|
||||||
|
return -1;
|
||||||
|
for(i=0;i<nsources;++i){
|
||||||
|
sources[i] = argv[optind];
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
sources[i]=NULL;
|
||||||
|
destination=argv[optind];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct location *parse_location(char *loc){
|
||||||
|
struct location *location=malloc(sizeof(struct location));
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
location->host=location->user=NULL;
|
||||||
|
ptr=strchr(loc,':');
|
||||||
|
if(ptr != NULL){
|
||||||
|
location->is_ssh=1;
|
||||||
|
location->path=strdup(ptr+1);
|
||||||
|
*ptr='\0';
|
||||||
|
ptr=strchr(loc,'@');
|
||||||
|
if(ptr != NULL){
|
||||||
|
location->host=strdup(ptr+1);
|
||||||
|
*ptr='\0';
|
||||||
|
location->user=strdup(loc);
|
||||||
|
} else {
|
||||||
|
location->host=strdup(loc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
location->is_ssh=0;
|
||||||
|
location->path=strdup(loc);
|
||||||
|
}
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_location(struct location *loc, int flag){
|
||||||
|
if(loc->is_ssh && flag==WRITE){
|
||||||
|
loc->session=connect_ssh(loc->host,loc->user,verbosity);
|
||||||
|
if(!loc->session){
|
||||||
|
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path);
|
||||||
|
if(!loc->scp){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(ssh_scp_init(loc->scp)==SSH_ERROR){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
ssh_scp_free(loc->scp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else if(loc->is_ssh && flag==READ){
|
||||||
|
loc->session=connect_ssh(loc->host, loc->user,verbosity);
|
||||||
|
if(!loc->session){
|
||||||
|
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path);
|
||||||
|
if(!loc->scp){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(ssh_scp_init(loc->scp)==SSH_ERROR){
|
||||||
|
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
|
||||||
|
ssh_scp_free(loc->scp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
loc->file=fopen(loc->path,flag==READ ? "r":"w");
|
||||||
|
if(!loc->file){
|
||||||
|
if(errno==EISDIR){
|
||||||
|
if(chdir(loc->path)){
|
||||||
|
fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief copies files from source location to destination
|
||||||
|
* @param src source location
|
||||||
|
* @param dest destination location
|
||||||
|
* @param recursive Copy also directories
|
||||||
|
*/
|
||||||
|
static int do_copy(struct location *src, struct location *dest, int recursive){
|
||||||
|
int size;
|
||||||
|
socket_t fd;
|
||||||
|
struct stat s;
|
||||||
|
int w,r;
|
||||||
|
char buffer[16384];
|
||||||
|
int total=0;
|
||||||
|
int mode;
|
||||||
|
char *filename;
|
||||||
|
/* recursive mode doesn't work yet */
|
||||||
|
(void)recursive;
|
||||||
|
/* Get the file name and size*/
|
||||||
|
if(!src->is_ssh){
|
||||||
|
fd=fileno(src->file);
|
||||||
|
fstat(fd,&s);
|
||||||
|
size=s.st_size;
|
||||||
|
mode = s.st_mode & ~S_IFMT;
|
||||||
|
filename=ssh_basename(src->path);
|
||||||
|
} else {
|
||||||
|
size=0;
|
||||||
|
do {
|
||||||
|
r=ssh_scp_pull_request(src->scp);
|
||||||
|
if(r==SSH_SCP_REQUEST_NEWDIR){
|
||||||
|
ssh_scp_deny_request(src->scp,"Not in recursive mode");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(r==SSH_SCP_REQUEST_NEWFILE){
|
||||||
|
size=ssh_scp_request_get_size(src->scp);
|
||||||
|
filename=strdup(ssh_scp_request_get_filename(src->scp));
|
||||||
|
mode=ssh_scp_request_get_permissions(src->scp);
|
||||||
|
//ssh_scp_accept_request(src->scp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while(r != SSH_SCP_REQUEST_NEWFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dest->is_ssh){
|
||||||
|
r=ssh_scp_push_file(dest->scp,src->path, size, mode);
|
||||||
|
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
|
||||||
|
ssh_scp_free(dest->scp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!dest->file){
|
||||||
|
dest->file=fopen(filename,"w");
|
||||||
|
if(!dest->file){
|
||||||
|
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
|
||||||
|
if(src->is_ssh)
|
||||||
|
ssh_scp_deny_request(src->scp,"Cannot open local file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(src->is_ssh){
|
||||||
|
ssh_scp_accept_request(src->scp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if(src->is_ssh){
|
||||||
|
r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(r==0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
r=fread(buffer,1,sizeof(buffer),src->file);
|
||||||
|
if(r==0)
|
||||||
|
break;
|
||||||
|
if(r<0){
|
||||||
|
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dest->is_ssh){
|
||||||
|
w=ssh_scp_write(dest->scp,buffer,r);
|
||||||
|
if(w == SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
|
||||||
|
ssh_scp_free(dest->scp);
|
||||||
|
dest->scp=NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w=fwrite(buffer,r,1,dest->file);
|
||||||
|
if(w<=0){
|
||||||
|
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total+=r;
|
||||||
|
|
||||||
|
} while(total < size);
|
||||||
|
printf("wrote %d bytes\n",total);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
struct location *dest, *src;
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
if(opts(argc,argv)<0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
dest=parse_location(destination);
|
||||||
|
if(open_location(dest,WRITE)<0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
for(i=0;i<nsources;++i){
|
||||||
|
src=parse_location(sources[i]);
|
||||||
|
if(open_location(src,READ)<0){
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if(do_copy(src,dest,0) < 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dest->is_ssh){
|
||||||
|
r=ssh_scp_close(dest->scp);
|
||||||
|
if(r == SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
|
||||||
|
ssh_scp_free(dest->scp);
|
||||||
|
dest->scp=NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fclose(dest->file);
|
||||||
|
dest->file=NULL;
|
||||||
|
}
|
||||||
|
ssh_disconnect(dest->session);
|
||||||
|
ssh_finalize();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
33
examples/libsshpp.cpp
Normal file
33
examples/libsshpp.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file demonstrates the use of the C++ wrapper to libssh */
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <libssh/libsshpp.hpp>
|
||||||
|
|
||||||
|
int main(int argc, const char **argv){
|
||||||
|
ssh::Session session;
|
||||||
|
try {
|
||||||
|
if(argc>1)
|
||||||
|
session.setOption(SSH_OPTIONS_HOST,argv[1]);
|
||||||
|
else
|
||||||
|
session.setOption(SSH_OPTIONS_HOST,"localhost");
|
||||||
|
session.connect();
|
||||||
|
session.userauthAutopubkey();
|
||||||
|
session.disconnect();
|
||||||
|
} catch (ssh::SshException e){
|
||||||
|
std::cout << "Error during connection : ";
|
||||||
|
std::cout << e.getError() << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
41
examples/libsshpp_noexcept.cpp
Normal file
41
examples/libsshpp_noexcept.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file demonstrates the use of the C++ wrapper to libssh
|
||||||
|
* specifically, without C++ exceptions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#define SSH_NO_CPP_EXCEPTIONS
|
||||||
|
#include <libssh/libsshpp.hpp>
|
||||||
|
|
||||||
|
int main(int argc, const char **argv){
|
||||||
|
ssh::Session session,s2;
|
||||||
|
int err;
|
||||||
|
if(argc>1)
|
||||||
|
err=session.setOption(SSH_OPTIONS_HOST,argv[1]);
|
||||||
|
else
|
||||||
|
err=session.setOption(SSH_OPTIONS_HOST,"localhost");
|
||||||
|
if(err==SSH_ERROR)
|
||||||
|
goto error;
|
||||||
|
err=session.connect();
|
||||||
|
if(err==SSH_ERROR)
|
||||||
|
goto error;
|
||||||
|
err=session.userauthAutopubkey();
|
||||||
|
if(err==SSH_ERROR)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
std::cout << "Error during connection : ";
|
||||||
|
std::cout << session.getError() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
538
examples/sample.c
Normal file
538
examples/sample.c
Normal file
@@ -0,0 +1,538 @@
|
|||||||
|
/* client.c */
|
||||||
|
/*
|
||||||
|
Copyright 2003-2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#ifdef HAVE_PTY_H
|
||||||
|
#include <pty.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libssh/callbacks.h>
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <libssh/sftp.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "examples_common.h"
|
||||||
|
#define MAXCMD 10
|
||||||
|
char *host;
|
||||||
|
char *user;
|
||||||
|
char *cmds[MAXCMD];
|
||||||
|
struct termios terminal;
|
||||||
|
|
||||||
|
char *pcap_file=NULL;
|
||||||
|
|
||||||
|
char *proxycommand;
|
||||||
|
|
||||||
|
static int auth_callback(const char *prompt, char *buf, size_t len,
|
||||||
|
int echo, int verify, void *userdata) {
|
||||||
|
char *answer = NULL;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
(void) verify;
|
||||||
|
(void) userdata;
|
||||||
|
|
||||||
|
if (echo) {
|
||||||
|
while ((answer = fgets(buf, len, stdin)) == NULL);
|
||||||
|
if ((ptr = strchr(buf, '\n'))) {
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ssh_getpass(prompt, buf, len, 0, 0) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (answer == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(buf, answer, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ssh_callbacks_struct cb = {
|
||||||
|
.auth_function=auth_callback,
|
||||||
|
.userdata=NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void add_cmd(char *cmd){
|
||||||
|
int n;
|
||||||
|
for(n=0;cmds[n] && (n<MAXCMD);n++);
|
||||||
|
if(n==MAXCMD)
|
||||||
|
return;
|
||||||
|
cmds[n]=strdup(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
" -P file : create a pcap debugging file\n"
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN32
|
||||||
|
" -T proxycommand : command to execute as a socket proxy\n"
|
||||||
|
#endif
|
||||||
|
,
|
||||||
|
ssh_version(0));
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opts(int argc, char **argv){
|
||||||
|
int i;
|
||||||
|
// for(i=0;i<argc;i++)
|
||||||
|
// printf("%d : %s\n",i,argv[i]);
|
||||||
|
/* insert your own arguments here */
|
||||||
|
while((i=getopt(argc,argv,"T:P:"))!=-1){
|
||||||
|
switch(i){
|
||||||
|
case 'P':
|
||||||
|
pcap_file=optarg;
|
||||||
|
break;
|
||||||
|
#ifndef _WIN32
|
||||||
|
case 'T':
|
||||||
|
proxycommand=optarg;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"unknown option %c\n",optopt);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(optind < argc)
|
||||||
|
host=argv[optind++];
|
||||||
|
while(optind < argc)
|
||||||
|
add_cmd(argv[optind++]);
|
||||||
|
if(host==NULL)
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_CFMAKERAW
|
||||||
|
static void cfmakeraw(struct termios *termios_p){
|
||||||
|
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||||
|
termios_p->c_oflag &= ~OPOST;
|
||||||
|
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||||
|
termios_p->c_cflag &= ~(CSIZE|PARENB);
|
||||||
|
termios_p->c_cflag |= CS8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void do_cleanup(int i) {
|
||||||
|
/* unused variable */
|
||||||
|
(void) i;
|
||||||
|
|
||||||
|
tcsetattr(0,TCSANOW,&terminal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_exit(int i) {
|
||||||
|
/* unused variable */
|
||||||
|
(void) i;
|
||||||
|
|
||||||
|
do_cleanup(0);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_channel chan;
|
||||||
|
int signal_delayed=0;
|
||||||
|
|
||||||
|
static void sigwindowchanged(int i){
|
||||||
|
(void) i;
|
||||||
|
signal_delayed=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
ssh_channel_change_pty_size(chan,win.ws_col, win.ws_row);
|
||||||
|
// printf("Changed pty size\n");
|
||||||
|
setsignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There are two flavors of select loop: the one based on
|
||||||
|
* ssh_select and the one based on channel_select.
|
||||||
|
* The ssh_select one permits you to give your own file descriptors to
|
||||||
|
* follow. It is thus a complete select loop.
|
||||||
|
* The second one only selects on channels. It is simplier to use
|
||||||
|
* but doesn't permit you to fill in your own file descriptor. It is
|
||||||
|
* more adapted if you can't use ssh_select as a main loop (because
|
||||||
|
* you already have another main loop system).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_CHANNEL_SELECT
|
||||||
|
|
||||||
|
/* channel_select base main loop, with a standard select(2)
|
||||||
|
*/
|
||||||
|
static void select_loop(ssh_session session,ssh_channel channel){
|
||||||
|
fd_set fds;
|
||||||
|
struct timeval timeout;
|
||||||
|
char buffer[4096];
|
||||||
|
ssh_buffer readbuf=ssh_buffer_new();
|
||||||
|
ssh_channel channels[2];
|
||||||
|
int lus;
|
||||||
|
int eof=0;
|
||||||
|
int maxfd;
|
||||||
|
int ret;
|
||||||
|
while(channel){
|
||||||
|
/* when a signal is caught, ssh_select will return
|
||||||
|
* with SSH_EINTR, which means it should be started
|
||||||
|
* again. It lets you handle the signal the faster you
|
||||||
|
* can, like in this window changed example. Of course, if
|
||||||
|
* your signal handler doesn't call libssh at all, you're
|
||||||
|
* free to handle signals directly in sighandler.
|
||||||
|
*/
|
||||||
|
do{
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
if(!eof)
|
||||||
|
FD_SET(0,&fds);
|
||||||
|
timeout.tv_sec=30;
|
||||||
|
timeout.tv_usec=0;
|
||||||
|
FD_SET(ssh_get_fd(session),&fds);
|
||||||
|
maxfd=ssh_get_fd(session)+1;
|
||||||
|
ret=select(maxfd,&fds,NULL,NULL,&timeout);
|
||||||
|
if(ret==EINTR)
|
||||||
|
continue;
|
||||||
|
if(FD_ISSET(0,&fds)){
|
||||||
|
lus=read(0,buffer,sizeof(buffer));
|
||||||
|
if(lus)
|
||||||
|
ssh_channel_write(channel,buffer,lus);
|
||||||
|
else {
|
||||||
|
eof=1;
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(FD_ISSET(ssh_get_fd(session),&fds)){
|
||||||
|
ssh_set_fd_toread(session);
|
||||||
|
}
|
||||||
|
channels[0]=channel; // set the first channel we want to read from
|
||||||
|
channels[1]=NULL;
|
||||||
|
ret=ssh_channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll
|
||||||
|
if(signal_delayed)
|
||||||
|
sizechanged();
|
||||||
|
} while (ret==EINTR || ret==SSH_EINTR);
|
||||||
|
|
||||||
|
// we already looked for input from stdin. Now, we are looking for input from the channel
|
||||||
|
|
||||||
|
if(channel && ssh_channel_is_closed(channel)){
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||||
|
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=NULL;
|
||||||
|
channels[0]=NULL;
|
||||||
|
}
|
||||||
|
if(channels[0]){
|
||||||
|
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)>0){
|
||||||
|
lus=channel_read_buffer(channel,readbuf,0,0);
|
||||||
|
if(lus==-1){
|
||||||
|
fprintf(stderr, "Error reading channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lus==0){
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||||
|
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=channels[0]=NULL;
|
||||||
|
} else
|
||||||
|
if (write(1,ssh_buffer_get_begin(readbuf),lus) < 0) {
|
||||||
|
fprintf(stderr, "Error writing to buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)>0){ /* stderr */
|
||||||
|
lus=channel_read_buffer(channel,readbuf,0,1);
|
||||||
|
if(lus==-1){
|
||||||
|
fprintf(stderr, "Error reading channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lus==0){
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=channels[0]=NULL;
|
||||||
|
} else
|
||||||
|
if (write(2,ssh_buffer_get_begin(readbuf),lus) < 0) {
|
||||||
|
fprintf(stderr, "Error writing to buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(channel && ssh_channel_is_closed(channel)){
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ssh_buffer_free(readbuf);
|
||||||
|
}
|
||||||
|
#else /* CHANNEL_SELECT */
|
||||||
|
|
||||||
|
static void select_loop(ssh_session session,ssh_channel channel){
|
||||||
|
fd_set fds;
|
||||||
|
struct timeval timeout;
|
||||||
|
char buffer[4096];
|
||||||
|
/* channels will be set to the channels to poll.
|
||||||
|
* outchannels will contain the result of the poll
|
||||||
|
*/
|
||||||
|
ssh_channel channels[2], outchannels[2];
|
||||||
|
int lus;
|
||||||
|
int eof=0;
|
||||||
|
int maxfd;
|
||||||
|
int ret;
|
||||||
|
while(channel){
|
||||||
|
do{
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
if(!eof)
|
||||||
|
FD_SET(0,&fds);
|
||||||
|
timeout.tv_sec=30;
|
||||||
|
timeout.tv_usec=0;
|
||||||
|
FD_SET(ssh_get_fd(session),&fds);
|
||||||
|
maxfd=ssh_get_fd(session)+1;
|
||||||
|
channels[0]=channel; // set the first channel we want to read from
|
||||||
|
channels[1]=NULL;
|
||||||
|
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
|
||||||
|
if(signal_delayed)
|
||||||
|
sizechanged();
|
||||||
|
if(ret==EINTR)
|
||||||
|
continue;
|
||||||
|
if(FD_ISSET(0,&fds)){
|
||||||
|
lus=read(0,buffer,sizeof(buffer));
|
||||||
|
if(lus)
|
||||||
|
ssh_channel_write(channel,buffer,lus);
|
||||||
|
else {
|
||||||
|
eof=1;
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(channel && ssh_channel_is_closed(channel)){
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||||
|
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=NULL;
|
||||||
|
channels[0]=NULL;
|
||||||
|
}
|
||||||
|
if(outchannels[0]){
|
||||||
|
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)!=0){
|
||||||
|
lus=ssh_channel_read(channel,buffer,sizeof(buffer),0);
|
||||||
|
if(lus==-1){
|
||||||
|
fprintf(stderr, "Error reading channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lus==0){
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||||
|
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=channels[0]=NULL;
|
||||||
|
} else
|
||||||
|
if (write(1,buffer,lus) < 0) {
|
||||||
|
fprintf(stderr, "Error writing to buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)!=0){ /* stderr */
|
||||||
|
lus=ssh_channel_read(channel,buffer,sizeof(buffer),1);
|
||||||
|
if(lus==-1){
|
||||||
|
fprintf(stderr, "Error reading channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lus==0){
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"EOF received");
|
||||||
|
ssh_log(session,SSH_LOG_RARE,"exit-status : %d",ssh_channel_get_exit_status(channel));
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=channels[0]=NULL;
|
||||||
|
} else
|
||||||
|
if (write(2,buffer,lus) < 0) {
|
||||||
|
fprintf(stderr, "Error writing to buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(channel && ssh_channel_is_closed(channel)){
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
channel=NULL;
|
||||||
|
}
|
||||||
|
} while (ret==EINTR || ret==SSH_EINTR);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void shell(ssh_session session){
|
||||||
|
ssh_channel channel;
|
||||||
|
struct termios terminal_local;
|
||||||
|
int interactive=isatty(0);
|
||||||
|
channel = ssh_channel_new(session);
|
||||||
|
if(interactive){
|
||||||
|
tcgetattr(0,&terminal_local);
|
||||||
|
memcpy(&terminal,&terminal_local,sizeof(struct termios));
|
||||||
|
}
|
||||||
|
if(ssh_channel_open_session(channel)){
|
||||||
|
printf("error opening channel : %s\n",ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chan=channel;
|
||||||
|
if(interactive){
|
||||||
|
ssh_channel_request_pty(channel);
|
||||||
|
sizechanged();
|
||||||
|
}
|
||||||
|
if(ssh_channel_request_shell(channel)){
|
||||||
|
printf("Requesting shell : %s\n",ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(interactive){
|
||||||
|
cfmakeraw(&terminal_local);
|
||||||
|
tcsetattr(0,TCSANOW,&terminal_local);
|
||||||
|
setsignal();
|
||||||
|
}
|
||||||
|
signal(SIGTERM,do_cleanup);
|
||||||
|
select_loop(session,channel);
|
||||||
|
if(interactive)
|
||||||
|
do_cleanup(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void batch_shell(ssh_session session){
|
||||||
|
ssh_channel channel;
|
||||||
|
char buffer[1024];
|
||||||
|
int i,s=0;
|
||||||
|
for(i=0;i<MAXCMD && cmds[i];++i) {
|
||||||
|
s+=snprintf(buffer+s,sizeof(buffer)-s,"%s ",cmds[i]);
|
||||||
|
free(cmds[i]);
|
||||||
|
cmds[i] = NULL;
|
||||||
|
}
|
||||||
|
channel=ssh_channel_new(session);
|
||||||
|
ssh_channel_open_session(channel);
|
||||||
|
if(ssh_channel_request_exec(channel,buffer)){
|
||||||
|
printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
select_loop(session,channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int client(ssh_session session){
|
||||||
|
int auth=0;
|
||||||
|
char *banner;
|
||||||
|
int state;
|
||||||
|
if (user)
|
||||||
|
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0)
|
||||||
|
return -1;
|
||||||
|
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
|
||||||
|
return -1;
|
||||||
|
if (proxycommand != NULL){
|
||||||
|
if(ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, proxycommand))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssh_options_parse_config(session, NULL);
|
||||||
|
|
||||||
|
if(ssh_connect(session)){
|
||||||
|
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state=verify_knownhost(session);
|
||||||
|
if (state != 0)
|
||||||
|
return -1;
|
||||||
|
ssh_userauth_none(session, NULL);
|
||||||
|
banner=ssh_get_issue_banner(session);
|
||||||
|
if(banner){
|
||||||
|
printf("%s\n",banner);
|
||||||
|
free(banner);
|
||||||
|
}
|
||||||
|
auth=authenticate_console(session);
|
||||||
|
if(auth != SSH_AUTH_SUCCESS){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
|
||||||
|
if(!cmds[0])
|
||||||
|
shell(session);
|
||||||
|
else
|
||||||
|
batch_shell(session);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_pcap_file pcap;
|
||||||
|
void set_pcap(ssh_session session);
|
||||||
|
void set_pcap(ssh_session session){
|
||||||
|
if(!pcap_file)
|
||||||
|
return;
|
||||||
|
pcap=ssh_pcap_file_new();
|
||||||
|
if(!pcap)
|
||||||
|
return;
|
||||||
|
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||||
|
printf("Error opening pcap file\n");
|
||||||
|
ssh_pcap_file_free(pcap);
|
||||||
|
pcap=NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ssh_set_pcap_file(session,pcap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup_pcap(void);
|
||||||
|
void cleanup_pcap(){
|
||||||
|
if(pcap)
|
||||||
|
ssh_pcap_file_free(pcap);
|
||||||
|
pcap=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
ssh_session session;
|
||||||
|
|
||||||
|
session = ssh_new();
|
||||||
|
|
||||||
|
ssh_callbacks_init(&cb);
|
||||||
|
ssh_set_callbacks(session,&cb);
|
||||||
|
|
||||||
|
if(ssh_options_getopt(session, &argc, argv)) {
|
||||||
|
fprintf(stderr, "error parsing command line :%s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
opts(argc,argv);
|
||||||
|
signal(SIGTERM, do_exit);
|
||||||
|
|
||||||
|
set_pcap(session);
|
||||||
|
client(session);
|
||||||
|
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
cleanup_pcap();
|
||||||
|
|
||||||
|
ssh_finalize();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
265
examples/samplesftp.c
Normal file
265
examples/samplesftp.c
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2003-2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <libssh/sftp.h>
|
||||||
|
|
||||||
|
#include "examples_common.h"
|
||||||
|
#ifdef WITH_SFTP
|
||||||
|
|
||||||
|
int verbosity;
|
||||||
|
char *destination;
|
||||||
|
#define DATALEN 65536
|
||||||
|
static void do_sftp(ssh_session session){
|
||||||
|
sftp_session sftp=sftp_new(session);
|
||||||
|
sftp_dir dir;
|
||||||
|
sftp_attributes file;
|
||||||
|
sftp_statvfs_t sftpstatvfs;
|
||||||
|
struct statvfs sysstatvfs;
|
||||||
|
sftp_file fichier;
|
||||||
|
sftp_file to;
|
||||||
|
int len=1;
|
||||||
|
unsigned int i;
|
||||||
|
char data[DATALEN]={0};
|
||||||
|
char *lnk;
|
||||||
|
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
if(!sftp){
|
||||||
|
fprintf(stderr, "sftp error initialising channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(sftp_init(sftp)){
|
||||||
|
fprintf(stderr, "error initialising sftp: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Additional SFTP extensions provided by the server:\n");
|
||||||
|
count = sftp_extensions_get_count(sftp);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
printf("\t%s, version: %s\n",
|
||||||
|
sftp_extensions_get_name(sftp, i),
|
||||||
|
sftp_extensions_get_data(sftp, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test symlink and readlink */
|
||||||
|
if (sftp_symlink(sftp, "/tmp/this_is_the_link",
|
||||||
|
"/tmp/sftp_symlink_test") < 0) {
|
||||||
|
fprintf(stderr, "Could not create link (%s)\n", ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lnk = sftp_readlink(sftp, "/tmp/sftp_symlink_test");
|
||||||
|
if (lnk == NULL) {
|
||||||
|
fprintf(stderr, "Could not read link (%s)\n", ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("readlink /tmp/sftp_symlink_test: %s\n", lnk);
|
||||||
|
|
||||||
|
sftp_unlink(sftp, "/tmp/sftp_symlink_test");
|
||||||
|
|
||||||
|
if (sftp_extension_supported(sftp, "statvfs@openssh.com", "2")) {
|
||||||
|
sftpstatvfs = sftp_statvfs(sftp, "/tmp");
|
||||||
|
if (sftpstatvfs == NULL) {
|
||||||
|
fprintf(stderr, "statvfs failed (%s)\n", ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("sftp statvfs:\n"
|
||||||
|
"\tfile system block size: %llu\n"
|
||||||
|
"\tfundamental fs block size: %llu\n"
|
||||||
|
"\tnumber of blocks (unit f_frsize): %llu\n"
|
||||||
|
"\tfree blocks in file system: %llu\n"
|
||||||
|
"\tfree blocks for non-root: %llu\n"
|
||||||
|
"\ttotal file inodes: %llu\n"
|
||||||
|
"\tfree file inodes: %llu\n"
|
||||||
|
"\tfree file inodes for to non-root: %llu\n"
|
||||||
|
"\tfile system id: %llu\n"
|
||||||
|
"\tbit mask of f_flag values: %llu\n"
|
||||||
|
"\tmaximum filename length: %llu\n",
|
||||||
|
(unsigned long long) sftpstatvfs->f_bsize,
|
||||||
|
(unsigned long long) sftpstatvfs->f_frsize,
|
||||||
|
(unsigned long long) sftpstatvfs->f_blocks,
|
||||||
|
(unsigned long long) sftpstatvfs->f_bfree,
|
||||||
|
(unsigned long long) sftpstatvfs->f_bavail,
|
||||||
|
(unsigned long long) sftpstatvfs->f_files,
|
||||||
|
(unsigned long long) sftpstatvfs->f_ffree,
|
||||||
|
(unsigned long long) sftpstatvfs->f_favail,
|
||||||
|
(unsigned long long) sftpstatvfs->f_fsid,
|
||||||
|
(unsigned long long) sftpstatvfs->f_flag,
|
||||||
|
(unsigned long long) sftpstatvfs->f_namemax);
|
||||||
|
|
||||||
|
sftp_statvfs_free(sftpstatvfs);
|
||||||
|
|
||||||
|
if (statvfs("/tmp", &sysstatvfs) < 0) {
|
||||||
|
fprintf(stderr, "statvfs failed (%s)\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("sys statvfs:\n"
|
||||||
|
"\tfile system block size: %llu\n"
|
||||||
|
"\tfundamental fs block size: %llu\n"
|
||||||
|
"\tnumber of blocks (unit f_frsize): %llu\n"
|
||||||
|
"\tfree blocks in file system: %llu\n"
|
||||||
|
"\tfree blocks for non-root: %llu\n"
|
||||||
|
"\ttotal file inodes: %llu\n"
|
||||||
|
"\tfree file inodes: %llu\n"
|
||||||
|
"\tfree file inodes for to non-root: %llu\n"
|
||||||
|
"\tfile system id: %llu\n"
|
||||||
|
"\tbit mask of f_flag values: %llu\n"
|
||||||
|
"\tmaximum filename length: %llu\n",
|
||||||
|
(unsigned long long) sysstatvfs.f_bsize,
|
||||||
|
(unsigned long long) sysstatvfs.f_frsize,
|
||||||
|
(unsigned long long) sysstatvfs.f_blocks,
|
||||||
|
(unsigned long long) sysstatvfs.f_bfree,
|
||||||
|
(unsigned long long) sysstatvfs.f_bavail,
|
||||||
|
(unsigned long long) sysstatvfs.f_files,
|
||||||
|
(unsigned long long) sysstatvfs.f_ffree,
|
||||||
|
(unsigned long long) sysstatvfs.f_favail,
|
||||||
|
(unsigned long long) sysstatvfs.f_fsid,
|
||||||
|
(unsigned long long) sysstatvfs.f_flag,
|
||||||
|
(unsigned long long) sysstatvfs.f_namemax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the connection is made */
|
||||||
|
/* opening a directory */
|
||||||
|
dir=sftp_opendir(sftp,"./");
|
||||||
|
if(!dir) {
|
||||||
|
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))){
|
||||||
|
fprintf(stderr, "%30s(%.8o) : %s(%.5d) %s(%.5d) : %.10llu bytes\n",
|
||||||
|
file->name,
|
||||||
|
file->permissions,
|
||||||
|
file->owner,
|
||||||
|
file->uid,
|
||||||
|
file->group,
|
||||||
|
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)){
|
||||||
|
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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, 0);
|
||||||
|
if(!fichier){
|
||||||
|
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, 0700);
|
||||||
|
if(!to){
|
||||||
|
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){
|
||||||
|
fprintf(stderr, "Error writing %d bytes: %s\n",
|
||||||
|
len, ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("finished\n");
|
||||||
|
if(len<0)
|
||||||
|
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,"/tmp/grosfichier",O_WRONLY|O_CREAT, 0644);
|
||||||
|
for(i=0;i<1000;++i){
|
||||||
|
len=sftp_write(to,data,DATALEN);
|
||||||
|
printf("wrote %d bytes\n",len);
|
||||||
|
if(len != DATALEN){
|
||||||
|
printf("chunk %d : %d (%s)\n",i,len,ssh_get_error(session));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sftp_close(to);
|
||||||
|
|
||||||
|
/* close the sftp session */
|
||||||
|
sftp_free(sftp);
|
||||||
|
printf("sftp session terminated\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(const char *argv0){
|
||||||
|
fprintf(stderr,"Usage : %s [-v] remotehost\n"
|
||||||
|
"sample sftp test client - libssh-%s\n"
|
||||||
|
"Options :\n"
|
||||||
|
" -v : increase log verbosity\n",
|
||||||
|
argv0,
|
||||||
|
ssh_version(0));
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opts(int argc, char **argv){
|
||||||
|
int i;
|
||||||
|
while((i=getopt(argc,argv,"v"))!=-1){
|
||||||
|
switch(i){
|
||||||
|
case 'v':
|
||||||
|
verbosity++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"unknown option %c\n",optopt);
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destination=argv[optind];
|
||||||
|
if(destination == NULL){
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
ssh_session session;
|
||||||
|
if(opts(argc,argv)<0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
session=connect_ssh(destination,NULL,verbosity);
|
||||||
|
if(session == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
do_sftp(session);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
308
examples/samplesshd.c
Normal file
308
examples/samplesshd.c
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
/* This is a sample implementation of a libssh based SSH server */
|
||||||
|
/*
|
||||||
|
Copyright 2003-2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <libssh/server.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_ARGP_H
|
||||||
|
#include <argp.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef KEYS_FOLDER
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define KEYS_FOLDER
|
||||||
|
#else
|
||||||
|
#define KEYS_FOLDER "/etc/ssh/"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
const char *pcap_file="debug.server.pcap";
|
||||||
|
ssh_pcap_file pcap;
|
||||||
|
|
||||||
|
void set_pcap(ssh_session session);
|
||||||
|
void set_pcap(ssh_session session){
|
||||||
|
if(!pcap_file)
|
||||||
|
return;
|
||||||
|
pcap=ssh_pcap_file_new();
|
||||||
|
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||||
|
printf("Error opening pcap file\n");
|
||||||
|
ssh_pcap_file_free(pcap);
|
||||||
|
pcap=NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ssh_set_pcap_file(session,pcap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup_pcap(void);
|
||||||
|
void cleanup_pcap(){
|
||||||
|
ssh_pcap_file_free(pcap);
|
||||||
|
pcap=NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int auth_password(char *user, char *password){
|
||||||
|
if(strcmp(user,"aris"))
|
||||||
|
return 0;
|
||||||
|
if(strcmp(password,"lala"))
|
||||||
|
return 0;
|
||||||
|
return 1; // authenticated
|
||||||
|
}
|
||||||
|
#ifdef HAVE_ARGP_H
|
||||||
|
const char *argp_program_version = "libssh server example "
|
||||||
|
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||||
|
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||||
|
|
||||||
|
/* Program documentation. */
|
||||||
|
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||||
|
|
||||||
|
/* A description of the arguments we accept. */
|
||||||
|
static char args_doc[] = "BINDADDR";
|
||||||
|
|
||||||
|
/* The options we understand. */
|
||||||
|
static struct argp_option options[] = {
|
||||||
|
{
|
||||||
|
.name = "port",
|
||||||
|
.key = 'p',
|
||||||
|
.arg = "PORT",
|
||||||
|
.flags = 0,
|
||||||
|
.doc = "Set the port to bind.",
|
||||||
|
.group = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "hostkey",
|
||||||
|
.key = 'k',
|
||||||
|
.arg = "FILE",
|
||||||
|
.flags = 0,
|
||||||
|
.doc = "Set the host key.",
|
||||||
|
.group = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "dsakey",
|
||||||
|
.key = 'd',
|
||||||
|
.arg = "FILE",
|
||||||
|
.flags = 0,
|
||||||
|
.doc = "Set the dsa key.",
|
||||||
|
.group = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "rsakey",
|
||||||
|
.key = 'r',
|
||||||
|
.arg = "FILE",
|
||||||
|
.flags = 0,
|
||||||
|
.doc = "Set the rsa key.",
|
||||||
|
.group = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "verbose",
|
||||||
|
.key = 'v',
|
||||||
|
.arg = NULL,
|
||||||
|
.flags = 0,
|
||||||
|
.doc = "Get verbose output.",
|
||||||
|
.group = 0
|
||||||
|
},
|
||||||
|
{NULL, 0, 0, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Parse a single option. */
|
||||||
|
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||||
|
/* Get the input argument from argp_parse, which we
|
||||||
|
* know is a pointer to our arguments structure.
|
||||||
|
*/
|
||||||
|
ssh_bind sshbind = state->input;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case 'p':
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||||
|
break;
|
||||||
|
case ARGP_KEY_ARG:
|
||||||
|
if (state->arg_num >= 1) {
|
||||||
|
/* Too many arguments. */
|
||||||
|
argp_usage (state);
|
||||||
|
}
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||||
|
break;
|
||||||
|
case ARGP_KEY_END:
|
||||||
|
if (state->arg_num < 1) {
|
||||||
|
/* Not enough arguments. */
|
||||||
|
argp_usage (state);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Our argp parser. */
|
||||||
|
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||||
|
#endif /* HAVE_ARGP_H */
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
ssh_session session;
|
||||||
|
ssh_bind sshbind;
|
||||||
|
ssh_message message;
|
||||||
|
ssh_channel chan=0;
|
||||||
|
char buf[2048];
|
||||||
|
int auth=0;
|
||||||
|
int sftp=0;
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
sshbind=ssh_bind_new();
|
||||||
|
session=ssh_new();
|
||||||
|
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
|
||||||
|
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
|
||||||
|
|
||||||
|
#ifdef HAVE_ARGP_H
|
||||||
|
/*
|
||||||
|
* Parse our arguments; every option seen by parse_opt will
|
||||||
|
* be reflected in arguments.
|
||||||
|
*/
|
||||||
|
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||||
|
#else
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
set_pcap(session);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(ssh_bind_listen(sshbind)<0){
|
||||||
|
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
r=ssh_bind_accept(sshbind,session);
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ssh_handle_key_exchange(session)) {
|
||||||
|
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
message=ssh_message_get(session);
|
||||||
|
if(!message)
|
||||||
|
break;
|
||||||
|
switch(ssh_message_type(message)){
|
||||||
|
case SSH_REQUEST_AUTH:
|
||||||
|
switch(ssh_message_subtype(message)){
|
||||||
|
case SSH_AUTH_METHOD_PASSWORD:
|
||||||
|
printf("User %s wants to auth with pass %s\n",
|
||||||
|
ssh_message_auth_user(message),
|
||||||
|
ssh_message_auth_password(message));
|
||||||
|
if(auth_password(ssh_message_auth_user(message),
|
||||||
|
ssh_message_auth_password(message))){
|
||||||
|
auth=1;
|
||||||
|
ssh_message_auth_reply_success(message,0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// not authenticated, send default message
|
||||||
|
case SSH_AUTH_METHOD_NONE:
|
||||||
|
default:
|
||||||
|
ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
}
|
||||||
|
ssh_message_free(message);
|
||||||
|
} while (!auth);
|
||||||
|
if(!auth){
|
||||||
|
printf("auth error: %s\n",ssh_get_error(session));
|
||||||
|
ssh_disconnect(session);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
message=ssh_message_get(session);
|
||||||
|
if(message){
|
||||||
|
switch(ssh_message_type(message)){
|
||||||
|
case SSH_REQUEST_CHANNEL_OPEN:
|
||||||
|
if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
|
||||||
|
chan=ssh_message_channel_request_open_reply_accept(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
}
|
||||||
|
ssh_message_free(message);
|
||||||
|
}
|
||||||
|
} while(message && !chan);
|
||||||
|
if(!chan){
|
||||||
|
printf("error : %s\n",ssh_get_error(session));
|
||||||
|
ssh_finalize();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
message=ssh_message_get(session);
|
||||||
|
if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
|
||||||
|
ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){
|
||||||
|
// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
|
||||||
|
sftp=1;
|
||||||
|
ssh_message_channel_request_reply_success(message);
|
||||||
|
break;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if(!sftp){
|
||||||
|
ssh_message_reply_default(message);
|
||||||
|
}
|
||||||
|
ssh_message_free(message);
|
||||||
|
} while (message && !sftp);
|
||||||
|
if(!sftp){
|
||||||
|
printf("error : %s\n",ssh_get_error(session));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("it works !\n");
|
||||||
|
do{
|
||||||
|
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||||
|
if(i>0) {
|
||||||
|
ssh_channel_write(chan, buf, i);
|
||||||
|
if (write(1,buf,i) < 0) {
|
||||||
|
printf("error writing to buffer\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (i>0);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_bind_free(sshbind);
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
cleanup_pcap();
|
||||||
|
#endif
|
||||||
|
ssh_finalize();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
165
examples/scp_download.c
Normal file
165
examples/scp_download.c
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/* scp_download.c
|
||||||
|
* Sample implementation of a tiny SCP downloader client
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2009 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
|
||||||
|
int verbosity=0;
|
||||||
|
const char *createcommand="rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
|
||||||
|
char *host=NULL;
|
||||||
|
static void usage(const char *argv0){
|
||||||
|
fprintf(stderr,"Usage : %s [options] host\n"
|
||||||
|
"sample tiny scp downloader client - libssh-%s\n"
|
||||||
|
"This program will create files in /tmp and try to fetch them\n",
|
||||||
|
// "Options :\n",
|
||||||
|
// " -r : use RSA to verify host public key\n",
|
||||||
|
argv0,
|
||||||
|
ssh_version(0));
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opts(int argc, char **argv){
|
||||||
|
int i;
|
||||||
|
while((i=getopt(argc,argv,"v"))!=-1){
|
||||||
|
switch(i){
|
||||||
|
case 'v':
|
||||||
|
verbosity++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"unknown option %c\n",optopt);
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
host = argv[optind];
|
||||||
|
if(host == NULL)
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_files(ssh_session session){
|
||||||
|
ssh_channel channel=ssh_channel_new(session);
|
||||||
|
char buffer[1];
|
||||||
|
if(channel == NULL){
|
||||||
|
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(ssh_channel_open_session(channel) != SSH_OK){
|
||||||
|
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(ssh_channel_request_exec(channel,createcommand) != SSH_OK){
|
||||||
|
fprintf(stderr,"Error executing command: %s\n",ssh_get_error(session));
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
while(!ssh_channel_is_eof(channel)){
|
||||||
|
ssh_channel_read(channel,buffer,1,1);
|
||||||
|
if (write(1,buffer,1) < 0) {
|
||||||
|
fprintf(stderr, "Error writing to buffer\n");
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_channel_free(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int fetch_files(ssh_session session){
|
||||||
|
int size;
|
||||||
|
char buffer[16384];
|
||||||
|
int mode;
|
||||||
|
char *filename;
|
||||||
|
int r;
|
||||||
|
ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*");
|
||||||
|
if(ssh_scp_init(scp) != SSH_OK){
|
||||||
|
fprintf(stderr,"error initializing scp: %s\n",ssh_get_error(session));
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n");
|
||||||
|
do {
|
||||||
|
|
||||||
|
r=ssh_scp_pull_request(scp);
|
||||||
|
switch(r){
|
||||||
|
case SSH_SCP_REQUEST_NEWFILE:
|
||||||
|
size=ssh_scp_request_get_size(scp);
|
||||||
|
filename=strdup(ssh_scp_request_get_filename(scp));
|
||||||
|
mode=ssh_scp_request_get_permissions(scp);
|
||||||
|
printf("downloading file %s, size %d, perms 0%o\n",filename,size,mode);
|
||||||
|
free(filename);
|
||||||
|
ssh_scp_accept_request(scp);
|
||||||
|
r=ssh_scp_read(scp,buffer,sizeof(buffer));
|
||||||
|
if(r==SSH_ERROR){
|
||||||
|
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(session));
|
||||||
|
ssh_scp_close(scp);
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("done\n");
|
||||||
|
break;
|
||||||
|
case SSH_ERROR:
|
||||||
|
fprintf(stderr,"Error: %s\n",ssh_get_error(session));
|
||||||
|
ssh_scp_close(scp);
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return -1;
|
||||||
|
case SSH_SCP_REQUEST_WARNING:
|
||||||
|
fprintf(stderr,"Warning: %s\n",ssh_scp_request_get_warning(scp));
|
||||||
|
break;
|
||||||
|
case SSH_SCP_REQUEST_NEWDIR:
|
||||||
|
filename=strdup(ssh_scp_request_get_filename(scp));
|
||||||
|
mode=ssh_scp_request_get_permissions(scp);
|
||||||
|
printf("downloading directory %s, perms 0%o\n",filename,mode);
|
||||||
|
free(filename);
|
||||||
|
ssh_scp_accept_request(scp);
|
||||||
|
break;
|
||||||
|
case SSH_SCP_REQUEST_ENDDIR:
|
||||||
|
printf("End of directory\n");
|
||||||
|
break;
|
||||||
|
case SSH_SCP_REQUEST_EOF:
|
||||||
|
printf("End of requests\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
end:
|
||||||
|
ssh_scp_close(scp);
|
||||||
|
ssh_scp_free(scp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
ssh_session session;
|
||||||
|
if(opts(argc,argv)<0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
session=connect_ssh(host,NULL,verbosity);
|
||||||
|
if(session == NULL)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
create_files(session);
|
||||||
|
fetch_files(session);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
ssh_finalize();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
64
examples/senddata.c
Normal file
64
examples/senddata.c
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include "examples_common.h"
|
||||||
|
|
||||||
|
#define LIMIT 0x100000000
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
ssh_session session;
|
||||||
|
ssh_channel channel;
|
||||||
|
char buffer[1024*1024];
|
||||||
|
int rc;
|
||||||
|
uint64_t total=0;
|
||||||
|
uint64_t lastshown=4096;
|
||||||
|
session = connect_ssh("localhost", NULL, 0);
|
||||||
|
if (session == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = ssh_channel_new(session);;
|
||||||
|
if (channel == NULL) {
|
||||||
|
ssh_disconnect(session);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_channel_open_session(channel);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_channel_request_exec(channel, "cat > /dev/null");
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while ((rc = ssh_channel_write(channel, buffer, sizeof(buffer))) > 0) {
|
||||||
|
total += rc;
|
||||||
|
if(total/2 >= lastshown){
|
||||||
|
printf("written %llx\n", (long long unsigned int) total);
|
||||||
|
lastshown=total;
|
||||||
|
}
|
||||||
|
if(total > LIMIT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
printf("error : %s\n",ssh_get_error(session));
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
ssh_disconnect(session);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_channel_send_eof(channel);
|
||||||
|
ssh_channel_close(channel);
|
||||||
|
|
||||||
|
ssh_disconnect(session);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
258
examples/sshnetcat.c
Normal file
258
examples/sshnetcat.c
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Aris Adamantiadis
|
||||||
|
|
||||||
|
This file is part of the SSH Library
|
||||||
|
|
||||||
|
You are free to copy this file, modify it in any way, consider it being public
|
||||||
|
domain. This does not apply to the rest of the library though, but it is
|
||||||
|
allowed to cut-and-paste working code from this file to any license of
|
||||||
|
program.
|
||||||
|
The goal is to show the API in action. It's not a reference on how terminal
|
||||||
|
clients must be made or how a client should react.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libssh/callbacks.h>
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <libssh/sftp.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "examples_common.h"
|
||||||
|
char *host;
|
||||||
|
const char *desthost="localhost";
|
||||||
|
const char *port="22";
|
||||||
|
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
#include <libssh/pcap.h>
|
||||||
|
char *pcap_file=NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void usage(){
|
||||||
|
fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opts(int argc, char **argv){
|
||||||
|
int i;
|
||||||
|
while((i=getopt(argc,argv,"P:"))!=-1){
|
||||||
|
switch(i){
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
case 'P':
|
||||||
|
pcap_file=optarg;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"unknown option %c\n",optopt);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(optind < argc)
|
||||||
|
host=argv[optind++];
|
||||||
|
if(optind < argc)
|
||||||
|
desthost=argv[optind++];
|
||||||
|
if(optind < argc)
|
||||||
|
port=argv[optind++];
|
||||||
|
if(host==NULL)
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void select_loop(ssh_session session,ssh_channel channel){
|
||||||
|
fd_set fds;
|
||||||
|
struct timeval timeout;
|
||||||
|
char buffer[4096];
|
||||||
|
/* channels will be set to the channels to poll.
|
||||||
|
* outchannels will contain the result of the poll
|
||||||
|
*/
|
||||||
|
ssh_channel channels[2], outchannels[2];
|
||||||
|
int lus;
|
||||||
|
int eof=0;
|
||||||
|
int maxfd;
|
||||||
|
int ret;
|
||||||
|
while(channel){
|
||||||
|
do{
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
if(!eof)
|
||||||
|
FD_SET(0,&fds);
|
||||||
|
timeout.tv_sec=30;
|
||||||
|
timeout.tv_usec=0;
|
||||||
|
FD_SET(ssh_get_fd(session),&fds);
|
||||||
|
maxfd=ssh_get_fd(session)+1;
|
||||||
|
channels[0]=channel; // set the first channel we want to read from
|
||||||
|
channels[1]=NULL;
|
||||||
|
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
|
||||||
|
if(ret==EINTR)
|
||||||
|
continue;
|
||||||
|
if(FD_ISSET(0,&fds)){
|
||||||
|
lus=read(0,buffer,sizeof(buffer));
|
||||||
|
if(lus)
|
||||||
|
channel_write(channel,buffer,lus);
|
||||||
|
else {
|
||||||
|
eof=1;
|
||||||
|
channel_send_eof(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(outchannels[0]){
|
||||||
|
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
|
||||||
|
lus=channel_read(channel,buffer,sizeof(buffer),0);
|
||||||
|
if(lus==-1){
|
||||||
|
fprintf(stderr, "Error reading channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lus==0){
|
||||||
|
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 {
|
||||||
|
ret = write(1, buffer, lus);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error writing to stdin: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
|
||||||
|
lus=channel_read(channel,buffer,sizeof(buffer),1);
|
||||||
|
if(lus==-1){
|
||||||
|
fprintf(stderr, "Error reading channel: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lus==0){
|
||||||
|
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
|
||||||
|
ret = write(2, buffer, lus);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error writing to stderr: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(channel && channel_is_closed(channel)){
|
||||||
|
channel_free(channel);
|
||||||
|
channel=NULL;
|
||||||
|
}
|
||||||
|
} while (ret==EINTR || ret==SSH_EINTR);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void forwarding(ssh_session session){
|
||||||
|
ssh_channel channel;
|
||||||
|
int r;
|
||||||
|
channel=channel_new(session);
|
||||||
|
r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
|
||||||
|
if(r<0) {
|
||||||
|
printf("error forwarding port : %s\n",ssh_get_error(session));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
select_loop(session,channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int client(ssh_session session){
|
||||||
|
int auth=0;
|
||||||
|
char *banner;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
|
||||||
|
return -1;
|
||||||
|
ssh_options_parse_config(session, NULL);
|
||||||
|
|
||||||
|
if(ssh_connect(session)){
|
||||||
|
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state=verify_knownhost(session);
|
||||||
|
if (state != 0)
|
||||||
|
return -1;
|
||||||
|
ssh_userauth_none(session, NULL);
|
||||||
|
banner=ssh_get_issue_banner(session);
|
||||||
|
if(banner){
|
||||||
|
printf("%s\n",banner);
|
||||||
|
free(banner);
|
||||||
|
}
|
||||||
|
auth=authenticate_console(session);
|
||||||
|
if(auth != SSH_AUTH_SUCCESS){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
|
||||||
|
forwarding(session);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
ssh_pcap_file pcap;
|
||||||
|
void set_pcap(ssh_session session);
|
||||||
|
void set_pcap(ssh_session session){
|
||||||
|
if(!pcap_file)
|
||||||
|
return;
|
||||||
|
pcap=ssh_pcap_file_new();
|
||||||
|
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||||
|
printf("Error opening pcap file\n");
|
||||||
|
ssh_pcap_file_free(pcap);
|
||||||
|
pcap=NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ssh_set_pcap_file(session,pcap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup_pcap(void);
|
||||||
|
void cleanup_pcap(){
|
||||||
|
ssh_pcap_file_free(pcap);
|
||||||
|
pcap=NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
ssh_session session;
|
||||||
|
|
||||||
|
session = ssh_new();
|
||||||
|
|
||||||
|
if(ssh_options_getopt(session, &argc, argv)) {
|
||||||
|
fprintf(stderr, "error parsing command line :%s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
opts(argc,argv);
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
set_pcap(session);
|
||||||
|
#endif
|
||||||
|
client(session);
|
||||||
|
|
||||||
|
ssh_disconnect(session);
|
||||||
|
ssh_free(session);
|
||||||
|
#ifdef WITH_PCAP
|
||||||
|
cleanup_pcap();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ssh_finalize();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
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
|
|
||||||
39
include/libssh/CMakeLists.txt
Normal file
39
include/libssh/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
project(libssh-headers C)
|
||||||
|
|
||||||
|
set(libssh_HDRS
|
||||||
|
callbacks.h
|
||||||
|
libssh.h
|
||||||
|
ssh2.h
|
||||||
|
legacy.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
|
|
||||||
97
include/libssh/agent.h
Normal file
97
include/libssh/agent.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#ifndef __AGENT_H
|
||||||
|
#define __AGENT_H
|
||||||
|
|
||||||
|
#include "libssh/libssh.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
|
||||||
|
|
||||||
|
struct ssh_agent_struct {
|
||||||
|
struct ssh_socket_struct *sock;
|
||||||
|
ssh_buffer ident;
|
||||||
|
unsigned int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* agent.c */
|
||||||
|
/**
|
||||||
|
* @brief Create a new ssh agent structure.
|
||||||
|
*
|
||||||
|
* @return An allocated ssh agent structure or NULL on error.
|
||||||
|
*/
|
||||||
|
struct ssh_agent_struct *agent_new(struct ssh_session_struct *session);
|
||||||
|
|
||||||
|
void agent_close(struct ssh_agent_struct *agent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free an allocated ssh agent structure.
|
||||||
|
*
|
||||||
|
* @param agent The ssh agent structure to free.
|
||||||
|
*/
|
||||||
|
void agent_free(struct ssh_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_struct *session);
|
||||||
|
|
||||||
|
int agent_get_ident_count(struct ssh_session_struct *session);
|
||||||
|
|
||||||
|
struct ssh_public_key_struct *agent_get_next_ident(struct ssh_session_struct *session,
|
||||||
|
char **comment);
|
||||||
|
|
||||||
|
struct ssh_public_key_struct *agent_get_first_ident(struct ssh_session_struct *session,
|
||||||
|
char **comment);
|
||||||
|
|
||||||
|
ssh_string agent_sign_data(struct ssh_session_struct *session,
|
||||||
|
struct ssh_buffer_struct *data,
|
||||||
|
struct ssh_public_key_struct *pubkey);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __AGENT_H */
|
||||||
|
/* vim: set ts=2 sw=2 et cindent: */
|
||||||
86
include/libssh/auth.h
Normal file
86
include/libssh/auth.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 AUTH_H_
|
||||||
|
#define AUTH_H_
|
||||||
|
#include "config.h"
|
||||||
|
#include "libssh/callbacks.h"
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_success);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request);
|
||||||
|
|
||||||
|
#ifdef WITH_SSH1
|
||||||
|
void ssh_auth1_handler(ssh_session session, uint8_t type);
|
||||||
|
|
||||||
|
/* auth1.c */
|
||||||
|
int ssh_userauth1_none(ssh_session session, const char *username);
|
||||||
|
int ssh_userauth1_offer_pubkey(ssh_session session, const char *username,
|
||||||
|
int type, ssh_string pubkey);
|
||||||
|
int ssh_userauth1_password(ssh_session session, const char *username,
|
||||||
|
const char *password);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* States of authentication in the client-side. They describe
|
||||||
|
* what was the last response from the server
|
||||||
|
*/
|
||||||
|
enum ssh_auth_state_e {
|
||||||
|
/** No authentication asked */
|
||||||
|
SSH_AUTH_STATE_NONE=0,
|
||||||
|
/** Last authentication response was a partial success */
|
||||||
|
SSH_AUTH_STATE_PARTIAL,
|
||||||
|
/** Last authentication response was a success */
|
||||||
|
SSH_AUTH_STATE_SUCCESS,
|
||||||
|
/** Last authentication response was failed */
|
||||||
|
SSH_AUTH_STATE_FAILED,
|
||||||
|
/** Last authentication was erroneous */
|
||||||
|
SSH_AUTH_STATE_ERROR,
|
||||||
|
/** Last state was a keyboard-interactive ask for info */
|
||||||
|
SSH_AUTH_STATE_INFO,
|
||||||
|
/** Last state was a public key accepted for authentication */
|
||||||
|
SSH_AUTH_STATE_PK_OK,
|
||||||
|
/** We asked for a keyboard-interactive authentication */
|
||||||
|
SSH_AUTH_STATE_KBDINT_SENT
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief states of the authentication service request
|
||||||
|
*/
|
||||||
|
enum ssh_auth_service_state_e {
|
||||||
|
/** initial state */
|
||||||
|
SSH_AUTH_SERVICE_NONE=0,
|
||||||
|
/** Authentication service request packet sent */
|
||||||
|
SSH_AUTH_SERVICE_SENT,
|
||||||
|
/** Service accepted */
|
||||||
|
SSH_AUTH_SERVICE_ACCEPTED,
|
||||||
|
/** Access to service denied (fatal) */
|
||||||
|
SSH_AUTH_SERVICE_DENIED,
|
||||||
|
/** Specific to SSH1 */
|
||||||
|
SSH_AUTH_SERVICE_USER_SENT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* AUTH_H_ */
|
||||||
53
include/libssh/bind.h
Normal file
53
include/libssh/bind.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 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 BIND_H_
|
||||||
|
#define BIND_H_
|
||||||
|
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
|
struct ssh_bind_struct {
|
||||||
|
struct error_struct error;
|
||||||
|
|
||||||
|
ssh_callbacks callbacks; /* Callbacks to user functions */
|
||||||
|
struct ssh_bind_callbacks_struct *bind_callbacks;
|
||||||
|
void *bind_callbacks_userdata;
|
||||||
|
|
||||||
|
struct ssh_poll_handle_struct *poll;
|
||||||
|
/* options */
|
||||||
|
char *wanted_methods[10];
|
||||||
|
char *banner;
|
||||||
|
char *dsakey;
|
||||||
|
char *rsakey;
|
||||||
|
char *bindaddr;
|
||||||
|
socket_t bindfd;
|
||||||
|
unsigned int bindport;
|
||||||
|
unsigned int log_verbosity;
|
||||||
|
|
||||||
|
int blocking;
|
||||||
|
int toaccept;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
||||||
|
*sshbind);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BIND_H_ */
|
||||||
73
include/libssh/buffer.h
Normal file
73
include/libssh/buffer.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 BUFFER_H_
|
||||||
|
#define BUFFER_H_
|
||||||
|
|
||||||
|
#include "libssh/libssh.h"
|
||||||
|
/*
|
||||||
|
* Describes a buffer state
|
||||||
|
* [XXXXXXXXXXXXDATA PAYLOAD XXXXXXXXXXXXXXXXXXXXXXXX]
|
||||||
|
* ^ ^ ^ ^]
|
||||||
|
* \_data points\_pos points here \_used points here | /
|
||||||
|
* here Allocated
|
||||||
|
*/
|
||||||
|
struct ssh_buffer_struct {
|
||||||
|
char *data;
|
||||||
|
uint32_t used;
|
||||||
|
uint32_t allocated;
|
||||||
|
uint32_t pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
|
||||||
|
LIBSSH_API void *ssh_buffer_get_begin(ssh_buffer buffer);
|
||||||
|
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
|
||||||
|
LIBSSH_API ssh_buffer ssh_buffer_new(void);
|
||||||
|
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
||||||
|
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
||||||
|
int buffer_add_u16(ssh_buffer buffer, uint16_t data);
|
||||||
|
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
|
||||||
|
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
|
||||||
|
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||||
|
int buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||||
|
int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
|
||||||
|
int buffer_reinit(ssh_buffer buffer);
|
||||||
|
|
||||||
|
/* buffer_get_rest returns a pointer to the current position into the buffer */
|
||||||
|
void *buffer_get_rest(ssh_buffer buffer);
|
||||||
|
/* buffer_get_rest_len returns the number of bytes which can be read */
|
||||||
|
uint32_t buffer_get_rest_len(ssh_buffer buffer);
|
||||||
|
|
||||||
|
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
|
||||||
|
int buffer_get_u8(ssh_buffer buffer, uint8_t *data);
|
||||||
|
int buffer_get_u32(ssh_buffer buffer, uint32_t *data);
|
||||||
|
int buffer_get_u64(ssh_buffer buffer, uint64_t *data);
|
||||||
|
|
||||||
|
uint32_t buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
|
||||||
|
/* buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
|
||||||
|
ssh_string buffer_get_ssh_string(ssh_buffer buffer);
|
||||||
|
/* gets a string out of a SSH-1 mpint */
|
||||||
|
ssh_string buffer_get_mpint(ssh_buffer buffer);
|
||||||
|
/* buffer_pass_bytes acts as if len bytes have been read (used for padding) */
|
||||||
|
uint32_t buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
|
||||||
|
uint32_t buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
|
||||||
|
|
||||||
|
#endif /* BUFFER_H_ */
|
||||||
463
include/libssh/callbacks.h
Normal file
463
include/libssh/callbacks.h
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 Aris Adamantiadis <aris@0xbadc0de.be>
|
||||||
|
*
|
||||||
|
* The SSH Library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* The SSH Library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with the SSH Library; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* callback.h
|
||||||
|
* This file includes the public declarations for the libssh callback mechanism
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SSH_CALLBACK_H
|
||||||
|
#define _SSH_CALLBACK_H
|
||||||
|
|
||||||
|
#include <libssh/libssh.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup libssh_callbacks The libssh callbacks
|
||||||
|
* @ingroup libssh
|
||||||
|
*
|
||||||
|
* Callback which can be replaced in libssh.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief callback to process simple codes
|
||||||
|
* @param code value to transmit
|
||||||
|
* @param user Userdata to pass in callback
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_callback_int) (int code, void *user);
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief callback for data received messages.
|
||||||
|
* @param data data retrieved from the socket or stream
|
||||||
|
* @param len number of bytes available from this stream
|
||||||
|
* @param user user-supplied pointer sent along with all callback messages
|
||||||
|
* @returns number of bytes processed by the callee. The remaining bytes will
|
||||||
|
* be sent in the next callback message, when more data is available.
|
||||||
|
*/
|
||||||
|
typedef int (*ssh_callback_data) (const void *data, size_t len, void *user);
|
||||||
|
|
||||||
|
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
|
||||||
|
|
||||||
|
typedef int (*ssh_message_callback) (ssh_session, ssh_message message, void *user);
|
||||||
|
typedef int (*ssh_channel_callback_int) (ssh_channel channel, int code, void *user);
|
||||||
|
typedef int (*ssh_channel_callback_data) (ssh_channel channel, int code, void *data, size_t len, void *user);
|
||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
/**
|
||||||
|
* @brief SSH log callback. All logging messages will go through this callback
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param priority Priority of the log, the smaller being the more important
|
||||||
|
* @param message the actual message
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_log_callback) (ssh_session session, int priority,
|
||||||
|
const char *message, void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH Connection status callback.
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param status Percentage of connection status, going from 0.0 to 1.0
|
||||||
|
* once connection is done.
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_status_callback) (ssh_session session, float status,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH global request callback. All global request will go through this
|
||||||
|
* callback.
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param message the actual message
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_global_request_callback) (ssh_session session,
|
||||||
|
ssh_message message, void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The structure to replace libssh functions with appropriate callbacks.
|
||||||
|
*/
|
||||||
|
struct ssh_callbacks_struct {
|
||||||
|
/** DON'T SET THIS use ssh_callbacks_init() instead. */
|
||||||
|
size_t size;
|
||||||
|
/**
|
||||||
|
* User-provided data. User is free to set anything he wants here
|
||||||
|
*/
|
||||||
|
void *userdata;
|
||||||
|
/**
|
||||||
|
* This functions will be called if e.g. a keyphrase is needed.
|
||||||
|
*/
|
||||||
|
ssh_auth_callback auth_function;
|
||||||
|
/**
|
||||||
|
* This function will be called each time a loggable event happens.
|
||||||
|
*/
|
||||||
|
ssh_log_callback log_function;
|
||||||
|
/**
|
||||||
|
* This function gets called during connection time to indicate the
|
||||||
|
* percentage of connection steps completed.
|
||||||
|
*/
|
||||||
|
void (*connect_status_function)(void *userdata, float status);
|
||||||
|
/**
|
||||||
|
* This function will be called each time a global request is received.
|
||||||
|
*/
|
||||||
|
ssh_global_request_callback global_request_function;
|
||||||
|
};
|
||||||
|
typedef struct ssh_callbacks_struct *ssh_callbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are the callbacks exported by the socket structure
|
||||||
|
* They are called by the socket module when a socket event appears
|
||||||
|
*/
|
||||||
|
struct ssh_socket_callbacks_struct {
|
||||||
|
/**
|
||||||
|
* User-provided data. User is free to set anything he wants here
|
||||||
|
*/
|
||||||
|
void *userdata;
|
||||||
|
/**
|
||||||
|
* This function will be called each time data appears on socket. The data
|
||||||
|
* not consumed will appear on the next data event.
|
||||||
|
*/
|
||||||
|
ssh_callback_data data;
|
||||||
|
/** This function will be called each time a controlflow state changes, i.e.
|
||||||
|
* the socket is available for reading or writing.
|
||||||
|
*/
|
||||||
|
ssh_callback_int controlflow;
|
||||||
|
/** This function will be called each time an exception appears on socket. An
|
||||||
|
* exception can be a socket problem (timeout, ...) or an end-of-file.
|
||||||
|
*/
|
||||||
|
ssh_callback_int_int exception;
|
||||||
|
/** This function is called when the ssh_socket_connect was used on the socket
|
||||||
|
* on nonblocking state, and the connection successed.
|
||||||
|
*/
|
||||||
|
ssh_callback_int_int connected;
|
||||||
|
};
|
||||||
|
typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
|
||||||
|
|
||||||
|
#define SSH_SOCKET_FLOW_WRITEWILLBLOCK 1
|
||||||
|
#define SSH_SOCKET_FLOW_WRITEWONTBLOCK 2
|
||||||
|
|
||||||
|
#define SSH_SOCKET_EXCEPTION_EOF 1
|
||||||
|
#define SSH_SOCKET_EXCEPTION_ERROR 2
|
||||||
|
|
||||||
|
#define SSH_SOCKET_CONNECTED_OK 1
|
||||||
|
#define SSH_SOCKET_CONNECTED_ERROR 2
|
||||||
|
#define SSH_SOCKET_CONNECTED_TIMEOUT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes an ssh_callbacks_struct
|
||||||
|
* A call to this macro is mandatory when you have set a new
|
||||||
|
* ssh_callback_struct structure. Its goal is to maintain the binary
|
||||||
|
* compatibility with future versions of libssh as the structure
|
||||||
|
* evolves with time.
|
||||||
|
*/
|
||||||
|
#define ssh_callbacks_init(p) do {\
|
||||||
|
(p)->size=sizeof(*(p)); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @brief tests if a callback can be called without crash
|
||||||
|
* verifies that the struct size if big enough
|
||||||
|
* verifies that the callback pointer exists
|
||||||
|
* @param p callback pointer
|
||||||
|
* @param c callback name
|
||||||
|
* @returns nonzero if callback can be called
|
||||||
|
*/
|
||||||
|
#define ssh_callbacks_exists(p,c) (\
|
||||||
|
(p != NULL) && ( (char *)&((p)-> c) < (char *)(p) + (p)->size ) && \
|
||||||
|
((p)-> c != NULL) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/** @brief Prototype for a packet callback, to be called when a new packet arrives
|
||||||
|
* @param session The current session of the packet
|
||||||
|
* @param type packet type (see ssh2.h)
|
||||||
|
* @param packet buffer containing the packet, excluding size, type and padding fields
|
||||||
|
* @param user user argument to the callback
|
||||||
|
* and are called each time a packet shows up
|
||||||
|
* @returns SSH_PACKET_USED Packet was parsed and used
|
||||||
|
* @returns SSH_PACKET_NOT_USED Packet was not used or understood, processing must continue
|
||||||
|
*/
|
||||||
|
typedef int (*ssh_packet_callback) (ssh_session session, uint8_t type, ssh_buffer packet, void *user);
|
||||||
|
|
||||||
|
/** return values for a ssh_packet_callback */
|
||||||
|
/** Packet was used and should not be parsed by another callback */
|
||||||
|
#define SSH_PACKET_USED 1
|
||||||
|
/** Packet was not used and should be passed to any other callback
|
||||||
|
* available */
|
||||||
|
#define SSH_PACKET_NOT_USED 2
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief This macro declares a packet callback handler
|
||||||
|
* @code
|
||||||
|
* SSH_PACKET_CALLBACK(mycallback){
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#define SSH_PACKET_CALLBACK(name) \
|
||||||
|
int name (ssh_session session, uint8_t type, ssh_buffer packet, void *user)
|
||||||
|
|
||||||
|
struct ssh_packet_callbacks_struct {
|
||||||
|
/** Index of the first packet type being handled */
|
||||||
|
uint8_t start;
|
||||||
|
/** Number of packets being handled by this callback struct */
|
||||||
|
uint8_t n_callbacks;
|
||||||
|
/** A pointer to n_callbacks packet callbacks */
|
||||||
|
ssh_packet_callback *callbacks;
|
||||||
|
/**
|
||||||
|
* User-provided data. User is free to set anything he wants here
|
||||||
|
*/
|
||||||
|
void *user;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the session callback functions.
|
||||||
|
*
|
||||||
|
* This functions sets the callback structure to use your own callback
|
||||||
|
* functions for auth, logging and status.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* struct ssh_callbacks_struct cb = {
|
||||||
|
* .userdata = data,
|
||||||
|
* .auth_function = my_auth_function
|
||||||
|
* };
|
||||||
|
* ssh_callbacks_init(&cb);
|
||||||
|
* ssh_set_callbacks(session, &cb);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param session The session to set the callback structure.
|
||||||
|
*
|
||||||
|
* @param cb The callback structure itself.
|
||||||
|
*
|
||||||
|
* @return SSH_OK on success, SSH_ERROR on error.
|
||||||
|
*/
|
||||||
|
LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH channel data callback. Called when data is available on a channel
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param channel the actual channel
|
||||||
|
* @param data the data that has been read on the channel
|
||||||
|
* @param len the length of the data
|
||||||
|
* @param is_stderr is 0 for stdout or 1 for stderr
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef int (*ssh_channel_data_callback) (ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
void *data,
|
||||||
|
uint32_t len,
|
||||||
|
int is_stderr,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH channel eof callback. Called when a channel receives EOF
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param channel the actual channel
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_channel_eof_callback) (ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH channel close callback. Called when a channel is closed by remote peer
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param channel the actual channel
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_channel_close_callback) (ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH channel signal callback. Called when a channel has received a signal
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param channel the actual channel
|
||||||
|
* @param signal the signal name (without the SIG prefix)
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_channel_signal_callback) (ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
const char *signal,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH channel exit status callback. Called when a channel has received an exit status
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param channel the actual channel
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
int exit_status,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSH channel exit signal callback. Called when a channel has received an exit signal
|
||||||
|
* @param session Current session handler
|
||||||
|
* @param channel the actual channel
|
||||||
|
* @param signal the signal name (without the SIG prefix)
|
||||||
|
* @param core a boolean telling wether a core has been dumped or not
|
||||||
|
* @param errmsg the description of the exception
|
||||||
|
* @param lang the language of the description (format: RFC 3066)
|
||||||
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
|
*/
|
||||||
|
typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
|
||||||
|
ssh_channel channel,
|
||||||
|
const char *signal,
|
||||||
|
int core,
|
||||||
|
const char *errmsg,
|
||||||
|
const char *lang,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
struct ssh_channel_callbacks_struct {
|
||||||
|
/** DON'T SET THIS use ssh_callbacks_init() instead. */
|
||||||
|
size_t size;
|
||||||
|
/**
|
||||||
|
* User-provided data. User is free to set anything he wants here
|
||||||
|
*/
|
||||||
|
void *userdata;
|
||||||
|
/**
|
||||||
|
* This functions will be called when there is data available.
|
||||||
|
*/
|
||||||
|
ssh_channel_data_callback channel_data_function;
|
||||||
|
/**
|
||||||
|
* This functions will be called when the channel has received an EOF.
|
||||||
|
*/
|
||||||
|
ssh_channel_eof_callback channel_eof_function;
|
||||||
|
/**
|
||||||
|
* This functions will be called when the channel has been closed by remote
|
||||||
|
*/
|
||||||
|
ssh_channel_close_callback channel_close_function;
|
||||||
|
/**
|
||||||
|
* This functions will be called when a signal has been received
|
||||||
|
*/
|
||||||
|
ssh_channel_signal_callback channel_signal_function;
|
||||||
|
/**
|
||||||
|
* This functions will be called when an exit status has been received
|
||||||
|
*/
|
||||||
|
ssh_channel_exit_status_callback channel_exit_status_function;
|
||||||
|
/**
|
||||||
|
* This functions will be called when an exit signal has been received
|
||||||
|
*/
|
||||||
|
ssh_channel_exit_signal_callback channel_exit_signal_function;
|
||||||
|
};
|
||||||
|
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the channel callback functions.
|
||||||
|
*
|
||||||
|
* This functions sets the callback structure to use your own callback
|
||||||
|
* functions for channel data and exceptions
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* struct ssh_channel_callbacks_struct cb = {
|
||||||
|
* .userdata = data,
|
||||||
|
* .channel_data = my_channel_data_function
|
||||||
|
* };
|
||||||
|
* ssh_callbacks_init(&cb);
|
||||||
|
* ssh_set_channel_callbacks(channel, &cb);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param channel The channel to set the callback structure.
|
||||||
|
*
|
||||||
|
* @param cb The callback structure itself.
|
||||||
|
*
|
||||||
|
* @return SSH_OK on success, SSH_ERROR on error.
|
||||||
|
*/
|
||||||
|
LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel,
|
||||||
|
ssh_channel_callbacks cb);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @group libssh_threads
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (*ssh_thread_callback) (void **lock);
|
||||||
|
|
||||||
|
typedef unsigned long (*ssh_thread_id_callback) (void);
|
||||||
|
struct ssh_threads_callbacks_struct {
|
||||||
|
const char *type;
|
||||||
|
ssh_thread_callback mutex_init;
|
||||||
|
ssh_thread_callback mutex_destroy;
|
||||||
|
ssh_thread_callback mutex_lock;
|
||||||
|
ssh_thread_callback mutex_unlock;
|
||||||
|
ssh_thread_id_callback thread_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sets the thread callbacks necessary if your program is using
|
||||||
|
* libssh in a multithreaded fashion. This function must be called first,
|
||||||
|
* outside of any threading context (in your main() for instance), before
|
||||||
|
* ssh_init().
|
||||||
|
* @param cb pointer to a ssh_threads_callbacks_struct structure, which contains
|
||||||
|
* the different callbacks to be set.
|
||||||
|
* @see ssh_threads_callbacks_struct
|
||||||
|
* @see SSH_THREADS_PTHREAD
|
||||||
|
*/
|
||||||
|
LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
|
||||||
|
*cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns a pointer on the pthread threads callbacks, to be used with
|
||||||
|
* ssh_threads_set_callbacks.
|
||||||
|
* @warning you have to link with the library ssh_threads.
|
||||||
|
* @see ssh_threads_set_callbacks
|
||||||
|
*/
|
||||||
|
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns a pointer on the noop threads callbacks, to be used with
|
||||||
|
* ssh_threads_set_callbacks. These callbacks do nothing and are being used by
|
||||||
|
* default.
|
||||||
|
* @see ssh_threads_set_callbacks
|
||||||
|
*/
|
||||||
|
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_SSH_CALLBACK_H */
|
||||||
|
|
||||||
|
/* @} */
|
||||||
109
include/libssh/channels.h
Normal file
109
include/libssh/channels.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 CHANNELS_H_
|
||||||
|
#define CHANNELS_H_
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* Describes the different possible states in a
|
||||||
|
* outgoing (client) channel request
|
||||||
|
*/
|
||||||
|
enum ssh_channel_request_state_e {
|
||||||
|
/** No request has been made */
|
||||||
|
SSH_CHANNEL_REQ_STATE_NONE = 0,
|
||||||
|
/** A request has been made and answer is pending */
|
||||||
|
SSH_CHANNEL_REQ_STATE_PENDING,
|
||||||
|
/** A request has been replied and accepted */
|
||||||
|
SSH_CHANNEL_REQ_STATE_ACCEPTED,
|
||||||
|
/** A request has been replied and refused */
|
||||||
|
SSH_CHANNEL_REQ_STATE_DENIED,
|
||||||
|
/** A request has been replied and an error happend */
|
||||||
|
SSH_CHANNEL_REQ_STATE_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ssh_channel_state_e {
|
||||||
|
SSH_CHANNEL_STATE_NOT_OPEN = 0,
|
||||||
|
SSH_CHANNEL_STATE_OPEN_DENIED,
|
||||||
|
SSH_CHANNEL_STATE_OPEN,
|
||||||
|
SSH_CHANNEL_STATE_CLOSED
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ssh_channel_struct {
|
||||||
|
ssh_session session; /* SSH_SESSION pointer */
|
||||||
|
uint32_t local_channel;
|
||||||
|
uint32_t local_window;
|
||||||
|
int local_eof;
|
||||||
|
uint32_t local_maxpacket;
|
||||||
|
|
||||||
|
uint32_t remote_channel;
|
||||||
|
uint32_t remote_window;
|
||||||
|
int remote_eof; /* end of file received */
|
||||||
|
uint32_t remote_maxpacket;
|
||||||
|
enum ssh_channel_state_e state;
|
||||||
|
int delayed_close;
|
||||||
|
ssh_buffer stdout_buffer;
|
||||||
|
ssh_buffer stderr_buffer;
|
||||||
|
void *userarg;
|
||||||
|
int version;
|
||||||
|
int blocking;
|
||||||
|
int exit_status;
|
||||||
|
enum ssh_channel_request_state_e request_state;
|
||||||
|
ssh_channel_callbacks callbacks;
|
||||||
|
};
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_success);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_failure);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_request_success);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_request_denied);
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(channel_rcv_change_window);
|
||||||
|
SSH_PACKET_CALLBACK(channel_rcv_eof);
|
||||||
|
SSH_PACKET_CALLBACK(channel_rcv_close);
|
||||||
|
SSH_PACKET_CALLBACK(channel_rcv_request);
|
||||||
|
SSH_PACKET_CALLBACK(channel_rcv_data);
|
||||||
|
|
||||||
|
ssh_channel ssh_channel_new(ssh_session session);
|
||||||
|
int channel_default_bufferize(ssh_channel channel, void *data, int len,
|
||||||
|
int is_stderr);
|
||||||
|
uint32_t ssh_channel_new_id(ssh_session session);
|
||||||
|
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
||||||
|
int channel_write_common(ssh_channel channel, const void *data,
|
||||||
|
uint32_t len, int is_stderr);
|
||||||
|
#ifdef WITH_SSH1
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_data1);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_close1);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_exist_status1);
|
||||||
|
|
||||||
|
/* channels1.c */
|
||||||
|
int channel_open_session1(ssh_channel channel);
|
||||||
|
int channel_request_pty_size1(ssh_channel channel, const char *terminal,
|
||||||
|
int cols, int rows);
|
||||||
|
int channel_change_pty_size1(ssh_channel channel, int cols, int rows);
|
||||||
|
int channel_request_shell1(ssh_channel channel);
|
||||||
|
int channel_request_exec1(ssh_channel channel, const char *cmd);
|
||||||
|
int channel_write1(ssh_channel channel, const void *data, int len);
|
||||||
|
ssh_channel ssh_get_channel1(ssh_session session);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CHANNELS_H_ */
|
||||||
@@ -1,44 +1,71 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2003 Aris Adamantiadis
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003,2009 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 cryptographic structures of libssh
|
||||||
|
*/
|
||||||
|
|
||||||
The SSH Library is free software; you can redistribute it and/or modify
|
#ifndef _CRYPTO_H_
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
#define _CRYPTO_H_
|
||||||
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
|
#include "config.h"
|
||||||
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
|
#ifdef HAVE_LIBGCRYPT
|
||||||
along with the SSH Library; see the file COPYING. If not, write to
|
#include <gcrypt.h>
|
||||||
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
|
#endif
|
||||||
|
#include "libssh/wrapper.h"
|
||||||
|
|
||||||
#ifdef cbc_encrypt
|
#ifdef cbc_encrypt
|
||||||
#undef cbc_encrypt
|
#undef cbc_encrypt
|
||||||
#endif
|
#endif
|
||||||
#ifdef cbc_decrypt
|
#ifdef cbc_decrypt
|
||||||
#undef cbc_decrypt
|
#undef cbc_decrypt
|
||||||
#endif
|
#endif
|
||||||
#ifdef des_set_key
|
|
||||||
#undef des_set_key
|
struct ssh_crypto_struct {
|
||||||
#endif
|
bignum e,f,x,k,y;
|
||||||
#ifdef GCRYPT
|
unsigned char session_id[SHA_DIGEST_LEN];
|
||||||
#include <gcrypt.h>
|
|
||||||
#endif
|
unsigned char encryptIV[SHA_DIGEST_LEN*2];
|
||||||
|
unsigned char decryptIV[SHA_DIGEST_LEN*2];
|
||||||
|
|
||||||
|
unsigned char decryptkey[SHA_DIGEST_LEN*2];
|
||||||
|
unsigned char encryptkey[SHA_DIGEST_LEN*2];
|
||||||
|
|
||||||
|
unsigned char encryptMAC[SHA_DIGEST_LEN];
|
||||||
|
unsigned char decryptMAC[SHA_DIGEST_LEN];
|
||||||
|
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
|
||||||
|
struct crypto_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
||||||
|
ssh_string server_pubkey;
|
||||||
|
const char *server_pubkey_type;
|
||||||
|
int do_compress_out; /* idem */
|
||||||
|
int do_compress_in; /* don't set them, set the option instead */
|
||||||
|
int delayed_compress_in; /* Use of zlib@openssh.org */
|
||||||
|
int delayed_compress_out;
|
||||||
|
void *compress_out_ctx; /* don't touch it */
|
||||||
|
void *compress_in_ctx; /* really, don't */
|
||||||
|
};
|
||||||
|
|
||||||
struct crypto_struct {
|
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 blocksize; /* blocksize of the algo */
|
||||||
unsigned int keylen; /* length of the key structure */
|
unsigned int keylen; /* length of the key structure */
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
@@ -48,15 +75,23 @@ struct crypto_struct {
|
|||||||
#endif
|
#endif
|
||||||
unsigned int keysize; /* bytes of key used. != keylen */
|
unsigned int keysize; /* bytes of key used. != keylen */
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV); /* sets the new key for immediate use */
|
/* sets the new key for immediate use */
|
||||||
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
|
int (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
|
||||||
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
|
int (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
|
||||||
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
|
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
|
#elif defined HAVE_LIBCRYPTO
|
||||||
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key); /* sets the new key for immediate use */
|
/* sets the new key for immediate use */
|
||||||
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
|
int (*set_encrypt_key)(struct crypto_struct *cipher, void *key);
|
||||||
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
|
int (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
|
||||||
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
|
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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* vim: set ts=2 sw=2 et cindent: */
|
||||||
|
#endif /* _CRYPTO_H_ */
|
||||||
|
|||||||
57
include/libssh/dh.h
Normal file
57
include/libssh/dh.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 DH_H_
|
||||||
|
#define DH_H_
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
/* DH key generation */
|
||||||
|
#include "libssh/keys.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ssh_string dh_get_e(ssh_session session);
|
||||||
|
ssh_string dh_get_f(ssh_session session);
|
||||||
|
int dh_import_f(ssh_session session,ssh_string f_string);
|
||||||
|
int dh_import_e(ssh_session session, ssh_string e_string);
|
||||||
|
void dh_import_pubkey(ssh_session session,ssh_string pubkey_string);
|
||||||
|
int dh_build_k(ssh_session session);
|
||||||
|
int make_sessionid(ssh_session session);
|
||||||
|
/* add data for the final cookie */
|
||||||
|
int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||||
|
int hashbufout_add_cookie(ssh_session session);
|
||||||
|
int generate_session_keys(ssh_session session);
|
||||||
|
int sig_verify(ssh_session session, ssh_public_key pubkey,
|
||||||
|
SIGNATURE *signature, unsigned char *digest, int size);
|
||||||
|
/* returns 1 if server signature ok, 0 otherwise. The NEXT crypto is checked, not the current one */
|
||||||
|
int signature_verify(ssh_session session,ssh_string signature);
|
||||||
|
bignum make_string_bn(ssh_string string);
|
||||||
|
ssh_string make_bignum_string(bignum num);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DH_H_ */
|
||||||
33
include/libssh/kex.h
Normal file
33
include/libssh/kex.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 KEX_H_
|
||||||
|
#define KEX_H_
|
||||||
|
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
#include "libssh/callbacks.h"
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
|
||||||
|
#ifdef WITH_SSH1
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_publickey1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* KEX_H_ */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user