Compare commits
2160 Commits
fdroid
...
1.08c-r1-n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18f989fae4 | ||
|
|
1ecfe83706 | ||
|
|
ad4b719f3f | ||
|
|
24b690d19b | ||
|
|
57308b476d | ||
|
|
90ae1bd7d7 | ||
|
|
67e40bc284 | ||
|
|
58a0f4d536 | ||
|
|
174c440813 | ||
|
|
1479ecf03f | ||
|
|
c8ac6ec972 | ||
|
|
b4e5b0107a | ||
|
|
8b072a3c3f | ||
|
|
7d98ea39e9 | ||
|
|
170a86f433 | ||
|
|
7d4c8d3735 | ||
|
|
2d23f579e9 | ||
|
|
9586e7f3ae | ||
|
|
7bda4095a6 | ||
|
|
54dc7f46fb | ||
|
|
87ddfc92a3 | ||
|
|
df98ebeb3b | ||
|
|
bbf3b40df8 | ||
|
|
a01e70012e | ||
|
|
48517665e2 | ||
|
|
387998a260 | ||
|
|
ef194fe70c | ||
|
|
c74c718021 | ||
|
|
c8f29bd424 | ||
|
|
64e26fe372 | ||
|
|
da213a1172 | ||
|
|
0e19dc9d17 | ||
|
|
27f9625d4e | ||
|
|
1a02741f95 | ||
|
|
35c69fcb3a | ||
|
|
561ff54afd | ||
|
|
f50c6ea3b9 | ||
|
|
40f6f5a72e | ||
|
|
700bedfe81 | ||
|
|
2b50407127 | ||
|
|
ba68402479 | ||
|
|
7b4c75aa90 | ||
|
|
a6c9e7a64a | ||
|
|
4c0c011714 | ||
|
|
4ba2f648df | ||
|
|
d8c2966d87 | ||
|
|
5a608fad93 | ||
|
|
9790d6ff69 | ||
|
|
f24e23d417 | ||
|
|
2eea4c163c | ||
|
|
541106f77b | ||
|
|
2231a9638f | ||
|
|
e01f910869 | ||
|
|
4f511655b4 | ||
|
|
081d3ed4ff | ||
|
|
46703c5ed6 | ||
|
|
db2ad06e7a | ||
|
|
328998be57 | ||
|
|
cb6dfa1521 | ||
|
|
f54f127fd4 | ||
|
|
00bc1e0998 | ||
|
|
8e0cad21d7 | ||
|
|
1df873540c | ||
|
|
454f7acb00 | ||
|
|
e848a5e4d8 | ||
|
|
5fa51ca833 | ||
|
|
28ee65da9a | ||
|
|
f2eeab8609 | ||
|
|
37b529a1d8 | ||
|
|
31f2abb3a8 | ||
|
|
10b6e0f35e | ||
|
|
f1d9655ea2 | ||
|
|
793845c92e | ||
|
|
52c8de4b5c | ||
|
|
3b3b0d7388 | ||
|
|
2bf4565c83 | ||
|
|
ee95bf3bcc | ||
|
|
f53f7d0fee | ||
|
|
8bc6e4c33e | ||
|
|
4b78fab2ac | ||
|
|
40f8b6da71 | ||
|
|
f92cb3d3ea | ||
|
|
1bc2ba2284 | ||
|
|
8ac84cb7c1 | ||
|
|
385d1b0979 | ||
|
|
01210c401d | ||
|
|
d48f54c086 | ||
|
|
7a800928e2 | ||
|
|
a893150c9e | ||
|
|
50a1092a65 | ||
|
|
555109c243 | ||
|
|
7409246425 | ||
|
|
feb38f52ea | ||
|
|
69ac2d1303 | ||
|
|
023a026a85 | ||
|
|
5198476d06 | ||
|
|
bc614ade20 | ||
|
|
86cf3a9630 | ||
|
|
aa57120c9c | ||
|
|
7ee0b78300 | ||
|
|
9ba4d95789 | ||
|
|
a221a6bfc3 | ||
|
|
0fea740a7f | ||
|
|
7755116473 | ||
|
|
244f64fc4d | ||
|
|
c4d105c02f | ||
|
|
c25bfb8ade | ||
|
|
e49a1c3d6e | ||
|
|
d81502e4b5 | ||
|
|
3763374f70 | ||
|
|
b043006a74 | ||
|
|
6897bedd7f | ||
|
|
b7fc2c4d1c | ||
|
|
4012c777a8 | ||
|
|
0ca0dd0ea5 | ||
|
|
a443507719 | ||
|
|
03714c70e0 | ||
|
|
6335d642ec | ||
|
|
48eb8c60ea | ||
|
|
065acfcb35 | ||
|
|
9b0d63b853 | ||
|
|
e6b93af59a | ||
|
|
024de21188 | ||
|
|
8ccab7fd78 | ||
|
|
7165f455a4 | ||
|
|
ff5ada3195 | ||
|
|
cae5f339c9 | ||
|
|
2b7b618302 | ||
|
|
5ec91691c8 | ||
|
|
690f456482 | ||
|
|
fa7e3e229e | ||
|
|
08a9af6b80 | ||
|
|
4322d3c09c | ||
|
|
0ba83b48fd | ||
|
|
dbdb98280a | ||
|
|
12641a754d | ||
|
|
882297877b | ||
|
|
bef0bd5226 | ||
|
|
e20da59b7f | ||
|
|
97682034a0 | ||
|
|
4326aa88e9 | ||
|
|
e60a5e6461 | ||
|
|
258673062a | ||
|
|
9b9ee82aea | ||
|
|
fb6f1c3a6e | ||
|
|
e8a2fe42e1 | ||
|
|
7dd422b0ce | ||
|
|
5820def039 | ||
|
|
7abfbd3e3b | ||
|
|
9b9ea2ed78 | ||
|
|
7abcff24dc | ||
|
|
c1b35a9a7e | ||
|
|
eeb9cc2324 | ||
|
|
db564dda61 | ||
|
|
1dc89389db | ||
|
|
74eb2c64e7 | ||
|
|
04f53d607b | ||
|
|
ee1d0bd61b | ||
|
|
3f1a54a962 | ||
|
|
670a50fdce | ||
|
|
b1c89d5dbc | ||
|
|
5afb5640c4 | ||
|
|
799d9c0fd7 | ||
|
|
4e833cd382 | ||
|
|
e933c29715 | ||
|
|
0bb78b5b17 | ||
|
|
12daa78948 | ||
|
|
8d563a9adf | ||
|
|
ae3295ce04 | ||
|
|
ca4221b7fb | ||
|
|
816cdd3156 | ||
|
|
eb13676193 | ||
|
|
7111ef5c8e | ||
|
|
86a40a8f3b | ||
|
|
268ed3990c | ||
|
|
bcde5f487d | ||
|
|
b749728946 | ||
|
|
7b6ac879db | ||
|
|
5633403f63 | ||
|
|
9f5ffca429 | ||
|
|
4a71208629 | ||
|
|
8d7d960173 | ||
|
|
5a69cd878d | ||
|
|
e81b1d6928 | ||
|
|
c22bace184 | ||
|
|
1dfaba8dad | ||
|
|
08c5403c00 | ||
|
|
8ac4ef3ce8 | ||
|
|
b6488af6fe | ||
|
|
65597bba5f | ||
|
|
88bdeebc93 | ||
|
|
9eb73c745c | ||
|
|
410f5f9437 | ||
|
|
390f20af79 | ||
|
|
d0954ec83d | ||
|
|
0718a7b5dd | ||
|
|
bc9d80f369 | ||
|
|
f94491526f | ||
|
|
c60ab35ad3 | ||
|
|
2227221725 | ||
|
|
90646f2551 | ||
|
|
8536c26828 | ||
|
|
a02e7a473f | ||
|
|
80d2f8cebd | ||
|
|
94a79b3c11 | ||
|
|
13e530d173 | ||
|
|
832ce4996a | ||
|
|
5fefd53bab | ||
|
|
646e203ea5 | ||
|
|
35162c6205 | ||
|
|
6ef20e2e07 | ||
|
|
a9724638af | ||
|
|
54677a41a4 | ||
|
|
c806130741 | ||
|
|
8b79022e48 | ||
|
|
1271596c8c | ||
|
|
e82b7e397e | ||
|
|
8813753a7e | ||
|
|
4da61a1f76 | ||
|
|
eb7d63a49a | ||
|
|
22dc95f8d9 | ||
|
|
ffa306f239 | ||
|
|
3cd8bf12ea | ||
|
|
ec51d0b52c | ||
|
|
0622c30e78 | ||
|
|
35e8338aca | ||
|
|
c5a3312bb1 | ||
|
|
1af865ae4e | ||
|
|
542584a531 | ||
|
|
6973546803 | ||
|
|
875488775b | ||
|
|
1c617ee172 | ||
|
|
ff86ef2114 | ||
|
|
8386ffc6aa | ||
|
|
5e65563e24 | ||
|
|
a26fd7df82 | ||
|
|
0d659a4170 | ||
|
|
5b14afce8b | ||
|
|
4856c31476 | ||
|
|
e07a33bb3f | ||
|
|
2d5ae5d24f | ||
|
|
2f0da0ae55 | ||
|
|
b33ab579bc | ||
|
|
94c8cb4c33 | ||
|
|
bc1143cc29 | ||
|
|
9e357e63fb | ||
|
|
f07a8fc831 | ||
|
|
1306ae91e0 | ||
|
|
11f7e6d01f | ||
|
|
c815ee5a54 | ||
|
|
cd92c7a135 | ||
|
|
6dcdeb1d81 | ||
|
|
05b6eb8d47 | ||
|
|
6f12c57780 | ||
|
|
18c806bb68 | ||
|
|
17b984dd75 | ||
|
|
ac889e9b1f | ||
|
|
e043c7aa85 | ||
|
|
c4a9d0b7b9 | ||
|
|
3902e35738 | ||
|
|
627684a806 | ||
|
|
b16e95a527 | ||
|
|
8fcf608515 | ||
|
|
2d86b7422d | ||
|
|
3c7cec40a2 | ||
|
|
c93515a45a | ||
|
|
73e9631459 | ||
|
|
e922d01ee7 | ||
|
|
d77e45ee41 | ||
|
|
b3774ea1a8 | ||
|
|
35324c4f59 | ||
|
|
81f3b354b4 | ||
|
|
3c7bc76d13 | ||
|
|
fde262e6a2 | ||
|
|
9dcefc79ac | ||
|
|
019a20e983 | ||
|
|
b7655ad5ee | ||
|
|
6e3d923ba5 | ||
|
|
c9cd62eff9 | ||
|
|
ade983ae6c | ||
|
|
5dd91b96c8 | ||
|
|
f4f4a55aba | ||
|
|
af76080539 | ||
|
|
a76c394f1a | ||
|
|
040f229ec1 | ||
|
|
617d4e0b99 | ||
|
|
747f89aa9e | ||
|
|
0b766062fd | ||
|
|
624a4430ca | ||
|
|
04377b03af | ||
|
|
cbcbdacca1 | ||
|
|
1cf6481847 | ||
|
|
902ae521ad | ||
|
|
dd679c295d | ||
|
|
f71b44c329 | ||
|
|
d0f13a7aaf | ||
|
|
7b071e8bf9 | ||
|
|
c24b592ed1 | ||
|
|
3faabacfa6 | ||
|
|
0587398f86 | ||
|
|
b7b4bde51d | ||
|
|
160dd70412 | ||
|
|
e354bbd647 | ||
|
|
b3e67cf8d6 | ||
|
|
b9c2dd83a9 | ||
|
|
0661598244 | ||
|
|
4d579fabdf | ||
|
|
6f77fac4b2 | ||
|
|
cd9bd03c47 | ||
|
|
932cb97e89 | ||
|
|
bedf92595c | ||
|
|
316668304e | ||
|
|
3da270c053 | ||
|
|
0d28047dfa | ||
|
|
ee4677b70e | ||
|
|
f8462fcdbc | ||
|
|
2afb269268 | ||
|
|
5fa13c6316 | ||
|
|
1c4c7243ed | ||
|
|
c9e6a521dc | ||
|
|
f2ecb9bc22 | ||
|
|
d60a20f2a5 | ||
|
|
c32a118157 | ||
|
|
07e6e440f2 | ||
|
|
4d6db6e394 | ||
|
|
9fa0f541ae | ||
|
|
73c5bab70c | ||
|
|
929fb69beb | ||
|
|
e52e8c76a4 | ||
|
|
1bf294c6fe | ||
|
|
d172aca74d | ||
|
|
66a62df64a | ||
|
|
902fd70071 | ||
|
|
b7b938fef3 | ||
|
|
6a6437fefb | ||
|
|
b90e959e48 | ||
|
|
abeefab726 | ||
|
|
1bea5cd1ef | ||
|
|
b4e22849bd | ||
|
|
07adea2465 | ||
|
|
e7fdb9239e | ||
|
|
b70adfbc09 | ||
|
|
1474549886 | ||
|
|
bfdf731fdd | ||
|
|
d3ced0cdf3 | ||
|
|
5fc2f94688 | ||
|
|
5aab4c98cf | ||
|
|
02073c01b6 | ||
|
|
d14d287c3a | ||
|
|
862083c0be | ||
|
|
1f9412c5cf | ||
|
|
dd18e505a6 | ||
|
|
7e2db583a0 | ||
|
|
8d33ced838 | ||
|
|
f83e5dcc6e | ||
|
|
eeaa9f3280 | ||
|
|
1fad137c1e | ||
|
|
b88bca35ab | ||
|
|
e9b9d0a781 | ||
|
|
d30c532a88 | ||
|
|
b4dbc4bc08 | ||
|
|
85d852cc54 | ||
|
|
484a4732f8 | ||
|
|
0649de8cc6 | ||
|
|
69f8481cf1 | ||
|
|
1625e5e3ac | ||
|
|
be1cc06a4b | ||
|
|
adc45d8151 | ||
|
|
965a79f029 | ||
|
|
7c72f781a2 | ||
|
|
b9a15471ef | ||
|
|
e667f4e89c | ||
|
|
349f6c7c90 | ||
|
|
e688639f47 | ||
|
|
8fbeb5c409 | ||
|
|
9d34dfe23e | ||
|
|
01ea54932c | ||
|
|
ad0ac93bd3 | ||
|
|
dc9d830d16 | ||
|
|
cab797ee1e | ||
|
|
e1416b984e | ||
|
|
ff95c32c2d | ||
|
|
2b2deb291a | ||
|
|
e51999ea1f | ||
|
|
7ba17b8552 | ||
|
|
406723fab0 | ||
|
|
e1ea3a1502 | ||
|
|
3f101c070d | ||
|
|
dd49cc9324 | ||
|
|
d607151734 | ||
|
|
9b780cb216 | ||
|
|
bd4c01c630 | ||
|
|
7f4a151a63 | ||
|
|
d6174dc69e | ||
|
|
61cd5775a2 | ||
|
|
69b4828add | ||
|
|
ca09103e98 | ||
|
|
efadf03238 | ||
|
|
11727b80f2 | ||
|
|
e57b7179e3 | ||
|
|
1c720ddb7d | ||
|
|
d19396e542 | ||
|
|
ae436249b7 | ||
|
|
4518a87f24 | ||
|
|
4cc0359c4d | ||
|
|
ec122e078b | ||
|
|
bbc0ba7b3c | ||
|
|
c4ba08db15 | ||
|
|
75ab8d4eed | ||
|
|
d91cfe7cb0 | ||
|
|
037c7d35d7 | ||
|
|
6fd0ab790c | ||
|
|
1a578ca68e | ||
|
|
60ea6cef08 | ||
|
|
d795dbffee | ||
|
|
a5163df44c | ||
|
|
9fd62088ab | ||
|
|
1f162c85d8 | ||
|
|
9ac6a6a770 | ||
|
|
78de922261 | ||
|
|
76c839b091 | ||
|
|
b5294d6d25 | ||
|
|
764963b087 | ||
|
|
0f7ce379d6 | ||
|
|
1d066f13ba | ||
|
|
1c9450ca10 | ||
|
|
4f4f9405fe | ||
|
|
284e5e472f | ||
|
|
14c1026ad1 | ||
|
|
a6f69cc433 | ||
|
|
dfb50586aa | ||
|
|
4f1358ffc7 | ||
|
|
1d12b1c925 | ||
|
|
de8202554a | ||
|
|
80655e1ca7 | ||
|
|
4148399f6d | ||
|
|
0bcba06ebf | ||
|
|
c2cc965c21 | ||
|
|
dd0c950474 | ||
|
|
b7c8baacc9 | ||
|
|
5e2fa65a4c | ||
|
|
52676eb113 | ||
|
|
bf5ca8908e | ||
|
|
acbe62d6ed | ||
|
|
79ec921abc | ||
|
|
65bd88af72 | ||
|
|
0273b4d2bb | ||
|
|
63ef21287a | ||
|
|
1be320b755 | ||
|
|
abcad958ab | ||
|
|
35b4350455 | ||
|
|
8f1251e59b | ||
|
|
0400ab3c53 | ||
|
|
2f3d614ac0 | ||
|
|
fd90b10444 | ||
|
|
7f5ec35ada | ||
|
|
b7f7b0d470 | ||
|
|
97fb35db90 | ||
|
|
69abcd0786 | ||
|
|
d697b93f6a | ||
|
|
2290b35317 | ||
|
|
d838ff0cd9 | ||
|
|
a2aa9d61a9 | ||
|
|
056d791ae9 | ||
|
|
d3acacb20b | ||
|
|
bb74305b26 | ||
|
|
32549c9eff | ||
|
|
83b5aa7d7b | ||
|
|
640a2c7e88 | ||
|
|
31aad963d6 | ||
|
|
326f4282d7 | ||
|
|
e5b3cf3db6 | ||
|
|
ca3e4a5135 | ||
|
|
c1607bbfb3 | ||
|
|
0639201b4c | ||
|
|
b5fe3b8ce4 | ||
|
|
2362efe5fc | ||
|
|
308d8889e4 | ||
|
|
5e4ea21377 | ||
|
|
45489ad600 | ||
|
|
683cde5a8b | ||
|
|
8a9c781de2 | ||
|
|
6812998c8d | ||
|
|
89fda1eee5 | ||
|
|
0cf0170144 | ||
|
|
cb79c8b1ff | ||
|
|
658dd6a0ec | ||
|
|
e6049eca2c | ||
|
|
f2ca846093 | ||
|
|
38cee50f34 | ||
|
|
d45fd99235 | ||
|
|
05eea4aae1 | ||
|
|
efcaa36325 | ||
|
|
905efd0454 | ||
|
|
3ce1c04cf2 | ||
|
|
cb979f8975 | ||
|
|
cc8cea0049 | ||
|
|
a94e6143e1 | ||
|
|
699c97eaf9 | ||
|
|
10d4ec9bba | ||
|
|
e1f1b10f56 | ||
|
|
cfc09b8f3b | ||
|
|
4c1571ff2d | ||
|
|
5aea520cd1 | ||
|
|
00294f1aad | ||
|
|
e0fd45f838 | ||
|
|
a7e8363ed7 | ||
|
|
cb144c5bcf | ||
|
|
57a9570d34 | ||
|
|
28162762ef | ||
|
|
b9e745a7fb | ||
|
|
e08e59c226 | ||
|
|
3d6b02a016 | ||
|
|
b18a7b1a23 | ||
|
|
8595674eb0 | ||
|
|
23fd50df21 | ||
|
|
af80997ed4 | ||
|
|
7e3ac2959e | ||
|
|
78124c505e | ||
|
|
589b3f9540 | ||
|
|
bd505d858a | ||
|
|
308909f4eb | ||
|
|
9cfcda2938 | ||
|
|
fa4887ffef | ||
|
|
f70f26149e | ||
|
|
3cc904dc18 | ||
|
|
16c6346797 | ||
|
|
01b8f92d43 | ||
|
|
082f0a928f | ||
|
|
2ec4d6e006 | ||
|
|
7bd46b2182 | ||
|
|
2e9ba3bcfc | ||
|
|
551e374786 | ||
|
|
4366858b73 | ||
|
|
29b7c24312 | ||
|
|
3c5894db5d | ||
|
|
1d652272d7 | ||
|
|
d8c7f479ae | ||
|
|
3a0cb3fc72 | ||
|
|
65f1ec8bf4 | ||
|
|
0421e16910 | ||
|
|
2489d8e95f | ||
|
|
ac46ac7372 | ||
|
|
3ed3c90dae | ||
|
|
a45530393e | ||
|
|
a3e4b61216 | ||
|
|
c4939dd231 | ||
|
|
c20303ebf1 | ||
|
|
d7627899ea | ||
|
|
87f82fb23f | ||
|
|
f866cdd4aa | ||
|
|
a9fc44a4a2 | ||
|
|
ee00e66e4f | ||
|
|
cfa97759da | ||
|
|
cf26b9fd58 | ||
|
|
6a5ddcc06d | ||
|
|
592667a845 | ||
|
|
8f6e3db71d | ||
|
|
70502414c3 | ||
|
|
c9189d37f5 | ||
|
|
9e62e32e0a | ||
|
|
f592126d63 | ||
|
|
c26b360bcc | ||
|
|
33c844bc97 | ||
|
|
23a4a90afa | ||
|
|
643d8cc644 | ||
|
|
10d9f73982 | ||
|
|
a8f3e079a4 | ||
|
|
8ad258d6b3 | ||
|
|
9a37d61892 | ||
|
|
30b5443ee1 | ||
|
|
82885da6aa | ||
|
|
b498b8b437 | ||
|
|
7109fe405a | ||
|
|
0611cf2d89 | ||
|
|
2f5a1770c4 | ||
|
|
f7ee43fc89 | ||
|
|
1457bdf69b | ||
|
|
db4a1a918e | ||
|
|
66fafc25c8 | ||
|
|
b83cd39754 | ||
|
|
3010643dc1 | ||
|
|
823d6467b9 | ||
|
|
9ebdf9c22c | ||
|
|
0e4421ddc2 | ||
|
|
3fbdf836cd | ||
|
|
124c07efa3 | ||
|
|
5d8cb69938 | ||
|
|
5e2f19b73e | ||
|
|
6e5f2dc910 | ||
|
|
11119c8aa6 | ||
|
|
b53ebafa9b | ||
|
|
53bb74b837 | ||
|
|
8b56ace8d1 | ||
|
|
524b8414d5 | ||
|
|
88bfa05921 | ||
|
|
4115463922 | ||
|
|
83ab0b2ee4 | ||
|
|
5bacadbca0 | ||
|
|
005930c8a0 | ||
|
|
a16e6ff00b | ||
|
|
aef334ec61 | ||
|
|
7917a59757 | ||
|
|
954fc0f5fb | ||
|
|
f9578493b4 | ||
|
|
f49a82745f | ||
|
|
84bd67bdea | ||
|
|
e32bb0a573 | ||
|
|
8f5d4be864 | ||
|
|
e99c425120 | ||
|
|
369379df2f | ||
|
|
9a35575741 | ||
|
|
455ca956ab | ||
|
|
b87df11941 | ||
|
|
beb9e2241b | ||
|
|
71c78d04c6 | ||
|
|
9a5b18d842 | ||
|
|
702baf3614 | ||
|
|
c8b7a8d51e | ||
|
|
95f1d2ca14 | ||
|
|
d4673abd01 | ||
|
|
225f0ab437 | ||
|
|
7a36a53a4b | ||
|
|
d9a3469e19 | ||
|
|
46a5202edb | ||
|
|
e28b55df9d | ||
|
|
91a8d6ac6c | ||
|
|
151d7bb5ca | ||
|
|
7432f294b2 | ||
|
|
6ac2bd3c1f | ||
|
|
3ad238e7e8 | ||
|
|
59230fe57a | ||
|
|
43e1e62b41 | ||
|
|
afb4dd5ce9 | ||
|
|
f2b861c369 | ||
|
|
4080966331 | ||
|
|
54b4662322 | ||
|
|
26e8e2afc9 | ||
|
|
9aa705f3e7 | ||
|
|
cb49c90b4a | ||
|
|
84b2b83901 | ||
|
|
abebc9d3aa | ||
|
|
19a6044044 | ||
|
|
6a396561a8 | ||
|
|
025b822046 | ||
|
|
1f95c684d8 | ||
|
|
7116370908 | ||
|
|
caca6237b8 | ||
|
|
c5ddf1644d | ||
|
|
7147874d79 | ||
|
|
91bcbcf47d | ||
|
|
e9ecff62a3 | ||
|
|
69e081a279 | ||
|
|
51ce9847e2 | ||
|
|
988cc8bd3d | ||
|
|
9b34ddfd9d | ||
|
|
bd158984b7 | ||
|
|
ba76baf6ce | ||
|
|
19cf36c1e6 | ||
|
|
2bee860748 | ||
|
|
edcbfeca1c | ||
|
|
db7a629e7d | ||
|
|
213ff373a9 | ||
|
|
13fe371b73 | ||
|
|
42e8c28320 | ||
|
|
cefeff50c9 | ||
|
|
d3bb247b65 | ||
|
|
6a7097a70f | ||
|
|
c00ba4ad67 | ||
|
|
63f3639196 | ||
|
|
5a02b65b66 | ||
|
|
daf0dfa761 | ||
|
|
9aaf0ff08d | ||
|
|
afac7406d7 | ||
|
|
6ae7c6e7ab | ||
|
|
16e8b01bcc | ||
|
|
ffd37f3658 | ||
|
|
f6d18b18b9 | ||
|
|
2061ea8e18 | ||
|
|
f9ff03d85d | ||
|
|
4b8a8e83d2 | ||
|
|
47466e7322 | ||
|
|
92be6e1b56 | ||
|
|
f763840c14 | ||
|
|
09fed92c4f | ||
|
|
0cb4e1db64 | ||
|
|
66c7afc8db | ||
|
|
7482006851 | ||
|
|
45f17d81e7 | ||
|
|
dc2e557d2c | ||
|
|
6d4630e2d9 | ||
|
|
fc96bc6b4e | ||
|
|
c13986a88f | ||
|
|
6eb7f15045 | ||
|
|
61346438eb | ||
|
|
47e520c4b0 | ||
|
|
bcdae3d3e7 | ||
|
|
a17aafeabd | ||
|
|
286c27f7f8 | ||
|
|
a44d08c352 | ||
|
|
aeb396f000 | ||
|
|
6c8dcbadb4 | ||
|
|
0071502c83 | ||
|
|
eb47e19df7 | ||
|
|
8ff2d10697 | ||
|
|
e1bfb4f7c2 | ||
|
|
8ae699b751 | ||
|
|
6381d323da | ||
|
|
8e9ec81591 | ||
|
|
ad847e0114 | ||
|
|
d44dd3e738 | ||
|
|
6b6a3db89a | ||
|
|
cecdb4e76d | ||
|
|
c984497454 | ||
|
|
5a617ad824 | ||
|
|
7f83846937 | ||
|
|
19de6e7d52 | ||
|
|
12d2f961cf | ||
|
|
8fe549fc55 | ||
|
|
a99e55e884 | ||
|
|
e361f770e8 | ||
|
|
a27e13bcb3 | ||
|
|
03cf25766b | ||
|
|
9ce42a8e98 | ||
|
|
c03a5b08fd | ||
|
|
9b5853d3f9 | ||
|
|
8a3735dc01 | ||
|
|
aae662ab5e | ||
|
|
d051f02a43 | ||
|
|
2e4cf0dfc6 | ||
|
|
fc76e2042d | ||
|
|
d7f462d21f | ||
|
|
2b61598c21 | ||
|
|
799dc3a38f | ||
|
|
9c76dce17d | ||
|
|
28ac79bbe5 | ||
|
|
bdf825a2b5 | ||
|
|
37d03a2735 | ||
|
|
e8fde4ad0a | ||
|
|
1aa29a82fb | ||
|
|
60f292a5a7 | ||
|
|
1f956ab1db | ||
|
|
df39fa5545 | ||
|
|
dd0800f543 | ||
|
|
8b3c6eb1ff | ||
|
|
88b35c0051 | ||
|
|
2f83169ddd | ||
|
|
ce4b301f5c | ||
|
|
433f46b8f1 | ||
|
|
03eb52dc14 | ||
|
|
9d785679c5 | ||
|
|
699a4f96b0 | ||
|
|
afd6f0f4d6 | ||
|
|
eaadc45fce | ||
|
|
e9852a6d98 | ||
|
|
e1b3e769d8 | ||
|
|
501535a9a4 | ||
|
|
fb8608e467 | ||
|
|
e9eb8c250a | ||
|
|
eaa5a9d375 | ||
|
|
d28834591a | ||
|
|
49aa0a20cd | ||
|
|
8d611bd6c6 | ||
|
|
bfe8650ec9 | ||
|
|
fd52a5f388 | ||
|
|
6b8c5ea1fb | ||
|
|
8347feceff | ||
|
|
626b7fc6b3 | ||
|
|
1701c9142b | ||
|
|
245794ed53 | ||
|
|
24aba30fa8 | ||
|
|
6338472e73 | ||
|
|
580b46a394 | ||
|
|
ea1a34353c | ||
|
|
f9790e0e3e | ||
|
|
540c4a72a2 | ||
|
|
bc905304e7 | ||
|
|
ad04309f9d | ||
|
|
684ffb8525 | ||
|
|
049764fe67 | ||
|
|
a048c45b32 | ||
|
|
60c78642b1 | ||
|
|
5c7f551922 | ||
|
|
ceac7841a0 | ||
|
|
a29fc9d3cc | ||
|
|
f5dbc85450 | ||
|
|
6a86a6906c | ||
|
|
2b4bd1a79d | ||
|
|
2b2ce4eb29 | ||
|
|
6ac875aeb5 | ||
|
|
f43c6d3899 | ||
|
|
3f240868d0 | ||
|
|
5ccea973ee | ||
|
|
c1d59d9203 | ||
|
|
c6d3eb7131 | ||
|
|
f462bbe98b | ||
|
|
c6be5fcf84 | ||
|
|
023d9e194f | ||
|
|
78ad964481 | ||
|
|
9c9a8277a9 | ||
|
|
3f414ded5b | ||
|
|
5906824ffc | ||
|
|
737c87bdf8 | ||
|
|
bb27734a07 | ||
|
|
a9e6880add | ||
|
|
a1c3bf19ae | ||
|
|
0dc86e8662 | ||
|
|
bddc731390 | ||
|
|
2521aa2621 | ||
|
|
23af6f3031 | ||
|
|
89ac5af115 | ||
|
|
1f1ac04640 | ||
|
|
67d2eeaaff | ||
|
|
0788af941e | ||
|
|
484cea229c | ||
|
|
827a680f81 | ||
|
|
8b5c170409 | ||
|
|
9ec76c2738 | ||
|
|
ea9539ad0a | ||
|
|
03f4040c09 | ||
|
|
869f5d35bd | ||
|
|
01ac1c601f | ||
|
|
22f3f5ce59 | ||
|
|
0b430c90f4 | ||
|
|
080483b2d0 | ||
|
|
2da645f25b | ||
|
|
3ff6c35e35 | ||
|
|
5f3fb52833 | ||
|
|
6117053dd7 | ||
|
|
c3a1faffca | ||
|
|
5d85fdda46 | ||
|
|
907705b657 | ||
|
|
22e460d7bf | ||
|
|
3a81ebfcd9 | ||
|
|
ec92225e50 | ||
|
|
5163d472b3 | ||
|
|
069a2d287c | ||
|
|
01b8469fbb | ||
|
|
421a590514 | ||
|
|
a0a494e724 | ||
|
|
3f6f0b7430 | ||
|
|
b8d161ffee | ||
|
|
e27ff98517 | ||
|
|
4c2c6bbb54 | ||
|
|
5de92719f8 | ||
|
|
34b9d71cbf | ||
|
|
57e9253270 | ||
|
|
99d0ecfd59 | ||
|
|
706debfa33 | ||
|
|
db26fb6f39 | ||
|
|
57e36fb728 | ||
|
|
7c49eeca97 | ||
|
|
8d065255d6 | ||
|
|
a630543ecc | ||
|
|
989e397ee2 | ||
|
|
f99843737f | ||
|
|
5197111a3a | ||
|
|
d12339bb50 | ||
|
|
e166e9f754 | ||
|
|
1d5bca81da | ||
|
|
56891d6183 | ||
|
|
d0f1882995 | ||
|
|
b1b67807ac | ||
|
|
265c67c91c | ||
|
|
7c55c50b4c | ||
|
|
a42b74b614 | ||
|
|
262b931a1e | ||
|
|
3f1db5aa56 | ||
|
|
95ce6878e6 | ||
|
|
9f6fea7038 | ||
|
|
28eaa2ee7f | ||
|
|
c35cf56d8a | ||
|
|
0526c58913 | ||
|
|
1f20c18ad6 | ||
|
|
4b56eca5e2 | ||
|
|
d14702494e | ||
|
|
f2bda0f2d1 | ||
|
|
5f90628d2d | ||
|
|
409c3eec55 | ||
|
|
2a7ea24d17 | ||
|
|
f81a398f4b | ||
|
|
7a94f83019 | ||
|
|
134234da12 | ||
|
|
7354c8933c | ||
|
|
0565a83085 | ||
|
|
eab79eaac2 | ||
|
|
1007f7ee6b | ||
|
|
ce008843e2 | ||
|
|
ea5ae50813 | ||
|
|
0970f0659a | ||
|
|
ef2123422c | ||
|
|
6d82642176 | ||
|
|
f9c22574a7 | ||
|
|
3fde6af2a2 | ||
|
|
5322468819 | ||
|
|
0ce77a2729 | ||
|
|
e50cb41d1f | ||
|
|
428c360abf | ||
|
|
b89f3906e9 | ||
|
|
c3898245ce | ||
|
|
f15748b4e9 | ||
|
|
d11c871526 | ||
|
|
6944d842c3 | ||
|
|
183087b441 | ||
|
|
5e081805f1 | ||
|
|
e1addd1485 | ||
|
|
801f13c2d3 | ||
|
|
6dcb22dfc2 | ||
|
|
e5dbd86eb3 | ||
|
|
1706891be4 | ||
|
|
11323c0206 | ||
|
|
c36d252159 | ||
|
|
7d1eeb1e34 | ||
|
|
e081a6aa2c | ||
|
|
014f238f6c | ||
|
|
9482b37672 | ||
|
|
69c5601de4 | ||
|
|
96c717f748 | ||
|
|
856ba36a20 | ||
|
|
396cf51794 | ||
|
|
8138790396 | ||
|
|
e698468c39 | ||
|
|
da005a35bf | ||
|
|
9b62f28e93 | ||
|
|
5adc738c03 | ||
|
|
d784394ea9 | ||
|
|
b1cbb7893c | ||
|
|
51b2049429 | ||
|
|
84c8af7357 | ||
|
|
69cbda8a39 | ||
|
|
48f351ba0d | ||
|
|
0a7fac77ff | ||
|
|
ff336b40ae | ||
|
|
86a8da3ef3 | ||
|
|
a72b681205 | ||
|
|
3c75a4a012 | ||
|
|
f9fc4b9a06 | ||
|
|
6869f940ac | ||
|
|
79f0f90f3e | ||
|
|
1119610a10 | ||
|
|
90fe3f04c0 | ||
|
|
aca0aef285 | ||
|
|
8134b73902 | ||
|
|
57414cd0b8 | ||
|
|
6792eb53f0 | ||
|
|
a6d4814980 | ||
|
|
3ef0afa6bc | ||
|
|
942be17e61 | ||
|
|
37e8f14e3b | ||
|
|
64ca771c51 | ||
|
|
df2c2cd827 | ||
|
|
4b692e4697 | ||
|
|
a0fa5ff4c2 | ||
|
|
32df0ae8fe | ||
|
|
73b9bcac7a | ||
|
|
11f606631c | ||
|
|
9f696441e3 | ||
|
|
118d18613f | ||
|
|
a39bc9b7f7 | ||
|
|
e0e17359c9 | ||
|
|
5ab25b0bc8 | ||
|
|
686e7eb6c1 | ||
|
|
c3ba8662b9 | ||
|
|
b7e23fd046 | ||
|
|
9ff89ba263 | ||
|
|
c84f85444a | ||
|
|
37c10e7b48 | ||
|
|
02b8292a2e | ||
|
|
2d1909c227 | ||
|
|
f470606af0 | ||
|
|
4a7b3f17c2 | ||
|
|
788df21115 | ||
|
|
2aaaa8b416 | ||
|
|
2660084401 | ||
|
|
e0dfb888c1 | ||
|
|
ab66b5585d | ||
|
|
bf8b9f32df | ||
|
|
d259143736 | ||
|
|
83dc82a308 | ||
|
|
233f4bb04f | ||
|
|
8183d17706 | ||
|
|
feedcae410 | ||
|
|
3157ea741e | ||
|
|
623040bf3e | ||
|
|
6a394f697a | ||
|
|
3908f4b5ce | ||
|
|
ad21ee1e64 | ||
|
|
6c69796248 | ||
|
|
e6f79562dc | ||
|
|
5e9c655672 | ||
|
|
6b01100ca4 | ||
|
|
838382ea0a | ||
|
|
3c62c22f3a | ||
|
|
bc1197b4a0 | ||
|
|
d691570099 | ||
|
|
772d55fa45 | ||
|
|
676072e96b | ||
|
|
29dec2d9f7 | ||
|
|
b1d6099e2c | ||
|
|
e5cbf010a3 | ||
|
|
023364f968 | ||
|
|
26fe7f610d | ||
|
|
37d6e54e70 | ||
|
|
adc4c59a99 | ||
|
|
16fd528e95 | ||
|
|
efdfdac6cb | ||
|
|
03ebe6b176 | ||
|
|
730019b420 | ||
|
|
b0f61038e3 | ||
|
|
477c36d880 | ||
|
|
d4a99ce9b2 | ||
|
|
025c5fe301 | ||
|
|
422f5deafb | ||
|
|
00b5473a7a | ||
|
|
945264d927 | ||
|
|
74848cd015 | ||
|
|
c583e3238a | ||
|
|
0cc7abf322 | ||
|
|
8f3b9c532c | ||
|
|
4ce35de276 | ||
|
|
7c05aa625f | ||
|
|
139ac0b269 | ||
|
|
8ba35083d8 | ||
|
|
02003abf1d | ||
|
|
88ce729351 | ||
|
|
dcac392e43 | ||
|
|
87cfa4c4d4 | ||
|
|
58ec829d1a | ||
|
|
90fd2daa01 | ||
|
|
d0749324c9 | ||
|
|
a43f72d18a | ||
|
|
3d691088be | ||
|
|
bca3becadb | ||
|
|
d937fbe7ad | ||
|
|
c13e00871d | ||
|
|
b5b716da4c | ||
|
|
45d2a8e0b2 | ||
|
|
d47c948699 | ||
|
|
fdf36babba | ||
|
|
d47411264e | ||
|
|
b9ebad7942 | ||
|
|
2878cc1cb5 | ||
|
|
9277d76f37 | ||
|
|
b7b1301334 | ||
|
|
954dd73ffa | ||
|
|
7aeab98c5b | ||
|
|
51123d60d3 | ||
|
|
395d4b5a97 | ||
|
|
654f025f64 | ||
|
|
8a9ccea5d3 | ||
|
|
92e00075c6 | ||
|
|
624e78e734 | ||
|
|
76bb8822fa | ||
|
|
e3cba097fa | ||
|
|
c812fca8c1 | ||
|
|
f86f4ee18c | ||
|
|
dafed9786e | ||
|
|
cd3a119053 | ||
|
|
f143a171aa | ||
|
|
ee93d7df82 | ||
|
|
61a3bcc53d | ||
|
|
17a46eb92c | ||
|
|
14b121a8ba | ||
|
|
41b57417e5 | ||
|
|
bb492c3043 | ||
|
|
b683dca67c | ||
|
|
b6e6024bda | ||
|
|
2b3a95e21d | ||
|
|
de9c27f1f5 | ||
|
|
85c9cb26b1 | ||
|
|
8ffa27e93d | ||
|
|
ea743fc2c5 | ||
|
|
7fab9aab00 | ||
|
|
444e224d41 | ||
|
|
9fde19f1ce | ||
|
|
4e085b5dca | ||
|
|
06ab58cc07 | ||
|
|
9dae1746ec | ||
|
|
db87191f1f | ||
|
|
76abe79b6d | ||
|
|
970bc29e01 | ||
|
|
79a3262659 | ||
|
|
3add6d64ef | ||
|
|
43168b18d1 | ||
|
|
6970b42456 | ||
|
|
a545b96601 | ||
|
|
59b66409e8 | ||
|
|
25c50bbcaf | ||
|
|
a9a5df00d2 | ||
|
|
5f4d9c29dc | ||
|
|
31e158e39b | ||
|
|
25af5844be | ||
|
|
f79bb49af1 | ||
|
|
2756bae656 | ||
|
|
b574b55f84 | ||
|
|
76ef1c4033 | ||
|
|
409deaee9d | ||
|
|
8396e18283 | ||
|
|
5e952e06ff | ||
|
|
7b6dc3d773 | ||
|
|
1759b67921 | ||
|
|
1307b0e5d1 | ||
|
|
c1af6994bf | ||
|
|
d09c15e5b8 | ||
|
|
ea98b170d9 | ||
|
|
c67f4e45c7 | ||
|
|
c21a5afe94 | ||
|
|
49de16f0f3 | ||
|
|
6d60afadf4 | ||
|
|
c6751af075 | ||
|
|
d41aa389a7 | ||
|
|
f95986fd7a | ||
|
|
ac522bce43 | ||
|
|
6e0729c3b3 | ||
|
|
9ce674da2b | ||
|
|
da8a8e7e77 | ||
|
|
566a1088bd | ||
|
|
11f1f07653 | ||
|
|
45194bb26f | ||
|
|
1f6440189f | ||
|
|
60e98d87d8 | ||
|
|
f560124088 | ||
|
|
7521d0b787 | ||
|
|
c45e52f571 | ||
|
|
275920e5be | ||
|
|
7045c6ee8d | ||
|
|
7a7b65e8c6 | ||
|
|
261526b4d1 | ||
|
|
bc74c91a2c | ||
|
|
ab47543df0 | ||
|
|
3a601468a9 | ||
|
|
f2002e2b90 | ||
|
|
29031167d6 | ||
|
|
7305ac47c3 | ||
|
|
2aec6c9e4b | ||
|
|
5a2cdf3cda | ||
|
|
a943df63fc | ||
|
|
ca771abebe | ||
|
|
010db6148d | ||
|
|
8f065f480c | ||
|
|
f163f9382f | ||
|
|
e752244b5f | ||
|
|
4bbb958a05 | ||
|
|
d1ddfed8dd | ||
|
|
bdb39f203a | ||
|
|
1bcb6aabe7 | ||
|
|
90b09b0f7e | ||
|
|
4e6e0a0e73 | ||
|
|
ad4c764adb | ||
|
|
2265432ec4 | ||
|
|
bb45e60a3f | ||
|
|
b1ff92d63e | ||
|
|
016864edfc | ||
|
|
dc5133e676 | ||
|
|
1fbd10c918 | ||
|
|
4cd219ab32 | ||
|
|
871e84fec9 | ||
|
|
08ce132587 | ||
|
|
4c58d8df72 | ||
|
|
bf554d2417 | ||
|
|
631cd8e35f | ||
|
|
f46c4d8054 | ||
|
|
0010713b78 | ||
|
|
f5bfd4f8f2 | ||
|
|
6d04d2f579 | ||
|
|
0d3cef1626 | ||
|
|
4d251becb0 | ||
|
|
372d4c4bf3 | ||
|
|
2dbda89973 | ||
|
|
2f55bbddd8 | ||
|
|
928773b183 | ||
|
|
bc9803cbc4 | ||
|
|
fca8f5efbc | ||
|
|
f09fe4f7e2 | ||
|
|
b2b29c692e | ||
|
|
de3bc0ff6c | ||
|
|
c4a1b6a82e | ||
|
|
bd08dd54e2 | ||
|
|
b1f93fdb75 | ||
|
|
51599b3f1a | ||
|
|
1b753877a9 | ||
|
|
d33ffa9d22 | ||
|
|
df710e523a | ||
|
|
7d218e0706 | ||
|
|
88127a4858 | ||
|
|
63f2a6f902 | ||
|
|
d8286eb639 | ||
|
|
668fa46a98 | ||
|
|
e16a671a26 | ||
|
|
7f89ef358c | ||
|
|
e0df319279 | ||
|
|
61c7a260b4 | ||
|
|
f26fce63ad | ||
|
|
74c3c96b43 | ||
|
|
765b020152 | ||
|
|
59c05235f6 | ||
|
|
92a4131c88 | ||
|
|
540e14bbe7 | ||
|
|
0ebd355edd | ||
|
|
68d4dfed04 | ||
|
|
37a482d2e4 | ||
|
|
b79cc65728 | ||
|
|
78977c7e31 | ||
|
|
1957fc5345 | ||
|
|
49cefff75d | ||
|
|
2ebb145b7b | ||
|
|
0a6f1394e4 | ||
|
|
1310913281 | ||
|
|
c245c5ade3 | ||
|
|
9e6f45a59b | ||
|
|
f6a78c8890 | ||
|
|
76717fa3cb | ||
|
|
a19230393d | ||
|
|
0b89969a33 | ||
|
|
bbe97230d2 | ||
|
|
ee0161737c | ||
|
|
e7e0b91703 | ||
|
|
dbcdf71bbe | ||
|
|
779615c09a | ||
|
|
1c3a1ce53c | ||
|
|
981c524e3f | ||
|
|
44a7d68f31 | ||
|
|
ae858e3dc4 | ||
|
|
22fd23a31d | ||
|
|
2babe87d6d | ||
|
|
95a8b3fe34 | ||
|
|
32c526a26a | ||
|
|
b2adfad2ee | ||
|
|
ee5a8534a7 | ||
|
|
80ba3b969d | ||
|
|
83bd6911c8 | ||
|
|
6c66f6199c | ||
|
|
c11731541c | ||
|
|
609593ebd0 | ||
|
|
85b867a5ca | ||
|
|
a3690051eb | ||
|
|
ecb44a2611 | ||
|
|
7898ea9ba7 | ||
|
|
90a2029f3d | ||
|
|
1d9a9ea658 | ||
|
|
e88f80eda3 | ||
|
|
025e2f415d | ||
|
|
e113ca79de | ||
|
|
f988c44440 | ||
|
|
37cda26e27 | ||
|
|
65c2da9afa | ||
|
|
434b7b756b | ||
|
|
9dfcab6c1c | ||
|
|
9f39f4e377 | ||
|
|
58da4284ac | ||
|
|
55787ff6cf | ||
|
|
3b93610e43 | ||
|
|
40f3066ee0 | ||
|
|
2108aac41c | ||
|
|
68f8300395 | ||
|
|
325a61912e | ||
|
|
7363c88fce | ||
|
|
0b0f95c65c | ||
|
|
354675f1e5 | ||
|
|
7a769f283b | ||
|
|
3dc67d5978 | ||
|
|
d3a0d71857 | ||
|
|
72f7534a5f | ||
|
|
27a733cbed | ||
|
|
92a0ce98bb | ||
|
|
84c9632508 | ||
|
|
22c2b406db | ||
|
|
bc374a1317 | ||
|
|
0bf82a999a | ||
|
|
453a8459ac | ||
|
|
53f6ddad22 | ||
|
|
14bd128931 | ||
|
|
b0b8daa03d | ||
|
|
940cd70f64 | ||
|
|
d8cdef0622 | ||
|
|
44a7cfe32e | ||
|
|
8584352e21 | ||
|
|
1c39d027e0 | ||
|
|
ce82e2cdcf | ||
|
|
a8492f75cd | ||
|
|
03afb38aa3 | ||
|
|
acc2acce2c | ||
|
|
3a612864f8 | ||
|
|
7e1789a3f4 | ||
|
|
69dea794e1 | ||
|
|
4e024bd8b1 | ||
|
|
6078e511aa | ||
|
|
58574cd824 | ||
|
|
635fa99cf2 | ||
|
|
074d71cef7 | ||
|
|
027075b1b2 | ||
|
|
898ad42f96 | ||
|
|
c87ffeff71 | ||
|
|
40f0744adc | ||
|
|
eba555f260 | ||
|
|
e7db208a40 | ||
|
|
69399bb328 | ||
|
|
749e928d66 | ||
|
|
a3b8690609 | ||
|
|
340e6794ca | ||
|
|
7a23152cee | ||
|
|
d00f71884a | ||
|
|
587014159d | ||
|
|
e2cb3691e4 | ||
|
|
a40be3b658 | ||
|
|
598d7c699a | ||
|
|
23c9b9f2d9 | ||
|
|
22aeff708a | ||
|
|
e9b7b935ee | ||
|
|
eb0d9ec482 | ||
|
|
cfd0d72100 | ||
|
|
f615dc265a | ||
|
|
53c4971c4e | ||
|
|
3a98fa9f53 | ||
|
|
6ed5386c12 | ||
|
|
a998a7f92b | ||
|
|
3218989b13 | ||
|
|
3aff954063 | ||
|
|
11e824c133 | ||
|
|
a26662a813 | ||
|
|
007838197b | ||
|
|
0ad82d5b91 | ||
|
|
52e47a62d2 | ||
|
|
cbaaf3ee54 | ||
|
|
26f26ee35d | ||
|
|
0102ac77e3 | ||
|
|
d24101bee2 | ||
|
|
36cced5ce7 | ||
|
|
87eb537ebe | ||
|
|
86fdc17d2a | ||
|
|
bd8763c62f | ||
|
|
bc917d41ad | ||
|
|
68b60b427a | ||
|
|
c9e64c53ec | ||
|
|
6ba6c6bac7 | ||
|
|
f2967e1d8f | ||
|
|
60783ca88e | ||
|
|
8d7c1371df | ||
|
|
090bfe9091 | ||
|
|
3ad2ba9f33 | ||
|
|
1036def599 | ||
|
|
2acad69940 | ||
|
|
1f18011a5b | ||
|
|
3da63b378c | ||
|
|
0852aa7429 | ||
|
|
8a863ca636 | ||
|
|
83db5c205d | ||
|
|
760e73959c | ||
|
|
e516e06a53 | ||
|
|
a954461be3 | ||
|
|
5998369af6 | ||
|
|
f41a2604c4 | ||
|
|
6fc578d286 | ||
|
|
f2604a5fec | ||
|
|
642026156a | ||
|
|
708c511a98 | ||
|
|
2c75b5886f | ||
|
|
0ef7f5a955 | ||
|
|
28856c01cd | ||
|
|
a47bd03e94 | ||
|
|
c5551ddeb5 | ||
|
|
020f274ef3 | ||
|
|
e2f8f04ace | ||
|
|
6d61d885c1 | ||
|
|
e98cd16032 | ||
|
|
4ec8bdda2f | ||
|
|
16df1624f8 | ||
|
|
cb978e012b | ||
|
|
b7ea02696b | ||
|
|
49cb8874ca | ||
|
|
1384256d87 | ||
|
|
705b2fcd9a | ||
|
|
906ca77973 | ||
|
|
7dc5c734d0 | ||
|
|
a3c1e311f7 | ||
|
|
4d246a250d | ||
|
|
8d2c41f558 | ||
|
|
3b06c4c14a | ||
|
|
f98dcb813d | ||
|
|
17cf31e8cf | ||
|
|
6771c378bf | ||
|
|
013aa4d071 | ||
|
|
b887e16628 | ||
|
|
7774ed65bd | ||
|
|
c85f996aa3 | ||
|
|
64d9cc00d1 | ||
|
|
a0efbecee4 | ||
|
|
cceb4c6677 | ||
|
|
66e448a648 | ||
|
|
eb134fd41a | ||
|
|
857d6f9008 | ||
|
|
32396c4534 | ||
|
|
2df46b6647 | ||
|
|
9f6ad37547 | ||
|
|
65955843e5 | ||
|
|
9e9b5fb9dd | ||
|
|
f96fc67bc2 | ||
|
|
07ebd0b4ca | ||
|
|
64e955c512 | ||
|
|
161753b195 | ||
|
|
f92adb847a | ||
|
|
98f780c277 | ||
|
|
3c512e74db | ||
|
|
9b752dd28f | ||
|
|
3cf2719c29 | ||
|
|
be420c0394 | ||
|
|
1b1d995b9d | ||
|
|
6410f41fa2 | ||
|
|
f90a45b1e6 | ||
|
|
9ca5569122 | ||
|
|
a6b4a35973 | ||
|
|
06cb6bac3e | ||
|
|
5241aeea9f | ||
|
|
6b69ad20ad | ||
|
|
a79d2ec323 | ||
|
|
209a0fe2da | ||
|
|
277f439f70 | ||
|
|
d9f29fdcaa | ||
|
|
a9141d3fe2 | ||
|
|
4ce55e88fa | ||
|
|
c930d388dc | ||
|
|
12c7911cf4 | ||
|
|
06377ff497 | ||
|
|
7a1938e515 | ||
|
|
445166d220 | ||
|
|
3963501d0c | ||
|
|
acb51d7859 | ||
|
|
4dbfb76ced | ||
|
|
4188464652 | ||
|
|
fb552a8d62 | ||
|
|
c998e4e34f | ||
|
|
ab46015a5a | ||
|
|
dd10740bf2 | ||
|
|
44f26685e4 | ||
|
|
3caa56ae8c | ||
|
|
1ca4fbb078 | ||
|
|
bdf5270fa0 | ||
|
|
e3e865b108 | ||
|
|
33f3736798 | ||
|
|
a86fbcee44 | ||
|
|
cdbf8a2811 | ||
|
|
da4fae4e04 | ||
|
|
ddeefc4ab6 | ||
|
|
33702064a5 | ||
|
|
b72995c8bf | ||
|
|
868eb1c4fb | ||
|
|
d93140efc6 | ||
|
|
0f59d46ede | ||
|
|
812b5f22f9 | ||
|
|
d1b5feae0d | ||
|
|
0861fa9e03 | ||
|
|
c3fe9f513d | ||
|
|
b513669f4d | ||
|
|
1ad74fdacc | ||
|
|
9a24ede989 | ||
|
|
7ea8dfa8ce | ||
|
|
670068eeba | ||
|
|
70310f1970 | ||
|
|
4463c148a5 | ||
|
|
c982b45134 | ||
|
|
d209a2c7f8 | ||
|
|
75c73193a2 | ||
|
|
fc99f6774d | ||
|
|
d40fab86c9 | ||
|
|
5c0520e093 | ||
|
|
1bb9ead202 | ||
|
|
3afd8915f0 | ||
|
|
ba3f2d2823 | ||
|
|
24989d80ac | ||
|
|
d2c16158cc | ||
|
|
8514fd6266 | ||
|
|
30d1534c01 | ||
|
|
4f0800d4fc | ||
|
|
41fa396318 | ||
|
|
d94af84002 | ||
|
|
63b92cc35a | ||
|
|
3238d9fbc5 | ||
|
|
780d4c95fe | ||
|
|
c3b27c75bf | ||
|
|
23c7031672 | ||
|
|
9e98d09a93 | ||
|
|
06e64f7347 | ||
|
|
92594db78d | ||
|
|
c574f2d6bd | ||
|
|
ee156cbfd6 | ||
|
|
73d12daf04 | ||
|
|
e4179a934b | ||
|
|
afd309d9a8 | ||
|
|
1a24b00c5e | ||
|
|
445e4d8b31 | ||
|
|
224ca98d0e | ||
|
|
13419c9fb7 | ||
|
|
00646bc84b | ||
|
|
cb4b686335 | ||
|
|
5e900b62c8 | ||
|
|
74c94d37e5 | ||
|
|
588814d1a6 | ||
|
|
572b858f81 | ||
|
|
1a9fc48490 | ||
|
|
2dd131e6c3 | ||
|
|
d1ad2a681f | ||
|
|
e2e7666c4f | ||
|
|
665639fdca | ||
|
|
8bb930c1fc | ||
|
|
b3b9d8d105 | ||
|
|
82c409252b | ||
|
|
14c63a03c4 | ||
|
|
0c7ad8b16c | ||
|
|
1bf2d8219a | ||
|
|
a72264ef36 | ||
|
|
1acc399568 | ||
|
|
160960437c | ||
|
|
61992adcca | ||
|
|
10e0ae8200 | ||
|
|
eb58b8576e | ||
|
|
9b4d2d6ed7 | ||
|
|
6417e9dec5 | ||
|
|
f5ac217f13 | ||
|
|
a3d3b14dd1 | ||
|
|
8fccce8684 | ||
|
|
4a847cd74a | ||
|
|
f4c1db39ad | ||
|
|
d9ff177427 | ||
|
|
95e3566c5f | ||
|
|
76e02ff514 | ||
|
|
8aca9a2d82 | ||
|
|
3abab2072a | ||
|
|
ca9e479dc5 | ||
|
|
4d230a7b3e | ||
|
|
974cc59e6c | ||
|
|
9f09b144f0 | ||
|
|
9d4dad5fee | ||
|
|
46ffa93d93 | ||
|
|
8b709bc070 | ||
|
|
c1284c760a | ||
|
|
6529a94d3a | ||
|
|
f5e91a0524 | ||
|
|
f63bd3016b | ||
|
|
09cd590796 | ||
|
|
da728c4039 | ||
|
|
14b7b8cec1 | ||
|
|
3695c04933 | ||
|
|
f0f3bb6ede | ||
|
|
7824326c5b | ||
|
|
a65d263ae2 | ||
|
|
f3e628be6b | ||
|
|
62e8dc7767 | ||
|
|
8e8cfa704a | ||
|
|
8b2eff0194 | ||
|
|
d4d063b97a | ||
|
|
d5ec33e1bd | ||
|
|
0726f22ec7 | ||
|
|
531ab93388 | ||
|
|
a7ad00d402 | ||
|
|
1f18848b4e | ||
|
|
38179d9ce3 | ||
|
|
b86c493cf8 | ||
|
|
0cc2df85da | ||
|
|
3157bac5f6 | ||
|
|
5cb1709f5d | ||
|
|
e6834b13a5 | ||
|
|
8a17daa002 | ||
|
|
1b09189195 | ||
|
|
7f21fa2c40 | ||
|
|
e0e4fc85f7 | ||
|
|
b3e57db9f8 | ||
|
|
f8d93a5de7 | ||
|
|
c5423ac650 | ||
|
|
6e93d17d14 | ||
|
|
127bc1be5c | ||
|
|
8136b09992 | ||
|
|
2ffac3268e | ||
|
|
c7056e9d40 | ||
|
|
3fb8b4e7ff | ||
|
|
c728a7802d | ||
|
|
e7d3049456 | ||
|
|
316675c77e | ||
|
|
c836d3de71 | ||
|
|
230429135a | ||
|
|
0be8092382 | ||
|
|
eb2019e568 | ||
|
|
bffbb17271 | ||
|
|
16b997096d | ||
|
|
3b23f2a4ed | ||
|
|
87f86fd2e8 | ||
|
|
396509579a | ||
|
|
91175f19c4 | ||
|
|
7c22ca0f91 | ||
|
|
5eb416d8d9 | ||
|
|
12e374bd2f | ||
|
|
9b50f0e77c | ||
|
|
6aa89287b1 | ||
|
|
4b9ebdc87c | ||
|
|
336b45667e | ||
|
|
3c33a1126b | ||
|
|
836cdfb16c | ||
|
|
8512bae997 | ||
|
|
6fbe8c5dee | ||
|
|
2132ea416b | ||
|
|
24081b9223 | ||
|
|
220cc98559 | ||
|
|
ef8b9b0685 | ||
|
|
e8dd47369c | ||
|
|
537eaddecd | ||
|
|
183c171da6 | ||
|
|
58c6114840 | ||
|
|
df5162ce56 | ||
|
|
ae61fe892d | ||
|
|
a78de3b4b9 | ||
|
|
f26a864e83 | ||
|
|
0e0b03e6f2 | ||
|
|
e5595f13eb | ||
|
|
1b12c16685 | ||
|
|
048055daac | ||
|
|
f2590f1fed | ||
|
|
2eb7b22100 | ||
|
|
f169750d1a | ||
|
|
fbb361fa7a | ||
|
|
902faca13c | ||
|
|
7e476a5785 | ||
|
|
c78c5aad02 | ||
|
|
42c49645da | ||
|
|
9427fb9ecc | ||
|
|
61878f293f | ||
|
|
2bd1727076 | ||
|
|
f0fbf7bf8b | ||
|
|
4a1fccc395 | ||
|
|
54c0497933 | ||
|
|
49a99e9f15 | ||
|
|
134fd5b2c2 | ||
|
|
696f9b3550 | ||
|
|
aeda42cb71 | ||
|
|
7ba8400c38 | ||
|
|
02f10f07e8 | ||
|
|
83cc32afaa | ||
|
|
5b8382643a | ||
|
|
003cb8719a | ||
|
|
c625ebc128 | ||
|
|
89c0b02327 | ||
|
|
94bb17a301 | ||
|
|
4f29b921e5 | ||
|
|
8d5dbb0f3d | ||
|
|
db321e45da | ||
|
|
8e254a341c | ||
|
|
847a52ab08 | ||
|
|
94e69e4e84 | ||
|
|
8834526cac | ||
|
|
788365687e | ||
|
|
4c3d328140 | ||
|
|
2588f74f7c | ||
|
|
b70a4ef428 | ||
|
|
026a903251 | ||
|
|
3557113ed8 | ||
|
|
acd8c27a13 | ||
|
|
3c186eb113 | ||
|
|
841eb34224 | ||
|
|
ef583ba7ec | ||
|
|
fa0e06df75 | ||
|
|
c26ee7271b | ||
|
|
f37c0a9124 | ||
|
|
8468049935 | ||
|
|
80fbd656a7 | ||
|
|
3fb5749c86 | ||
|
|
7cef6c8566 | ||
|
|
98f2a139e9 | ||
|
|
1692130559 | ||
|
|
cf77a9eae2 | ||
|
|
26151af48a | ||
|
|
c3b858f0fd | ||
|
|
914e788ad8 | ||
|
|
074178621c | ||
|
|
25d1b6b695 | ||
|
|
f121c73c4b | ||
|
|
3f79e7677c | ||
|
|
ca573f27be | ||
|
|
056a3342bf | ||
|
|
eaa661cf09 | ||
|
|
b2d791d6ea | ||
|
|
f1ea1935c5 | ||
|
|
d9c101debe | ||
|
|
e3a720a69d | ||
|
|
4f3f18a0ad | ||
|
|
10a3a8324b | ||
|
|
a2dab72b25 | ||
|
|
ca0a381d8c | ||
|
|
a503e85a57 | ||
|
|
0d668561b4 | ||
|
|
c8d39a2c15 | ||
|
|
6146ac90c1 | ||
|
|
2bb00c948d | ||
|
|
01eadd986c | ||
|
|
b482ea4ecc | ||
|
|
19bb98c857 | ||
|
|
225afb85e4 | ||
|
|
2873ffdff7 | ||
|
|
52ba506138 | ||
|
|
798f70a706 | ||
|
|
d731d55a7a | ||
|
|
1bfcea0227 | ||
|
|
71a307bfef | ||
|
|
7a16a8eaff | ||
|
|
c1c2ccd940 | ||
|
|
8a993b7dcb | ||
|
|
977393a9aa | ||
|
|
4f36de9900 | ||
|
|
ef658eb4cd | ||
|
|
6f77577482 | ||
|
|
bfdb1a8f62 | ||
|
|
0935d70ae4 | ||
|
|
24e4e2b960 | ||
|
|
e608d7463e | ||
|
|
47453f1471 | ||
|
|
362780f59a | ||
|
|
a2a511b3c0 | ||
|
|
78cde8ab62 | ||
|
|
46b779c9d5 | ||
|
|
23129bf95a | ||
|
|
fba137bb3f | ||
|
|
e50a73b4bf | ||
|
|
31afe11d0e | ||
|
|
5dc1d047ac | ||
|
|
19e0cf406c | ||
|
|
0bc1eece0a | ||
|
|
f2e93e915b | ||
|
|
8db6a99194 | ||
|
|
1490ebce03 | ||
|
|
cd189e01dc | ||
|
|
15467248ee | ||
|
|
23008ab5b8 | ||
|
|
041fbb10a1 | ||
|
|
9ba0e59df5 | ||
|
|
0bb9f57919 | ||
|
|
106da869c1 | ||
|
|
d34a3352f2 | ||
|
|
4b5c922f11 | ||
|
|
aacb415364 | ||
|
|
bdc8bcfe5c | ||
|
|
154238edf0 | ||
|
|
eba789c200 | ||
|
|
63cb67a03c | ||
|
|
1c299c6d5d | ||
|
|
486c5310d7 | ||
|
|
5ef4a97d5f | ||
|
|
03adb8f730 | ||
|
|
abdcd0b3f0 | ||
|
|
6e225808a9 | ||
|
|
382c96f587 | ||
|
|
80cb0119c7 | ||
|
|
e7bc5072c0 | ||
|
|
a65057679c | ||
|
|
025186d22f | ||
|
|
e17217206f | ||
|
|
c64ca44457 | ||
|
|
c6e9a16274 | ||
|
|
2dc125e0ce | ||
|
|
9c88ce213b | ||
|
|
f945380a87 | ||
|
|
bb9664eafc | ||
|
|
eaca802ecc | ||
|
|
2e6ca574b6 | ||
|
|
026de5dd4e | ||
|
|
262897fbf6 | ||
|
|
304a9d90d0 | ||
|
|
91e1674833 | ||
|
|
d4c61ce932 | ||
|
|
7387ebe182 | ||
|
|
d6f305cfa6 | ||
|
|
73b9fbb435 | ||
|
|
51c2f313d4 | ||
|
|
0a390107a3 | ||
|
|
077bf997c6 | ||
|
|
48cb473ecb | ||
|
|
40dc542302 | ||
|
|
28bb4894b2 | ||
|
|
774d17dd25 | ||
|
|
790637f1bd | ||
|
|
99fb5d3b8e | ||
|
|
6676e62579 | ||
|
|
d735992f5c | ||
|
|
8a32cfc185 | ||
|
|
285fafc300 | ||
|
|
0c90433a34 | ||
|
|
d6070368b7 | ||
|
|
b42389500f | ||
|
|
daca972fc2 | ||
|
|
8447e59d1f | ||
|
|
07ff8cd662 | ||
|
|
dbc734eee5 | ||
|
|
eaa95fdba4 | ||
|
|
3ba1169e9c | ||
|
|
0117b53ea2 | ||
|
|
a2ec04b641 | ||
|
|
8fdcef9c42 | ||
|
|
d311de764d | ||
|
|
e9b16b2f70 | ||
|
|
21a81b977b | ||
|
|
9ce1c2b075 | ||
|
|
b974cbd14c | ||
|
|
1d96282fd9 | ||
|
|
48efda6bd9 | ||
|
|
aba3e0033f | ||
|
|
5bf61a63cc | ||
|
|
48095c0433 | ||
|
|
3e1599119a | ||
|
|
f488e8a7ab | ||
|
|
b5c17bf7bc | ||
|
|
77e994e9fd | ||
|
|
bbd3fc4d1d | ||
|
|
ee63946be2 | ||
|
|
b1bcfacf35 | ||
|
|
d4936e8eec | ||
|
|
dbba098555 | ||
|
|
b368e93061 | ||
|
|
10b333ae48 | ||
|
|
87c0345a6a | ||
|
|
381510d213 | ||
|
|
f5f99f5a04 | ||
|
|
fcf1214f80 | ||
|
|
7e122529d2 | ||
|
|
600c3d21dc | ||
|
|
135d7ebda5 | ||
|
|
2a57b94e08 | ||
|
|
366a37b765 | ||
|
|
a3806f7a81 | ||
|
|
cf28e373f7 | ||
|
|
8d80295e07 | ||
|
|
1f7ffe6ea0 | ||
|
|
a740753175 | ||
|
|
c70f996915 | ||
|
|
707dfc2a0b | ||
|
|
77db3362fc | ||
|
|
c8e0687288 | ||
|
|
f61a6191ec | ||
|
|
2648236bb4 | ||
|
|
382e23f545 | ||
|
|
2eddbe3669 | ||
|
|
267d710c13 | ||
|
|
5e41517178 | ||
|
|
5c9cf0a655 | ||
|
|
337297e3e0 | ||
|
|
26def9805f | ||
|
|
5429876cde | ||
|
|
6301b48b5d | ||
|
|
5dea97cce2 | ||
|
|
69b63bcb15 | ||
|
|
d13b2d236b | ||
|
|
9dce637d22 | ||
|
|
dbb291fb86 | ||
|
|
cefad66475 | ||
|
|
726f4438d6 | ||
|
|
880e75a91c | ||
|
|
0f1fd0e367 | ||
|
|
7a44cf6e26 | ||
|
|
177c709e0a | ||
|
|
699eb824a1 | ||
|
|
bc2dc1b2e9 | ||
|
|
6b19e305f3 | ||
|
|
8b1b4044b3 | ||
|
|
2d9429d688 | ||
|
|
62f3ff1902 | ||
|
|
36735cdfbe | ||
|
|
f57db90d7b | ||
|
|
97aec23384 | ||
|
|
eb3bcf04ea | ||
|
|
40626ba708 | ||
|
|
882597365b | ||
|
|
6b456c2f57 | ||
|
|
515ae57e88 | ||
|
|
9cc9d6ab66 | ||
|
|
40b4fd210a | ||
|
|
2ce2d0efab | ||
|
|
97a863293d | ||
|
|
d45426a4c1 | ||
|
|
d5a49db782 | ||
|
|
4b393f412c | ||
|
|
8cc77fbe1d | ||
|
|
673632bd92 | ||
|
|
d2b9a5d1a9 | ||
|
|
2bc46b0a0e | ||
|
|
74200daf90 | ||
|
|
b89c127df4 | ||
|
|
67bbbb2097 | ||
|
|
c6ddf0de87 | ||
|
|
0ef73952b1 | ||
|
|
0e02a3aeee | ||
|
|
1558a7c386 | ||
|
|
b72becd328 | ||
|
|
df2ac8e203 | ||
|
|
c6c230002c | ||
|
|
885503b5fa | ||
|
|
40fd91257e | ||
|
|
02ece3cf41 | ||
|
|
901c879647 | ||
|
|
990a73f4a4 | ||
|
|
73169d339d | ||
|
|
265b86c031 | ||
|
|
7c29c23015 | ||
|
|
538e579477 | ||
|
|
73db5f55e2 | ||
|
|
31a9980343 | ||
|
|
02c50f510f | ||
|
|
3541ee0512 | ||
|
|
e72821ba1e | ||
|
|
3af00871a5 | ||
|
|
22fe4ca790 | ||
|
|
72d0570c15 | ||
|
|
62e0cc0867 | ||
|
|
8987480491 | ||
|
|
70bb4c2478 | ||
|
|
cf079a6be4 | ||
|
|
f153cdcba1 | ||
|
|
4e048240c5 | ||
|
|
c098bb1ca0 | ||
|
|
e02ded734c | ||
|
|
e721f29f5a | ||
|
|
f763d5f936 | ||
|
|
a3368eb557 | ||
|
|
b5758347c2 | ||
|
|
775a6d92aa | ||
|
|
2ab5995177 | ||
|
|
f6e847d43f | ||
|
|
cac2ca3d18 | ||
|
|
d1e870cee0 | ||
|
|
ca0f65767b | ||
|
|
7968bfc262 | ||
|
|
ed4bbe9814 | ||
|
|
6e83eb6da2 | ||
|
|
00949b6135 | ||
|
|
f3a857f26f | ||
|
|
4bd03372aa | ||
|
|
dcc589c57a | ||
|
|
3018ec8cf0 | ||
|
|
c452a66a4f | ||
|
|
7a860f8564 | ||
|
|
94f6f4bdff | ||
|
|
a627dac4b7 | ||
|
|
848b6862be | ||
|
|
d181575e93 | ||
|
|
778775055f | ||
|
|
22ccda8d34 | ||
|
|
c5fc6fd72e | ||
|
|
c8a4978b5f | ||
|
|
9e88f8c884 | ||
|
|
2e543bf4d3 | ||
|
|
caf42d423f | ||
|
|
dc39f874ac | ||
|
|
d1c7a124cf | ||
|
|
8ec17ce9a6 | ||
|
|
012af35e87 | ||
|
|
78bd1f4a5d | ||
|
|
4477158182 | ||
|
|
6e96021047 | ||
|
|
48f57eea66 | ||
|
|
4b6cfefaf3 | ||
|
|
0e34cc7f26 | ||
|
|
27fb2870ab | ||
|
|
ee6b7c4fe0 | ||
|
|
0464cecde5 | ||
|
|
b237259599 | ||
|
|
8c379739f0 | ||
|
|
4fb8db982c | ||
|
|
921b50b642 | ||
|
|
031332e8ab | ||
|
|
f03ccced8d | ||
|
|
51973d225c | ||
|
|
a59666e752 | ||
|
|
8259191e50 | ||
|
|
3eb84cc955 | ||
|
|
832d3b3a95 | ||
|
|
37867634cd | ||
|
|
b1b7bff09d | ||
|
|
82f28bfc8c | ||
|
|
dfed92ac61 | ||
|
|
0d6c9b468e | ||
|
|
2bc12c510b | ||
|
|
f3022a19c2 | ||
|
|
800afae1c9 | ||
|
|
3c19f8e76f | ||
|
|
3ca462f46f | ||
|
|
fadd21ebd0 | ||
|
|
a10c474ce5 | ||
|
|
513ea5a198 | ||
|
|
4bab1c32d7 | ||
|
|
39064eb2c6 | ||
|
|
28a60f5243 | ||
|
|
56b9b878f8 | ||
|
|
e7ad6e32e3 | ||
|
|
a1d6347db3 | ||
|
|
9e80013e28 | ||
|
|
e66a8a0b21 | ||
|
|
77593969b2 | ||
|
|
186fa35f70 | ||
|
|
c39d0048a8 | ||
|
|
5fc22b9530 | ||
|
|
51735c3f6d | ||
|
|
f14aad0c50 | ||
|
|
cdbb492f2c | ||
|
|
de18aefd7b | ||
|
|
5f8807d62c | ||
|
|
e42d8b8eeb | ||
|
|
d67b8b8298 | ||
|
|
10c8d157f5 | ||
|
|
1f10558f1f | ||
|
|
409228285e | ||
|
|
0ac7758c04 | ||
|
|
802e3d04b2 | ||
|
|
39ef4a4711 | ||
|
|
b2215e1db6 | ||
|
|
7d42da5d3c | ||
|
|
82770e6dd0 | ||
|
|
62bbfc6075 | ||
|
|
a5eb77dd87 | ||
|
|
cb9cf4885f | ||
|
|
a5455925ea | ||
|
|
61ef383c38 | ||
|
|
b0aa706c07 | ||
|
|
a04c8f6214 | ||
|
|
fd5b582c6c | ||
|
|
dc45613b7b | ||
|
|
d986d8f398 | ||
|
|
6c64f20a14 | ||
|
|
2071087794 | ||
|
|
ba56ab719c | ||
|
|
617c053b95 | ||
|
|
868cff2c4c | ||
|
|
8e23ebf3e4 | ||
|
|
d9713f8e18 | ||
|
|
c583b58cb9 | ||
|
|
6dd6eff02c | ||
|
|
3a1fcd2147 | ||
|
|
bfeaf5dbf5 | ||
|
|
d4bd4a8150 | ||
|
|
2ace518db9 | ||
|
|
e8641cee8f | ||
|
|
884328d10f | ||
|
|
d8bd8a29bc | ||
|
|
cbd6b796ca | ||
|
|
90cfa4ed5c | ||
|
|
6426abfedf | ||
|
|
d746928765 | ||
|
|
f83554c817 | ||
|
|
6fc4741c9a | ||
|
|
7b63346bd0 | ||
|
|
737c63e8b0 | ||
|
|
94b37f6414 | ||
|
|
5fa2bc3bc8 | ||
|
|
5d7a5ace66 | ||
|
|
0bd213a327 | ||
|
|
3d9f351d84 | ||
|
|
9fda220f33 | ||
|
|
991ae1d6e3 | ||
|
|
b993be4658 | ||
|
|
c4f8af2311 | ||
|
|
4c541e98ab | ||
|
|
7b8b24b45d | ||
|
|
a61a44edc9 | ||
|
|
393f3e5737 | ||
|
|
c34e38e50f | ||
|
|
b98676ea77 | ||
|
|
002c67e48c | ||
|
|
cf21684916 | ||
|
|
9fe1a904c8 | ||
|
|
c4e67db75f | ||
|
|
8487555315 | ||
|
|
304c1ef5d2 | ||
|
|
c911a7a310 | ||
|
|
322f29b31b | ||
|
|
f0a86db9e4 | ||
|
|
60bcfa8ab1 | ||
|
|
074b63d68d | ||
|
|
45fb856898 | ||
|
|
138ed85f93 | ||
|
|
a632dd172e | ||
|
|
8fbf915710 | ||
|
|
8eafc5816d | ||
|
|
17b50df101 | ||
|
|
b9e436d56d | ||
|
|
a929db9939 | ||
|
|
8287232866 | ||
|
|
11330b608b | ||
|
|
ff94d188db | ||
|
|
332ce12eb5 | ||
|
|
e4eb0c7019 | ||
|
|
8e45d6462f | ||
|
|
1857dd72b9 | ||
|
|
e4c6285fab | ||
|
|
c150d24843 | ||
|
|
6c69119d09 | ||
|
|
d87b8f7652 | ||
|
|
577febe3b7 | ||
|
|
c8d56a237b | ||
|
|
fb018946b9 | ||
|
|
0697f4a964 | ||
|
|
4c0cfb77fb | ||
|
|
1a2885408d | ||
|
|
de8e363d33 | ||
|
|
7436ac0b5e | ||
|
|
eaf9447abc | ||
|
|
45cadb9cfb | ||
|
|
9bab31514e | ||
|
|
6e13320f36 | ||
|
|
1ed1e91189 | ||
|
|
7561afd92d | ||
|
|
92eb5836fb | ||
|
|
0068fcef88 | ||
|
|
e2df24522f | ||
|
|
0c185c78e3 | ||
|
|
7720e8005e | ||
|
|
4a738990ae | ||
|
|
f7e8f25b70 | ||
|
|
da828523f3 | ||
|
|
d621ea15a3 | ||
|
|
db74e573d1 | ||
|
|
0907fa5685 | ||
|
|
ff8dc76c75 | ||
|
|
d40656b69a | ||
|
|
4a5402db0f | ||
|
|
b7df1b0bb0 | ||
|
|
d0b80492c7 | ||
|
|
7174c3956c | ||
|
|
135f2617f6 | ||
|
|
5f855209c9 | ||
|
|
0741bcbbaa | ||
|
|
a4361a28b2 | ||
|
|
417164cc58 | ||
|
|
d9159ffc96 | ||
|
|
ec022e7acd | ||
|
|
7a0aa556ff | ||
|
|
9f7eaf22b0 | ||
|
|
6a3fee98fd | ||
|
|
abf5bfdd69 | ||
|
|
994939b121 | ||
|
|
1b3334341d | ||
|
|
286ac6dc05 | ||
|
|
85ae4cae34 | ||
|
|
ba840822bc | ||
|
|
d10515c003 | ||
|
|
0db5d24673 | ||
|
|
e6135c69b4 | ||
|
|
e2e4c97300 | ||
|
|
635d06df87 | ||
|
|
fcc7d126f9 | ||
|
|
fa152a908b | ||
|
|
230887bea3 | ||
|
|
8677aa1bca | ||
|
|
0b09e2790f | ||
|
|
781350aa5f | ||
|
|
9716130336 | ||
|
|
6eee282fa4 | ||
|
|
e491463862 | ||
|
|
721bf97def | ||
|
|
f34bdd57b3 | ||
|
|
9d4757a737 | ||
|
|
82fa7eaf9f | ||
|
|
c7bad6f9a0 | ||
|
|
911c630b91 | ||
|
|
dbca918f07 | ||
|
|
9a05a47122 | ||
|
|
bceb6749af | ||
|
|
50396f0c9b |
21
.gitignore
vendored
21
.gitignore
vendored
@@ -149,3 +149,24 @@ intermediates
|
||||
*.iml
|
||||
/build
|
||||
/src/Kp2aKeyboardBinding/Jars
|
||||
/src/java/Kp2aAccServiceLib/app/build
|
||||
/src/java/Kp2aAccServiceLib/app/app.iml
|
||||
/src/java/Kp2aAccServiceLib/gradle
|
||||
adbprompt.ps1
|
||||
/src/java/KP2ASoftkeyboard_AS/build/android-profile/*.rawproto
|
||||
src/java/KP2ASoftkeyboard_AS/build/generated/mockable-android-23.jar
|
||||
*.rawproto
|
||||
src/java/Keepass2AndroidPluginSDK2/build/generated/mockable-Google-Inc.-Google-APIs-23.jar
|
||||
/src/.vs
|
||||
/src/JavaFileStorageBindings/Jars/JavaFileStorage-release.aar
|
||||
/src/PluginSdkBinding/Jars/app-debug.aar
|
||||
/src/java/KP2AKdbLibrary/libs/arm64-v8a/libfinal-key.so
|
||||
/src/java/KP2AKdbLibrary/libs/x86_64/libfinal-key.so
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/libs/arm64-v8a/libkp2akeyboard_jni.so
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/libs/armeabi-v7a/libkp2akeyboard_jni.so
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/libs/x86/libkp2akeyboard_jni.so
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/libs/x86_64/libkp2akeyboard_jni.so
|
||||
/src/java/KP2AKdbLibrary/app/build
|
||||
/src/java/KP2ASoftkeyboard_AS/app/.cxx
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/libs
|
||||
/src/java/KP2AKdbLibrary/app/.cxx
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +1,6 @@
|
||||
[submodule "src/SamsungPass"]
|
||||
path = src/SamsungPass
|
||||
url = https://github.com/PhilippC/Xamarin-Samsung-Pass.git
|
||||
[submodule "src/netftpandroid"]
|
||||
path = src/netftpandroid
|
||||
url = https://git01.codeplex.com/forks/philippc/netftpandroid
|
||||
[submodule "src/java/argon2/phc-winner-argon2"]
|
||||
path = src/java/argon2/phc-winner-argon2
|
||||
url = https://github.com/P-H-C/phc-winner-argon2
|
||||
|
||||
34
crowdin.yml
Normal file
34
crowdin.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
files:
|
||||
- source: src/keepass2android/Resources/values/strings.xml
|
||||
translation: >-
|
||||
/src/keepass2android/Resources/values-%two_letters_code%/%original_file_name%
|
||||
translate_attributes: '0'
|
||||
content_segmentation: '0'
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh
|
||||
zh-TW: zh-rTW
|
||||
pt-PT: pt
|
||||
pt-BR: pt-rBR
|
||||
- source: src/java/android-filechooser-AS/app/src/main/res/values/strings.xml
|
||||
translation: >-
|
||||
/src/java/android-filechooser-AS/app/src/main/res/values-%two_letters_code%/%original_file_name%
|
||||
translate_attributes: '0'
|
||||
content_segmentation: '0'
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh
|
||||
zh-TW: zh-rTW
|
||||
pt-PT: pt
|
||||
pt-BR: pt-rBR
|
||||
- source: src/java/KP2ASoftkeyboard_AS/app/src/main/res/values/strings.xml
|
||||
translation: >-
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/res/values-%two_letters_code%/%original_file_name%
|
||||
translate_attributes: '0'
|
||||
content_segmentation: '0'
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh
|
||||
zh-TW: zh-rTW
|
||||
pt-PT: pt
|
||||
pt-BR: pt-rBR
|
||||
5
docs/AccServiceAutoFill.md
Normal file
5
docs/AccServiceAutoFill.md
Normal file
@@ -0,0 +1,5 @@
|
||||
As of December 2017, Google does not accept the use of Accessibility services for anything except helping people with disabilities. This means that Keepass2Android can no longer provide the accessibility service based AutoFill feature. Otherwise, Google would remove Keepass2Android from Play Store.
|
||||
|
||||
If you want to continue using this feature, please [install the Accessibility service based AutoFill plugin](https://github.com/PhilippC/kp2a_accservice_autofill/releases/).
|
||||
|
||||
After installation, please enable the accessibility service "KP2A AutoFillPlugin" in the Android system settings. When trying to use the plugin for the first time, KP2A will ask you if the plugin may access the Keepass database. Please accept this to use the plugin.
|
||||
@@ -2,10 +2,18 @@
|
||||
Displays password entries as QR code; can be used to scan QR codes which can then be added to Keepass2Android.
|
||||
[https://play.google.com/store/apps/details?id=keepass2android.plugin.qr](https://play.google.com/store/apps/details?id=keepass2android.plugin.qr)
|
||||
|
||||
# KeyboardSwap Plug-in
|
||||
Allows to switch input method automatically on non-rooted devices.
|
||||
[https://play.google.com/store/apps/details?id=keepass2android.plugin.keyboardswap2](https://play.google.com/store/apps/details?id=keepass2android.plugin.keyboardswap2)
|
||||
|
||||
# AutoFill Plug-in
|
||||
Uses Android Accessibility Service to provide an option to AutoFill forms (e.g. on Chrome) or any Android app.
|
||||
[https://philippc.github.io/keepass2android/AccServiceAutoFill.html](https://philippc.github.io/keepass2android/AccServiceAutoFill.html)
|
||||
|
||||
# InputStick Plug-in
|
||||
Allows to send text from KP2A via InputStick to your PC.
|
||||
[https://play.google.com/store/apps/details?id=com.inputstick.apps.kp2aplugin](https://play.google.com/store/apps/details?id=com.inputstick.apps.kp2aplugin)
|
||||
|
||||
# USB Keyboard Plug-in
|
||||
Allows to send text from KP2A to your PC. Requires special kernel on the Android device.
|
||||
[https://play.google.com/store/apps/details?id=th.in.whs.k2ausbkbd](https://play.google.com/store/apps/details?id=th.in.whs.k2ausbkbd)
|
||||
[https://play.google.com/store/apps/details?id=th.in.whs.k2ausbkbd](https://play.google.com/store/apps/details?id=th.in.whs.k2ausbkbd)
|
||||
|
||||
@@ -7,11 +7,12 @@ If you think something is missing in the documentation, please create an issue a
|
||||
If you store important information using Keepass2Android, you should know a little bit about what's going on:
|
||||
* Keepass2Android stores your password in an encrypted file. It is *your responsibility* to backup this file regularly and safely.
|
||||
* There is no way for anyone, including the app's author, to access the information stored in your password database without
|
||||
** having the database file
|
||||
** knowing the master password (and additional second factor if you chose one)
|
||||
This means that **if you forget the master password, your database is lost**! So make sure you remember the password. You might also want to think about:
|
||||
** What happens if I have an accident? Should any trusted person be able to access my database?
|
||||
** What happens if my phone gets lost or stolen? Do I know how to recover my database from a backup or the cloud?
|
||||
* having the database file
|
||||
* knowing the master password (and additional second factor if you chose one)
|
||||
This means that **if you forget the master password, your database is lost**! So make sure you remember the password and retain any second factor method (if one is used).
|
||||
* You might also want to think about:
|
||||
* What happens if I have an accident? Should any trusted person be able to access my database?
|
||||
* What happens if my phone gets lost or stolen? Do I know how to recover my database from a backup or the cloud?
|
||||
|
||||
|
||||
# Getting started
|
||||
@@ -27,14 +28,14 @@ Select "Create new database" from the start screen. Tap the integrated help icon
|
||||
## Getting passwords into password fields
|
||||
There are many ways how to enter the passwords from your database in the corresponding fields. By default, the clipboard as well as the KP2A keyboard are activated in the settings:
|
||||
* The KP2A keyboard is the recommended way because it's safe against clipboard loggers: Whenever you select an entry, the KP2A keyboard notification will appear in the notification bar. Click it to activate the keyboard. (The first time you do this, you are required to enable the keyboard in the system settings. This must be done by the user for Android security reasons.) As soon as it's activated, you can tap a field where you want to enter data from the selected entry. The KP2A keyboard will come up. Click the KP2A key (on the bottom left) to select whether you want to enter Username/password etc. When you're done, click the Keyboard key (next to the KP2A key) to switch back to your favorite keyboard.
|
||||
* You can enable the Keepass2Android Autofill service in the system's accessibility settings which allows to fill data using Android's accessibility system. This works with many apps including Chrome browser but is not supported for Firefox on Android.
|
||||
* The clipboard based approach can be used as well: Pull the notification bar down and select "Copy username/password to clipboard". Then long-tap the field where you want to paste the data. A small "paste" button should come up. Note, however, that information in the clipboard can be monitored by all apps on your device.
|
||||
* You can enable the Keepass2Android Autofill service in the system's Autofill settings (Android 8+) which allows to fill data using Android's accessibility system. This works with many apps including Firefox browser but is not supported for Chrome (when writing this).
|
||||
* The clipboard based approach can be used as well: Pull the notification bar down and select "Copy username/password to clipboard". Then long-tap the field where you want to paste the data. A small "paste" button should come up. Note, however, that information in the clipboard can be monitored by all apps on your device and clearing the clipboard is not always possible.
|
||||
|
||||
These options can be used in different workflows:
|
||||
### Browser-based workflow
|
||||
If you are browsing the web and need to enter crendentials for a webpage, a simple and powerful workflow is to use the "Share URL" option from the browser's menu. Then select Keepass2Android (or KP2A Offline). Open your database (if it's not already opened) and select the entry you want to enter (if KP2A did not already select the appropriate entry). Use the built-in keyboard or the clipboard to enter the password.
|
||||
### Autofill service based workflow
|
||||
If you have enabled the autofill service and open a (supported) app with a password field, a notification appears in the notification bar. Select this notification to select the appropriate entry. When you return to the app, the password and user field should be filled already.
|
||||
If you have enabled the autofill service and open a (supported) app with a password field, a dropdown appears. Select "Fill with Keepass2Android" to select the appropriate entry. When you return to the app, the password and user field should be filled already.
|
||||
### KP2A based workflow for websites
|
||||
Open KP2A, open your database, select your entry (in this step, the notification bar items should show up already). Now click the URL link of the entry to open a browser window with the website. Use one of the methods described above to enter the credentials.
|
||||
### KP2A Keyboard based workflow
|
||||
@@ -69,16 +70,51 @@ Please see the [Advanced usage of the Keepass2Android keyboard](Advanced-usage-o
|
||||
|
||||
# FAQ
|
||||
|
||||
* Should I use the KP2A keyboard for entering passwords?
|
||||
## Should I use the KP2A keyboard for entering passwords?
|
||||
The KP2A keyboard is meant to quickly "paste" or "type" values from your database to any text fields by using the KP2A icon. The QUERTY keyboard is just for convenience (if you just have the KP2A keyboard activated and need to enter a few letters). However, every other (trustworthy) keyboard is ok as well to enter sensitive information: Keyboard's aren't unsafe in Android. Only the clipboard is. Thus, the KP2A keyboard allows to get information out of the database without using the clipboard.
|
||||
**You can use any keyboard when you enter the main database password**
|
||||
|
||||
* Is it safe to store my kdbx file in the cloud?
|
||||
While it may happen that someone gets access to your kdbx file in the cloud, there is still no need to worry: the purpose of encryption is to protect the data even in case someone gets the kdbx file! As long as you are using a safe master key, you're safe!
|
||||
## Is it safe to store my kdbx file in the cloud?
|
||||
While it may happen that someone gets access to your kdbx file in the cloud, there is still no need to worry: the purpose of encryption is to protect the data even in case someone gets the kdbx file! As long as you are using a safe master key, you're safe! [Key files](https://keepass.info/help/base/keys.html#keyfiles) can help with securing the database even more.
|
||||
|
||||
* Why is Keepass2Android so big?
|
||||
## Doesn't Keepass2Android create automatic backups?
|
||||
Yes and no. Yes: Keepass2Android stores the last successfully opened file as a read-only backup locally on the phone (unless you disable this is in the settings). This should make sure that even if the file gets destroyed during a save operation or gets deleted by accident, you should always have a version that can be opened. (Don't mix this up with the internal file cache which is not meant as a backup and can easily be overwritten even with a corrupt file. This internal file cache is meant for providing writable access even when the original file is not reachable, e.g. when you're offline.)
|
||||
No: The local backup has two shortcomings: It is only one backup and does not allow to revert to older versions. So if you deleted an entry from the database, it might be deleted in the local backup soon as well. The even more important shortcoming is that it is just a local backup. It won't help when your phone gets lost or broken. Please create additional backups on seperate storage!
|
||||
|
||||
## How do I backup the database?
|
||||
If you have stored your database on the cloud, you might rely on your cloud storage providers backups. Make sure they allow you to revert to older revisions in case the file gets corrupted for some reason.
|
||||
If you are working with a local database file, make sure you create regular backups. I suggest you have an aumotated mechanism, e.g. with FolderSync (Lite) which can copy local files from your device to other locations, e.g. your PC in a local network. You can also use USB or tools like MyPhoneExploror to transfer data to your PC. Or, you use a removable storage like an SD card which you keep in a safe place after making the backup.
|
||||
In all cases, you need to verify that your backup is readable! It's even best to test this on another device (e.g. a PC), so you simulate the case that you may lose your phone.
|
||||
|
||||
## I can open my database with fingerprint, but don't remember my master password!
|
||||
It's time for action! As soon as possible, select Settings - Database - Export and choose unencrypted XML (don't put this on the cloud but on a local file). Transfer this file to a PC and import it to a new kdbx file, e.g. with Keepass2. Choose a new master password and make sure you don't forget this password!
|
||||
|
||||
## How can I transfer data from one device to another?
|
||||
* If you are about to get a new Android device, you should make sure you're not losing your passwords in the transition! The first thing you need to make sure is that you can access your .kdbx file (which stores the passwords) on the new device. If it is already stored in the cloud, you only need to make sure you know how to setup the cloud storage on the new device (it might require a password, so make sure you have access to that!).
|
||||
* If the .kdbx-file is stored locally on the old device, make sure you have an up-to-date backup (see above). You can then transfer that backup copy to the new device. (Note: transferring via USB causes data corruption in some cases, use MyPhoneExplorer or similar tools to be sure this does not happen.)
|
||||
* If you are securing your password database with a keyfile, also transfer this key file to the new device.
|
||||
* If you are opening your database with a fingerprint, make sure you also know the master password because fingerprint will not be available immediately on the new device.
|
||||
|
||||
## Why is Keepass2Android's apk so big?
|
||||
Please see [Keepass2Android Apk](Keepass2Android-Apk.md) for more information.
|
||||
|
||||
## I get a message "File is trashed" when reading or writing a file on Google Drive
|
||||
This happens because ocaml-fuse (I guess you are on Linux and use that) moves files to trash and then creates a new one instead of correctly updating the file on Google Drive (each file has a unique ID which Keepass2Android uses). Fortunately, this was fixed: https://github.com/astrada/google-drive-ocamlfuse/issues/494After activating this option, please select "Change database" in KP2A, tap ,"Open file" and browse to the file on Google Drive again. After that, the message should no longer pop up.
|
||||
|
||||
## I get a message "The name must not be empty: null" when opening from Google Drive
|
||||
Please follow these steps:
|
||||
|
||||
* select "Change database" on the password screen, then "Open database" and browse to your file again
|
||||
* go to Android app settings and disable all permissions for the KP2A app. Then try again to open the database file.
|
||||
* reboot the device
|
||||
|
||||
(Before running the following steps, make sure you don't have local changes in your database which have not been synchronized with Google Drive (this can happen if you worked offline). If you have, please open the database from the local cache and go to settings - database settings - export database and make a backup copy of the data.)
|
||||
|
||||
* clear KP2A's app cache in the Android settings
|
||||
* uninstall & reinstall
|
||||
|
||||
One of these has helped all users so far, but unfortunately it's not totally clear to me why different steps are required (or nothing for most users).
|
||||
|
||||
# For developers
|
||||
If you are interested in adding new features, you have two options:
|
||||
Either your features can be implemented as a plug-in. Please see [How to create a plug-in?](How-to-create-a-plug-in_.md) for more information. Or you add the features directly in the source code of the projects and create a pull request.
|
||||
|
||||
@@ -13,10 +13,9 @@ Keepass2Android stores very sensitive user data and therefore implements a plug-
|
||||
|
||||
To tell Kp2a that you're a plug-in, you need to add a simple BroadcastReceiver like this:
|
||||
|
||||
{{
|
||||
```java
|
||||
|
||||
public class PluginAAccessReceiver
|
||||
extends keepass2android.pluginsdk.PluginAccessBroadcastReceiver
|
||||
public class PluginAAccessReceiver extends keepass2android.pluginsdk.PluginAccessBroadcastReceiver
|
||||
{
|
||||
|
||||
@Override
|
||||
@@ -29,33 +28,33 @@ public class PluginAAccessReceiver
|
||||
}
|
||||
|
||||
}
|
||||
}}
|
||||
```
|
||||
|
||||
Here, you define the method getScopes where the list of scopes is created which must be granted by the user. The actual logic of the authorization process is implemented by the base class in the sdk.
|
||||
|
||||
In order to make this broadcast receiver visible to KP2A, add the following lines (probably with the name adapted to your class name) in the AndroidManifest.xml:
|
||||
|
||||
{{
|
||||
<receiver android:name="PluginAAccessReceiver" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="keepass2android.ACTION_TRIGGER_REQUEST_ACCESS" />
|
||||
```xml
|
||||
<receiver android:name="PluginAAccessReceiver" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="keepass2android.ACTION_TRIGGER_REQUEST_ACCESS" />
|
||||
<action android:name="keepass2android.ACTION_RECEIVE_ACCESS" />
|
||||
<action android:name="keepass2android.ACTION_REVOKE_ACCESS" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
}}
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
```
|
||||
|
||||
Please also add a few strings in your resource files (e.g. strings.xml) with the following keys:
|
||||
|
||||
{{
|
||||
```xml
|
||||
<string name="kp2aplugin_title">The Great PluginA</string>
|
||||
<string name="kp2aplugin_shortdesc">Test plugin to demonstrate how plugins work</string>
|
||||
<string name="kp2aplugin_author">[your name here](your-name-here)</string>
|
||||
}}
|
||||
<string name="kp2aplugin_shortdesc">Test plugin to demonstrate how plugins work</string>
|
||||
<string name="kp2aplugin_author">[your name here](your-name-here)</string>
|
||||
```
|
||||
These strings will be displayed to the user when KP2A asks if access should be granted.
|
||||
|
||||
## Modifying the entry view
|
||||
You can add menu options for the full entry or for individual fields of the entry when displayed to the user. This is done, for example, by the QR plugin ([https://play.google.com/store/apps/details?id=keepass2android.plugin.qr](https___play.google.com_store_apps_details_id=keepass2android.plugin.qr)).
|
||||
You can add menu options for the full entry or for individual fields of the entry when displayed to the user. This is done, for example, by the QR plugin ([https://play.google.com/store/apps/details?id=keepass2android.plugin.qr](https://play.google.com/store/apps/details?id=keepass2android.plugin.qr)).
|
||||
In addition, it is even possible to add new fields or modify existing fields. Please see the sample plugin "PluginA" in the KP2A repository for a simple example on how to do this:
|
||||
[https://keepass2android.codeplex.com/SourceControl/latest#src/java/PluginA/src/keepass2android/plugina/PluginAActionReceiver.java](https://keepass2android.codeplex.com/SourceControl/latest#src/java/PluginA/src/keepass2android/plugina/PluginAActionReceiver.java)
|
||||
|
||||
@@ -64,7 +63,7 @@ KP2A 0.9.4 adds a great opportunity for third party apps: Instead of prompting t
|
||||
|
||||
To implement this, simply follow the steps descrIbed above in the sections Preparation and Authorization. Then, wherever appropriate in your app, do something like this:
|
||||
|
||||
{{
|
||||
```java
|
||||
try
|
||||
{
|
||||
PlaceholderFragment.this.startActivityForResult(
|
||||
@@ -73,40 +72,44 @@ To implement this, simply follow the steps descrIbed above in the sections Prepa
|
||||
}
|
||||
catch (ActivityNotFoundException e)
|
||||
{
|
||||
Toast.makeText(PlaceholderFragment.this.getActivity(), "no KP2A host app found", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(
|
||||
PlaceholderFragment.this.getActivity(),
|
||||
"no KP2A host app found",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}}
|
||||
```
|
||||
|
||||
(of course you can use PacketManager to check if the intent can be started instead of catching the Exception).
|
||||
(of course you can use `PacketManager` to check if the intent can be started instead of catching the `Exception`).
|
||||
|
||||
Instead of querying credentials associated with your own app, you might want to query other credentials as well. instead of Kp2aControl.getQueryEntryIntentForOwnPackage() use
|
||||
{{
|
||||
Kp2aControl.getQueryEntryIntent("google.com")
|
||||
}}
|
||||
This requires {"SCOPE_QUERY_CREDENTIALS (whereas getQueryEntryIntentForOwnPackage() requires SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE)"}.
|
||||
Instead of querying credentials associated with your own app, you might want to query other credentials as well. instead of `KpControl.getQueryEntryIntentForOwnPackage()` use
|
||||
`Kp2aControl.getQueryEntryIntent("google.com")`
|
||||
This requires \{"SCOPE_QUERY_CREDENTIALS (whereas getQueryEntryIntentForOwnPackage() requires SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE)"\}.
|
||||
|
||||
The credential data can be retrieved in onActivityResult():
|
||||
|
||||
{{
|
||||
```java
|
||||
if ((requestCode == 1) //queryEntry for own package
|
||||
&& (resultCode == RESULT_OK)) // ensure user granted access and selected something
|
||||
&& (resultCode == RESULT_OK)) // ensure user granted access and selected something
|
||||
{
|
||||
HashMap<String, String> credentials = Kp2aControl.getEntryFieldsFromIntent(data);
|
||||
if (!credentials.isEmpty())
|
||||
{
|
||||
//here we go!
|
||||
Toast.makeText(getActivity(), "retrieved credenitals! Username="+credentials.get(KeepassDefs.UserNameField), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(
|
||||
getActivity(),
|
||||
"retrieved credenitals! Username="+credentials.get(KeepassDefs.UserNameField),
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}}
|
||||
```
|
||||
|
||||
Note that you get access to all strings (Title, Username, Password, URL, Notes + any user defined strings) in the entry. This may be in intersting in combination with the following section:
|
||||
|
||||
## Storing data in KP2A
|
||||
If you allow the user to set up an account in your app or create a password, e.g. for encryption, please add an option to store this data in the Keepass2Android database, as this will lead to great workflows for the user. It's as simple as
|
||||
|
||||
{{
|
||||
```java
|
||||
try {
|
||||
HashMap<String, String> fields = new HashMap<String, String>();
|
||||
//standard fields
|
||||
@@ -124,16 +127,15 @@ try {
|
||||
|
||||
//add to KP2A
|
||||
PlaceholderFragment.this.startActivityForResult(
|
||||
Kp2aControl
|
||||
.getAddEntryIntent(fields, protectedFields),
|
||||
2);
|
||||
Kp2aControl.getAddEntryIntent(fields, protectedFields),
|
||||
2);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(
|
||||
PlaceholderFragment.this.getActivity(),
|
||||
"no KP2A host app found",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
PlaceholderFragment.this.getActivity(),
|
||||
"no KP2A host app found",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}}
|
||||
```
|
||||
|
||||
Note that this does not even require access authorization because the user will actively save the entry anyways (after selecting the group where to create it.)
|
||||
|
||||
@@ -142,13 +144,13 @@ With {"SCOPE_DATABASE_ACTIONS"}, you will be informed when the user opens, close
|
||||
|
||||
PluginA uses this to simply display a toast message in its ActionReceiver:
|
||||
|
||||
{{
|
||||
```java
|
||||
@Override
|
||||
protected void dbAction(DatabaseAction db) {
|
||||
|
||||
Log.d("PluginA", db.getAction() + " in file " + db.getFileDisplayName() + " ("+db.getFilePath()+")");
|
||||
}
|
||||
}}
|
||||
```
|
||||
|
||||
|
||||
## Sample plugin
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
on how to set up a Keepass 2 database with Yubikey/OTP protection.<br>
|
||||
<br>
|
||||
After successful setup you should have the database file, e.g. yubi.kdbx, and the OTP auxiliary file, e.g. yubi.otp.xml, both in the same folder.<br>
|
||||
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767825"><img title="OTPAuxFile" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767826" alt="OTPAuxFile" width="513" height="40" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<a href="How to use Keepass2Android with YubiKey NEO_OTPAuxFile_2.png"><img title="OTPAuxFile" src="How to use Keepass2Android with YubiKey NEO_OTPAuxFile_thumb.png" alt="OTPAuxFile" width="513" height="40" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<p>Make sure you make <strong>both files</strong> available to Keepass2Android, e.g. by placing them both in your Dropbox.</p>
|
||||
<p>Now you should check your NDEF setup of the Yubikey NEO. Therefore, go to the Tools menu in the Yubico Personalization Utility. Select the same slot as used for OTPs with Keepass 2. The default setting for NDEF type and payload should work. If you experience
|
||||
problems, you may use the configuration as shown in this screenshot or simply press the “Reset” button:</p>
|
||||
<p><a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767911"><img title="image" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767912" alt="image" width="760" height="622" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<p><a href="How to use Keepass2Android with YubiKey NEO_image_2.png"><img title="image" src="How to use Keepass2Android with YubiKey NEO_image_thumb.png" alt="image" width="760" height="622" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<p><br>
|
||||
<br>
|
||||
In Keepass2Android, select "Open file" and locate your database file, e.g. yubi.kdbx.<br>
|
||||
<br>
|
||||
In the password screen under "Select master key type" select "Password + OTP".</p>
|
||||
<p><a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767913"><img title="Screenshot_2013-12-13-06-38-50" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767914" alt="Screenshot_2013-12-13-06-38-50" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<p><a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-50_2.png"><img title="Screenshot_2013-12-13-06-38-50" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-50_thumb.png" alt="Screenshot_2013-12-13-06-38-50" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<p>Click "Load auxiliary OTP file". This is required to load the information how many OTPs must be entered. As loading the file might require user action in some cases, this is not performed automatically.<br>
|
||||
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767915"><img title="Screenshot_2013-12-13-06-38-12" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767916" alt="Screenshot_2013-12-13-06-38-12" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
|
||||
<a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-12_2.png"><img title="Screenshot_2013-12-13-06-38-12" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-12_thumb.png" alt="Screenshot_2013-12-13-06-38-12" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
|
||||
After loading the OTP auxiliary file, you should see a few text fields for entering the OTPs. Now swipe your YubiKey NEO at the back of your Android device. If you have multiple apps which can handle NFC actions, you might be prompted to select which app to
|
||||
use. Select Keepass2Android in this case. Swipe your YubiKey again until all OTP fields are filled. Note: You don't need to select the next text field, this is done automatically!<br>
|
||||
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767917"><img title="Screenshot_2013-12-13-06-38-36" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767918" alt="Screenshot_2013-12-13-06-38-36" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
|
||||
<a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-36_2.png"><img title="Screenshot_2013-12-13-06-38-36" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-36_thumb.png" alt="Screenshot_2013-12-13-06-38-36" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
|
||||
Don't forget to also enter your password and click OK. You will see the “Saving auxiliary OTP file…” dialog. Note that there is some encryption envolved which is probably fast on your PC but might take some time on your mobile device. You
|
||||
can reduce the look-ahead window length to speed this up.<br>
|
||||
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767919"><img title="Screenshot_2013-12-13-06-39-47" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767920" alt="Screenshot_2013-12-13-06-39-47" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-39-47_2.png"><img title="Screenshot_2013-12-13-06-39-47" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-39-47_thumb.png" alt="Screenshot_2013-12-13-06-39-47" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
|
||||
<h2> </h2>
|
||||
<h2>A note about offline access</h2>
|
||||
<p>If your database is stored in the cloud or on the web, you can still access it if you have enabled file caching (which is on by default). With OTPs, this becomes a little bit more complicated: If you repeatedly open your datbase while being offline, the
|
||||
OTP counter stored on the Yubikey will be increased. Don’t forget to synchronize the database (which will also synchronize the OTP auxiliary file) as soon as possible to avoid problems with accessing your database on other devices! If you often need
|
||||
to open the database while you’re offline, consider increasing the look-ahead window length!</p>
|
||||
</div><div class="ClearBoth"></div>
|
||||
</div><div class="ClearBoth"></div>
|
||||
|
||||
@@ -2,7 +2,7 @@ Keepass2Android's apk is pretty big, e.g. when comparing to Keepassdroid. The ma
|
||||
|
||||
Here's a list of what is contained in the Keepass2Android 0.9.1 application package:
|
||||
|
||||
{{
|
||||
```
|
||||
Mono for Android
|
||||
.net dlls 5.0 MB
|
||||
Runtime 2.5 MB
|
||||
@@ -22,4 +22,4 @@ Java/Mono bindings 0.5 MB
|
||||
rest 0.3 MB
|
||||
|
||||
TOTAL 13 MB
|
||||
}}
|
||||
```
|
||||
|
||||
20
docs/OreoAutoFill.md
Normal file
20
docs/OreoAutoFill.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Google has introduced the Android Autofill interface in Android 8. Keepass2Android supports this interface. In most Android apps and all Autofill-enabled browsers, this is the most convenient way of entering passwords. As soon as you focus a field, you will see a popup "Fill with Keepass2Android".
|
||||
|
||||
<img src="autofill-facebook.png" />
|
||||
|
||||
After clicking this popup, you can unlock your KP2A database. If automatic look up succeeds, KP2A will close automatically, if not you are prompted to select the entry you want to auto-fill. When returning to the target app, the fields should be filled automatically already.
|
||||
|
||||
As of January 2018, the following browsers are known to have Android Autofill support:
|
||||
|
||||
* Firefox Focus / Firefox Klar
|
||||
* Opera Mini
|
||||
|
||||
These browsers do not (yet) have autofill support:
|
||||
|
||||
* Google Chrome
|
||||
* Firefox for Android ([bugzilla entry](https://bugzilla.mozilla.org/show_bug.cgi?id=1352011))
|
||||
* Brave-Browser
|
||||
* Opera
|
||||
|
||||
Please use the Share-URL-feature and the built-in KP2A keyboard for these browsers.
|
||||
|
||||
@@ -11,9 +11,7 @@ is the author of Keepass2Android and Keepass2Android Offline.
|
||||
|
||||
The contents of your password database is yours and is never collected by us. Keepass2Android stores this data on a location chosen by the user and encrypted in the Keepass database format. The app author does not have any access, neither to the files nor the contents. Depending on the user's choice of the storage location, the files may be stored on third-party servers like Dropbox or Google Drive.
|
||||
|
||||
Keepass2Android does not collect personal identifiable information. After unexpected errors or crashes of the app, the user may be asked if he/she whants to send an error report (Keepass2Android regular only). Error reports do not contain database contents, except (depending on the error message) UUIDs of entries. They may contain file paths if the error was related to a failed file operation. Error reports sent from inside the app are sent using Xamarin Insights.
|
||||
|
||||
The app author does not pass any of this data to third parties.
|
||||
Keepass2Android does not collect personal identifiable information. For debugging purposes, the user may activate creating a debug log. This collects data inside the app and is not accessible to any other app nor the author of the app, unless the user explicitly sends the debug log to the author. Debug logs usually do not contain personal identifiable information, except if such information is part of file or folder names. Debug logs will not be shared with third parties unless explicitly authorized by the sender.
|
||||
|
||||
# What Android permissions are required?
|
||||
|
||||
@@ -22,5 +20,4 @@ The app author does not pass any of this data to third parties.
|
||||
* **Storage**: Required to allow the user to read/store password databases or key files on the device locally.
|
||||
* **Fingerprint**: Required if you want to use fingerprint unlock.
|
||||
* **Vibrate**: Required by the built-in keyboard (vibrate on key press)
|
||||
* **Bind Accessibility service**: Required to provide the Auto-Fill accessibility service.
|
||||
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
<h1 align="center"><img src="/src/keepass2android/Resources/mipmap-xxxhdpi/ic_launcher_online.png" align="center" width="100" alt="Keepass2Android Logo">Keepass2Android</h1>
|
||||
|
||||
|
||||
# What is Keepass2Android?
|
||||
Keepass2Android is a password manager app. It allows to store and retrieve passwords and other sensitive information in a file called "database". This database is secured with a so-called master password. The master password typically is a strong password and can be complemented with a second factor for additional security.
|
||||
The password database file can be synchronized across different devices. This works best using one of the built-in cloud storage options, but can also be performed with third-party apps. Keepass2Android is compatible with Keepass 1 and Keepass 2 on Windows and KepassX on Linux.
|
||||
The password database file can be synchronized across different devices. This works best using one of the built-in cloud storage options, but can also be performed with third-party apps. Keepass2Android is compatible with Keepass 1 and Keepass 2 on Windows and KeepassX on Linux.
|
||||
|
||||
# Where to get it?
|
||||
Regular stable releases of Keepass2Android are available on [Google Play](https://play.google.com/store/apps/details?id=keepass2android.keepass2android).
|
||||
|
||||
Beta-releases can be obtained by opting in to the [Beta testing channel](https://play.google.com/apps/testing/keepass2android.keepass2android). Please join the [Beta tester group](https://plus.google.com/communities/107293657110547776032) for news and discussions about the latest beta releases.
|
||||
Beta-releases can be obtained by opting in to the [Beta testing channel](https://play.google.com/apps/testing/keepass2android.keepass2android) or [Beta testing channel for Keepass2Android Offline](https://play.google.com/apps/testing/keepass2android.keepass2android_nonet). Please join the [Beta tester group](https://plus.google.com/communities/107293657110547776032) for news and discussions about the latest beta releases.
|
||||
|
||||
# How can I contribute?
|
||||
* Help to translate Keepass2Android into your language or improve translations at [our Crowdin page](http://crowdin.net/project/keepass2android)
|
||||
* Add features by [creating a plugin](How-to-create-a-plug-in_) or creating a pull request. You might want to contact me before you start working so I can coordinate efforts.
|
||||
* Add features by [creating a plugin](How-to-create-a-plug-in_.md) or creating a pull request. You might want to contact me before you start working so I can coordinate efforts.
|
||||
* [Become a GitHub sponsor to boost 🚀 development](https://github.com/sponsors/PhilippC)
|
||||
* [Make a donation](http://philipp.crocoll.net/donate.php)
|
||||
|
||||
# How do I learn more?
|
||||
Please see the [documentation](Documentation.md).
|
||||
|
||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
|
||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
|
||||
|
||||
1
docs/_config.yml
Normal file
1
docs/_config.yml
Normal file
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-slate
|
||||
BIN
docs/autofill-facebook.png
Normal file
BIN
docs/autofill-facebook.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
3287
graphics/launcher_icon/Logo-blue.svg
Normal file
3287
graphics/launcher_icon/Logo-blue.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 353 KiB |
BIN
graphics/launcher_icon/Logo-green-96.png
Normal file
BIN
graphics/launcher_icon/Logo-green-96.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
47
graphics/launcher_icon/Logo-green-foreground.svg
Normal file
47
graphics/launcher_icon/Logo-green-foreground.svg
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 800 800"
|
||||
enable-background="new 0 0 800 800"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="Logo-green-foreground.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"><metadata
|
||||
id="metadata4969"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs4967" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview4965"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.75130096"
|
||||
inkscape:cx="413.59403"
|
||||
inkscape:cy="332.90312"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
d="m 318.7,232 c 13.6,0 24.6,10.9 24.6,24.4 0,13.5 -11,24.4 -24.6,24.4 -13.6,0 -24.6,-10.9 -24.6,-24.4 0,-13.5 11,-24.4 24.6,-24.4 z m 134.8,24.4 c 0,13.5 11,24.4 24.6,24.4 13.6,0 24.6,-10.9 24.6,-24.4 0,-13.5 -11,-24.4 -24.6,-24.4 -13.6,0 -24.6,10.9 -24.6,24.4 z M 399.8,177.7 M 140.2,600.6 v 47 h 517.3 v -47 z m 0,-249.7 v 47 h 517.3 v -47 z m -0.1,130.3 h 191.8 c -0.8,-4.1 -1.2,-8.3 -1.2,-12.4 0,-12.4 3.4,-24.2 9.9,-34.6 H 140.1 Z m 517.4,0 v -47 H 454.9 c 6.5,10.4 9.8,22.2 9.8,34.6 0,4.1 -0.4,8.3 -1.2,12.4 z m -517.4,36.2 v 47 h 186.6 l 14.3,-47 z m 314.2,0 14.4,47 h 188.8 v -47 z m -21.6,48.4 -21,-68.9 2.7,-1.6 c 10.3,-5.9 16.7,-16.9 16.7,-28.6 0,-18.2 -15,-33 -33.3,-33 -18.3,0 -33.3,14.8 -33.3,33 0,11.8 6.4,22.7 16.7,28.6 l 2.7,1.6 -21.1,68.9 z m 74.8,-407.3 0.2,-0.3 35.6,-51.3 c 2.4,-3.5 1.8,-8.1 -1.4,-10.3 -3.2,-2.2 -7.7,-1.1 -10.2,2.4 l -37.2,53.5 -0.1,0.3 c -29.3,-11.8 -62.1,-18.5 -96.8,-18.5 -35.2,0 -68.5,6.9 -98.1,19 L 261.8,99 c -2.4,-3.5 -7,-4.6 -10.2,-2.4 -3.2,2.2 -3.8,6.8 -1.4,10.3 l 36.2,52.2 c -66.8,32.2 -111.9,92.4 -111.9,161.3 h 42.9 c 0,-79.1 80.8,-143.5 180.1,-143.5 99.3,0 180.1,64.3 180.1,143.5 h 42.9 c 0.2,-69.3 -45.4,-129.8 -113,-161.9 z"
|
||||
id="path4962"
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd" /></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
3279
graphics/launcher_icon/Logo-green.svg
Normal file
3279
graphics/launcher_icon/Logo-green.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 353 KiB |
64
src/AdalBindings/AdalBindings.csproj
Normal file
64
src/AdalBindings/AdalBindings.csproj
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{0B109C0E-0514-4340-8779-5BD6A0DDE84E}</ProjectGuid>
|
||||
<ProjectTypeGuids>{10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AdalBindings</RootNamespace>
|
||||
<AssemblyName>AdalBindings</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
<LibraryProjectZip Include="Jars\adal-1.14.0.aar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TransformFile Include="Transforms\Metadata.xml" />
|
||||
<TransformFile Include="Transforms\EnumFields.xml" />
|
||||
<TransformFile Include="Transforms\EnumMethods.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gson-2.3.1.jar" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
48
src/AdalBindings/Additions/AboutAdditions.txt
Normal file
48
src/AdalBindings/Additions/AboutAdditions.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
Additions allow you to add arbitrary C# to the generated classes
|
||||
before they are compiled. This can be helpful for providing convenience
|
||||
methods or adding pure C# classes.
|
||||
|
||||
== Adding Methods to Generated Classes ==
|
||||
|
||||
Let's say the library being bound has a Rectangle class with a constructor
|
||||
that takes an x and y position, and a width and length size. It will look like
|
||||
this:
|
||||
|
||||
public partial class Rectangle
|
||||
{
|
||||
public Rectangle (int x, int y, int width, int height)
|
||||
{
|
||||
// JNI bindings
|
||||
}
|
||||
}
|
||||
|
||||
Imagine we want to add a constructor to this class that takes a Point and
|
||||
Size structure instead of 4 ints. We can add a new file called Rectangle.cs
|
||||
with a partial class containing our new method:
|
||||
|
||||
public partial class Rectangle
|
||||
{
|
||||
public Rectangle (Point location, Size size) :
|
||||
this (location.X, location.Y, size.Width, size.Height)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
At compile time, the additions class will be added to the generated class
|
||||
and the final assembly will a Rectangle class with both constructors.
|
||||
|
||||
|
||||
== Adding C# Classes ==
|
||||
|
||||
Another thing that can be done is adding fully C# managed classes to the
|
||||
generated library. In the above example, let's assume that there isn't a
|
||||
Point class available in Java or our library. The one we create doesn't need
|
||||
to interact with Java, so we'll create it like a normal class in C#.
|
||||
|
||||
By adding a Point.cs file with this class, it will end up in the binding library:
|
||||
|
||||
public class Point
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
}
|
||||
24
src/AdalBindings/Jars/AboutJars.txt
Normal file
24
src/AdalBindings/Jars/AboutJars.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
This directory is for Android .jars.
|
||||
|
||||
There are 2 types of jars that are supported:
|
||||
|
||||
== Input Jar ==
|
||||
|
||||
This is the jar that bindings should be generated for.
|
||||
|
||||
For example, if you were binding the Google Maps library, this would
|
||||
be Google's "maps.jar".
|
||||
|
||||
Set the build action for these jars in the properties page to "InputJar".
|
||||
|
||||
|
||||
== Reference Jars ==
|
||||
|
||||
These are jars that are referenced by the input jar. C# bindings will
|
||||
not be created for these jars. These jars will be used to resolve
|
||||
types used by the input jar.
|
||||
|
||||
NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
|
||||
based on the Target Framework selected.
|
||||
|
||||
Set the build action for these jars in the properties page to "ReferenceJar".
|
||||
BIN
src/AdalBindings/Jars/adal-1.14.0.aar
Normal file
BIN
src/AdalBindings/Jars/adal-1.14.0.aar
Normal file
Binary file not shown.
30
src/AdalBindings/Properties/AssemblyInfo.cs
Normal file
30
src/AdalBindings/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Android.App;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AdalBindings")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AdalBindings")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
14
src/AdalBindings/Transforms/EnumFields.xml
Normal file
14
src/AdalBindings/Transforms/EnumFields.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<enum-field-mappings>
|
||||
<!--
|
||||
This example converts the constants Fragment_id, Fragment_name,
|
||||
and Fragment_tag from android.support.v4.app.FragmentActivity.FragmentTag
|
||||
to an enum called Android.Support.V4.App.FragmentTagType with values
|
||||
Id, Name, and Tag.
|
||||
|
||||
<mapping jni-class="android/support/v4/app/FragmentActivity$FragmentTag" clr-enum-type="Android.Support.V4.App.FragmentTagType">
|
||||
<field jni-name="Fragment_name" clr-name="Name" value="0" />
|
||||
<field jni-name="Fragment_id" clr-name="Id" value="1" />
|
||||
<field jni-name="Fragment_tag" clr-name="Tag" value="2" />
|
||||
</mapping>
|
||||
-->
|
||||
</enum-field-mappings>
|
||||
13
src/AdalBindings/Transforms/EnumMethods.xml
Normal file
13
src/AdalBindings/Transforms/EnumMethods.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<enum-method-mappings>
|
||||
<!--
|
||||
This example changes the Java method:
|
||||
android.support.v4.app.Fragment.SavedState.writeToParcel (int flags)
|
||||
to be:
|
||||
android.support.v4.app.Fragment.SavedState.writeToParcel (Android.OS.ParcelableWriteFlags flags)
|
||||
when bound in C#.
|
||||
|
||||
<mapping jni-class="android/support/v4/app/Fragment.SavedState">
|
||||
<method jni-name="writeToParcel" parameter="flags" clr-enum-type="Android.OS.ParcelableWriteFlags" />
|
||||
</mapping>
|
||||
-->
|
||||
</enum-method-mappings>
|
||||
13
src/AdalBindings/Transforms/Metadata.xml
Normal file
13
src/AdalBindings/Transforms/Metadata.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<metadata>
|
||||
<!--
|
||||
This sample removes the class: android.support.v4.content.AsyncTaskLoader.LoadTask:
|
||||
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />
|
||||
|
||||
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
|
||||
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
|
||||
-->
|
||||
<remove-node path="/api/package[@name='com.microsoft.aad.adal']/class[@name='AuthenticationActivity']" />
|
||||
<remove-node path="/api/package[@name='com.microsoft.aad.adal']/class[@name='DateTimeAdapter']" />
|
||||
<remove-node path="/api/package[@name='com.microsoft.aad.adal']" />
|
||||
|
||||
</metadata>
|
||||
@@ -10,8 +10,9 @@
|
||||
<RootNamespace>AndroidFileChooserBinding</RootNamespace>
|
||||
<AssemblyName>AndroidFileChooserBinding</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -47,9 +48,6 @@
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Xamarin.Android.Support.v4">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.v4.20.0.0.4\lib\MonoAndroid10\Xamarin.Android.Support.v4.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Xamarin.Android.Support.v4" version="20.0.0.4" targetFramework="MonoAndroid22" requireReinstallation="True" />
|
||||
|
||||
</packages>
|
||||
@@ -26,6 +26,7 @@
|
||||
android:hint="@string/http_auth_dialog_password"
|
||||
android:inputType="textPassword"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="20dp" />
|
||||
android:paddingBottom="20dp"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
</LinearLayout>
|
||||
BIN
src/JavaFileStorageBindings/Jars/dropbox-core-sdk-3.1.1.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/dropbox-core-sdk-3.1.1.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/gdrive/httpclient-4.0.3.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/gdrive/httpclient-4.0.3.jar
Normal file
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/gdrive/httpcore-4.0.1.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/gdrive/httpcore-4.0.1.jar
Normal file
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/gdrive/httpmime-4.0.3.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/gdrive/httpmime-4.0.3.jar
Normal file
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/gdrive/json_simple-1.1.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/gdrive/json_simple-1.1.jar
Normal file
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/gdrive/jsr305-1.3.9.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/gdrive/jsr305-1.3.9.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/gson-2.8.1.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/gson-2.8.1.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/okhttp-4.10.0-RC1.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/okhttp-4.10.0-RC1.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/okhttp-digest-2.5.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/okhttp-digest-2.5.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/okio-2.9.0.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/okio-2.9.0.jar
Normal file
Binary file not shown.
@@ -10,8 +10,10 @@
|
||||
<RootNamespace>JavaFileStorageBindings</RootNamespace>
|
||||
<AssemblyName>JavaFileStorageBindings</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidClassParser>class-parse</AndroidClassParser>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -50,15 +52,6 @@
|
||||
<Reference Include="GooglePlayServicesLib">
|
||||
<HintPath>..\Components\googleplayservices-19.0.0\lib\android\GooglePlayServicesLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v4">
|
||||
<HintPath>..\Components\googleplayservices-19.0.0\lib\android\Xamarin.Android.Support.v4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v7.AppCompat">
|
||||
<HintPath>..\Components\googleplayservices-19.0.0\lib\android\Xamarin.Android.Support.v7.AppCompat.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.v7.MediaRouter">
|
||||
<HintPath>..\Components\googleplayservices-19.0.0\lib\android\Xamarin.Android.Support.v7.MediaRouter.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -90,13 +83,7 @@
|
||||
</XamarinComponentReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-3.4.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gson-2.3.1.jar" />
|
||||
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\msa-auth-0.8.6\classes-msa-auth.jar" />
|
||||
@@ -105,12 +92,66 @@
|
||||
<EmbeddedReferenceJar Include="Jars\onedrive-sdk-android-1.2.2\classes-onedrive-sdk.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\adal-1.1.19\classes-adal.jar" />
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\commons-logging-1.1.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-client-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-client-android-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-services-drive-v2-rev102-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-android-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-jackson-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-jackson2-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-oauth-client-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\httpclient-4.0.3.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\httpcore-4.0.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\httpmime-4.0.3.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\json_simple-1.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\jsr305-1.3.9.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-gson-1.16.0-rc.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\jackson-core-2.7.4.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okio-1.9.0.jar" />
|
||||
<EmbeddedJar Include="Jars\dropbox-core-sdk-3.1.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gson-2.8.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-digest-2.5.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okio-2.9.0.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-4.10.0-RC1.jar" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -11,6 +11,8 @@
|
||||
<remove-node path="/api/package[@name='com.jcraft.jsch.jcraft']" />
|
||||
<remove-node path="/api/package[@name='com.jcraft.jzlib']" />
|
||||
|
||||
<remove-node path="/api/package[@name='com.pcloud.sdk']" />
|
||||
|
||||
<remove-node path="/api/package[@name='com.dropbox.core']" />
|
||||
<remove-node path="/api/package[@name='com.dropbox.core.util']" />
|
||||
<remove-node path="/api/package[@name='com.dropbox.core.http']" />
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
<RootNamespace>KP2AKdbLibraryBinding</RootNamespace>
|
||||
<AssemblyName>KP2AKdbLibraryBinding</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -52,10 +53,11 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<LibraryProjectZip Include="..\java\KP2AKdbLibrary\app\build\outputs\aar\app-debug.aar">
|
||||
<Link>Jars\app-debug.aar</Link>
|
||||
</LibraryProjectZip>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
<EmbeddedNativeLibrary Include="libs\armeabi-v7a\libfinal-key.so" />
|
||||
<EmbeddedNativeLibrary Include="libs\armeabi\libfinal-key.so" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TransformFile Include="Transforms\Metadata.xml">
|
||||
@@ -65,9 +67,7 @@
|
||||
<TransformFile Include="Transforms\EnumMethods.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedJar Include="..\java\KP2AKdbLibrary\bin\kp2akdblibrary.jar">
|
||||
<Link>Jars\kp2akdblibrary.jar</Link>
|
||||
</EmbeddedJar>
|
||||
<Folder Include="libs\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29418.71
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
||||
EndProject
|
||||
@@ -13,8 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBu
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwofishCipher", "TwofishCipher\TwofishCipher.csproj", "{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaFileStorageBindings", "JavaFileStorageBindings\JavaFileStorageBindings.csproj", "{48574278-4779-4B3A-A9E4-9CF1BC285D0B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidFileChooserBinding", "AndroidFileChooserBinding\AndroidFileChooserBinding.csproj", "{3C0F7FE5-639F-4422-A087-8B26CF862D1B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KP2AKdbLibraryBinding", "KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj", "{70D3844A-D9FA-4A64-B205-A84C6A822196}"
|
||||
@@ -23,10 +21,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginSdkBinding", "PluginS
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Android", "netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj", "{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCloudBindings", "PCloudBindings\PCloudBindings.csproj", "{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -109,8 +107,8 @@ Global
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -156,19 +154,25 @@ Global
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
@@ -181,8 +185,8 @@ Global
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -199,8 +203,8 @@ Global
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -217,8 +221,8 @@ Global
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -247,24 +251,6 @@ Global
|
||||
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
|
||||
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
@@ -283,10 +269,37 @@ Global
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2B48EDA2-ABCE-4DB5-A609-DFDF5FAAE767}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
|
||||
@@ -21,7 +21,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using keepass2android;
|
||||
#if KeePassUAP
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
@@ -55,7 +55,10 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
get { return "AES-KDF"; }
|
||||
}
|
||||
|
||||
public AesKdf()
|
||||
public override byte[] GetSeed(KdfParameters p)
|
||||
{ return p.GetByteArray(ParamSeed); }
|
||||
|
||||
public AesKdf()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -141,6 +144,7 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
||||
ulong uNumRounds)
|
||||
{
|
||||
Kp2aLog.Log("Warning: transforming key managed. Expect this to be slow!");
|
||||
#if KeePassUAP
|
||||
KeyParameter kp = new KeyParameter(pbKeySeed32);
|
||||
AesEngine aes = new AesEngine();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace KeePassLib.Cryptography.KeyDerivation
|
||||
@@ -68,7 +69,10 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
get { return "Argon2"; }
|
||||
}
|
||||
|
||||
public Argon2Kdf()
|
||||
public override byte[] GetSeed(KdfParameters p)
|
||||
{ return p.GetByteArray(ParamSalt); }
|
||||
|
||||
public Argon2Kdf()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -124,8 +128,44 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
byte[] pbSecretKey = p.GetByteArray(ParamSecretKey);
|
||||
byte[] pbAssocData = p.GetByteArray(ParamAssocData);
|
||||
|
||||
if (pbSecretKey != null) {
|
||||
throw new ArgumentOutOfRangeException("Unsupported configuration: non-null pbSecretKey");
|
||||
}
|
||||
|
||||
if (pbAssocData != null) {
|
||||
throw new ArgumentOutOfRangeException("Unsupported configuration: non-null pbAssocData");
|
||||
}
|
||||
|
||||
/*
|
||||
byte[] pbRet = Argon2d(pbMsg, pbSalt, uPar, uMem, uIt,
|
||||
32, v, pbSecretKey, pbAssocData);
|
||||
*/
|
||||
|
||||
IntPtr msgPtr = Marshal.AllocHGlobal(pbMsg.Length);
|
||||
IntPtr saltPtr = Marshal.AllocHGlobal(pbSalt.Length);
|
||||
IntPtr retPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(pbMsg, 0, msgPtr, pbMsg.Length);
|
||||
Marshal.Copy(pbSalt, 0, saltPtr, pbSalt.Length);
|
||||
|
||||
const UInt32 Argon2_d = 0;
|
||||
|
||||
int ret = argon2_hash(
|
||||
(UInt32)uIt, (UInt32)(uMem / 1024), uPar,
|
||||
msgPtr, (IntPtr)pbMsg.Length,
|
||||
saltPtr, (IntPtr)pbSalt.Length,
|
||||
retPtr, (IntPtr)32,
|
||||
(IntPtr)0, (IntPtr)0, Argon2_d, v);
|
||||
|
||||
if (ret != 0) {
|
||||
throw new Exception("argon2_hash failed with " + ret);
|
||||
}
|
||||
|
||||
byte[] pbRet = new byte[32];
|
||||
Marshal.Copy(retPtr, pbRet, 0, 32);
|
||||
|
||||
Marshal.FreeHGlobal(msgPtr);
|
||||
Marshal.FreeHGlobal(saltPtr);
|
||||
Marshal.FreeHGlobal(retPtr);
|
||||
|
||||
if(uMem > (100UL * 1024UL * 1024UL)) GC.Collect();
|
||||
return pbRet;
|
||||
@@ -140,5 +180,14 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
MaxIterations, uMilliseconds, true);
|
||||
return p;
|
||||
}
|
||||
|
||||
[DllImport("argon2")]
|
||||
static extern int argon2_hash(
|
||||
UInt32 t_cost, UInt32 m_cost, UInt32 parallelism,
|
||||
IntPtr pwd, IntPtr pwdlen,
|
||||
IntPtr salt, IntPtr saltlen,
|
||||
IntPtr hash, IntPtr hashlen,
|
||||
IntPtr encoded, IntPtr encodedlen,
|
||||
UInt32 type, UInt32 version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
get;
|
||||
}
|
||||
|
||||
public virtual KdfParameters GetDefaultParameters()
|
||||
public abstract byte[] GetSeed(KdfParameters p);
|
||||
|
||||
public virtual KdfParameters GetDefaultParameters()
|
||||
{
|
||||
return new KdfParameters(this.Uuid);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
|
||||
<AndroidResgenClass>Resource</AndroidResgenClass>
|
||||
<AssemblyName>KeePassLib2Android</AssemblyName>
|
||||
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<NuGetPackageImportStamp>8482b288</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
|
||||
@@ -20,11 +20,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using KeePassLib.Cryptography;
|
||||
using KeePassLib.Cryptography.KeyDerivation;
|
||||
using KeePassLib.Native;
|
||||
using KeePassLib.Resources;
|
||||
using KeePassLib.Security;
|
||||
using KeePassLib.Utility;
|
||||
@@ -163,11 +160,12 @@ namespace KeePassLib.Keys
|
||||
{
|
||||
return (T) GetUserKey(typeof (T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the composite key from the supplied user key sources (password,
|
||||
/// key file, user account, computer ID, etc.).
|
||||
/// </summary>
|
||||
private byte[] CreateRawCompositeKey32()
|
||||
private byte[] CreateRawCompositeKey32(byte[] mPbMasterSeed, byte[] mPbKdfSeed)
|
||||
{
|
||||
ValidateUserKeys();
|
||||
|
||||
@@ -176,6 +174,8 @@ namespace KeePassLib.Keys
|
||||
int cbData = 0;
|
||||
foreach(IUserKey pKey in m_vUserKeys)
|
||||
{
|
||||
if (pKey is ISeedBasedUserKey)
|
||||
((ISeedBasedUserKey)pKey).SetParams(mPbMasterSeed, mPbKdfSeed);
|
||||
ProtectedBinary b = pKey.KeyData;
|
||||
if(b != null)
|
||||
{
|
||||
@@ -200,51 +200,25 @@ namespace KeePassLib.Keys
|
||||
return pbHash;
|
||||
}
|
||||
|
||||
public bool EqualsValue(CompositeKey ckOther)
|
||||
{
|
||||
if(ckOther == null) throw new ArgumentNullException("ckOther");
|
||||
|
||||
byte[] pbThis = CreateRawCompositeKey32();
|
||||
byte[] pbOther = ckOther.CreateRawCompositeKey32();
|
||||
bool bResult = MemUtil.ArraysEqual(pbThis, pbOther);
|
||||
MemUtil.ZeroByteArray(pbOther);
|
||||
MemUtil.ZeroByteArray(pbThis);
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds)
|
||||
{
|
||||
Debug.Assert(pbKeySeed32 != null);
|
||||
if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
|
||||
Debug.Assert(pbKeySeed32.Length == 32);
|
||||
if(pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32");
|
||||
|
||||
AesKdf kdf = new AesKdf();
|
||||
KdfParameters p = kdf.GetDefaultParameters();
|
||||
p.SetUInt64(AesKdf.ParamRounds, uNumRounds);
|
||||
p.SetByteArray(AesKdf.ParamSeed, pbKeySeed32);
|
||||
|
||||
return GenerateKey32(p);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a 32-byte (256-bit) key from the composite key.
|
||||
/// </summary>
|
||||
public ProtectedBinary GenerateKey32(KdfParameters p)
|
||||
public ProtectedBinary GenerateKey32(KdfParameters p, byte[] mPbMasterSeed)
|
||||
{
|
||||
if(p == null) { Debug.Assert(false); throw new ArgumentNullException("p"); }
|
||||
|
||||
byte[] pbRaw32 = CreateRawCompositeKey32();
|
||||
|
||||
KdfEngine kdf = KdfPool.Get(p.KdfUuid);
|
||||
if (kdf == null) // CryptographicExceptions are translated to "file corrupted"
|
||||
throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph +
|
||||
KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph +
|
||||
"UUID: " + p.KdfUuid.ToHexString() + ".");
|
||||
|
||||
byte[] pbRaw32 = CreateRawCompositeKey32(mPbMasterSeed, kdf.GetSeed(p));
|
||||
if((pbRaw32 == null) || (pbRaw32.Length != 32))
|
||||
{ Debug.Assert(false); return null; }
|
||||
|
||||
KdfEngine kdf = KdfPool.Get(p.KdfUuid);
|
||||
if(kdf == null) // CryptographicExceptions are translated to "file corrupted"
|
||||
throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph +
|
||||
KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph +
|
||||
"UUID: " + p.KdfUuid.ToHexString() + ".");
|
||||
|
||||
byte[] pbTrf32 = kdf.Transform(pbRaw32, p);
|
||||
if(pbTrf32 == null) { Debug.Assert(false); return null; }
|
||||
@@ -279,6 +253,11 @@ namespace KeePassLib.Keys
|
||||
}
|
||||
}
|
||||
|
||||
public interface ISeedBasedUserKey
|
||||
{
|
||||
void SetParams(byte[] masterSeed, byte[] mPbKdfSeed);
|
||||
}
|
||||
|
||||
public sealed class InvalidCompositeKeyException : Exception
|
||||
{
|
||||
public override string Message
|
||||
|
||||
@@ -38,9 +38,11 @@ namespace KeePassLib.Keys
|
||||
get;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Clear the key and securely erase all security-critical information.
|
||||
// /// </summary>
|
||||
// void Clear();
|
||||
// /// <summary>
|
||||
// /// Clear the key and securely erase all security-critical information.
|
||||
// /// </summary>
|
||||
// void Clear();
|
||||
|
||||
uint GetMinKdbxVersion();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,12 @@ namespace KeePassLib.Keys
|
||||
get { return m_pbKey; }
|
||||
}
|
||||
|
||||
public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
|
||||
public uint GetMinKdbxVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
|
||||
{
|
||||
Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
|
||||
Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
|
||||
|
||||
@@ -64,7 +64,12 @@ namespace KeePassLib.Keys
|
||||
get { return m_pbKeyData; }
|
||||
}
|
||||
|
||||
public IOConnectionInfo Ioc
|
||||
public uint GetMinKdbxVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public IOConnectionInfo Ioc
|
||||
{
|
||||
get { return m_ioc; }
|
||||
}
|
||||
|
||||
@@ -53,7 +53,12 @@ namespace KeePassLib.Keys
|
||||
get { return m_pbKeyData; }
|
||||
}
|
||||
|
||||
public KcpPassword(byte[] pbPasswordUtf8)
|
||||
public uint GetMinKdbxVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public KcpPassword(byte[] pbPasswordUtf8)
|
||||
{
|
||||
SetKey(pbPasswordUtf8);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
#if !KeePassUAP
|
||||
@@ -60,7 +59,12 @@ namespace KeePassLib.Keys
|
||||
get { return m_pbKeyData; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
public uint GetMinKdbxVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a user account key.
|
||||
/// </summary>
|
||||
public KcpUserAccount()
|
||||
@@ -73,26 +77,7 @@ namespace KeePassLib.Keys
|
||||
// m_pbKeyData = null;
|
||||
// }
|
||||
|
||||
private static string GetUserKeyFilePath(bool bCreate)
|
||||
{
|
||||
#if KeePassRT
|
||||
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
|
||||
#else
|
||||
string strUserDir = Environment.GetFolderPath(
|
||||
Environment.SpecialFolder.ApplicationData);
|
||||
#endif
|
||||
|
||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||
strUserDir += PwDefs.ShortProductName;
|
||||
|
||||
if (bCreate && !Directory.Exists(strUserDir))
|
||||
Directory.CreateDirectory(strUserDir);
|
||||
|
||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||
return strUserDir + UserKeyFileName;
|
||||
}
|
||||
|
||||
private static byte[] LoadUserKey(bool bShowWarning)
|
||||
private static byte[] LoadUserKey(bool bShowWarning)
|
||||
{
|
||||
byte[] pbKey = null;
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Preferences;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
@@ -57,7 +60,7 @@ namespace keepass2android
|
||||
|
||||
private static string LogFilename
|
||||
{
|
||||
get { return "/mnt/sdcard/keepass2android.log"; }
|
||||
get { return Application.Context.FilesDir.CanonicalPath +"/keepass2android.log"; }
|
||||
}
|
||||
|
||||
private static bool LogToFile
|
||||
@@ -77,5 +80,43 @@ namespace keepass2android
|
||||
if (OnUnexpectedError != null)
|
||||
OnUnexpectedError(null, exception);
|
||||
}
|
||||
|
||||
public static void CreateLogFile()
|
||||
{
|
||||
if (!File.Exists(LogFilename))
|
||||
{
|
||||
File.Create(LogFilename).Dispose();
|
||||
_logToFile = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void FinishLogFile()
|
||||
{
|
||||
if (File.Exists(LogFilename))
|
||||
{
|
||||
_logToFile = false;
|
||||
int count = 0;
|
||||
while (File.Exists(LogFilename + "." + count))
|
||||
count++;
|
||||
File.Move(LogFilename, LogFilename + "." + count);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void SendLog(Context ctx)
|
||||
{
|
||||
if (!File.Exists(LogFilename))
|
||||
return;
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.SetAction(Intent.ActionSend);
|
||||
sendIntent.PutExtra(Intent.ExtraText, File.ReadAllText(LogFilename));
|
||||
sendIntent.PutExtra(Intent.ExtraEmail, "crocoapps@gmail.com");
|
||||
sendIntent.PutExtra(Intent.ExtraSubject, "Keepass2Android log");
|
||||
sendIntent.SetType("text/plain");
|
||||
ctx.StartActivity(Intent.CreateChooser(sendIntent, "Send log to..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ namespace KeePassLib.Native
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.Log(e.Message);
|
||||
Kp2aLog.Log(e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -485,12 +485,6 @@ namespace KeePassLib
|
||||
set { m_pbHashOfLastIO = value; }
|
||||
}
|
||||
|
||||
public bool UseFileTransactions
|
||||
{
|
||||
get { return m_bUseFileTransactions; }
|
||||
set { m_bUseFileTransactions = value; }
|
||||
}
|
||||
|
||||
public bool UseFileLocks
|
||||
{
|
||||
get { return m_bUseFileLocks; }
|
||||
@@ -593,7 +587,7 @@ namespace KeePassLib
|
||||
/// </summary>
|
||||
/// <param name="ioConnection">IO connection of the new database.</param>
|
||||
/// <param name="pwKey">Key to open the database.</param>
|
||||
public void New(IOConnectionInfo ioConnection, CompositeKey pwKey)
|
||||
public void New(IOConnectionInfo ioConnection, CompositeKey pwKey, string filenameWithoutPathAndExt)
|
||||
{
|
||||
Debug.Assert(ioConnection != null);
|
||||
if(ioConnection == null) throw new ArgumentNullException("ioConnection");
|
||||
@@ -608,26 +602,11 @@ namespace KeePassLib
|
||||
m_bDatabaseOpened = true;
|
||||
m_bModified = true;
|
||||
|
||||
m_pgRootGroup = new PwGroup(true, true,
|
||||
UrlUtil.StripExtension(UrlUtil.GetFileName(ioConnection.Path)),
|
||||
m_pgRootGroup = new PwGroup(true, true, filenameWithoutPathAndExt,
|
||||
PwIcon.FolderOpen);
|
||||
m_pgRootGroup.IsExpanded = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a database. The URL may point to any supported data source.
|
||||
/// </summary>
|
||||
/// <param name="ioSource">IO connection to load the database from.</param>
|
||||
/// <param name="pwKey">Key used to open the specified database.</param>
|
||||
/// <param name="slLogger">Logger, which gets all status messages.</param>
|
||||
public void Open(IOConnectionInfo ioSource, CompositeKey pwKey,
|
||||
IStatusLogger slLogger, IDatabaseFormat format)
|
||||
|
||||
{
|
||||
Open(IOConnection.OpenRead(ioSource), UrlUtil.StripExtension(
|
||||
UrlUtil.GetFileName(ioSource.Path)), ioSource, pwKey, slLogger, format);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a database. The URL may point to any supported data source.
|
||||
@@ -675,37 +654,7 @@ namespace KeePassLib
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the currently opened database. The file is written to the location
|
||||
/// it has been opened from.
|
||||
/// </summary>
|
||||
/// <param name="slLogger">Logger that recieves status information.</param>
|
||||
public void Save(IStatusLogger slLogger)
|
||||
{
|
||||
Debug.Assert(!HasDuplicateUuids());
|
||||
|
||||
FileLock fl = null;
|
||||
if(m_bUseFileLocks) fl = new FileLock(m_ioSource);
|
||||
try
|
||||
{
|
||||
FileTransactionEx ft = new FileTransactionEx(m_ioSource,
|
||||
m_bUseFileTransactions);
|
||||
Stream s = ft.OpenWrite();
|
||||
|
||||
KdbxFile kdb = new KdbxFile(this);
|
||||
kdb.Save(s, null, KdbpFile.GetFormatToUse(m_ioSource), slLogger);
|
||||
|
||||
ft.CommitWrite();
|
||||
|
||||
m_pbHashOfLastIO = kdb.HashOfFileOnDisk;
|
||||
m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
|
||||
Debug.Assert(m_pbHashOfFileOnDisk != null);
|
||||
}
|
||||
finally { if(fl != null) fl.Dispose(); }
|
||||
|
||||
m_bModified = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Save the currently opened database. The file is written to the given stream which is expected to be the original location.
|
||||
@@ -723,46 +672,6 @@ namespace KeePassLib
|
||||
m_bModified = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the currently opened database to a different location. If
|
||||
/// <paramref name="bIsPrimaryNow" /> is <c>true</c>, the specified
|
||||
/// location is made the default location for future saves
|
||||
/// using <c>SaveDatabase</c>.
|
||||
/// </summary>
|
||||
/// <param name="ioConnection">New location to serialize the database to.</param>
|
||||
/// <param name="bIsPrimaryNow">If <c>true</c>, the new location is made the
|
||||
/// standard location for the database. If <c>false</c>, a copy of the currently
|
||||
/// opened database is saved to the specified location, but it isn't
|
||||
/// made the default location (i.e. no lock files will be moved for
|
||||
/// example).</param>
|
||||
/// <param name="slLogger">Logger that recieves status information.</param>
|
||||
public void SaveAs(IOConnectionInfo ioConnection, bool bIsPrimaryNow,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
Debug.Assert(ioConnection != null);
|
||||
if(ioConnection == null) throw new ArgumentNullException("ioConnection");
|
||||
|
||||
IOConnectionInfo ioCurrent = m_ioSource; // Remember current
|
||||
m_ioSource = ioConnection;
|
||||
|
||||
byte[] pbHashCopy = m_pbHashOfFileOnDisk;
|
||||
|
||||
try { this.Save(slLogger); }
|
||||
catch(Exception)
|
||||
{
|
||||
m_ioSource = ioCurrent; // Restore
|
||||
m_pbHashOfFileOnDisk = pbHashCopy;
|
||||
|
||||
m_pbHashOfLastIO = null;
|
||||
throw;
|
||||
}
|
||||
|
||||
if(!bIsPrimaryNow)
|
||||
{
|
||||
m_ioSource = ioCurrent; // Restore
|
||||
m_pbHashOfFileOnDisk = pbHashCopy;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the currently opened database. No confirmation message is shown
|
||||
|
||||
@@ -360,5 +360,12 @@ namespace KeePassLib.Serialization
|
||||
m_ioCredProtMode = IOCredProtMode.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSameFileAs(IOConnectionInfo other)
|
||||
{
|
||||
if (other == null)
|
||||
return false;
|
||||
return Path == other.Path && UserName == other.UserName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
using keepass2android;
|
||||
#if !KeePassUAP
|
||||
using System.Drawing;
|
||||
#endif
|
||||
@@ -872,8 +872,17 @@ namespace KeePassLib.Serialization
|
||||
pb = pb8;
|
||||
}
|
||||
long lSec = MemUtil.BytesToInt64(pb);
|
||||
return new DateTime(lSec * TimeSpan.TicksPerSecond, DateTimeKind.Utc);
|
||||
}
|
||||
try
|
||||
{
|
||||
return new DateTime(lSec * TimeSpan.TicksPerSecond, DateTimeKind.Utc);
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException e)
|
||||
{
|
||||
//files might contain bad data, e.g. see #868. Fall back to MinValue
|
||||
Kp2aLog.Log("Failed to read date from file.");
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string str = ReadString(xr);
|
||||
|
||||
@@ -581,7 +581,7 @@ namespace KeePassLib.Serialization
|
||||
return vEntries; */
|
||||
|
||||
PwDatabase pd = new PwDatabase();
|
||||
pd.New(new IOConnectionInfo(), new CompositeKey());
|
||||
pd.New(new IOConnectionInfo(), new CompositeKey(), "");
|
||||
|
||||
KdbxFile f = new KdbxFile(pd);
|
||||
f.Load(msData, KdbxFormat.PlainXml, null);
|
||||
|
||||
@@ -1048,7 +1048,7 @@ namespace KeePassLib.Serialization
|
||||
return true; */
|
||||
|
||||
PwDatabase pd = new PwDatabase();
|
||||
pd.New(new IOConnectionInfo(), new CompositeKey());
|
||||
pd.New(new IOConnectionInfo(), new CompositeKey(), "");
|
||||
|
||||
PwGroup pg = pd.RootGroup;
|
||||
if (pg == null) { Debug.Assert(false); return false; }
|
||||
|
||||
@@ -23,6 +23,7 @@ using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
@@ -126,8 +127,8 @@ namespace KeePassLib.Serialization
|
||||
/// </summary>
|
||||
private const uint FileVersion32 = 0x00040000;
|
||||
|
||||
internal const uint FileVersion32_4 = 0x00040000; // First of 4.x series
|
||||
internal const uint FileVersion32_3 = 0x00030001; // Old format 3.1
|
||||
public const uint FileVersion32_4 = 0x00040000; // First of 4.x series
|
||||
public const uint FileVersion32_3 = 0x00030001; // Old format 3.1
|
||||
|
||||
private const uint FileVersionCriticalMask = 0xFFFF0000;
|
||||
|
||||
@@ -372,16 +373,22 @@ namespace KeePassLib.Serialization
|
||||
{
|
||||
if(m_uForceVersion != 0) return m_uForceVersion;
|
||||
|
||||
// See also KeePassKdb2x3.Export (KDBX 3.1 export module)
|
||||
// See also KeePassKdb2x3.Export (KDBX 3.1 export module)
|
||||
uint minVersionForKeys = m_pwDatabase.MasterKey.UserKeys.Select(key => key.GetMinKdbxVersion()).Max();
|
||||
|
||||
AesKdf kdfAes = new AesKdf();
|
||||
uint minRequiredVersion = Math.Max(minVersionForKeys, m_uFileVersion); //don't save a version lower than what we read
|
||||
|
||||
|
||||
AesKdf kdfAes = new AesKdf();
|
||||
if(!kdfAes.Uuid.Equals(m_pwDatabase.KdfParameters.KdfUuid))
|
||||
return FileVersion32;
|
||||
return Math.Max(FileVersion32, minRequiredVersion);
|
||||
|
||||
if(m_pwDatabase.PublicCustomData.Count > 0)
|
||||
return FileVersion32;
|
||||
return Math.Max(FileVersion32, minRequiredVersion);
|
||||
|
||||
bool bCustomData = false;
|
||||
|
||||
|
||||
bool bCustomData = false;
|
||||
GroupHandler gh = delegate(PwGroup pg)
|
||||
{
|
||||
if(pg == null) { Debug.Assert(false); return true; }
|
||||
@@ -396,9 +403,10 @@ namespace KeePassLib.Serialization
|
||||
};
|
||||
gh(m_pwDatabase.RootGroup);
|
||||
m_pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh);
|
||||
if(bCustomData) return FileVersion32;
|
||||
if(bCustomData)
|
||||
return Math.Max(FileVersion32, minRequiredVersion);
|
||||
|
||||
return FileVersion32_3; // KDBX 3.1 is sufficient
|
||||
return Math.Max(FileVersion32_3, minRequiredVersion); ; // KDBX 3.1 is sufficient
|
||||
}
|
||||
|
||||
private void ComputeKeys(out byte[] pbCipherKey, int cbCipherKey,
|
||||
@@ -413,12 +421,15 @@ namespace KeePassLib.Serialization
|
||||
Debug.Assert(m_pbMasterSeed.Length == 32);
|
||||
if(m_pbMasterSeed.Length != 32)
|
||||
throw new FormatException(KLRes.MasterSeedLengthInvalid);
|
||||
Array.Copy(m_pbMasterSeed, 0, pbCmp, 0, 32);
|
||||
|
||||
|
||||
Debug.Assert(m_pwDatabase != null);
|
||||
Debug.Assert(m_pwDatabase.MasterKey != null);
|
||||
ProtectedBinary pbinUser = m_pwDatabase.MasterKey.GenerateKey32(
|
||||
m_pwDatabase.KdfParameters);
|
||||
ProtectedBinary pbinUser = m_pwDatabase.MasterKey.GenerateKey32(m_pwDatabase.KdfParameters,
|
||||
m_pbMasterSeed);
|
||||
|
||||
Array.Copy(m_pbMasterSeed, 0, pbCmp, 0, 32);
|
||||
|
||||
Debug.Assert(pbinUser != null);
|
||||
if(pbinUser == null)
|
||||
throw new SecurityException(KLRes.InvalidCompositeKey);
|
||||
|
||||
@@ -26,11 +26,11 @@ namespace KeePassLib.Serialization
|
||||
/// <summary>
|
||||
/// Determines whether the database pointed to by the specified ioc should be (de)serialised in default (xml) or protocol buffers format.
|
||||
/// </summary>
|
||||
public static KdbxFormat GetFormatToUse(IOConnectionInfo ioc)
|
||||
public static KdbxFormat GetFormatToUse(string fileExt)
|
||||
{
|
||||
// If the filename ends in .kdbp, use ProtocolBuffers format.
|
||||
return UrlUtil.GetExtension(UrlUtil.GetFileName(ioc.Path)).Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default;
|
||||
}
|
||||
return fileExt.Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers :
|
||||
(fileExt.Equals("xml", StringComparison.OrdinalIgnoreCase) ? KdbxFormat.PlainXml : KdbxFormat.Default);
|
||||
}
|
||||
|
||||
public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader)
|
||||
{
|
||||
|
||||
47
src/Kp2aBusinessLogic/ElementAndDatabaseId.cs
Normal file
47
src/Kp2aBusinessLogic/ElementAndDatabaseId.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using keepass2android.Io;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class ElementAndDatabaseId
|
||||
{
|
||||
private const char Separator = '+';
|
||||
|
||||
public ElementAndDatabaseId(Database db, IStructureItem element)
|
||||
{
|
||||
DatabaseId = db.IocAsHexString();
|
||||
ElementIdString = element.Uuid.ToHexString();
|
||||
}
|
||||
|
||||
public ElementAndDatabaseId(string fullId)
|
||||
{
|
||||
string[] parts = fullId.Split(Separator);
|
||||
if (parts.Length != 2)
|
||||
throw new Exception("Invalid full id " + fullId);
|
||||
DatabaseId = parts[0];
|
||||
ElementIdString = parts[1];
|
||||
}
|
||||
|
||||
public string DatabaseId { get; set; }
|
||||
public string ElementIdString { get; set; }
|
||||
public PwUuid ElementId { get { return new PwUuid(MemUtil.HexStringToByteArray(ElementIdString));} }
|
||||
|
||||
public string FullId
|
||||
{
|
||||
get { return DatabaseId + Separator + ElementIdString; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Android.App;
|
||||
@@ -9,7 +10,8 @@ using KeePassLib;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
using keepass2android.Io;
|
||||
#if !NoNet
|
||||
using KeePassLib.Interfaces;
|
||||
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE
|
||||
using Keepass2android.Javafilestorage;
|
||||
#endif
|
||||
|
||||
@@ -27,37 +29,47 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Interface through which Activities and the logic layer can access some app specific functionalities and Application static data
|
||||
/// </summary>
|
||||
/// This also contains methods which are UI specific and should be replacable for testing.
|
||||
public interface IKp2aApp : ICertificateValidationHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Locks the currently open database, quicklocking if available (unless false is passed for allowQuickUnlock)
|
||||
/// </summary>
|
||||
void LockDatabase(bool allowQuickUnlock = true);
|
||||
/// <summary>
|
||||
/// Locks all currently open databases, quicklocking if available (unless false is passed for allowQuickUnlock)
|
||||
/// </summary>
|
||||
void Lock(bool allowQuickUnlock, bool lockWasTriggeredByTimeout);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the specified data as the currently open database, as unlocked.
|
||||
/// </summary>
|
||||
void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey,
|
||||
ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current database
|
||||
/// </summary>
|
||||
Database GetDb();
|
||||
/// <summary>
|
||||
/// Loads the specified data as the currently open database, as unlocked.
|
||||
/// </summary>
|
||||
Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat, bool makeCurrent);
|
||||
|
||||
/// <summary>
|
||||
/// Tell the app that the file from ioc was opened with keyfile.
|
||||
/// </summary>
|
||||
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile);
|
||||
|
||||
HashSet<PwGroup> DirtyGroups { get; }
|
||||
|
||||
void MarkAllGroupsAsDirty();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current database
|
||||
/// </summary>
|
||||
Database CurrentDb { get; }
|
||||
|
||||
IEnumerable<Database> OpenDatabases { get; }
|
||||
void CloseDatabase(Database db);
|
||||
|
||||
Database FindDatabaseForElement(IStructureItem element);
|
||||
|
||||
/// <summary>
|
||||
/// Tell the app that the file from ioc was opened with keyfile.
|
||||
/// </summary>
|
||||
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, bool updateTimestamp, string displayName = "");
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new database and returns it
|
||||
/// </summary>
|
||||
Database CreateNewDatabase();
|
||||
Database CreateNewDatabase(bool makeCurrent);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the user-displayable string identified by stringKey
|
||||
@@ -76,7 +88,8 @@ namespace keepass2android
|
||||
EventHandler<DialogClickEventArgs> yesHandler,
|
||||
EventHandler<DialogClickEventArgs> noHandler,
|
||||
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||
Context ctx);
|
||||
Context ctx,
|
||||
string messageSuffix = "");
|
||||
|
||||
/// <summary>
|
||||
/// Asks the user the question "messageKey" with the options Yes/No/Cancel, but the yes/no strings can be selected freely, calls the handler corresponding to the answer.
|
||||
@@ -86,7 +99,8 @@ namespace keepass2android
|
||||
EventHandler<DialogClickEventArgs> yesHandler,
|
||||
EventHandler<DialogClickEventArgs> noHandler,
|
||||
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||
Context ctx);
|
||||
Context ctx,
|
||||
string messageSuffix = "");
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Handler object which can run tasks on the UI thread
|
||||
@@ -109,8 +123,12 @@ namespace keepass2android
|
||||
|
||||
|
||||
bool CheckForDuplicateUuids { get; }
|
||||
#if !NoNet
|
||||
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE
|
||||
ICertificateErrorHandler CertificateErrorHandler { get; }
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,16 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using Android;
|
||||
using Android.Content;
|
||||
using Android.Database;
|
||||
using Android.OS;
|
||||
using Android.Provider;
|
||||
using Java.IO;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
using Console = System.Console;
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
@@ -28,7 +33,12 @@ namespace keepass2android.Io
|
||||
get { yield return "content"; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
public bool UserShouldBackup
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -45,7 +55,20 @@ namespace keepass2android.Io
|
||||
|
||||
public Stream OpenFileForRead(IOConnectionInfo ioc)
|
||||
{
|
||||
return _ctx.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(ioc.Path));
|
||||
try
|
||||
{
|
||||
return _ctx.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(ioc.Path));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e.Message.Contains("requires that you obtain access using ACTION_OPEN_DOCUMENT"))
|
||||
{
|
||||
//looks like permission was revoked.
|
||||
throw new DocumentAccessRevokedException();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
|
||||
@@ -55,10 +78,16 @@ namespace keepass2android.Io
|
||||
|
||||
public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return UrlUtil.StripExtension(
|
||||
UrlUtil.GetFileName(ioc.Path));
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
public string GetFileExtension(IOConnectionInfo ioc)
|
||||
{
|
||||
return UrlUtil.GetExtension(ioc.Path);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -183,8 +212,7 @@ namespace keepass2android.Io
|
||||
|
||||
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
|
||||
{
|
||||
//TODO: required for OTP Aux file retrieval
|
||||
throw new NotImplementedException();
|
||||
return IoUtil.GetParentPath(ioc);
|
||||
}
|
||||
|
||||
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
|
||||
@@ -242,7 +270,7 @@ namespace keepass2android.Io
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
else throw new Exception("couldn't move to first result element: " + (cursor == null) + uri.ToString());
|
||||
else return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -261,7 +289,26 @@ namespace keepass2android.Io
|
||||
|
||||
}
|
||||
|
||||
class AndroidContentWriteTransaction : IWriteTransaction
|
||||
public class DocumentAccessRevokedException : Exception
|
||||
{
|
||||
public DocumentAccessRevokedException()
|
||||
{
|
||||
}
|
||||
|
||||
public DocumentAccessRevokedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public DocumentAccessRevokedException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected DocumentAccessRevokedException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class AndroidContentWriteTransaction : IWriteTransaction
|
||||
{
|
||||
private readonly string _path;
|
||||
private readonly Context _ctx;
|
||||
@@ -286,11 +333,16 @@ namespace keepass2android.Io
|
||||
|
||||
public void CommitWrite()
|
||||
{
|
||||
using (Stream outputStream = _ctx.ContentResolver.OpenOutputStream(Android.Net.Uri.Parse(_path)))
|
||||
ParcelFileDescriptor fileDescriptor = _ctx.ContentResolver.OpenFileDescriptor(Android.Net.Uri.Parse(_path), "rwt");
|
||||
|
||||
using (var outputStream = new FileOutputStream(fileDescriptor.FileDescriptor))
|
||||
{
|
||||
byte[] data = _memoryStream.ToArray();
|
||||
outputStream.Write(data, 0, data.Length);
|
||||
|
||||
outputStream.Write(data);
|
||||
outputStream.Close();
|
||||
}
|
||||
fileDescriptor.Close();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
using System.Security;
|
||||
@@ -10,10 +11,11 @@ using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Java.IO;
|
||||
using Android.Support.V4;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
using File = System.IO.File;
|
||||
using FileNotFoundException = System.IO.FileNotFoundException;
|
||||
using IOException = System.IO.IOException;
|
||||
@@ -59,7 +61,12 @@ namespace keepass2android.Io
|
||||
|
||||
public abstract IEnumerable<string> SupportedProtocols { get; }
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
public bool UserShouldBackup
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
{
|
||||
//todo check if directory
|
||||
IOConnection.DeleteFile(ioc);
|
||||
@@ -194,7 +201,12 @@ namespace keepass2android.Io
|
||||
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
public string GetFileExtension(IOConnectionInfo ioc)
|
||||
{
|
||||
return UrlUtil.GetExtension(ioc.Path);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return (!ioc.IsLocalFile()) && (ioc.CredSaveMode != IOCredSaveMode.SaveCred);
|
||||
}
|
||||
@@ -245,7 +257,8 @@ namespace keepass2android.Io
|
||||
if (ioc.IsLocalFile())
|
||||
{
|
||||
bool requiresPermission = !(ioc.Path.StartsWith(activity.Activity.FilesDir.CanonicalPath)
|
||||
|| ioc.Path.StartsWith(IoUtil.GetInternalDirectory(activity.Activity).CanonicalPath));
|
||||
|| ioc.Path.StartsWith(IoUtil.GetInternalDirectory(activity.Activity).CanonicalPath)
|
||||
|| ioc.Path.StartsWith(IoUtil.GetInternalDirectory(activity.Activity).CanonicalPath));
|
||||
|
||||
var extDirectory = activity.Activity.GetExternalFilesDir(null);
|
||||
if ((extDirectory != null) && (ioc.Path.StartsWith(extDirectory.CanonicalPath)))
|
||||
@@ -253,10 +266,14 @@ namespace keepass2android.Io
|
||||
|
||||
if (requiresPermission && (Build.VERSION.SdkInt >= BuildVersionCodes.M))
|
||||
{
|
||||
if (activity.Activity.CheckSelfPermission(Manifest.Permission.WriteExternalStorage) ==
|
||||
if ((activity.Activity.CheckSelfPermission(Manifest.Permission.WriteExternalStorage) ==
|
||||
Permission.Denied)
|
||||
{
|
||||
activity.StartFileUsageProcess(ioc, requestCode, alwaysReturnSuccess);
|
||||
||
|
||||
(activity.Activity.CheckSelfPermission(Manifest.Permission.ReadExternalStorage) ==
|
||||
Permission.Denied))
|
||||
|
||||
{
|
||||
activity.StartFileUsageProcess(ioc, requestCode, alwaysReturnSuccess);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -274,7 +291,7 @@ namespace keepass2android.Io
|
||||
|
||||
public void OnCreate(IFileStorageSetupActivity fileStorageSetupActivity, Bundle savedInstanceState)
|
||||
{
|
||||
((Activity)fileStorageSetupActivity).RequestPermissions(new[] { Manifest.Permission.WriteExternalStorage }, 0);
|
||||
Android.Support.V4.App.ActivityCompat.RequestPermissions(((Activity)fileStorageSetupActivity), new[] { Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage }, 0);
|
||||
}
|
||||
|
||||
public void OnResume(IFileStorageSetupActivity activity)
|
||||
@@ -367,7 +384,14 @@ namespace keepass2android.Io
|
||||
{
|
||||
if (ioc.IsLocalFile())
|
||||
{
|
||||
if (IsLocalFileFlaggedReadOnly(ioc))
|
||||
if (IsLocalBackup(ioc))
|
||||
{
|
||||
if (reason != null)
|
||||
reason.Result = UiStringKey.ReadOnlyReason_LocalBackup;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsLocalFileFlaggedReadOnly(ioc))
|
||||
{
|
||||
if (reason != null)
|
||||
reason.Result = UiStringKey.ReadOnlyReason_ReadOnlyFlag;
|
||||
@@ -388,7 +412,22 @@ namespace keepass2android.Io
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsLocalFileFlaggedReadOnly(IOConnectionInfo ioc)
|
||||
private readonly Dictionary<string, bool> _isLocalBackupCache = new Dictionary<string, bool>();
|
||||
public bool IsLocalBackup(IOConnectionInfo ioc)
|
||||
{
|
||||
if (!ioc.IsLocalFile())
|
||||
return false;
|
||||
bool result;
|
||||
if (_isLocalBackupCache.TryGetValue(ioc.Path, out result))
|
||||
return result;
|
||||
|
||||
result = (PreferenceManager.GetDefaultSharedPreferences(Application.Context)
|
||||
.GetBoolean(IoUtil.GetIocPrefKey(ioc, "is_local_backup"), false));
|
||||
_isLocalBackupCache[ioc.Path] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool IsLocalFileFlaggedReadOnly(IOConnectionInfo ioc)
|
||||
{
|
||||
//see http://stackoverflow.com/a/33292700/292233
|
||||
try
|
||||
@@ -412,7 +451,7 @@ namespace keepass2android.Io
|
||||
public void OnRequestPermissionsResult(IFileStorageSetupActivity fileStorageSetupActivity, int requestCode,
|
||||
string[] permissions, Permission[] grantResults)
|
||||
{
|
||||
fileStorageSetupActivity.State.PutBoolean(PermissionGrantedKey, grantResults[0] == Permission.Granted);
|
||||
fileStorageSetupActivity.State.PutBoolean(PermissionGrantedKey, grantResults.All(res => res == Permission.Granted));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,26 +65,37 @@ namespace keepass2android.Io
|
||||
|
||||
protected readonly OfflineSwitchableFileStorage _cachedStorage;
|
||||
private readonly ICacheSupervisor _cacheSupervisor;
|
||||
private readonly string _streamCacheDir;
|
||||
private readonly string _legacyCacheDir;
|
||||
private readonly string _cacheDir;
|
||||
|
||||
public CachingFileStorage(IFileStorage cachedStorage, string cacheDir, ICacheSupervisor cacheSupervisor)
|
||||
public CachingFileStorage(IFileStorage cachedStorage, Context cacheDirContext, ICacheSupervisor cacheSupervisor)
|
||||
{
|
||||
_cachedStorage = new OfflineSwitchableFileStorage(cachedStorage);
|
||||
_cacheSupervisor = cacheSupervisor;
|
||||
_streamCacheDir = cacheDir + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
|
||||
if (!Directory.Exists(_streamCacheDir))
|
||||
Directory.CreateDirectory(_streamCacheDir);
|
||||
|
||||
}
|
||||
_legacyCacheDir = cacheDirContext.CacheDir.Path + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
|
||||
if (!Directory.Exists(_legacyCacheDir))
|
||||
Directory.CreateDirectory(_legacyCacheDir);
|
||||
|
||||
_cacheDir = IoUtil.GetInternalDirectory(cacheDirContext).Path + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
|
||||
if (!Directory.Exists(_cacheDir))
|
||||
Directory.CreateDirectory(_cacheDir);
|
||||
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
IoUtil.DeleteDir(new Java.IO.File(_streamCacheDir), true);
|
||||
}
|
||||
IoUtil.DeleteDir(new Java.IO.File(_legacyCacheDir), true);
|
||||
IoUtil.DeleteDir(new Java.IO.File(_cacheDir), true);
|
||||
}
|
||||
|
||||
public IEnumerable<string> SupportedProtocols { get { return _cachedStorage.SupportedProtocols; } }
|
||||
|
||||
public void DeleteFile(IOConnectionInfo ioc)
|
||||
public bool UserShouldBackup
|
||||
{
|
||||
get { return _cachedStorage.UserShouldBackup; }
|
||||
}
|
||||
|
||||
public void DeleteFile(IOConnectionInfo ioc)
|
||||
{
|
||||
if (IsCached(ioc))
|
||||
{
|
||||
@@ -100,7 +111,11 @@ namespace keepass2android.Io
|
||||
{
|
||||
SHA256Managed sha256 = new SHA256Managed();
|
||||
string iocAsHexString = MemUtil.ByteArrayToHexString(sha256.ComputeHash(Encoding.Unicode.GetBytes(ioc.Path.ToCharArray())))+".cache";
|
||||
return _streamCacheDir + iocAsHexString;
|
||||
if (File.Exists(_legacyCacheDir + iocAsHexString))
|
||||
return _legacyCacheDir + iocAsHexString;
|
||||
|
||||
return _cacheDir + iocAsHexString;
|
||||
|
||||
}
|
||||
|
||||
public bool IsCached(IOConnectionInfo ioc)
|
||||
@@ -163,7 +178,9 @@ namespace keepass2android.Io
|
||||
if (!IsCached(ioc))
|
||||
throw;
|
||||
|
||||
Kp2aLog.Log("couldn't open from remote " + ioc.Path);
|
||||
#if DEBUG
|
||||
Kp2aLog.Log("couldn't open from remote " + ioc.Path);
|
||||
#endif
|
||||
Kp2aLog.Log(ex.ToString());
|
||||
|
||||
_cacheSupervisor.CouldntOpenFromRemote(ioc, ex);
|
||||
@@ -340,57 +357,7 @@ namespace keepass2android.Io
|
||||
|
||||
private class CachedWriteTransaction: IWriteTransaction
|
||||
{
|
||||
private class CachedWriteMemoryStream : MemoryStream
|
||||
{
|
||||
private readonly IOConnectionInfo ioc;
|
||||
private readonly CachingFileStorage _cachingFileStorage;
|
||||
private readonly bool _useFileTransaction;
|
||||
private bool _closed;
|
||||
|
||||
public CachedWriteMemoryStream(IOConnectionInfo ioc, CachingFileStorage cachingFileStorage, bool useFileTransaction)
|
||||
{
|
||||
this.ioc = ioc;
|
||||
_cachingFileStorage = cachingFileStorage;
|
||||
_useFileTransaction = useFileTransaction;
|
||||
}
|
||||
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
if (_closed) return;
|
||||
|
||||
//write file to cache:
|
||||
//(note: this might overwrite local changes. It's assumed that a sync operation or check was performed before
|
||||
string hash;
|
||||
using (var hashingStream = new HashingStreamEx(File.Create(_cachingFileStorage.CachedFilePath(ioc)), true, new SHA256Managed()))
|
||||
{
|
||||
Position = 0;
|
||||
CopyTo(hashingStream);
|
||||
|
||||
hashingStream.Close();
|
||||
hash = MemUtil.ByteArrayToHexString(hashingStream.Hash);
|
||||
}
|
||||
|
||||
File.WriteAllText(_cachingFileStorage.VersionFilePath(ioc), hash);
|
||||
//update file on remote. This might overwrite changes there as well, see above.
|
||||
Position = 0;
|
||||
if (_cachingFileStorage.IsCached(ioc))
|
||||
{
|
||||
//if the file already is in the cache, it's ok if writing to remote fails.
|
||||
_cachingFileStorage.TryUpdateRemoteFile(this, ioc, _useFileTransaction, hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if not, we don't accept a failure (e.g. invalid credentials would always remain a problem)
|
||||
_cachingFileStorage.UpdateRemoteFile(this, ioc, _useFileTransaction, hash);
|
||||
}
|
||||
|
||||
base.Close();
|
||||
|
||||
_closed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private readonly IOConnectionInfo _ioc;
|
||||
private readonly bool _useFileTransaction;
|
||||
@@ -424,17 +391,48 @@ namespace keepass2android.Io
|
||||
|
||||
public Stream OpenFile()
|
||||
{
|
||||
_memoryStream = new CachedWriteMemoryStream(_ioc, _cachingFileStorage, _useFileTransaction);
|
||||
_memoryStream = new MemoryStream();
|
||||
return _memoryStream;
|
||||
}
|
||||
|
||||
public void CommitWrite()
|
||||
{
|
||||
//the transaction is committed in the stream's Close
|
||||
_committed = true;
|
||||
_memoryStream.Close();
|
||||
|
||||
//write file to cache:
|
||||
//(note: this might overwrite local changes. It's assumed that a sync operation or check was performed before
|
||||
|
||||
byte[] output = _memoryStream.ToArray();
|
||||
|
||||
string hash;
|
||||
using (var hashingStream = new HashingStreamEx(File.Create(_cachingFileStorage.CachedFilePath(_ioc)), true, new SHA256Managed()))
|
||||
{
|
||||
hashingStream.Write(output, 0, output.Length);
|
||||
|
||||
hashingStream.Close();
|
||||
hash = MemUtil.ByteArrayToHexString(hashingStream.Hash);
|
||||
}
|
||||
|
||||
File.WriteAllText(_cachingFileStorage.VersionFilePath(_ioc), hash);
|
||||
//create another memory stream which is open for reading again
|
||||
MemoryStream openMemStream = new MemoryStream(output);
|
||||
//update file on remote. This might overwrite changes there as well, see above.
|
||||
if (_cachingFileStorage.IsCached(_ioc))
|
||||
{
|
||||
//if the file already is in the cache, it's ok if writing to remote fails.
|
||||
_cachingFileStorage.TryUpdateRemoteFile(openMemStream, _ioc, _useFileTransaction, hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if not, we don't accept a failure (e.g. invalid credentials would always remain a problem)
|
||||
_cachingFileStorage.UpdateRemoteFile(openMemStream, _ioc, _useFileTransaction, hash);
|
||||
}
|
||||
|
||||
openMemStream.Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
|
||||
@@ -450,7 +448,12 @@ namespace keepass2android.Io
|
||||
return _cachedStorage.GetFilenameWithoutPathAndExt(ioc);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
public string GetFileExtension(IOConnectionInfo ioc)
|
||||
{
|
||||
return _cachedStorage.GetFileExtension(ioc);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return _cachedStorage.RequiresCredentials(ioc);
|
||||
}
|
||||
|
||||
35
src/Kp2aBusinessLogic/Io/DropboxFileStorage.cs
Normal file
35
src/Kp2aBusinessLogic/Io/DropboxFileStorage.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Android.Content;
|
||||
#if !EXCLUDE_JAVAFILESTORAGE
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
public partial class DropboxFileStorage: JavaFileStorage
|
||||
{
|
||||
public DropboxFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.DropboxV2Storage(ctx, AppKey, AppSecret), app)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
public partial class DropboxAppFolderFileStorage: JavaFileStorage
|
||||
{
|
||||
public DropboxAppFolderFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.DropboxV2AppFolderStorage(ctx, AppKey, AppSecret), app)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -2,12 +2,12 @@ namespace keepass2android.Io
|
||||
{
|
||||
public partial class DropboxFileStorage
|
||||
{
|
||||
private const string AppKey = "";
|
||||
private const string AppSecret = "";
|
||||
private const string AppKey = "dummy";
|
||||
private const string AppSecret = "dummy";
|
||||
}
|
||||
public partial class DropboxAppFolderFileStorage
|
||||
{
|
||||
private const string AppKey = "";
|
||||
private const string AppSecret = "";
|
||||
private const string AppKey = "dummy";
|
||||
private const string AppSecret = "dummy";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
31
src/Kp2aBusinessLogic/Io/GDriveFileStorage.cs
Normal file
31
src/Kp2aBusinessLogic/Io/GDriveFileStorage.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib.Serialization;
|
||||
#if !EXCLUDE_JAVAFILESTORAGE
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
public class GoogleDriveFileStorage : JavaFileStorage
|
||||
{
|
||||
public GoogleDriveFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.GoogleDriveFileStorage(), app)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -46,9 +46,14 @@ namespace keepass2android.Io
|
||||
/// <summary>
|
||||
/// returns the protocol ids supported by this FileStorage. Can return pseudo-protocols like "dropbox" or real protocols like "ftp"
|
||||
/// </summary>
|
||||
IEnumerable<string> SupportedProtocols { get; }
|
||||
IEnumerable<string> SupportedProtocols { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// returns true if users should backup files on this file storage (if the file is important). Can be false for cloud providers with built-in versioning or backups.
|
||||
/// </summary>
|
||||
bool UserShouldBackup { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the given file or directory.
|
||||
/// </summary>
|
||||
void Delete(IOConnectionInfo ioc);
|
||||
@@ -83,11 +88,13 @@ namespace keepass2android.Io
|
||||
IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction);
|
||||
|
||||
string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the the given ioc must be filled with username/password
|
||||
/// </summary>
|
||||
bool RequiresCredentials(IOConnectionInfo ioc);
|
||||
|
||||
string GetFileExtension(IOConnectionInfo ioc);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the the given ioc must be filled with username/password
|
||||
/// </summary>
|
||||
bool RequiresCredentials(IOConnectionInfo ioc);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the directory described by ioc
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Java.IO;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
@@ -125,5 +127,55 @@ namespace keepass2android.Io
|
||||
return ctx.FilesDir;
|
||||
}
|
||||
|
||||
}
|
||||
//creates a local ioc where the sourceIoc can be stored to
|
||||
public static IOConnectionInfo GetInternalIoc(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app)
|
||||
{
|
||||
Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(ctx);
|
||||
var filestorage = app.GetFileStorage(sourceIoc);
|
||||
|
||||
string targetPath = filestorage.GetFilenameWithoutPathAndExt(sourceIoc);
|
||||
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
|
||||
if (targetPath == "")
|
||||
targetPath = "internal";
|
||||
if (new File(internalDirectory, targetPath).Exists())
|
||||
{
|
||||
int c = 1;
|
||||
var ext = UrlUtil.GetExtension(targetPath);
|
||||
var filenameWithoutExt = UrlUtil.StripExtension(targetPath);
|
||||
do
|
||||
{
|
||||
c++;
|
||||
targetPath = filenameWithoutExt + c;
|
||||
if (!String.IsNullOrEmpty(ext))
|
||||
targetPath += "." + ext;
|
||||
} while (new File(internalDirectory, targetPath).Exists());
|
||||
}
|
||||
return IOConnectionInfo.FromPath(new File(internalDirectory, targetPath).CanonicalPath);
|
||||
}
|
||||
|
||||
public static IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app)
|
||||
{
|
||||
var targetIoc = GetInternalIoc(sourceIoc, ctx, app);
|
||||
|
||||
|
||||
IoUtil.Copy(targetIoc, sourceIoc, app);
|
||||
return targetIoc;
|
||||
}
|
||||
|
||||
public static string GetIocPrefKey(IOConnectionInfo ioc, string suffix)
|
||||
{
|
||||
var iocAsHexString = IocAsHexString(ioc);
|
||||
|
||||
return "kp2a_ioc_key_" + iocAsHexString + suffix;
|
||||
}
|
||||
|
||||
|
||||
public static string IocAsHexString(IOConnectionInfo ioc)
|
||||
{
|
||||
SHA256Managed sha256 = new SHA256Managed();
|
||||
string iocAsHexString =
|
||||
MemUtil.ByteArrayToHexString(sha256.ComputeHash(Encoding.Unicode.GetBytes(ioc.Path.ToCharArray())));
|
||||
return iocAsHexString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,10 @@ namespace keepass2android.Io
|
||||
protected string Protocol { get { return _jfs.ProtocolId; } }
|
||||
|
||||
public virtual IEnumerable<string> SupportedProtocols { get { yield return Protocol; } }
|
||||
public abstract bool UserShouldBackup { get; }
|
||||
|
||||
|
||||
private readonly IJavaFileStorage _jfs;
|
||||
private readonly IJavaFileStorage _jfs;
|
||||
private readonly IKp2aApp _app;
|
||||
|
||||
public JavaFileStorage(IJavaFileStorage jfs, IKp2aApp app)
|
||||
@@ -176,7 +177,12 @@ namespace keepass2android.Io
|
||||
_jfs.GetFilename(IocToPath(ioc)));
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
public string GetFileExtension(IOConnectionInfo ioc)
|
||||
{
|
||||
return UrlUtil.GetExtension(ioc.Path);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -232,7 +238,6 @@ namespace keepass2android.Io
|
||||
|
||||
public FileDescription GetFileDescription(IOConnectionInfo ioc)
|
||||
{
|
||||
Kp2aLog.Log("GetFileDescription "+ioc.Path);
|
||||
try
|
||||
{
|
||||
return ConvertToFileDescription(Jfs.GetFileEntry(IocToPath(ioc)));
|
||||
@@ -301,7 +306,9 @@ namespace keepass2android.Io
|
||||
|
||||
public void OnResume(IFileStorageSetupActivity activity)
|
||||
{
|
||||
#if DEBUG
|
||||
Kp2aLog.Log("JFS/OnResume Ioc.Path=" +activity.Ioc.Path+". Path="+((IJavaFileStorageFileStorageSetupActivity)activity).Path);
|
||||
#endif
|
||||
_jfs.OnResume(((IJavaFileStorageFileStorageSetupActivity) activity));
|
||||
}
|
||||
|
||||
@@ -365,4 +372,4 @@ namespace keepass2android.Io
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.FtpClient;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using FluentFTP;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
@@ -17,73 +17,6 @@ namespace keepass2android.Io
|
||||
{
|
||||
public class NetFtpFileStorage: IFileStorage
|
||||
{
|
||||
class RetryConnectFtpClient : FtpClient
|
||||
{
|
||||
protected override FtpClient CloneConnection()
|
||||
{
|
||||
RetryConnectFtpClient conn = new RetryConnectFtpClient();
|
||||
|
||||
conn.m_isClone = true;
|
||||
|
||||
foreach (PropertyInfo prop in GetType().GetProperties())
|
||||
{
|
||||
object[] attributes = prop.GetCustomAttributes(typeof(FtpControlConnectionClone), true);
|
||||
|
||||
if (attributes != null && attributes.Length > 0)
|
||||
{
|
||||
prop.SetValue(conn, prop.GetValue(this, null), null);
|
||||
}
|
||||
}
|
||||
|
||||
// always accept certficate no matter what because if code execution ever
|
||||
// gets here it means the certificate on the control connection object being
|
||||
// cloned was already accepted.
|
||||
conn.ValidateCertificate += new FtpSslValidation(
|
||||
delegate(FtpClient obj, FtpSslValidationEventArgs e)
|
||||
{
|
||||
e.Accept = true;
|
||||
});
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
private static T DoInRetryLoop<T>(Func<T> func)
|
||||
{
|
||||
double timeout = 30.0;
|
||||
double timePerRequest = 1.0;
|
||||
var startTime = DateTime.Now;
|
||||
while (true)
|
||||
{
|
||||
var attemptStartTime = DateTime.Now;
|
||||
try
|
||||
{
|
||||
return func();
|
||||
}
|
||||
catch (System.Net.Sockets.SocketException e)
|
||||
{
|
||||
if ((e.ErrorCode != 10061) || (DateTime.Now > startTime.AddSeconds(timeout)))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
double secondsSinceAttemptStart = (DateTime.Now - attemptStartTime).TotalSeconds;
|
||||
if (secondsSinceAttemptStart < timePerRequest)
|
||||
{
|
||||
Thread.Sleep(TimeSpan.FromSeconds(timePerRequest - secondsSinceAttemptStart));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void Connect()
|
||||
{
|
||||
DoInRetryLoop(() =>
|
||||
{
|
||||
base.Connect();
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConnectionSettings
|
||||
{
|
||||
public FtpEncryptionMode EncryptionMode {get; set; }
|
||||
@@ -147,9 +80,8 @@ namespace keepass2android.Io
|
||||
|
||||
public NetFtpFileStorage(Context context, ICertificateValidationHandler app)
|
||||
{
|
||||
_app = app;
|
||||
_app = app;
|
||||
traceStream = new MemoryStream();
|
||||
FtpTrace.AddListener(new System.Diagnostics.TextWriterTraceListener(traceStream));
|
||||
|
||||
}
|
||||
|
||||
@@ -161,15 +93,20 @@ namespace keepass2android.Io
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
public bool UserShouldBackup
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FtpClient client = GetClient(ioc))
|
||||
{
|
||||
string localPath = IocToUri(ioc).PathAndQuery;
|
||||
string localPath = IocToLocalPath(ioc);
|
||||
if (client.DirectoryExists(localPath))
|
||||
client.DeleteDirectory(localPath, true);
|
||||
client.DeleteDirectory(localPath);
|
||||
else
|
||||
client.DeleteFile(localPath);
|
||||
}
|
||||
@@ -200,7 +137,8 @@ namespace keepass2android.Io
|
||||
{
|
||||
var settings = ConnectionSettings.FromIoc(ioc);
|
||||
|
||||
FtpClient client = new RetryConnectFtpClient();
|
||||
FtpClient client = new FtpClient();
|
||||
client.RetryAttempts = 3;
|
||||
if ((settings.Username.Length > 0) || (settings.Password.Length > 0))
|
||||
client.Credentials = new NetworkCredential(settings.Username, settings.Password);
|
||||
else
|
||||
@@ -226,7 +164,7 @@ namespace keepass2android.Io
|
||||
|
||||
|
||||
|
||||
internal Uri IocToUri(IOConnectionInfo ioc)
|
||||
public static Uri IocToUri(IOConnectionInfo ioc)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ioc.UserName))
|
||||
{
|
||||
@@ -245,20 +183,22 @@ namespace keepass2android.Io
|
||||
path = path.Substring(settings.Length + 1);
|
||||
|
||||
}
|
||||
return new Uri(scheme + "://" + path);
|
||||
Kp2aLog.Log("FTP: IocToUri out = " + scheme + "://" + path);
|
||||
return new Uri(scheme + "://" + path);
|
||||
}
|
||||
|
||||
private string IocPathFromUri(IOConnectionInfo baseIoc, Uri uri)
|
||||
private string IocPathFromUri(IOConnectionInfo baseIoc, string uri)
|
||||
{
|
||||
string basePath = baseIoc.Path;
|
||||
string basePath = baseIoc.Path;
|
||||
int schemeLength = basePath.IndexOf("://", StringComparison.Ordinal);
|
||||
string scheme = basePath.Substring(0, schemeLength);
|
||||
basePath = basePath.Substring(schemeLength + 3);
|
||||
string baseSettings = basePath.Substring(0, basePath.IndexOf(ConnectionSettings.SettingsPostFix, StringComparison.Ordinal));
|
||||
basePath = basePath.Substring(baseSettings.Length+1);
|
||||
string baseHost = basePath.Substring(0, basePath.IndexOf("/", StringComparison.Ordinal));
|
||||
return scheme + "://" + baseSettings + ConnectionSettings.SettingsPostFix + baseHost + uri.AbsolutePath; //TODO does this contain Query?
|
||||
}
|
||||
string result = scheme + "://" + baseSettings + ConnectionSettings.SettingsPostFix + baseHost + uri; //TODO does this contain Query?
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
|
||||
@@ -276,9 +216,12 @@ namespace keepass2android.Io
|
||||
try
|
||||
{
|
||||
using (var cl = GetClient(ioc))
|
||||
{
|
||||
return cl.OpenRead(IocToUri(ioc).PathAndQuery, FtpDataType.Binary, 0);
|
||||
}
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
cl.OpenRead(IocToLocalPath(ioc), FtpDataType.Binary, 0).CopyTo(memStream);
|
||||
memStream.Seek(0, SeekOrigin.Begin);
|
||||
return memStream;
|
||||
}
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
{
|
||||
@@ -309,7 +252,12 @@ namespace keepass2android.Io
|
||||
UrlUtil.GetFileName(ioc.Path));
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
public string GetFileExtension(IOConnectionInfo ioc)
|
||||
{
|
||||
return UrlUtil.GetExtension(ioc.Path);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -320,7 +268,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
using (var client = GetClient(ioc))
|
||||
{
|
||||
client.CreateDirectory(IocToUri(GetFilePath(ioc, newDirName)).PathAndQuery);
|
||||
client.CreateDirectory(IocToLocalPath(GetFilePath(ioc, newDirName)));
|
||||
}
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
@@ -329,14 +277,19 @@ namespace keepass2android.Io
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc)
|
||||
public static string IocToLocalPath(IOConnectionInfo ioc)
|
||||
{
|
||||
return WebUtility.UrlDecode(IocToUri(ioc).PathAndQuery);
|
||||
}
|
||||
|
||||
public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = GetClient(ioc))
|
||||
using (var client = GetClient(ioc))
|
||||
{
|
||||
List<FileDescription> files = new List<FileDescription>();
|
||||
foreach (FtpListItem item in client.GetListing(IocToUri(ioc).PathAndQuery,
|
||||
foreach (FtpListItem item in client.GetListing(IocToLocalPath(ioc),
|
||||
FtpListOption.Modify | FtpListOption.Size | FtpListOption.DerefLinks))
|
||||
{
|
||||
|
||||
@@ -350,7 +303,7 @@ namespace keepass2android.Io
|
||||
DisplayName = item.Name,
|
||||
IsDirectory = true,
|
||||
LastModified = item.Modified,
|
||||
Path = IocPathFromUri(ioc, new Uri(item.FullName))
|
||||
Path = IocPathFromUri(ioc, item.FullName)
|
||||
});
|
||||
break;
|
||||
case FtpFileSystemObjectType.File:
|
||||
@@ -361,7 +314,7 @@ namespace keepass2android.Io
|
||||
DisplayName = item.Name,
|
||||
IsDirectory = false,
|
||||
LastModified = item.Modified,
|
||||
Path = IocPathFromUri(ioc, new Uri(item.FullName)),
|
||||
Path = IocPathFromUri(ioc, item.FullName),
|
||||
SizeInBytes = item.Size
|
||||
});
|
||||
break;
|
||||
@@ -386,10 +339,10 @@ namespace keepass2android.Io
|
||||
//is it very inefficient to connect for each description?
|
||||
|
||||
using (FtpClient client = GetClient(ioc))
|
||||
{
|
||||
|
||||
var uri = IocToUri(ioc);
|
||||
string path = uri.PathAndQuery;
|
||||
{
|
||||
|
||||
|
||||
string path = IocToLocalPath(ioc);
|
||||
if (!client.FileExists(path) && (!client.DirectoryExists(path)))
|
||||
throw new FileNotFoundException();
|
||||
var fileDesc = new FileDescription()
|
||||
@@ -501,7 +454,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
using (var client = GetClient(ioc))
|
||||
{
|
||||
return client.OpenWrite(IocToUri(ioc).PathAndQuery);
|
||||
return client.OpenWrite(IocToLocalPath(ioc));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -570,7 +523,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
|
||||
_client = _fileStorage.GetClient(_ioc, false);
|
||||
_stream = _client.OpenWrite(_fileStorage.IocToUri(_iocTemp).PathAndQuery);
|
||||
_stream = _client.OpenWrite(NetFtpFileStorage.IocToLocalPath(_iocTemp));
|
||||
return _stream;
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
@@ -585,22 +538,11 @@ namespace keepass2android.Io
|
||||
{
|
||||
Android.Util.Log.Debug("NETFTP","connected: " + _client.IsConnected.ToString());
|
||||
_stream.Close();
|
||||
Android.Util.Log.Debug("NETFTP", "connected: " + _client.IsConnected.ToString());
|
||||
_stream.Dispose();
|
||||
_client.GetReply();
|
||||
|
||||
//make sure target file does not exist:
|
||||
//try
|
||||
{
|
||||
if (_client.FileExists(_fileStorage.IocToUri(_ioc).PathAndQuery))
|
||||
_client.DeleteFile(_fileStorage.IocToUri(_ioc).PathAndQuery);
|
||||
|
||||
}
|
||||
//catch (FtpCommandException)
|
||||
{
|
||||
//TODO get a new clien? might be stale
|
||||
}
|
||||
|
||||
_client.Rename(_fileStorage.IocToUri(_iocTemp).PathAndQuery,
|
||||
_fileStorage.IocToUri(_ioc).PathAndQuery);
|
||||
_client.MoveFile(NetFtpFileStorage.IocToLocalPath(_iocTemp),
|
||||
NetFtpFileStorage.IocToLocalPath(_ioc));
|
||||
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
|
||||
@@ -32,7 +32,12 @@ namespace keepass2android.Io
|
||||
get { return _baseStorage.SupportedProtocols; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
public bool UserShouldBackup
|
||||
{
|
||||
get { return _baseStorage.UserShouldBackup; }
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
{
|
||||
_baseStorage.Delete(ioc);
|
||||
}
|
||||
@@ -73,7 +78,12 @@ namespace keepass2android.Io
|
||||
return _baseStorage.GetFilenameWithoutPathAndExt(ioc);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
public string GetFileExtension(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.GetFileExtension(ioc);
|
||||
}
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return _baseStorage.RequiresCredentials(ioc);
|
||||
}
|
||||
|
||||
1154
src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs
Normal file
1154
src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs
Normal file
File diff suppressed because it is too large
Load Diff
26
src/Kp2aBusinessLogic/Io/OneDrive2PrefixContainer.cs
Normal file
26
src/Kp2aBusinessLogic/Io/OneDrive2PrefixContainer.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace keepass2android.Io.ItemLocation
|
||||
{
|
||||
public abstract class OneDrive2PrefixContainer
|
||||
{
|
||||
public abstract string Onedrive2ProtocolId { get; }
|
||||
public string Onedrive2Prefix { get { return Onedrive2ProtocolId + "://"; } }
|
||||
}
|
||||
|
||||
//for permissions including all my files and all shared files
|
||||
public class OneDrive2FullPrefixContainer : OneDrive2PrefixContainer
|
||||
{
|
||||
public override string Onedrive2ProtocolId { get { return "onedrive2_full"; }}
|
||||
}
|
||||
|
||||
//for permissions including all my files
|
||||
public class OneDrive2MyFilesPrefixContainer : OneDrive2PrefixContainer
|
||||
{
|
||||
public override string Onedrive2ProtocolId { get { return "onedrive2_myfiles"; } }
|
||||
}
|
||||
|
||||
//for permissions to app folder only
|
||||
public class OneDrive2AppFolderPrefixContainer : OneDrive2PrefixContainer
|
||||
{
|
||||
public override string Onedrive2ProtocolId { get { return "onedrive2_appfolder"; } }
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,11 @@ namespace keepass2android.Io
|
||||
yield return "onedrive";
|
||||
}
|
||||
}
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
23
src/Kp2aBusinessLogic/Io/PCloudFileStorage.cs
Normal file
23
src/Kp2aBusinessLogic/Io/PCloudFileStorage.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Android.Content;
|
||||
#if !EXCLUDE_JAVAFILESTORAGE
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
public partial class PCloudFileStorage: JavaFileStorage
|
||||
{
|
||||
private const string ClientId = "CkRWTQXY6Lm";
|
||||
|
||||
public PCloudFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.PCloudFileStorage(ctx, ClientId), app)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -5,12 +5,16 @@ namespace keepass2android.Io
|
||||
{
|
||||
public class SftpFileStorage: JavaFileStorage
|
||||
{
|
||||
public SftpFileStorage(IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.SftpStorage(), app)
|
||||
public SftpFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.SftpStorage(ctx.ApplicationContext), app)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user