mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-08-02 09:07:23 +02:00
Compare commits
2720 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
601d9b0e02 | ||
![]() |
f209e00dde | ||
![]() |
86523b0597 | ||
![]() |
85a2637fc5 | ||
![]() |
2f991918b1 | ||
![]() |
5b5a9b60fb | ||
![]() |
5287809043 | ||
![]() |
ea9ff2dcaf | ||
![]() |
9dce36fe3d | ||
![]() |
c4718a5355 | ||
![]() |
c9c8790ff2 | ||
![]() |
d135bfc4b8 | ||
![]() |
e269beadba | ||
![]() |
3e55fc855a | ||
![]() |
c8d9936f9d | ||
![]() |
79940956ef | ||
![]() |
9f98c6c3c8 | ||
![]() |
93eef7b02d | ||
![]() |
26ed1f8b9f | ||
![]() |
243db1d256 | ||
![]() |
5224b0b0e7 | ||
![]() |
3267d356d2 | ||
![]() |
78f4e6240e | ||
![]() |
36b1086f60 | ||
![]() |
266eb405f2 | ||
![]() |
0a8e646231 | ||
![]() |
8ebc4780ea | ||
![]() |
4ded663e68 | ||
![]() |
c00bc3a065 | ||
![]() |
f469db8a95 | ||
![]() |
c3a27354ff | ||
![]() |
d927fd07c1 | ||
![]() |
8dff156eb6 | ||
![]() |
e5c41a8024 | ||
![]() |
603d6b2881 | ||
![]() |
d1aa4009bc | ||
![]() |
3c5081c7a6 | ||
![]() |
7d5bcd738b | ||
![]() |
0a93c55552 | ||
![]() |
7f9ea7640d | ||
![]() |
c52d913f20 | ||
![]() |
651b647570 | ||
![]() |
8cf9734d2b | ||
![]() |
d70fbade44 | ||
![]() |
f0e515b6ff | ||
![]() |
47ef40d645 | ||
![]() |
9e10efbef5 | ||
![]() |
224afbb9ca | ||
![]() |
bf69e6210c | ||
![]() |
258482d509 | ||
![]() |
1caad4ca88 | ||
![]() |
59464a0ca4 | ||
![]() |
93b25c87d6 | ||
![]() |
e971ef71d5 | ||
![]() |
bff5006b38 | ||
![]() |
ea571861d6 | ||
![]() |
f3e4263f51 | ||
![]() |
77639d2d45 | ||
![]() |
1662707f22 | ||
![]() |
5f4bf2a5e5 | ||
![]() |
40af18f96a | ||
![]() |
ab4fa30c7e | ||
![]() |
43f73823ec | ||
![]() |
f4439fd2b6 | ||
![]() |
bf82aff039 | ||
![]() |
4b535cee1f | ||
![]() |
7144741537 | ||
![]() |
64b872f363 | ||
![]() |
83a2457550 | ||
![]() |
43f895142c | ||
![]() |
c352b35bf1 | ||
![]() |
d4bba5c838 | ||
![]() |
1dd9f94713 | ||
![]() |
c458e6612d | ||
![]() |
45db339dcd | ||
![]() |
887d8c8fe8 | ||
![]() |
c6932efa30 | ||
![]() |
f3ba82b0e1 | ||
![]() |
a26fcd8f2d | ||
![]() |
ab49b404fd | ||
![]() |
9bc71b2853 | ||
![]() |
5b104967ce | ||
![]() |
4680c0c13b | ||
![]() |
c36358cc7c | ||
![]() |
235f6e5f14 | ||
![]() |
980e132f48 | ||
![]() |
900aa5810e | ||
![]() |
8cf83d6620 | ||
![]() |
ee52bc60ff | ||
![]() |
3f4a29651e | ||
![]() |
f58cad8cd9 | ||
![]() |
b9c3feb198 | ||
![]() |
94ebc9d90b | ||
![]() |
b0759ebbb2 | ||
![]() |
f2ac45eb52 | ||
![]() |
7c5b40ff6b | ||
![]() |
7465abe5f8 | ||
![]() |
a910a21beb | ||
![]() |
c40e665094 | ||
![]() |
bb57d61add | ||
![]() |
fc2965649c | ||
![]() |
fa25de4ad1 | ||
![]() |
901305dcdd | ||
![]() |
b4a4495537 | ||
![]() |
ccd91fe556 | ||
![]() |
e89e4d692c | ||
![]() |
0868418ad1 | ||
![]() |
d81de65533 | ||
![]() |
65073ffcfa | ||
![]() |
d0b9fc84b5 | ||
![]() |
e0727bfeb6 | ||
![]() |
8e10e00904 | ||
![]() |
a2b2f66c4c | ||
![]() |
ca9b7ccaf6 | ||
![]() |
354bce64dd | ||
![]() |
ff4edacb42 | ||
![]() |
a6edf6f31e | ||
![]() |
31787e3788 | ||
![]() |
e98a76aefb | ||
![]() |
4a04d41409 | ||
![]() |
8bb22a722b | ||
![]() |
c459dc75c0 | ||
![]() |
1a554a300d | ||
![]() |
6cc6a8a2cb | ||
![]() |
b0a011d8f4 | ||
![]() |
a27b7823df | ||
![]() |
14b9291490 | ||
![]() |
354200f9da | ||
![]() |
acc5daf0e2 | ||
![]() |
5c22ab6621 | ||
![]() |
af99fbb6c0 | ||
![]() |
4b2c6de45c | ||
![]() |
30cc3ecf7b | ||
![]() |
87a8884f25 | ||
![]() |
4f2bf0b0a6 | ||
![]() |
184c3efcb3 | ||
![]() |
3f06d0128a | ||
![]() |
3bc8b90c0e | ||
![]() |
f6cfcb8ca2 | ||
![]() |
163c2ebd37 | ||
![]() |
154a29be05 | ||
![]() |
23cf6107c6 | ||
![]() |
c66438e34f | ||
![]() |
c778ddf0c2 | ||
![]() |
2ad9561069 | ||
![]() |
f4ec1ee509 | ||
![]() |
b98bc30c23 | ||
![]() |
4c3cbdc8d3 | ||
![]() |
61cba6bd28 | ||
![]() |
574b0d80dc | ||
![]() |
0c228f4465 | ||
![]() |
1ac3915641 | ||
![]() |
e9ac7ab378 | ||
![]() |
7ba5b0f924 | ||
![]() |
54b6330845 | ||
![]() |
b5aff74e3b | ||
![]() |
294426b450 | ||
![]() |
4482b8dc24 | ||
![]() |
bf2441e311 | ||
![]() |
95a9e052de | ||
![]() |
5c7777ff0f | ||
![]() |
d223f49fbc | ||
![]() |
e5c0e18751 | ||
![]() |
5f74ed75e7 | ||
![]() |
17fbab110c | ||
![]() |
02ec70e290 | ||
![]() |
5118f08d79 | ||
![]() |
e565b75032 | ||
![]() |
db9c0480ef | ||
![]() |
10f5bc9be7 | ||
![]() |
548ef00291 | ||
![]() |
93806cd522 | ||
![]() |
1a3a035404 | ||
![]() |
6d94599977 | ||
![]() |
c639bf0b19 | ||
![]() |
514e483bc3 | ||
![]() |
7604762013 | ||
![]() |
f81855349a | ||
![]() |
1455988efb | ||
![]() |
d2f14b2951 | ||
![]() |
73c79dbd41 | ||
![]() |
0d7ff8ebd9 | ||
![]() |
05166d0999 | ||
![]() |
0e3322b5da | ||
![]() |
a7d8b9a068 | ||
![]() |
b31e298df4 | ||
![]() |
a73b877c5b | ||
![]() |
68e1d055dd | ||
![]() |
aca92df19b | ||
![]() |
560ad581ad | ||
![]() |
fe2a91ae11 | ||
![]() |
cd1507620f | ||
![]() |
7ee7848a96 | ||
![]() |
be7b19d587 | ||
![]() |
16f5bbc20a | ||
![]() |
8a27cff8c0 | ||
![]() |
d43f05224d | ||
![]() |
96492483ee | ||
![]() |
194d8a3052 | ||
![]() |
d500a44ff3 | ||
![]() |
faa6a392e4 | ||
![]() |
e33fa63243 | ||
![]() |
d7f669dd7c | ||
![]() |
993e48cab2 | ||
![]() |
9762c61b4d | ||
![]() |
d8803b309d | ||
![]() |
f9a55e3728 | ||
![]() |
a63fd6abb9 | ||
![]() |
eff2a2afcf | ||
![]() |
5cdad6ab86 | ||
![]() |
30ca00d2c4 | ||
![]() |
fbf8ed4140 | ||
![]() |
64d68b4f08 | ||
![]() |
91f7253ae1 | ||
![]() |
06c8080664 | ||
![]() |
b7da34a5d2 | ||
![]() |
a972b77dc2 | ||
![]() |
d27de1b111 | ||
![]() |
d2cda84383 | ||
![]() |
af1b017003 | ||
![]() |
556f90ec28 | ||
![]() |
22f238706c | ||
![]() |
906afefbf3 | ||
![]() |
38c36ff145 | ||
![]() |
9ea0117dc4 | ||
![]() |
4f81953338 | ||
![]() |
ffc6d6325d | ||
![]() |
6d46698494 | ||
![]() |
b54dcafa80 | ||
![]() |
ac0f13798b | ||
![]() |
51771694cd | ||
![]() |
9232991e25 | ||
![]() |
71dc347582 | ||
![]() |
31b18a8c8b | ||
![]() |
d92e4c5663 | ||
![]() |
300f0ddac5 | ||
![]() |
77cf621f15 | ||
![]() |
5c824cc24e | ||
![]() |
3fd5250c0d | ||
![]() |
8de70b1952 | ||
![]() |
35808debae | ||
![]() |
685d105739 | ||
![]() |
43d5e89fac | ||
![]() |
88a71eca72 | ||
![]() |
b4983fdcae | ||
![]() |
16a05316b2 | ||
![]() |
1dda441b85 | ||
![]() |
5cf826c73a | ||
![]() |
9a5c64481e | ||
![]() |
6de09a5eba | ||
![]() |
03645acf4f | ||
![]() |
c1e2a6c44c | ||
![]() |
b3e7b7539e | ||
![]() |
fdbbd8b383 | ||
![]() |
70d1d71612 | ||
![]() |
4bfc794a37 | ||
![]() |
8a1f8d1a9a | ||
![]() |
b05c1cafcd | ||
![]() |
3be01a83ab | ||
![]() |
26efca80d7 | ||
![]() |
5fb3ac5937 | ||
![]() |
9274f70fec | ||
![]() |
78bdb26296 | ||
![]() |
3132e9f595 | ||
![]() |
b9e4dfbd40 | ||
![]() |
2e80a09184 | ||
![]() |
49cddea10b | ||
![]() |
be3f6a2ca0 | ||
![]() |
88d3261bc2 | ||
![]() |
e5816b024f | ||
![]() |
9cdc726dc1 | ||
![]() |
e196cb1178 | ||
![]() |
468cecdbca | ||
![]() |
546dea11b6 | ||
![]() |
da13aab419 | ||
![]() |
ccd702f7da | ||
![]() |
6365c1f6de | ||
![]() |
2f2b5740da | ||
![]() |
6b94ab3889 | ||
![]() |
6bedcb4622 | ||
![]() |
121c2c5653 | ||
![]() |
eb3345b51b | ||
![]() |
795f57e816 | ||
![]() |
71a7190ed2 | ||
![]() |
405b897687 | ||
![]() |
62e2a3535d | ||
![]() |
d9aaf6c842 | ||
![]() |
b7559d68c7 | ||
![]() |
8bb3e3c4fa | ||
![]() |
c76f7eac05 | ||
![]() |
c2ad0006eb | ||
![]() |
5fcfb430b2 | ||
![]() |
3a17c8e3c5 | ||
![]() |
6febe5bed1 | ||
![]() |
338577bb3a | ||
![]() |
83c032a583 | ||
![]() |
d34b4e16e0 | ||
![]() |
52a47c9fd4 | ||
![]() |
816d258cab | ||
![]() |
5067654a6d | ||
![]() |
aef394895d | ||
![]() |
cdbd59103e | ||
![]() |
52c6a6b8ea | ||
![]() |
42273fd122 | ||
![]() |
14aa333a39 | ||
![]() |
ee52968043 | ||
![]() |
d13af0a4a2 | ||
![]() |
9f18bf402c | ||
![]() |
9d4c34dc7a | ||
![]() |
e296a61e3f | ||
![]() |
82161909a1 | ||
![]() |
c2ef5f3f68 | ||
![]() |
fba4ee90d0 | ||
![]() |
a559bd7c40 | ||
![]() |
988f68e916 | ||
![]() |
b38f71f221 | ||
![]() |
3f04bc427d | ||
![]() |
3ab09e0ae2 | ||
![]() |
cc0fcb2bb4 | ||
![]() |
b1edef3a14 | ||
![]() |
c0058c07bf | ||
![]() |
9f31663e21 | ||
![]() |
793228028d | ||
![]() |
d4c68d7d83 | ||
![]() |
77cdbd186b | ||
![]() |
98ae3d4197 | ||
![]() |
d8a6fb86c1 | ||
![]() |
32f3745745 | ||
![]() |
c54ef5a8da | ||
![]() |
a507c08bfe | ||
![]() |
ba5a6df2d1 | ||
![]() |
6315b42861 | ||
![]() |
42b4da1be2 | ||
![]() |
bcfbaa096d | ||
![]() |
593c9dee6c | ||
![]() |
aa0a439856 | ||
![]() |
1fe68aef0b | ||
![]() |
643503eeea | ||
![]() |
085a2511f6 | ||
![]() |
6415420f1c | ||
![]() |
1a79092383 | ||
![]() |
f52180d41c | ||
![]() |
197087d081 | ||
![]() |
d03b06db85 | ||
![]() |
4b3e82f742 | ||
![]() |
a6638513d4 | ||
![]() |
5abf54f2dc | ||
![]() |
7080a4453e | ||
![]() |
8f7443b0b3 | ||
![]() |
407a8a4441 | ||
![]() |
705898d1db | ||
![]() |
aaf1d91d51 | ||
![]() |
b0ad6158e1 | ||
![]() |
0a3797a4d4 | ||
![]() |
77e5c94dc6 | ||
![]() |
593fad5260 | ||
![]() |
a2fff11823 | ||
![]() |
cfb468e44d | ||
![]() |
a5f5578a61 | ||
![]() |
cc371641ed | ||
![]() |
9ba6dac066 | ||
![]() |
ba9717d445 | ||
![]() |
e89ba32d30 | ||
![]() |
a938313cba | ||
![]() |
390fd58cad | ||
![]() |
0f1d9685e7 | ||
![]() |
8f5109c439 | ||
![]() |
7a76385ec9 | ||
![]() |
688d277008 | ||
![]() |
5af1fe34b6 | ||
![]() |
63e35dbd88 | ||
![]() |
60e165095a | ||
![]() |
da94b2c6a9 | ||
![]() |
3349cdd5f4 | ||
![]() |
e8e5d91e5a | ||
![]() |
0979ff697a | ||
![]() |
393b6ee87b | ||
![]() |
56dac6744b | ||
![]() |
7b0cda76a9 | ||
![]() |
4efd1a1702 | ||
![]() |
cf137f4199 | ||
![]() |
0a0a257e1e | ||
![]() |
4f80e8baef | ||
![]() |
6b677e8db0 | ||
![]() |
a7fe6a9c12 | ||
![]() |
d756e60f24 | ||
![]() |
65a03d8049 | ||
![]() |
5a426433dd | ||
![]() |
84d018e722 | ||
![]() |
0dd2f0000e | ||
![]() |
ded1a35c41 | ||
![]() |
3524b5ef43 | ||
![]() |
737ebf437f | ||
![]() |
c1d40e2263 | ||
![]() |
62dad5e792 | ||
![]() |
2d26304663 | ||
![]() |
195d1f8720 | ||
![]() |
0bb181a368 | ||
![]() |
788c7ed010 | ||
![]() |
fda946e070 | ||
![]() |
ba0d35ff38 | ||
![]() |
305c4113e8 | ||
![]() |
78a39e926f | ||
![]() |
52e6a7c2ee | ||
![]() |
8ab24b423b | ||
![]() |
e3b5522769 | ||
![]() |
bdaae53cf8 | ||
![]() |
8d68b33e76 | ||
![]() |
290f294c60 | ||
![]() |
5ce1c0d001 | ||
![]() |
b10ef09186 | ||
![]() |
5a4fc931e7 | ||
![]() |
44e9816dcb | ||
![]() |
a40d5199a8 | ||
![]() |
400782b6e4 | ||
![]() |
ca0806438b | ||
![]() |
aaaa3d1800 | ||
![]() |
5e1f19fca7 | ||
![]() |
5e0a97b197 | ||
![]() |
cac10b52fc | ||
![]() |
4b147217ac | ||
![]() |
6afda046c2 | ||
![]() |
87055f5a02 | ||
![]() |
6a60cb5a32 | ||
![]() |
fa14ac125e | ||
![]() |
00ffb056e8 | ||
![]() |
aa116ba522 | ||
![]() |
3c02f387cb | ||
![]() |
c8a86edffe | ||
![]() |
e2f28312e2 | ||
![]() |
485f9f56bf | ||
![]() |
30c6a10f28 | ||
![]() |
a14d78596d | ||
![]() |
972d277363 | ||
![]() |
c59669a366 | ||
![]() |
28798990d2 | ||
![]() |
05c1d34c6e | ||
![]() |
708a8feaba | ||
![]() |
1aa83722a0 | ||
![]() |
904373eee7 | ||
![]() |
7498eaae62 | ||
![]() |
d12d8bec85 | ||
![]() |
afc8f53fd3 | ||
![]() |
e1c2706674 | ||
![]() |
bef70275f7 | ||
![]() |
dbce8f9ff9 | ||
![]() |
13952ff350 | ||
![]() |
2be49a93ba | ||
![]() |
3b6d279184 | ||
![]() |
6e2dacb0ec | ||
![]() |
8d2e35b2d4 | ||
![]() |
2f4c09def0 | ||
![]() |
29778733e5 | ||
![]() |
6f7384d5c7 | ||
![]() |
809ddcebbd | ||
![]() |
2ca9a55fd5 | ||
![]() |
cf378e562e | ||
![]() |
a7d35a27a3 | ||
![]() |
9dbfac2756 | ||
![]() |
c193d36499 | ||
![]() |
f9833665b7 | ||
![]() |
c0a356711d | ||
![]() |
653122498a | ||
![]() |
c574c80e27 | ||
![]() |
20f13184f2 | ||
![]() |
8864329928 | ||
![]() |
e57cc5d4c6 | ||
![]() |
9107378efe | ||
![]() |
5a78ebe895 | ||
![]() |
c398672200 | ||
![]() |
b8bfbc141d | ||
![]() |
a943a81f87 | ||
![]() |
320041eaf2 | ||
![]() |
3ac5da2535 | ||
![]() |
aabedeeb6c | ||
![]() |
b3071dfd15 | ||
![]() |
5b49ea4e2d | ||
![]() |
acb1abceae | ||
![]() |
2f2798afb8 | ||
![]() |
0859ed8448 | ||
![]() |
efdc2a63eb | ||
![]() |
3e0e31544e | ||
![]() |
49b9eae18c | ||
![]() |
0a502562c3 | ||
![]() |
ef27f87dbe | ||
![]() |
ccb29663cc | ||
![]() |
2c7bf2756e | ||
![]() |
c0b92d9498 | ||
![]() |
808f8eea34 | ||
![]() |
0c9df85f5e | ||
![]() |
30effaf164 | ||
![]() |
33ba7f7dcd | ||
![]() |
d0c1025179 | ||
![]() |
fe9751d4d8 | ||
![]() |
6320d6db0f | ||
![]() |
96587f3c8c | ||
![]() |
f780f73f75 | ||
![]() |
dfb76edda8 | ||
![]() |
06ad1ace00 | ||
![]() |
2ba88f05e9 | ||
![]() |
b7180d4d29 | ||
![]() |
600bea73ec | ||
![]() |
f86e7283e7 | ||
![]() |
073292315f | ||
![]() |
0cb3e4af30 | ||
![]() |
66f47343d9 | ||
![]() |
6e5df64f6d | ||
![]() |
71c125193f | ||
![]() |
c972684e1a | ||
![]() |
06ed56e78f | ||
![]() |
970d23a858 | ||
![]() |
0bb99bcc33 | ||
![]() |
52c098ea74 | ||
![]() |
e83070e074 | ||
![]() |
6463fa2561 | ||
![]() |
112b1de2ee | ||
![]() |
e4fb9786c5 | ||
![]() |
043a050e57 | ||
![]() |
f5ae310eae | ||
![]() |
8285318228 | ||
![]() |
59033bc705 | ||
![]() |
9205308c47 | ||
![]() |
e74dd446fb | ||
![]() |
0007699677 | ||
![]() |
927e27b8b5 | ||
![]() |
df4d0eef5c | ||
![]() |
a9578c5f99 | ||
![]() |
783319b45f | ||
![]() |
4a0a973790 | ||
![]() |
822ad91faa | ||
![]() |
613ad4bc32 | ||
![]() |
b736f07e2e | ||
![]() |
7418c5fd3c | ||
![]() |
5f4f15a600 | ||
![]() |
cda7644557 | ||
![]() |
0be288c5aa | ||
![]() |
9479c31a72 | ||
![]() |
8c4633ef72 | ||
![]() |
ae76fa876f | ||
![]() |
d09b106998 | ||
![]() |
6ae9b4dc58 | ||
![]() |
b1cc4c236b | ||
![]() |
6f7dd97607 | ||
![]() |
2e2f6f991d | ||
![]() |
29edb1626d | ||
![]() |
b7872de90a | ||
![]() |
c866f8dc9a | ||
![]() |
b2e830739c | ||
![]() |
92822bd53a | ||
![]() |
6e98d6bf13 | ||
![]() |
dba29c1bfb | ||
![]() |
f0ae46916f | ||
![]() |
8eab0229f1 | ||
![]() |
855318374e | ||
![]() |
a50605a456 | ||
![]() |
0b4dc9d8a5 | ||
![]() |
b1b45f5509 | ||
![]() |
6065d86fa7 | ||
![]() |
568048b0ee | ||
![]() |
7fc1d207e1 | ||
![]() |
464f5c25db | ||
![]() |
189c23a5d9 | ||
![]() |
109cb70f22 | ||
![]() |
0f5da071fa | ||
![]() |
563ecc63e8 | ||
![]() |
23f0f5717c | ||
![]() |
6c39a2f53f | ||
![]() |
3687f7947b | ||
![]() |
68089783b6 | ||
![]() |
38f5aff139 | ||
![]() |
b080854d3e | ||
![]() |
6c97ebb813 | ||
![]() |
dd1000f245 | ||
![]() |
8f0420c533 | ||
![]() |
8f668cc3a8 | ||
![]() |
e13e2a5636 | ||
![]() |
ad769b718b | ||
![]() |
590e8f4f13 | ||
![]() |
a952cc6a47 | ||
![]() |
44a37d7eae | ||
![]() |
8465dddcab | ||
![]() |
b42923dc5d | ||
![]() |
e0ea324f77 | ||
![]() |
53911bf8e9 | ||
![]() |
e82dac4b2d | ||
![]() |
dc38964e42 | ||
![]() |
3345c56fbb | ||
![]() |
62301b7918 | ||
![]() |
fb8ef45213 | ||
![]() |
c57071df65 | ||
![]() |
62c99d7c33 | ||
![]() |
c7034aa41b | ||
![]() |
95652a30d1 | ||
![]() |
e9db40bb42 | ||
![]() |
98b758f893 | ||
![]() |
89309a8621 | ||
![]() |
5e0ff318e7 | ||
![]() |
17120dfc3b | ||
![]() |
ae0762786e | ||
![]() |
ce3507558c | ||
![]() |
5db06bf935 | ||
![]() |
967702e166 | ||
![]() |
54a0683558 | ||
![]() |
711a5ff5d1 | ||
![]() |
605338f110 | ||
![]() |
a59a9c00fb | ||
![]() |
5612045407 | ||
![]() |
0c223892b1 | ||
![]() |
c5a281781d | ||
![]() |
995c34450e | ||
![]() |
d504b74c61 | ||
![]() |
6957b5fdf0 | ||
![]() |
d8ca993a1c | ||
![]() |
fdd5d166b5 | ||
![]() |
155c266d6c | ||
![]() |
c31ae041a2 | ||
![]() |
0930d0dffc | ||
![]() |
b373d1fa69 | ||
![]() |
70e3a43475 | ||
![]() |
c66e5ce8fc | ||
![]() |
17afcf84dc | ||
![]() |
2429ab958d | ||
![]() |
eda02fb929 | ||
![]() |
58d70a8c10 | ||
![]() |
71c921fb42 | ||
![]() |
76a94b4cc8 | ||
![]() |
1a20e37100 | ||
![]() |
7c517b4fcf | ||
![]() |
553052a337 | ||
![]() |
cfdfe9c54c | ||
![]() |
e70a241f34 | ||
![]() |
1c1ad68a63 | ||
![]() |
65236f7231 | ||
![]() |
e9ea7b45c9 | ||
![]() |
cda4f42a7b | ||
![]() |
1d4130f41b | ||
![]() |
28f5297b78 | ||
![]() |
9e01563e8c | ||
![]() |
d87ba1f486 | ||
![]() |
ebac58e452 | ||
![]() |
ad02cbee13 | ||
![]() |
14290e0b9a | ||
![]() |
2ba0ad212e | ||
![]() |
5042c8e924 | ||
![]() |
14d9bdbd9a | ||
![]() |
cf6c958a97 | ||
![]() |
58383bda0c | ||
![]() |
7d8ba43212 | ||
![]() |
3a87b6c518 | ||
![]() |
16b420e2ff | ||
![]() |
95fa101861 | ||
![]() |
fce6234fbf | ||
![]() |
428f1914ef | ||
![]() |
a1d30fe1cb | ||
![]() |
6a616df125 | ||
![]() |
59a0947c76 | ||
![]() |
ea93e74a06 | ||
![]() |
ed357d78b3 | ||
![]() |
3c6a0647b3 | ||
![]() |
9d003ae585 | ||
![]() |
c6792a4bcc | ||
![]() |
3cd93505d6 | ||
![]() |
bce3ab2bf2 | ||
![]() |
78efd60297 | ||
![]() |
13eb9c57d8 | ||
![]() |
3e8868c8b9 | ||
![]() |
2600d3938e | ||
![]() |
741c1fa021 | ||
![]() |
27a00a6806 | ||
![]() |
e192a237b6 | ||
![]() |
00baa75e96 | ||
![]() |
2f1c2930f0 | ||
![]() |
a793a41662 | ||
![]() |
ef81917e8d | ||
![]() |
e63c5bf4f8 | ||
![]() |
b4406cce82 | ||
![]() |
644586e273 | ||
![]() |
91c6dea57b | ||
![]() |
ee850422ba | ||
![]() |
55924fbb56 | ||
![]() |
809067c924 | ||
![]() |
9ef440eb8e | ||
![]() |
606769dbea | ||
![]() |
c89c37378b | ||
![]() |
b9855f7d62 | ||
![]() |
13b7aa9715 | ||
![]() |
ba067fcf94 | ||
![]() |
c53280062c | ||
![]() |
b627f99800 | ||
![]() |
0363d51c5c | ||
![]() |
2b64b493d0 | ||
![]() |
7d4d868236 | ||
![]() |
262685e818 | ||
![]() |
5f84a78638 | ||
![]() |
a4678949f9 | ||
![]() |
b5121e28ac | ||
![]() |
4e9948aacb | ||
![]() |
c63783ee89 | ||
![]() |
069d6d1d9c | ||
![]() |
ceda955ba7 | ||
![]() |
4ffcde8125 | ||
![]() |
d4da6b5bec | ||
![]() |
9f1fa53aae | ||
![]() |
53469c5c0d | ||
![]() |
707b12abf8 | ||
![]() |
91daa22ed4 | ||
![]() |
802e9e5916 | ||
![]() |
47b6da81b4 | ||
![]() |
0f95c97649 | ||
![]() |
d129c54364 | ||
![]() |
99c0cdfab4 | ||
![]() |
342acc9a67 | ||
![]() |
4af66b8cac | ||
![]() |
81e48eaba5 | ||
![]() |
13bdb5ee80 | ||
![]() |
ad51250835 | ||
![]() |
5ebcc48814 | ||
![]() |
5d8b86ff7c | ||
![]() |
98b684b417 | ||
![]() |
1f9d9e1eb1 | ||
![]() |
8bc871ba62 | ||
![]() |
4da101da92 | ||
![]() |
639e2a6fa3 | ||
![]() |
72c2a94df9 | ||
![]() |
75ec7d8076 | ||
![]() |
60bd973441 | ||
![]() |
7584b38562 | ||
![]() |
d1acc80331 | ||
![]() |
17131c860a | ||
![]() |
3f60bd7e63 | ||
![]() |
2f64f0d080 | ||
![]() |
ecadc72bcd | ||
![]() |
fb9bcdadec | ||
![]() |
e61cada28f | ||
![]() |
b3c3b08785 | ||
![]() |
5998043bd2 | ||
![]() |
e30298d957 | ||
![]() |
8799d5a393 | ||
![]() |
bf4ad7a6e7 | ||
![]() |
81b9eb515e | ||
![]() |
4c30bd68ea | ||
![]() |
8040826079 | ||
![]() |
150856c315 | ||
![]() |
d643964fed | ||
![]() |
7ab97db9a9 | ||
![]() |
59ace1b691 | ||
![]() |
ec3085e932 | ||
![]() |
f1a713a0fa | ||
![]() |
94ecdc799a | ||
![]() |
201b85e8da | ||
![]() |
b85b92b3ee | ||
![]() |
7f2aa40bba | ||
![]() |
72d35fc491 | ||
![]() |
dc6575130e | ||
![]() |
9d042ca321 | ||
![]() |
ea82616b6b | ||
![]() |
5010ca2c99 | ||
![]() |
216b232946 | ||
![]() |
d82869c346 | ||
![]() |
ba6a48018c | ||
![]() |
887073b5d9 | ||
![]() |
6b81b6e46a | ||
![]() |
f9b7e32c2d | ||
![]() |
0c8f06441e | ||
![]() |
2acbe26684 | ||
![]() |
bc3722060e | ||
![]() |
1d3455ba16 | ||
![]() |
7d1968b086 | ||
![]() |
1f044b8f45 | ||
![]() |
e31d6296d8 | ||
![]() |
3bc5728815 | ||
![]() |
5abf980b70 | ||
![]() |
615e57c289 | ||
![]() |
47e11dea58 | ||
![]() |
72e7d3ceb8 | ||
![]() |
afa9a1261c | ||
![]() |
ac976c6f71 | ||
![]() |
bead4745ac | ||
![]() |
06ec89d6b8 | ||
![]() |
59d36cf24f | ||
![]() |
edf556cc7b | ||
![]() |
174e9f2fe9 | ||
![]() |
cd258df337 | ||
![]() |
23a22edaed | ||
![]() |
9efcea3604 | ||
![]() |
0f6d461779 | ||
![]() |
f3b31e48e0 | ||
![]() |
8d224624fc | ||
![]() |
ae0fa6207e | ||
![]() |
8758cc8948 | ||
![]() |
5181d20986 | ||
![]() |
5e731527e5 | ||
![]() |
ad59fb6249 | ||
![]() |
0e6aaea2a9 | ||
![]() |
ceebf0dc53 | ||
![]() |
07a9fc6c09 | ||
![]() |
8833a7377e | ||
![]() |
e12f198255 | ||
![]() |
391607de93 | ||
![]() |
dfdc9fdb3b | ||
![]() |
cd3f82ce8c | ||
![]() |
4c6cc29f4a | ||
![]() |
803e2d6dd2 | ||
![]() |
fd035cba9a | ||
![]() |
a484b928ac | ||
![]() |
dd80bbf397 | ||
![]() |
4d062c73ea | ||
![]() |
81ee935a48 | ||
![]() |
7d97869c1f | ||
![]() |
3d8865f2c0 | ||
![]() |
abcacce4be | ||
![]() |
3b87e12c49 | ||
![]() |
a2f805a3ae | ||
![]() |
c084dcf6b8 | ||
![]() |
bced9dcf4b | ||
![]() |
7f81ab9bbb | ||
![]() |
0b6eb251d5 | ||
![]() |
9a447b9b31 | ||
![]() |
af9111355c | ||
![]() |
945fbd5b91 | ||
![]() |
4cf655936e | ||
![]() |
a4c0515e0f | ||
![]() |
11bae53408 | ||
![]() |
fbdd4471a1 | ||
![]() |
b79c7d49cd | ||
![]() |
a8b1139dcb | ||
![]() |
98ba09562e | ||
![]() |
b0b1a46779 | ||
![]() |
ce36d2fb15 | ||
![]() |
49d098b434 | ||
![]() |
f079444c6c | ||
![]() |
c5874c9ab0 | ||
![]() |
15c7379b4d | ||
![]() |
0e72ce8861 | ||
![]() |
483d4f2e61 | ||
![]() |
45f95ecf35 | ||
![]() |
f10bac5ff5 | ||
![]() |
881807d14b | ||
![]() |
7fd712ec96 | ||
![]() |
e8d2d80266 | ||
![]() |
e28243a584 | ||
![]() |
818ec70549 | ||
![]() |
f6a890f5cb | ||
![]() |
f56d01d25e | ||
![]() |
950624761c | ||
![]() |
4545f80e58 | ||
![]() |
3439d09817 | ||
![]() |
90dc2e5547 | ||
![]() |
41ce56bf0d | ||
![]() |
fb76a4ef13 | ||
![]() |
1e1a6d6754 | ||
![]() |
77c366ba2e | ||
![]() |
103eeb2cc6 | ||
![]() |
69e9945ef7 | ||
![]() |
fce1bb60a8 | ||
![]() |
be02c3fa3d | ||
![]() |
9aefec6124 | ||
![]() |
8091d5a53d | ||
![]() |
9ae4b959a2 | ||
![]() |
fa56dcfe91 | ||
![]() |
99a71ee819 | ||
![]() |
143b346a4b | ||
![]() |
85dd94dfcf | ||
![]() |
3940453ad2 | ||
![]() |
0fdc5e87d1 | ||
![]() |
e67169337f | ||
![]() |
5374e44354 | ||
![]() |
7e99f1343c | ||
![]() |
b094f734e4 | ||
![]() |
38ed5e5039 | ||
![]() |
d6b3d6d730 | ||
![]() |
69339c7a97 | ||
![]() |
91df2ee364 | ||
![]() |
0bc44a038b | ||
![]() |
8c01edf74b | ||
![]() |
3d691038bc | ||
![]() |
82f873a025 | ||
![]() |
bb604b92f1 | ||
![]() |
911572f09a | ||
![]() |
1709148484 | ||
![]() |
83a5f6edd1 | ||
![]() |
dfcba7c83c | ||
![]() |
544aafb675 | ||
![]() |
aa0d8f1283 | ||
![]() |
9b628dd02d | ||
![]() |
471d34704f | ||
![]() |
907a2fd7b9 | ||
![]() |
27d8cf4ccc | ||
![]() |
f555e5dda2 | ||
![]() |
61682cdc97 | ||
![]() |
cfd2fe7d33 | ||
![]() |
6b87d3e7e2 | ||
![]() |
f4c3278a7b | ||
![]() |
d9a16fee56 | ||
![]() |
f2961cd63a | ||
![]() |
98620ecd11 | ||
![]() |
081b0af2d6 | ||
![]() |
3f1d72e545 | ||
![]() |
b52ed27b72 | ||
![]() |
7d6a38de93 | ||
![]() |
71ac0a8909 | ||
![]() |
1efbe1637f | ||
![]() |
4353935e0a | ||
![]() |
890f212af2 | ||
![]() |
aff5663c0b | ||
![]() |
4e55447a60 | ||
![]() |
43db085ef1 | ||
![]() |
53988a7285 | ||
![]() |
fb014268d5 | ||
![]() |
a3521ff172 | ||
![]() |
7f63872dcf | ||
![]() |
6c6bfb3d16 | ||
![]() |
a7ed0e6ba5 | ||
![]() |
9baaaebd38 | ||
![]() |
3d48d147ca | ||
![]() |
bdcbccbb9f | ||
![]() |
d46fac6e93 | ||
![]() |
fce1449a87 | ||
![]() |
62bdd1bea5 | ||
![]() |
d8fe443363 | ||
![]() |
e089ab2de2 | ||
![]() |
07a3b1d655 | ||
![]() |
99773ea7e8 | ||
![]() |
5692dcf9a0 | ||
![]() |
c57a15d21c | ||
![]() |
b84b71042b | ||
![]() |
f807901c47 | ||
![]() |
f2ccc1bf84 | ||
![]() |
0593846ffc | ||
![]() |
ee68e44b80 | ||
![]() |
043a6959e0 | ||
![]() |
d58e754344 | ||
![]() |
187706c348 | ||
![]() |
39fa246d9e | ||
![]() |
6022ebaa36 | ||
![]() |
b7664c7970 | ||
![]() |
951781686b | ||
![]() |
6ce16686df | ||
![]() |
82cc80e54e | ||
![]() |
5bf1410ac4 | ||
![]() |
89a86d0975 | ||
![]() |
0b68601c10 | ||
![]() |
e4c3cfd229 | ||
![]() |
da8a87fcf5 | ||
![]() |
3ccaf7beed | ||
![]() |
35dd2c0821 | ||
![]() |
e1d485029b | ||
![]() |
c7b0c57010 | ||
![]() |
80051f0124 | ||
![]() |
80f9374440 | ||
![]() |
ac8e9f53f2 | ||
![]() |
d1c5e42ae2 | ||
![]() |
0d953f22e4 | ||
![]() |
d6c129a30b | ||
![]() |
ac2aee288f | ||
![]() |
d127c5b997 | ||
![]() |
de1f078897 | ||
![]() |
030251e78d | ||
![]() |
2c92a5e137 | ||
![]() |
5b58390b8d | ||
![]() |
01ae1a9d88 | ||
![]() |
d802762be1 | ||
![]() |
e0613311c2 | ||
![]() |
b878be31ae | ||
![]() |
125c9b195c | ||
![]() |
03cc7a5f79 | ||
![]() |
bfdef282ae | ||
![]() |
7fad6590bd | ||
![]() |
cfb782cfff | ||
![]() |
267feb94b0 | ||
![]() |
53e8bf4cb0 | ||
![]() |
1ecadc3952 | ||
![]() |
3e5ce99e82 | ||
![]() |
c10ade711d | ||
![]() |
a276243e9a | ||
![]() |
16739cb4e6 | ||
![]() |
d7136483c3 | ||
![]() |
d43ec1b014 | ||
![]() |
8f42507641 | ||
![]() |
f4279ebf53 | ||
![]() |
72fac7f1b8 | ||
![]() |
679cea02af | ||
![]() |
2c0bb06d1a | ||
![]() |
c4fe900a71 | ||
![]() |
c65b2ec317 | ||
![]() |
a46707a595 | ||
![]() |
57888632a3 | ||
![]() |
00e41eb0ff | ||
![]() |
8237264848 | ||
![]() |
1aa418d098 | ||
![]() |
032a3d1473 | ||
![]() |
e88a0757ab | ||
![]() |
ba1253df3b | ||
![]() |
ef956995b8 | ||
![]() |
f2fe9206c6 | ||
![]() |
8a8c2fbe38 | ||
![]() |
c7640f8346 | ||
![]() |
39b36f8e21 | ||
![]() |
cb6289b622 | ||
![]() |
649ddf696e | ||
![]() |
d555a867fb | ||
![]() |
5c1cc7729d | ||
![]() |
b2ed779ce9 | ||
![]() |
db3d6a3652 | ||
![]() |
2ad5e48314 | ||
![]() |
c36f94a15a | ||
![]() |
0545dbcf24 | ||
![]() |
19693f587f | ||
![]() |
df46776046 | ||
![]() |
1296e4eacb | ||
![]() |
e2aca6e917 | ||
![]() |
7290989e15 | ||
![]() |
a18c6e10a7 | ||
![]() |
eb8362bf76 | ||
![]() |
0e77e33a4d | ||
![]() |
e000eff492 | ||
![]() |
87bb9a42b5 | ||
![]() |
1e6773d2a7 | ||
![]() |
78c918c2c1 | ||
![]() |
641f558b3d | ||
![]() |
7104e12667 | ||
![]() |
ce227e7b94 | ||
![]() |
38e2d4383a | ||
![]() |
6cea51b79f | ||
![]() |
58eaecbd14 | ||
![]() |
8115105835 | ||
![]() |
3d27d0d80a | ||
![]() |
0b9e7eb120 | ||
![]() |
503ce2e488 | ||
![]() |
d459509087 | ||
![]() |
b96bbb35e0 | ||
![]() |
f12cf1ab9d | ||
![]() |
2c9c5b6602 | ||
![]() |
28d13f9a43 | ||
![]() |
f370b1b960 | ||
![]() |
f3c633e222 | ||
![]() |
e44ccf3daa | ||
![]() |
2019823443 | ||
![]() |
ee3a044b75 | ||
![]() |
ccdea73df2 | ||
![]() |
5b42cb6cda | ||
![]() |
1ef97e5cbc | ||
![]() |
1409364371 | ||
![]() |
099700a154 | ||
![]() |
126883ae79 | ||
![]() |
5caeb82d61 | ||
![]() |
b27ab1270c | ||
![]() |
14217e6ca4 | ||
![]() |
07197e24fc | ||
![]() |
8a877d8692 | ||
![]() |
867c68c05b | ||
![]() |
c5f44f8d38 | ||
![]() |
9353c7748b | ||
![]() |
5453f71a7c | ||
![]() |
cec5fab9b3 | ||
![]() |
9edb196395 | ||
![]() |
5710cc097b | ||
![]() |
1a903001f9 | ||
![]() |
e70d7e0857 | ||
![]() |
f199e3f40d | ||
![]() |
bc9dfee7cd | ||
![]() |
e993503c4d | ||
![]() |
b731e121c9 | ||
![]() |
c74ac94c31 | ||
![]() |
6003ad1527 | ||
![]() |
309760cbab | ||
![]() |
87345b4c14 | ||
![]() |
96e8c0a3ab | ||
![]() |
01efa0171d | ||
![]() |
5ef196f74d | ||
![]() |
197368dcfc | ||
![]() |
7b5f640931 | ||
![]() |
cb76f219fb | ||
![]() |
f7dc05969f | ||
![]() |
dc7e12ac0c | ||
![]() |
92ef3da714 | ||
![]() |
3fad65e5df | ||
![]() |
3169bfee19 | ||
![]() |
85d9d6461f | ||
![]() |
57ae02ab71 | ||
![]() |
25db380833 | ||
![]() |
f59e69c6c4 | ||
![]() |
5c7f34d66b | ||
![]() |
31b5275c1f | ||
![]() |
dbd6ddfc95 | ||
![]() |
95ad47bd98 | ||
![]() |
1e56898606 | ||
![]() |
9e2b0e75b1 | ||
![]() |
b342dfd8d5 | ||
![]() |
5a14daf9b8 | ||
![]() |
54552db7ba | ||
![]() |
b5df2e27be | ||
![]() |
2894f2e3eb | ||
![]() |
8fa2b7de45 | ||
![]() |
e753e867f3 | ||
![]() |
040b8c2d5f | ||
![]() |
fa366c79e4 | ||
![]() |
416ad05ce7 | ||
![]() |
b1bc8fb7fb | ||
![]() |
1fca13f07a | ||
![]() |
a773aa6a07 | ||
![]() |
f97b53608d | ||
![]() |
8d5e64e90d | ||
![]() |
45f86d7148 | ||
![]() |
83299ef6aa | ||
![]() |
0201cde7ce | ||
![]() |
ce94013bae | ||
![]() |
6f7743426b | ||
![]() |
d78950e039 | ||
![]() |
cc9f8d7489 | ||
![]() |
dbca7fcc02 | ||
![]() |
ad1e5252f3 | ||
![]() |
f717480c18 | ||
![]() |
12c77ef647 | ||
![]() |
51d4e14440 | ||
![]() |
c852892426 | ||
![]() |
2ee4e95193 | ||
![]() |
f1a7e23eea | ||
![]() |
6e608b14f5 | ||
![]() |
327f719f91 | ||
![]() |
2e173d4523 | ||
![]() |
6ada150026 | ||
![]() |
4e786f4143 | ||
![]() |
559a4058cd | ||
![]() |
34ba0d7d4a | ||
![]() |
78301ec9cb | ||
![]() |
9f6576be05 | ||
![]() |
ed81351f15 | ||
![]() |
d39389afdd | ||
![]() |
064b98e27f | ||
![]() |
0e23eafdfc | ||
![]() |
1d348b131d | ||
![]() |
7bbcb67892 | ||
![]() |
1c5a2da046 | ||
![]() |
778dacd262 | ||
![]() |
a8f3098115 | ||
![]() |
86f34a394b | ||
![]() |
2552ec26b7 | ||
![]() |
d4e9cda0c0 | ||
![]() |
70fc6ea262 | ||
![]() |
be2e1faa31 | ||
![]() |
1974a67b30 | ||
![]() |
9224575a83 | ||
![]() |
27bf997545 | ||
![]() |
d38b7f2406 | ||
![]() |
1024384ffd | ||
![]() |
6e660032c1 | ||
![]() |
44b3e7a8bb | ||
![]() |
5627ef4141 | ||
![]() |
c20828f252 | ||
![]() |
2f50038363 | ||
![]() |
69a5ccbe5c | ||
![]() |
3348f20696 | ||
![]() |
999879c9b8 | ||
![]() |
111e13cad6 | ||
![]() |
7882621ca9 | ||
![]() |
5b6f1e3662 | ||
![]() |
1343cb928f | ||
![]() |
ff6961fbc4 | ||
![]() |
417b6fd022 | ||
![]() |
650cac7979 | ||
![]() |
d3d449e287 | ||
![]() |
a3997dc16a | ||
![]() |
30abadd8e7 | ||
![]() |
6fce08c301 | ||
![]() |
1de7ef0afd | ||
![]() |
d3f7458e26 | ||
![]() |
6a4a3086ce | ||
![]() |
521960c7d6 | ||
![]() |
cfb0987eb5 | ||
![]() |
69c1a1ba7c | ||
![]() |
50a546705e | ||
![]() |
82b808cdfe | ||
![]() |
de411818f0 | ||
![]() |
d6b2a3af50 | ||
![]() |
f7f602e1b1 | ||
![]() |
c819903a7c | ||
![]() |
5ca7948dfb | ||
![]() |
cd3857f810 | ||
![]() |
15c0920777 | ||
![]() |
4ebc79c466 | ||
![]() |
0fe054076f | ||
![]() |
15b5385e71 | ||
![]() |
73e428cf3f | ||
![]() |
1157e0a184 | ||
![]() |
e8e9c68dea | ||
![]() |
64f225df6e | ||
![]() |
01cd858760 | ||
![]() |
429eabf042 | ||
![]() |
06ec2a2e32 | ||
![]() |
b1c4a505b2 | ||
![]() |
3a91efd3a8 | ||
![]() |
9966533e6a | ||
![]() |
94cc957c5e | ||
![]() |
86cfa25910 | ||
![]() |
32465396eb | ||
![]() |
91caecedec | ||
![]() |
2c355db7fa | ||
![]() |
2e0a7d265c | ||
![]() |
9a81a4a967 | ||
![]() |
b44e32fde9 | ||
![]() |
672098118d | ||
![]() |
8a5b3f6880 | ||
![]() |
fe2272c112 | ||
![]() |
ceb43cb354 | ||
![]() |
6ff99f1766 | ||
![]() |
1284a6ca9f | ||
![]() |
010b0e27f9 | ||
![]() |
d4b93220c5 | ||
![]() |
b47ada02bf | ||
![]() |
d22b174a73 | ||
![]() |
b2d0bb08a0 | ||
![]() |
ccf571f78b | ||
![]() |
570fc638a7 | ||
![]() |
30b04bc3bb | ||
![]() |
26b7446178 | ||
![]() |
d8116e8828 | ||
![]() |
dfaf6e045f | ||
![]() |
4d2176df29 | ||
![]() |
079489bd66 | ||
![]() |
4a3792da7e | ||
![]() |
76b6aa66b3 | ||
![]() |
8ce491fbb2 | ||
![]() |
52fafd8f5b | ||
![]() |
73cd3578d9 | ||
![]() |
ac78076663 | ||
![]() |
e500511490 | ||
![]() |
f70c0cb2f9 | ||
![]() |
c3b18c44e0 | ||
![]() |
301a55c8c3 | ||
![]() |
2c6bb735ac | ||
![]() |
62978ef0fb | ||
![]() |
bef550df81 | ||
![]() |
1fd6aba43c | ||
![]() |
c125d2b003 | ||
![]() |
6051a14952 | ||
![]() |
280620d7ac | ||
![]() |
c4c86ea1df | ||
![]() |
af375a1cde | ||
![]() |
e1593df4bd | ||
![]() |
188d09af42 | ||
![]() |
44a7bc640b | ||
![]() |
b20774a55f | ||
![]() |
9d0c5222aa | ||
![]() |
a5495978b7 | ||
![]() |
8a09cd3472 | ||
![]() |
60e0a5073a | ||
![]() |
d2ca0c4f18 | ||
![]() |
eddcc4c5b6 | ||
![]() |
938e056896 | ||
![]() |
5e9178b9de | ||
![]() |
22faf3482c | ||
![]() |
01960ec66e | ||
![]() |
b7b0b4eb02 | ||
![]() |
c5fb68bb2e | ||
![]() |
627e54eb20 | ||
![]() |
bbfcdf0ac7 | ||
![]() |
34348fcb42 | ||
![]() |
ceb6da81b3 | ||
![]() |
2435adc33b | ||
![]() |
7a3d4dabb1 | ||
![]() |
692d137a21 | ||
![]() |
0b36f497c5 | ||
![]() |
9aae6e2c16 | ||
![]() |
fc61e5fe46 | ||
![]() |
94afeabc18 | ||
![]() |
0c8d3f106a | ||
![]() |
c78573b468 | ||
![]() |
f8459427d3 | ||
![]() |
295430a47e | ||
![]() |
ae12132495 | ||
![]() |
87e1045b11 | ||
![]() |
217bb6dc65 | ||
![]() |
c7a6730d28 | ||
![]() |
6e5d1a540c | ||
![]() |
372a1c05e6 | ||
![]() |
5cb7591bc0 | ||
![]() |
8b9442efe0 | ||
![]() |
6ae1917733 | ||
![]() |
073346ee37 | ||
![]() |
b44460464e | ||
![]() |
cba19d3bf5 | ||
![]() |
fe95cbe077 | ||
![]() |
967c95829f | ||
![]() |
1ebbb1a11e | ||
![]() |
6ce41f6211 | ||
![]() |
82818d7454 | ||
![]() |
e6ecc078a1 | ||
![]() |
235042fcd5 | ||
![]() |
39020bf14d | ||
![]() |
786e36eee6 | ||
![]() |
0f7ea99605 | ||
![]() |
847a8ba265 | ||
![]() |
226fd5c0b8 | ||
![]() |
6a421a1254 | ||
![]() |
1ec0fd75e1 | ||
![]() |
b007909c0d | ||
![]() |
67ded4c2fd | ||
![]() |
1f91c03bf6 | ||
![]() |
380896d08a | ||
![]() |
790d431624 | ||
![]() |
f3e2147e72 | ||
![]() |
e38dcbbdbf | ||
![]() |
0d7482e379 | ||
![]() |
01ea05d650 | ||
![]() |
7991c861e1 | ||
![]() |
ebed84ab55 | ||
![]() |
e321c48211 | ||
![]() |
4f1cd8af93 | ||
![]() |
23a1a66aee | ||
![]() |
876d81e861 | ||
![]() |
90105e822f | ||
![]() |
f05e60f338 | ||
![]() |
994c18c44e | ||
![]() |
7d9b198df6 | ||
![]() |
0fd7cdcb78 | ||
![]() |
7ef165035e | ||
![]() |
88f2309796 | ||
![]() |
8178ea17fd | ||
![]() |
cbe454a46a | ||
![]() |
eb84b2a6e8 | ||
![]() |
d6d481210e | ||
![]() |
4ee44ee0ea | ||
![]() |
04fccea63b | ||
![]() |
b7f873bbbc | ||
![]() |
ea3fd01ebb | ||
![]() |
5333207207 | ||
![]() |
1dcab170b6 | ||
![]() |
d676f159d3 | ||
![]() |
c3a76e0f9d | ||
![]() |
4e2005d53b | ||
![]() |
7c30fc2cbf | ||
![]() |
60366346fb | ||
![]() |
1825fd7ab7 | ||
![]() |
9fc53cfa7b | ||
![]() |
76d54b28ea | ||
![]() |
eeab42af03 | ||
![]() |
ce9188ee35 | ||
![]() |
ba040219ce | ||
![]() |
c631dc88a0 | ||
![]() |
7691e859d1 | ||
![]() |
1a9734d704 | ||
![]() |
ec0f4e8826 | ||
![]() |
8f711078b8 | ||
![]() |
00fddaa868 | ||
![]() |
d3fca54a7e | ||
![]() |
c42080fe28 | ||
![]() |
d2240c4a62 | ||
![]() |
926c8bb9bd | ||
![]() |
59a5cf3de4 | ||
![]() |
84c095e787 | ||
![]() |
992deb36d4 | ||
![]() |
683d3a3f04 | ||
![]() |
76d9a2e702 | ||
![]() |
acfbc34909 | ||
![]() |
f06d0bd028 | ||
![]() |
ae52ab2cfb | ||
![]() |
5ab6566a3b | ||
![]() |
484dea8d7a | ||
![]() |
4a8a43965f | ||
![]() |
1a27cd1548 | ||
![]() |
53e68b64b2 | ||
![]() |
124b04fff6 | ||
![]() |
385dd2d469 | ||
![]() |
1c1b63aae7 | ||
![]() |
0f5e8266cd | ||
![]() |
e04c363d9f | ||
![]() |
abfd749335 | ||
![]() |
f17fd791cf | ||
![]() |
d65aaf8740 | ||
![]() |
0822b942af | ||
![]() |
43037a94cf | ||
![]() |
669a92607c | ||
![]() |
c511e4be2a | ||
![]() |
cdf05183b9 | ||
![]() |
bc36aca98e | ||
![]() |
e6b4354530 | ||
![]() |
7ecdee6eaa | ||
![]() |
cd15a1698b | ||
![]() |
94cdbb4669 | ||
![]() |
9c732cb32d | ||
![]() |
24494e978c | ||
![]() |
56ea2c4d15 | ||
![]() |
f3c9b66f08 | ||
![]() |
945710fae1 | ||
![]() |
5ab1a1298f | ||
![]() |
61dfa943c6 | ||
![]() |
7103bda058 | ||
![]() |
aed383b037 | ||
![]() |
44faa81a06 | ||
![]() |
876fe9f210 | ||
![]() |
b735c90c42 | ||
![]() |
88c786093b | ||
![]() |
af30466867 | ||
![]() |
83cfaee59a | ||
![]() |
f82422cc63 | ||
![]() |
22c77cc037 | ||
![]() |
fa1c12453b | ||
![]() |
9cd1f8a7df | ||
![]() |
6ac062d151 | ||
![]() |
5e7949c144 | ||
![]() |
76c41775fb | ||
![]() |
05ae9689eb | ||
![]() |
005198bf07 | ||
![]() |
d30fc97815 | ||
![]() |
c473290b47 | ||
![]() |
d9cd657135 | ||
![]() |
cfd191a803 | ||
![]() |
43059d5022 | ||
![]() |
5a111ac902 | ||
![]() |
017069bf68 | ||
![]() |
ea23556a40 | ||
![]() |
f85fc4202a | ||
![]() |
0082784b49 | ||
![]() |
b3991c1a40 | ||
![]() |
09f4bd9210 | ||
![]() |
ba5f4616d2 | ||
![]() |
d4e3ec52b2 | ||
![]() |
6852cf0a3e | ||
![]() |
fd85192a54 | ||
![]() |
b4c20ef81c | ||
![]() |
873924a027 | ||
![]() |
25936b1365 | ||
![]() |
6ea58f9fde | ||
![]() |
2c7998e8db | ||
![]() |
72dbab789d | ||
![]() |
392eebc0a9 | ||
![]() |
4e61d04e0d | ||
![]() |
ae03fcb50d | ||
![]() |
6450f3ea3f | ||
![]() |
5651117f86 | ||
![]() |
762f9f2533 | ||
![]() |
89407089cd | ||
![]() |
4d66e11b0c | ||
![]() |
3a47181a50 | ||
![]() |
39ba0a9ebd | ||
![]() |
4b1ce76549 | ||
![]() |
062fc7852a | ||
![]() |
93a06769c4 | ||
![]() |
48b0a95528 | ||
![]() |
6a477061c7 | ||
![]() |
0971eb4d0c | ||
![]() |
f0a85ddeb4 | ||
![]() |
2b1b8cce54 | ||
![]() |
7e38962d59 | ||
![]() |
ec634ad2a7 | ||
![]() |
cfde6c3f55 | ||
![]() |
927a3dc322 | ||
![]() |
d702e037c0 | ||
![]() |
23799d0cb4 | ||
![]() |
04773eaa2c | ||
![]() |
e782911d33 | ||
![]() |
e4b78d83d6 | ||
![]() |
2dec023f63 | ||
![]() |
6a4fffe6da | ||
![]() |
3dc724d734 | ||
![]() |
ae0ee89d72 | ||
![]() |
42ab82c20c | ||
![]() |
747cb00c31 | ||
![]() |
2b88840316 | ||
![]() |
659a63ae20 | ||
![]() |
bec0cabde4 | ||
![]() |
b16621b9ee | ||
![]() |
74e7e341fd | ||
![]() |
4b88607b19 | ||
![]() |
8f036c229e | ||
![]() |
850d2c7ea8 | ||
![]() |
1c86327029 | ||
![]() |
bf5afa52e5 | ||
![]() |
7fed9f758f | ||
![]() |
224721e7f0 | ||
![]() |
2135a4f845 | ||
![]() |
5d9e0401fc | ||
![]() |
b6fd028fe7 | ||
![]() |
f1b2bca6bd | ||
![]() |
6b71a71e19 | ||
![]() |
219e18323f | ||
![]() |
a205afe2de | ||
![]() |
3d736d4c20 | ||
![]() |
adceab280b | ||
![]() |
1ec6c46a1d | ||
![]() |
5ff7d113b9 | ||
![]() |
ec2c060b75 | ||
![]() |
80135367cf | ||
![]() |
a001740506 | ||
![]() |
a584396147 | ||
![]() |
e519d1139a | ||
![]() |
80ed3ef5b2 | ||
![]() |
24d4790537 | ||
![]() |
48e7c0bd50 | ||
![]() |
119de8ec55 | ||
![]() |
f1b106f6eb | ||
![]() |
cc850d3a3d | ||
![]() |
2e882946f8 | ||
![]() |
63b0778c99 | ||
![]() |
fba3b90c11 | ||
![]() |
898c7e636e | ||
![]() |
f9edb5e605 | ||
![]() |
af47112a30 | ||
![]() |
d2f52a6723 | ||
![]() |
1cd3cd2eb9 | ||
![]() |
9766426b59 | ||
![]() |
6f925c4dae | ||
![]() |
c5890ac87f | ||
![]() |
7f55a241a4 | ||
![]() |
3021472358 | ||
![]() |
d71a604385 | ||
![]() |
83a30fe5ae | ||
![]() |
7c1e3ab76a | ||
![]() |
908dff807e | ||
![]() |
a71f24109f | ||
![]() |
26befb5850 | ||
![]() |
9da9c5a63f | ||
![]() |
e6340996d7 | ||
![]() |
183a7a18a9 | ||
![]() |
0f3b2ae180 | ||
![]() |
ad4d639854 | ||
![]() |
27be63fe65 | ||
![]() |
ae358bd524 | ||
![]() |
d0b0004c8c | ||
![]() |
7e9708ddbc | ||
![]() |
d68c9e69fa | ||
![]() |
c4c14f3ac0 | ||
![]() |
bc0375fb30 | ||
![]() |
8ce7dc3dbe | ||
![]() |
141b01f82a | ||
![]() |
69cf481ca9 | ||
![]() |
10c8e5e263 | ||
![]() |
7474ff0975 | ||
![]() |
08936c1534 | ||
![]() |
e6aaceeb4b | ||
![]() |
6c0eb76cb7 | ||
![]() |
4747df491b | ||
![]() |
8db2f442bc | ||
![]() |
2613564093 | ||
![]() |
7e95480094 | ||
![]() |
61c804f5b2 | ||
![]() |
1e9c3b3d1e | ||
![]() |
23fb4493df | ||
![]() |
1187fcbf42 | ||
![]() |
dfd304353d | ||
![]() |
b6884df39a | ||
![]() |
cf0f6ebddf | ||
![]() |
31075ab2ef | ||
![]() |
a0deadc919 | ||
![]() |
9a080dffcd | ||
![]() |
a2990443d2 | ||
![]() |
10f026748e | ||
![]() |
885c4c9632 | ||
![]() |
e798d4fe9d | ||
![]() |
ea16ade5e0 | ||
![]() |
e90356285b | ||
![]() |
22ff2a5f79 | ||
![]() |
421f068903 | ||
![]() |
c678ba16b8 | ||
![]() |
bfde5d4d09 | ||
![]() |
4dff4b2336 | ||
![]() |
5c7b5920b0 | ||
![]() |
6dc7fde272 | ||
![]() |
06482b8116 | ||
![]() |
2aded60c94 | ||
![]() |
923f7b6a11 | ||
![]() |
8ada894f70 | ||
![]() |
764376b677 | ||
![]() |
b41106d359 | ||
![]() |
5760e300c3 | ||
![]() |
ca767aa857 | ||
![]() |
85a6fc25f1 | ||
![]() |
5e631c8af8 | ||
![]() |
63ef918671 | ||
![]() |
ec1c348b4f | ||
![]() |
f45696485c | ||
![]() |
8a43473504 | ||
![]() |
8a735edac0 | ||
![]() |
e462dcda56 | ||
![]() |
71384da38f | ||
![]() |
a6c4972290 | ||
![]() |
c235c9fa54 | ||
![]() |
4d95e3a161 | ||
![]() |
77d2d79ac2 | ||
![]() |
171b2b90b8 | ||
![]() |
805920dc68 | ||
![]() |
64923913c2 | ||
![]() |
17827f1ff9 | ||
![]() |
c0fe7070a3 | ||
![]() |
514e3b2710 | ||
![]() |
163fb868c2 | ||
![]() |
e10bb3bd77 | ||
![]() |
4b7138b05c | ||
![]() |
a94c0ed29e | ||
![]() |
df6221bcb2 | ||
![]() |
56c2cf9f10 | ||
![]() |
42bd5ba7c2 | ||
![]() |
c19dc6605f | ||
![]() |
e11ad83222 | ||
![]() |
f8b703efed | ||
![]() |
e6f5efbe73 | ||
![]() |
81816ce04d | ||
![]() |
926dc608af | ||
![]() |
4329b669d0 | ||
![]() |
8b573fe398 | ||
![]() |
97587e399f | ||
![]() |
6f4b91ac8e | ||
![]() |
481af204b0 | ||
![]() |
6dbde8121d | ||
![]() |
7fda423e12 | ||
![]() |
4c6f0ff75a | ||
![]() |
a0a05a88b9 | ||
![]() |
1574909535 | ||
![]() |
9049ed2f25 | ||
![]() |
3f4cafe135 | ||
![]() |
a50af3b751 | ||
![]() |
23af586acd | ||
![]() |
eeb42c56f0 | ||
![]() |
3d82ab167f | ||
![]() |
305189523a | ||
![]() |
7e9b4170b1 | ||
![]() |
f78ea26f13 | ||
![]() |
8ca638fb88 | ||
![]() |
799e7af9c7 | ||
![]() |
7fe55567bd | ||
![]() |
5b226a8151 | ||
![]() |
bedd20b08e | ||
![]() |
06ee649a91 | ||
![]() |
f2197fa06b | ||
![]() |
11271cd967 | ||
![]() |
92a3d8f498 | ||
![]() |
ac395525c8 | ||
![]() |
165557070e | ||
![]() |
920dc5b087 | ||
![]() |
7123f47f84 | ||
![]() |
9d045fae0e | ||
![]() |
c93966d5a1 | ||
![]() |
c545674918 | ||
![]() |
48c5e8d215 | ||
![]() |
59d4e86bc5 | ||
![]() |
ba152c567c | ||
![]() |
dd9265f2db | ||
![]() |
8b6ad5d3b9 | ||
![]() |
038b9bff4d | ||
![]() |
db2f14225d | ||
![]() |
3975e4eb6d | ||
![]() |
1b44527511 | ||
![]() |
735dc0b7f3 | ||
![]() |
318568bcb6 | ||
![]() |
f0d227dcb5 | ||
![]() |
10aac88be5 | ||
![]() |
c79f583e0c | ||
![]() |
5b7ec7689a | ||
![]() |
093d23a869 | ||
![]() |
eb1149ca1f | ||
![]() |
d383a49b7b | ||
![]() |
581b6139dc | ||
![]() |
ad228461ab | ||
![]() |
5de6af9f4a | ||
![]() |
cb7e9b5885 | ||
![]() |
1a01486170 | ||
![]() |
4657bd55f5 | ||
![]() |
d2a3809ca8 | ||
![]() |
665f63ff97 | ||
![]() |
7d94aee5b6 | ||
![]() |
a3db60b7b1 | ||
![]() |
4b38c92f26 | ||
![]() |
6680a771e8 | ||
![]() |
194b4cf60e | ||
![]() |
f26f51bf8c | ||
![]() |
70b6451dc2 | ||
![]() |
5776ce87d7 | ||
![]() |
f6683bab75 | ||
![]() |
58d2814a92 | ||
![]() |
8f5f62575d | ||
![]() |
3045ef0770 | ||
![]() |
3eff81864c | ||
![]() |
bc046994db | ||
![]() |
a90c4025f1 | ||
![]() |
ed10b00afa | ||
![]() |
c96812a5f6 | ||
![]() |
89de05463d | ||
![]() |
a75126af39 | ||
![]() |
47ebd81393 | ||
![]() |
07da17ec5f | ||
![]() |
db9f001865 | ||
![]() |
b252b65ee0 | ||
![]() |
f328d62f55 | ||
![]() |
382bbf1861 | ||
![]() |
a4ee9c8152 | ||
![]() |
9eb3adc33b | ||
![]() |
ea572f23fc | ||
![]() |
6f9dd97f50 | ||
![]() |
07fc7905ca | ||
![]() |
8e5a68f407 | ||
![]() |
1e0553250b | ||
![]() |
3616b37789 | ||
![]() |
81cf11b0f5 | ||
![]() |
f0a890da8a | ||
![]() |
c21dc9ed6f | ||
![]() |
99a94bc441 | ||
![]() |
fd43a3938f | ||
![]() |
42fe6c5a15 | ||
![]() |
7b98a6ed9c | ||
![]() |
cb4f1d2a99 | ||
![]() |
a2c777ba84 | ||
![]() |
973ee269d3 | ||
![]() |
f721f1de1e | ||
![]() |
dbd8842d51 | ||
![]() |
6fee25af9b | ||
![]() |
790bb44785 | ||
![]() |
c03afda96f | ||
![]() |
365f955318 | ||
![]() |
382b73c11a | ||
![]() |
5c14742a87 | ||
![]() |
c2caa325ba | ||
![]() |
82d7c81bd3 | ||
![]() |
3adb91fc9e | ||
![]() |
78f5a5dde4 | ||
![]() |
36777d1e68 | ||
![]() |
cd2dd4e2dc | ||
![]() |
b705a579ad | ||
![]() |
5ebbe07fa6 | ||
![]() |
732871b601 | ||
![]() |
80ee406e3e | ||
![]() |
4e3cedc901 | ||
![]() |
23cf6cb2e4 | ||
![]() |
2af0166970 | ||
![]() |
97a34e6b4a | ||
![]() |
5c9de0cf23 | ||
![]() |
541dca499a | ||
![]() |
876ac5f569 | ||
![]() |
7a74a825a4 | ||
![]() |
57933425ca | ||
![]() |
c7466cd56a | ||
![]() |
dffff73e89 | ||
![]() |
ba6c8174d2 | ||
![]() |
89bddf551a | ||
![]() |
c23c37c07c | ||
![]() |
ea3ce7a119 | ||
![]() |
836f0d9a08 | ||
![]() |
a15b781feb | ||
![]() |
89c1ec3d79 | ||
![]() |
5519faecba | ||
![]() |
4f5010f69d | ||
![]() |
f6f08f9b96 | ||
![]() |
249a1ef1c0 | ||
![]() |
7af6aac440 | ||
![]() |
6e331efbda | ||
![]() |
1addaf3355 | ||
![]() |
20f7907436 | ||
![]() |
49eb17973e | ||
![]() |
85759a6f3c | ||
![]() |
3800f991b2 | ||
![]() |
7d0cbf15bc | ||
![]() |
5bf614a7af | ||
![]() |
e819ee6df6 | ||
![]() |
15236f30db | ||
![]() |
77d5b57e9e | ||
![]() |
3402f5994b | ||
![]() |
518808c709 | ||
![]() |
30158fe89c | ||
![]() |
9a15a46df5 | ||
![]() |
8203b1d542 | ||
![]() |
80123efabd | ||
![]() |
7321705e90 | ||
![]() |
77c4d311ff | ||
![]() |
3afa5e570d | ||
![]() |
b543bf76f1 | ||
![]() |
eb968c9098 | ||
![]() |
2e50e6fc05 | ||
![]() |
328cb02e4d | ||
![]() |
3ab0d8270a | ||
![]() |
b33d100f7b | ||
![]() |
04f563c3dc | ||
![]() |
a4d18ecf8f | ||
![]() |
80fec3f5f4 | ||
![]() |
da0fa4e012 | ||
![]() |
7e9971661b | ||
![]() |
f24cfa481b | ||
![]() |
8f9e6b3f76 | ||
![]() |
289b8826bf | ||
![]() |
aa7845ca98 | ||
![]() |
317e345a6a | ||
![]() |
60e2a9994f | ||
![]() |
17d653904f | ||
![]() |
b55732066d | ||
![]() |
3f69ddb615 | ||
![]() |
9a8129abd6 | ||
![]() |
a3b9967c13 | ||
![]() |
d58ae33e5c | ||
![]() |
95574e4538 | ||
![]() |
630c2c2a08 | ||
![]() |
236bb27cdd | ||
![]() |
1959d23b18 | ||
![]() |
f1d6e6094e | ||
![]() |
d4e8ba072a | ||
![]() |
4bcfa21ca4 | ||
![]() |
e2e625fa18 | ||
![]() |
04d00c5c20 | ||
![]() |
1d9f2d69e0 | ||
![]() |
52189d99f6 | ||
![]() |
b5c3fc1222 | ||
![]() |
75b20ff1d0 | ||
![]() |
ba5bc1f5b3 | ||
![]() |
36bc4e15c3 | ||
![]() |
1b4c6e9be8 | ||
![]() |
befa448017 | ||
![]() |
30d32e4a58 | ||
![]() |
78b9328db6 | ||
![]() |
f902c7019d | ||
![]() |
8d40c37469 | ||
![]() |
74fa720e60 | ||
![]() |
2e777a0d31 | ||
![]() |
ca8f3edc33 | ||
![]() |
0c8406780f | ||
![]() |
51b437bbfe | ||
![]() |
47ba837e98 | ||
![]() |
8cfe038d67 | ||
![]() |
bedf2b0596 | ||
![]() |
46c19b6c6a | ||
![]() |
f7b59750d0 | ||
![]() |
8606f6e96a | ||
![]() |
87dde21ec5 | ||
![]() |
64211c292d | ||
![]() |
eab0bf6e8a | ||
![]() |
6d76b3e21d | ||
![]() |
38e3e72684 | ||
![]() |
c957d25dad | ||
![]() |
f67e5ea6d8 | ||
![]() |
cb5939f941 | ||
![]() |
9c07741a0a | ||
![]() |
a46269d5b0 | ||
![]() |
c02b1466c4 | ||
![]() |
67be05ec3e | ||
![]() |
891b78e9e8 | ||
![]() |
d12ac0fa71 | ||
![]() |
e82f0d3459 | ||
![]() |
f0e3d92d00 | ||
![]() |
03b99ba0d5 | ||
![]() |
fefa93e3ba | ||
![]() |
0925a362d6 | ||
![]() |
3474953d16 | ||
![]() |
d8f9d9d45c | ||
![]() |
cb810c12ff | ||
![]() |
18ec5589f8 | ||
![]() |
7d67192493 | ||
![]() |
8de07357fd | ||
![]() |
08845fb19c | ||
![]() |
8320e3ab92 | ||
![]() |
0815b85f22 | ||
![]() |
993a934803 | ||
![]() |
77e387dd0c | ||
![]() |
f7b5ebd097 | ||
![]() |
636c6eb645 | ||
![]() |
1a7c5786f6 | ||
![]() |
10fd485d7d | ||
![]() |
6470601a34 | ||
![]() |
37bc48add4 | ||
![]() |
7fafb627d8 | ||
![]() |
57a57646d8 | ||
![]() |
3f42e4df25 | ||
![]() |
f22c958b79 | ||
![]() |
de04e6d723 | ||
![]() |
ead1f0e96e | ||
![]() |
2a66b3bfe5 | ||
![]() |
869bcf59d5 | ||
![]() |
27583e6b35 | ||
![]() |
a8e2023a8e | ||
![]() |
29aea1d411 | ||
![]() |
c1bf2376d4 | ||
![]() |
10e5bee5ef | ||
![]() |
3f1e4cce65 | ||
![]() |
277437f3d6 | ||
![]() |
308071796a | ||
![]() |
b63674dc21 | ||
![]() |
1d64c96a5c | ||
![]() |
dfdc8716be | ||
![]() |
dcd48e1f66 | ||
![]() |
667023b01b | ||
![]() |
e4d007e14f | ||
![]() |
fbe8b7a3c0 | ||
![]() |
412fea3ffa | ||
![]() |
ed283d7b14 | ||
![]() |
584377f8f1 | ||
![]() |
b6236255d2 | ||
![]() |
19e5cc9b0d | ||
![]() |
002fc2d632 | ||
![]() |
653821c521 | ||
![]() |
7436cef012 | ||
![]() |
2a37dba4bf | ||
![]() |
6d47354e63 | ||
![]() |
37896485b6 | ||
![]() |
a5f3aed1ef | ||
![]() |
049cb701d0 | ||
![]() |
eb84e29c81 | ||
![]() |
051a911840 | ||
![]() |
d9c324a511 | ||
![]() |
7f4dd181b2 | ||
![]() |
3dcf1fd9d8 | ||
![]() |
c295fba546 | ||
![]() |
b1c8a57047 | ||
![]() |
de83176b04 | ||
![]() |
6f99368935 | ||
![]() |
e7529fc7de | ||
![]() |
094537efc6 | ||
![]() |
772aa687d7 | ||
![]() |
75a9199bc4 | ||
![]() |
f9907cdaac | ||
![]() |
e583bc470f | ||
![]() |
0be475af3c | ||
![]() |
c54ba7158c | ||
![]() |
617e99a423 | ||
![]() |
04bfe55c36 | ||
![]() |
f7c6fe0ed6 | ||
![]() |
0e865a7028 | ||
![]() |
42afc31cbe | ||
![]() |
1399b5688b | ||
![]() |
69d9a07e34 | ||
![]() |
d96f542951 | ||
![]() |
ec9260fa0c | ||
![]() |
aa9a914975 | ||
![]() |
e9a33524a2 | ||
![]() |
45c7aa0d18 | ||
![]() |
03b48b5621 | ||
![]() |
647f1e9b91 | ||
![]() |
297cde85bc | ||
![]() |
43692cb377 | ||
![]() |
6111706911 | ||
![]() |
2d480f12e1 | ||
![]() |
3450bca695 | ||
![]() |
575f603f89 | ||
![]() |
2686baae69 | ||
![]() |
a17745661e | ||
![]() |
842a70a307 | ||
![]() |
e41bee377d | ||
![]() |
46f6fb1bd1 | ||
![]() |
e39cdc7a29 | ||
![]() |
77ea7ad437 | ||
![]() |
683ff1a4e4 | ||
![]() |
d773c0b4ac | ||
![]() |
2b0b5d4173 | ||
![]() |
11f42e2476 | ||
![]() |
f6f5570bc8 | ||
![]() |
cf950f6d3f | ||
![]() |
dbd66bd497 | ||
![]() |
709b77794b | ||
![]() |
74761fcdd3 | ||
![]() |
8679b82db4 | ||
![]() |
10ac107ba6 | ||
![]() |
ea9bc11fc8 | ||
![]() |
7a4d48c16d | ||
![]() |
29f2ac2070 | ||
![]() |
d8b305d799 | ||
![]() |
6d9d2f5b89 | ||
![]() |
b9304eaf20 | ||
![]() |
d50ee161f5 | ||
![]() |
f1bc1ed4be | ||
![]() |
2471d4c3cd | ||
![]() |
fc81e07c13 | ||
![]() |
7163a9d9d7 | ||
![]() |
a6002562ef | ||
![]() |
ff2840f95f | ||
![]() |
c5d1a5c31f | ||
![]() |
e56e4ade90 | ||
![]() |
6e5b26ba64 | ||
![]() |
9518d68d9a | ||
![]() |
920ac37a40 | ||
![]() |
5eb0b7ca8e | ||
![]() |
f50a51d943 | ||
![]() |
38ded68a38 | ||
![]() |
1822062d55 | ||
![]() |
ca561be4b9 | ||
![]() |
db3024eed6 | ||
![]() |
00763fde0d | ||
![]() |
e265f95f45 | ||
![]() |
5120f46199 | ||
![]() |
ec6ee1c20b | ||
![]() |
1cde7c9f3e | ||
![]() |
a20a61dca4 | ||
![]() |
074ed35b3d | ||
![]() |
efa5b0cc62 | ||
![]() |
e47bc6ede4 | ||
![]() |
6ff152669a | ||
![]() |
c3b1425edd | ||
![]() |
0dca744d4b | ||
![]() |
5d9b9de462 | ||
![]() |
788bbb3650 | ||
![]() |
ab8e091946 | ||
![]() |
8d8ea67da1 | ||
![]() |
8e68e73c43 | ||
![]() |
edf7294c06 | ||
![]() |
23451be606 | ||
![]() |
66b73262df | ||
![]() |
877d910a44 | ||
![]() |
0be5beffc8 | ||
![]() |
3fde169001 | ||
![]() |
2ecf5ff0d7 | ||
![]() |
7c9561f027 | ||
![]() |
02e46542e3 | ||
![]() |
df04877a67 | ||
![]() |
7fc0a8fc0f | ||
![]() |
9a3639f2fa | ||
![]() |
8e09c4a6fb | ||
![]() |
e5fcc93a9e | ||
![]() |
7385e2c90e | ||
![]() |
78fe1cc0ef | ||
![]() |
9b7d761db5 | ||
![]() |
ff333a112b | ||
![]() |
80712face4 | ||
![]() |
f95e3a02e8 | ||
![]() |
e8eb05feea | ||
![]() |
dfe57b8bb0 | ||
![]() |
48ddd52ced | ||
![]() |
c0a1760f46 | ||
![]() |
f9c2fa7bb2 | ||
![]() |
b89720ca47 | ||
![]() |
968584d3f0 | ||
![]() |
7b26a87d7a | ||
![]() |
f3d662db74 | ||
![]() |
694ccf62d0 | ||
![]() |
174c14aefb | ||
![]() |
73d98d8875 | ||
![]() |
a8736b8df8 | ||
![]() |
a3906272cc | ||
![]() |
751db56045 | ||
![]() |
c365cc1b8d | ||
![]() |
e1fc36966b | ||
![]() |
8606bd6435 | ||
![]() |
29dd246f5e | ||
![]() |
e0f21ed293 | ||
![]() |
d3d6090c32 | ||
![]() |
767c2f61b4 | ||
![]() |
1134e55150 | ||
![]() |
486c859ad6 | ||
![]() |
1b5a58233c | ||
![]() |
c10b8d42e3 | ||
![]() |
184b19c992 | ||
![]() |
d973c347be | ||
![]() |
84ca680611 | ||
![]() |
f35a40c0c5 | ||
![]() |
6c5fe246a7 | ||
![]() |
0d45316891 | ||
![]() |
37811a092c | ||
![]() |
2c0234e161 | ||
![]() |
2697af428e | ||
![]() |
d5aecc6ef4 | ||
![]() |
4085aceb4a | ||
![]() |
acbbedb9d3 | ||
![]() |
d87b580c20 | ||
![]() |
0531e9ab08 | ||
![]() |
3b3f6d33fe | ||
![]() |
dcfd0e2ade | ||
![]() |
f4d515fc79 | ||
![]() |
f3e4266add | ||
![]() |
07fe995a5d | ||
![]() |
a0911ca778 | ||
![]() |
06aa84ccaf | ||
![]() |
e0ffd94832 | ||
![]() |
e148e1ea99 | ||
![]() |
694799c9c2 | ||
![]() |
ca9895692a | ||
![]() |
5cc0f68d51 | ||
![]() |
ab6cd7e465 | ||
![]() |
11914431bc | ||
![]() |
8cb61f9aae | ||
![]() |
1c9a736ed5 | ||
![]() |
e5550ed58f | ||
![]() |
775f4643b5 | ||
![]() |
9d9c516596 | ||
![]() |
bba47527d3 | ||
![]() |
936542fa79 | ||
![]() |
1fe5070666 | ||
![]() |
337f5e062e | ||
![]() |
654154e721 | ||
![]() |
8d58f5b679 | ||
![]() |
0ad463742b | ||
![]() |
4a1dafb907 | ||
![]() |
a83bb33ea5 | ||
![]() |
5e0069e146 | ||
![]() |
23249c85c7 | ||
![]() |
0611632d7b | ||
![]() |
4fa2ce2cbe | ||
![]() |
b8ef64f6e3 | ||
![]() |
7a2719f314 | ||
![]() |
d42549e46d | ||
![]() |
f98ddf2201 | ||
![]() |
cb6faed69a | ||
![]() |
1f4d73ab73 | ||
![]() |
8aac527e29 | ||
![]() |
d11974c717 | ||
![]() |
709c86086f | ||
![]() |
d4e27b8ee2 | ||
![]() |
45dd5d2f7c | ||
![]() |
1b0f24a283 | ||
![]() |
38a7c4a8dc | ||
![]() |
ea324a7959 | ||
![]() |
61d0abe910 | ||
![]() |
6096d8895d | ||
![]() |
89b3d34dd3 | ||
![]() |
d3eef8b56a | ||
![]() |
9bbe14e7a3 | ||
![]() |
726a12461f | ||
![]() |
b276e3f590 | ||
![]() |
d04ab5ad96 | ||
![]() |
379ec4b952 | ||
![]() |
026ec40e1c | ||
![]() |
93b49a72ac | ||
![]() |
3284ed4e8e | ||
![]() |
5b4a7fc377 | ||
![]() |
6c9f72380d | ||
![]() |
51fc2453ba | ||
![]() |
01acadbeb9 | ||
![]() |
b8da948caf | ||
![]() |
3c3c1a3304 | ||
![]() |
0756c301f3 | ||
![]() |
135ad0880e | ||
![]() |
fc4739f2db | ||
![]() |
d008b93444 | ||
![]() |
1c0b001b53 | ||
![]() |
9e412f9fdd | ||
![]() |
f5c5efa033 | ||
![]() |
81e3dc6ae6 | ||
![]() |
44625373bc | ||
![]() |
0d6b572ca5 | ||
![]() |
c390deafcb | ||
![]() |
ca085d799d | ||
![]() |
d79e883e93 | ||
![]() |
e30345d699 | ||
![]() |
fa3fad37ce | ||
![]() |
b5b815ef16 | ||
![]() |
19ce2d86dd | ||
![]() |
a04d4423f8 | ||
![]() |
90485cb2ee | ||
![]() |
28a7dd7fba | ||
![]() |
9b682d43db | ||
![]() |
21e95dd2d8 | ||
![]() |
874b17ca56 | ||
![]() |
c2330c5332 | ||
![]() |
2c2c1e3ebf | ||
![]() |
c66ade2eac | ||
![]() |
4913a4dd6e | ||
![]() |
e730baac4a | ||
![]() |
f80189d161 | ||
![]() |
24cb11dfd4 | ||
![]() |
b531444a7c | ||
![]() |
9a67a21bd2 | ||
![]() |
d958239da9 | ||
![]() |
73b247d72f | ||
![]() |
0b38aabde3 | ||
![]() |
b17f27f04d | ||
![]() |
edad26b4be | ||
![]() |
997c54f185 | ||
![]() |
3e3ef284de | ||
![]() |
af3d0d21a0 | ||
![]() |
e7c7e7de41 | ||
![]() |
5033b5a24d | ||
![]() |
fb0a1fba2a | ||
![]() |
f6801be8a3 | ||
![]() |
2b5e566c9d | ||
![]() |
4577ee01f2 | ||
![]() |
88d0a6a7c0 | ||
![]() |
97de24e694 | ||
![]() |
2a46ab3042 | ||
![]() |
133347440e | ||
![]() |
e8c87c8b42 | ||
![]() |
0c0d9e5696 | ||
![]() |
ea3dedffd9 | ||
![]() |
f51025e143 | ||
![]() |
74ec6530cb | ||
![]() |
113c1086e2 | ||
![]() |
d60c58f595 | ||
![]() |
3dae0592b0 | ||
![]() |
e467566866 | ||
![]() |
a941d4169f | ||
![]() |
666402870e | ||
![]() |
17cf4da726 | ||
![]() |
926ab2accf | ||
![]() |
a6b7624033 | ||
![]() |
f868c2989c | ||
![]() |
18a63f91fd | ||
![]() |
f7b5bd4a79 | ||
![]() |
ed05585063 | ||
![]() |
c19fd0ee78 | ||
![]() |
71ba94121d | ||
![]() |
bc3d285c5e | ||
![]() |
f89270325f | ||
![]() |
e84f257bff | ||
![]() |
17a4cd4be0 | ||
![]() |
0ba0418b53 | ||
![]() |
07eea03cca | ||
![]() |
a483ec7b68 | ||
![]() |
28e58887ec | ||
![]() |
7de5b4adef | ||
![]() |
a2926bd3ed | ||
![]() |
3621e998c9 | ||
![]() |
fe6f4153c5 | ||
![]() |
66b4723216 | ||
![]() |
e714e72e05 | ||
![]() |
b689100c1c | ||
![]() |
cdb2c2b3e3 | ||
![]() |
fd934aa39e | ||
![]() |
c660feadf1 | ||
![]() |
670f063a30 | ||
![]() |
2e55e00662 | ||
![]() |
73b89555fa | ||
![]() |
d8abc88e4c | ||
![]() |
48d27c982d | ||
![]() |
8f33926a75 | ||
![]() |
11f0abebe6 | ||
![]() |
bf9d2b6c52 | ||
![]() |
5e79cda7c6 | ||
![]() |
697b4ce82f | ||
![]() |
80ff2fe140 | ||
![]() |
bb27cea54c | ||
![]() |
e5a66bf51f | ||
![]() |
e8389190a9 | ||
![]() |
0e13c8d32b | ||
![]() |
904238b6ec | ||
![]() |
90b695cfdf | ||
![]() |
4682c22ece | ||
![]() |
c10bd14cde | ||
![]() |
1791ef1dc7 | ||
![]() |
272a60a478 | ||
![]() |
c2d71fdaa5 | ||
![]() |
a0865c9010 | ||
![]() |
25ec652423 | ||
![]() |
e8ad4f10b0 | ||
![]() |
bde3e0f6e3 | ||
![]() |
72f14b86cf | ||
![]() |
d2bd68693b | ||
![]() |
a2f1389efa | ||
![]() |
6b6d0de163 | ||
![]() |
ff82133050 | ||
![]() |
2df581d1ff | ||
![]() |
88f2b44bba | ||
![]() |
3a9c401f63 | ||
![]() |
963bd1344f | ||
![]() |
c68e9fc0a6 | ||
![]() |
c96317041d | ||
![]() |
c2104b62a9 | ||
![]() |
6421b3c5c1 | ||
![]() |
0b5e7ab7bb | ||
![]() |
a327e3f4d8 | ||
![]() |
8232fbddbf | ||
![]() |
f0d811b79c | ||
![]() |
fa9ae4acb7 | ||
![]() |
e009f6298a | ||
![]() |
6930987aa6 | ||
![]() |
0854592cc6 | ||
![]() |
2b2b6185e4 | ||
![]() |
f7df7939e6 | ||
![]() |
897ef661fe | ||
![]() |
9885568b47 | ||
![]() |
6ad50ac49b | ||
![]() |
f046bed225 | ||
![]() |
0ae3e1c59d | ||
![]() |
17ba7e415b | ||
![]() |
3f1cd5a596 | ||
![]() |
8139b6bad7 | ||
![]() |
5a65bc37fe | ||
![]() |
af8438878f | ||
![]() |
fb217479d2 | ||
![]() |
a8768e354d | ||
![]() |
f21e79c81c | ||
![]() |
ed80dc68aa | ||
![]() |
1dc4d6e9ba | ||
![]() |
c5538f6450 | ||
![]() |
5c96e1e81e | ||
![]() |
e7d941dc3c | ||
![]() |
b60f564bed | ||
![]() |
4b07280319 | ||
![]() |
c026337792 | ||
![]() |
603988476a | ||
![]() |
ce5e1e1933 | ||
![]() |
0c277e442e | ||
![]() |
5370fefdad | ||
![]() |
c3e160880f | ||
![]() |
6ced1ec9de | ||
![]() |
73309686bd | ||
![]() |
ab5fd961c8 | ||
![]() |
9af25d937d | ||
![]() |
8fd6985214 | ||
![]() |
454cee12d4 | ||
![]() |
eac2410c83 | ||
![]() |
ccbd32503b | ||
![]() |
4015222f89 | ||
![]() |
f0e0060ddc | ||
![]() |
79928e69cb | ||
![]() |
6a7c7df7fd | ||
![]() |
bb7c515887 | ||
![]() |
1c80672983 | ||
![]() |
3ce1e053f0 | ||
![]() |
c3f76cb5a5 | ||
![]() |
078a41b011 | ||
![]() |
676ee1e4d2 | ||
![]() |
479506013c | ||
![]() |
ec15ef1d34 | ||
![]() |
d51529bef5 | ||
![]() |
996700e207 | ||
![]() |
2bebb4bdc7 | ||
![]() |
83e1265c6b | ||
![]() |
8bf43c95a8 | ||
![]() |
c319bca477 | ||
![]() |
06ca8e20a9 | ||
![]() |
68303ae485 | ||
![]() |
add3d43dad | ||
![]() |
08a295c348 | ||
![]() |
d372d59bea | ||
![]() |
e04ae506a3 | ||
![]() |
56538bf75b | ||
![]() |
fc10ee8745 | ||
![]() |
074bc52717 | ||
![]() |
436c5a45e4 | ||
![]() |
065f19b479 | ||
![]() |
af93217701 | ||
![]() |
756158dfc9 | ||
![]() |
7b2ce98abd | ||
![]() |
9f33740d41 | ||
![]() |
ed0f3e87ca | ||
![]() |
bd6d19e084 | ||
![]() |
aefcaf8559 | ||
![]() |
4635e095ba | ||
![]() |
c09e97689b | ||
![]() |
32028f6daf | ||
![]() |
7429b2162d | ||
![]() |
a04b61ec77 | ||
![]() |
fda4734a1b | ||
![]() |
63c8df78a3 | ||
![]() |
d1b3f2d14f | ||
![]() |
30e7bf5f0d | ||
![]() |
5e7ec20057 | ||
![]() |
d83b4a4597 | ||
![]() |
d544fb9fa8 | ||
![]() |
6db352a82d | ||
![]() |
6f62056fcf | ||
![]() |
a9c32d85ea | ||
![]() |
b0e970ae38 | ||
![]() |
cc345582ad | ||
![]() |
296f1d0d1c | ||
![]() |
5c95c5cc16 | ||
![]() |
54e3bb385a | ||
![]() |
d6e99c1197 | ||
![]() |
a55f8864d2 | ||
![]() |
6fdae0c4eb | ||
![]() |
84cae48c1b | ||
![]() |
b0aa1e4e88 | ||
![]() |
5e631b4e38 | ||
![]() |
944e0b5e23 | ||
![]() |
8539c7aa9e | ||
![]() |
053afbf19b | ||
![]() |
9659c936cd | ||
![]() |
11d1d860f0 | ||
![]() |
9c33572aee | ||
![]() |
158dc40340 | ||
![]() |
b5d927ec3b | ||
![]() |
5a6b474a14 | ||
![]() |
e03b1e263d | ||
![]() |
947d7c611b | ||
![]() |
4266b88658 | ||
![]() |
f456501b9e | ||
![]() |
9ac59700d1 | ||
![]() |
11ff9adba1 | ||
![]() |
0ba811df3c | ||
![]() |
4233e0ca3a | ||
![]() |
8e03d56688 | ||
![]() |
8620698b66 | ||
![]() |
0b3b644c55 | ||
![]() |
9edd941bc2 | ||
![]() |
1f8f209c04 | ||
![]() |
c15cdbe753 | ||
![]() |
a17e5e0f7f | ||
![]() |
a0aa6fecb4 | ||
![]() |
18e48a7997 | ||
![]() |
93b5a5a4ae | ||
![]() |
0ba73ec139 | ||
![]() |
67cb8de2ef | ||
![]() |
2fe20808c2 | ||
![]() |
08de8186c6 | ||
![]() |
cf17d42972 | ||
![]() |
09b124f073 | ||
![]() |
668b61ff3a | ||
![]() |
c3d5caec98 | ||
![]() |
9ef3d51f87 | ||
![]() |
d5c364a4e4 | ||
![]() |
355c2df97e | ||
![]() |
bbf79bc511 | ||
![]() |
047b0e71a1 | ||
![]() |
d3606cd255 | ||
![]() |
62d31539d6 | ||
![]() |
f5a30a1cfc | ||
![]() |
e3bece76f9 | ||
![]() |
01c108938e | ||
![]() |
55e7caa8e0 | ||
![]() |
5567caf64a | ||
![]() |
fe0879f7d1 | ||
![]() |
e8031bab2a | ||
![]() |
5525f32cdd | ||
![]() |
6a1853b01a | ||
![]() |
eaf176220c | ||
![]() |
799ab03f59 | ||
![]() |
554a78fbf0 | ||
![]() |
0193940e50 | ||
![]() |
fde1012f5d | ||
![]() |
f39d1b4ac2 | ||
![]() |
4e4ba6769d | ||
![]() |
ada46fb2db | ||
![]() |
d40cac403f | ||
![]() |
d2cc033d09 | ||
![]() |
b18f843532 | ||
![]() |
41b8a32dfc | ||
![]() |
3f686da550 | ||
![]() |
4353110684 | ||
![]() |
278abc66be | ||
![]() |
967b7e75e3 | ||
![]() |
b647f8e1f0 | ||
![]() |
d8dc5a9bd1 | ||
![]() |
ee3c56328f | ||
![]() |
e402a11f06 | ||
![]() |
ccf265b943 | ||
![]() |
ebc42ccecf | ||
![]() |
7c7831b53d | ||
![]() |
69e86f4d21 | ||
![]() |
6f5ec005e9 | ||
![]() |
eb151efc81 | ||
![]() |
b6cf9ef866 | ||
![]() |
3890431090 | ||
![]() |
9e541fe7e8 | ||
![]() |
4168e20243 | ||
![]() |
5a7eb91378 | ||
![]() |
e1e1c4edd1 | ||
![]() |
dcaf0150b9 | ||
![]() |
c46a5d7c84 | ||
![]() |
b24e201248 | ||
![]() |
845658bd32 | ||
![]() |
a6808aa55a | ||
![]() |
423f9a4e60 | ||
![]() |
1eb82d661f | ||
![]() |
3c708b0e14 | ||
![]() |
f88d45c9d3 | ||
![]() |
6bf514c4c3 | ||
![]() |
eb92c0a6e5 | ||
![]() |
4bf8bf2396 | ||
![]() |
fedfda9fb5 | ||
![]() |
95df3e660b | ||
![]() |
6f893dbc31 | ||
![]() |
53c9a692fa | ||
![]() |
4f59231f79 | ||
![]() |
5e9f1a6806 | ||
![]() |
bb876953ac | ||
![]() |
8d76cae6b1 | ||
![]() |
7c5fb5aad4 | ||
![]() |
609f9c8f43 | ||
![]() |
d3a57d47f3 | ||
![]() |
1106514a38 | ||
![]() |
836beb1276 | ||
![]() |
32db13aef8 | ||
![]() |
946a67502b | ||
![]() |
aa9e6684cb | ||
![]() |
39ca2c3e05 | ||
![]() |
da6b818a53 | ||
![]() |
2d45461dfd | ||
![]() |
efe53e28c8 | ||
![]() |
a472874890 | ||
![]() |
5ec8a9f116 | ||
![]() |
ef7d33ee86 | ||
![]() |
62810ca3e7 | ||
![]() |
2a6690e50d | ||
![]() |
957a8aac25 | ||
![]() |
16698d0c9a | ||
![]() |
acb31477c1 | ||
![]() |
c098db1837 | ||
![]() |
5420fdaf01 | ||
![]() |
d03ea531de | ||
![]() |
e1b3e73c2b | ||
![]() |
5153b88cbe | ||
![]() |
c0149f1106 | ||
![]() |
1db3aa6092 | ||
![]() |
304627e086 | ||
![]() |
87a29c9ca3 | ||
![]() |
2079b1ef4a | ||
![]() |
4e9b455a2e | ||
![]() |
201763ff7f | ||
![]() |
18d1c752f4 | ||
![]() |
01912a427a | ||
![]() |
f769d8f1b3 | ||
![]() |
42605c9e76 | ||
![]() |
b7e2a98628 | ||
![]() |
3e69c33f74 | ||
![]() |
26c4b8b4fe | ||
![]() |
334b03478b | ||
![]() |
017d5f56df | ||
![]() |
ebd712af4e | ||
![]() |
9c72d2f546 | ||
![]() |
e28c211c36 | ||
![]() |
939a67255a | ||
![]() |
719646df4d | ||
![]() |
550f8f454c | ||
![]() |
04487f575b | ||
![]() |
313d8dbbed | ||
![]() |
008b29f359 | ||
![]() |
1f89ebb86a | ||
![]() |
9815fb38cf | ||
![]() |
758dba214e | ||
![]() |
84e32ba448 | ||
![]() |
e9179c4270 | ||
![]() |
db038022e8 | ||
![]() |
b321db20ad | ||
![]() |
15c04bb395 | ||
![]() |
d5c7b47745 | ||
![]() |
ef902c5f7e | ||
![]() |
520ad56f83 | ||
![]() |
975696c5e0 | ||
![]() |
fab764967b | ||
![]() |
3de345e903 | ||
![]() |
cbd73f8067 | ||
![]() |
1a02fdcefd | ||
![]() |
c51e187462 | ||
![]() |
311e91b944 | ||
![]() |
c58b91dfd4 | ||
![]() |
47596c67d3 | ||
![]() |
df0b64f8d0 | ||
![]() |
9897efe75c | ||
![]() |
c707bee6ac | ||
![]() |
ab51228b38 | ||
![]() |
4cc067e58e | ||
![]() |
5cf748e98b | ||
![]() |
1e8fedce6c | ||
![]() |
ee4e1368d2 | ||
![]() |
68cb9d38bf | ||
![]() |
185b676f31 | ||
![]() |
fbe7e0bd36 | ||
![]() |
1f68696578 | ||
![]() |
766257c5d6 | ||
![]() |
8e9a2fe05d | ||
![]() |
6b99b33974 | ||
![]() |
6b3d6f9d60 | ||
![]() |
d745fbe24e | ||
![]() |
cc44f50d67 | ||
![]() |
18531a524f | ||
![]() |
83a9de58c2 | ||
![]() |
f3e2c4e5c3 | ||
![]() |
bbcfde8743 | ||
![]() |
2f51b51152 | ||
![]() |
2e7fb5ee50 | ||
![]() |
9acb89d6f4 | ||
![]() |
d78d0d5937 | ||
![]() |
eeca2b3f38 | ||
![]() |
29eb08ead2 | ||
![]() |
2a8d7d4835 | ||
![]() |
e8888fab2e | ||
![]() |
cd90097ce1 | ||
![]() |
d232edde72 | ||
![]() |
4676dd7efd | ||
![]() |
1b03675002 | ||
![]() |
ffe9ce8034 | ||
![]() |
3e1a0539f5 | ||
![]() |
e1393501e7 | ||
![]() |
159afd7f18 | ||
![]() |
ddf111d2c4 | ||
![]() |
4fa4cc5867 | ||
![]() |
52810ba445 | ||
![]() |
116b36e943 | ||
![]() |
fbb0776716 | ||
![]() |
1eb2735239 | ||
![]() |
0a6de7932a | ||
![]() |
561c64e7f8 | ||
![]() |
5b94c9d243 | ||
![]() |
5df28473cb | ||
![]() |
d43a640d71 | ||
![]() |
20b7540201 | ||
![]() |
cf3ea5d4df | ||
![]() |
8b41413170 | ||
![]() |
e81b1b77c8 | ||
![]() |
b437bfaced | ||
![]() |
7b933db78a | ||
![]() |
b9cb6134d6 | ||
![]() |
03ff410dff | ||
![]() |
4c6173ee89 | ||
![]() |
6e2aba3907 | ||
![]() |
0036cb976f | ||
![]() |
199b7837d4 | ||
![]() |
17955fcf5a | ||
![]() |
9bb5ecf27a | ||
![]() |
2e3ad0f6b3 | ||
![]() |
0d5409eb04 | ||
![]() |
1f404e32a6 | ||
![]() |
2bd2462968 | ||
![]() |
3ec3855de9 | ||
![]() |
91adbcb7f4 | ||
![]() |
ad97dbee08 | ||
![]() |
85259bb519 | ||
![]() |
edac41b1b3 | ||
![]() |
0772d4b61a | ||
![]() |
9594b03a35 | ||
![]() |
c7b072ff21 | ||
![]() |
0d2d34c353 | ||
![]() |
d511b4b782 | ||
![]() |
6bba989913 | ||
![]() |
0fc97d2674 | ||
![]() |
0fad5fef71 | ||
![]() |
9335680cd8 | ||
![]() |
aa3dc1b953 | ||
![]() |
3ab2542f5f | ||
![]() |
4bc20a0979 | ||
![]() |
7a7c580ffc | ||
![]() |
99112c9317 | ||
![]() |
43c101ab14 | ||
![]() |
1f89311798 | ||
![]() |
2231179b97 | ||
![]() |
66e9d4fca9 | ||
![]() |
8c1bf5385e | ||
![]() |
1449b8fbc4 | ||
![]() |
137309c998 | ||
![]() |
d55e00b31d | ||
![]() |
7713e00992 | ||
![]() |
e4b1d4202f | ||
![]() |
a4fa91a695 | ||
![]() |
619a5ed43b | ||
![]() |
19ab25f1d6 | ||
![]() |
7a91f6dba4 | ||
![]() |
3aafb80b54 | ||
![]() |
3cf8af2431 | ||
![]() |
6f9b087304 | ||
![]() |
8173ded0eb | ||
![]() |
8840d4623d | ||
![]() |
65fdc8f2fe | ||
![]() |
e58a818ce9 | ||
![]() |
ac5ddda56f | ||
![]() |
b0fe62af5a | ||
![]() |
9047157b5e | ||
![]() |
9b459c1943 | ||
![]() |
5140c005c1 | ||
![]() |
5dd7f5a0fe | ||
![]() |
df60f0ace6 | ||
![]() |
e768f034a3 | ||
![]() |
50f2b3d0ca | ||
![]() |
4c64e0d560 | ||
![]() |
17c569ba4c | ||
![]() |
1f910f84b4 | ||
![]() |
49f38b0d2e | ||
![]() |
bfd8cead95 | ||
![]() |
94d4b341e3 | ||
![]() |
4fbfa76fc5 | ||
![]() |
9e98a74efd | ||
![]() |
0480989a73 | ||
![]() |
45d74ac1ed | ||
![]() |
c826dd0052 | ||
![]() |
8a5861d3f5 | ||
![]() |
225a28f364 | ||
![]() |
b40d7460b3 | ||
![]() |
69259b3a3f | ||
![]() |
a95cd4f0fa | ||
![]() |
930df7a2b9 | ||
![]() |
f22ba5aebb | ||
![]() |
59ce53ceb2 | ||
![]() |
887f679023 | ||
![]() |
30933423fd | ||
![]() |
1d852e10ad | ||
![]() |
4315461a6c | ||
![]() |
fb4b7e7a0b | ||
![]() |
b12a9f599d | ||
![]() |
1db8a85a60 | ||
![]() |
952b2e041c | ||
![]() |
211f7dde6e | ||
![]() |
b67ef78d1c | ||
![]() |
11c332be09 | ||
![]() |
64b2d29af6 | ||
![]() |
8016658618 | ||
![]() |
bfa670d4ef | ||
![]() |
3910b9d9c3 | ||
![]() |
2dea8bcc69 | ||
![]() |
c42de40a3b | ||
![]() |
650e7715b1 | ||
![]() |
914a03c4bf | ||
![]() |
8faa0c1f0d | ||
![]() |
28d3eed32e | ||
![]() |
736aadc75f | ||
![]() |
40c091ac7f | ||
![]() |
5600c736b8 | ||
![]() |
1f4b32ff53 | ||
![]() |
b4d85942e6 | ||
![]() |
e64de776a7 | ||
![]() |
07915485ed | ||
![]() |
edf6b1b644 | ||
![]() |
fc96b35cdc | ||
![]() |
4cf5f5c4b6 | ||
![]() |
4165d9414f | ||
![]() |
f85fcf2f21 | ||
![]() |
933be89812 | ||
![]() |
b94bc39827 | ||
![]() |
344fb528ab | ||
![]() |
bafd604834 | ||
![]() |
66f4981650 | ||
![]() |
8b64fa97f0 | ||
![]() |
b924b1da61 | ||
![]() |
75e014f72b | ||
![]() |
2fa3495e74 | ||
![]() |
ee933c6b58 | ||
![]() |
c8f4b9d98f | ||
![]() |
a09d7628dd | ||
![]() |
09c9482045 | ||
![]() |
7d3092e1ca | ||
![]() |
122ea7a8aa | ||
![]() |
5f7b28d501 | ||
![]() |
a3d0eebe74 | ||
![]() |
7e0084e6ae | ||
![]() |
98cf2bf3ec | ||
![]() |
771f292939 | ||
![]() |
0fdc3b3ed6 | ||
![]() |
38c8fe06a4 | ||
![]() |
70824d7b5a | ||
![]() |
a1b41f786e | ||
![]() |
b026e6740b | ||
![]() |
10e83aa347 | ||
![]() |
05b803cb76 | ||
![]() |
faa31802c5 | ||
![]() |
ec7044d615 | ||
![]() |
05ad0120a8 | ||
![]() |
f7c036a801 | ||
![]() |
6c9c65a5de | ||
![]() |
6bf5c3ddbd | ||
![]() |
19b0d0f2e2 | ||
![]() |
19cce531ca |
3
.codespellrc
Normal file
3
.codespellrc
Normal file
@ -0,0 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list = fils, FILS, SME, assertIn, OCE, clen, aci, ELL, sav, ths
|
||||
skip = build-aux, linux, autom4te.cache, aclocal.m4, AUTHORS, libtool, configure*, *.5, ell
|
20
.gitignore
vendored
20
.gitignore
vendored
@ -1,9 +1,16 @@
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.gcno
|
||||
*.gcda
|
||||
.libs
|
||||
.deps
|
||||
.dirstamp
|
||||
.cache
|
||||
.ccls-cache
|
||||
compile_commands.json
|
||||
tags
|
||||
cscope.*
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
@ -20,6 +27,7 @@ autom4te.cache
|
||||
ell
|
||||
src/iwd
|
||||
src/iwd.8
|
||||
src/iwd.ap.5
|
||||
src/iwd.debug.7
|
||||
src/iwd.config.5
|
||||
src/iwd.network.5
|
||||
@ -33,8 +41,9 @@ wired/ead.8
|
||||
wired/ead.service
|
||||
tools/hwsim
|
||||
tools/hwsim.1
|
||||
tools/test-runner
|
||||
tools/probe-req
|
||||
tools/iwd-decrypt-profile
|
||||
tools/iwd-psk
|
||||
unit/test-cmac-aes
|
||||
unit/test-arc4
|
||||
unit/test-hmac-md5
|
||||
@ -54,6 +63,12 @@ unit/test-eap-mschapv2
|
||||
unit/test-eap-sim
|
||||
unit/test-client
|
||||
unit/test-p2p
|
||||
unit/test-band
|
||||
unit/test-dpp
|
||||
unit/test-json
|
||||
unit/test-nl80211util
|
||||
unit/test-pmksa
|
||||
unit/test-storage
|
||||
unit/cert-*.pem
|
||||
unit/cert-*.csr
|
||||
unit/cert-*.srl
|
||||
@ -62,3 +77,6 @@ unit/*.log
|
||||
unit/*.trs
|
||||
test-suite.log
|
||||
src/builtin.h
|
||||
autotests/*/__pycache__
|
||||
iwd-coverage.info
|
||||
gcov
|
||||
|
19
AUTHORS
19
AUTHORS
@ -22,3 +22,22 @@ Pinghao Wu <xdavidwuph@gmail.com>
|
||||
Rosen Penev <rosenp@gmail.com>
|
||||
Diego Santa Cruz <Diego.SantaCruz@spinetix.com>
|
||||
Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Daniel DE ALMEIDA BRAGA <daniel.de-almeida-braga@irisa.fr>
|
||||
Ard Biesheuvel <ardb@kernel.org>
|
||||
Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
||||
Jonathan Liu <net147@gmail.com>
|
||||
Daniel Lin <ephemient@gmail.com>
|
||||
Sean Anderson <sean.anderson@seco.com>
|
||||
Joseph Benden <joe@benden.us>
|
||||
Michael Johnson <mjohnson459@gmail.com>
|
||||
Matt Oberle <matt.r.oberle@gmail.com>
|
||||
Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
|
||||
Torsten Schmitz <noreply.torsten@gmail.com>
|
||||
Diederik de Haas <didi.debian@cknow.org>
|
||||
Vladimír Dudr <vladimir@tango-dj.cz>
|
||||
Emmanuel VAUTRIN <Emmanuel.VAUTRIN@cpexterne.org>
|
||||
Jesse Lentz <jesse@twosheds.org>
|
||||
Pinghao Wu <xdavidwuph@gmail.com>
|
||||
Neehar Vijay <env252525@gmail.com>
|
||||
Jiajie Chen <c@jia.je>
|
||||
Ronan Pigott <ronan@rjp.ie>
|
||||
|
318
ChangeLog
318
ChangeLog
@ -1,3 +1,321 @@
|
||||
ver 3.9:
|
||||
Fix issue with Access Point mode and frequency unlocking.
|
||||
Fix issue with network configuration and BSS retry logic.
|
||||
Fix issue with handling busy notification from Access Point.
|
||||
Fix issue with handling P-192, P-224 and P-521 for SAE.
|
||||
|
||||
ver 3.8:
|
||||
Fix issue with handling unit tests and missing kernel features.
|
||||
|
||||
ver 3.7:
|
||||
Fix issue with handling length of EncryptedSecurity.
|
||||
Fix issue with handling empty affinities lists.
|
||||
Fix issue with handling survey scanning results.
|
||||
Fix issue with handling duplicate values in DPP URI.
|
||||
|
||||
ver 3.6:
|
||||
Fix issue with handling blacklisting and roaming requests.
|
||||
Fix issue with handling CQM thresholds for FullMAC devices.
|
||||
Add support for PMKSA when using FullMAC devices.
|
||||
|
||||
ver 3.5:
|
||||
Add support for option to disable blacklist handling.
|
||||
Add support for option to disable SAE for broken drivers.
|
||||
|
||||
ver 3.4:
|
||||
Add support for the Test Anything Protocol.
|
||||
|
||||
ver 3.3:
|
||||
Fix issue with handling External Authentication.
|
||||
|
||||
ver 3.2:
|
||||
Fix issue with GCC 15 and -std=c23 build errors.
|
||||
Add support for using PMKSA over SAE if available.
|
||||
Add support for HighUtilization/StationCount thresholds.
|
||||
Add support for disabling Multicast RX option.
|
||||
|
||||
ver 3.1:
|
||||
Fix issue with handling OWE transition BSS selection.
|
||||
Fix issue with handling oper class 136 starting frequency.
|
||||
|
||||
ver 3.0:
|
||||
Fix issue with handling alpha2 code for United Kingdom.
|
||||
Fix issue with handling empty TX/RX bitrate attributes.
|
||||
Fix issue with handling RSSI polling fallback workaround.
|
||||
Fix issue with handling harmless cloned information elements.
|
||||
Add experimental support for External Authentication feature.
|
||||
|
||||
ver 2.22:
|
||||
Fix issue with handling the Affinities property.
|
||||
Fix issue with handling ConnectedAccessPoint signal when roaming.
|
||||
|
||||
ver 2.21:
|
||||
Fix issue with pending scan requests after regdom update.
|
||||
Fix issue with handling the rearming of the roaming timeout.
|
||||
Fix issue with survey request and externally triggered scans.
|
||||
Fix issue with RSSI fallback when setting CQM threshold fails.
|
||||
Fix issue with FT-over-Air without offchannel support.
|
||||
Add support for per station Affinities property.
|
||||
|
||||
ver 2.20:
|
||||
Fix issue with PKEX timeout and number of frequencies used.
|
||||
Fix issue with handling logic for handshake failures.
|
||||
Fix issue with handling ConnectedAccessPoint signal.
|
||||
|
||||
ver 2.19:
|
||||
Fix issue with handling flush flag for external scans.
|
||||
Fix issue with handling SNR calculation in ranking.
|
||||
|
||||
ver 2.18:
|
||||
Fix issue with handling BSS with invalid HE capabilities.
|
||||
Fix issue with neighbor reports with invalid country codes.
|
||||
Fix issue with EAP-TTLS Start packets with L flag set.
|
||||
Add support for enabling SAE for AP mode operation.
|
||||
|
||||
ver 2.17:
|
||||
Fix issue with handling deauthenticate on disconnect.
|
||||
Fix issue with handling of rate estimation errors.
|
||||
Fix issue with handling EAPOL frame listeners.
|
||||
|
||||
ver 2.16:
|
||||
Fix issue with uninitialized variable and DPP encrypt.
|
||||
Fix issue with Access Point mode and ATTR_MAC validation.
|
||||
Fix issue with Access Point mode and frequency attributes.
|
||||
Fix issue with P2P and handling client info description.
|
||||
Fix issue with P2P and handling parsing of service info.
|
||||
Fix issue with netconfig and handling domain list.
|
||||
Add support for forcing a default ECC group.
|
||||
|
||||
ver 2.15:
|
||||
Fix issue with notice events for connection timeouts.
|
||||
Fix issue with reason code and deauthenticate event.
|
||||
Fix issue with handling basename() functionality.
|
||||
|
||||
ver 2.14:
|
||||
Fix issue with accepting PTK 4/4 after receiving PTK 2/4.
|
||||
Fix issue with frequency limit for quick scans.
|
||||
Fix issue with limiting DHCPv4 attempts.
|
||||
|
||||
ver 2.13:
|
||||
Fix issue with handling netconfig and roaming conditions.
|
||||
Fix issue with logging requirement for CMD_EXTERNAL_AUTH.
|
||||
Fix issue with using OpenSSL 3.2 installations.
|
||||
|
||||
ver 2.12:
|
||||
Fix issue with DPP extra settings not being used.
|
||||
Fix issue with DPP and PRF+ handling on AARCH64.
|
||||
Add support for SAE password identifiers.
|
||||
|
||||
ver 2.11:
|
||||
Fix issue with handling iovecs with multiple IEs.
|
||||
Fix issue with handling SAE password identifiers.
|
||||
Fix issue with handling agent release method call.
|
||||
|
||||
ver 2.10:
|
||||
Fix issue with buffer overflow for 32 byte SSIDs.
|
||||
Fix issue with deauthentication before FT work completes.
|
||||
Fix issue with power save disabling procedure.
|
||||
|
||||
ver 2.9:
|
||||
Fix issue with handling certain FT failures.
|
||||
Fix issue with handling user-disabled bands.
|
||||
Fix issue with handling roam on beacon loss event.
|
||||
Add support for PKEX configurator.
|
||||
Add support for PKEX enrollee.
|
||||
|
||||
ver 2.8:
|
||||
Fix issue with handling OWE AKM in association reply.
|
||||
|
||||
ver 2.7:
|
||||
Fix issue with handling FT-8021X and SHA256 PMKID derivation.
|
||||
|
||||
ver 2.6:
|
||||
Add support for setting driver specific quirks.
|
||||
Add support for disabling power saving mode.
|
||||
|
||||
ver 2.5:
|
||||
Fix issue with HT40+/- checks when creating chandef.
|
||||
Fix issue with handling support for FT-8021X-SHA384.
|
||||
Fix issue with handling secure bit check in handshake 1/4.
|
||||
Fix issue with allowing roaming before netconfig finishes.
|
||||
Fix issue with double free when disconnecting during FT.
|
||||
|
||||
ver 2.4:
|
||||
Fix issue with FT-over-Air and same channel operation.
|
||||
Fix issue with AP mode and missing support for GTK.
|
||||
Fix issue with AP mode and channel switch event.
|
||||
Fix issue with SSID string conversion handling.
|
||||
|
||||
ver 2.3:
|
||||
Fix issue with length calculation for WMM IE.
|
||||
Fix issue with channel number allocation off-by-one.
|
||||
Fix issue with cached session when TLS phase2 fails.
|
||||
Add support for FastReauthentication setting for EAP-TLS.
|
||||
|
||||
ver 2.2:
|
||||
Fix issue with handling FT and multiple roaming scans.
|
||||
Fix issue with handling multiple wiphy registrations.
|
||||
Fix issue with with EAP-PEAP session resumption.
|
||||
Add support for using PTK rekeying in AP mode.
|
||||
Add support for setting country IE in AP mode.
|
||||
Add support for setting WMM parameter IE in AP mode.
|
||||
|
||||
ver 2.1:
|
||||
Fix issue with handling FT-over-DS action.
|
||||
Fix issue with handling scan and 6 GHz support check.
|
||||
Fix issue with handling when periodic scans get aborted.
|
||||
Add support for using 5 GHz frequencies in AP mode.
|
||||
|
||||
ver 2.0:
|
||||
Fix issue with handling P2P and limiting ciphers to CCMP.
|
||||
Fix issue with scanning before forced roaming action.
|
||||
Fix issue with provided scan frequencies from RRM.
|
||||
Fix issue with handling Michael MIC failure message.
|
||||
Fix issue with handling timestamp size in MPDU frames.
|
||||
Fix issue with handling enablement of OCVC for FT AKMs.
|
||||
Fix issue with handling FT work as highest priority.
|
||||
Fix issue with handling roaming events and Multi-BSS.
|
||||
Add support for utilizing roaming candidates list.
|
||||
Add support for utilizing TLS session caching.
|
||||
Add support for ciphers with 256 bits key size.
|
||||
Add support for Access Point mode with legacy TKIP.
|
||||
Add support for MAC address changes while powered.
|
||||
Add support for IPv4 and IPv6 network configuration.
|
||||
|
||||
ver 1.30:
|
||||
Fix issue with handling OWE if buggy AP is detected.
|
||||
Fix issue with handling quick scan and enabling 6GHz.
|
||||
Fix issue with handling tags for extended IEs.
|
||||
Add support for handling HE capabilities.
|
||||
Add support for handling regulatory domain changes.
|
||||
Add support for handling netdev packet loss events.
|
||||
|
||||
ver 1.29:
|
||||
Fix issue with handling EAP-Success message.
|
||||
Fix issue with handling secure setting and EAPoL.
|
||||
Add support for DeviceProvisioning API properties.
|
||||
|
||||
ver 1.28:
|
||||
Fix issue with handling invalid EAPoL frames.
|
||||
Fix issue with handling unexpectedly unencrypted EAP frames.
|
||||
Fix issue with handling AlwaysRandomizeAddress/AddressOverride.
|
||||
Fix issue with handling initial signal level notification.
|
||||
Fix issue with handling sorting of scan requests.
|
||||
Fix issue with handling frame type check in FT.
|
||||
|
||||
ver 1.27:
|
||||
Fix issue with hidden networks on connection error.
|
||||
Fix issue with directed roams if already trying to roam.
|
||||
Fix issue with checking for connected in FT frame event.
|
||||
|
||||
ver 1.26:
|
||||
Fix issue with handling BSS that changed frequency.
|
||||
Fix issue with handling frequencies in neighbor report.
|
||||
Fix issue with operating classes for 802.11ax standard.
|
||||
Fix issue with enforcing of MFPR for 6 GHz frequencies.
|
||||
Add support for band defined in the WiFi 6E amendment.
|
||||
Add support for scanning while in AP mode.
|
||||
|
||||
ver 1.25:
|
||||
Fix issue with handling abort of periodic scans.
|
||||
Fix issue with handling connection when link goes down.
|
||||
Fix issue with handling operating channel information.
|
||||
Add support for encrypted network profile storage.
|
||||
Add support for DPP initiating as a configurator.
|
||||
|
||||
ver 1.24:
|
||||
Fix issue with handshake and missing rekeying support.
|
||||
Fix issue with BSS ranking and zero signal strength.
|
||||
Fix issue with setting OWE IE length correctly.
|
||||
|
||||
ver 1.23:
|
||||
Fix issue with handling handshake offloading.
|
||||
Fix issue with at_console and D-Bus policy.
|
||||
|
||||
ver 1.22:
|
||||
Fix issue with handling periodic scanning.
|
||||
Fix issue with handling scanning completion.
|
||||
Fix issue with handling scanning for OWE auto-connect.
|
||||
Add support for additional DPP features.
|
||||
|
||||
ver 1.21:
|
||||
Fix issue with handling disconnect events issued by AP.
|
||||
Add experimental support for DPP feature.
|
||||
|
||||
ver 1.20:
|
||||
Fix issue with handling Hotspot 2.0 requirements.
|
||||
Add support for evict_nocarrier setting during roaming.
|
||||
Add support for experimental NetworkConfigurationAgent API.
|
||||
|
||||
ver 1.19:
|
||||
Fix issue with handling OCV if offloading is supported.
|
||||
Fix issue with handling SA Query on channel switch event.
|
||||
Fix issue with starting FT-over-DS actions after roaming.
|
||||
Add support for OWE transition networks.
|
||||
Add support for extended key IDs.
|
||||
|
||||
ver 1.18:
|
||||
Fix issue with handling faulty SAE duplicate commits.
|
||||
Add support for Access Point FILS IP Address Assignment IE.
|
||||
Add support for P2P GO-side 4-way handshake IP allocation.
|
||||
Add support for forcing SAE group 19 if BSS requires it.
|
||||
|
||||
ver 1.17:
|
||||
Fix issue with sending additional and vendor IEs.
|
||||
Fix issue with IE ordering for 802.11-2020 support.
|
||||
Fix issue with frequency update on channel switch events.
|
||||
Fix issue with drivers and handling of IF_OPER_UP setting.
|
||||
|
||||
ver 1.16:
|
||||
Fix issue with writing provisioning files with a passphrase.
|
||||
Add support for Authenticator & Supplicant RSN Extension elements.
|
||||
Add support for handling Transition Disable info.
|
||||
Add support for SAE Hash-to-Element feature.
|
||||
|
||||
ver 1.15:
|
||||
Add support for FT-over-DS procedure with multiple BSS.
|
||||
Add support for estimation of VHT RX data rate.
|
||||
Add support for exporting Daemon information.
|
||||
|
||||
ver 1.14:
|
||||
Fix issue with scanning property and quick scan cancellation.
|
||||
Fix issue with handling authentication timeouts from SAE.
|
||||
Fix issue with handling association timeouts and retries.
|
||||
Fix issue with handling roaming frequencies after roaming.
|
||||
Fix issue with requesting neighbor report after roaming.
|
||||
Add support for handling PSK offload connections.
|
||||
|
||||
ver 1.13:
|
||||
Fix issue with EAPoL protocol version 2010 handling.
|
||||
Fix issue with authenticator method logic handling.
|
||||
Fix issue with getting scan results from firmware.
|
||||
Add support for handling SAE offload connections.
|
||||
Add support for roaming with FullMAC devices.
|
||||
|
||||
ver 1.12:
|
||||
Fix issue with handling retry roaming without higher RSSI.
|
||||
Fix issue with WPA3, OWE and FILS authentication handling.
|
||||
Fix issue with handling locally generated deauth frames.
|
||||
Fix issue with quick scanning and connect interaction.
|
||||
Add support for diagnostic D-Bus interfaces.
|
||||
|
||||
ver 1.11:
|
||||
Add support for ACD client for static configuration.
|
||||
Add support for intelligent scan of all frequencies.
|
||||
|
||||
ver 1.10:
|
||||
Add support for DHCP v6 configuration.
|
||||
Add support for DHCP server operation with AP mode.
|
||||
Add support for IP allocation during the 4-Way Handshake.
|
||||
Add support for P2P Group-owner handling.
|
||||
|
||||
ver 1.9:
|
||||
Fix issue with WPA3 connections in transition mode.
|
||||
Fix issue with handling roaming attempt failures.
|
||||
Add support for radio management work queue.
|
||||
Add support P2P service manager interface.
|
||||
Add support for WiFi Display client API.
|
||||
|
||||
ver 1.8:
|
||||
Fix issue with handling FT AKMs when not supported.
|
||||
Fix issue with handling FILS and RSNE in authenticate.
|
||||
|
2
HACKING
2
HACKING
@ -5,7 +5,7 @@ If you fixed a bug or you want to add support for something, patches are
|
||||
welcome! The preferred method of submitting the patches to the project is by
|
||||
email to the iwd mailing list:
|
||||
|
||||
iwd@lists.01.org
|
||||
iwd@lists.linux.dev
|
||||
|
||||
In order to ease the inclusion of your patch, it's important to follow
|
||||
some rules, otherwise it will likely be rejected by maintainers.
|
||||
|
246
Makefile.am
246
Makefile.am
@ -10,12 +10,12 @@ if EXTERNAL_ELL
|
||||
ell_cflags = @ELL_CFLAGS@
|
||||
ell_ldadd = @ELL_LIBS@
|
||||
ell_dependencies =
|
||||
ell_built_sources =
|
||||
ell_built_sources = ell/shared
|
||||
else
|
||||
ell_cflags =
|
||||
ell_ldadd = ell/libell-internal.la
|
||||
ell_dependencies = $(ell_ldadd)
|
||||
ell_built_sources = ell/internal ell/ell.h
|
||||
ell_built_sources = ell/shared ell/internal ell/ell.h
|
||||
|
||||
noinst_LTLIBRARIES = ell/libell-internal.la
|
||||
|
||||
@ -34,7 +34,6 @@ ell_headers = ell/util.h \
|
||||
ell/io.h \
|
||||
ell/ringbuf.h \
|
||||
ell/log.h \
|
||||
ell/plugin.h \
|
||||
ell/checksum.h \
|
||||
ell/netlink.h \
|
||||
ell/genl.h \
|
||||
@ -51,7 +50,6 @@ ell_headers = ell/util.h \
|
||||
ell/tls.h \
|
||||
ell/uuid.h \
|
||||
ell/key.h \
|
||||
ell/pkcs5.h \
|
||||
ell/file.h \
|
||||
ell/dir.h \
|
||||
ell/net.h \
|
||||
@ -60,18 +58,29 @@ ell_headers = ell/util.h \
|
||||
ell/ecc.h \
|
||||
ell/ecdh.h \
|
||||
ell/time.h \
|
||||
ell/path.h
|
||||
ell/path.h \
|
||||
ell/icmp6.h \
|
||||
ell/dhcp6.h \
|
||||
ell/acd.h \
|
||||
ell/cleanup.h \
|
||||
ell/netconfig.h \
|
||||
ell/sysctl.h \
|
||||
ell/notifylist.h \
|
||||
ell/minheap.h
|
||||
|
||||
ell_sources = ell/private.h \
|
||||
ell/missing.h \
|
||||
ell/util.c \
|
||||
ell/test-private.h \
|
||||
ell/test.c \
|
||||
ell/test-dbus.c \
|
||||
ell/strv.c \
|
||||
ell/utf8.c \
|
||||
ell/queue.c \
|
||||
ell/hashmap.c \
|
||||
ell/string.c \
|
||||
ell/settings.c \
|
||||
ell/main-private.h \
|
||||
ell/main.c \
|
||||
ell/idle.c \
|
||||
ell/signal.c \
|
||||
@ -79,11 +88,11 @@ ell_sources = ell/private.h \
|
||||
ell/io.c \
|
||||
ell/ringbuf.c \
|
||||
ell/log.c \
|
||||
ell/plugin.c \
|
||||
ell/checksum.c \
|
||||
ell/netlink-private.h \
|
||||
ell/netlink.c \
|
||||
ell/genl.c \
|
||||
ell/rtnl-private.h \
|
||||
ell/rtnl.c \
|
||||
ell/dbus-private.h \
|
||||
ell/dbus.c \
|
||||
@ -112,25 +121,49 @@ ell_sources = ell/private.h \
|
||||
ell/tls-extensions.c \
|
||||
ell/uuid.c \
|
||||
ell/key.c \
|
||||
ell/pkcs5-private.h \
|
||||
ell/pkcs5.c \
|
||||
ell/file.c \
|
||||
ell/dir.c \
|
||||
ell/net-private.h \
|
||||
ell/net.c \
|
||||
ell/dhcp-private.h \
|
||||
ell/dhcp.c \
|
||||
ell/dhcp-transport.c \
|
||||
ell/dhcp-lease.c \
|
||||
ell/dhcp-util.c \
|
||||
ell/dhcp-server.c \
|
||||
ell/cert-private.h \
|
||||
ell/cert.c \
|
||||
ell/cert-crypto.c \
|
||||
ell/ecc-external.c \
|
||||
ell/ecc-private.h \
|
||||
ell/ecc.c \
|
||||
ell/ecdh.c \
|
||||
ell/time.c \
|
||||
ell/path.c
|
||||
ell/time-private.h \
|
||||
ell/path.c \
|
||||
ell/dhcp6.c \
|
||||
ell/dhcp6-private.h \
|
||||
ell/icmp6.c \
|
||||
ell/icmp6-private.h \
|
||||
ell/dhcp6-lease.c \
|
||||
ell/dhcp6-transport.c \
|
||||
ell/acd.c \
|
||||
ell/netconfig.c \
|
||||
ell/sysctl.c \
|
||||
ell/notifylist.c \
|
||||
ell/minheap.c
|
||||
|
||||
ell_libell_internal_la_SOURCES = $(ell_headers) $(ell_sources)
|
||||
ell_shared = ell/useful.h ell/asn1-private.h
|
||||
|
||||
ell_libell_internal_la_SOURCES = $(ell_headers) $(ell_sources) $(ell_shared)
|
||||
endif
|
||||
|
||||
if LIBEDIT
|
||||
client_cflags = $(LIBEDIT_CFLAGS)
|
||||
client_ldadd = $(LIBEDIT_LIBS)
|
||||
else
|
||||
client_cflags =
|
||||
client_ldadd = $(READLINE_LIBS)
|
||||
endif
|
||||
|
||||
bin_PROGRAMS =
|
||||
@ -161,7 +194,8 @@ man_MANS =
|
||||
endif
|
||||
|
||||
manual_pages = src/iwd.8 src/iwd.debug.7 src/iwd.config.5 src/iwd.network.5 \
|
||||
client/iwctl.1 monitor/iwmon.1 wired/ead.8 tools/hwsim.1
|
||||
src/iwd.ap.5 client/iwctl.1 monitor/iwmon.1 wired/ead.8 \
|
||||
tools/hwsim.1
|
||||
|
||||
eap_sources = src/eap.c src/eap.h src/eap-private.h \
|
||||
src/eap-md5.c \
|
||||
@ -184,8 +218,8 @@ eap_sources = src/eap.c src/eap.h src/eap-private.h \
|
||||
if DAEMON
|
||||
libexec_PROGRAMS += src/iwd
|
||||
|
||||
src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
|
||||
src/plugin.h src/plugin.c \
|
||||
src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
|
||||
src/missing.h src/defs.h \
|
||||
src/netdev.h src/netdev.c \
|
||||
src/wiphy.h src/wiphy.c \
|
||||
src/device.c \
|
||||
@ -207,7 +241,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
|
||||
src/knownnetworks.c \
|
||||
src/rfkill.h src/rfkill.c \
|
||||
src/ft.h src/ft.c \
|
||||
src/ap.c src/adhoc.c \
|
||||
src/ap.h src/ap.c src/adhoc.c \
|
||||
src/sae.h src/sae.c \
|
||||
src/nl80211util.h src/nl80211util.c \
|
||||
src/nl80211cmd.h src/nl80211cmd.c \
|
||||
@ -220,7 +254,8 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
|
||||
src/anqp.h src/anqp.c \
|
||||
src/anqputil.h src/anqputil.c \
|
||||
src/netconfig.h src/netconfig.c\
|
||||
src/resolve.h src/resolve.c\
|
||||
src/netconfig-commit.c \
|
||||
src/resolve.h src/resolve.c \
|
||||
src/hotspot.c \
|
||||
src/p2p.h src/p2p.c \
|
||||
src/p2putil.h src/p2putil.c \
|
||||
@ -229,20 +264,25 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
|
||||
src/frame-xchg.h src/frame-xchg.c \
|
||||
src/eap-wsc.c src/eap-wsc.h \
|
||||
src/wscutil.h src/wscutil.c \
|
||||
src/diagnostic.h src/diagnostic.c \
|
||||
src/ip-pool.h src/ip-pool.c \
|
||||
src/band.h src/band.c \
|
||||
src/sysfs.h src/sysfs.c \
|
||||
src/offchannel.h src/offchannel.c \
|
||||
src/dpp-util.h src/dpp-util.c \
|
||||
src/json.h src/json.c \
|
||||
src/dpp.c \
|
||||
src/udev.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
$(eap_sources) \
|
||||
$(builtin_sources)
|
||||
|
||||
src_iwd_LDADD = $(ell_ldadd) -ldl
|
||||
src_iwd_DEPENDENCIES = $(ell_dependencies)
|
||||
|
||||
if SIM_HARDCODED
|
||||
builtin_modules += sim_hardcoded
|
||||
builtin_sources += plugins/sim_hardcoded.c
|
||||
endif
|
||||
|
||||
if OFONO
|
||||
builtin_modules += ofono
|
||||
builtin_sources += plugins/ofono.c
|
||||
builtin_sources += src/ofono.c
|
||||
endif
|
||||
|
||||
if DBUS_POLICY
|
||||
@ -259,7 +299,8 @@ systemd_network_DATA += src/80-iwd.link
|
||||
endif
|
||||
|
||||
if MANUAL_PAGES
|
||||
man_MANS += src/iwd.8 src/iwd.debug.7 src/iwd.config.5 src/iwd.network.5
|
||||
man_MANS += src/iwd.8 src/iwd.debug.7 src/iwd.config.5 src/iwd.network.5 \
|
||||
src/iwd.ap.5
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -279,8 +320,16 @@ client_iwctl_SOURCES = client/main.c \
|
||||
client/known-networks.c \
|
||||
client/network.h client/network.c \
|
||||
client/properties.h client/properties.c \
|
||||
client/wsc.c client/station.c
|
||||
client_iwctl_LDADD = $(ell_ldadd) -lreadline
|
||||
client/wsc.c client/station.c \
|
||||
client/diagnostic.c client/diagnostic.h \
|
||||
client/daemon.c client/daemon.h \
|
||||
client/dpp.c client/dpp-pkex.c \
|
||||
client/station-debug.c \
|
||||
client/bss.c \
|
||||
src/util.c src/util.h \
|
||||
src/band.c src/band.h
|
||||
|
||||
client_iwctl_LDADD = $(ell_ldadd) $(client_ldadd)
|
||||
|
||||
if MANUAL_PAGES
|
||||
man_MANS += client/iwctl.1
|
||||
@ -301,10 +350,10 @@ monitor_iwmon_SOURCES = monitor/main.c linux/nl80211.h \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/watchlist.h src/watchlist.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/nl80211cmd.h src/nl80211cmd.c \
|
||||
src/p2putil.c src/p2putil.h \
|
||||
src/anqputil.h src/anqputil.c
|
||||
src/anqputil.h src/anqputil.c \
|
||||
src/band.h src/band.c
|
||||
monitor_iwmon_LDADD = $(ell_ldadd)
|
||||
|
||||
if MANUAL_PAGES
|
||||
@ -319,6 +368,7 @@ wired_ead_SOURCES = wired/main.c wired/ethdev.h wired/ethdev.c \
|
||||
wired/network.h wired/network.c \
|
||||
wired/dbus.h wired/dbus.c \
|
||||
src/module.h src/module.c \
|
||||
src/band.h src/band.c \
|
||||
$(eap_sources)
|
||||
wired_ead_LDADD = $(ell_ldadd)
|
||||
wired_ead_DEPENDENCIES = $(ell_dependencies)
|
||||
@ -339,22 +389,36 @@ man_MANS += wired/ead.8
|
||||
endif
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS += tools/probe-req
|
||||
if DAEMON
|
||||
noinst_PROGRAMS += tools/probe-req tools/iwd-decrypt-profile
|
||||
|
||||
tools_probe_req_SOURCES = tools/probe-req.c src/mpdu.h src/mpdu.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/nl80211util.h src/nl80211util.c \
|
||||
src/util.h src/util.c \
|
||||
src/common.h src/common.c
|
||||
src/common.h src/common.c \
|
||||
src/band.h src/band.c
|
||||
tools_probe_req_LDADD = $(ell_ldadd)
|
||||
|
||||
tools_iwd_decrypt_profile_SOURCES = tools/iwd-decrypt-profile.c \
|
||||
src/common.h src/common.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/storage.h src/storage.c
|
||||
tools_iwd_decrypt_profile_LDADD = ${ell_ldadd}
|
||||
endif
|
||||
|
||||
if HWSIM
|
||||
bin_PROGRAMS += tools/hwsim
|
||||
|
||||
tools_hwsim_SOURCES = tools/hwsim.c src/mpdu.h \
|
||||
src/util.h src/util.c \
|
||||
src/nl80211cmd.h src/nl80211cmd.c \
|
||||
src/nl80211util.h src/nl80211util.c \
|
||||
src/storage.h src/storage.c \
|
||||
src/common.h src/common.c
|
||||
src/common.h src/common.c \
|
||||
src/band.h src/band.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/crypto.h src/crypto.c
|
||||
tools_hwsim_LDADD = $(ell_ldadd)
|
||||
|
||||
if DBUS_POLICY
|
||||
@ -366,20 +430,19 @@ man_MANS += tools/hwsim.1
|
||||
endif
|
||||
endif
|
||||
|
||||
if TOOLS
|
||||
noinst_PROGRAMS += tools/test-runner
|
||||
unit_tests =
|
||||
|
||||
tools_test_runner_SOURCES = tools/test-runner.c
|
||||
tools_test_runner_LDADD = $(ell_ldadd)
|
||||
endif
|
||||
|
||||
unit_tests = unit/test-cmac-aes \
|
||||
if DAEMON
|
||||
unit_tests += unit/test-cmac-aes \
|
||||
unit/test-hmac-md5 unit/test-hmac-sha1 unit/test-hmac-sha256 \
|
||||
unit/test-prf-sha1 unit/test-kdf-sha256 \
|
||||
unit/test-crypto unit/test-eapol unit/test-mpdu \
|
||||
unit/test-ie unit/test-util unit/test-ssid-security \
|
||||
unit/test-arc4 unit/test-wsc unit/test-eap-mschapv2 \
|
||||
unit/test-eap-sim unit/test-sae unit/test-p2p
|
||||
unit/test-eap-sim unit/test-sae unit/test-p2p unit/test-band \
|
||||
unit/test-dpp unit/test-json unit/test-nl80211util \
|
||||
unit/test-pmksa unit/test-storage
|
||||
endif
|
||||
|
||||
if CLIENT
|
||||
unit_tests += unit/test-client
|
||||
@ -389,6 +452,7 @@ if MAINTAINER_MODE
|
||||
noinst_PROGRAMS += $(unit_tests)
|
||||
endif
|
||||
|
||||
if DAEMON
|
||||
unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||
src/crypto.h src/crypto.c src/simutil.h src/simutil.c \
|
||||
src/ie.h src/ie.c \
|
||||
@ -396,12 +460,13 @@ unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/util.h src/util.c \
|
||||
src/simauth.h src/simauth.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/eap-sim.c
|
||||
|
||||
unit_test_eap_sim_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_cmac_aes_SOURCES = unit/test-cmac-aes.c \
|
||||
@ -410,7 +475,6 @@ unit_test_cmac_aes_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_arc4_SOURCES = unit/test-arc4.c \
|
||||
src/crypto.h src/crypto.c
|
||||
|
||||
unit_test_arc4_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_hmac_md5_SOURCES = unit/test-hmac-md5.c \
|
||||
@ -436,6 +500,10 @@ unit_test_kdf_sha256_LDADD = $(ell_ldadd)
|
||||
unit_test_ie_SOURCES = unit/test-ie.c src/ie.h src/ie.c
|
||||
unit_test_ie_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_band_SOURCES = unit/test-band.c src/band.h src/band.c src/netdev.h \
|
||||
src/ie.h src/ie.c
|
||||
unit_test_band_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_crypto_SOURCES = unit/test-crypto.c \
|
||||
src/crypto.h src/crypto.c
|
||||
unit_test_crypto_LDADD = $(ell_ldadd)
|
||||
@ -452,11 +520,13 @@ unit_test_eapol_SOURCES = unit/test-eapol.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/eap-tls.c src/eap-ttls.c \
|
||||
src/eap-md5.c src/util.c \
|
||||
src/eap-tls-common.h src/eap-tls-common.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/mschaputil.h src/mschaputil.c
|
||||
unit_test_eapol_LDADD = $(ell_ldadd)
|
||||
unit_test_eapol_DEPENDENCIES = $(ell_dependencies) \
|
||||
@ -466,7 +536,7 @@ unit_test_eapol_DEPENDENCIES = $(ell_dependencies) \
|
||||
unit/cert-client-key-pkcs8.pem \
|
||||
unit/tls-settings.8021x
|
||||
|
||||
unit_test_util_SOURCES = src/util.h src/util.c \
|
||||
unit_test_util_SOURCES = src/util.h src/util.c src/band.c src/band.h \
|
||||
unit/test-util.c
|
||||
unit_test_util_LDADD = $(ell_ldadd)
|
||||
|
||||
@ -481,9 +551,11 @@ unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
|
||||
src/eapol.h src/eapol.c \
|
||||
src/eapolutil.h src/eapolutil.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/eap.h src/eap.c src/eap-private.h \
|
||||
src/util.h src/util.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/eap-wsc.h src/eap-wsc.c
|
||||
unit_test_wsc_LDADD = $(ell_ldadd)
|
||||
|
||||
@ -493,6 +565,53 @@ unit_test_eap_mschapv2_SOURCES = src/eap-mschapv2.h src/eap-mschapv2.c \
|
||||
unit/test-eap-mschapv2.c
|
||||
unit_test_eap_mschapv2_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_sae_SOURCES = unit/test-sae.c \
|
||||
src/sae.h src/sae.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/pmksa.h src/pmksa.c \
|
||||
src/erp.h src/erp.c \
|
||||
src/band.h src/band.c \
|
||||
src/util.h src/util.c \
|
||||
src/mpdu.h src/mpdu.c
|
||||
unit_test_sae_LDADD = $(ell_ldadd)
|
||||
unit_test_sae_LDFLAGS = -Wl,-wrap,l_ecc_supported_ike_groups
|
||||
|
||||
unit_test_p2p_SOURCES = unit/test-p2p.c src/wscutil.h src/wscutil.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/util.h src/util.c \
|
||||
src/p2putil.h src/p2putil.c \
|
||||
src/band.h src/band.c
|
||||
unit_test_p2p_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_dpp_SOURCES = unit/test-dpp.c src/dpp-util.h src/dpp-util.c \
|
||||
src/band.h src/band.c \
|
||||
src/util.h src/util.c src/crypto.h \
|
||||
src/crypto.c src/json.h src/json.c
|
||||
unit_test_dpp_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_json_SOURCES = unit/test-json.c src/json.h src/json.c shared/jsmn.h
|
||||
unit_test_json_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_nl80211util_SOURCES = unit/test-nl80211util.c \
|
||||
src/nl80211util.h src/nl80211util.c \
|
||||
src/band.h src/band.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/util.h src/util.c
|
||||
unit_test_nl80211util_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_pmksa_SOURCES = unit/test-pmksa.c src/pmksa.c src/pmksa.h \
|
||||
src/module.h src/util.h
|
||||
unit_test_pmksa_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_storage_SOURCES = unit/test-storage.c src/storage.c src/storage.h \
|
||||
src/crypto.c src/crypto.h \
|
||||
src/common.c src/common.h
|
||||
unit_test_storage_LDADD = $(ell_ldadd)
|
||||
endif
|
||||
|
||||
if CLIENT
|
||||
unit_test_client_SOURCES = unit/test-client.c \
|
||||
client/adapter.c \
|
||||
@ -503,35 +622,23 @@ unit_test_client_SOURCES = unit/test-client.c \
|
||||
client/display.h client/display.c \
|
||||
client/network.h client/network.c \
|
||||
client/properties.h client/properties.c
|
||||
unit_test_client_LDADD = $(ell_ldadd) -lreadline
|
||||
unit_test_client_LDADD = $(ell_ldadd) $(client_ldadd)
|
||||
endif
|
||||
|
||||
unit_test_sae_SOURCES = unit/test-sae.c \
|
||||
src/sae.h src/sae.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/handshake.h src/handshake.c \
|
||||
src/util.h src/util.c \
|
||||
src/mpdu.h src/mpdu.c
|
||||
unit_test_sae_LDADD = $(ell_ldadd)
|
||||
|
||||
unit_test_p2p_SOURCES = unit/test-p2p.c src/wscutil.h src/wscutil.c \
|
||||
src/crypto.h src/crypto.c \
|
||||
src/ie.h src/ie.c \
|
||||
src/util.h src/util.c \
|
||||
src/p2putil.h src/p2putil.c
|
||||
unit_test_p2p_LDADD = $(ell_ldadd)
|
||||
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
|
||||
$(top_srcdir)/build-aux/tap-driver.sh
|
||||
|
||||
TESTS = $(unit_tests)
|
||||
|
||||
EXTRA_DIST = src/genbuiltin src/iwd.service.in src/net.connman.iwd.service \
|
||||
wired/ead.service.in wired/net.connman.ead.service \
|
||||
src/80-iwd.link src/pkcs8.conf unit/gencerts.cnf \
|
||||
doc/main.conf \
|
||||
$(manual_pages) $(patsubst %.1,%.rst, \
|
||||
$(patsubst %.5,%.rst, \
|
||||
$(patsubst %.8,%.rst,$(manual_pages))))
|
||||
|
||||
AM_CFLAGS = $(ell_cflags) -fvisibility=hidden \
|
||||
AM_CFLAGS = $(ell_cflags) $(client_cflags) -fvisibility=hidden \
|
||||
-DUNITDIR=\""$(top_srcdir)/unit/"\" \
|
||||
-DCERTDIR=\""$(top_builddir)/unit/"\"
|
||||
|
||||
@ -542,7 +649,6 @@ endif
|
||||
CLEANFILES = src/iwd.service wired/ead.service
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --disable-dbus-policy --disable-systemd-service \
|
||||
--enable-sim-hardcoded \
|
||||
--enable-ofono \
|
||||
--enable-wired \
|
||||
--enable-hwsim \
|
||||
@ -621,6 +727,14 @@ unit/tls-settings.8021x: unit/cert-ca.pem unit/cert-client.pem unit/cert-client-
|
||||
|
||||
BUILT_SOURCES = $(ell_built_sources) src/builtin.h
|
||||
|
||||
ell/shared: Makefile
|
||||
$(AM_V_at)$(MKDIR_P) ell
|
||||
$(AM_V_GEN)for f in $(ell_shared) ; do \
|
||||
if [ ! -f $$f ] ; then \
|
||||
$(LN_S) -t ell -f $(abs_srcdir)/../ell/$$f ; \
|
||||
fi \
|
||||
done > $@
|
||||
|
||||
ell/internal: Makefile
|
||||
$(AM_V_at)$(MKDIR_P) ell
|
||||
$(AM_V_GEN)for f in $(ell_headers) $(ell_sources) ; do \
|
||||
@ -630,6 +744,7 @@ ell/internal: Makefile
|
||||
done > $@
|
||||
|
||||
ell/ell.h: Makefile
|
||||
$(AM_V_at)$(MKDIR_P) ell
|
||||
$(AM_V_at)echo -n > $@
|
||||
$(AM_V_GEN)for f in $(ell_headers) ; do \
|
||||
echo "#include <$$f>" >> $@ ; \
|
||||
@ -673,12 +788,25 @@ if WIRED
|
||||
endif
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
gcov-clean:
|
||||
if GCOV
|
||||
-$(LCOV) --quiet --directory $(builddir) -z
|
||||
-rm -rf "$(builddir)/iwd-coverage.info" "$(builddir)/gcov"
|
||||
-find . -name "*.gcda" -o -name "*.gcov" -o -name "*.gcno" -delete
|
||||
endif
|
||||
|
||||
clean-local: gcov-clean
|
||||
-rm -f unit/cert-*.pem unit/cert-*.csr unit/cert-*.srl unit/*-settings.8021x
|
||||
|
||||
maintainer-clean-local:
|
||||
-rm -rf build-aux ell
|
||||
|
||||
gcov-report:
|
||||
if GCOV
|
||||
$(LCOV) --quiet --directory $(builddir) --capture --output-file "iwd-coverage.info"
|
||||
LANG=C $(GENHTML) --quiet --prefix $(builddir) --output-directory "$(builddir)/gcov" --title "iwd Code Coverage" --legend "$(builddir)/iwd-coverage.info"
|
||||
endif
|
||||
|
||||
src/builtin.h: src/genbuiltin config.status
|
||||
$(AM_V_at)$(MKDIR_P) $(@D)
|
||||
$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
|
||||
|
11
README
11
README
@ -193,12 +193,6 @@ that can be enabled if the functionality is required:
|
||||
|
||||
Note: With --disable-daemon this option is ignored
|
||||
|
||||
--enable-sim-hardcoded
|
||||
|
||||
Enable support for hard coded SIM keys
|
||||
|
||||
Note: With --disable-daemon this option is ignored
|
||||
|
||||
|
||||
Netlink monitoring
|
||||
==================
|
||||
@ -274,10 +268,11 @@ Information
|
||||
===========
|
||||
|
||||
Mailing list:
|
||||
https://lists.01.org/postorius/lists/iwd.lists.01.org/
|
||||
https://lists.linux.dev/
|
||||
https://lore.kernel.org/iwd/
|
||||
|
||||
IRC:
|
||||
irc://irc.freenode.net/#iwd
|
||||
irc://irc.oftc.net/#iwd
|
||||
|
||||
Wiki:
|
||||
https://iwd.wiki.kernel.org/
|
||||
|
57
TODO
57
TODO
@ -110,7 +110,7 @@ Wireless monitor
|
||||
|
||||
- Subscribe to all nl80211 multicast groups at startup
|
||||
|
||||
It seems the nlmon packets are limited to actual subscribed mutlicast
|
||||
It seems the nlmon packets are limited to actual subscribed multicast
|
||||
groups. To get a complete picture of all the nl80211 commands and
|
||||
events, it is required that iwmon adds membership to all multicast
|
||||
groups that the nl80211 lists.
|
||||
@ -199,11 +199,6 @@ Wireless daemon
|
||||
Priority: Low
|
||||
Complexity: C4
|
||||
|
||||
- Add support for 802.11u. This is required for Passpoint 2.0 support.
|
||||
|
||||
Priority: Low
|
||||
Complexity: C8
|
||||
|
||||
- Add support for Wireless Network Management (WNM) from 802.11v. Parts of
|
||||
this are needed for Passpoint support.
|
||||
|
||||
@ -237,21 +232,9 @@ Wireless daemon
|
||||
Priority: Low
|
||||
Complexity: C4
|
||||
|
||||
- Take EAP MSK size into consideration.
|
||||
|
||||
MSK is mandated to be 64 bytes long, and depending on the AKM, different parts
|
||||
of the MSK are used to generate keys. Some EAP methods produce MSKs with less
|
||||
than 64 bytes of useable data. For example, LEAP produces only 16 bytes and
|
||||
MSCHAPv2 produces 32 bytes. If the AKM requires MSK of a certain size, and
|
||||
the EAP method does not provide enough data, then the handshake should be
|
||||
aborted.
|
||||
|
||||
Priority: Medium
|
||||
Complexity: C2
|
||||
|
||||
- Implement Enrollee Session Overlap Detection after WSC Protocol Run
|
||||
|
||||
WSC Best Practices v2.0.1, Section 3.15 describes an enhacement to detect
|
||||
WSC Best Practices v2.0.1, Section 3.15 describes an enhancement to detect
|
||||
PBC session overlaps. The Enrollee is asked to perform an extra scan without
|
||||
the PBC request in the ProbeRequest frames after EAP-WSC completes
|
||||
successfully. If another AP in PBC mode is found, then a SessionOverlap
|
||||
@ -260,14 +243,6 @@ Wireless daemon
|
||||
Priority: Low
|
||||
Complexity: C2
|
||||
|
||||
- Use NL80211_CMD_CRIT_PROTOCOL_START / CRIT_PROTOCOL_STOP
|
||||
|
||||
Research whether iwd should be making use of these commands in order to
|
||||
make EAP & 4-way handshakes, as well as DHCP exchanges more reliable.
|
||||
|
||||
Priority: Medium
|
||||
Complexity: C2
|
||||
|
||||
- DPP Support
|
||||
|
||||
Device Provisioning Protocol is a new specification from WiFi Alliance.
|
||||
@ -311,7 +286,7 @@ Wireless daemon
|
||||
- Support OCE mutually non-overlapping channels optimization.
|
||||
|
||||
OCE Section 3.10 mandates that the STA should scan channels 1, 6 and 11 in
|
||||
the 2.4Ghz band first, unless it expects to find an AP on a different
|
||||
the 2.4GHz band first, unless it expects to find an AP on a different
|
||||
channel.
|
||||
|
||||
Priority: Low
|
||||
@ -357,24 +332,18 @@ Wireless daemon
|
||||
Priority: Medium
|
||||
Complexity: C4
|
||||
|
||||
- Support Diagnostics interface
|
||||
|
||||
The diagnostic interface for a particular Device would contain information
|
||||
(and possibly operations) that would be meant for diagnostics applications
|
||||
or other applications that require access to very low level details. Such
|
||||
applications would be expected how to interpret this information
|
||||
appropriately.
|
||||
Network Configuration
|
||||
=====================
|
||||
|
||||
This interface would also be heavily utilized by the Auto-Test framework
|
||||
in order to more easily ascertain the internal state of the hardware & the
|
||||
daemon itself.
|
||||
- Support elements of RFC4436 - DNAv4
|
||||
|
||||
The list of possible information exposed via this interface includes:
|
||||
- MAC address of the currently connected AP (in a Station)
|
||||
- MAC addresses of currently connected clients (Adhoc, AP, etc)
|
||||
- packet error rates or signal strength
|
||||
- Throughput statistics
|
||||
- FTM / direction finding operations
|
||||
Assumption: netconfig is able to save lease information for networks that
|
||||
have been joined previously and does not release the lease when the network
|
||||
is left temporarily.
|
||||
|
||||
Priority: Medium
|
||||
Attempt to re-assume the lease via methods described in DNAv4 if we attempt
|
||||
to rejoin a network and the lease has not expired yet.
|
||||
|
||||
Priority: Low
|
||||
Complexity: C4
|
||||
|
30
acinclude.m4
30
acinclude.m4
@ -46,10 +46,30 @@ AC_DEFUN([AC_PROG_CC_UBSAN], [
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_PROG_CC_GCOV], [
|
||||
AC_CACHE_CHECK([whether ${CC-cc} accepts -fprofile-arcs], ac_cv_prog_cc_profile_arcs, [
|
||||
echo 'void f(){}' > conftest.c
|
||||
if test -z "`${CC-cc} -fprofile-arcs -c conftest.c 2>&1`"; then
|
||||
ac_cv_prog_cc_profile_arcs=yes
|
||||
else
|
||||
ac_cv_prog_cc_profile_arcs=no
|
||||
fi
|
||||
rm -rf conftest*
|
||||
])
|
||||
AC_CACHE_CHECK([whether ${CC-cc} accepts -ftest_coverage], ac_cv_prog_cc_test_coverage, [
|
||||
echo 'void f(){}' > conftest.c
|
||||
if test -z "`${CC-cc} -ftest-coverage -c conftest.c 2>&1`"; then
|
||||
ac_cv_prog_cc_test_coverage=yes
|
||||
else
|
||||
ac_cv_prog_cc_test_coverage=no
|
||||
fi
|
||||
rm -rf conftest*
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([COMPILER_FLAGS], [
|
||||
if (test "${CFLAGS}" = ""); then
|
||||
CFLAGS="-Wall -O2 -fsigned-char -fno-exceptions"
|
||||
CFLAGS+=" -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2"
|
||||
CFLAGS="-Wall -fsigned-char -fno-exceptions"
|
||||
fi
|
||||
if (test "$USE_MAINTAINER_MODE" = "yes"); then
|
||||
CFLAGS+=" -Werror -Wextra"
|
||||
@ -58,10 +78,14 @@ AC_DEFUN([COMPILER_FLAGS], [
|
||||
CFLAGS+=" -Wdeclaration-after-statement"
|
||||
CFLAGS+=" -Wmissing-declarations"
|
||||
CFLAGS+=" -Wredundant-decls"
|
||||
CFALGS+=" -Wvariadic-macros"
|
||||
CFLAGS+=" -Wformat -Wformat-security"
|
||||
if ( $CC -v 2>/dev/null | grep "gcc version" ); then
|
||||
CFLAGS+=" -Wcast-align"
|
||||
fi
|
||||
fi
|
||||
|
||||
if (test "$CC" = "clang"); then
|
||||
CFLAGS+=" -Wno-unknown-warning-option"
|
||||
CFLAGS+=" -Wno-unknown-pragmas"
|
||||
fi
|
||||
])
|
||||
|
BIN
autotests/misc/certs/cert-client.crt
Normal file
BIN
autotests/misc/certs/cert-client.crt
Normal file
Binary file not shown.
BIN
autotests/misc/certs/cert-client.p12
Normal file
BIN
autotests/misc/certs/cert-client.p12
Normal file
Binary file not shown.
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* TLS
|
||||
# Phase 2
|
||||
"abc@example.com" MD5 "testpasswd" [2]
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* TTLS
|
||||
# Phase 2
|
||||
"user" MSCHAPV2 "testpasswd" [2]
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* TTLS
|
||||
# Phase 2
|
||||
"abc@example.com" MD5 "testpasswd" [2]
|
@ -1 +0,0 @@
|
||||
"domain\User" MSCHAPV2 "Password"
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* PEAP
|
||||
# Phase 2
|
||||
"domain\User" MSCHAPV2 "Password" [2]
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* PEAP
|
||||
# Phase 2
|
||||
"132010000000000@example.com" SIM [2]
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* PEAP [ver=0]
|
||||
# Phase 2
|
||||
"secure@identity.com" MSCHAPV2 "testpasswd" [2]
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* PEAP [ver=0]
|
||||
# Phase 2
|
||||
"secure@identity.com" MD5 "testpasswd" [2]
|
@ -1,4 +0,0 @@
|
||||
# Phase 1 users
|
||||
* PEAP [ver=1]
|
||||
# Phase 2
|
||||
"secure@identity.com" MD5 "testpasswd" [2]
|
27
autotests/misc/secrets/eap-user.text
Normal file
27
autotests/misc/secrets/eap-user.text
Normal file
@ -0,0 +1,27 @@
|
||||
"112345678@phonesim.org" SIM
|
||||
"012345678@phonesim.org" AKA
|
||||
"612345678@phonesim.org" AKA'
|
||||
"mschapv2@example.com" MSCHAPV2 "Password"
|
||||
"pwd@example.com" PWD "Password"
|
||||
|
||||
# Phase 1 users
|
||||
"tls@example.com" TLS
|
||||
"ttls@example.com" TTLS
|
||||
"peap@example.com" PEAP
|
||||
"peapv0@example.com" PEAP [ver=0]
|
||||
"peapv1@example.com" PEAP [ver=1]
|
||||
|
||||
# Phase 2
|
||||
"md5-phase2@example.com" MD5 "Password" [2]
|
||||
"gtc-phase2@example.com" GTC "Password" [2]
|
||||
"mschapv2-phase2@example.com" MSCHAPV2 "Password" [2]
|
||||
"ttls-chap-phase2@example.com" TTLS-CHAP "Password" [2]
|
||||
"ttls-mschap-phase2@example.com" TTLS-MSCHAP "Password" [2]
|
||||
"ttls-mschapv2-phase2@example.com" TTLS-MSCHAPV2 "Password" [2]
|
||||
"ttls-pap-phase2@example.com" TTLS-PAP "Password" [2]
|
||||
"112345678@phonesim.org" SIM [2]
|
||||
|
||||
# TODO: Hostapd is broken with phase1 lookups for reauthentication.
|
||||
# Allowing a wildcard phase1 for PEAP/TTLS is a stop gap until
|
||||
# hostapd is actually fixed.
|
||||
* PEAP,TTLS
|
3
autotests/testAP-no-support/TestAP2.ap
Normal file
3
autotests/testAP-no-support/TestAP2.ap
Normal file
@ -0,0 +1,3 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
PairwiseCiphers=CCMP
|
66
autotests/testAP-no-support/connection_test.py
Normal file
66
autotests/testAP-no-support/connection_test.py
Normal file
@ -0,0 +1,66 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD, NetworkType, PSKAgent
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_no_ap_mode(self):
|
||||
wd = IWD(True)
|
||||
|
||||
dev = wd.list_devices(1)[0]
|
||||
|
||||
with self.assertRaises(iwd.NotSupportedEx):
|
||||
dev.start_ap('TestAP2', 'Password2')
|
||||
|
||||
def test_only_tkip_support(self):
|
||||
wd = IWD(True)
|
||||
|
||||
devices = wd.list_devices(2)
|
||||
|
||||
dev_sta = devices[0]
|
||||
dev_ap = devices[1]
|
||||
|
||||
dev_ap.start_ap('TestAP2', 'Password2')
|
||||
|
||||
self.assertTrue(dev_ap.group_cipher == 'TKIP')
|
||||
self.assertIn('TKIP', dev_ap.pairwise_ciphers)
|
||||
|
||||
ordered_network = dev_sta.get_ordered_network('TestAP2')
|
||||
|
||||
if ordered_network.type != NetworkType.psk:
|
||||
raise Exception("Network type mismatch")
|
||||
|
||||
psk_agent = PSKAgent('Password2')
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev_sta, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_no_ccmp_support(self):
|
||||
wd = IWD(True)
|
||||
|
||||
dev = wd.list_devices(2)[1]
|
||||
|
||||
# Should fail to start since the radio doesn't support CCMP but the
|
||||
# profile only lists CCMP as allowed.
|
||||
with self.assertRaises(iwd.NotSupportedEx):
|
||||
dev.start_ap('TestAP2')
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_ap('TestAP2.ap')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,6 +1,9 @@
|
||||
[SETUP]
|
||||
num_radios=1
|
||||
radio_confs=rad0
|
||||
num_radios=2
|
||||
start_iwd=0
|
||||
|
||||
[rad0]
|
||||
iftype_disable=ap
|
||||
|
||||
[rad1]
|
||||
cipher_disable=ccmp,bip_cmac,gcmp,gcmp_256,ccmp_256,bip_gmac,bip_gmac_256,bip_cmac_256
|
||||
|
2
autotests/testAP/TestAP2.ap
Normal file
2
autotests/testAP/TestAP2.ap
Normal file
@ -0,0 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=Password2
|
77
autotests/testAP/connection_test.py
Normal file
77
autotests/testAP/connection_test.py
Normal file
@ -0,0 +1,77 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from iwd import IWD
|
||||
from config import ctx
|
||||
from validation import validate, client_connect
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_connection_success(self):
|
||||
IWD.copy_to_storage('TestAP1.psk')
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
client_connect(wd, dev1, 'TestAP1')
|
||||
|
||||
dev1.start_ap('TestAP2', 'Password2')
|
||||
|
||||
validate(wd, dev2, dev1, 'TestAP2', 'Password2')
|
||||
|
||||
# Finally test dev1 can go to client mode and connect again
|
||||
client_connect(wd, dev1, 'TestAP1')
|
||||
|
||||
def test_client_start_ap(self):
|
||||
IWD.copy_to_storage('TestAP1.psk')
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
ctx.start_process(['iwctl', 'device', dev1.name, 'set-property', 'Mode', 'ap'], check=True)
|
||||
ctx.start_process(['iwctl', 'ap', dev1.name, 'start', 'TestAP2', 'Password2'], check=True)
|
||||
|
||||
iwctl = ctx.start_process(['iwctl', 'ap', 'list'], check=True)
|
||||
|
||||
self.assertIn(dev1.name, iwctl.out)
|
||||
|
||||
iwctl = ctx.start_process(['iwctl', 'ap', dev1.name, 'show'], check=True)
|
||||
|
||||
self.assertIn('TestAP2', iwctl.out)
|
||||
|
||||
validate(wd, dev2, dev1, 'TestAP2', 'Password2')
|
||||
|
||||
def test_valid_ciphers(self):
|
||||
ciphers = ['TKIP', 'CCMP-128', 'GCMP-128', 'CCMP-256', 'GCMP-256']
|
||||
|
||||
for group in ciphers:
|
||||
for pairwise in ciphers:
|
||||
IWD.copy_to_ap('TestAP2.ap')
|
||||
os.system('echo "PairwiseCiphers=%s" >> /tmp/iwd/ap/TestAP2.ap' % pairwise)
|
||||
os.system('echo "GroupCipher=%s" >> /tmp/iwd/ap/TestAP2.ap' % group)
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
dev1.start_ap('TestAP2')
|
||||
|
||||
self.assertTrue(dev1.group_cipher == group)
|
||||
self.assertIn(pairwise, dev1.pairwise_ciphers)
|
||||
|
||||
try:
|
||||
validate(wd, dev2, dev1, 'TestAP2', 'Password2', ip_checks=False)
|
||||
except:
|
||||
raise Exception("Failed with pairwise=%s group=%s" % (pairwise, group))
|
||||
finally:
|
||||
IWD.clear_storage()
|
||||
del wd
|
||||
|
||||
def tearDown(self):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
10
autotests/testAP/dhcp/APConfig.ap
Normal file
10
autotests/testAP/dhcp/APConfig.ap
Normal file
@ -0,0 +1,10 @@
|
||||
[Security]
|
||||
Passphrase=password123
|
||||
|
||||
[IPv4]
|
||||
Address=192.168.1.1
|
||||
Gateway=192.168.1.1
|
||||
Netmask=255.255.255.0
|
||||
DNSList=192.168.1.1,192.168.1.2
|
||||
LeaseTime=10
|
||||
IPRange=192.168.1.3,192.168.1.100
|
8
autotests/testAP/dhcp/main.conf
Normal file
8
autotests/testAP/dhcp/main.conf
Normal file
@ -0,0 +1,8 @@
|
||||
[Scan]
|
||||
DisableMacAddressRandomization=true
|
||||
|
||||
[General]
|
||||
EnableNetworkConfiguration=true
|
||||
|
||||
[IPv4]
|
||||
APAddressPool=192.168.80.0/27
|
39
autotests/testAP/dhcp_config_test.py
Normal file
39
autotests/testAP/dhcp_config_test.py
Normal file
@ -0,0 +1,39 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
|
||||
from iwd import IWD
|
||||
from config import ctx
|
||||
from validation import validate
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_connection_success(self):
|
||||
# Using main.conf containing APRanges. The APConfig SSID should override
|
||||
# this range.
|
||||
wd = IWD(True, '/tmp/dhcp')
|
||||
|
||||
ns0 = ctx.get_namespace('ns0')
|
||||
|
||||
wd_ns0 = IWD(True, '/tmp/dhcp', namespace=ns0)
|
||||
|
||||
dev1 = wd_ns0.list_devices(1)[0]
|
||||
dev2, dev3, dev4, dev5 = wd.list_devices(4)
|
||||
dev3.disconnect()
|
||||
dev4.disconnect()
|
||||
dev5.disconnect()
|
||||
|
||||
dev1.start_ap('APConfig')
|
||||
|
||||
validate(wd, dev2, dev1, 'APConfig', 'password123',
|
||||
sta_ip_info=('192.168.1.3', ctx), ap_ip_info=('192.168.1.1', ns0))
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_ap('dhcp/APConfig.ap')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
70
autotests/testAP/dhcp_test.py
Normal file
70
autotests/testAP/dhcp_test.py
Normal file
@ -0,0 +1,70 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from config import ctx
|
||||
import testutil
|
||||
|
||||
from validation import validate
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_connection_success(self):
|
||||
wd = IWD(True, '/tmp/dhcp')
|
||||
|
||||
# dev1, dev3, and dev4 are all AP's
|
||||
# The configured IP range only supports 2 subnets, so dev4 should fail
|
||||
# to start AP.
|
||||
dev1, dev2, dev3, dev4 = wd.list_devices(4)
|
||||
|
||||
dev1.start_ap('TestAP2', "Password2")
|
||||
dev3.start_ap('TestAP3', 'Password3')
|
||||
|
||||
with self.assertRaises(iwd.AlreadyExistsEx):
|
||||
dev4.start_ap('TestAP4', 'Password4')
|
||||
|
||||
validate(wd, dev2, dev1, 'TestAP2', 'Password2', ip_checks=False)
|
||||
|
||||
network = dev2.get_ordered_network('TestAP2', full_scan=True)
|
||||
|
||||
try:
|
||||
testutil.test_ip_address_match(dev1.name, "192.168.80.1")
|
||||
testutil.test_ip_address_match(dev2.name, "192.168.80.2")
|
||||
ip = "192.168.80.1"
|
||||
except:
|
||||
testutil.test_ip_address_match(dev1.name, "192.168.80.17")
|
||||
testutil.test_ip_address_match(dev2.name, "192.168.80.18")
|
||||
ip = "192.168.80.17"
|
||||
|
||||
dev2.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(network.network_object, condition)
|
||||
|
||||
# This should release the IP */
|
||||
dev1.stop_ap()
|
||||
|
||||
# This should now succeed and the IP should match the old IP dev1
|
||||
# got initially.
|
||||
dev4.start_ap('TestAP4', 'Password4')
|
||||
|
||||
testutil.test_ip_address_match(dev4.name, ip)
|
||||
|
||||
dev1.stop_ap()
|
||||
dev3.stop_ap()
|
||||
dev4.stop_ap()
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -8,12 +8,13 @@ import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
import hostapd
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def client_connect(self, wd, dev):
|
||||
hostapd = HostapdCLI(config='psk-ccmp.conf')
|
||||
|
||||
ordered_network = dev.get_ordered_network('TestAP1', True)
|
||||
|
||||
@ -24,14 +25,13 @@ class Test(unittest.TestCase):
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
testutil.test_iface_operstate(dev.name)
|
||||
testutil.test_ifaces_connected(list(hostapd.hostapd_map.keys())[0],
|
||||
dev.name)
|
||||
testutil.test_ifaces_connected(hostapd.ifname, dev.name)
|
||||
|
||||
dev.disconnect()
|
||||
|
||||
@ -39,7 +39,7 @@ class Test(unittest.TestCase):
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
def test_connection_failure(self):
|
||||
wd = IWD()
|
||||
wd = IWD(True)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
@ -48,16 +48,10 @@ class Test(unittest.TestCase):
|
||||
dev1.start_ap('TestAP2', 'Password2')
|
||||
|
||||
try:
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
dev2.scan()
|
||||
condition = 'obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
networks = {}
|
||||
networks['TestAP1'] = dev2.get_ordered_network('TestAP1', full_scan=True)
|
||||
networks['TestAP2'] = dev2.get_ordered_network('TestAP2', full_scan=True)
|
||||
|
||||
ordered_networks = dev2.get_ordered_networks()
|
||||
networks = { n.name: n for n in ordered_networks }
|
||||
self.assertEqual(networks['TestAP1'].type, NetworkType.psk)
|
||||
self.assertEqual(networks['TestAP2'].type, NetworkType.psk)
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
max_test_exec_interval_sec=40
|
||||
tmpfs_extra_stuff=main.conf
|
||||
num_radios=6
|
||||
start_iwd=0
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=psk-ccmp.conf
|
||||
|
||||
[NameSpaces]
|
||||
ns0=rad5
|
||||
|
20
autotests/testAP/scan_test.py
Normal file
20
autotests/testAP/scan_test.py
Normal file
@ -0,0 +1,20 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
|
||||
from iwd import IWD
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_ap_scan(self):
|
||||
wd = IWD(True)
|
||||
|
||||
dev = wd.list_devices(1)[0]
|
||||
|
||||
dev.start_ap('TestAP2', 'Password2')
|
||||
|
||||
dev.scan()
|
||||
|
||||
networks = dev.get_ordered_networks()
|
||||
|
||||
self.assertTrue(len(networks) == 1)
|
||||
self.assertTrue(networks[0]['Name'] == 'TestAP1')
|
@ -1,105 +0,0 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
import hostapd
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def client_connect(self, wd, dev):
|
||||
|
||||
ordered_network = dev.get_ordered_network('TestAP1', True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
psk_agent = PSKAgent('Password1')
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
testutil.test_iface_operstate(dev.name)
|
||||
testutil.test_ifaces_connected(list(hostapd.hostapd_map.keys())[0],
|
||||
dev.name)
|
||||
|
||||
dev.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
def test_connection_success(self):
|
||||
wd = IWD()
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
self.client_connect(wd, dev1)
|
||||
|
||||
dev1.start_ap('TestAP2', 'Password2')
|
||||
|
||||
try:
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
dev2.scan()
|
||||
condition = 'obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
ordered_networks = dev2.get_ordered_networks()
|
||||
networks = { n.name: n for n in ordered_networks }
|
||||
self.assertEqual(networks['TestAP1'].type, NetworkType.psk)
|
||||
self.assertEqual(networks['TestAP2'].type, NetworkType.psk)
|
||||
|
||||
psk_agent = PSKAgent('Password2')
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
try:
|
||||
dev2.disconnect()
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
except:
|
||||
pass
|
||||
|
||||
networks['TestAP2'].network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(networks['TestAP2'].network_object,
|
||||
condition)
|
||||
|
||||
testutil.test_iface_operstate(dev2.name)
|
||||
testutil.test_ifaces_connected(dev1.name, dev2.name)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
dev2.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(networks['TestAP2'].network_object,
|
||||
condition)
|
||||
finally:
|
||||
dev1.stop_ap()
|
||||
|
||||
# Finally test dev1 can go to client mode and connect again
|
||||
self.client_connect(wd, dev1)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('TestAP1.psk')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
71
autotests/testAP/validation.py
Normal file
71
autotests/testAP/validation.py
Normal file
@ -0,0 +1,71 @@
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
def validate(wd, sta_dev, ap_dev, ssid, passphrase,
|
||||
sta_ip_info=None, ap_ip_info=None, ip_checks=True):
|
||||
try:
|
||||
network = sta_dev.get_ordered_network(ssid, full_scan=True)
|
||||
|
||||
if network.type != NetworkType.psk:
|
||||
raise Exception("Network type mismatch")
|
||||
|
||||
psk_agent = PSKAgent(passphrase)
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(sta_dev, condition)
|
||||
|
||||
testutil.test_iface_operstate(sta_dev.name)
|
||||
|
||||
# This implies separate namespaces so the iface names won't exist
|
||||
if not sta_ip_info or not ap_ip_info:
|
||||
testutil.test_ifaces_connected(ap_dev.name, sta_dev.name, group=False)
|
||||
|
||||
if not ip_checks:
|
||||
return
|
||||
|
||||
if sta_ip_info:
|
||||
testutil.test_ip_address_match(sta_dev.name, sta_ip_info[0])
|
||||
|
||||
if sta_ip_info and ap_ip_info:
|
||||
testutil.test_ip_connected(sta_ip_info, ap_ip_info)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
sta_dev.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(network.network_object, condition)
|
||||
finally:
|
||||
if ip_checks:
|
||||
ap_dev.stop_ap()
|
||||
|
||||
def client_connect(wd, dev, ssid):
|
||||
hostapd = HostapdCLI(config='psk-ccmp.conf')
|
||||
|
||||
ordered_network = dev.get_ordered_network(ssid)
|
||||
|
||||
if ordered_network.type != NetworkType.psk:
|
||||
raise Exception("Network type mismatch")
|
||||
|
||||
psk_agent = PSKAgent('Password1')
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
testutil.test_iface_operstate(dev.name)
|
||||
testutil.test_ifaces_connected(hostapd.ifname, dev.name)
|
||||
|
||||
dev.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
2
autotests/testAPRoam/TestAPRoam.psk
Normal file
2
autotests/testAPRoam/TestAPRoam.psk
Normal file
@ -0,0 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
@ -6,79 +6,75 @@ import sys
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hostapd import hostapd_map
|
||||
|
||||
from hwsim import Hwsim
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
hwsim = Hwsim()
|
||||
|
||||
bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
bss_radio = [ hwsim.get_radio('rad0'),
|
||||
hwsim.get_radio('rad1'),
|
||||
hwsim.get_radio('rad2') ]
|
||||
|
||||
wd = IWD()
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network('TestAPRoam')
|
||||
def initial_connection(self):
|
||||
ordered_network = self.device.get_ordered_network('TestAPRoam')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
self.device.connect_bssid(self.bss_hostapd[0].bssid)
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
self.assertTrue(bss_hostapd[0].list_sta())
|
||||
self.assertFalse(bss_hostapd[1].list_sta())
|
||||
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED')
|
||||
|
||||
bss_hostapd[0].send_bss_transition(device.address,
|
||||
[(bss_radio[1].addresses[0], '8f0000005102060603000000'),
|
||||
(bss_radio[2].addresses[0], '8f0000005103060603000000')])
|
||||
self.assertFalse(self.bss_hostapd[1].list_sta())
|
||||
|
||||
condition = 'obj.state == DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition, 15)
|
||||
def validate_roam(self, from_bss, to_bss, expect_roam=True):
|
||||
from_bss.send_bss_transition(self.device.address,
|
||||
self.neighbor_list,
|
||||
disassoc_imminent=expect_roam)
|
||||
|
||||
condition = 'obj.state != DeviceState.roaming'
|
||||
wd.wait_for_object_condition(device, condition, 5)
|
||||
if expect_roam:
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
self.assertEqual(device.state, iwd.DeviceState.connected)
|
||||
self.assertTrue(bss_hostapd[1].list_sta())
|
||||
device.disconnect()
|
||||
to_bss.wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
else:
|
||||
self.device.wait_for_event("no-roam-candidates")
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
def test_disassoc_imminent(self):
|
||||
self.initial_connection()
|
||||
self.validate_roam(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
def test_no_candidates(self):
|
||||
self.initial_connection()
|
||||
# We now have BSS0 roam blacklisted
|
||||
self.validate_roam(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
# Try and trigger another roam back, which shouldn't happen since now
|
||||
# both BSS's are roam blacklisted
|
||||
self.validate_roam(self.bss_hostapd[1], self.bss_hostapd[0], expect_roam=False)
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
devices = self.wd.list_devices(1)
|
||||
self.device = devices[0]
|
||||
|
||||
def tearDown(self):
|
||||
self.wd = None
|
||||
self.device = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
IWD.copy_to_storage('TestAPRoam.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
cls.neighbor_list = [
|
||||
(cls.bss_hostapd[0].bssid, "8f0000005101060603000000"),
|
||||
(cls.bss_hostapd[1].bssid, "8f0000005102060603000000"),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -1,6 +1,7 @@
|
||||
[SETUP]
|
||||
num_radios=4
|
||||
needs_hwsim=1
|
||||
hwsim_medium=true
|
||||
start_iwd=false
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssid1.conf
|
||||
|
6
autotests/testAPRoam/main.conf.roaming
Normal file
6
autotests/testAPRoam/main.conf.roaming
Normal file
@ -0,0 +1,6 @@
|
||||
[General]
|
||||
RoamThreshold=-72
|
||||
CriticalRoamThreshold=-72
|
||||
|
||||
[Blacklist]
|
||||
InitialAccessPointBusyTimeout=20
|
183
autotests/testAPRoam/roam_blacklist_test.py
Normal file
183
autotests/testAPRoam/roam_blacklist_test.py
Normal file
@ -0,0 +1,183 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD, IWD_CONFIG_DIR
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def validate_connected(self, hostapd):
|
||||
ordered_network = self.device.get_ordered_network('TestAPRoam')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
self.device.connect_bssid(hostapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
hostapd.wait_for_event('AP-STA-CONNECTED')
|
||||
|
||||
def validate_ap_roamed(self, from_hostapd, to_hostapd):
|
||||
from_hostapd.send_bss_transition(
|
||||
self.device.address, self.neighbor_list, disassoc_imminent=True
|
||||
)
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
to_hostapd.wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
|
||||
self.device.wait_for_event("ap-roam-blacklist-added")
|
||||
|
||||
def test_roam_to_optimal_candidates(self):
|
||||
# In this test IWD will naturally transition down the list after each
|
||||
# BSS gets roam blacklisted. All BSS's are above the RSSI thresholds.
|
||||
self.rule_ssid1.signal = -5000
|
||||
self.rule_ssid2.signal = -6500
|
||||
self.rule_ssid3.signal = -6900
|
||||
|
||||
# Connect to BSS0
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
# AP directed roam to BSS1
|
||||
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
# AP directed roam to BSS2
|
||||
self.validate_ap_roamed(self.bss_hostapd[1], self.bss_hostapd[2])
|
||||
|
||||
def test_avoiding_under_threshold_bss(self):
|
||||
# In this test IWD will blacklist BSS0, then roam the BSS1. BSS1 will
|
||||
# then tell IWD to roam, but it should go back to BSS0 since the only
|
||||
# non-blacklisted BSS is under the roam threshold.
|
||||
self.rule_ssid1.signal = -5000
|
||||
self.rule_ssid2.signal = -6500
|
||||
self.rule_ssid3.signal = -7300
|
||||
|
||||
# Connect to BSS0
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
# AP directed roam to BSS1
|
||||
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
# AP directed roam, but IWD should choose BSS0 since BSS2 is -73dB
|
||||
self.validate_ap_roamed(self.bss_hostapd[1], self.bss_hostapd[0])
|
||||
|
||||
def test_connect_to_roam_blacklisted_bss(self):
|
||||
# In this test a BSS will be roam blacklisted, but all other options are
|
||||
# below the RSSI threshold so IWD should roam back to the blacklisted
|
||||
# BSS.
|
||||
self.rule_ssid1.signal = -5000
|
||||
self.rule_ssid2.signal = -8000
|
||||
self.rule_ssid3.signal = -8500
|
||||
|
||||
# Connect to BSS0
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
# AP directed roam, should connect to BSS1 as its the next best
|
||||
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
|
||||
|
||||
# Connected to BSS1, but the signal is bad, so IWD should try to roam
|
||||
# again. BSS0 is still blacklisted, but its the only reasonable option
|
||||
# since both BSS1 and BSS2 are below the set RSSI threshold (-72dB)
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
# IWD should have connected to BSS0, even though its roam blacklisted
|
||||
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
|
||||
def test_blacklist_during_roam_scan(self):
|
||||
# Tests that an AP roam request mid-roam results in the AP still being
|
||||
# blacklisted even though the request itself doesn't directly trigger
|
||||
# a roam.
|
||||
self.rule_ssid1.signal = -7300
|
||||
self.rule_ssid2.signal = -7500
|
||||
self.rule_ssid3.signal = -8500
|
||||
|
||||
# Connect to BSS0 under the roam threshold so IWD will immediately try
|
||||
# roaming elsewhere
|
||||
self.validate_connected(self.bss_hostapd[0])
|
||||
|
||||
self.device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
self.bss_hostapd[0].send_bss_transition(
|
||||
self.device.address, self.neighbor_list, disassoc_imminent=True
|
||||
)
|
||||
self.device.wait_for_event("ap-roam-blacklist-added")
|
||||
|
||||
# BSS0 should have gotten blacklisted even though IWD was mid-roam,
|
||||
# causing IWD to choose BSS1 when it gets is results.
|
||||
|
||||
from_condition = 'obj.state == DeviceState.roaming'
|
||||
to_condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
|
||||
|
||||
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
devices = self.wd.list_devices(1)
|
||||
self.device = devices[0]
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.wd = None
|
||||
self.device = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage("main.conf.roaming", IWD_CONFIG_DIR, "main.conf")
|
||||
IWD.copy_to_storage('TestAPRoam.psk')
|
||||
hwsim = Hwsim()
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
rad2 = hwsim.get_radio('rad2')
|
||||
|
||||
cls.neighbor_list = [
|
||||
(cls.bss_hostapd[0].bssid, "8f0000005101060603000000"),
|
||||
(cls.bss_hostapd[1].bssid, "8f0000005102060603000000"),
|
||||
(cls.bss_hostapd[2].bssid, "8f0000005103060603000000"),
|
||||
]
|
||||
|
||||
|
||||
cls.rule_ssid1 = hwsim.rules.create()
|
||||
cls.rule_ssid1.source = rad0.addresses[0]
|
||||
cls.rule_ssid1.bidirectional = True
|
||||
cls.rule_ssid1.enabled = True
|
||||
|
||||
cls.rule_ssid2 = hwsim.rules.create()
|
||||
cls.rule_ssid2.source = rad1.addresses[0]
|
||||
cls.rule_ssid2.bidirectional = True
|
||||
cls.rule_ssid2.enabled = True
|
||||
|
||||
cls.rule_ssid3 = hwsim.rules.create()
|
||||
cls.rule_ssid3.source = rad2.addresses[0]
|
||||
cls.rule_ssid3.bidirectional = True
|
||||
cls.rule_ssid3.enabled = True
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -2,26 +2,43 @@
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import AdHocDevice
|
||||
from config import ctx
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def validate_connection(self, wd):
|
||||
def validate_connection(self, wd, client=False):
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
self.assertIsNotNone(dev1)
|
||||
self.assertIsNotNone(dev2)
|
||||
|
||||
dev1.start_adhoc("AdHocNetwork", "secret123")
|
||||
dev2.start_adhoc("AdHocNetwork", "secret123")
|
||||
adhoc1 = dev1.start_adhoc("AdHocNetwork", "secret123")
|
||||
|
||||
dev1.adhoc_wait_for_connected(dev2.address)
|
||||
dev2.adhoc_wait_for_connected(dev1.address)
|
||||
condition = 'obj.started == True'
|
||||
wd.wait_for_object_condition(adhoc1, condition)
|
||||
|
||||
if not client:
|
||||
adhoc2 = dev2.start_adhoc("AdHocNetwork", "secret123")
|
||||
else:
|
||||
ctx.start_process(['iwctl', 'device', dev2.name, 'set-property',
|
||||
'Mode', 'ad-hoc'], check=True)
|
||||
ctx.start_process(['iwctl', 'ad-hoc', dev2.name, 'start',
|
||||
'AdHocNetwork', 'secret123'], check=True)
|
||||
adhoc2 = AdHocDevice(dev2.device_path)
|
||||
|
||||
condition = 'obj.started == True'
|
||||
wd.wait_for_object_condition(adhoc1, condition)
|
||||
|
||||
condition = '"%s" in obj.connected_peers' % dev2.address
|
||||
wd.wait_for_object_condition(adhoc1, condition)
|
||||
|
||||
condition = '"%s" in obj.connected_peers' % dev1.address
|
||||
wd.wait_for_object_condition(adhoc2, condition)
|
||||
|
||||
testutil.test_iface_operstate(dev1.name)
|
||||
testutil.test_iface_operstate(dev2.name)
|
||||
@ -32,6 +49,10 @@ class Test(unittest.TestCase):
|
||||
|
||||
self.validate_connection(wd)
|
||||
|
||||
def test_client_adhoc(self):
|
||||
wd = IWD(True)
|
||||
self.validate_connection(wd, client=True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
@ -1,4 +1,3 @@
|
||||
[SETUP]
|
||||
num_radios=2
|
||||
max_test_exec_interval_sec=35
|
||||
start_iwd=0
|
||||
|
@ -18,12 +18,21 @@ class Test(unittest.TestCase):
|
||||
self.assertIsNotNone(dev1)
|
||||
self.assertIsNotNone(dev2)
|
||||
|
||||
dev1.start_adhoc("AdHocNetwork")
|
||||
sleep(1)
|
||||
dev2.start_adhoc("AdHocNetwork")
|
||||
adhoc1 = dev1.start_adhoc("AdHocNetwork")
|
||||
|
||||
dev1.adhoc_wait_for_connected(dev2.address)
|
||||
dev2.adhoc_wait_for_connected(dev1.address)
|
||||
condition = 'obj.started == True'
|
||||
wd.wait_for_object_condition(adhoc1, condition)
|
||||
|
||||
adhoc2 = dev2.start_adhoc("AdHocNetwork")
|
||||
|
||||
condition = 'obj.started == True'
|
||||
wd.wait_for_object_condition(adhoc1, condition)
|
||||
|
||||
condition = '"%s" in obj.connected_peers' % dev2.address
|
||||
wd.wait_for_object_condition(adhoc1, condition)
|
||||
|
||||
condition = '"%s" in obj.connected_peers' % dev1.address
|
||||
wd.wait_for_object_condition(adhoc2, condition)
|
||||
|
||||
testutil.test_iface_operstate(dev1.name)
|
||||
testutil.test_iface_operstate(dev2.name)
|
||||
|
@ -24,8 +24,8 @@ class Test(unittest.TestCase):
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected()
|
||||
@ -45,16 +45,8 @@ class Test(unittest.TestCase):
|
||||
|
||||
perm_addr = device.address
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# 1. Test per-network deterministic MAC generation
|
||||
os.system('cat pernetwork.psk > /var/lib/iwd/ssidCCMP.psk')
|
||||
IWD.copy_to_storage('pernetwork.psk', name='ssidCCMP.psk')
|
||||
new_addr = self.try_connection(wd)
|
||||
self.assertNotEqual(perm_addr, new_addr)
|
||||
# try again to ensure the generation was deterministic
|
||||
@ -62,7 +54,7 @@ class Test(unittest.TestCase):
|
||||
self.assertEqual(new_addr, new_addr2)
|
||||
|
||||
# 2. Test FullAddressRandomization
|
||||
os.system('cat full_random.psk > /var/lib/iwd/ssidCCMP.psk')
|
||||
IWD.copy_to_storage('full_random.psk', name='ssidCCMP.psk')
|
||||
new_addr = self.try_connection(wd)
|
||||
self.assertNotEqual(perm_addr, new_addr)
|
||||
# try again to make sure the generation was random
|
||||
@ -70,7 +62,7 @@ class Test(unittest.TestCase):
|
||||
self.assertNotEqual(new_addr, new_addr2)
|
||||
|
||||
# 3. Test AddressOverride
|
||||
os.system('cat override.psk > /var/lib/iwd/ssidCCMP.psk')
|
||||
IWD.copy_to_storage('override.psk', name='ssidCCMP.psk')
|
||||
new_addr = self.try_connection(wd)
|
||||
self.assertEqual(new_addr, 'e6:f6:38:a9:02:02')
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=2
|
||||
tmpfs_extra_stuff=main.conf
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidCCMP.conf
|
||||
|
2
autotests/testAffinity/TestFT.psk
Normal file
2
autotests/testAffinity/TestFT.psk
Normal file
@ -0,0 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=EasilyGuessedPassword
|
@ -13,9 +13,7 @@ wpa=2
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
ieee80211w=0
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
@ -35,7 +33,9 @@ pmk_r1_push=0
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
ft_over_ds=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -13,9 +13,7 @@ wpa=2
|
||||
wpa_key_mgmt=FT-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=EasilyGuessedPassword
|
||||
wpa_ptk_rekey=30
|
||||
wpa_group_rekey=80
|
||||
ieee80211w=1
|
||||
ieee80211w=0
|
||||
rsn_preauth=1
|
||||
rsn_preauth_interfaces=lo
|
||||
disable_pmksa_caching=0
|
||||
@ -35,7 +33,9 @@ pmk_r1_push=0
|
||||
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
|
||||
# CONFIG_BRIDGE enabled in the kernel.
|
||||
ft_psk_generate_local=1
|
||||
ft_over_ds=1
|
||||
rkh_pull_timeout=50
|
||||
ft_over_ds=0
|
||||
ap_table_expiration_time=36000
|
||||
ap_table_max_size=10
|
||||
rrm_neighbor_report=1
|
||||
ocv=1
|
@ -1,8 +1,7 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
max_test_exec_interval_sec=45
|
||||
tmpfs_extra_stuff=main.conf
|
||||
needs_hwsim=1
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ft-psk-ccmp-1.conf
|
5
autotests/testAffinity/main.conf
Normal file
5
autotests/testAffinity/main.conf
Normal file
@ -0,0 +1,5 @@
|
||||
[Scan]
|
||||
DisableMacAddressRandomization=true
|
||||
|
||||
[General]
|
||||
RoamRetryInterval=1
|
216
autotests/testAffinity/test_set_affinity.py
Normal file
216
autotests/testAffinity/test_set_affinity.py
Normal file
@ -0,0 +1,216 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
import dbus
|
||||
|
||||
sys.path.append('../util')
|
||||
from config import ctx
|
||||
import iwd
|
||||
from iwd import IWD, IWDDBusAbstract
|
||||
from iwd import NetworkType
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
|
||||
#
|
||||
# Separate client used to test DBus disconnects so we don't bring down the
|
||||
# entire IWD python library
|
||||
#
|
||||
class AffinityClient(IWDDBusAbstract):
|
||||
def __init__(self, device_path):
|
||||
self._bus = dbus.bus.BusConnection(address_or_type=ctx.dbus_address)
|
||||
self._station_prop_if = dbus.Interface(
|
||||
self._bus.get_object(iwd.IWD_SERVICE, device_path),
|
||||
iwd.DBUS_PROPERTIES)
|
||||
|
||||
def set(self, values):
|
||||
self._station_prop_if.Set(iwd.IWD_STATION_INTERFACE, 'Affinities', dbus.Array([dbus.ObjectPath(v) for v in values], signature="o"))
|
||||
|
||||
def close(self):
|
||||
self._bus.close()
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def connect(self, device, hapd):
|
||||
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
device.connect_bssid(hapd.bssid)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def test_set_affinity(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
print(device.connected_bss)
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# IWD should not attempt to roam
|
||||
with self.assertRaises(TimeoutError):
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
device.affinities = []
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_roam_below_critical(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# IWD should not attempt to roam
|
||||
with self.assertRaises(TimeoutError):
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
# Lower signal past critical level
|
||||
self.bss0_rule.signal = -9000
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_error_conditions(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
# Calling set while disconnected should fail
|
||||
with self.assertRaises(iwd.NotConnectedEx):
|
||||
device.affinities = ["/some/path"]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# An invalid path should fail
|
||||
with self.assertRaises(iwd.InvalidArgumentsEx):
|
||||
device.affinities = [device.connected_bss, "/an/invalid/path"]
|
||||
|
||||
def test_affinity_client_disconnect(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
client = AffinityClient(device.device_path)
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
client.set([device.connected_bss])
|
||||
|
||||
with self.assertRaises(TimeoutError):
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
client._bus.close()
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_affinity_client_reconnect_during_roam(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
client = AffinityClient(device.device_path)
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
client.set([device.connected_bss])
|
||||
|
||||
# Lower signal past critical level
|
||||
self.bss0_rule.signal = -9000
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
client.close()
|
||||
del client
|
||||
client = AffinityClient(device.device_path)
|
||||
# setting here should get cleared after connecting
|
||||
client.set([device.connected_bss])
|
||||
|
||||
device.wait_for_event("ft-authenticating")
|
||||
device.wait_for_event("associating")
|
||||
device.wait_for_event("connected")
|
||||
|
||||
# Affinity should be reset, and IWD should be trying to roam
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
def test_cleanup_with_connected_client(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
client = AffinityClient(device.device_path)
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
client.set([device.connected_bss])
|
||||
self.wd.stop()
|
||||
|
||||
def test_affinity_removed_after_roam(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
self.connect(device, self.bss_hostapd[0])
|
||||
|
||||
device.affinities = [device.connected_bss]
|
||||
|
||||
# Lower signal past critical level
|
||||
self.bss0_rule.signal = -9000
|
||||
|
||||
device.wait_for_event("roam-scan-triggered")
|
||||
|
||||
device.wait_for_event("ft-authenticating")
|
||||
device.wait_for_event("associating")
|
||||
device.wait_for_event("connected")
|
||||
|
||||
self.assertEqual(device.affinities, [])
|
||||
|
||||
def tearDown(self):
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
|
||||
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
|
||||
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
|
||||
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
def setUp(self):
|
||||
self.bss0_rule.signal = -8000
|
||||
self.bss1_rule.signal = -8000
|
||||
|
||||
self.wd = IWD(True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('TestFT.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
|
||||
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
|
||||
cls.bss0_rule = hwsim.rules.create()
|
||||
cls.bss0_rule.source = rad0.addresses[0]
|
||||
cls.bss0_rule.bidirectional = True
|
||||
cls.bss0_rule.signal = -8000
|
||||
cls.bss0_rule.enabled = True
|
||||
|
||||
cls.bss1_rule = hwsim.rules.create()
|
||||
cls.bss1_rule.source = rad1.addresses[0]
|
||||
cls.bss1_rule.bidirectional = True
|
||||
cls.bss1_rule.signal = -8000
|
||||
cls.bss1_rule.enabled = True
|
||||
|
||||
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
|
||||
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
|
||||
|
||||
HostapdCLI.group_neighbors(*cls.bss_hostapd)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.bss0_rule.remove()
|
||||
cls.bss1_rule.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -2,6 +2,7 @@
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import dbus
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
@ -10,13 +11,14 @@ from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
import testutil
|
||||
import subprocess
|
||||
from config import ctx
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def check_connection(self, wd, ssid):
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
ordered_network = device.get_ordered_network(ssid, scan_if_needed=True)
|
||||
ordered_network = device.get_ordered_network(ssid)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
@ -54,38 +56,19 @@ class Test(unittest.TestCase):
|
||||
|
||||
IWD.clear_storage()
|
||||
|
||||
def test_connection_with_other_agent(self):
|
||||
def test_connection_use_first_from_multiple_registered(self):
|
||||
wd = IWD()
|
||||
|
||||
iwctl = subprocess.Popen(['iwctl', '-P', 'secret_ssid2'])
|
||||
# Let iwctl to start and register its agent.
|
||||
wd.wait(2)
|
||||
|
||||
self.check_connection(wd, 'ssid2')
|
||||
|
||||
iwctl.terminate()
|
||||
iwctl.communicate()
|
||||
|
||||
IWD.clear_storage()
|
||||
|
||||
def test_connection_use_own_agent_from_multiple_registered(self):
|
||||
|
||||
wd = IWD()
|
||||
|
||||
iwctl = subprocess.Popen(['iwctl', '-P', 'secret_ssid2'])
|
||||
# Let iwctl to start and register its agent.
|
||||
wd.wait(2)
|
||||
|
||||
psk_agent = PSKAgent("secret_ssid1")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
psk_agent = PSKAgent("secret_ssid2")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
self.check_connection(wd, 'ssid1')
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
iwctl.terminate()
|
||||
iwctl.communicate()
|
||||
|
||||
IWD.clear_storage()
|
||||
|
||||
@classmethod
|
||||
|
@ -1,6 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
max_test_exec_interval_sec=40
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssid1.conf
|
||||
|
2
autotests/testBSSBlacklist/TestBlacklist.psk
Normal file
2
autotests/testBSSBlacklist/TestBlacklist.psk
Normal file
@ -0,0 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
@ -1,99 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hostapd import hostapd_map
|
||||
|
||||
from hwsim import Hwsim
|
||||
|
||||
import time
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
hwsim = Hwsim()
|
||||
|
||||
bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
bss_radio = [ hwsim.get_radio('rad0'),
|
||||
hwsim.get_radio('rad1'),
|
||||
hwsim.get_radio('rad2') ]
|
||||
|
||||
rule0 = hwsim.rules.create()
|
||||
rule0.source = bss_radio[0].addresses[0]
|
||||
rule0.bidirectional = True
|
||||
rule0.signal = -2000
|
||||
|
||||
rule1 = hwsim.rules.create()
|
||||
rule1.source = bss_radio[1].addresses[0]
|
||||
rule1.bidirectional = True
|
||||
rule1.signal = -8000
|
||||
|
||||
rule2 = hwsim.rules.create()
|
||||
rule2.source = bss_radio[2].addresses[0]
|
||||
rule2.bidirectional = True
|
||||
rule2.signal = -10000
|
||||
|
||||
wd = IWD(True)
|
||||
|
||||
psk_agent = PSKAgent(["secret123", 'secret123'])
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist")
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
# Have both APs drop all packets, both should get blacklisted
|
||||
rule0.drop = True
|
||||
rule1.drop = True
|
||||
rule2.drop = True
|
||||
|
||||
with self.assertRaises(iwd.FailedEx):
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
rule0.drop = False
|
||||
rule1.drop = False
|
||||
|
||||
# This connect should work
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
self.assertIn(device.address, bss_hostapd[0].list_sta())
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,96 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hostapd import hostapd_map
|
||||
|
||||
from hwsim import Hwsim
|
||||
|
||||
import time
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
hwsim = Hwsim()
|
||||
|
||||
bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
bss_radio = [ hwsim.get_radio('rad0'),
|
||||
hwsim.get_radio('rad1'),
|
||||
hwsim.get_radio('rad2') ]
|
||||
|
||||
rule0 = hwsim.rules.create()
|
||||
rule0.source = bss_radio[0].addresses[0]
|
||||
rule0.bidirectional = True
|
||||
rule0.signal = -2000
|
||||
|
||||
rule1 = hwsim.rules.create()
|
||||
rule1.source = bss_radio[1].addresses[0]
|
||||
rule1.bidirectional = True
|
||||
rule1.signal = -3000
|
||||
|
||||
rule2 = hwsim.rules.create()
|
||||
rule2.source = bss_radio[2].addresses[0]
|
||||
rule2.bidirectional = True
|
||||
rule2.signal = -4000
|
||||
|
||||
wd = IWD(True, '/tmp')
|
||||
|
||||
psk_agent = PSKAgent("wrong_password")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist")
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
with self.assertRaises(iwd.FailedEx):
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
# We failed to connect bss_hostapd[0], but with a bad password. Verify
|
||||
# that this did not trigger a blacklist and that we did reconnect
|
||||
# successfully to bss_hostapd[0]
|
||||
self.assertIn(device.address, bss_hostapd[0].list_sta())
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -8,64 +8,195 @@ import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from iwd import IWD_CONFIG_DIR
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hostapd import hostapd_map
|
||||
|
||||
from hwsim import Hwsim
|
||||
|
||||
import time
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_temp_blacklist(self):
|
||||
rule0 = self.rule0
|
||||
rule1 = self.rule1
|
||||
rule2 = self.rule2
|
||||
|
||||
def test_connection_success(self):
|
||||
hwsim = Hwsim()
|
||||
bss_hostapd = self.bss_hostapd
|
||||
wd = self.wd
|
||||
|
||||
bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
bss_radio = [ hwsim.get_radio('rad0'),
|
||||
hwsim.get_radio('rad1'),
|
||||
hwsim.get_radio('rad2') ]
|
||||
|
||||
rule0 = hwsim.rules.create()
|
||||
rule0.source = bss_radio[0].addresses[0]
|
||||
rule0.bidirectional = True
|
||||
rule0.signal = -2000
|
||||
|
||||
rule1 = hwsim.rules.create()
|
||||
rule1.source = bss_radio[1].addresses[0]
|
||||
rule1.bidirectional = True
|
||||
rule1.signal = -3000
|
||||
|
||||
rule2 = hwsim.rules.create()
|
||||
rule2.source = bss_radio[2].addresses[0]
|
||||
rule2.bidirectional = True
|
||||
rule2.signal = -4000
|
||||
|
||||
wd = IWD(True, '/tmp')
|
||||
rule0.signal = -8000
|
||||
rule1.signal = -7000
|
||||
rule2.signal = -2000
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist")
|
||||
ordered_network = dev1.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev1, condition)
|
||||
|
||||
bss_hostapd[2].wait_for_event('AP-STA-CONNECTED %s' % dev1.address)
|
||||
|
||||
# dev1 now connected, this should max out the first AP, causing the next
|
||||
# connection to fail to this AP.
|
||||
|
||||
ordered_network = dev2.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
# We should have temporarily blacklisted the first BSS, and connected
|
||||
# to this one.
|
||||
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % dev2.address)
|
||||
|
||||
# Now check that the first BSS is still not blacklisted. We can
|
||||
# disconnect dev1, opening up the AP for more connections
|
||||
dev1.disconnect()
|
||||
dev2.disconnect()
|
||||
|
||||
ordered_network = dev2.get_ordered_network("TestBlacklist")
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
bss_hostapd[2].wait_for_event('AP-STA-CONNECTED %s' % dev2.address)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_all_blacklisted(self):
|
||||
wd = self.wd
|
||||
bss_hostapd = self.bss_hostapd
|
||||
|
||||
rule0 = self.rule0
|
||||
rule1 = self.rule1
|
||||
rule2 = self.rule2
|
||||
|
||||
psk_agent = PSKAgent(["secret123", 'secret123'])
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
# Have both APs drop all packets, both should get blacklisted
|
||||
rule0.drop = True
|
||||
rule0.enabled = True
|
||||
rule1.drop = True
|
||||
rule1.enabled = True
|
||||
rule2.drop = True
|
||||
rule2.enabled = True
|
||||
|
||||
with self.assertRaises(iwd.FailedEx):
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
rule0.drop = False
|
||||
rule1.drop = False
|
||||
rule2.drop = False
|
||||
|
||||
# Wait for scanning (likely a quick-scan) to finish, otherwise we will
|
||||
# may not have all BSS's in the list.
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# This connect should work
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_invalid_password(self):
|
||||
wd = self.wd
|
||||
bss_hostapd = self.bss_hostapd
|
||||
|
||||
psk_agent = PSKAgent("wrong_password")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
with self.assertRaises(iwd.FailedEx):
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
# We failed to connect bss_hostapd[0], but with a bad password. Verify
|
||||
# that this did not trigger a blacklist and that we did reconnect
|
||||
# successfully to bss_hostapd[0]
|
||||
self.assertIn(device.address, bss_hostapd[0].list_sta())
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_connection_success(self):
|
||||
wd = self.wd
|
||||
bss_hostapd = self.bss_hostapd
|
||||
rule0 = self.rule0
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(2)
|
||||
device = devices[0]
|
||||
|
||||
devices[1].disconnect()
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
rule0.drop = True
|
||||
|
||||
ordered_network.network_object.connect(wait=False)
|
||||
|
||||
# Have AP1 drop all packets, should result in a connection timeout
|
||||
@ -83,14 +214,12 @@ class Test(unittest.TestCase):
|
||||
# should automatically try the next BSS in the list, which is
|
||||
# bss_hostapd[1]
|
||||
self.assertNotIn(device.address, bss_hostapd[0].list_sta())
|
||||
self.assertIn(device.address, bss_hostapd[1].list_sta())
|
||||
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
rule0.drop = False
|
||||
|
||||
# Next try autoconnecting to a network with a blacklisted BSS. Since an
|
||||
# explicit disconnect call would disable autoconnect we reset
|
||||
# hostapd which will disconnect IWD.
|
||||
bss_hostapd[1].reload()
|
||||
device.disconnect()
|
||||
device.autoconnect = True
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
@ -98,32 +227,24 @@ class Test(unittest.TestCase):
|
||||
# Now we wait... AutoConnect should take over
|
||||
|
||||
condition = 'obj.state == DeviceState.connecting'
|
||||
wd.wait_for_object_condition(device, condition, 15)
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition, 15)
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
# Same as before, make sure we didn't connect to the blacklisted AP.
|
||||
self.assertNotIn(device.address, bss_hostapd[0].list_sta())
|
||||
self.assertIn(device.address, bss_hostapd[1].list_sta())
|
||||
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
# Wait for the blacklist to expire (10 seconds)
|
||||
elapsed = time.time() - start
|
||||
|
||||
if elapsed < 11:
|
||||
time.sleep(11 - elapsed)
|
||||
if elapsed < 15:
|
||||
wd.wait(15 - elapsed)
|
||||
|
||||
device.disconnect()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist")
|
||||
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
@ -132,20 +253,111 @@ class Test(unittest.TestCase):
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
self.assertIn(device.address, bss_hostapd[0].list_sta())
|
||||
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
self.wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
def test_blacklist_disabled(self):
|
||||
wd = self.wd
|
||||
bss_hostapd = self.bss_hostapd
|
||||
|
||||
rule0 = self.rule0
|
||||
rule1 = self.rule1
|
||||
rule2 = self.rule2
|
||||
|
||||
psk_agent = PSKAgent(["secret123", 'secret123'])
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
rule0.drop = True
|
||||
rule0.enabled = True
|
||||
|
||||
device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
# The first BSS should fail, and we should connect to the second. This
|
||||
# should not result in a connection blacklist though since its disabled.
|
||||
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
device.disconnect()
|
||||
|
||||
rule0.drop = False
|
||||
device.autoconnect = True
|
||||
|
||||
# Verify the first BSS wasn't blacklisted.
|
||||
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
|
||||
|
||||
def setUp(self):
|
||||
_, _, name = self.id().split(".")
|
||||
|
||||
# TODO: If we have this pattern elsewhere it might be nice to turn this
|
||||
# into a decorator e.g.
|
||||
#
|
||||
# @config("main.conf.disabled")
|
||||
# @profile("TestBlacklist.psk")
|
||||
# def test_blacklist_disabled(self)
|
||||
# ...
|
||||
#
|
||||
if name == "test_blacklist_disabled":
|
||||
IWD.copy_to_storage("main.conf.disabled", IWD_CONFIG_DIR, "main.conf")
|
||||
IWD.copy_to_storage("TestBlacklist.psk")
|
||||
else:
|
||||
IWD.copy_to_storage("main.conf.default", IWD_CONFIG_DIR, "main.conf")
|
||||
|
||||
self.wd = IWD(True)
|
||||
|
||||
def tearDown(self):
|
||||
IWD.clear_storage()
|
||||
self.wd = None
|
||||
self.rule0.drop = False
|
||||
self.rule1.drop = False
|
||||
self.rule2.drop = False
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('main.conf')
|
||||
cls.hwsim = Hwsim()
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
cls.bss_radio = [ cls.hwsim.get_radio('rad0'),
|
||||
cls.hwsim.get_radio('rad1'),
|
||||
cls.hwsim.get_radio('rad2') ]
|
||||
|
||||
cls.rule0 = cls.hwsim.rules.create()
|
||||
cls.rule0.source = cls.bss_radio[0].addresses[0]
|
||||
cls.rule0.bidirectional = True
|
||||
cls.rule0.signal = -2000
|
||||
cls.rule0.enabled = True
|
||||
|
||||
cls.rule1 = cls.hwsim.rules.create()
|
||||
cls.rule1.source = cls.bss_radio[1].addresses[0]
|
||||
cls.rule1.bidirectional = True
|
||||
cls.rule1.signal = -7000
|
||||
cls.rule1.enabled = True
|
||||
|
||||
cls.rule2 = cls.hwsim.rules.create()
|
||||
cls.rule2.source = cls.bss_radio[2].addresses[0]
|
||||
cls.rule2.bidirectional = True
|
||||
cls.rule2.signal = -8000
|
||||
cls.rule2.enabled = True
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
cls.hwsim.rules.remove_all()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
||||
|
@ -1,8 +1,7 @@
|
||||
[SETUP]
|
||||
num_radios=5
|
||||
tmpfs_extra_stuff=main.conf
|
||||
max_test_exec_interval_sec=45
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssid1.conf
|
||||
|
@ -2,4 +2,4 @@
|
||||
InitialTimeout=10
|
||||
|
||||
[Scan]
|
||||
disable_mac_randomization=true
|
||||
DisableMacAddressRandomization=true
|
2
autotests/testBSSBlacklist/main.conf.disabled
Normal file
2
autotests/testBSSBlacklist/main.conf.disabled
Normal file
@ -0,0 +1,2 @@
|
||||
[Blacklist]
|
||||
InitialTimeout=0
|
@ -9,3 +9,4 @@ wpa_passphrase=secret123
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
rrm_neighbor_report=1
|
||||
beacon_int=10
|
||||
|
@ -9,3 +9,4 @@ wpa_passphrase=secret123
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
rrm_neighbor_report=1
|
||||
beacon_int=10
|
||||
|
@ -9,4 +9,5 @@ wpa_passphrase=secret123
|
||||
ctrl_interface=/var/run/hostapd
|
||||
|
||||
rrm_neighbor_report=1
|
||||
max_num_sta=1
|
||||
max_num_sta=1
|
||||
beacon_int=10
|
||||
|
@ -1,131 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hostapd import hostapd_map
|
||||
|
||||
from hwsim import Hwsim
|
||||
|
||||
import time
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
hwsim = Hwsim()
|
||||
|
||||
bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
|
||||
HostapdCLI(config='ssid2.conf'),
|
||||
HostapdCLI(config='ssid3.conf') ]
|
||||
bss_radio = [ hwsim.get_radio('rad0'),
|
||||
hwsim.get_radio('rad1'),
|
||||
hwsim.get_radio('rad2') ]
|
||||
|
||||
rule0 = hwsim.rules.create()
|
||||
rule0.source = bss_radio[0].addresses[0]
|
||||
rule0.bidirectional = True
|
||||
rule0.signal = -8000
|
||||
|
||||
rule1 = hwsim.rules.create()
|
||||
rule1.source = bss_radio[1].addresses[0]
|
||||
rule1.bidirectional = True
|
||||
rule1.signal = -2500
|
||||
|
||||
rule2 = hwsim.rules.create()
|
||||
rule2.source = bss_radio[2].addresses[0]
|
||||
rule2.bidirectional = True
|
||||
rule2.signal = -2000
|
||||
|
||||
wd = IWD(True, '/tmp')
|
||||
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
dev1, dev2 = wd.list_devices(2)
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev1, condition)
|
||||
|
||||
dev1.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev1, condition)
|
||||
|
||||
ordered_network = dev1.get_ordered_network("TestBlacklist")
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
self.assertIn(dev1.address, bss_hostapd[2].list_sta())
|
||||
|
||||
# dev1 now connected, this should max out the first AP, causing the next
|
||||
# connection to fail to this AP.
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
dev2.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
ordered_network = dev2.get_ordered_network("TestBlacklist")
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
# We should have temporarily blacklisted the first BSS, and connected
|
||||
# to this one.
|
||||
self.assertIn(dev2.address, bss_hostapd[1].list_sta())
|
||||
|
||||
# Now check that the first BSS is still not blacklisted. We can
|
||||
# disconnect dev1, opening up the AP for more connections
|
||||
dev1.disconnect()
|
||||
dev2.disconnect()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
dev2.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(dev2, condition)
|
||||
|
||||
ordered_network = dev2.get_ordered_network("TestBlacklist")
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
self.assertIn(dev2.address, bss_hostapd[2].list_sta())
|
||||
|
||||
wd.unregister_psk_agent(psk_agent)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('main.conf')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
98
autotests/testBasicServiceSet/basic_service_set_test.py
Normal file
98
autotests/testBasicServiceSet/basic_service_set_test.py
Normal file
@ -0,0 +1,98 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys, os
|
||||
|
||||
sys.path.append('../util')
|
||||
import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hwsim import Hwsim
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_bss_unregister(self):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
ordered_network = device.get_ordered_network('ssidTKIP', full_scan=True)
|
||||
network = ordered_network.network_object
|
||||
|
||||
self.assertEqual(len(network.extended_service_set), 2)
|
||||
|
||||
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
|
||||
|
||||
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
|
||||
self.assertIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
|
||||
|
||||
self.rule_bss1.enabled = True
|
||||
|
||||
# Even with flushing, the kernel still seems to return the scan
|
||||
# results
|
||||
self.wd.wait(40)
|
||||
ordered_network = device.get_ordered_network('ssidTKIP', full_scan=True)
|
||||
network = ordered_network.network_object
|
||||
|
||||
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
|
||||
|
||||
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
|
||||
self.assertNotIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
|
||||
|
||||
self.rule_bss0.enabled = True
|
||||
|
||||
self.wd.wait(40)
|
||||
ordered_networks = device.get_ordered_networks('ssidTKIP', full_scan=True)
|
||||
self.assertIsNone(ordered_networks)
|
||||
|
||||
self.rule_bss0.enabled = False
|
||||
|
||||
ordered_networks = device.get_ordered_networks('ssidTKIP', full_scan=True)
|
||||
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
|
||||
|
||||
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
|
||||
self.assertNotIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
|
||||
|
||||
def tearDown(self):
|
||||
self.rule_bss0.enabled = False
|
||||
self.rule_bss1.enabled = False
|
||||
|
||||
self.wd.stop()
|
||||
self.wd.wait(10)
|
||||
self.wd = None
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hwsim = Hwsim()
|
||||
|
||||
IWD.copy_to_storage('ssidTKIP.psk')
|
||||
|
||||
cls.bss_hostapd = [ HostapdCLI(config='ssidTKIP-1.conf'),
|
||||
HostapdCLI(config='ssidTKIP-2.conf') ]
|
||||
|
||||
|
||||
rad0 = hwsim.get_radio('rad0')
|
||||
rad1 = hwsim.get_radio('rad1')
|
||||
|
||||
cls.rule_bss0 = hwsim.rules.create()
|
||||
cls.rule_bss0.source = rad0.addresses[0]
|
||||
cls.rule_bss0.bidirectional = True
|
||||
cls.rule_bss0.drop = True
|
||||
|
||||
cls.rule_bss1 = hwsim.rules.create()
|
||||
cls.rule_bss1.source = rad1.addresses[0]
|
||||
cls.rule_bss1.bidirectional = True
|
||||
cls.rule_bss1.drop = True
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage()
|
||||
cls.bss_hostapd = None
|
||||
cls.rule_bss0.remove()
|
||||
cls.rule_bss1.remove()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
8
autotests/testBasicServiceSet/hw.conf
Normal file
8
autotests/testBasicServiceSet/hw.conf
Normal file
@ -0,0 +1,8 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
hwsim_medium=yes
|
||||
start_iwd=no
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidTKIP-1.conf
|
||||
rad1=ssidTKIP-2.conf
|
7
autotests/testBasicServiceSet/ssidTKIP-1.conf
Normal file
7
autotests/testBasicServiceSet/ssidTKIP-1.conf
Normal file
@ -0,0 +1,7 @@
|
||||
hw_mode=g
|
||||
channel=1
|
||||
ssid=ssidTKIP
|
||||
|
||||
wpa=1
|
||||
wpa_pairwise=TKIP
|
||||
wpa_passphrase=secret123
|
7
autotests/testBasicServiceSet/ssidTKIP-2.conf
Normal file
7
autotests/testBasicServiceSet/ssidTKIP-2.conf
Normal file
@ -0,0 +1,7 @@
|
||||
hw_mode=g
|
||||
channel=2
|
||||
ssid=ssidTKIP
|
||||
|
||||
wpa=1
|
||||
wpa_pairwise=TKIP
|
||||
wpa_passphrase=secret123
|
@ -1,5 +1,5 @@
|
||||
[Security]
|
||||
EAP-Method=PWD
|
||||
Passphrase=secret123
|
||||
|
||||
[Settings]
|
||||
AutoConnect=False
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/python3
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
@ -8,40 +8,44 @@ import iwd
|
||||
from iwd import IWD
|
||||
from iwd import PSKAgent
|
||||
from iwd import NetworkType
|
||||
from hostapd import HostapdCLI
|
||||
import testutil
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_connection_success(self):
|
||||
hapd = HostapdCLI()
|
||||
wd = IWD()
|
||||
|
||||
psk_agent = PSKAgent('abc', ('user', 'testpasswd'))
|
||||
psk_agent = PSKAgent("secret123")
|
||||
wd.register_psk_agent(psk_agent)
|
||||
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
ordered_network = device.get_ordered_network('ssidCCMP')
|
||||
|
||||
if not device.get_ordered_networks():
|
||||
device.scan()
|
||||
condition = 'obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network('ssidEAP-TTLS')
|
||||
|
||||
self.assertEqual(ordered_network.type, NetworkType.eap)
|
||||
self.assertEqual(ordered_network.type, NetworkType.psk)
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected()
|
||||
|
||||
hapd.chan_switch(2)
|
||||
# Make sure the SA Query is verified and IWD doesn't disconnect
|
||||
with self.assertRaises(TimeoutError):
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
wd.wait_for_object_condition(device, condition, 4)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
testutil.test_iface_operstate()
|
||||
testutil.test_ifaces_connected()
|
||||
@ -55,7 +59,7 @@ class Test(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('ssidEAP-TTLS.8021x')
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
5
autotests/testChannelSwitch/hw.conf
Normal file
5
autotests/testChannelSwitch/hw.conf
Normal file
@ -0,0 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=2
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidCCMP.conf
|
@ -5,3 +5,4 @@ ssid=ssidCCMP
|
||||
wpa=2
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=secret123
|
||||
ocv=1
|
@ -8,114 +8,91 @@ import iwd
|
||||
from iwd import IWD
|
||||
import testutil
|
||||
import subprocess
|
||||
from config import ctx
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def check_connection_success(self, ssid):
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
ordered_network = device.get_ordered_network(ssid)
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.disconnect()
|
||||
|
||||
condition = 'not obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
|
||||
def establish_network(self, ssid):
|
||||
device = self.wd.list_devices(1)[0]
|
||||
device.get_ordered_network(ssid)
|
||||
|
||||
def test_connection_with_passphrase(self):
|
||||
ssid = 'ssidPassphrase'
|
||||
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
self.establish_network(ssid)
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
# Use --dontaks cmd-line option
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
subprocess.check_call(['iwctl', '-d', 'station',
|
||||
device.name, 'connect', ssid])
|
||||
ctx.start_process(['iwctl', 'd', 'station', device.name, 'connect', ssid], check=True)
|
||||
|
||||
subprocess.check_call(['iwctl', '-P', 'passphrase',
|
||||
'station', device.name, 'connect', ssid])
|
||||
ctx.start_process(['iwctl', '-P', 'passphrase', 'station', device.name, 'connect', ssid],
|
||||
check=True)
|
||||
|
||||
self.check_connection_success(ssid)
|
||||
|
||||
def test_connection_with_username_and_password(self):
|
||||
ssid = 'ssidUNameAndPWord'
|
||||
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
subprocess.check_call(['iwctl', '-u', 'user', '-p', 'password',
|
||||
'station', device.name, 'connect', ssid])
|
||||
self.establish_network(ssid)
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
ctx.start_process(['iwctl', '-u', 'user', '-p', 'password', 'station', \
|
||||
device.name, 'connect', ssid], check=True)
|
||||
self.check_connection_success(ssid)
|
||||
|
||||
def test_connection_with_password(self):
|
||||
ssid = 'ssidPWord'
|
||||
|
||||
wd = IWD()
|
||||
self.establish_network(ssid)
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
subprocess.check_call(['iwctl', '-p', 'password',
|
||||
'station', device.name, 'connect', ssid])
|
||||
ctx.start_process(['iwctl', '-p', 'password', 'station', device.name, 'connect', ssid],
|
||||
check=True)
|
||||
|
||||
self.check_connection_success(ssid)
|
||||
|
||||
def test_connection_failure(self):
|
||||
ssid = 'ssidPassphrase'
|
||||
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
self.establish_network(ssid)
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
subprocess.check_call(['iwctl', '-P', 'incorrect_passphrase',
|
||||
'station', device.name, 'connect', ssid])
|
||||
ctx.start_process(['iwctl', '-P', 'incorrect_passphrase', 'station', device.name, \
|
||||
'connect', ssid], check=True)
|
||||
|
||||
def test_invalid_command_line_option(self):
|
||||
ssid = 'ssidPassphrase'
|
||||
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
self.establish_network(ssid)
|
||||
device = self.wd.list_devices(1)[0]
|
||||
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
subprocess.check_call(['iwctl', '-z',
|
||||
'station', device.name, 'connect', ssid])
|
||||
ctx.start_process(['iwctl', '-z', 'station', device.name, 'connect', ssid], check=True)
|
||||
|
||||
def test_invalid_command(self):
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
subprocess.check_call(['iwctl', 'inexistent', 'command'])
|
||||
ctx.start_process(['iwctl', 'inexistent', 'command'], check=True)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
IWD.copy_to_storage('ssidUNameAndPWord.8021x')
|
||||
IWD.copy_to_storage('ssidPWord.8021x')
|
||||
|
||||
wd = IWD()
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
cls.wd = IWD()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -1,7 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=4
|
||||
max_test_exec_interval_sec=40
|
||||
tmpfs_extra_stuff=../misc/certs:eap-user-ttls-mschap.text
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidPassphrase.conf
|
||||
|
@ -11,7 +11,7 @@ from iwd import IWD
|
||||
|
||||
class Test8021xNetwork(unittest.TestCase):
|
||||
'''
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
The below test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
|
@ -1,11 +1,9 @@
|
||||
[SETUP]
|
||||
num_radios=5
|
||||
start_iwd=0
|
||||
max_test_exec_interval_sec=120
|
||||
tmpfs_extra_stuff=../misc/certs
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidOpen.conf
|
||||
rad1=ssidWPA.conf
|
||||
rad2=ssidEAP-TLS.conf
|
||||
rad3=ssidEAP-Other.conf
|
||||
rad3=ssidEAP-Other.conf
|
||||
|
@ -11,7 +11,7 @@ from iwd import IWD
|
||||
|
||||
class TestOpenNetwork(unittest.TestCase):
|
||||
'''
|
||||
The bellow test cases excesise the following connection scenarios:
|
||||
The below test cases excesise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
@ -24,6 +24,10 @@ class TestOpenNetwork(unittest.TestCase):
|
||||
tca.validate('ssidOpen', False)
|
||||
tca.validate('ssidOpen', True)
|
||||
|
||||
def setUp(self):
|
||||
IWD.copy_to_storage('ssidOpen.open')
|
||||
|
||||
def tearDown(self):
|
||||
IWD.clear_storage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -6,7 +6,7 @@ wpa=3
|
||||
wpa_key_mgmt=WPA-EAP
|
||||
ieee8021x=1
|
||||
eap_server=1
|
||||
eap_user_file=/tmp/certs/eap-user-ttls.text
|
||||
eap_user_file=/tmp/secrets/eap-user.text
|
||||
ca_cert=/tmp/certs/cert-ca.pem
|
||||
server_cert=/tmp/certs/cert-server.pem
|
||||
private_key=/tmp/certs/cert-server-key.pem
|
||||
|
@ -3,4 +3,4 @@ EAP-Method=TLS
|
||||
EAP-TLS-CACert=/tmp/certs/cert-ca.pem
|
||||
EAP-TLS-ClientCert=/tmp/certs/cert-client.pem
|
||||
EAP-TLS-ClientKey=/tmp/certs/cert-client-key-pkcs8.pem
|
||||
EAP-Identity=abc@example.com
|
||||
EAP-Identity=tls@example.com
|
||||
|
@ -6,7 +6,7 @@ wpa=3
|
||||
wpa_key_mgmt=WPA-EAP
|
||||
ieee8021x=1
|
||||
eap_server=1
|
||||
eap_user_file=/tmp/certs/eap-user-tls.text
|
||||
eap_user_file=/tmp/secrets/eap-user.text
|
||||
ca_cert=/tmp/certs/cert-ca.pem
|
||||
server_cert=/tmp/certs/cert-server.pem
|
||||
private_key=/tmp/certs/cert-server-key.pem
|
||||
|
0
autotests/testConnectAutoconnect/ssidOpen.open
Normal file
0
autotests/testConnectAutoconnect/ssidOpen.open
Normal file
@ -24,10 +24,12 @@ class TestConnectAutoConnect(unittest.TestCase):
|
||||
else:
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(ordered_network.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
def check_autoconnect(self, wd, device, ssid, throws):
|
||||
device.autoconnect = True
|
||||
|
||||
if throws is None:
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
@ -11,7 +11,7 @@ from iwd import IWD
|
||||
|
||||
class TestWpaNetwork(unittest.TestCase):
|
||||
'''
|
||||
The bellow test cases exercise the following connection scenarios:
|
||||
The below test cases exercise the following connection scenarios:
|
||||
|
||||
Network config is
|
||||
present at start time: Connect: AutoConnect: Result:
|
||||
|
175
autotests/testDPP/connection_test.py
Normal file
175
autotests/testDPP/connection_test.py
Normal file
@ -0,0 +1,175 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
from iwd import DeviceProvisioning
|
||||
from wpas import Wpas
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
from config import ctx
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_iwd_as_enrollee(self):
|
||||
self.device.autoconnect = True
|
||||
self.hapd.reload()
|
||||
|
||||
uri = self.device.dpp_start_enrollee()
|
||||
|
||||
self.wpas.dpp_configurator_create(uri)
|
||||
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_iwd_as_enrollee_channel_switch(self):
|
||||
self.device.autoconnect = True
|
||||
self.hapd.reload()
|
||||
|
||||
uri = self.device.dpp_start_enrollee()
|
||||
|
||||
self.wpas.dpp_configurator_create(uri)
|
||||
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123', freq=2462)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_iwd_as_enrollee_scan_after(self):
|
||||
self.wpas.disconnect()
|
||||
self.device.autoconnect = True
|
||||
uri = self.device.dpp_start_enrollee()
|
||||
|
||||
self.wpas.dpp_configurator_create(uri)
|
||||
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
self.device.get_ordered_network('ssidCCMP', scan_if_needed=False)
|
||||
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_iwd_as_enrollee_no_ack(self):
|
||||
self.rule0.enabled = True
|
||||
self.device.autoconnect = True
|
||||
self.hapd.reload()
|
||||
|
||||
uri = self.device.dpp_start_enrollee()
|
||||
|
||||
self.wpas.dpp_configurator_create(uri)
|
||||
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_iwd_as_configurator(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
IWD.copy_to_storage('ssidCCMP.psk')
|
||||
self.device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
uri = self.device.dpp_start_configurator()
|
||||
|
||||
self.wpas.dpp_enrollee_start(uri)
|
||||
|
||||
self.wpas.wait_for_event('DPP-CONF-RECEIVED', timeout=30)
|
||||
|
||||
def test_iwd_as_configurator_initiator(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
IWD.copy_to_storage('ssidCCMP.psk')
|
||||
self.device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
uri = self.wpas.dpp_enrollee_start(oper_and_channel='81/2')
|
||||
|
||||
self.device.dpp_start_configurator(uri)
|
||||
|
||||
self.wpas.wait_for_event('DPP-CONF-RECEIVED', timeout=30)
|
||||
|
||||
def test_client_as_configurator(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
IWD.copy_to_storage('ssidCCMP.psk')
|
||||
self.device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
ctx.start_process(['iwctl', 'dpp', self.device.name, 'start-configurator'], check=True)
|
||||
|
||||
dpp = DeviceProvisioning(self.device.device_path)
|
||||
|
||||
self.wpas.dpp_enrollee_start(dpp.uri)
|
||||
|
||||
self.wpas.wait_for_event('DPP-CONF-RECEIVED', timeout=30)
|
||||
|
||||
def test_client_as_enrollee(self):
|
||||
self.device.autoconnect = True
|
||||
self.hapd.reload()
|
||||
|
||||
ctx.start_process(['iwctl', 'dpp', self.device.name, 'start-enrollee'], check=True)
|
||||
|
||||
dpp = DeviceProvisioning(self.device.device_path)
|
||||
|
||||
self.wpas.dpp_configurator_create(dpp.uri)
|
||||
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def setUp(self):
|
||||
self.wpas = Wpas('wpas.conf')
|
||||
self.wd = IWD(True)
|
||||
self.device = self.wd.list_devices(1)[0]
|
||||
self.hapd = HostapdCLI('hostapd.conf')
|
||||
self.hapd.disable()
|
||||
self.hwsim = Hwsim()
|
||||
|
||||
self.rule0 = self.hwsim.rules.create()
|
||||
self.rule0.prefix = 'd0'
|
||||
self.rule0.match_offset = 24
|
||||
self.rule0.match = '04 09 50 6f 9a 1a 01 01'
|
||||
self.rule0.match_times = 1
|
||||
self.rule0.drop = True
|
||||
|
||||
def tearDown(self):
|
||||
# Tests end in various states, don't fail when tearing down.
|
||||
try:
|
||||
self.device.disconnect()
|
||||
self.device.dpp_stop()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.wpas.dpp_configurator_remove()
|
||||
self.wpas.clean_up()
|
||||
|
||||
self.wd = None
|
||||
self.device = None
|
||||
self.wpas = None
|
||||
self.hapd = None
|
||||
self.rule0 = None
|
||||
IWD.clear_storage()
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
2
autotests/testDPP/existingProfile.psk
Normal file
2
autotests/testDPP/existingProfile.psk
Normal file
@ -0,0 +1,2 @@
|
||||
[Security]
|
||||
Passphrase=IncorrectPassphrase
|
7
autotests/testDPP/hostapd.conf
Normal file
7
autotests/testDPP/hostapd.conf
Normal file
@ -0,0 +1,7 @@
|
||||
hw_mode=g
|
||||
channel=6
|
||||
ssid=ssidCCMP
|
||||
|
||||
wpa=2
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=secret123
|
14
autotests/testDPP/hw.conf
Normal file
14
autotests/testDPP/hw.conf
Normal file
@ -0,0 +1,14 @@
|
||||
[SETUP]
|
||||
num_radios=5
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[WPA_SUPPLICANT]
|
||||
rad0=wpas.conf
|
||||
|
||||
[HOSTAPD]
|
||||
rad1=hostapd.conf
|
||||
rad2=ssidHidden.conf
|
||||
|
||||
[NameSpaces]
|
||||
ns0=rad3
|
336
autotests/testDPP/pkex_test.py
Normal file
336
autotests/testDPP/pkex_test.py
Normal file
@ -0,0 +1,336 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD, SharedCodeAgent, DeviceState
|
||||
from iwd import DeviceProvisioning
|
||||
from wpas import Wpas
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
from config import ctx
|
||||
from time import time
|
||||
import os
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def start_wpas_pkex(self, code, curve=None, **kwargs):
|
||||
self.wpas.dpp_bootstrap_gen(type='pkex', curve=curve)
|
||||
self.wpas.dpp_pkex_add(code=code, **kwargs)
|
||||
if kwargs.get('role', 'configurator') == 'configurator':
|
||||
self.wpas.dpp_configurator_create()
|
||||
self.wpas.dpp_listen(2437)
|
||||
|
||||
def stop_wpas_pkex(self):
|
||||
self.wpas.dpp_pkex_remove()
|
||||
self.wpas.dpp_stop_listen()
|
||||
self.wpas.dpp_configurator_remove()
|
||||
|
||||
def start_iwd_pkex_configurator(self, device, agent=False, profile='ssidCCMP.psk'):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
|
||||
IWD.copy_to_storage(profile)
|
||||
device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(device, condition)
|
||||
|
||||
if agent:
|
||||
self.agent = SharedCodeAgent(codes = {"test": "secret123"})
|
||||
|
||||
device.dpp_pkex_start_configurator(self.agent.path)
|
||||
else:
|
||||
device.dpp_pkex_configure_enrollee('secret123', identifier="test")
|
||||
|
||||
#
|
||||
# WPA Supplicant has awful handling of retransmissions and no-ACK
|
||||
# conditions. It only handles retransmitting the exchange request when
|
||||
# there is no-ACK, which makes zero sense since its a broadcast...
|
||||
#
|
||||
# So, really, testing against wpa_supplicant is fragile and dependent on
|
||||
# how the scheduling works out. If IWD doesn't ACK due to being on the
|
||||
# next frequency or in between offchannel requests wpa_supplicant gets
|
||||
# into a state where it thinks a PKEX session has been started (having
|
||||
# received the exchange request) but will only accept commit-reveal
|
||||
# frames. IWD is unaware because it never got a response so it keeps
|
||||
# sending exchange requests which are ignored.
|
||||
#
|
||||
# Nevertheless we should still test against wpa_supplicant for
|
||||
# compatibility so attempt to detect this case and restart the
|
||||
# wpa_supplicant configurator.
|
||||
#
|
||||
def restart_wpas_if_needed(self):
|
||||
i = 0
|
||||
|
||||
while i < 10:
|
||||
data = self.wpas.wait_for_event("DPP-RX")
|
||||
self.assertIn("type=7", data)
|
||||
|
||||
data = self.wpas.wait_for_event("DPP-TX")
|
||||
self.assertIn("type=8", data)
|
||||
|
||||
data = self.wpas.wait_for_event("DPP-TX-STATUS")
|
||||
if "result=no-ACK" in data:
|
||||
self.stop_wpas_pkex()
|
||||
self.start_wpas_pkex('secret123', identifier="test")
|
||||
else:
|
||||
return
|
||||
|
||||
i += 1
|
||||
|
||||
raise Exception("wpa_supplicant could not complete PKEX after 10 retries")
|
||||
|
||||
def test_pkex_iwd_as_enrollee(self):
|
||||
self.start_wpas_pkex('secret123', identifier="test")
|
||||
|
||||
self.device[0].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
self.restart_wpas_if_needed()
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
|
||||
def test_pkex_iwd_as_enrollee_retransmit(self):
|
||||
self.rule_reveal_req.enabled = True
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test")
|
||||
|
||||
self.device[0].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
self.restart_wpas_if_needed()
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
|
||||
def test_pkex_unsupported_version(self):
|
||||
self.start_wpas_pkex('secret123', identifier="test", version=2)
|
||||
|
||||
now = time()
|
||||
self.device[0].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = "obj.started == False"
|
||||
self.wd.wait_for_object_condition(self.device[0]._sc_device_provisioning,
|
||||
condition, max_wait=125)
|
||||
|
||||
# Check the enrollee stopped after 2 minutes
|
||||
elapsed = time() - now
|
||||
self.assertLess(elapsed, 125)
|
||||
|
||||
def test_pkex_configurator_timeout(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
now = time()
|
||||
|
||||
condition = "obj.started == False"
|
||||
self.wd.wait_for_object_condition(self.device[0]._sc_device_provisioning,
|
||||
condition, max_wait=125)
|
||||
|
||||
# Check the enrollee stopped after 2 minutes
|
||||
elapsed = time() - now
|
||||
self.assertLess(elapsed, 125)
|
||||
|
||||
def test_pkex_iwd_as_configurator(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test", initiator=True,
|
||||
role='enrollee')
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
self.wpas.wait_for_event("DPP-CONF-RECEIVED")
|
||||
|
||||
def test_pkex_iwd_as_configurator_retransmit(self):
|
||||
self.rule_xchg_resp.enabled = True
|
||||
self.rule_reveal_resp.enabled = True
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test", initiator=True,
|
||||
role='enrollee')
|
||||
|
||||
self.wpas.wait_for_event("DPP-AUTH-SUCCESS")
|
||||
self.wpas.wait_for_event("DPP-CONF-RECEIVED")
|
||||
|
||||
def test_pkex_iwd_as_configurator_bad_group(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.start_wpas_pkex('secret123', identifier="test", initiator=True,
|
||||
role='enrollee', curve='P-384')
|
||||
|
||||
self.wpas.wait_for_event(f"DPP-RX src={self.device[0].address} freq=2437 type=8")
|
||||
self.wpas.wait_for_event("DPP-FAIL")
|
||||
|
||||
def test_pkex_iwd_to_iwd(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
self.device[1].autoconnect = True
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidCCMP.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("SendHostname=true", settings)
|
||||
|
||||
def test_pkex_configurator_with_agent(self):
|
||||
self.start_iwd_pkex_configurator(self.device[0], agent=True)
|
||||
self.device[1].autoconnect = True
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
self.agent = None
|
||||
|
||||
def test_existing_network(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidCCMP.psk")
|
||||
|
||||
# Scan first so a network object exists, and its a known network
|
||||
self.device[1].scan()
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == True')
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == False')
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
|
||||
self.device[1].autoconnect = False
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidCCMP.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("SendHostname=true", settings)
|
||||
|
||||
def test_existing_incorrect_profile(self):
|
||||
self.hapd.reload()
|
||||
self.hapd.wait_for_event('AP-ENABLED')
|
||||
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidCCMP.psk")
|
||||
|
||||
# Start connecting
|
||||
self.device[1].autoconnect = True
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.state == DeviceState.connecting')
|
||||
|
||||
# We should be able to start DPP despite the connecting state
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0])
|
||||
self.assertEqual(self.device[1].state, DeviceState.disconnected)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
def test_existing_hidden_network(self):
|
||||
self.hapd_hidden.reload()
|
||||
self.hapd_hidden.wait_for_event('AP-ENABLED')
|
||||
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidHidden.psk")
|
||||
|
||||
# Scan first so a network object exists, and its a known network
|
||||
self.device[1].scan()
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == True')
|
||||
self.wd.wait_for_object_condition(self.device[1], 'obj.scanning == False')
|
||||
|
||||
self.start_iwd_pkex_configurator(self.device[0], profile='ssidHidden.psk')
|
||||
|
||||
self.device[1].autoconnect = False
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidHidden.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("Hidden=true", settings)
|
||||
|
||||
def test_hidden_network(self):
|
||||
self.hapd_hidden.reload()
|
||||
self.hapd_hidden.wait_for_event('AP-ENABLED')
|
||||
self.start_iwd_pkex_configurator(self.device[0], profile='ssidHidden.psk')
|
||||
|
||||
self.device[1].autoconnect = False
|
||||
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device[1], condition)
|
||||
|
||||
# Check additional settings were carried over
|
||||
with open('/tmp/ns0/ssidHidden.psk', 'r') as f:
|
||||
settings = f.read()
|
||||
|
||||
self.assertIn("Hidden=true", settings)
|
||||
|
||||
def setUp(self):
|
||||
ns0 = ctx.get_namespace('ns0')
|
||||
self.wpas = Wpas('wpas.conf')
|
||||
|
||||
self.wd = IWD(True)
|
||||
self.wd_ns0 = IWD(True, iwd_storage_dir='/tmp/ns0', namespace=ns0)
|
||||
self.device = []
|
||||
self.device.append(self.wd.list_devices(1)[0])
|
||||
self.device.append(self.wd_ns0.list_devices(1)[0])
|
||||
self.hapd = HostapdCLI('hostapd.conf')
|
||||
self.hapd.disable()
|
||||
self.hapd_hidden = HostapdCLI('ssidHidden.conf')
|
||||
self.hapd_hidden.disable()
|
||||
self.hwsim = Hwsim()
|
||||
|
||||
self.rule_xchg_resp = self.hwsim.rules.create()
|
||||
self.rule_xchg_resp.prefix = 'd0'
|
||||
self.rule_xchg_resp.match_offset = 24
|
||||
self.rule_xchg_resp.match = '04 09 50 6f 9a 1a 01 08'
|
||||
self.rule_xchg_resp.match_times = 1
|
||||
self.rule_xchg_resp.drop = True
|
||||
|
||||
self.rule_reveal_resp = self.hwsim.rules.create()
|
||||
self.rule_reveal_resp.prefix = 'd0'
|
||||
self.rule_reveal_resp.match_offset = 24
|
||||
self.rule_reveal_resp.match = '04 09 50 6f 9a 1a 01 0a'
|
||||
self.rule_reveal_resp.match_times = 1
|
||||
self.rule_reveal_resp.drop = True
|
||||
|
||||
self.rule_reveal_req = self.hwsim.rules.create()
|
||||
self.rule_reveal_req.prefix = 'd0'
|
||||
self.rule_reveal_req.match_offset = 24
|
||||
self.rule_reveal_req.match = '04 09 50 6f 9a 1a 01 09'
|
||||
self.rule_reveal_req.match_times = 1
|
||||
self.rule_reveal_req.drop = True
|
||||
|
||||
def tearDown(self):
|
||||
# Tests end in various states, don't fail when tearing down.
|
||||
try:
|
||||
self.device[0].disconnect()
|
||||
self.device[0].dpp_pkex_stop()
|
||||
self.device[1].disconnect()
|
||||
self.device[1].dpp_pkex_stop()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.wpas.dpp_configurator_remove()
|
||||
self.wpas.clean_up()
|
||||
|
||||
self.wd = None
|
||||
self.wd_ns0 = None
|
||||
self.device = None
|
||||
self.wpas = None
|
||||
self.hapd = None
|
||||
self.rule_xchg_resp = None
|
||||
IWD.clear_storage()
|
||||
IWD.clear_storage('/tmp/ns0')
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
5
autotests/testDPP/ssidCCMP.psk
Normal file
5
autotests/testDPP/ssidCCMP.psk
Normal file
@ -0,0 +1,5 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
|
||||
[IPv4]
|
||||
SendHostname=true
|
9
autotests/testDPP/ssidHidden.conf
Normal file
9
autotests/testDPP/ssidHidden.conf
Normal file
@ -0,0 +1,9 @@
|
||||
hw_mode=g
|
||||
channel=6
|
||||
ssid=ssidHidden
|
||||
|
||||
wpa=1
|
||||
wpa_pairwise=TKIP
|
||||
wpa_passphrase=secret123
|
||||
|
||||
ignore_broadcast_ssid=1
|
5
autotests/testDPP/ssidHidden.psk
Normal file
5
autotests/testDPP/ssidHidden.psk
Normal file
@ -0,0 +1,5 @@
|
||||
[Security]
|
||||
Passphrase=secret123
|
||||
|
||||
[Settings]
|
||||
Hidden=true
|
107
autotests/testDPP/state_change_test.py
Normal file
107
autotests/testDPP/state_change_test.py
Normal file
@ -0,0 +1,107 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD, SharedCodeAgent, DeviceState
|
||||
from iwd import DeviceProvisioning
|
||||
from wpas import Wpas
|
||||
from hostapd import HostapdCLI
|
||||
from hwsim import Hwsim
|
||||
from config import ctx
|
||||
from time import time
|
||||
import os
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def auto_connect(self):
|
||||
IWD.copy_to_storage('ssidCCMP.psk')
|
||||
self.device.autoconnect = True
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_configurator_stops_on_disconnect(self):
|
||||
self.auto_connect()
|
||||
|
||||
self.device.dpp_start_configurator()
|
||||
|
||||
self.device.disconnect()
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
self.assertEqual(self.device._device_provisioning.started, False)
|
||||
|
||||
def test_enrollee_stops_on_connect(self):
|
||||
# Scan to get a list of networks
|
||||
self.device.scan()
|
||||
self.wd.wait_for_object_condition(self.device, 'obj.scanning == True')
|
||||
self.wd.wait_for_object_condition(self.device, 'obj.scanning == False')
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
network = self.device.get_ordered_network("ssidCCMP")
|
||||
network.network_object.connect()
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
self.assertEqual(self.device._device_provisioning.started, False)
|
||||
|
||||
def test_enrollee_disconnects_automatically(self):
|
||||
self.auto_connect()
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
condition = 'obj.state == DeviceState.disconnected'
|
||||
self.wd.wait_for_object_condition(self.device, condition)
|
||||
|
||||
def test_enrollee_autoconnect_stays_on(self):
|
||||
# Put in an autoconnecting state, no saved profile though
|
||||
self.device.autoconnect = True
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
# DPP should set autoconnect false, but then re-enable after it stops
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
|
||||
self.wd.wait_for_object_condition(self.device._device_provisioning, "obj.started == True")
|
||||
|
||||
# Stop DPP
|
||||
self.device.dpp_stop()
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == True")
|
||||
|
||||
def test_enrollee_autoconnect_stays_off(self):
|
||||
# Autoconnect should be off by default
|
||||
|
||||
self.device.dpp_start_enrollee()
|
||||
|
||||
# DPP should set autoconnect false, but stay off after it stops
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
|
||||
self.wd.wait_for_object_condition(self.device._device_provisioning, "obj.started == True")
|
||||
|
||||
# Stop DPP
|
||||
self.device.dpp_stop()
|
||||
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
|
||||
|
||||
def setUp(self):
|
||||
self.wd = IWD(True)
|
||||
self.device = self.wd.list_devices(1)[0]
|
||||
|
||||
def tearDown(self):
|
||||
self.wd.stop()
|
||||
self.wd = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
hapd = HostapdCLI(config="hostapd.conf")
|
||||
hapd.reload()
|
||||
|
||||
hapd.wait_for_event("AP-ENABLED")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
6
autotests/testDPP/wpas.conf
Normal file
6
autotests/testDPP/wpas.conf
Normal file
@ -0,0 +1,6 @@
|
||||
ctrl_interface=/tmp/rad1-p2p-wpas
|
||||
|
||||
update_config=0
|
||||
pmf=2
|
||||
dpp_config_processing=2
|
||||
p2p_disabled=1
|
@ -10,7 +10,6 @@ from iwd import DeviceState
|
||||
from iwd import NetworkType
|
||||
|
||||
from hostapd import HostapdCLI
|
||||
from hostapd import hostapd_map
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
@ -20,15 +19,9 @@ class Test(unittest.TestCase):
|
||||
devices = wd.list_devices(1)
|
||||
device = devices[0]
|
||||
|
||||
hostapd_if = list(hostapd_map.values())[0]
|
||||
hostapd = HostapdCLI(hostapd_if)
|
||||
hostapd = HostapdCLI(config='ssidOpen.conf')
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
ordered_network = device.get_ordered_network('ssidOpen')
|
||||
ordered_network = device.get_ordered_network('ssidOpen', full_scan=True)
|
||||
|
||||
ordered_network.network_object.connect()
|
||||
|
||||
|
@ -20,14 +20,6 @@ class Test(unittest.TestCase):
|
||||
|
||||
device = wd.list_devices(1)[0]
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
device.scan()
|
||||
|
||||
condition = 'not obj.scanning'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
wpa_net = device.get_ordered_network('ssidTKIP')
|
||||
self.assertEqual(wpa_net.type, NetworkType.psk)
|
||||
|
||||
@ -36,16 +28,16 @@ class Test(unittest.TestCase):
|
||||
|
||||
wpa_net.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(wpa_net.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
open_net = device.get_ordered_network('ssidOpen')
|
||||
self.assertEqual(open_net.type, NetworkType.open)
|
||||
|
||||
open_net.network_object.connect()
|
||||
|
||||
condition = 'obj.connected'
|
||||
wd.wait_for_object_condition(open_net.network_object, condition)
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
||||
condition = 'obj.state == DeviceState.connected'
|
||||
wd.wait_for_object_condition(device, condition)
|
||||
|
@ -1,6 +1,5 @@
|
||||
[SETUP]
|
||||
num_radios=3
|
||||
max_test_exec_interval_sec=40
|
||||
|
||||
[HOSTAPD]
|
||||
rad0=ssidTKIP.conf
|
||||
|
44
autotests/testEAD/connection_test.py
Normal file
44
autotests/testEAD/connection_test.py
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
from config import ctx
|
||||
|
||||
from ead import EAD
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_connection_success(self):
|
||||
env = os.environ.copy()
|
||||
env['STATE_DIRECTORY'] = '/tmp/ead'
|
||||
p = ctx.start_process(['ead', '-i', 'eth1', '-d'], env=env)
|
||||
|
||||
ead = EAD()
|
||||
|
||||
adapter = ead.list_adapters(1)[0]
|
||||
|
||||
condition = 'obj.connected == True'
|
||||
IWD._wait_for_object_condition(adapter, condition)
|
||||
|
||||
condition = 'obj.authenticated == True'
|
||||
IWD._wait_for_object_condition(adapter, condition)
|
||||
|
||||
ctx.stop_process(p)
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.mkdir('/tmp/ead')
|
||||
|
||||
IWD.copy_to_storage('default.8021x', storage_dir='/tmp/ead')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
IWD.clear_storage(storage_dir='/tmp/ead')
|
||||
|
||||
shutil.rmtree('/tmp/ead')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
@ -1,6 +1,6 @@
|
||||
[Security]
|
||||
EAP-Method=MSCHAPV2
|
||||
EAP-Identity=domain\\User
|
||||
EAP-Identity=mschapv2@example.com
|
||||
EAP-Password=Password
|
||||
|
||||
[Settings]
|
6
autotests/testEAD/hw.conf
Normal file
6
autotests/testEAD/hw.conf
Normal file
@ -0,0 +1,6 @@
|
||||
[SETUP]
|
||||
num_radios=0
|
||||
start_iwd=0
|
||||
|
||||
[HOSTAPD]
|
||||
radius_server=wired.conf
|
17
autotests/testEAD/wired.conf
Normal file
17
autotests/testEAD/wired.conf
Normal file
@ -0,0 +1,17 @@
|
||||
interface=eth0
|
||||
driver=wired
|
||||
logger_stdout=-1
|
||||
logger_stdout_level=1
|
||||
|
||||
ieee8021x=1
|
||||
eap_reauth_period=3600
|
||||
|
||||
use_pae_group_addr=1
|
||||
|
||||
nas_identifier=ap.example.com
|
||||
|
||||
radius_server_clients=/tmp/certs/radius-clients.text
|
||||
radius_server_auth_port=1812
|
||||
|
||||
eap_user_file=/tmp/secrets/eap-user.text
|
||||
eap_server=1
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user